Skip to content

Commit 7ed779b

Browse files
authored
feat: enhanced ai command to perfom other commands (#1156)
* Enhanced ai command to perfom other commands * Enhance AI Command in Puter's shell
1 parent 8c49793 commit 7ed779b

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
]
4848
},
4949
"dependencies": {
50+
"@heyputer/putility": "^1.0.2",
5051
"dedent": "^1.5.3",
5152
"javascript-time-ago": "^2.5.11",
5253
"json-colorizer": "^3.0.1",

src/phoenix/src/puter-shell/coreutils/ai.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export default {
2626
$: 'simple-parser',
2727
allowPositionals: true,
2828
},
29+
input: {
30+
synchLines: true,
31+
},
2932
execute: async ctx => {
3033
const { positionals } = ctx.locals;
3134
const [ prompt ] = positionals;
@@ -49,6 +52,18 @@ export default {
4952
a_args = {
5053
messages: [
5154
...chatHistory.get_messages(),
55+
{
56+
role: 'system',
57+
content: `You are a helpful AI assistant that helps users with shell commands.
58+
When a user asks to perform an action:
59+
1. If the action requires a command, wrap ONLY the command between %%% markers
60+
2. Keep the command simple and on a single line
61+
3. Do not ask for confirmation
62+
Example:
63+
User: "create a directory named test"
64+
You: "Creating directory 'test'
65+
%%%mkdir test%%%"`
66+
},
5267
{
5368
role: 'user',
5469
content: prompt,
@@ -80,8 +95,47 @@ export default {
8095
return;
8196
}
8297

98+
8399
chatHistory.add_message(resobj?.result?.message);
84100

85-
await ctx.externs.out.write(message + '\n');
101+
const commandMatch = message.match(/%%%(.*?)%%%/);
102+
103+
if (commandMatch) {
104+
const commandToExecute = commandMatch[1].trim();
105+
const cleanMessage = message.replace(/%%%(.*?)%%%/, '');
106+
107+
await ctx.externs.out.write(cleanMessage + '\n');
108+
109+
await ctx.externs.out.write(`Execute command: '${commandToExecute}' (y/n): `);
110+
111+
try {
112+
let line, done;
113+
const next_line = async () => {
114+
({ value: line, done } = await ctx.externs.in_.read());
115+
}
116+
117+
await next_line();
118+
119+
const inputString = new TextDecoder().decode(line);
120+
const response = (inputString ?? '').trim().toLowerCase();
121+
122+
console.log('processed response', {response});
123+
124+
if (!response.startsWith('y')) {
125+
await ctx.externs.out.write('\nCommand execution cancelled\n');
126+
return;
127+
}
128+
129+
await ctx.externs.out.write('\n');
130+
await ctx.shell.runPipeline(commandToExecute);
131+
await ctx.externs.out.write(`Command executed: ${commandToExecute}\n`);
132+
} catch (error) {
133+
await ctx.externs.err.write(`Error executing command: ${error.message}\n`);
134+
return;
135+
}
136+
} else {
137+
await ctx.externs.out.write(message + '\n');
138+
}
139+
86140
}
87141
}

0 commit comments

Comments
 (0)