2026-01-28 19:34:39 +01:00
// retoor <retoor@molodetz.nl>
# include "tool.h"
# include "r_config.h"
# include "bash_executor.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
static struct json_object * terminal_get_description ( void ) ;
static char * terminal_execute ( tool_t * self , struct json_object * args ) ;
static void terminal_print_action ( const char * name , struct json_object * args ) ;
static struct json_object * terminal_interactive_get_description ( void ) ;
static char * terminal_interactive_execute ( tool_t * self , struct json_object * args ) ;
static const tool_vtable_t terminal_vtable = {
. get_description = terminal_get_description ,
. execute = terminal_execute ,
. print_action = terminal_print_action
} ;
static const tool_vtable_t terminal_interactive_vtable = {
. get_description = terminal_interactive_get_description ,
. execute = terminal_interactive_execute ,
. print_action = terminal_print_action
} ;
static tool_t terminal_tool = {
. vtable = & terminal_vtable ,
. name = " linux_terminal_execute "
} ;
static tool_t terminal_interactive_tool = {
. vtable = & terminal_interactive_vtable ,
. name = " linux_terminal_execute_interactive "
} ;
tool_t * tool_terminal_create ( void ) {
return & terminal_tool ;
}
tool_t * tool_terminal_interactive_create ( void ) {
return & terminal_interactive_tool ;
}
static void terminal_print_action ( const char * name , struct json_object * args ) {
if ( ! args ) {
fprintf ( stderr , " -> %s \n " , name ) ;
return ;
}
2026-01-29 06:01:05 +01:00
struct json_object * cmd , * timeout_obj ;
int timeout = 300 ;
if ( json_object_object_get_ex ( args , " timeout " , & timeout_obj ) ) {
timeout = json_object_get_int ( timeout_obj ) ;
}
2026-01-28 19:34:39 +01:00
if ( json_object_object_get_ex ( args , " command " , & cmd ) ) {
if ( strcmp ( name , " linux_terminal_execute_interactive " ) = = 0 ) {
2026-01-29 06:01:05 +01:00
fprintf ( stderr , " \033 [1m-> Running interactive (timeout %ds): \033 [0m %s \n " , timeout , json_object_get_string ( cmd ) ) ;
2026-01-28 19:34:39 +01:00
} else {
2026-01-29 06:01:05 +01:00
fprintf ( stderr , " \033 [1m-> Running command (timeout %ds): \033 [0m %s \n " , timeout , json_object_get_string ( cmd ) ) ;
2026-01-28 19:34:39 +01:00
}
}
}
static char * terminal_execute ( tool_t * self , struct json_object * args ) {
( void ) self ;
2026-01-29 06:01:05 +01:00
struct json_object * cmd_obj , * timeout_obj ;
2026-01-28 19:34:39 +01:00
if ( ! json_object_object_get_ex ( args , " command " , & cmd_obj ) ) {
return strdup ( " Error: missing 'command' argument " ) ;
}
2026-01-29 06:01:05 +01:00
int timeout = 300 ;
if ( json_object_object_get_ex ( args , " timeout " , & timeout_obj ) ) {
timeout = json_object_get_int ( timeout_obj ) ;
}
2026-01-28 19:34:39 +01:00
const char * command = json_object_get_string ( cmd_obj ) ;
2026-01-29 06:01:05 +01:00
return r_bash_execute ( command , false , timeout ) ;
2026-01-28 19:34:39 +01:00
}
static char * terminal_interactive_execute ( tool_t * self , struct json_object * args ) {
( void ) self ;
2026-01-29 06:01:05 +01:00
struct json_object * cmd_obj , * timeout_obj ;
2026-01-28 19:34:39 +01:00
if ( ! json_object_object_get_ex ( args , " command " , & cmd_obj ) ) {
return strdup ( " Error: missing 'command' argument " ) ;
}
2026-01-29 06:01:05 +01:00
int timeout = 300 ;
if ( json_object_object_get_ex ( args , " timeout " , & timeout_obj ) ) {
timeout = json_object_get_int ( timeout_obj ) ;
}
2026-01-28 19:34:39 +01:00
const char * command = json_object_get_string ( cmd_obj ) ;
2026-01-29 06:01:05 +01:00
return r_bash_execute ( command , true , timeout ) ;
2026-01-28 19:34:39 +01:00
}
static struct json_object * terminal_get_description ( void ) {
struct json_object * root = json_object_new_object ( ) ;
json_object_object_add ( root , " type " , json_object_new_string ( " function " ) ) ;
struct json_object * function = json_object_new_object ( ) ;
json_object_object_add ( function , " name " ,
json_object_new_string ( " linux_terminal_execute " ) ) ;
json_object_object_add ( function , " description " ,
2026-01-29 06:01:05 +01:00
json_object_new_string ( " Execute a linux_terminal command on user terminal with a timeout. " ) ) ;
2026-01-28 19:34:39 +01:00
struct json_object * parameters = json_object_new_object ( ) ;
json_object_object_add ( parameters , " type " , json_object_new_string ( " object " ) ) ;
struct json_object * properties = json_object_new_object ( ) ;
struct json_object * cmd = json_object_new_object ( ) ;
json_object_object_add ( cmd , " type " , json_object_new_string ( " string " ) ) ;
json_object_object_add ( cmd , " description " ,
json_object_new_string ( " Bash command to execute. " ) ) ;
json_object_object_add ( properties , " command " , cmd ) ;
2026-01-29 06:01:05 +01:00
struct json_object * timeout = json_object_new_object ( ) ;
json_object_object_add ( timeout , " type " , json_object_new_string ( " integer " ) ) ;
json_object_object_add ( timeout , " description " ,
json_object_new_string ( " Timeout in seconds (default 300). " ) ) ;
json_object_object_add ( timeout , " default " , json_object_new_int ( 300 ) ) ;
json_object_object_add ( properties , " timeout " , timeout ) ;
2026-01-28 19:34:39 +01:00
json_object_object_add ( parameters , " properties " , properties ) ;
struct json_object * required = json_object_new_array ( ) ;
json_object_array_add ( required , json_object_new_string ( " command " ) ) ;
2026-01-29 06:01:05 +01:00
json_object_array_add ( required , json_object_new_string ( " timeout " ) ) ;
2026-01-28 19:34:39 +01:00
json_object_object_add ( parameters , " required " , required ) ;
json_object_object_add ( parameters , " additionalProperties " , json_object_new_boolean ( 0 ) ) ;
json_object_object_add ( function , " parameters " , parameters ) ;
r_config_handle cfg = r_config_get_instance ( ) ;
if ( r_config_use_strict ( cfg ) ) {
json_object_object_add ( function , " strict " , json_object_new_boolean ( 1 ) ) ;
}
json_object_object_add ( root , " function " , function ) ;
return root ;
}
static struct json_object * terminal_interactive_get_description ( void ) {
struct json_object * root = json_object_new_object ( ) ;
json_object_object_add ( root , " type " , json_object_new_string ( " function " ) ) ;
struct json_object * function = json_object_new_object ( ) ;
json_object_object_add ( function , " name " ,
json_object_new_string ( " linux_terminal_execute_interactive " ) ) ;
json_object_object_add ( function , " description " ,
2026-01-29 06:01:05 +01:00
json_object_new_string ( " Executes interactive terminal for user with a timeout. You will not be able to read the result. Do not use if you need to know output. " ) ) ;
2026-01-28 19:34:39 +01:00
struct json_object * parameters = json_object_new_object ( ) ;
json_object_object_add ( parameters , " type " , json_object_new_string ( " object " ) ) ;
struct json_object * properties = json_object_new_object ( ) ;
struct json_object * cmd = json_object_new_object ( ) ;
json_object_object_add ( cmd , " type " , json_object_new_string ( " string " ) ) ;
json_object_object_add ( cmd , " description " ,
json_object_new_string ( " Executable with parameters to execute interactively. " ) ) ;
json_object_object_add ( properties , " command " , cmd ) ;
2026-01-29 06:01:05 +01:00
struct json_object * timeout = json_object_new_object ( ) ;
json_object_object_add ( timeout , " type " , json_object_new_string ( " integer " ) ) ;
json_object_object_add ( timeout , " description " ,
json_object_new_string ( " Timeout in seconds (default 300). " ) ) ;
json_object_object_add ( timeout , " default " , json_object_new_int ( 300 ) ) ;
json_object_object_add ( properties , " timeout " , timeout ) ;
2026-01-28 19:34:39 +01:00
json_object_object_add ( parameters , " properties " , properties ) ;
struct json_object * required = json_object_new_array ( ) ;
json_object_array_add ( required , json_object_new_string ( " command " ) ) ;
2026-01-29 06:01:05 +01:00
json_object_array_add ( required , json_object_new_string ( " timeout " ) ) ;
2026-01-28 19:34:39 +01:00
json_object_object_add ( parameters , " required " , required ) ;
json_object_object_add ( parameters , " additionalProperties " , json_object_new_boolean ( 0 ) ) ;
json_object_object_add ( function , " parameters " , parameters ) ;
r_config_handle cfg = r_config_get_instance ( ) ;
if ( r_config_use_strict ( cfg ) ) {
json_object_object_add ( function , " strict " , json_object_new_boolean ( 1 ) ) ;
}
json_object_object_add ( root , " function " , function ) ;
return root ;
}