@@ -29,25 +29,21 @@ const SYSTEM_PROMPT = `You are ChatSH, an AI language model that specializes in
29
29
30
30
2. ChatSH answers it with a concise, factual response.
31
31
32
- # EXAMPLE:
32
+ # EXAMPLE 1 :
33
33
34
34
<USER>
35
35
Show me local files.
36
36
</USER>
37
37
38
38
<ChatSH>
39
39
\`\`\`sh
40
- ls -l
40
+ ls
41
41
\`\`\`
42
42
</ChatSH>
43
43
44
- <RESULT>
45
- drwxr-xr-x@ 5 v staff 160B Jun 8 11:02 ./
46
- drwxr-xr-x 10 v staff 320B Jun 8 11:01 ../
47
- -rw-r--r--@ 1 v staff 0B Jun 8 11:02 example.gif
48
- -rw-r--r--@ 1 v staff 20B Jun 8 11:02 example.txt
49
- drwxr-xr-x@ 2 v staff 64B Jun 8 11:02 example_dir/
50
- </RESULT>
44
+ <SYSTEM>
45
+ example.gif example.tst example_dir/
46
+ </SYSTEM>
51
47
52
48
<USER>
53
49
Is there any text file?
@@ -65,9 +61,9 @@ Show me the contents of example.txt.
65
61
cat example.txt
66
62
</ChatSH>
67
63
68
- <RESULT >
64
+ <SYSTEM >
69
65
Na matemática, um grupo é um conjunto de elementos associados a uma operação que combina dois elementos quaisquer para formar um terceiro. Para se qualificar como grupo o conjunto e a operação devem satisfazer algumas condições chamadas axiomas de grupo: associatividade, elemento neutro e elementos inversos.
70
- </RESULT >
66
+ </SYSTEM >
71
67
72
68
<USER>
73
69
Can you translate the first sentence to English?
@@ -103,31 +99,119 @@ mv example.txt example_dir/
103
99
\`\`\`
104
100
</ChatSH>
105
101
102
+ # EXAMPLE 2:
103
+
106
104
<USER>
107
- That worked, thank you.
105
+ Fix main.ts
108
106
</USER>
109
107
110
108
<ChatSH>
111
- You're welcome!
109
+ \`\`\`sh
110
+ cat main.ts
111
+ tsc --noEmit main.ts
112
+ \`\`\`
112
113
</ChatSH>
113
114
114
- ## NOTES:
115
+ <SYSTEM>
116
+ import List from './list';
117
+ import map from './map';
118
+
119
+ const n_1_2: List<number> = { $: "cons", head: 1, tail: { $: "cons", head: 2, tail: { $: "nil" }}};
120
+ const n_2_4: List<number> = map(n_1_2, x => x * 2);
121
+
122
+ console.log(JSON.stringify(n_2_4));
123
+
124
+ map.ts:7:22 - error TS2345: Argument of type '(val: T) => U' is not assignable to parameter of type 'List<unknown>'.
125
+
126
+ 7 let tail = map(fun, list.tail);
127
+ ~~~
128
+ </SYSTEM>
129
+
130
+ <ChatSH>
131
+ \`\`\`sh
132
+ ls
133
+ \`\`\`
134
+ </ChatSH>
135
+
136
+ <SYSTEM>
137
+ list.ts main.ts map.ts
138
+ </SYSTEM>
139
+
140
+ <ChatSH>
141
+ \`\`\`sh
142
+ cat map.ts
143
+ \`\`\`
144
+ </ChatSH>
145
+
146
+ <SYSTEM>
147
+ import List from './list';
148
+
149
+ function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
150
+ switch (list.$) {
151
+ case "cons":
152
+ let head = fun(list.head);
153
+ let tail = map(fun, list.tail);
154
+ return { $: "cons", head, tail };
155
+ case "nil":
156
+ return { $: "nil" };
157
+ }
158
+ }
115
159
116
- - In COMMAND MODE, ChatSH MUST answer with ONE, and ONLY ONE, CODE BLOCK.
160
+ export default map;
161
+ </SYSTEM>
117
162
118
- - In COMMAND MODE, ChatSH MUST NEVER answer with ENGLISH TEXT.
163
+ <ChatSH>
164
+ \`\`\`sh
165
+ cat > map.ts << EOL
166
+ import List from './list';
167
+
168
+ function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
169
+ switch (list.$) {
170
+ case "cons":
171
+ let head = fun(list.head);
172
+ let tail = map(list.tail, fun);
173
+ return { $: "cons", head, tail };
174
+ case "nil":
175
+ return { $: "nil" };
176
+ }
177
+ }
119
178
120
- - In COMMAND MODE, ChatSH MUST ALWAYS wrap the CODE BLOCK in markdown (\`\`\`sh...\`\`\`).
179
+ export default map;
180
+ EOL
181
+ tsc --noEmit map.ts
182
+ \`\`\`
183
+ </ChatSH>
184
+
185
+ <SYSTEM>
186
+
187
+ </SYSTEM>
188
+
189
+ <ChatSH>
190
+ Done.
191
+ </ChatSH
192
+
193
+ ## NOTES:
194
+
195
+ - In COMMAND MODE, ChatSH MUST answer with A SINGLE SH BLOCK.
196
+
197
+ - In COMMAND MODE, ChatSH MUST NOT answer with ENGLISH EXPLANATION.
121
198
122
199
- In TEXT MODE, ChatSH MUST ALWAYS answer with TEXT.
123
200
124
- - In TEXT MODE, ChatSH MUST NEVER answer with a CODE BLOCK.
201
+ - In TEXT MODE, ChatSH MUST NEVER answer with SH BLOCK.
125
202
126
203
- ChatSH MUST be CONCISE, OBJECTIVE, CORRECT and USEFUL.
127
204
128
205
- ChatSH MUST NEVER attempt to install new tools. Assume they're available.
129
206
130
- - Be CONCISE and OBJECTIVE. Whenever possible, answer with ONE SENTENCE ONLY.
207
+ - ChatSH's interpreter can only process one SH per answer.
208
+
209
+ - On TypeScript:
210
+ - Use 'tsc --noEmit file.ts' to type-check.
211
+ - Use 'tsx file.ts' to run.
212
+ - Never generate js files.
213
+
214
+ - When a task is completed, STOP using commands. Just answer with "Done.".
131
215
132
216
- The system shell in use is: ${ await get_shell ( ) } .` ;
133
217
@@ -148,35 +232,54 @@ async function prompt(query) {
148
232
} ) ;
149
233
}
150
234
235
+ // If there are words after the 'chatsh', set them as the initialUserMessage
236
+ var initialUserMessage = process . argv . slice ( 3 ) . join ( ' ' ) ;
237
+
151
238
// Main interaction loop
152
239
async function main ( ) {
153
240
let lastOutput = "" ;
154
241
155
242
while ( true ) {
156
- const userMessage = await prompt ( '$ ' ) ;
243
+ let userMessage ;
244
+ if ( initialUserMessage ) {
245
+ userMessage = initialUserMessage ;
246
+ initialUserMessage = null ;
247
+ } else {
248
+ process . stdout . write ( '\x1b[1m' ) ; // blue color
249
+ userMessage = await prompt ( 'λ ' ) ;
250
+ process . stdout . write ( '\x1b[0m' ) ; // reset color
251
+ }
157
252
158
253
try {
159
- const fullMessage = lastOutput + userMessage ;
254
+ const fullMessage = userMessage . trim ( ) !== ''
255
+ ? `<SYSTEM>\n${ lastOutput . trim ( ) } \n</SYSTEM>\n<USER>\n${ userMessage } \n</USER>\n`
256
+ : `<SYSTEM>\n${ lastOutput . trim ( ) } \n</SYSTEM>` ;
257
+
160
258
const assistantMessage = await ask ( fullMessage , { system : SYSTEM_PROMPT , model : MODEL } ) ;
161
259
console . log ( ) ;
162
260
163
261
const code = extractCode ( assistantMessage ) ;
164
262
lastOutput = "" ;
165
263
166
264
if ( code ) {
167
- const answer = await prompt ( 'Execute? [Y/n] ' ) ;
265
+ console . log ( "\x1b[31mPress enter to execute, or 'N' to cancel.\x1b[0m" ) ;
266
+ const answer = await prompt ( '' ) ;
267
+ // TODO: delete the warning above from the terminal
268
+ process . stdout . moveCursor ( 0 , - 2 ) ;
269
+ process . stdout . clearLine ( 2 ) ;
168
270
if ( answer . toLowerCase ( ) === 'n' ) {
169
271
console . log ( 'Execution skipped.' ) ;
170
272
lastOutput = "Command skipped.\n" ;
171
273
} else {
172
274
try {
173
275
const { stdout, stderr} = await execAsync ( code ) ;
174
- const output = `<RESULT>\n ${ stdout } ${ stderr } \n</RESULT>\n ` ;
175
- console . log ( output ) ;
276
+ const output = `${ stdout . trim ( ) } ${ stderr . trim ( ) } ` ;
277
+ console . log ( '\x1b[2m' + output . trim ( ) + '\x1b[0m' ) ;
176
278
lastOutput = output ;
177
279
} catch ( error ) {
178
- console . error ( `Execution error: ${ error . message } ` ) ;
179
- lastOutput = `<ERROR>\n${ error . message } \n</ERROR>\n` ;
280
+ const output = `${ error . stdout ?. trim ( ) || '' } ${ error . stderr ?. trim ( ) || '' } ` ;
281
+ console . log ( '\x1b[2m' + output . trim ( ) + '\x1b[0m' ) ;
282
+ lastOutput = output ;
180
283
}
181
284
}
182
285
}
0 commit comments