Spaces:
Runtime error
Runtime error
coder agent
Browse files- patches/@langchain+core+1.1.47.patch +25 -0
- src/agents/coder/agent.ts +113 -8
- src/agents/coder/outputs/.gitkeep +0 -0
- src/agents/coder/prompts.ts +96 -0
- src/agents/coder/run.ts +33 -0
- src/agents/coder/state.ts +2 -0
- src/agents/coder/tools/compile-solidity.ts +50 -0
patches/@langchain+core+1.1.47.patch
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
diff --git a/node_modules/@langchain/core/dist/utils/uuid/index.cjs b/node_modules/@langchain/core/dist/utils/uuid/index.cjs
|
| 2 |
+
index 1151178..c05caf9 100644
|
| 3 |
+
--- a/node_modules/@langchain/core/dist/utils/uuid/index.cjs
|
| 4 |
+
+++ b/node_modules/@langchain/core/dist/utils/uuid/index.cjs
|
| 5 |
+
@@ -36,12 +36,12 @@ Object.defineProperty(exports, "uuid_exports", {
|
| 6 |
+
return uuid_exports;
|
| 7 |
+
}
|
| 8 |
+
});
|
| 9 |
+
-exports.v1 = require_v1;
|
| 10 |
+
-exports.v4 = require_v4;
|
| 11 |
+
-exports.v5 = require_v5;
|
| 12 |
+
-exports.v6 = require_v6;
|
| 13 |
+
-exports.v7 = require_v7;
|
| 14 |
+
-exports.validate = require_validate;
|
| 15 |
+
-exports.version = require_version;
|
| 16 |
+
+exports.v1 = require_v1.default;
|
| 17 |
+
+exports.v4 = require_v4.default;
|
| 18 |
+
+exports.v5 = require_v5.default;
|
| 19 |
+
+exports.v6 = require_v6.default;
|
| 20 |
+
+exports.v7 = require_v7.default;
|
| 21 |
+
+exports.validate = require_validate.default;
|
| 22 |
+
+exports.version = require_version.default;
|
| 23 |
+
|
| 24 |
+
//# sourceMappingURL=index.cjs.map
|
| 25 |
+
|
src/agents/coder/agent.ts
CHANGED
|
@@ -1,20 +1,125 @@
|
|
| 1 |
import { END, type GraphNode, START, StateGraph } from "@langchain/langgraph";
|
|
|
|
| 2 |
|
| 3 |
import { CoderState } from "./state.ts";
|
|
|
|
|
|
|
| 4 |
|
| 5 |
-
const
|
| 6 |
-
pragma solidity ^0.8.0;
|
| 7 |
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
};
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
export const coderAgent = new StateGraph(CoderState)
|
| 17 |
.addNode("generateContract", generateContract)
|
|
|
|
|
|
|
|
|
|
| 18 |
.addEdge(START, "generateContract")
|
| 19 |
-
.addEdge("generateContract",
|
|
|
|
|
|
|
|
|
|
| 20 |
.compile();
|
|
|
|
| 1 |
import { END, type GraphNode, START, StateGraph } from "@langchain/langgraph";
|
| 2 |
+
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
|
| 3 |
|
| 4 |
import { CoderState } from "./state.ts";
|
| 5 |
+
import { solidityCoderPrompt, solidityFixPrompt, solidityReviewPrompt } from "./prompts.ts";
|
| 6 |
+
import { compileSolidityTool } from "./tools/compile-solidity.ts";
|
| 7 |
|
| 8 |
+
const MAX_FIX_ATTEMPTS = 3;
|
|
|
|
| 9 |
|
| 10 |
+
function createLLM() {
|
| 11 |
+
return new ChatGoogleGenerativeAI({
|
| 12 |
+
apiKey: process.env.GOOGLE_API_KEY || "",
|
| 13 |
+
model: process.env.MODEL_NAME || "gemini-2.5-flash",
|
| 14 |
+
temperature: 0.2,
|
| 15 |
+
});
|
| 16 |
+
}
|
| 17 |
|
| 18 |
+
/**
|
| 19 |
+
* Extrai apenas o bloco de código Solidity de uma resposta do LLM.
|
| 20 |
+
*/
|
| 21 |
+
function extractSolidityCode(text: string): string {
|
| 22 |
+
const match = text.match(/```(?:solidity)?\s*\n([\s\S]*?)```/);
|
| 23 |
+
if (match) return match[1].trim();
|
| 24 |
+
// Se não tem bloco de código, assume que a resposta inteira é código
|
| 25 |
+
return text.trim();
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
/**
|
| 29 |
+
* Nó 1: Gera o smart contract a partir dos requisitos.
|
| 30 |
+
*/
|
| 31 |
+
const generateContract: GraphNode<typeof CoderState> = async (state) => {
|
| 32 |
+
const llm = createLLM();
|
| 33 |
+
const chain = solidityCoderPrompt.pipe(llm);
|
| 34 |
+
|
| 35 |
+
const requirementsText = state.requirements
|
| 36 |
+
.map((r, i) => `${i + 1}. ${r}`)
|
| 37 |
+
.join("\n");
|
| 38 |
+
|
| 39 |
+
const result = await chain.invoke({ requirements: requirementsText });
|
| 40 |
+
const code = extractSolidityCode(
|
| 41 |
+
typeof result.content === "string" ? result.content : JSON.stringify(result.content),
|
| 42 |
+
);
|
| 43 |
+
|
| 44 |
+
return { contract: code, compilationErrors: [] };
|
| 45 |
};
|
| 46 |
|
| 47 |
+
/**
|
| 48 |
+
* Nó 2: Compila o contrato e armazena erros (se houver).
|
| 49 |
+
*/
|
| 50 |
+
const compileContract: GraphNode<typeof CoderState> = async (state) => {
|
| 51 |
+
const result = await compileSolidityTool.invoke({
|
| 52 |
+
sourceCode: state.contract,
|
| 53 |
+
filename: "Contract.sol",
|
| 54 |
+
});
|
| 55 |
+
|
| 56 |
+
return { compilationErrors: result.errors };
|
| 57 |
+
};
|
| 58 |
+
|
| 59 |
+
/**
|
| 60 |
+
* Nó 3: Corrige o contrato com base nos erros de compilação.
|
| 61 |
+
*/
|
| 62 |
+
const fixContract: GraphNode<typeof CoderState> = async (state) => {
|
| 63 |
+
const llm = createLLM();
|
| 64 |
+
const chain = solidityFixPrompt.pipe(llm);
|
| 65 |
+
|
| 66 |
+
const errorsText = state.compilationErrors.join("\n\n");
|
| 67 |
+
|
| 68 |
+
const result = await chain.invoke({
|
| 69 |
+
contract: state.contract,
|
| 70 |
+
errors: errorsText,
|
| 71 |
+
});
|
| 72 |
+
|
| 73 |
+
const code = extractSolidityCode(
|
| 74 |
+
typeof result.content === "string" ? result.content : JSON.stringify(result.content),
|
| 75 |
+
);
|
| 76 |
+
|
| 77 |
+
return { contract: code, compilationErrors: [] };
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
/**
|
| 81 |
+
* Nó 4: Revisa o contrato compilado quanto a segurança e boas práticas.
|
| 82 |
+
*/
|
| 83 |
+
const reviewContract: GraphNode<typeof CoderState> = async (state) => {
|
| 84 |
+
const llm = createLLM();
|
| 85 |
+
const chain = solidityReviewPrompt.pipe(llm);
|
| 86 |
+
|
| 87 |
+
const requirementsText = state.requirements.join(", ");
|
| 88 |
+
|
| 89 |
+
const result = await chain.invoke({
|
| 90 |
+
requirements: requirementsText,
|
| 91 |
+
contract: state.contract,
|
| 92 |
+
});
|
| 93 |
+
|
| 94 |
+
const summary =
|
| 95 |
+
typeof result.content === "string" ? result.content : JSON.stringify(result.content);
|
| 96 |
+
|
| 97 |
+
return { reviewSummary: summary };
|
| 98 |
+
};
|
| 99 |
+
|
| 100 |
+
/**
|
| 101 |
+
* Roteador: decide se precisa corrigir ou se pode seguir para revisão.
|
| 102 |
+
* Controla o número de tentativas de correção.
|
| 103 |
+
*/
|
| 104 |
+
let fixAttempts = 0;
|
| 105 |
+
|
| 106 |
+
function shouldFix(state: { compilationErrors: string[] }): "fixContract" | "reviewContract" {
|
| 107 |
+
if (state.compilationErrors.length > 0 && fixAttempts < MAX_FIX_ATTEMPTS) {
|
| 108 |
+
fixAttempts++;
|
| 109 |
+
return "fixContract";
|
| 110 |
+
}
|
| 111 |
+
fixAttempts = 0; // reset para próxima execução
|
| 112 |
+
return "reviewContract";
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
export const coderAgent = new StateGraph(CoderState)
|
| 116 |
.addNode("generateContract", generateContract)
|
| 117 |
+
.addNode("compileContract", compileContract)
|
| 118 |
+
.addNode("fixContract", fixContract)
|
| 119 |
+
.addNode("reviewContract", reviewContract)
|
| 120 |
.addEdge(START, "generateContract")
|
| 121 |
+
.addEdge("generateContract", "compileContract")
|
| 122 |
+
.addConditionalEdges("compileContract", shouldFix)
|
| 123 |
+
.addEdge("fixContract", "compileContract")
|
| 124 |
+
.addEdge("reviewContract", END)
|
| 125 |
.compile();
|
src/agents/coder/outputs/.gitkeep
ADDED
|
File without changes
|
src/agents/coder/prompts.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Prompt para gerar smart contracts Solidity a partir de requisitos.
|
| 5 |
+
*/
|
| 6 |
+
export const solidityCoderPrompt = ChatPromptTemplate.fromMessages([
|
| 7 |
+
[
|
| 8 |
+
"system",
|
| 9 |
+
`Você é um desenvolvedor sênior especialista em smart contracts Solidity.
|
| 10 |
+
Sua função é gerar contratos Solidity completos, compiláveis e seguros.
|
| 11 |
+
|
| 12 |
+
Regras:
|
| 13 |
+
- Gere código Solidity production-ready
|
| 14 |
+
- Use pragma solidity ^0.8.20
|
| 15 |
+
- NÃO use imports externos (OpenZeppelin, etc.) — implemente tudo inline
|
| 16 |
+
- Adicione comentários NatDoc explicativos
|
| 17 |
+
- Inclua eventos para todas as operações relevantes
|
| 18 |
+
- Use modificadores de acesso customizados (ex: onlyOwner)
|
| 19 |
+
- Inclua tratamento de erros com require e mensagens claras
|
| 20 |
+
- Siga boas práticas de segurança (checks-effects-interactions, proteção contra reentrância)
|
| 21 |
+
- NÃO use placeholders como "TODO" ou "implementar depois"
|
| 22 |
+
- O contrato deve compilar sem erros com solc 0.8.20+`,
|
| 23 |
+
],
|
| 24 |
+
[
|
| 25 |
+
"human",
|
| 26 |
+
`Gere um smart contract Solidity completo com base nos seguintes requisitos:
|
| 27 |
+
|
| 28 |
+
{requirements}
|
| 29 |
+
|
| 30 |
+
Retorne APENAS o código Solidity completo, sem explicações adicionais.
|
| 31 |
+
O código deve ser auto-contido (sem imports externos).`,
|
| 32 |
+
],
|
| 33 |
+
]);
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* Prompt para corrigir erros de compilação em contratos Solidity.
|
| 37 |
+
*/
|
| 38 |
+
export const solidityFixPrompt = ChatPromptTemplate.fromMessages([
|
| 39 |
+
[
|
| 40 |
+
"system",
|
| 41 |
+
`Você é um desenvolvedor sênior especialista em smart contracts Solidity.
|
| 42 |
+
Sua função é corrigir erros de compilação em contratos Solidity.
|
| 43 |
+
|
| 44 |
+
Regras:
|
| 45 |
+
- Corrija TODOS os erros indicados
|
| 46 |
+
- Mantenha a lógica de negócio original intacta
|
| 47 |
+
- NÃO adicione imports externos
|
| 48 |
+
- O contrato deve compilar sem erros com solc 0.8.20+
|
| 49 |
+
- Retorne APENAS o código Solidity corrigido completo`,
|
| 50 |
+
],
|
| 51 |
+
[
|
| 52 |
+
"human",
|
| 53 |
+
`O seguinte contrato Solidity tem erros de compilação. Corrija-os:
|
| 54 |
+
|
| 55 |
+
**Código atual:**
|
| 56 |
+
\`\`\`solidity
|
| 57 |
+
{contract}
|
| 58 |
+
\`\`\`
|
| 59 |
+
|
| 60 |
+
**Erros de compilação:**
|
| 61 |
+
{errors}
|
| 62 |
+
|
| 63 |
+
Retorne APENAS o código Solidity corrigido completo, sem explicações.`,
|
| 64 |
+
],
|
| 65 |
+
]);
|
| 66 |
+
|
| 67 |
+
/**
|
| 68 |
+
* Prompt para revisar contratos Solidity quanto a segurança e boas práticas.
|
| 69 |
+
*/
|
| 70 |
+
export const solidityReviewPrompt = ChatPromptTemplate.fromMessages([
|
| 71 |
+
[
|
| 72 |
+
"system",
|
| 73 |
+
`Você é um auditor de segurança sênior especialista em smart contracts Solidity.
|
| 74 |
+
Analise o contrato quanto a:
|
| 75 |
+
- Vulnerabilidades de segurança (reentrância, overflow, acesso não autorizado)
|
| 76 |
+
- Aderência a boas práticas Solidity
|
| 77 |
+
- Legibilidade e manutenibilidade
|
| 78 |
+
- Potenciais problemas de gas
|
| 79 |
+
|
| 80 |
+
Seja objetivo e conciso. Responda em português brasileiro.`,
|
| 81 |
+
],
|
| 82 |
+
[
|
| 83 |
+
"human",
|
| 84 |
+
`Revise o seguinte smart contract:
|
| 85 |
+
|
| 86 |
+
**Requisitos originais:**
|
| 87 |
+
{requirements}
|
| 88 |
+
|
| 89 |
+
**Código:**
|
| 90 |
+
\`\`\`solidity
|
| 91 |
+
{contract}
|
| 92 |
+
\`\`\`
|
| 93 |
+
|
| 94 |
+
Forneça um resumo breve da revisão em 2-3 frases destacando se o contrato está seguro e funcional.`,
|
| 95 |
+
],
|
| 96 |
+
]);
|
src/agents/coder/run.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import "dotenv/config";
|
| 2 |
+
import { readFileSync, mkdirSync, writeFileSync } from "node:fs";
|
| 3 |
+
import { resolve, dirname } from "node:path";
|
| 4 |
+
import { fileURLToPath } from "node:url";
|
| 5 |
+
import { coderAgent } from "./agent.ts";
|
| 6 |
+
|
| 7 |
+
const inputPath = process.argv[2];
|
| 8 |
+
|
| 9 |
+
if (!inputPath) {
|
| 10 |
+
console.log("Uso: npx tsx src/agents/coder/run.ts <caminho-do-arquivo-de-requisitos>");
|
| 11 |
+
console.log("Exemplo: npx tsx src/agents/coder/run.ts input/requirements.md");
|
| 12 |
+
process.exit(1);
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
const requirementsText = readFileSync(resolve(inputPath), "utf-8");
|
| 16 |
+
console.log("Requisitos carregados de:", inputPath);
|
| 17 |
+
console.log("Gerando contrato...\n");
|
| 18 |
+
|
| 19 |
+
const result = await coderAgent.invoke({ requirements: [requirementsText] });
|
| 20 |
+
|
| 21 |
+
console.log("======= Contrato Gerado =======");
|
| 22 |
+
console.log(result.contract);
|
| 23 |
+
console.log("\n======= Erros de Compilação =======");
|
| 24 |
+
console.log(result.compilationErrors.length === 0 ? "Nenhum erro" : result.compilationErrors.join("\n"));
|
| 25 |
+
console.log("\n======= Revisão de Segurança =======");
|
| 26 |
+
console.log(result.reviewSummary);
|
| 27 |
+
|
| 28 |
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
| 29 |
+
const outputDir = resolve(__dirname, "outputs");
|
| 30 |
+
mkdirSync(outputDir, { recursive: true });
|
| 31 |
+
const outputPath = resolve(outputDir, "Contract.sol");
|
| 32 |
+
writeFileSync(outputPath, result.contract, "utf-8");
|
| 33 |
+
console.log("\nContrato salvo em:", outputPath);
|
src/agents/coder/state.ts
CHANGED
|
@@ -4,4 +4,6 @@ import { z } from "zod";
|
|
| 4 |
export const CoderState = new StateSchema({
|
| 5 |
requirements: z.array(z.string()).default([]),
|
| 6 |
contract: z.string().default(""),
|
|
|
|
|
|
|
| 7 |
});
|
|
|
|
| 4 |
export const CoderState = new StateSchema({
|
| 5 |
requirements: z.array(z.string()).default([]),
|
| 6 |
contract: z.string().default(""),
|
| 7 |
+
compilationErrors: z.array(z.string()).default([]),
|
| 8 |
+
reviewSummary: z.string().default(""),
|
| 9 |
});
|
src/agents/coder/tools/compile-solidity.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { tool } from "langchain";
|
| 2 |
+
import { z } from "zod";
|
| 3 |
+
import solc from "solc";
|
| 4 |
+
|
| 5 |
+
/**
|
| 6 |
+
* Tool que compila código Solidity usando solc e retorna erros/warnings.
|
| 7 |
+
*/
|
| 8 |
+
export const compileSolidityTool = tool(
|
| 9 |
+
async (input) => {
|
| 10 |
+
const compilerInput = {
|
| 11 |
+
language: "Solidity",
|
| 12 |
+
sources: {
|
| 13 |
+
[input.filename]: { content: input.sourceCode },
|
| 14 |
+
},
|
| 15 |
+
settings: {
|
| 16 |
+
outputSelection: {
|
| 17 |
+
"*": { "*": ["abi", "evm.bytecode.object"] },
|
| 18 |
+
},
|
| 19 |
+
},
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
const output = JSON.parse(solc.compile(JSON.stringify(compilerInput)));
|
| 23 |
+
|
| 24 |
+
const errors = (output.errors || [])
|
| 25 |
+
.filter((e: { severity: string }) => e.severity === "error")
|
| 26 |
+
.map((e: { formattedMessage: string }) => e.formattedMessage);
|
| 27 |
+
|
| 28 |
+
const warnings = (output.errors || [])
|
| 29 |
+
.filter((e: { severity: string }) => e.severity === "warning")
|
| 30 |
+
.map((e: { formattedMessage: string }) => e.formattedMessage);
|
| 31 |
+
|
| 32 |
+
const contracts = output.contracts?.[input.filename] || {};
|
| 33 |
+
const contractNames = Object.keys(contracts);
|
| 34 |
+
|
| 35 |
+
return {
|
| 36 |
+
success: errors.length === 0,
|
| 37 |
+
errors,
|
| 38 |
+
warnings,
|
| 39 |
+
contracts: contractNames,
|
| 40 |
+
};
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
name: "compilar_solidity",
|
| 44 |
+
description: "Compila código Solidity com solc e retorna erros, warnings e contratos encontrados.",
|
| 45 |
+
schema: z.object({
|
| 46 |
+
sourceCode: z.string().describe("Código-fonte Solidity completo"),
|
| 47 |
+
filename: z.string().default("Contract.sol").describe("Nome do arquivo .sol"),
|
| 48 |
+
}),
|
| 49 |
+
},
|
| 50 |
+
);
|