Governed substrate for autonomous agents: scoped identity (passports), audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
267 lines
7.1 KiB
JavaScript
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
|
|
};
|