Skip to content

Adapt ai command to use tool use / function calling #1163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
KernelDeimos opened this issue Mar 8, 2025 · 9 comments
Open

Adapt ai command to use tool use / function calling #1163

KernelDeimos opened this issue Mar 8, 2025 · 9 comments
Assignees

Comments

@KernelDeimos
Copy link
Contributor

KernelDeimos commented Mar 8, 2025

Recently the AI command gained the ability to run commands. If we used the streaming mode of the puter-chat-completion driver interface it would be possible to the AI command to take multiple steps and command execution might be slightly more reliable.

For more details, refer to this previous issue

@Sashank-Singh
Copy link

Hello @KernelDeimos can I work on this Issue?

@ntwari-bruce
Copy link
Contributor

@KernelDeimos i would like to continue with this issue as well.

@KernelDeimos
Copy link
Contributor Author

@ntwari-bruce gets first dibs on this for working on #1156, but @Sashank-Singh if you'd like to work with Ntwari on this and he says it's okay then I can assign both of you

@Sashank-Singh
Copy link

Sashank-Singh commented Mar 10, 2025

Yes, I would like to work on it too. Thanks @KernelDeimos

@ntwari-bruce
Copy link
Contributor

@KernelDeimos yes you can assign both of us

@KernelDeimos
Copy link
Contributor Author

Thanks for confirming, I've assigned both of you

@ntwari-bruce
Copy link
Contributor

Hello @KernelDeimos,

I hope you’re doing well. I’ve been testing an implementation where I focused on adding a single command, "mkdir", as a starting point to validate my approach. I wanted your thoughts on it and see if you have suggestions for alternative methods or improvements.

I’m currently using the tools I defined in my setup, and I’ve attached the code below for your review.

`

    let fullMessage = '';
    
    for (const line of lines) {
        try {
            const chunk = JSON.parse(line);
            
            if (chunk.type === 'text') {
                fullMessage += chunk.text;
                await ctx.externs.out.write(chunk.text);
            }
           
            if (chunk.type === 'tool_use') {
                if (chunk.name === 'mkdir') {
                    const args = chunk.input;
                    
                    await ctx.externs.out.write(`\nCreating directory: ${args.path}\n`);
                    await ctx.externs.out.write('Proceed? (y/n): ');

                    let { value: line } = await ctx.externs.in_.read();
                    const inputString = new TextDecoder().decode(line);
                    const response = inputString.trim().toLowerCase();
                    
                    await ctx.externs.out.write('\n');

                    if (response.startsWith('y')) {
                        try {
                            await ctx.shell.runPipeline(`mkdir ${args.parents ? '-p' : ''} ${args.path}`);

                            await drivers.call({
                                interface: 'puter-chat-completion',
                                method: 'complete',
                                args: {
                                    messages: [
                                        ...chatHistory.get_messages(),
                                        {
                                            role: "tool",
                                            tool_call_id: chunk.id,
                                            content: `Directory '${args.path}' created successfully`
                                        }
                                    ]
                                }
                            });
                            
                            fullMessage += `Directory '${args.path}' created successfully`;
                        } catch(error) {
                            await ctx.externs.out.write('\n');
                            await ctx.externs.err.write(`Error creating directory: ${error.message}\n`);
                            fullMessage += `Failed to create directory: ${error.message}`;
                            return;
                        }
                    } else {
                        await ctx.externs.out.write('\nOperation cancelled.\n');
                        fullMessage += 'Operation cancelled';
                    }
                }
            }
        } catch (error) {
            await ctx.externs.err.write(`Error parsing chunk: ${error.message}\n`);
            throw new Exit(1);
        }
    }

    await ctx.externs.out.write('\n');

    if (!fullMessage) {
        await ctx.externs.err.write('message not found in response\n');
        return;
    }

    chatHistory.add_message({
        role: 'assistant',
        content: fullMessage
    });

`

@ntwari-bruce
Copy link
Contributor

ntwari-bruce commented Mar 16, 2025

@KernelDeimos

This is the tool i used.

const tools = [{ type: "function", function: { name: "mkdir", description: "Create a new directory", parameters: { type: "object", properties: { path: { type: "string", description: "Directory name or path to create" }, parents: { type: "boolean", description: "Create parent directories if they don't exitst", default: false } }, required: ["path"] }, strict: true } }]

@KernelDeimos
Copy link
Contributor Author

The schema of each command would be better as metadata on the command itself (for builtin commands at least, external commands would need a different approach but we can consider that to be out of scope for now). Then you should be able to lookup commands and generate a list of tools. It might require exposing the command provider like I did with the shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants