diff --git a/6-tc-computer.ts b/6-tc-computer.ts index 55ae2eb..72e0dc0 100644 --- a/6-tc-computer.ts +++ b/6-tc-computer.ts @@ -19,7 +19,6 @@ const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms)) async function main ( prompt: string = 'Show a welcome message on screen. After the task is complete, ask the user to confirm before ending the program, or ask user for more tasks to perform on the website.', - max_steps: number = 10, model: string = 'gpt-5.2' ) { const client = new OpenAI({ @@ -73,7 +72,7 @@ async function main ( content: prompt }) - for (let i = 0; i < max_steps; i++) { + while(true) { console.log(`\n=== ROUND ${i + 1} ===\n`) //await sleep(1000) // pause between rounds for readability const resp = await client.responses.create({ @@ -153,7 +152,7 @@ JavaScript to execute. Write small snippets of interactive code. To persist vari console.log('response output item =', item) if (item.type == 'shell_call') { console.log('shell call item =', item) - let shell_call_output = [] + let shell_call_output: { stdout: string; stderr: string; outcome: { type: string; exit_code: number } }[] = []; item.action.commands.forEach(command => { console.log('$', command, '\n') diff --git a/8-skill-in-shell.mjs b/8-skill-in-shell.mjs new file mode 100644 index 0000000..a554898 --- /dev/null +++ b/8-skill-in-shell.mjs @@ -0,0 +1,92 @@ +import OpenAI from "openai"; +import path from "path"; +import shell from 'shelljs' + +const client = new OpenAI(); + +// const responseHosted = await client.responses.create({ +// model: "gpt-5.2", +// tools: [ +// { +// type: "shell", +// environment: { +// type: "container_auto", +// skills: [ +// { type: "skill_reference", skill_id: "skill_69b7aab7a0988191afca6ad2c530326b07c9ae27b6429c7c" }, +// ], +// }, +// }, +// ], +// input: "Use the skills to find phone number of Qiaozhen.", +// }); + +// console.log('Hosted shell response:', responseHosted.output_text); + +const conversation = [{ + role: 'user', + content: "Use the mycontacts skill and run locally to find the phone number of Qiaozhen." + }] + +let hasShellCall = true +let round = 0 + +while(hasShellCall) { + hasShellCall = false + round++ + +const responseLocal = await client.responses.create({ + model: "gpt-5.2", + tools: [ + { + type: "shell", + environment: { + type: "local", + skills: [ + { + name: "mycontacts", + description: "My contacts info", + path: path.resolve("./skills/mycontacts"), + }, + ], + }, + }, + ], + input: conversation, +}); + +console.log('Local shell response output:', JSON.stringify(responseLocal.output, null, 2)); + +conversation.push(...responseLocal.output) + +responseLocal.output.forEach(item => { + if (item.type == 'shell_call') { + hasShellCall = true + console.log('shell call item =', item) + let shell_call_output = [] + item.action.commands.forEach(command => { + + console.log('$', command, '\n') + + + let { stdout, stderr } = shell.exec(command, { + silent: true + }) + shell_call_output.push({ + stdout, + stderr, + outcome: { type: 'exit', exit_code: 0 } + }) + }) + + conversation.push({ + type: 'shell_call_output', + call_id: item.call_id, + output: shell_call_output + }) + } +}) + +console.log('Local shell response of round ' + round + ':', JSON.stringify(responseLocal.output_text, null, 2)); + + +} \ No newline at end of file diff --git a/8-skill.md b/8-skill.md new file mode 100644 index 0000000..8f4dcc2 --- /dev/null +++ b/8-skill.md @@ -0,0 +1,26 @@ +``` +curl -X POST 'https://api.openai.com/v1/skills' -H "Authorization: Bearer $OPENAI_API_KEY" -F 'files[]=@./contacts/SKILL.md;filename=contacts/SKILL.md;type=text/markdown'' +{ + "id": "skill_69b7aab7a0988191afca6ad2c530326b07c9ae27b6429c7c", + "object": "skill", + "created_at": 1773644471, + "default_version": "1", + "description": "My contact list", + "latest_version": "1", + "name": "contacts" +} +<07:01:11#root@codespaces-5a7969=23.97.62.113^x86_64,Linux,Debtrixie/sid:/workspaces/my-default-codespace/aitest># +``` + +注意,必须只有一级目录,不能有子目录 (skills/contacts/skill.md),否则会报错: + +``` +{ + "error": { + "message": "Exactly one of SKILL.md or Skills.md must be present in the skill root", + "type": "invalid_request_error", + "param": "files", + "code": "invalid_value" + } +} +``` diff --git a/skills/contacts/skill.md b/contacts/SKILL.md similarity index 100% rename from skills/contacts/skill.md rename to contacts/SKILL.md diff --git a/skills/mycontacts/SKILL.md b/skills/mycontacts/SKILL.md new file mode 100644 index 0000000..3ce50c1 --- /dev/null +++ b/skills/mycontacts/SKILL.md @@ -0,0 +1,6 @@ +--- +name: contacts +description: My contact list +--- + +Use this skill when you need to find details of a contact of mine. The skill provides a list of contacts in CSV format: "name, phone" in contacts.csv. diff --git a/skills/mycontacts/contacts.csv b/skills/mycontacts/contacts.csv new file mode 100644 index 0000000..4c4c99e --- /dev/null +++ b/skills/mycontacts/contacts.csv @@ -0,0 +1,3 @@ +Xue Hua, 18617591633 +Luk Lu, 15295439901 +Zong Qiaozhen, 13585016982 \ No newline at end of file diff --git a/skills/skill_cid.js b/skills/skill_cid.js deleted file mode 100644 index 2160ddb..0000000 --- a/skills/skill_cid.js +++ /dev/null @@ -1,3 +0,0 @@ -const ipfsOnlyHash = require('ipfs-only-hash') - -ipfsOnlyHash.of(content, option) diff --git a/skills/skill_cid.md b/skills/skill_cid.md deleted file mode 100644 index 43296c8..0000000 --- a/skills/skill_cid.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: basic-math -description: Add or multiply numbers. ---- - -Use this skill when you need to calcuate cid of a string.