1
1
import { Tool } from "../../core/types.js" ;
2
2
import { z } from "zod" ;
3
3
import { zodToJsonSchema } from "zod-to-json-schema" ;
4
+ import { processStates } from "./shellStart.js" ;
4
5
5
6
// Define valid NodeJS signals as a union type
6
7
type NodeSignals =
7
- | ' SIGABRT'
8
- | ' SIGALRM'
9
- | ' SIGBUS'
10
- | ' SIGCHLD'
11
- | ' SIGCONT'
12
- | ' SIGFPE'
13
- | ' SIGHUP'
14
- | ' SIGILL'
15
- | ' SIGINT'
16
- | ' SIGIO'
17
- | ' SIGIOT'
18
- | ' SIGKILL'
19
- | ' SIGPIPE'
20
- | ' SIGPOLL'
21
- | ' SIGPROF'
22
- | ' SIGPWR'
23
- | ' SIGQUIT'
24
- | ' SIGSEGV'
25
- | ' SIGSTKFLT'
26
- | ' SIGSTOP'
27
- | ' SIGSYS'
28
- | ' SIGTERM'
29
- | ' SIGTRAP'
30
- | ' SIGTSTP'
31
- | ' SIGTTIN'
32
- | ' SIGTTOU'
33
- | ' SIGUNUSED'
34
- | ' SIGURG'
35
- | ' SIGUSR1'
36
- | ' SIGUSR2'
37
- | ' SIGVTALRM'
38
- | ' SIGWINCH'
39
- | ' SIGXCPU'
40
- | ' SIGXFSZ' ;
8
+ | " SIGABRT"
9
+ | " SIGALRM"
10
+ | " SIGBUS"
11
+ | " SIGCHLD"
12
+ | " SIGCONT"
13
+ | " SIGFPE"
14
+ | " SIGHUP"
15
+ | " SIGILL"
16
+ | " SIGINT"
17
+ | " SIGIO"
18
+ | " SIGIOT"
19
+ | " SIGKILL"
20
+ | " SIGPIPE"
21
+ | " SIGPOLL"
22
+ | " SIGPROF"
23
+ | " SIGPWR"
24
+ | " SIGQUIT"
25
+ | " SIGSEGV"
26
+ | " SIGSTKFLT"
27
+ | " SIGSTOP"
28
+ | " SIGSYS"
29
+ | " SIGTERM"
30
+ | " SIGTRAP"
31
+ | " SIGTSTP"
32
+ | " SIGTTIN"
33
+ | " SIGTTOU"
34
+ | " SIGUNUSED"
35
+ | " SIGURG"
36
+ | " SIGUSR1"
37
+ | " SIGUSR2"
38
+ | " SIGVTALRM"
39
+ | " SIGWINCH"
40
+ | " SIGXCPU"
41
+ | " SIGXFSZ" ;
41
42
42
43
const parameterSchema = z . object ( {
43
44
instanceId : z . string ( ) . describe ( "The ID returned by shellStart" ) ,
44
45
stdin : z . string ( ) . optional ( ) . describe ( "Input to send to process" ) ,
45
- signal : z . enum ( [
46
- 'SIGABRT' , 'SIGALRM' , 'SIGBUS' , 'SIGCHLD' , 'SIGCONT' ,
47
- 'SIGFPE' , 'SIGHUP' , 'SIGILL' , 'SIGINT' , 'SIGIO' ,
48
- 'SIGIOT' , 'SIGKILL' , 'SIGPIPE' , 'SIGPOLL' , 'SIGPROF' ,
49
- 'SIGPWR' , 'SIGQUIT' , 'SIGSEGV' , 'SIGSTKFLT' , 'SIGSTOP' ,
50
- 'SIGSYS' , 'SIGTERM' , 'SIGTRAP' , 'SIGTSTP' , 'SIGTTIN' ,
51
- 'SIGTTOU' , 'SIGUNUSED' , 'SIGURG' , 'SIGUSR1' , 'SIGUSR2' ,
52
- 'SIGVTALRM' , 'SIGWINCH' , 'SIGXCPU' , 'SIGXFSZ'
53
- ] as const ) . optional ( ) . describe ( "Signal to send to the process (e.g., SIGTERM, SIGINT)" ) ,
46
+ signal : z
47
+ . enum ( [
48
+ "SIGABRT" ,
49
+ "SIGALRM" ,
50
+ "SIGBUS" ,
51
+ "SIGCHLD" ,
52
+ "SIGCONT" ,
53
+ "SIGFPE" ,
54
+ "SIGHUP" ,
55
+ "SIGILL" ,
56
+ "SIGINT" ,
57
+ "SIGIO" ,
58
+ "SIGIOT" ,
59
+ "SIGKILL" ,
60
+ "SIGPIPE" ,
61
+ "SIGPOLL" ,
62
+ "SIGPROF" ,
63
+ "SIGPWR" ,
64
+ "SIGQUIT" ,
65
+ "SIGSEGV" ,
66
+ "SIGSTKFLT" ,
67
+ "SIGSTOP" ,
68
+ "SIGSYS" ,
69
+ "SIGTERM" ,
70
+ "SIGTRAP" ,
71
+ "SIGTSTP" ,
72
+ "SIGTTIN" ,
73
+ "SIGTTOU" ,
74
+ "SIGUNUSED" ,
75
+ "SIGURG" ,
76
+ "SIGUSR1" ,
77
+ "SIGUSR2" ,
78
+ "SIGVTALRM" ,
79
+ "SIGWINCH" ,
80
+ "SIGXCPU" ,
81
+ "SIGXFSZ" ,
82
+ ] as const )
83
+ . optional ( )
84
+ . describe ( "Signal to send to the process (e.g., SIGTERM, SIGINT)" ) ,
54
85
description : z
55
86
. string ( )
56
87
. max ( 80 )
@@ -79,60 +110,53 @@ export const shellMessageTool: Tool<Parameters, ReturnType> = {
79
110
parameters : zodToJsonSchema ( parameterSchema ) ,
80
111
returns : zodToJsonSchema ( returnSchema ) ,
81
112
82
- execute : async ( { instanceId, stdin, signal } , { logger } ) : Promise < ReturnType > => {
113
+ execute : async (
114
+ { instanceId, stdin, signal } ,
115
+ { logger }
116
+ ) : Promise < ReturnType > => {
83
117
logger . verbose (
84
118
`Interacting with shell process ${ instanceId } ${ stdin ? " with input" : "" } ${ signal ? ` with signal ${ signal } ` : "" } `
85
119
) ;
86
120
87
121
try {
88
- const process = global . startedProcesses . get ( instanceId ) ;
89
- if ( ! process ) {
90
- throw new Error ( `No process found with ID ${ instanceId } ` ) ;
91
- }
92
-
93
- const processOutput = global . processOutputs . get ( instanceId ) ;
94
- if ( ! processOutput ) {
95
- throw new Error ( `No output buffers found for process ${ instanceId } ` ) ;
96
- }
97
-
98
- const processState = global . processState . get ( instanceId ) ;
122
+ const processState = processStates . get ( instanceId ) ;
99
123
if ( ! processState ) {
100
- throw new Error ( `No state information found for process ${ instanceId } ` ) ;
124
+ throw new Error ( `No process found with ID ${ instanceId } ` ) ;
101
125
}
102
126
103
127
// Send signal if provided
104
128
if ( signal ) {
105
- const wasKilled = process . kill ( signal ) ;
129
+ const wasKilled = processState . process . kill ( signal ) ;
106
130
if ( ! wasKilled ) {
107
131
return {
108
132
stdout : "" ,
109
133
stderr : "" ,
110
- completed : processState . completed ,
134
+ completed : processState . state . completed ,
111
135
signaled : false ,
112
- error : `Failed to send signal ${ signal } to process (process may have already terminated)`
136
+ error : `Failed to send signal ${ signal } to process (process may have already terminated)` ,
113
137
} ;
114
138
}
115
- processState . signaled = true ;
139
+ processState . state . signaled = true ;
116
140
}
117
141
118
142
// Send input if provided
119
143
if ( stdin ) {
120
- if ( ! process . stdin ?. writable ) {
144
+ if ( ! processState . process . stdin ?. writable ) {
121
145
throw new Error ( "Process stdin is not available" ) ;
122
146
}
123
- process . stdin . write ( `${ stdin } \n` ) ;
147
+ processState . process . stdin . write ( `${ stdin } \n` ) ;
124
148
}
125
149
126
150
// Wait a brief moment for output to be processed
127
151
await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
128
152
129
153
// Get accumulated output
130
- const stdout = processOutput . stdout . join ( "" ) ;
131
- const stderr = processOutput . stderr . join ( "" ) ;
154
+ const stdout = processState . stdout . join ( "" ) ;
155
+ const stderr = processState . stderr . join ( "" ) ;
132
156
133
157
// Clear the buffers
134
- processOutput . stdout = [ ] ;
135
- processOutput . stderr = [ ] ;
158
+ processState . stdout = [ ] ;
159
+ processState . stderr = [ ] ;
136
160
137
161
logger . verbose ( "Interaction completed successfully" ) ;
138
162
if ( stdout ) {
@@ -145,8 +169,8 @@ export const shellMessageTool: Tool<Parameters, ReturnType> = {
145
169
return {
146
170
stdout : stdout . trim ( ) ,
147
171
stderr : stderr . trim ( ) ,
148
- completed : processState . completed ,
149
- signaled : processState . signaled ,
172
+ completed : processState . state . completed ,
173
+ signaled : processState . state . signaled ,
150
174
} ;
151
175
} catch ( error ) {
152
176
if ( error instanceof Error ) {
0 commit comments