Initial commit: Add CLI tool with OpenAI integration, including file listing and echo functionalities. Introduce package.json for dependencies and scripts, and system prompt for AI behavior.
This commit is contained in:
104
cli.js
Normal file
104
cli.js
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env node
|
||||
import 'dotenv/config';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
import { promises as fs } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import path from "node:path";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
async function loadTools() {
|
||||
const toolsDir = path.join(__dirname, "tools");
|
||||
const dirents = await fs.readdir(toolsDir, { withFileTypes: true });
|
||||
const toolEntries = await Promise.all(
|
||||
dirents
|
||||
.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".js"))
|
||||
.map(async (dirent) => {
|
||||
const fileName = dirent.name.replace(/\.js$/, "");
|
||||
const module = await import(`file://${path.join(toolsDir, dirent.name)}`);
|
||||
return [fileName, { def: module.default, run: module.run }];
|
||||
})
|
||||
);
|
||||
return Object.fromEntries(toolEntries);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
streamOnce(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }), 'Zeig mir die Dateiein in /');
|
||||
|
||||
async function streamOnce(openai, userText) {
|
||||
const toolsByFile = await loadTools();
|
||||
|
||||
const input =[
|
||||
{ "role": "developer", "content": [ {"type": "input_text","text": '' }] },
|
||||
{"role": "user", "content": [ { "type": "input_text", "text": userText } ]},
|
||||
]
|
||||
|
||||
const call = {
|
||||
model: 'gpt-5-nano',
|
||||
input,
|
||||
text: { format: { type: 'text' }, verbosity: 'low' },
|
||||
reasoning: { effort: 'high', summary: 'detailed' },
|
||||
tools: Object.values(toolsByFile).map(t => t.def),
|
||||
store: true,
|
||||
}
|
||||
|
||||
const stream = await openai.responses.stream(call);
|
||||
|
||||
stream.on('response.created', (event) => {
|
||||
//console.log('respid:', event.response.id);
|
||||
});
|
||||
stream.on('response.reasoning_summary_text.delta', (event) => {
|
||||
//process.stdout.write(event.delta);
|
||||
});
|
||||
stream.on('response.reasoning_summary_text.done', () => {
|
||||
//process.stdout.write('\n');
|
||||
//clear on next delta
|
||||
});
|
||||
|
||||
stream.on('response.output_text.delta', (event) => {
|
||||
process.stdout.write(event.delta);
|
||||
});
|
||||
|
||||
|
||||
stream.on('response.output_item.added', (event) => {
|
||||
if(event.item && event.item.type === 'function_call'){
|
||||
//console.log('function call:', event.item);
|
||||
}
|
||||
});
|
||||
stream.on('response.function_call_arguments.delta', (event) => {
|
||||
//process.stdout.write(event.delta);
|
||||
});
|
||||
|
||||
const functionCalls = [];
|
||||
|
||||
stream.on('response.output_item.done', async (event) => {
|
||||
if(event.item && event.item.type === 'function_call'){
|
||||
const id = event.item.id;
|
||||
const name = event.item.name;
|
||||
let args = {};
|
||||
try {
|
||||
args = JSON.parse(event.item.arguments);
|
||||
} catch (e){
|
||||
console.error('Error parsing arguments:', e, event.item.arguments);
|
||||
}
|
||||
console.log('function call:', id,name, args,await toolsByFile[name].run(args));
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('response.completed', (event) => {
|
||||
const filtered = {
|
||||
id: event?.response?.id,
|
||||
status: event?.response?.status,
|
||||
output: event?.response?.output,
|
||||
usage: event?.response?.usage,
|
||||
};
|
||||
//console.log('OPENAI RESPONSE:', event);
|
||||
});
|
||||
|
||||
await Array.fromAsync(stream);
|
||||
|
||||
console.log('OPENAI STREAM FINISHED');
|
||||
}
|
||||
Reference in New Issue
Block a user