Spaces:
Runtime error
Runtime error
Uanderson Silva commited on
Commit ·
32a4f79
1
Parent(s): 098ab50
integrate with coder agent
Browse files- README_GH.md +2 -0
- frontend/src/App.tsx +107 -15
- package-lock.json +169 -169
- src/agents/auditor/agent.ts +6 -4
- src/agents/auditor/model.ts +0 -13
- src/agents/auditor/prompts.ts +32 -33
- src/config/llm.ts +7 -1
- src/index.ts +7 -4
- src/server.ts +35 -14
README_GH.md
CHANGED
|
@@ -19,6 +19,8 @@ O sistema é implementado em **TypeScript** e **Node.js**, utilizando a bibliote
|
|
| 19 |
|
| 20 |
O sistema é composto por agentes especializados que colaboram entre si em diferentes etapas do processo:
|
| 21 |
|
|
|
|
|
|
|
| 22 |
1. **Exploração e análise dos requisitos**
|
| 23 |
|
| 24 |
* Processamento e compreensão dos documentos fornecidos;
|
|
|
|
| 19 |
|
| 20 |
O sistema é composto por agentes especializados que colaboram entre si em diferentes etapas do processo:
|
| 21 |
|
| 22 |
+

|
| 23 |
+
|
| 24 |
1. **Exploração e análise dos requisitos**
|
| 25 |
|
| 26 |
* Processamento e compreensão dos documentos fornecidos;
|
frontend/src/App.tsx
CHANGED
|
@@ -1,10 +1,25 @@
|
|
| 1 |
import { useState, useRef, useCallback } from "react";
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
interface AgentResult {
|
| 4 |
contract?: string;
|
| 5 |
compilationErrors?: string[];
|
| 6 |
reviewSummary?: string;
|
| 7 |
-
|
| 8 |
results?: unknown[];
|
| 9 |
}
|
| 10 |
|
|
@@ -58,8 +73,10 @@ export function App() {
|
|
| 58 |
for (const line of lines) {
|
| 59 |
if (line.startsWith("event:")) {
|
| 60 |
currentEvent = line.slice(6).trim();
|
|
|
|
| 61 |
} else if (line.startsWith("data:")) {
|
| 62 |
const data = line.slice(5).trim();
|
|
|
|
| 63 |
switch (currentEvent) {
|
| 64 |
case "log":
|
| 65 |
appendLog(data);
|
|
@@ -90,12 +107,10 @@ export function App() {
|
|
| 90 |
return (
|
| 91 |
<div style={styles.container}>
|
| 92 |
<header style={styles.header}>
|
| 93 |
-
<h1 style={styles.title}>
|
| 94 |
-
Multi-Agent: Geração, Auditoria e Teste de Smart Contracts
|
| 95 |
-
</h1>
|
| 96 |
<p style={styles.subtitle}>
|
| 97 |
-
Descreva um cenário ou requisito cuja solução seja um smart contract em Solidity.
|
| 98 |
-
|
| 99 |
</p>
|
| 100 |
</header>
|
| 101 |
|
|
@@ -103,15 +118,21 @@ export function App() {
|
|
| 103 |
<textarea
|
| 104 |
value={requirements}
|
| 105 |
onChange={(e) => setRequirements(e.target.value)}
|
| 106 |
-
placeholder={
|
|
|
|
|
|
|
| 107 |
style={styles.textarea}
|
| 108 |
rows={6}
|
| 109 |
disabled={running}
|
| 110 |
/>
|
| 111 |
-
<button
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
{running ? "Executando pipeline..." : "Executar Pipeline"}
|
| 116 |
</button>
|
| 117 |
</form>
|
|
@@ -122,7 +143,9 @@ export function App() {
|
|
| 122 |
<h2 style={styles.sectionTitle}>📋 Log de Execução</h2>
|
| 123 |
<div style={styles.logBox}>
|
| 124 |
{logs.map((log, i) => (
|
| 125 |
-
<div key={i} style={styles.logLine}>
|
|
|
|
|
|
|
| 126 |
))}
|
| 127 |
<div ref={logsEndRef} />
|
| 128 |
</div>
|
|
@@ -163,9 +186,33 @@ export function App() {
|
|
| 163 |
{auditorResult && (
|
| 164 |
<section style={styles.section}>
|
| 165 |
<h2 style={styles.sectionTitle}>🔍 Agente Auditor</h2>
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
</section>
|
| 170 |
)}
|
| 171 |
|
|
@@ -186,6 +233,19 @@ export function App() {
|
|
| 186 |
);
|
| 187 |
}
|
| 188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
const styles: Record<string, React.CSSProperties> = {
|
| 190 |
container: {
|
| 191 |
maxWidth: 900,
|
|
@@ -305,4 +365,36 @@ const styles: Record<string, React.CSSProperties> = {
|
|
| 305 |
color: "#cbd5e1",
|
| 306 |
whiteSpace: "pre-wrap",
|
| 307 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
};
|
|
|
|
| 1 |
import { useState, useRef, useCallback } from "react";
|
| 2 |
|
| 3 |
+
interface Finding {
|
| 4 |
+
title: string;
|
| 5 |
+
description: string;
|
| 6 |
+
recommendation: string;
|
| 7 |
+
severity: "high" | "medium" | "low";
|
| 8 |
+
codeSnippet: string;
|
| 9 |
+
location: string;
|
| 10 |
+
path: string;
|
| 11 |
+
judgeReview: {
|
| 12 |
+
review: string;
|
| 13 |
+
confidence: number;
|
| 14 |
+
exploitablePaths: string[];
|
| 15 |
+
};
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
interface AgentResult {
|
| 19 |
contract?: string;
|
| 20 |
compilationErrors?: string[];
|
| 21 |
reviewSummary?: string;
|
| 22 |
+
findings?: Finding[];
|
| 23 |
results?: unknown[];
|
| 24 |
}
|
| 25 |
|
|
|
|
| 73 |
for (const line of lines) {
|
| 74 |
if (line.startsWith("event:")) {
|
| 75 |
currentEvent = line.slice(6).trim();
|
| 76 |
+
console.log("event", currentEvent);
|
| 77 |
} else if (line.startsWith("data:")) {
|
| 78 |
const data = line.slice(5).trim();
|
| 79 |
+
console.log("data", data);
|
| 80 |
switch (currentEvent) {
|
| 81 |
case "log":
|
| 82 |
appendLog(data);
|
|
|
|
| 107 |
return (
|
| 108 |
<div style={styles.container}>
|
| 109 |
<header style={styles.header}>
|
| 110 |
+
<h1 style={styles.title}>Multi-Agent: Geração, Auditoria e Teste de Smart Contracts</h1>
|
|
|
|
|
|
|
| 111 |
<p style={styles.subtitle}>
|
| 112 |
+
Descreva um cenário ou requisito cuja solução seja um smart contract em Solidity. O sistema irá gerar,
|
| 113 |
+
compilar, auditar e testar o contrato automaticamente.
|
| 114 |
</p>
|
| 115 |
</header>
|
| 116 |
|
|
|
|
| 118 |
<textarea
|
| 119 |
value={requirements}
|
| 120 |
onChange={(e) => setRequirements(e.target.value)}
|
| 121 |
+
placeholder={
|
| 122 |
+
"Ex: Crie um token ERC20 com as seguintes características:\n- Nome: MeuToken, Símbolo: MTK\n- Supply inicial de 1.000.000 tokens\n- Funções de mint (apenas owner) e burn\n- Pausável pelo owner"
|
| 123 |
+
}
|
| 124 |
style={styles.textarea}
|
| 125 |
rows={6}
|
| 126 |
disabled={running}
|
| 127 |
/>
|
| 128 |
+
<button
|
| 129 |
+
type="submit"
|
| 130 |
+
disabled={running || !requirements.trim()}
|
| 131 |
+
style={{
|
| 132 |
+
...styles.button,
|
| 133 |
+
opacity: running || !requirements.trim() ? 0.5 : 1,
|
| 134 |
+
}}
|
| 135 |
+
>
|
| 136 |
{running ? "Executando pipeline..." : "Executar Pipeline"}
|
| 137 |
</button>
|
| 138 |
</form>
|
|
|
|
| 143 |
<h2 style={styles.sectionTitle}>📋 Log de Execução</h2>
|
| 144 |
<div style={styles.logBox}>
|
| 145 |
{logs.map((log, i) => (
|
| 146 |
+
<div key={i} style={styles.logLine}>
|
| 147 |
+
{log}
|
| 148 |
+
</div>
|
| 149 |
))}
|
| 150 |
<div ref={logsEndRef} />
|
| 151 |
</div>
|
|
|
|
| 186 |
{auditorResult && (
|
| 187 |
<section style={styles.section}>
|
| 188 |
<h2 style={styles.sectionTitle}>🔍 Agente Auditor</h2>
|
| 189 |
+
{auditorResult.findings && auditorResult.findings.length > 0 ? (
|
| 190 |
+
auditorResult.findings.map((f, i) => (
|
| 191 |
+
<div key={i} style={{ ...styles.findingCard, borderColor: severityColor(f.severity) }}>
|
| 192 |
+
<div style={styles.findingHeader}>
|
| 193 |
+
<span style={{ ...styles.severityBadge, background: severityColor(f.severity) }}>
|
| 194 |
+
{f.severity.toUpperCase()}
|
| 195 |
+
</span>
|
| 196 |
+
<span style={styles.findingTitle}>{f.title}</span>
|
| 197 |
+
</div>
|
| 198 |
+
<p style={styles.findingText}>{f.description}</p>
|
| 199 |
+
<p style={{ ...styles.findingText, color: "#94a3b8" }}>
|
| 200 |
+
<strong>Localização:</strong> {f.location ?? "-"}
|
| 201 |
+
</p>
|
| 202 |
+
{f.codeSnippet && <pre style={styles.code}>{f.codeSnippet}</pre>}
|
| 203 |
+
<p style={{ ...styles.findingText, color: "#94a3b8" }}>
|
| 204 |
+
<strong>Recomendação:</strong> {f.recommendation}
|
| 205 |
+
</p>
|
| 206 |
+
<p style={{ ...styles.findingText, color: "#64748b", fontSize: 12 }}>
|
| 207 |
+
Confiança: {Math.round(f.judgeReview.confidence)}% — {f.judgeReview.review}
|
| 208 |
+
</p>
|
| 209 |
+
</div>
|
| 210 |
+
))
|
| 211 |
+
) : (
|
| 212 |
+
<div style={styles.resultBox}>
|
| 213 |
+
<p style={styles.resultText}>Nenhuma vulnerabilidade encontrada.</p>
|
| 214 |
+
</div>
|
| 215 |
+
)}
|
| 216 |
</section>
|
| 217 |
)}
|
| 218 |
|
|
|
|
| 233 |
);
|
| 234 |
}
|
| 235 |
|
| 236 |
+
const severityColor = (severity: string) => {
|
| 237 |
+
switch (severity) {
|
| 238 |
+
case "high":
|
| 239 |
+
return "#ef4444";
|
| 240 |
+
case "medium":
|
| 241 |
+
return "#f97316";
|
| 242 |
+
case "low":
|
| 243 |
+
return "#eab308";
|
| 244 |
+
default:
|
| 245 |
+
return "#64748b";
|
| 246 |
+
}
|
| 247 |
+
};
|
| 248 |
+
|
| 249 |
const styles: Record<string, React.CSSProperties> = {
|
| 250 |
container: {
|
| 251 |
maxWidth: 900,
|
|
|
|
| 365 |
color: "#cbd5e1",
|
| 366 |
whiteSpace: "pre-wrap",
|
| 367 |
},
|
| 368 |
+
findingCard: {
|
| 369 |
+
background: "#1e293b",
|
| 370 |
+
border: "1px solid",
|
| 371 |
+
borderRadius: 8,
|
| 372 |
+
padding: 16,
|
| 373 |
+
marginBottom: 12,
|
| 374 |
+
},
|
| 375 |
+
findingHeader: {
|
| 376 |
+
display: "flex",
|
| 377 |
+
alignItems: "center",
|
| 378 |
+
gap: 10,
|
| 379 |
+
marginBottom: 8,
|
| 380 |
+
},
|
| 381 |
+
severityBadge: {
|
| 382 |
+
fontSize: 11,
|
| 383 |
+
fontWeight: 700,
|
| 384 |
+
color: "#fff",
|
| 385 |
+
padding: "2px 8px",
|
| 386 |
+
borderRadius: 4,
|
| 387 |
+
letterSpacing: "0.05em",
|
| 388 |
+
},
|
| 389 |
+
findingTitle: {
|
| 390 |
+
fontSize: 15,
|
| 391 |
+
fontWeight: 600,
|
| 392 |
+
color: "#f8fafc",
|
| 393 |
+
},
|
| 394 |
+
findingText: {
|
| 395 |
+
margin: "4px 0",
|
| 396 |
+
fontSize: 13,
|
| 397 |
+
lineHeight: 1.6,
|
| 398 |
+
color: "#cbd5e1",
|
| 399 |
+
},
|
| 400 |
};
|
package-lock.json
CHANGED
|
@@ -330,9 +330,9 @@
|
|
| 330 |
}
|
| 331 |
},
|
| 332 |
"node_modules/@langchain/core": {
|
| 333 |
-
"version": "1.1.
|
| 334 |
-
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.
|
| 335 |
-
"integrity": "sha512-
|
| 336 |
"license": "MIT",
|
| 337 |
"dependencies": {
|
| 338 |
"@cfworker/json-schema": "^4.0.2",
|
|
@@ -363,13 +363,13 @@
|
|
| 363 |
}
|
| 364 |
},
|
| 365 |
"node_modules/@langchain/langgraph": {
|
| 366 |
-
"version": "1.3.
|
| 367 |
-
"resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-1.3.
|
| 368 |
-
"integrity": "sha512-
|
| 369 |
"license": "MIT",
|
| 370 |
"dependencies": {
|
| 371 |
"@langchain/langgraph-checkpoint": "^1.0.2",
|
| 372 |
-
"@langchain/langgraph-sdk": "~1.9.
|
| 373 |
"@langchain/protocol": "^0.0.15",
|
| 374 |
"@standard-schema/spec": "1.1.0",
|
| 375 |
"uuid": "^10.0.0"
|
|
@@ -418,12 +418,11 @@
|
|
| 418 |
}
|
| 419 |
},
|
| 420 |
"node_modules/@langchain/langgraph-sdk": {
|
| 421 |
-
"version": "1.9.
|
| 422 |
-
"resolved": "https://registry.npmjs.org/@langchain/langgraph-sdk/-/langgraph-sdk-1.9.
|
| 423 |
-
"integrity": "sha512-
|
| 424 |
"license": "MIT",
|
| 425 |
"dependencies": {
|
| 426 |
-
"@langchain/core": "^1.1.44",
|
| 427 |
"@langchain/protocol": "^0.0.15",
|
| 428 |
"@types/json-schema": "^7.0.15",
|
| 429 |
"p-queue": "^9.0.1",
|
|
@@ -431,6 +430,7 @@
|
|
| 431 |
"uuid": "^13.0.0"
|
| 432 |
},
|
| 433 |
"peerDependencies": {
|
|
|
|
| 434 |
"react": "^18 || ^19",
|
| 435 |
"react-dom": "^18 || ^19",
|
| 436 |
"svelte": "^4.0.0 || ^5.0.0",
|
|
@@ -458,9 +458,9 @@
|
|
| 458 |
"license": "MIT"
|
| 459 |
},
|
| 460 |
"node_modules/@langchain/langgraph-sdk/node_modules/p-queue": {
|
| 461 |
-
"version": "9.
|
| 462 |
-
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.
|
| 463 |
-
"integrity": "sha512-
|
| 464 |
"license": "MIT",
|
| 465 |
"dependencies": {
|
| 466 |
"eventemitter3": "^5.0.4",
|
|
@@ -1061,6 +1061,26 @@
|
|
| 1061 |
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
| 1062 |
}
|
| 1063 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1064 |
"node_modules/assertion-error": {
|
| 1065 |
"version": "2.0.1",
|
| 1066 |
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
|
@@ -1203,41 +1223,6 @@
|
|
| 1203 |
"node": ">=8"
|
| 1204 |
}
|
| 1205 |
},
|
| 1206 |
-
"node_modules/color-convert": {
|
| 1207 |
-
"version": "2.0.1",
|
| 1208 |
-
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
| 1209 |
-
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
| 1210 |
-
"dev": true,
|
| 1211 |
-
"license": "MIT",
|
| 1212 |
-
"dependencies": {
|
| 1213 |
-
"color-name": "~1.1.4"
|
| 1214 |
-
},
|
| 1215 |
-
"engines": {
|
| 1216 |
-
"node": ">=7.0.0"
|
| 1217 |
-
}
|
| 1218 |
-
},
|
| 1219 |
-
"node_modules/color-name": {
|
| 1220 |
-
"version": "1.1.4",
|
| 1221 |
-
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
| 1222 |
-
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
| 1223 |
-
"dev": true,
|
| 1224 |
-
"license": "MIT"
|
| 1225 |
-
},
|
| 1226 |
-
"node_modules/command-exists": {
|
| 1227 |
-
"version": "1.2.9",
|
| 1228 |
-
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
|
| 1229 |
-
"integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
|
| 1230 |
-
"license": "MIT"
|
| 1231 |
-
},
|
| 1232 |
-
"node_modules/commander": {
|
| 1233 |
-
"version": "8.3.0",
|
| 1234 |
-
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
| 1235 |
-
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
| 1236 |
-
"license": "MIT",
|
| 1237 |
-
"engines": {
|
| 1238 |
-
"node": ">= 12"
|
| 1239 |
-
}
|
| 1240 |
-
},
|
| 1241 |
"node_modules/color": {
|
| 1242 |
"version": "5.0.3",
|
| 1243 |
"resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz",
|
|
@@ -1284,6 +1269,21 @@
|
|
| 1284 |
"node": ">=18"
|
| 1285 |
}
|
| 1286 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1287 |
"node_modules/convert-source-map": {
|
| 1288 |
"version": "2.0.0",
|
| 1289 |
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
|
@@ -1361,6 +1361,12 @@
|
|
| 1361 |
"node": ">= 0.4"
|
| 1362 |
}
|
| 1363 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1364 |
"node_modules/es-define-property": {
|
| 1365 |
"version": "1.0.1",
|
| 1366 |
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
|
@@ -1381,12 +1387,6 @@
|
|
| 1381 |
"node": ">= 0.4"
|
| 1382 |
}
|
| 1383 |
},
|
| 1384 |
-
"node_modules/enabled": {
|
| 1385 |
-
"version": "2.0.0",
|
| 1386 |
-
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
| 1387 |
-
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
|
| 1388 |
-
"license": "MIT"
|
| 1389 |
-
},
|
| 1390 |
"node_modules/es-module-lexer": {
|
| 1391 |
"version": "2.1.0",
|
| 1392 |
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
|
|
@@ -1460,6 +1460,12 @@
|
|
| 1460 |
}
|
| 1461 |
}
|
| 1462 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1463 |
"node_modules/fill-range": {
|
| 1464 |
"version": "7.1.1",
|
| 1465 |
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
|
@@ -1483,6 +1489,12 @@
|
|
| 1483 |
"micromatch": "^4.0.2"
|
| 1484 |
}
|
| 1485 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1486 |
"node_modules/follow-redirects": {
|
| 1487 |
"version": "1.16.0",
|
| 1488 |
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
|
@@ -1518,18 +1530,6 @@
|
|
| 1518 |
"node": ">=12"
|
| 1519 |
}
|
| 1520 |
},
|
| 1521 |
-
"node_modules/fecha": {
|
| 1522 |
-
"version": "4.2.3",
|
| 1523 |
-
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
| 1524 |
-
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
|
| 1525 |
-
"license": "MIT"
|
| 1526 |
-
},
|
| 1527 |
-
"node_modules/fn.name": {
|
| 1528 |
-
"version": "1.1.0",
|
| 1529 |
-
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
| 1530 |
-
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
|
| 1531 |
-
"license": "MIT"
|
| 1532 |
-
},
|
| 1533 |
"node_modules/fsevents": {
|
| 1534 |
"version": "2.3.3",
|
| 1535 |
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
|
@@ -1672,6 +1672,12 @@
|
|
| 1672 |
"node": ">=16.9.0"
|
| 1673 |
}
|
| 1674 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1675 |
"node_modules/is-docker": {
|
| 1676 |
"version": "2.2.1",
|
| 1677 |
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
|
@@ -1688,16 +1694,10 @@
|
|
| 1688 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 1689 |
}
|
| 1690 |
},
|
| 1691 |
-
"node_modules/inherits": {
|
| 1692 |
-
"version": "2.0.4",
|
| 1693 |
-
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
| 1694 |
-
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
| 1695 |
-
"license": "ISC"
|
| 1696 |
-
},
|
| 1697 |
"node_modules/is-network-error": {
|
| 1698 |
-
"version": "1.3.
|
| 1699 |
-
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.
|
| 1700 |
-
"integrity": "sha512-
|
| 1701 |
"license": "MIT",
|
| 1702 |
"engines": {
|
| 1703 |
"node": ">=16"
|
|
@@ -1716,6 +1716,18 @@
|
|
| 1716 |
"node": ">=0.12.0"
|
| 1717 |
}
|
| 1718 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1719 |
"node_modules/is-wsl": {
|
| 1720 |
"version": "2.2.0",
|
| 1721 |
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
|
@@ -1749,18 +1761,6 @@
|
|
| 1749 |
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
|
| 1750 |
"license": "MIT"
|
| 1751 |
},
|
| 1752 |
-
"node_modules/is-stream": {
|
| 1753 |
-
"version": "2.0.1",
|
| 1754 |
-
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
| 1755 |
-
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
| 1756 |
-
"license": "MIT",
|
| 1757 |
-
"engines": {
|
| 1758 |
-
"node": ">=8"
|
| 1759 |
-
},
|
| 1760 |
-
"funding": {
|
| 1761 |
-
"url": "https://github.com/sponsors/sindresorhus"
|
| 1762 |
-
}
|
| 1763 |
-
},
|
| 1764 |
"node_modules/js-tiktoken": {
|
| 1765 |
"version": "1.0.21",
|
| 1766 |
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
|
|
@@ -1770,6 +1770,19 @@
|
|
| 1770 |
"base64-js": "^1.5.1"
|
| 1771 |
}
|
| 1772 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1773 |
"node_modules/json-stable-stringify": {
|
| 1774 |
"version": "1.3.0",
|
| 1775 |
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz",
|
|
@@ -1823,19 +1836,6 @@
|
|
| 1823 |
"graceful-fs": "^4.1.11"
|
| 1824 |
}
|
| 1825 |
},
|
| 1826 |
-
"node_modules/json-schema-to-ts": {
|
| 1827 |
-
"version": "3.1.1",
|
| 1828 |
-
"resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
|
| 1829 |
-
"integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
|
| 1830 |
-
"license": "MIT",
|
| 1831 |
-
"dependencies": {
|
| 1832 |
-
"@babel/runtime": "^7.18.3",
|
| 1833 |
-
"ts-algebra": "^2.0.0"
|
| 1834 |
-
},
|
| 1835 |
-
"engines": {
|
| 1836 |
-
"node": ">=16"
|
| 1837 |
-
}
|
| 1838 |
-
},
|
| 1839 |
"node_modules/kuler": {
|
| 1840 |
"version": "2.0.0",
|
| 1841 |
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
|
@@ -1843,12 +1843,12 @@
|
|
| 1843 |
"license": "MIT"
|
| 1844 |
},
|
| 1845 |
"node_modules/langchain": {
|
| 1846 |
-
"version": "1.4.
|
| 1847 |
-
"resolved": "https://registry.npmjs.org/langchain/-/langchain-1.4.
|
| 1848 |
-
"integrity": "sha512-
|
| 1849 |
"license": "MIT",
|
| 1850 |
"dependencies": {
|
| 1851 |
-
"@langchain/langgraph": "^1.3.
|
| 1852 |
"@langchain/langgraph-checkpoint": "^1.0.1",
|
| 1853 |
"langsmith": ">=0.5.0 <1.0.0",
|
| 1854 |
"zod": "^3.25.76 || ^4"
|
|
@@ -1857,7 +1857,7 @@
|
|
| 1857 |
"node": ">=20"
|
| 1858 |
},
|
| 1859 |
"peerDependencies": {
|
| 1860 |
-
"@langchain/core": "^1.1.
|
| 1861 |
}
|
| 1862 |
},
|
| 1863 |
"node_modules/langsmith": {
|
|
@@ -2291,6 +2291,15 @@
|
|
| 2291 |
],
|
| 2292 |
"license": "MIT"
|
| 2293 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2294 |
"node_modules/open": {
|
| 2295 |
"version": "7.4.2",
|
| 2296 |
"resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
|
|
@@ -2308,15 +2317,6 @@
|
|
| 2308 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 2309 |
}
|
| 2310 |
},
|
| 2311 |
-
"node_modules/one-time": {
|
| 2312 |
-
"version": "1.0.0",
|
| 2313 |
-
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
| 2314 |
-
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
| 2315 |
-
"license": "MIT",
|
| 2316 |
-
"dependencies": {
|
| 2317 |
-
"fn.name": "1.x.x"
|
| 2318 |
-
}
|
| 2319 |
-
},
|
| 2320 |
"node_modules/openai": {
|
| 2321 |
"version": "6.36.0",
|
| 2322 |
"resolved": "https://registry.npmjs.org/openai/-/openai-6.36.0.tgz",
|
|
@@ -2566,6 +2566,35 @@
|
|
| 2566 |
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.18"
|
| 2567 |
}
|
| 2568 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2569 |
"node_modules/semver": {
|
| 2570 |
"version": "5.7.2",
|
| 2571 |
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
|
@@ -2616,35 +2645,6 @@
|
|
| 2616 |
"node": ">=8"
|
| 2617 |
}
|
| 2618 |
},
|
| 2619 |
-
"node_modules/safe-buffer": {
|
| 2620 |
-
"version": "5.2.1",
|
| 2621 |
-
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
| 2622 |
-
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
| 2623 |
-
"funding": [
|
| 2624 |
-
{
|
| 2625 |
-
"type": "github",
|
| 2626 |
-
"url": "https://github.com/sponsors/feross"
|
| 2627 |
-
},
|
| 2628 |
-
{
|
| 2629 |
-
"type": "patreon",
|
| 2630 |
-
"url": "https://www.patreon.com/feross"
|
| 2631 |
-
},
|
| 2632 |
-
{
|
| 2633 |
-
"type": "consulting",
|
| 2634 |
-
"url": "https://feross.org/support"
|
| 2635 |
-
}
|
| 2636 |
-
],
|
| 2637 |
-
"license": "MIT"
|
| 2638 |
-
},
|
| 2639 |
-
"node_modules/safe-stable-stringify": {
|
| 2640 |
-
"version": "2.5.0",
|
| 2641 |
-
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
| 2642 |
-
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
| 2643 |
-
"license": "MIT",
|
| 2644 |
-
"engines": {
|
| 2645 |
-
"node": ">=10"
|
| 2646 |
-
}
|
| 2647 |
-
},
|
| 2648 |
"node_modules/siginfo": {
|
| 2649 |
"version": "2.0.0",
|
| 2650 |
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
|
|
@@ -2716,6 +2716,15 @@
|
|
| 2716 |
"dev": true,
|
| 2717 |
"license": "MIT"
|
| 2718 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2719 |
"node_modules/supports-color": {
|
| 2720 |
"version": "7.2.0",
|
| 2721 |
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
|
@@ -2729,15 +2738,6 @@
|
|
| 2729 |
"node": ">=8"
|
| 2730 |
}
|
| 2731 |
},
|
| 2732 |
-
"node_modules/string_decoder": {
|
| 2733 |
-
"version": "1.3.0",
|
| 2734 |
-
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
| 2735 |
-
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
| 2736 |
-
"license": "MIT",
|
| 2737 |
-
"dependencies": {
|
| 2738 |
-
"safe-buffer": "~5.2.0"
|
| 2739 |
-
}
|
| 2740 |
-
},
|
| 2741 |
"node_modules/text-hex": {
|
| 2742 |
"version": "1.0.0",
|
| 2743 |
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
|
@@ -3087,22 +3087,6 @@
|
|
| 3087 |
"node": ">=8"
|
| 3088 |
}
|
| 3089 |
},
|
| 3090 |
-
"node_modules/yaml": {
|
| 3091 |
-
"version": "2.9.0",
|
| 3092 |
-
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
|
| 3093 |
-
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
|
| 3094 |
-
"dev": true,
|
| 3095 |
-
"license": "ISC",
|
| 3096 |
-
"bin": {
|
| 3097 |
-
"yaml": "bin.mjs"
|
| 3098 |
-
},
|
| 3099 |
-
"engines": {
|
| 3100 |
-
"node": ">= 14.6"
|
| 3101 |
-
},
|
| 3102 |
-
"funding": {
|
| 3103 |
-
"url": "https://github.com/sponsors/eemeli"
|
| 3104 |
-
}
|
| 3105 |
-
},
|
| 3106 |
"node_modules/winston": {
|
| 3107 |
"version": "3.19.0",
|
| 3108 |
"resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz",
|
|
@@ -3139,6 +3123,22 @@
|
|
| 3139 |
"node": ">= 12.0.0"
|
| 3140 |
}
|
| 3141 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3142 |
"node_modules/zod": {
|
| 3143 |
"version": "4.4.3",
|
| 3144 |
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
|
|
|
| 330 |
}
|
| 331 |
},
|
| 332 |
"node_modules/@langchain/core": {
|
| 333 |
+
"version": "1.1.48",
|
| 334 |
+
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.48.tgz",
|
| 335 |
+
"integrity": "sha512-fQU6Guyb1pwc2fEplmA8FPbKfOMAofjnyJzExevro0FxEiuGHE18Ov/ZHmT9trWCDTZRI9eW1VIc6aChxV8pAQ==",
|
| 336 |
"license": "MIT",
|
| 337 |
"dependencies": {
|
| 338 |
"@cfworker/json-schema": "^4.0.2",
|
|
|
|
| 363 |
}
|
| 364 |
},
|
| 365 |
"node_modules/@langchain/langgraph": {
|
| 366 |
+
"version": "1.3.2",
|
| 367 |
+
"resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-1.3.2.tgz",
|
| 368 |
+
"integrity": "sha512-SL7Ktsr681R7da+1b2MVOWEbaCoFJOXEJPTGOjg4JIG4C7quWbTYC8DzxhcCxte6D/8cGp0rYDBnbKLXEpNqlA==",
|
| 369 |
"license": "MIT",
|
| 370 |
"dependencies": {
|
| 371 |
"@langchain/langgraph-checkpoint": "^1.0.2",
|
| 372 |
+
"@langchain/langgraph-sdk": "~1.9.4",
|
| 373 |
"@langchain/protocol": "^0.0.15",
|
| 374 |
"@standard-schema/spec": "1.1.0",
|
| 375 |
"uuid": "^10.0.0"
|
|
|
|
| 418 |
}
|
| 419 |
},
|
| 420 |
"node_modules/@langchain/langgraph-sdk": {
|
| 421 |
+
"version": "1.9.6",
|
| 422 |
+
"resolved": "https://registry.npmjs.org/@langchain/langgraph-sdk/-/langgraph-sdk-1.9.6.tgz",
|
| 423 |
+
"integrity": "sha512-cem5LckknNULd8o4WiOpf+rv+Qxvfpf5MzXiCQb9JnEfJdCRrWsl0/qBeZRpAXMf/1Va3uDMZouTmw9odmI0Hw==",
|
| 424 |
"license": "MIT",
|
| 425 |
"dependencies": {
|
|
|
|
| 426 |
"@langchain/protocol": "^0.0.15",
|
| 427 |
"@types/json-schema": "^7.0.15",
|
| 428 |
"p-queue": "^9.0.1",
|
|
|
|
| 430 |
"uuid": "^13.0.0"
|
| 431 |
},
|
| 432 |
"peerDependencies": {
|
| 433 |
+
"@langchain/core": "^1.1.44",
|
| 434 |
"react": "^18 || ^19",
|
| 435 |
"react-dom": "^18 || ^19",
|
| 436 |
"svelte": "^4.0.0 || ^5.0.0",
|
|
|
|
| 458 |
"license": "MIT"
|
| 459 |
},
|
| 460 |
"node_modules/@langchain/langgraph-sdk/node_modules/p-queue": {
|
| 461 |
+
"version": "9.3.0",
|
| 462 |
+
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.0.tgz",
|
| 463 |
+
"integrity": "sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==",
|
| 464 |
"license": "MIT",
|
| 465 |
"dependencies": {
|
| 466 |
"eventemitter3": "^5.0.4",
|
|
|
|
| 1061 |
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
| 1062 |
}
|
| 1063 |
},
|
| 1064 |
+
"node_modules/ansi-styles/node_modules/color-convert": {
|
| 1065 |
+
"version": "2.0.1",
|
| 1066 |
+
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
| 1067 |
+
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
| 1068 |
+
"dev": true,
|
| 1069 |
+
"license": "MIT",
|
| 1070 |
+
"dependencies": {
|
| 1071 |
+
"color-name": "~1.1.4"
|
| 1072 |
+
},
|
| 1073 |
+
"engines": {
|
| 1074 |
+
"node": ">=7.0.0"
|
| 1075 |
+
}
|
| 1076 |
+
},
|
| 1077 |
+
"node_modules/ansi-styles/node_modules/color-name": {
|
| 1078 |
+
"version": "1.1.4",
|
| 1079 |
+
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
| 1080 |
+
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
| 1081 |
+
"dev": true,
|
| 1082 |
+
"license": "MIT"
|
| 1083 |
+
},
|
| 1084 |
"node_modules/assertion-error": {
|
| 1085 |
"version": "2.0.1",
|
| 1086 |
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
|
|
|
| 1223 |
"node": ">=8"
|
| 1224 |
}
|
| 1225 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1226 |
"node_modules/color": {
|
| 1227 |
"version": "5.0.3",
|
| 1228 |
"resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz",
|
|
|
|
| 1269 |
"node": ">=18"
|
| 1270 |
}
|
| 1271 |
},
|
| 1272 |
+
"node_modules/command-exists": {
|
| 1273 |
+
"version": "1.2.9",
|
| 1274 |
+
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
|
| 1275 |
+
"integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
|
| 1276 |
+
"license": "MIT"
|
| 1277 |
+
},
|
| 1278 |
+
"node_modules/commander": {
|
| 1279 |
+
"version": "8.3.0",
|
| 1280 |
+
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
| 1281 |
+
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
| 1282 |
+
"license": "MIT",
|
| 1283 |
+
"engines": {
|
| 1284 |
+
"node": ">= 12"
|
| 1285 |
+
}
|
| 1286 |
+
},
|
| 1287 |
"node_modules/convert-source-map": {
|
| 1288 |
"version": "2.0.0",
|
| 1289 |
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
|
|
|
| 1361 |
"node": ">= 0.4"
|
| 1362 |
}
|
| 1363 |
},
|
| 1364 |
+
"node_modules/enabled": {
|
| 1365 |
+
"version": "2.0.0",
|
| 1366 |
+
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
| 1367 |
+
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
|
| 1368 |
+
"license": "MIT"
|
| 1369 |
+
},
|
| 1370 |
"node_modules/es-define-property": {
|
| 1371 |
"version": "1.0.1",
|
| 1372 |
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
|
|
|
| 1387 |
"node": ">= 0.4"
|
| 1388 |
}
|
| 1389 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1390 |
"node_modules/es-module-lexer": {
|
| 1391 |
"version": "2.1.0",
|
| 1392 |
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
|
|
|
|
| 1460 |
}
|
| 1461 |
}
|
| 1462 |
},
|
| 1463 |
+
"node_modules/fecha": {
|
| 1464 |
+
"version": "4.2.3",
|
| 1465 |
+
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
| 1466 |
+
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
|
| 1467 |
+
"license": "MIT"
|
| 1468 |
+
},
|
| 1469 |
"node_modules/fill-range": {
|
| 1470 |
"version": "7.1.1",
|
| 1471 |
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
|
|
|
| 1489 |
"micromatch": "^4.0.2"
|
| 1490 |
}
|
| 1491 |
},
|
| 1492 |
+
"node_modules/fn.name": {
|
| 1493 |
+
"version": "1.1.0",
|
| 1494 |
+
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
| 1495 |
+
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
|
| 1496 |
+
"license": "MIT"
|
| 1497 |
+
},
|
| 1498 |
"node_modules/follow-redirects": {
|
| 1499 |
"version": "1.16.0",
|
| 1500 |
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
|
|
|
| 1530 |
"node": ">=12"
|
| 1531 |
}
|
| 1532 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1533 |
"node_modules/fsevents": {
|
| 1534 |
"version": "2.3.3",
|
| 1535 |
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
|
|
|
| 1672 |
"node": ">=16.9.0"
|
| 1673 |
}
|
| 1674 |
},
|
| 1675 |
+
"node_modules/inherits": {
|
| 1676 |
+
"version": "2.0.4",
|
| 1677 |
+
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
| 1678 |
+
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
| 1679 |
+
"license": "ISC"
|
| 1680 |
+
},
|
| 1681 |
"node_modules/is-docker": {
|
| 1682 |
"version": "2.2.1",
|
| 1683 |
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
|
|
|
| 1694 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 1695 |
}
|
| 1696 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1697 |
"node_modules/is-network-error": {
|
| 1698 |
+
"version": "1.3.2",
|
| 1699 |
+
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz",
|
| 1700 |
+
"integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==",
|
| 1701 |
"license": "MIT",
|
| 1702 |
"engines": {
|
| 1703 |
"node": ">=16"
|
|
|
|
| 1716 |
"node": ">=0.12.0"
|
| 1717 |
}
|
| 1718 |
},
|
| 1719 |
+
"node_modules/is-stream": {
|
| 1720 |
+
"version": "2.0.1",
|
| 1721 |
+
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
| 1722 |
+
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
| 1723 |
+
"license": "MIT",
|
| 1724 |
+
"engines": {
|
| 1725 |
+
"node": ">=8"
|
| 1726 |
+
},
|
| 1727 |
+
"funding": {
|
| 1728 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 1729 |
+
}
|
| 1730 |
+
},
|
| 1731 |
"node_modules/is-wsl": {
|
| 1732 |
"version": "2.2.0",
|
| 1733 |
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
|
|
|
| 1761 |
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
|
| 1762 |
"license": "MIT"
|
| 1763 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1764 |
"node_modules/js-tiktoken": {
|
| 1765 |
"version": "1.0.21",
|
| 1766 |
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
|
|
|
|
| 1770 |
"base64-js": "^1.5.1"
|
| 1771 |
}
|
| 1772 |
},
|
| 1773 |
+
"node_modules/json-schema-to-ts": {
|
| 1774 |
+
"version": "3.1.1",
|
| 1775 |
+
"resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
|
| 1776 |
+
"integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
|
| 1777 |
+
"license": "MIT",
|
| 1778 |
+
"dependencies": {
|
| 1779 |
+
"@babel/runtime": "^7.18.3",
|
| 1780 |
+
"ts-algebra": "^2.0.0"
|
| 1781 |
+
},
|
| 1782 |
+
"engines": {
|
| 1783 |
+
"node": ">=16"
|
| 1784 |
+
}
|
| 1785 |
+
},
|
| 1786 |
"node_modules/json-stable-stringify": {
|
| 1787 |
"version": "1.3.0",
|
| 1788 |
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz",
|
|
|
|
| 1836 |
"graceful-fs": "^4.1.11"
|
| 1837 |
}
|
| 1838 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1839 |
"node_modules/kuler": {
|
| 1840 |
"version": "2.0.0",
|
| 1841 |
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
|
|
|
| 1843 |
"license": "MIT"
|
| 1844 |
},
|
| 1845 |
"node_modules/langchain": {
|
| 1846 |
+
"version": "1.4.2",
|
| 1847 |
+
"resolved": "https://registry.npmjs.org/langchain/-/langchain-1.4.2.tgz",
|
| 1848 |
+
"integrity": "sha512-SLGipy0r4nqQD0aiUOBYLMeGFfB/QiYnMndfZ8sGN89vXDCIXbYqcE7G/4QDDX3nZsM7/emQpoScmlxEX6sDnQ==",
|
| 1849 |
"license": "MIT",
|
| 1850 |
"dependencies": {
|
| 1851 |
+
"@langchain/langgraph": "^1.3.2",
|
| 1852 |
"@langchain/langgraph-checkpoint": "^1.0.1",
|
| 1853 |
"langsmith": ">=0.5.0 <1.0.0",
|
| 1854 |
"zod": "^3.25.76 || ^4"
|
|
|
|
| 1857 |
"node": ">=20"
|
| 1858 |
},
|
| 1859 |
"peerDependencies": {
|
| 1860 |
+
"@langchain/core": "^1.1.48"
|
| 1861 |
}
|
| 1862 |
},
|
| 1863 |
"node_modules/langsmith": {
|
|
|
|
| 2291 |
],
|
| 2292 |
"license": "MIT"
|
| 2293 |
},
|
| 2294 |
+
"node_modules/one-time": {
|
| 2295 |
+
"version": "1.0.0",
|
| 2296 |
+
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
| 2297 |
+
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
| 2298 |
+
"license": "MIT",
|
| 2299 |
+
"dependencies": {
|
| 2300 |
+
"fn.name": "1.x.x"
|
| 2301 |
+
}
|
| 2302 |
+
},
|
| 2303 |
"node_modules/open": {
|
| 2304 |
"version": "7.4.2",
|
| 2305 |
"resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
|
|
|
|
| 2317 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 2318 |
}
|
| 2319 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2320 |
"node_modules/openai": {
|
| 2321 |
"version": "6.36.0",
|
| 2322 |
"resolved": "https://registry.npmjs.org/openai/-/openai-6.36.0.tgz",
|
|
|
|
| 2566 |
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.18"
|
| 2567 |
}
|
| 2568 |
},
|
| 2569 |
+
"node_modules/safe-buffer": {
|
| 2570 |
+
"version": "5.2.1",
|
| 2571 |
+
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
| 2572 |
+
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
| 2573 |
+
"funding": [
|
| 2574 |
+
{
|
| 2575 |
+
"type": "github",
|
| 2576 |
+
"url": "https://github.com/sponsors/feross"
|
| 2577 |
+
},
|
| 2578 |
+
{
|
| 2579 |
+
"type": "patreon",
|
| 2580 |
+
"url": "https://www.patreon.com/feross"
|
| 2581 |
+
},
|
| 2582 |
+
{
|
| 2583 |
+
"type": "consulting",
|
| 2584 |
+
"url": "https://feross.org/support"
|
| 2585 |
+
}
|
| 2586 |
+
],
|
| 2587 |
+
"license": "MIT"
|
| 2588 |
+
},
|
| 2589 |
+
"node_modules/safe-stable-stringify": {
|
| 2590 |
+
"version": "2.5.0",
|
| 2591 |
+
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
| 2592 |
+
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
| 2593 |
+
"license": "MIT",
|
| 2594 |
+
"engines": {
|
| 2595 |
+
"node": ">=10"
|
| 2596 |
+
}
|
| 2597 |
+
},
|
| 2598 |
"node_modules/semver": {
|
| 2599 |
"version": "5.7.2",
|
| 2600 |
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
|
|
|
| 2645 |
"node": ">=8"
|
| 2646 |
}
|
| 2647 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2648 |
"node_modules/siginfo": {
|
| 2649 |
"version": "2.0.0",
|
| 2650 |
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
|
|
|
|
| 2716 |
"dev": true,
|
| 2717 |
"license": "MIT"
|
| 2718 |
},
|
| 2719 |
+
"node_modules/string_decoder": {
|
| 2720 |
+
"version": "1.3.0",
|
| 2721 |
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
| 2722 |
+
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
| 2723 |
+
"license": "MIT",
|
| 2724 |
+
"dependencies": {
|
| 2725 |
+
"safe-buffer": "~5.2.0"
|
| 2726 |
+
}
|
| 2727 |
+
},
|
| 2728 |
"node_modules/supports-color": {
|
| 2729 |
"version": "7.2.0",
|
| 2730 |
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
|
|
|
| 2738 |
"node": ">=8"
|
| 2739 |
}
|
| 2740 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2741 |
"node_modules/text-hex": {
|
| 2742 |
"version": "1.0.0",
|
| 2743 |
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
|
|
|
| 3087 |
"node": ">=8"
|
| 3088 |
}
|
| 3089 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3090 |
"node_modules/winston": {
|
| 3091 |
"version": "3.19.0",
|
| 3092 |
"resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz",
|
|
|
|
| 3123 |
"node": ">= 12.0.0"
|
| 3124 |
}
|
| 3125 |
},
|
| 3126 |
+
"node_modules/yaml": {
|
| 3127 |
+
"version": "2.9.0",
|
| 3128 |
+
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
|
| 3129 |
+
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
|
| 3130 |
+
"dev": true,
|
| 3131 |
+
"license": "ISC",
|
| 3132 |
+
"bin": {
|
| 3133 |
+
"yaml": "bin.mjs"
|
| 3134 |
+
},
|
| 3135 |
+
"engines": {
|
| 3136 |
+
"node": ">= 14.6"
|
| 3137 |
+
},
|
| 3138 |
+
"funding": {
|
| 3139 |
+
"url": "https://github.com/sponsors/eemeli"
|
| 3140 |
+
}
|
| 3141 |
+
},
|
| 3142 |
"node_modules/zod": {
|
| 3143 |
"version": "4.4.3",
|
| 3144 |
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
src/agents/auditor/agent.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { END, type GraphNode, START, StateGraph } from "@langchain/langgraph";
|
|
| 6 |
import { z } from "zod";
|
| 7 |
|
| 8 |
import { logger } from "../../logger.ts";
|
| 9 |
-
import {
|
| 10 |
import { JUDGE_FINDINGS_PROMPT, FIND_VULNERABILITIES_PROMPT, GATHER_CONTEXT_PROMPT } from "./prompts.ts";
|
| 11 |
import { AuditorState, JudgeReviewSchema, CandidateFindingSchema } from "./state.ts";
|
| 12 |
import { analyzeSolidityFile } from "./tools/solidity-analyzer-tool.ts";
|
|
@@ -24,6 +24,8 @@ import {
|
|
| 24 |
} from "./config.ts";
|
| 25 |
import { matchLines } from "./utils.ts";
|
| 26 |
|
|
|
|
|
|
|
| 27 |
const walkDirectory = (dir: string, depth: number, solFiles: string[], docFiles: string[]) => {
|
| 28 |
if (depth > MAX_DEPTH) return;
|
| 29 |
|
|
@@ -119,7 +121,7 @@ const gatherContext: GraphNode<typeof AuditorState> = async (state) => {
|
|
| 119 |
parts.push(`### ${filePath}\n\`\`\`solidity\n${source}\n\`\`\``);
|
| 120 |
}
|
| 121 |
|
| 122 |
-
const model =
|
| 123 |
const result = await model.invoke([new SystemMessage(GATHER_CONTEXT_PROMPT), new HumanMessage(parts.join("\n\n"))]);
|
| 124 |
|
| 125 |
logger.info(`gatherContext: context built (${parts.join("\n\n").length} chars)`);
|
|
@@ -129,7 +131,7 @@ const gatherContext: GraphNode<typeof AuditorState> = async (state) => {
|
|
| 129 |
};
|
| 130 |
|
| 131 |
const findVulnerabilities: GraphNode<typeof AuditorState> = async (state) => {
|
| 132 |
-
const model =
|
| 133 |
|
| 134 |
const previousFeedback =
|
| 135 |
state.judgeReviews.length > 0
|
|
@@ -192,7 +194,7 @@ const judgeFindings: GraphNode<typeof AuditorState> = async (state) => {
|
|
| 192 |
};
|
| 193 |
}
|
| 194 |
|
| 195 |
-
const model =
|
| 196 |
|
| 197 |
logger.info(`judgeFindings: reviewing ${state.candidateFindings.length} candidate finding(s) in parallel`);
|
| 198 |
|
|
|
|
| 6 |
import { z } from "zod";
|
| 7 |
|
| 8 |
import { logger } from "../../logger.ts";
|
| 9 |
+
import { createLLM } from "../../config/llm.ts";
|
| 10 |
import { JUDGE_FINDINGS_PROMPT, FIND_VULNERABILITIES_PROMPT, GATHER_CONTEXT_PROMPT } from "./prompts.ts";
|
| 11 |
import { AuditorState, JudgeReviewSchema, CandidateFindingSchema } from "./state.ts";
|
| 12 |
import { analyzeSolidityFile } from "./tools/solidity-analyzer-tool.ts";
|
|
|
|
| 24 |
} from "./config.ts";
|
| 25 |
import { matchLines } from "./utils.ts";
|
| 26 |
|
| 27 |
+
const llm = createLLM();
|
| 28 |
+
|
| 29 |
const walkDirectory = (dir: string, depth: number, solFiles: string[], docFiles: string[]) => {
|
| 30 |
if (depth > MAX_DEPTH) return;
|
| 31 |
|
|
|
|
| 121 |
parts.push(`### ${filePath}\n\`\`\`solidity\n${source}\n\`\`\``);
|
| 122 |
}
|
| 123 |
|
| 124 |
+
const model = llm.withStructuredOutput(z.object({ context: z.string() }));
|
| 125 |
const result = await model.invoke([new SystemMessage(GATHER_CONTEXT_PROMPT), new HumanMessage(parts.join("\n\n"))]);
|
| 126 |
|
| 127 |
logger.info(`gatherContext: context built (${parts.join("\n\n").length} chars)`);
|
|
|
|
| 131 |
};
|
| 132 |
|
| 133 |
const findVulnerabilities: GraphNode<typeof AuditorState> = async (state) => {
|
| 134 |
+
const model = llm.withStructuredOutput(z.object({ findings: z.array(CandidateFindingSchema) }));
|
| 135 |
|
| 136 |
const previousFeedback =
|
| 137 |
state.judgeReviews.length > 0
|
|
|
|
| 194 |
};
|
| 195 |
}
|
| 196 |
|
| 197 |
+
const model = llm.withStructuredOutput(JudgeReviewSchema);
|
| 198 |
|
| 199 |
logger.info(`judgeFindings: reviewing ${state.candidateFindings.length} candidate finding(s) in parallel`);
|
| 200 |
|
src/agents/auditor/model.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
import { ChatAnthropic } from "@langchain/anthropic";
|
| 2 |
-
|
| 3 |
-
export const gatherContextModel = new ChatAnthropic({
|
| 4 |
-
model: "claude-haiku-4-5",
|
| 5 |
-
});
|
| 6 |
-
|
| 7 |
-
export const findVulnerabilitiesModel = new ChatAnthropic({
|
| 8 |
-
model: "claude-sonnet-4-6",
|
| 9 |
-
});
|
| 10 |
-
|
| 11 |
-
export const judgeFindingsModel = new ChatAnthropic({
|
| 12 |
-
model: "claude-sonnet-4-6",
|
| 13 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/agents/auditor/prompts.ts
CHANGED
|
@@ -1,51 +1,50 @@
|
|
| 1 |
-
|
| 2 |
-
export const GATHER_CONTEXT_PROMPT = `You are a smart contract security expert. You will receive documentation, a structural analysis, and the full source of all in-scope Solidity contracts. Produce a thorough protocol context that will guide vulnerability discovery.
|
| 3 |
|
| 4 |
-
|
| 5 |
|
| 6 |
-
## 1.
|
| 7 |
-
|
| 8 |
|
| 9 |
-
## 2.
|
| 10 |
-
|
| 11 |
|
| 12 |
-
## 3.
|
| 13 |
-
Trace
|
| 14 |
|
| 15 |
-
## 4.
|
| 16 |
-
|
| 17 |
|
| 18 |
-
## 5.
|
| 19 |
-
|
| 20 |
|
| 21 |
-
## 6.
|
| 22 |
-
|
| 23 |
|
| 24 |
-
|
| 25 |
|
| 26 |
-
export const FIND_VULNERABILITIES_PROMPT = `
|
| 27 |
|
| 28 |
-
|
| 29 |
|
| 30 |
-
- **title**:
|
| 31 |
-
- **description**:
|
| 32 |
-
- **recommendation**:
|
| 33 |
-
- **severity**:
|
| 34 |
-
- **codeSnippet**:
|
| 35 |
|
| 36 |
-
|
| 37 |
|
| 38 |
-
|
| 39 |
|
| 40 |
-
export const JUDGE_FINDINGS_PROMPT = `
|
| 41 |
|
| 42 |
-
|
| 43 |
|
| 44 |
-
- **review**:
|
| 45 |
-
- **isFalsePositive**: true
|
| 46 |
-
- **confidence**:
|
| 47 |
-
- **exploitablePaths**: Array
|
| 48 |
|
| 49 |
-
|
| 50 |
|
| 51 |
-
|
|
|
|
| 1 |
+
export const GATHER_CONTEXT_PROMPT = `Você é um especialista em segurança de smart contracts. Você receberá documentação, uma análise estrutural e o código-fonte completo de todos os contratos Solidity em escopo. Produza um contexto detalhado do protocolo que guiará a descoberta de vulnerabilidades.
|
|
|
|
| 2 |
|
| 3 |
+
Estruture sua resposta nas seguintes seções:
|
| 4 |
|
| 5 |
+
## 1. Visão Geral dos Contratos
|
| 6 |
+
Para cada contrato: seu propósito, tipo (contract/interface/library/abstract), cadeia de herança e principais dependências de outros contratos em escopo ou protocolos externos.
|
| 7 |
|
| 8 |
+
## 2. Mapa de Estado e Armazenamento
|
| 9 |
+
Liste todas as variáveis de estado relevantes entre os contratos, o que representam e quais funções as leem ou escrevem. Sinalize armazenamento compartilhado ou herdado.
|
| 10 |
|
| 11 |
+
## 3. Fluxos Principais
|
| 12 |
+
Trace os principais caminhos de execução e transições de estado de ponta a ponta entre contratos (ex.: depósito → cunhar shares → atualizar recompensas; saque → queimar shares → transferir ETH). Inclua chamadas entre contratos.
|
| 13 |
|
| 14 |
+
## 4. Invariantes
|
| 15 |
+
Condições que devem sempre ser verdadeiras (ex.: "o supply total deve ser igual à soma de todos os saldos", "o saldo de ETH do contrato ≥ soma de todos os depósitos dos usuários"). Derive-as tanto do código-fonte quanto da documentação.
|
| 16 |
|
| 17 |
+
## 5. Premissas de Design
|
| 18 |
+
O que o protocolo assume sobre chamadores, contratos externos, oráculos, chaves de administrador e comportamento de tokens (ex.: "tokens são compatíveis com ERC-20", "o admin é confiável", "sem tokens com taxa de transferência").
|
| 19 |
|
| 20 |
+
## 6. Regras de Negócio
|
| 21 |
+
Controles de acesso, estruturas de taxas, timelocks, limites, mecanismos de pausa, padrões de atualização e quaisquer outras restrições de domínio.
|
| 22 |
|
| 23 |
+
Seja preciso e exaustivo — quanto mais rico o contexto, com mais precisão as vulnerabilidades podem ser identificadas e validadas.`;
|
| 24 |
|
| 25 |
+
export const FIND_VULNERABILITIES_PROMPT = `Você é um auditor especialista em segurança de smart contracts com foco em Solidity. Analise sistematicamente o código-fonte do contrato e o contexto do protocolo para identificar vulnerabilidades de segurança.
|
| 26 |
|
| 27 |
+
Para cada vulnerabilidade, forneça TODOS os seguintes campos:
|
| 28 |
|
| 29 |
+
- **title**: Nome curto e preciso (ex.: "Reentrância em withdraw", "Controle de acesso ausente em setFee").
|
| 30 |
+
- **description**: Explique o comportamento ESPERADO versus o comportamento OBSERVADO (vulnerável) em 2 a 4 frases.
|
| 31 |
+
- **recommendation**: Correção específica e acionável (ex.: "Aplicar o padrão checks-effects-interactions", "Adicionar o modificador onlyOwner").
|
| 32 |
+
- **severity**: Um de "high" (perda direta de fundos ou tomada de controle do contrato), "medium" (risco indireto ou condicional), "low" (problema de boas práticas, sem risco financeiro imediato).
|
| 33 |
+
- **codeSnippet**: O bloco de código vulnerável exatamente como aparece no código-fonte.
|
| 34 |
|
| 35 |
+
Categorias de vulnerabilidades a verificar sistematicamente: reentrância (simples e entre funções), controle de acesso, overflow/underflow de inteiros, manipulação de oráculo, ataques de flash loan, front-running/MEV, replay de assinatura, colisões de armazenamento, proxies não inicializados, delegatecall inseguro, griefing de gas, negação de serviço, perda de precisão e violações de lógica/regras de negócio.
|
| 36 |
|
| 37 |
+
Se feedback do juiz de uma iteração anterior for fornecido, remova os falsos positivos confirmados da sua lista e refine ou expanda os achados restantes com base na crítica.`;
|
| 38 |
|
| 39 |
+
export const JUDGE_FINDINGS_PROMPT = `Você é um revisor rigoroso de segurança de smart contracts. Avalie cada vulnerabilidade candidata submetida pelo auditor e determine se é um verdadeiro positivo ou um falso positivo.
|
| 40 |
|
| 41 |
+
Para cada achado, forneça TODOS os seguintes campos:
|
| 42 |
|
| 43 |
+
- **review**: Análise detalhada (3 a 6 frases) explicando por que a vulnerabilidade é ou não real. Referencie código específico, invariantes do protocolo, pré-condições e controles mitigadores.
|
| 44 |
+
- **isFalsePositive**: true se o achado NÃO for explorável na prática; false se for uma vulnerabilidade real.
|
| 45 |
+
- **confidence**: Número inteiro de 0 a 100 refletindo sua confiança no veredicto.
|
| 46 |
+
- **exploitablePaths**: Array de strings. Se for verdadeiro positivo, forneça caminhos concretos confirmando a explorabilidade com valores reais. Cada rastreamento deve descrever os passos do atacante com entradas/valores realistas (ex.: "1. Atacante chama deposit(100 ETH) 2. Contrato do atacante no fallback chama withdraw() novamente antes da atualização do saldo 3. Atacante drena 100 ETH duas vezes"). Se for falso positivo, forneça o raciocínio que bloqueia o exploit.
|
| 47 |
|
| 48 |
+
Um achado é falso positivo somente se: o caminho de exploit for inacessível dados os controles de acesso ou pré-condições, já estiver totalmente mitigado pelo código, exigir condições impossíveis ou economicamente inviáveis, ou for explicitamente documentado como comportamento esperado nas premissas do protocolo.
|
| 49 |
|
| 50 |
+
Você deve fornecer exatamente um objeto de revisão por achado, na mesma ordem em que os achados foram apresentados.`;
|
src/config/llm.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
| 1 |
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
|
|
|
|
| 2 |
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
| 3 |
|
| 4 |
-
export type LLMProvider = "google" | "openrouter";
|
| 5 |
|
| 6 |
export function createLLM(overrideProvider?: LLMProvider): BaseChatModel {
|
| 7 |
const provider = overrideProvider || (process.env.LLM_PROVIDER as LLMProvider) || "google";
|
|
@@ -14,6 +15,11 @@ export function createLLM(overrideProvider?: LLMProvider): BaseChatModel {
|
|
| 14 |
temperature: 0.2,
|
| 15 |
}) as BaseChatModel;
|
| 16 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
case "google":
|
| 18 |
default:
|
| 19 |
return new ChatGoogleGenerativeAI({
|
|
|
|
| 1 |
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
|
| 2 |
+
import { ChatAnthropic } from "@langchain/anthropic";
|
| 3 |
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
| 4 |
|
| 5 |
+
export type LLMProvider = "google" | "openrouter" | "anthropic";
|
| 6 |
|
| 7 |
export function createLLM(overrideProvider?: LLMProvider): BaseChatModel {
|
| 8 |
const provider = overrideProvider || (process.env.LLM_PROVIDER as LLMProvider) || "google";
|
|
|
|
| 15 |
temperature: 0.2,
|
| 16 |
}) as BaseChatModel;
|
| 17 |
}
|
| 18 |
+
case "anthropic":
|
| 19 |
+
return new ChatAnthropic({
|
| 20 |
+
model: process.env.ANTHROPIC_MODEL || "claude-sonnet-4-6",
|
| 21 |
+
temperature: 0.2,
|
| 22 |
+
});
|
| 23 |
case "google":
|
| 24 |
default:
|
| 25 |
return new ChatGoogleGenerativeAI({
|
src/index.ts
CHANGED
|
@@ -27,9 +27,9 @@ console.log(coderResult.contract);
|
|
| 27 |
const __dirname = dirname(fileURLToPath(import.meta.url));
|
| 28 |
const outputDir = resolve(__dirname, "agents/coder/outputs");
|
| 29 |
mkdirSync(outputDir, { recursive: true });
|
| 30 |
-
|
| 31 |
-
writeFileSync(
|
| 32 |
-
console.log("\nContrato
|
| 33 |
|
| 34 |
console.log("\n======= Auditor =======");
|
| 35 |
logger.info("Starting auditorAgent");
|
|
@@ -37,7 +37,10 @@ logger.info("Starting auditorAgent");
|
|
| 37 |
const auditorResult = await auditorAgent.invoke({ repoPath: outputDir });
|
| 38 |
|
| 39 |
logger.info("Agent completed");
|
| 40 |
-
logger.
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
const testerResult = await testerAgent.invoke({
|
| 43 |
solidityFiles: [coderResult.contract],
|
|
|
|
| 27 |
const __dirname = dirname(fileURLToPath(import.meta.url));
|
| 28 |
const outputDir = resolve(__dirname, "agents/coder/outputs");
|
| 29 |
mkdirSync(outputDir, { recursive: true });
|
| 30 |
+
writeFileSync(resolve(outputDir, "Contract.sol"), coderResult.contract, "utf-8");
|
| 31 |
+
writeFileSync(resolve(outputDir, "README.md"), requirementsText, "utf-8");
|
| 32 |
+
console.log("\nContrato e requisitos salvos em:", outputDir);
|
| 33 |
|
| 34 |
console.log("\n======= Auditor =======");
|
| 35 |
logger.info("Starting auditorAgent");
|
|
|
|
| 37 |
const auditorResult = await auditorAgent.invoke({ repoPath: outputDir });
|
| 38 |
|
| 39 |
logger.info("Agent completed");
|
| 40 |
+
logger.info(`Findings: ${auditorResult.findings.length}`);
|
| 41 |
+
for (const f of auditorResult.findings) {
|
| 42 |
+
logger.info(` [${f.severity.toUpperCase()}] ${f.title} — ${f.location}`);
|
| 43 |
+
}
|
| 44 |
|
| 45 |
const testerResult = await testerAgent.invoke({
|
| 46 |
solidityFiles: [coderResult.contract],
|
src/server.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
| 1 |
import "dotenv/config";
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import { serve } from "@hono/node-server";
|
| 3 |
import { Hono } from "hono";
|
| 4 |
import { cors } from "hono/cors";
|
|
@@ -42,32 +46,49 @@ app.post("/api/run", (c) => {
|
|
| 42 |
await send("log", "[Coder] Contrato compilado sem erros.");
|
| 43 |
}
|
| 44 |
|
| 45 |
-
await send(
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
// === AUDITOR ===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
await send("log", "[Auditor] Iniciando auditoria de segurança...");
|
| 53 |
-
const auditorResult = await auditorAgent.invoke({
|
| 54 |
-
await send("log", `[Auditor] ${auditorResult.
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
-
await send(
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
// === TESTER ===
|
| 61 |
await send("log", "[Tester] Gerando testes de prova de conceito...");
|
| 62 |
const testerResult = await testerAgent.invoke({
|
| 63 |
solidityFiles: [coderResult.contract],
|
| 64 |
-
vulnerability: auditorResult.
|
| 65 |
});
|
| 66 |
await send("log", `[Tester] ${testerResult.results.length} resultado(s) de teste.`);
|
| 67 |
|
| 68 |
-
await send(
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
await send("log", "Pipeline concluído.");
|
| 73 |
await send("done", "ok");
|
|
|
|
| 1 |
import "dotenv/config";
|
| 2 |
+
|
| 3 |
+
import { mkdirSync, writeFileSync } from "node:fs";
|
| 4 |
+
import { resolve } from "node:path";
|
| 5 |
+
import { tmpdir } from "node:os";
|
| 6 |
import { serve } from "@hono/node-server";
|
| 7 |
import { Hono } from "hono";
|
| 8 |
import { cors } from "hono/cors";
|
|
|
|
| 46 |
await send("log", "[Coder] Contrato compilado sem erros.");
|
| 47 |
}
|
| 48 |
|
| 49 |
+
await send(
|
| 50 |
+
"coder",
|
| 51 |
+
JSON.stringify({
|
| 52 |
+
contract: coderResult.contract,
|
| 53 |
+
compilationErrors: coderResult.compilationErrors,
|
| 54 |
+
reviewSummary: coderResult.reviewSummary,
|
| 55 |
+
}),
|
| 56 |
+
);
|
| 57 |
|
| 58 |
// === AUDITOR ===
|
| 59 |
+
const outputDir = resolve(tmpdir(), `talp1-${Date.now()}`);
|
| 60 |
+
mkdirSync(outputDir, { recursive: true });
|
| 61 |
+
writeFileSync(resolve(outputDir, "Contract.sol"), coderResult.contract, "utf-8");
|
| 62 |
+
writeFileSync(resolve(outputDir, "README.md"), requirements, "utf-8");
|
| 63 |
+
|
| 64 |
await send("log", "[Auditor] Iniciando auditoria de segurança...");
|
| 65 |
+
const auditorResult = await auditorAgent.invoke({ repoPath: outputDir });
|
| 66 |
+
await send("log", `[Auditor] ${auditorResult.findings.length} vulnerabilidade(s) encontrada(s).`);
|
| 67 |
+
for (const f of auditorResult.findings) {
|
| 68 |
+
await send("log", `[Auditor] [${f.severity.toUpperCase()}] ${f.title} — ${f.location}`);
|
| 69 |
+
}
|
| 70 |
|
| 71 |
+
await send(
|
| 72 |
+
"auditor",
|
| 73 |
+
JSON.stringify({
|
| 74 |
+
findings: auditorResult.findings,
|
| 75 |
+
}),
|
| 76 |
+
);
|
| 77 |
|
| 78 |
// === TESTER ===
|
| 79 |
await send("log", "[Tester] Gerando testes de prova de conceito...");
|
| 80 |
const testerResult = await testerAgent.invoke({
|
| 81 |
solidityFiles: [coderResult.contract],
|
| 82 |
+
vulnerability: auditorResult.findings[0] ?? {},
|
| 83 |
});
|
| 84 |
await send("log", `[Tester] ${testerResult.results.length} resultado(s) de teste.`);
|
| 85 |
|
| 86 |
+
await send(
|
| 87 |
+
"tester",
|
| 88 |
+
JSON.stringify({
|
| 89 |
+
results: testerResult.results,
|
| 90 |
+
}),
|
| 91 |
+
);
|
| 92 |
|
| 93 |
await send("log", "Pipeline concluído.");
|
| 94 |
await send("done", "ok");
|