@ai.ntellect/core 0.6.11 → 0.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/README.md +36 -0
- package/app/app/favicon.ico +0 -0
- package/app/app/globals.css +21 -0
- package/app/app/gun.ts +0 -0
- package/app/app/layout.tsx +18 -0
- package/app/app/page.tsx +321 -0
- package/app/eslint.config.mjs +16 -0
- package/app/next.config.ts +7 -0
- package/app/package-lock.json +5912 -0
- package/app/package.json +31 -0
- package/app/pnpm-lock.yaml +4031 -0
- package/app/postcss.config.mjs +8 -0
- package/app/public/file.svg +1 -0
- package/app/public/globe.svg +1 -0
- package/app/public/next.svg +1 -0
- package/app/public/vercel.svg +1 -0
- package/app/public/window.svg +1 -0
- package/app/tailwind.config.ts +18 -0
- package/app/tsconfig.json +27 -0
- package/dist/graph/controller.js +30 -41
- package/dist/graph/graph.js +167 -0
- package/dist/index.js +3 -2
- package/dist/memory/adapters/meilisearch/index.js +39 -63
- package/dist/utils/experimental-graph-rag.js +152 -0
- package/dist/utils/stringifiy-zod-schema.js +7 -6
- package/graph/controller.ts +57 -52
- package/graph/graph.ts +198 -0
- package/index.ts +3 -2
- package/memory/adapters/meilisearch/index.ts +41 -76
- package/package.json +2 -2
- package/tsconfig.json +1 -1
- package/types/index.ts +35 -38
- package/utils/experimental-graph-rag.ts +170 -0
- package/utils/stringifiy-zod-schema.ts +6 -6
- package/create-llm-to-select-multiple-graph copy.ts +0 -237
- package/create-llm-to-select-multiple-graph.ts +0 -148
- package/dist/create-llm-to-select-multiple-graph copy.js +0 -171
- package/dist/create-llm-to-select-multiple-graph.js +0 -142
- package/dist/graph/engine.js +0 -646
- package/dist/index copy.js +0 -76
- package/dist/utils/setup-graphs.js +0 -28
- package/graph/engine.ts +0 -805
- package/index copy.ts +0 -81
- package/utils/setup-graphs.ts +0 -45
package/app/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
2
|
+
|
3
|
+
## Getting Started
|
4
|
+
|
5
|
+
First, run the development server:
|
6
|
+
|
7
|
+
```bash
|
8
|
+
npm run dev
|
9
|
+
# or
|
10
|
+
yarn dev
|
11
|
+
# or
|
12
|
+
pnpm dev
|
13
|
+
# or
|
14
|
+
bun dev
|
15
|
+
```
|
16
|
+
|
17
|
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
18
|
+
|
19
|
+
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
20
|
+
|
21
|
+
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
22
|
+
|
23
|
+
## Learn More
|
24
|
+
|
25
|
+
To learn more about Next.js, take a look at the following resources:
|
26
|
+
|
27
|
+
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
28
|
+
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
29
|
+
|
30
|
+
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
31
|
+
|
32
|
+
## Deploy on Vercel
|
33
|
+
|
34
|
+
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
35
|
+
|
36
|
+
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
@tailwind base;
|
2
|
+
@tailwind components;
|
3
|
+
@tailwind utilities;
|
4
|
+
|
5
|
+
:root {
|
6
|
+
--background: #ffffff;
|
7
|
+
--foreground: #171717;
|
8
|
+
}
|
9
|
+
|
10
|
+
@media (prefers-color-scheme: dark) {
|
11
|
+
:root {
|
12
|
+
--background: #0a0a0a;
|
13
|
+
--foreground: #ededed;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
body {
|
18
|
+
color: var(--foreground);
|
19
|
+
background: var(--background);
|
20
|
+
font-family: Arial, Helvetica, sans-serif;
|
21
|
+
}
|
package/app/app/gun.ts
ADDED
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import type { Metadata } from "next";
|
2
|
+
import "./globals.css";
|
3
|
+
export const metadata: Metadata = {
|
4
|
+
title: "Create Next App",
|
5
|
+
description: "Generated by create next app",
|
6
|
+
};
|
7
|
+
|
8
|
+
export default function RootLayout({
|
9
|
+
children,
|
10
|
+
}: Readonly<{
|
11
|
+
children: React.ReactNode;
|
12
|
+
}>) {
|
13
|
+
return (
|
14
|
+
<html lang="en">
|
15
|
+
<body>{children}</body>
|
16
|
+
</html>
|
17
|
+
);
|
18
|
+
}
|
package/app/app/page.tsx
ADDED
@@ -0,0 +1,321 @@
|
|
1
|
+
"use client";
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
3
|
+
import ForceGraph2D from "react-force-graph-2d";
|
4
|
+
import { MeilisearchAdapter } from "../../memory/adapters/meilisearch";
|
5
|
+
|
6
|
+
// Interfaces restent les mêmes
|
7
|
+
export interface GraphNode {
|
8
|
+
id: number;
|
9
|
+
name?: string;
|
10
|
+
neighbors: GraphNode[];
|
11
|
+
links: GraphLink[];
|
12
|
+
x?: number;
|
13
|
+
y?: number;
|
14
|
+
}
|
15
|
+
|
16
|
+
export interface GraphLink {
|
17
|
+
source: number | GraphNode;
|
18
|
+
target: number | GraphNode;
|
19
|
+
relation?: string;
|
20
|
+
}
|
21
|
+
const SPACING_FORCE = -200; // Augmente la répulsion entre les nœuds
|
22
|
+
|
23
|
+
async function fetchGraphData() {
|
24
|
+
const memoryManager = new MeilisearchAdapter({
|
25
|
+
apiKey: process.env.NEXT_PUBLIC_MEILISEARCH_API_KEY,
|
26
|
+
host: process.env.NEXT_PUBLIC_MEILISEARCH_HOST,
|
27
|
+
});
|
28
|
+
|
29
|
+
const existingNodesMemories = await memoryManager.getAllMemories("nodes");
|
30
|
+
const existingEdgesMemories = await memoryManager.getAllMemories("edges");
|
31
|
+
|
32
|
+
let nodes: GraphNode[] = existingNodesMemories.map((memory) => ({
|
33
|
+
id: memory.id,
|
34
|
+
name: memory.data.name,
|
35
|
+
neighbors: [],
|
36
|
+
links: [],
|
37
|
+
}));
|
38
|
+
|
39
|
+
let nodeMap: Record<string, GraphNode> = {};
|
40
|
+
nodes.forEach((node, idx) => {
|
41
|
+
nodeMap[existingNodesMemories[idx].id] = node;
|
42
|
+
});
|
43
|
+
|
44
|
+
let links: GraphLink[] = existingEdgesMemories
|
45
|
+
.map((memory) => {
|
46
|
+
const sourceNode = nodeMap[memory.data.source];
|
47
|
+
const targetNode = nodeMap[memory.data.target];
|
48
|
+
|
49
|
+
if (!sourceNode || !targetNode) {
|
50
|
+
console.warn(
|
51
|
+
`⚠️ Relation ignorée : ${memory.data.source} → ${memory.data.relation} → ${memory.data.target}`
|
52
|
+
);
|
53
|
+
return null;
|
54
|
+
}
|
55
|
+
|
56
|
+
return {
|
57
|
+
source: sourceNode,
|
58
|
+
target: targetNode,
|
59
|
+
relation: memory.data.relation,
|
60
|
+
};
|
61
|
+
})
|
62
|
+
.filter((link) => link !== null) as GraphLink[];
|
63
|
+
|
64
|
+
return { nodes, links };
|
65
|
+
}
|
66
|
+
|
67
|
+
const NODE_R = 12;
|
68
|
+
|
69
|
+
const HighlightGraph = () => {
|
70
|
+
const fgRef = useRef<any>(null);
|
71
|
+
const [data, setData] = useState<{ nodes: GraphNode[]; links: GraphLink[] }>({
|
72
|
+
nodes: [],
|
73
|
+
links: [],
|
74
|
+
});
|
75
|
+
const [highlightNodes, setHighlightNodes] = useState(new Set<GraphNode>());
|
76
|
+
const [highlightLinks, setHighlightLinks] = useState(new Set<GraphLink>());
|
77
|
+
const [hoverNode, setHoverNode] = useState<GraphNode | null>(null);
|
78
|
+
const [selectedNode, setSelectedNode] = useState<GraphNode | null>(null);
|
79
|
+
|
80
|
+
useEffect(() => {
|
81
|
+
const loadGraphData = async () => {
|
82
|
+
try {
|
83
|
+
const graphData = await fetchGraphData();
|
84
|
+
setData(graphData);
|
85
|
+
} catch (error) {
|
86
|
+
console.error("❌ Erreur lors de la récupération du graphe :", error);
|
87
|
+
}
|
88
|
+
};
|
89
|
+
|
90
|
+
loadGraphData();
|
91
|
+
}, []);
|
92
|
+
|
93
|
+
useEffect(() => {
|
94
|
+
if (fgRef.current && data.nodes.length > 0) {
|
95
|
+
fgRef.current.d3Force("charge")?.strength(-200);
|
96
|
+
fgRef.current.d3Force("link")?.distance(200);
|
97
|
+
}
|
98
|
+
}, [data]);
|
99
|
+
|
100
|
+
useMemo(() => {
|
101
|
+
data.links.forEach((link) => {
|
102
|
+
const a =
|
103
|
+
typeof link.source === "object"
|
104
|
+
? link.source
|
105
|
+
: data.nodes.find((node) => node.id === link.source);
|
106
|
+
const b =
|
107
|
+
typeof link.target === "object"
|
108
|
+
? link.target
|
109
|
+
: data.nodes.find((node) => node.id === link.target);
|
110
|
+
|
111
|
+
if (!a || !b) return;
|
112
|
+
|
113
|
+
if (!a.neighbors.includes(b)) a.neighbors.push(b);
|
114
|
+
if (!b.neighbors.includes(a)) b.neighbors.push(a);
|
115
|
+
if (!a.links.includes(link)) a.links.push(link);
|
116
|
+
if (!b.links.includes(link)) b.links.push(link);
|
117
|
+
});
|
118
|
+
}, [data]);
|
119
|
+
|
120
|
+
const handleNodeHover = useCallback((node: GraphNode | null) => {
|
121
|
+
setHoverNode(node);
|
122
|
+
}, []);
|
123
|
+
|
124
|
+
const handleNodeClick = useCallback((node: GraphNode) => {
|
125
|
+
// Mise à jour des nœuds et liens en surbrillance
|
126
|
+
const newHighlightNodes = new Set<GraphNode>([node, ...node.neighbors]);
|
127
|
+
const newHighlightLinks = new Set<GraphLink>(node.links);
|
128
|
+
|
129
|
+
setHighlightNodes(newHighlightNodes);
|
130
|
+
setHighlightLinks(newHighlightLinks);
|
131
|
+
setSelectedNode(node);
|
132
|
+
|
133
|
+
if (node.x !== undefined && node.y !== undefined && fgRef.current) {
|
134
|
+
fgRef.current.centerAt(node.x, node.y, 1000);
|
135
|
+
}
|
136
|
+
}, []);
|
137
|
+
|
138
|
+
const getNodeColor = useCallback(
|
139
|
+
(node: GraphNode) => {
|
140
|
+
if (selectedNode?.id === node.id) {
|
141
|
+
return "#3b82f6"; // Bleu vif pour le nœud sélectionné
|
142
|
+
}
|
143
|
+
if (highlightNodes.has(node)) {
|
144
|
+
return "#60a5fa"; // Bleu clair pour les voisins
|
145
|
+
}
|
146
|
+
return selectedNode ? "#1e3a8a" : "#1d4ed8"; // Assombri si non connecté, normal sinon
|
147
|
+
},
|
148
|
+
[selectedNode, highlightNodes]
|
149
|
+
);
|
150
|
+
|
151
|
+
const paintRing = useCallback(
|
152
|
+
(node: GraphNode, ctx: CanvasRenderingContext2D) => {
|
153
|
+
const x = node.x ?? 0;
|
154
|
+
const y = node.y ?? 0;
|
155
|
+
|
156
|
+
// Effet de lueur pour les nœuds en surbrillance
|
157
|
+
if (highlightNodes.has(node)) {
|
158
|
+
ctx.beginPath();
|
159
|
+
ctx.arc(x, y, NODE_R + 4, 0, 2 * Math.PI);
|
160
|
+
ctx.fillStyle = "rgba(147, 197, 253, 0.3)"; // Lueur bleue
|
161
|
+
ctx.fill();
|
162
|
+
}
|
163
|
+
|
164
|
+
// Nœud principal
|
165
|
+
ctx.beginPath();
|
166
|
+
ctx.arc(x, y, NODE_R, 0, 2 * Math.PI);
|
167
|
+
ctx.fillStyle = getNodeColor(node);
|
168
|
+
ctx.fill();
|
169
|
+
|
170
|
+
// Bordure
|
171
|
+
ctx.strokeStyle = highlightNodes.has(node) ? "#ffffff" : "#94a3b8";
|
172
|
+
ctx.lineWidth = highlightNodes.has(node) ? 2.5 : 2.5;
|
173
|
+
ctx.stroke();
|
174
|
+
|
175
|
+
// Label
|
176
|
+
const label = node.name ?? `Node ${node.id}`;
|
177
|
+
ctx.font = "14px Inter, system-ui, sans-serif";
|
178
|
+
const textWidth = ctx.measureText(label).width;
|
179
|
+
|
180
|
+
// Fond du label
|
181
|
+
ctx.fillStyle = "#000000";
|
182
|
+
ctx.globalAlpha = 0.8;
|
183
|
+
ctx.fillRect(x - textWidth / 2 - 6, y - NODE_R - 24, textWidth + 12, 22);
|
184
|
+
ctx.globalAlpha = 1;
|
185
|
+
|
186
|
+
// Texte
|
187
|
+
ctx.textAlign = "center";
|
188
|
+
ctx.fillStyle = "white";
|
189
|
+
ctx.fillText(label, x, y - NODE_R - 8);
|
190
|
+
},
|
191
|
+
[hoverNode, selectedNode, highlightNodes, getNodeColor]
|
192
|
+
);
|
193
|
+
|
194
|
+
const clearSelection = useCallback(() => {
|
195
|
+
setSelectedNode(null);
|
196
|
+
setHighlightNodes(new Set());
|
197
|
+
setHighlightLinks(new Set());
|
198
|
+
}, []);
|
199
|
+
|
200
|
+
return (
|
201
|
+
<div className="drawer">
|
202
|
+
<input
|
203
|
+
id="my-drawer"
|
204
|
+
type="checkbox"
|
205
|
+
className="drawer-toggle"
|
206
|
+
checked={selectedNode !== null}
|
207
|
+
onChange={(e) => !e.target.checked && clearSelection()}
|
208
|
+
/>
|
209
|
+
<div
|
210
|
+
className="drawer-content"
|
211
|
+
style={{ height: "100vh", background: "#0f172a" }}
|
212
|
+
>
|
213
|
+
<ForceGraph2D
|
214
|
+
ref={fgRef}
|
215
|
+
graphData={data}
|
216
|
+
nodeRelSize={NODE_R}
|
217
|
+
autoPauseRedraw={false}
|
218
|
+
linkWidth={(link) => (highlightLinks.has(link as GraphLink) ? 5 : 2)}
|
219
|
+
linkColor={(link) =>
|
220
|
+
highlightLinks.has(link as GraphLink) ? "#60a5fa" : "#64748b"
|
221
|
+
}
|
222
|
+
linkDirectionalParticles={4}
|
223
|
+
linkDirectionalParticleWidth={(link) =>
|
224
|
+
highlightLinks.has(link as GraphLink) ? 6 : 2
|
225
|
+
}
|
226
|
+
linkDirectionalParticleSpeed={0.004}
|
227
|
+
linkDirectionalParticleColor={(link) =>
|
228
|
+
highlightLinks.has(link as GraphLink) ? "#93c5fd" : "#94a3b8"
|
229
|
+
}
|
230
|
+
nodeCanvasObjectMode={() => "before"}
|
231
|
+
nodeCanvasObject={paintRing}
|
232
|
+
onNodeHover={handleNodeHover}
|
233
|
+
onNodeClick={handleNodeClick}
|
234
|
+
linkLabel={(link: GraphLink) => link.relation ?? ""}
|
235
|
+
backgroundColor="#0f172a"
|
236
|
+
linkCanvasObjectMode={() => "after"}
|
237
|
+
linkCanvasObject={(
|
238
|
+
link: GraphLink,
|
239
|
+
ctx: CanvasRenderingContext2D
|
240
|
+
) => {
|
241
|
+
const start = link.source as GraphNode;
|
242
|
+
const end = link.target as GraphNode;
|
243
|
+
const textPos = {
|
244
|
+
x: start.x! + (end.x! - start.x!) * 0.5,
|
245
|
+
y: start.y! + (end.y! - start.y!) * 0.5,
|
246
|
+
};
|
247
|
+
|
248
|
+
if (!textPos.x || !textPos.y) return;
|
249
|
+
|
250
|
+
// Fond du label
|
251
|
+
const label = link.relation || "";
|
252
|
+
ctx.font = "12px Inter";
|
253
|
+
const textWidth = ctx.measureText(label).width;
|
254
|
+
|
255
|
+
ctx.fillStyle = "#000000";
|
256
|
+
ctx.globalAlpha = 0.8;
|
257
|
+
ctx.fillRect(
|
258
|
+
textPos.x - textWidth / 2 - 4,
|
259
|
+
textPos.y - 8,
|
260
|
+
textWidth + 8,
|
261
|
+
16
|
262
|
+
);
|
263
|
+
ctx.globalAlpha = 1;
|
264
|
+
|
265
|
+
// Texte de la relation
|
266
|
+
ctx.textAlign = "center";
|
267
|
+
ctx.textBaseline = "middle";
|
268
|
+
ctx.fillStyle = highlightLinks.has(link) ? "#93c5fd" : "#ffffff";
|
269
|
+
ctx.fillText(label, textPos.x, textPos.y);
|
270
|
+
}}
|
271
|
+
d3AlphaDecay={0.05}
|
272
|
+
d3VelocityDecay={0.2}
|
273
|
+
/>
|
274
|
+
</div>
|
275
|
+
<div className="drawer-side">
|
276
|
+
<label htmlFor="my-drawer" className="drawer-overlay"></label>
|
277
|
+
<div className="bg-slate-900 text-white min-h-full w-80 p-6 shadow-xl">
|
278
|
+
{selectedNode ? (
|
279
|
+
<div className="space-y-6">
|
280
|
+
<h3 className="text-xl font-bold border-b border-slate-700 pb-2">
|
281
|
+
{selectedNode.name || `Node ${selectedNode.id}`}
|
282
|
+
</h3>
|
283
|
+
<div>
|
284
|
+
<h4 className="text-lg font-semibold mb-3">Connexions</h4>
|
285
|
+
<ul className="space-y-2">
|
286
|
+
{selectedNode.neighbors.map((neighbor) => (
|
287
|
+
<li
|
288
|
+
key={neighbor.id}
|
289
|
+
className="pl-2 border-l-2 border-blue-500"
|
290
|
+
>
|
291
|
+
<button
|
292
|
+
className="text-blue-400 hover:text-blue-300 transition-colors"
|
293
|
+
onClick={() => handleNodeClick(neighbor)}
|
294
|
+
>
|
295
|
+
{neighbor.name || `Node ${neighbor.id}`}
|
296
|
+
</button>
|
297
|
+
</li>
|
298
|
+
))}
|
299
|
+
</ul>
|
300
|
+
</div>
|
301
|
+
<button
|
302
|
+
className="w-full px-4 py-2 bg-slate-700 text-white rounded hover:bg-slate-600 transition-colors"
|
303
|
+
onClick={clearSelection}
|
304
|
+
>
|
305
|
+
Fermer
|
306
|
+
</button>
|
307
|
+
</div>
|
308
|
+
) : (
|
309
|
+
<p className="text-slate-400">
|
310
|
+
Sélectionnez un nœud pour voir ses détails
|
311
|
+
</p>
|
312
|
+
)}
|
313
|
+
</div>
|
314
|
+
</div>
|
315
|
+
</div>
|
316
|
+
);
|
317
|
+
};
|
318
|
+
|
319
|
+
export default function Home() {
|
320
|
+
return <HighlightGraph />;
|
321
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { dirname } from "path";
|
2
|
+
import { fileURLToPath } from "url";
|
3
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
4
|
+
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
6
|
+
const __dirname = dirname(__filename);
|
7
|
+
|
8
|
+
const compat = new FlatCompat({
|
9
|
+
baseDirectory: __dirname,
|
10
|
+
});
|
11
|
+
|
12
|
+
const eslintConfig = [
|
13
|
+
...compat.extends("next/core-web-vitals", "next/typescript"),
|
14
|
+
];
|
15
|
+
|
16
|
+
export default eslintConfig;
|