godcrm/backend/services/CodeToolsService.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

267 lines
7.1 KiB
JavaScript

/**
* Code Tools Service
* ADR-032: Code Execution Engine — Judge0 + Agent Loop
*
* Provides AI Agent tools for code execution:
* - run_code: Execute code synchronously
* - validate_code: Validate syntax without execution
* - run_code_loop: Execute with Agent callback
*/
import { aiLogger } from '../utils/logger.js';
const CODE_API_URL = process.env.BACKEND_URL || 'http://localhost:5001';
/**
* Supported programming languages
*/
const SUPPORTED_LANGUAGES = [
'python', 'javascript', 'typescript', 'cpp', 'java',
'go', 'rust', 'ruby', 'php', 'csharp', 'bash', 'sql',
'kotlin', 'swift', 'r', 'perl', 'lua'
];
/**
* run_code Tool Definition
* Executes code synchronously and returns result
*/
export const runCodeTool = {
name: 'run_code',
type: 'function',
function: {
name: 'run_code',
description: `Execute code in various programming languages.
Supported languages: ${SUPPORTED_LANGUAGES.join(', ')}.
Returns stdout, stderr, execution time and memory usage.
Use for quick calculations, data processing, or testing code snippets.`,
parameters: {
type: 'object',
properties: {
source_code: {
type: 'string',
description: 'Source code to execute'
},
language: {
type: 'string',
enum: SUPPORTED_LANGUAGES,
description: 'Programming language (default: python)'
},
stdin: {
type: 'string',
description: 'Input data for the program (optional)'
},
timeout: {
type: 'number',
description: 'Timeout in seconds (default: 5, max: 30)'
}
},
required: ['source_code']
}
},
async execute({ source_code, language = 'python', stdin = '', timeout = 5 }) {
try {
aiLogger.debug({ language, codeLength: source_code?.length }, 'Executing code via run_code tool');
const response = await fetch(`${CODE_API_URL}/api/v3/code/execute`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ source_code, language, stdin, timeout })
});
const result = await response.json();
aiLogger.debug({
success: result.success,
time: result.time
}, 'Code execution completed');
return result;
} catch (err) {
aiLogger.error({ err: err.message }, 'run_code tool failed');
return {
success: false,
error: err.message,
stdout: '',
stderr: `Tool execution error: ${err.message}`
};
}
}
};
/**
* validate_code Tool Definition
* Validates code syntax without execution
*/
export const validateCodeTool = {
name: 'validate_code',
type: 'function',
function: {
name: 'validate_code',
description: `Validate code syntax without executing it.
Fast check for syntax errors before running.
Works best with Python (uses AST parser).`,
parameters: {
type: 'object',
properties: {
source_code: {
type: 'string',
description: 'Source code to validate'
},
language: {
type: 'string',
description: 'Programming language (default: python)'
}
},
required: ['source_code']
}
},
async execute({ source_code, language = 'python' }) {
try {
aiLogger.debug({ language }, 'Validating code syntax');
const response = await fetch(`${CODE_API_URL}/api/v3/code/validate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ source_code, language })
});
return response.json();
} catch (err) {
aiLogger.error({ err: err.message }, 'validate_code tool failed');
return {
valid: false,
errors: [{ message: `Validation error: ${err.message}` }]
};
}
}
};
/**
* run_code_loop Tool Definition
* Executes code with automatic Agent callback for iterative workflows
*/
export const runCodeLoopTool = {
name: 'run_code_loop',
type: 'function',
function: {
name: 'run_code_loop',
description: `Execute code and automatically continue the conversation with the result.
Use for iterative tasks: debugging, experiments, step-by-step calculations.
The result will be analyzed automatically and the conversation will continue.`,
parameters: {
type: 'object',
properties: {
source_code: {
type: 'string',
description: 'Source code to execute'
},
language: {
type: 'string',
description: 'Programming language (default: python)'
},
stdin: {
type: 'string',
description: 'Input data for the program'
},
next_prompt: {
type: 'string',
description: 'What to do after execution (e.g., "Analyze the result and optimize")'
}
},
required: ['source_code']
}
},
async execute({ source_code, language = 'python', stdin = '', next_prompt = '' }, context = {}) {
try {
const { conversationId, agentId } = context;
aiLogger.debug({
language,
conversationId,
hasNextPrompt: !!next_prompt
}, 'Submitting code for loop execution');
const response = await fetch(`${CODE_API_URL}/api/v3/code/execute-loop`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
source_code,
language,
stdin,
conversation_id: conversationId,
agent_id: agentId,
next_prompt
})
});
const result = await response.json();
return {
status: result.status || 'executing',
token: result.token,
message: result.message || 'Code is executing, result will be processed automatically'
};
} catch (err) {
aiLogger.error({ err: err.message }, 'run_code_loop tool failed');
return {
status: 'error',
error: err.message,
message: `Failed to submit code: ${err.message}`
};
}
}
};
/**
* All Code Tools for AI Agent
* Export as array for easy integration with AGENT_TOOLS
*/
export const CODE_TOOLS = [
{
type: 'function',
function: runCodeTool.function
},
{
type: 'function',
function: validateCodeTool.function
},
{
type: 'function',
function: runCodeLoopTool.function
}
];
/**
* Execute a code tool by name
* @param {string} toolName - Tool name (run_code, validate_code, run_code_loop)
* @param {object} params - Tool parameters
* @param {object} context - Agent context (conversationId, agentId)
*/
export async function executeCodeTool(toolName, params, context = {}) {
const tools = {
run_code: runCodeTool,
validate_code: validateCodeTool,
run_code_loop: runCodeLoopTool
};
const tool = tools[toolName];
if (!tool) {
return {
success: false,
error: `Unknown tool: ${toolName}`
};
}
return tool.execute(params, context);
}
export default {
CODE_TOOLS,
runCodeTool,
validateCodeTool,
runCodeLoopTool,
executeCodeTool
};