@plastichub/osr-ai-tools
Version:
CLI and library for LLM tools
125 lines (120 loc) • 5.58 kB
text/typescript
import * as path from 'path'
import { RunnableToolFunction } from 'openai/lib/RunnableFunction'
import { exec, spawn } from 'child_process'
import { promisify } from 'util'
const execAsync = promisify(exec)
import { toolLogger } from '../..'
import { IKBotTask } from '../../types'
export const tools = (target: string, options: IKBotTask): Array<any> => {
const logger = toolLogger(path.parse(__filename).name, options)
return [
{
type: 'function',
function: {
name: 'execute_command',
description: 'Execute a terminal command and capture output',
parameters: {
type: 'object',
properties: {
command: {
type: 'string',
description: 'Command to execute'
},
args: {
type: 'array',
items: { type: 'string' },
description: 'Command arguments',
optional: true
},
cwd: {
type: 'string',
description: 'Working directory for command execution',
optional: true
},
background: {
type: 'boolean',
description: 'Run command in background (non-blocking)',
optional: true
},
window: {
type: 'boolean',
description: 'Open command in new terminal window',
optional: true
},
detached: {
type: 'boolean',
description: 'Run process detached from parent',
optional: true
}
},
required: ['command']
},
function: async (params: any) => {
try {
const workingDir = params.cwd ? path.join(target, params.cwd) : target;
const args = params.args || [];
logger.debug(`Tool::Terminal : ExecuteCommand Running '${params.command}' in ${workingDir}`,params)
if (params.detached) {
const isWindows = process.platform === 'win32';
if (isWindows) {
spawn('cmd', ['/c', 'start', 'cmd', '/k', params.command, ...args], {
cwd: workingDir,
detached: true,
stdio: 'ignore'
});
} else {
// For macOS/Linux
spawn('x-terminal-emulator', ['-e', `${params.command} ${args.join(' ')}`], {
cwd: workingDir,
detached: true,
stdio: 'ignore'
});
}
return {
success: true,
output: 'Command launched in new window',
error: null
};
}
// Handle background/detached mode
if (params.background || params.detached) {
const child = spawn(params.command, args, {
cwd: workingDir,
detached: params.detached === true,
stdio: 'ignore'
});
if (params.detached) {
child.unref();
}
return {
success: true,
output: `Process started with PID: ${child.pid}`,
error: null
};
}
// Regular synchronous execution
const fullCommand = `${params.command} ${args.join(' ')}`.trim();
logger.debug(`Tool::ExecuteCommand Running '${fullCommand}' in ${workingDir}`);
const { stdout, stderr } = await execAsync(fullCommand, {
cwd: workingDir
});
logger.debug(`Tool::ExecuteCommand Output: ${stdout}`);
return {
success: !stderr,
output: stdout,
error: stderr || null
};
} catch (error: any) {
logger.error('Error executing command', error);
return {
success: false,
output: null,
error: error.message
};
}
},
parse: JSON.parse
}
} as RunnableToolFunction<any>
];
};