research format

This commit is contained in:
lovebird 2025-06-28 12:45:24 +02:00
parent c52e058f25
commit eb12d74af8
6 changed files with 180 additions and 31 deletions

View File

@ -1,3 +1,3 @@
import OpenAI from 'openai';
import { IKBotTask } from '@polymech/ai-tools';
export declare const runResponses: (client: OpenAI, params: any, options: IKBotTask) => Promise<any>;
export declare const runResponses: (client: OpenAI, params: any, options: IKBotTask) => Promise<string | false>;

View File

@ -1,3 +1,5 @@
import { sync as readFS } from '@polymech/fs/read';
import { sync as exists } from '@polymech/fs/exists';
import { onCompletion } from './run-completion.js';
export const runResponses = async (client, params, options) => {
if (options.dry) {
@ -19,18 +21,36 @@ export const runResponses = async (client, params, options) => {
},
// { type: "web_search_preview" },
];
const response = await client.responses.create({
model: options.model,
input,
stream: false,
parallel_tool_calls: false,
tools
});
if (!response || !response.output_text) {
return '';
let format = null;
if (exists(options.format)) {
const content = readFS(options.format);
format = JSON.parse(content.toString());
}
try {
const response = await client.responses.create({
model: options.model,
input,
stream: false,
parallel_tool_calls: false,
tools: tools,
text: {
format: {
type: "json_schema",
name: "format",
schema: format,
strict: false
}
}
});
if (!response || !response.output_text) {
return '';
}
let result = response.output_text;
result = await onCompletion(result, options);
return result;
}
catch (e) {
options.logger?.error(`Error running responses mode: ${e.message}`, e.stack);
}
let result = response.output_text;
result = await onCompletion(result, options);
return result;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXJlc3BvbnNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9ydW4tcmVzcG9uc2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUVsRCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsS0FBSyxFQUFFLE1BQWMsRUFBRSxNQUFXLEVBQUUsT0FBa0IsRUFBRSxFQUFFO0lBQ2xGLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2QsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtRQUNuRCxPQUFPLEtBQUssQ0FBQTtJQUNoQixDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVE7U0FDeEIsR0FBRyxDQUFDLENBQUMsQ0FBNkIsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztTQUNqRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFakIsTUFBTSxLQUFLLEdBQUc7UUFDVjtZQUNJLElBQUksRUFBRSxZQUFZO1lBQ2xCLGFBQWEsRUFBRTtnQkFDWCxJQUFJLEVBQUUsYUFBYTtnQkFDbkIsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsSUFBSSxFQUFFLFlBQVk7Z0JBQ2xCLE1BQU0sRUFBRSxXQUFXO2FBQ3RCO1NBQ0o7UUFDRCxrQ0FBa0M7S0FDckMsQ0FBQTtJQUVELE1BQU0sUUFBUSxHQUFHLE1BQU8sTUFBYyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDcEQsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLEtBQUs7UUFDTCxNQUFNLEVBQUUsS0FBSztRQUNiLG1CQUFtQixFQUFFLEtBQUs7UUFDMUIsS0FBSztLQUNSLENBQUMsQ0FBQTtJQUVGLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckMsT0FBTyxFQUFFLENBQUE7SUFDYixDQUFDO0lBRUQsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQTtJQUNqQyxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQzVDLE9BQU8sTUFBTSxDQUFBO0FBQ2pCLENBQUMsQ0FBQSJ9
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXJlc3BvbnNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9ydW4tcmVzcG9uc2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDbEQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDbEQsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxNQUFjLEVBQUUsTUFBVyxFQUFFLE9BQWtCLEVBQUUsRUFBRTtJQUNsRixJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNkLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7UUFDbkQsT0FBTyxLQUFLLENBQUE7SUFDaEIsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRO1NBQ3hCLEdBQUcsQ0FBQyxDQUFDLENBQTZCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7U0FDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBRWpCLE1BQU0sS0FBSyxHQUFHO1FBQ1Y7WUFDSSxJQUFJLEVBQUUsWUFBWTtZQUNsQixhQUFhLEVBQUU7Z0JBQ1gsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLE9BQU8sRUFBRSxJQUFJO2dCQUNiLElBQUksRUFBRSxZQUFZO2dCQUNsQixNQUFNLEVBQUUsV0FBVzthQUN0QjtTQUNKO1FBQ0Qsa0NBQWtDO0tBQ3JDLENBQUE7SUFFRCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFFbEIsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDekIsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztZQUMzQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7WUFDcEIsS0FBSztZQUNMLE1BQU0sRUFBRSxLQUFLO1lBQ2IsbUJBQW1CLEVBQUUsS0FBSztZQUMxQixLQUFLLEVBQUUsS0FBWTtZQUNuQixJQUFJLEVBQUU7Z0JBQ0YsTUFBTSxFQUFFO29CQUNKLElBQUksRUFBRSxhQUFhO29CQUNuQixJQUFJLEVBQUUsUUFBUTtvQkFDZCxNQUFNLEVBQUUsTUFBTTtvQkFDZCxNQUFNLEVBQUUsS0FBSztpQkFDaEI7YUFDSjtTQUNKLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckMsT0FBTyxFQUFFLENBQUE7UUFDYixDQUFDO1FBRUQsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQTtRQUNqQyxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQzVDLE9BQU8sTUFBTSxDQUFBO0lBQ2pCLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1QsT0FBTyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEYsQ0FBQztBQUNMLENBQUMsQ0FBQSJ9

View File

@ -1,10 +1,9 @@
import OpenAI from 'openai'
import { ChatCompletionMessageParam } from 'openai/resources/index.mjs'
import { IKBotTask } from '@polymech/ai-tools'
import { sync as readFS } from '@polymech/fs/read'
import { sync as exists } from '@polymech/fs/exists'
import { onCompletion } from './run-completion.js'
export const runResponses = async (client: OpenAI, params: any, options: IKBotTask) => {
if (options.dry) {
options.logger?.info('Dry run - skipping API call')
@ -28,19 +27,38 @@ export const runResponses = async (client: OpenAI, params: any, options: IKBotTa
// { type: "web_search_preview" },
]
const response = await (client as any).responses.create({
model: options.model,
input,
stream: false,
parallel_tool_calls: false,
tools
})
let format = null;
if (!response || !response.output_text) {
return ''
if (exists(options.format)) {
const content = readFS(options.format);
format = JSON.parse(content.toString());
}
let result = response.output_text
result = await onCompletion(result, options)
return result
try {
const response = await client.responses.create({
model: options.model,
input,
stream: false,
parallel_tool_calls: false,
tools: tools as any,
text: {
format: {
type: "json_schema",
name: "format",
schema: format,
strict: false
}
}
})
if (!response || !response.output_text) {
return ''
}
let result = response.output_text
result = await onCompletion(result, options)
return result
} catch (e) {
options.logger?.error(`Error running responses mode: ${e.message}`, e.stack)
}
}

View File

@ -0,0 +1,60 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/oled-display-list.schema.json",
"title": "OLED Display List",
"description": "A schema for a list of OLED displays with their properties.",
"type": "object",
"properties": {
"displays": {
"type": "array",
"description": "A list of OLED displays suitable for ESP-32 with buttons.",
"items": {
"type": "object",
"properties": {
"model_name": {
"type": "string",
"description": "The model name of the OLED display."
},
"link": {
"type": "string",
"description": "URL to the product page.",
"format": "uri"
},
"price": {
"type": "number",
"description": "Price in USD.",
"minimum": 0
},
"type": {
"type": "string",
"description": "Type of the display (e.g., I2C, SPI)."
},
"features": {
"type": "string",
"description": "Key features of the display."
},
"pros": {
"type": "string",
"description": "Advantages of using this display."
},
"cons": {
"type": "string",
"description": "Disadvantages of using this display."
}
},
"required": [
"model_name",
"link",
"price",
"type",
"features",
"pros",
"cons"
]
}
}
},
"required": [
"displays"
]
}

View File

@ -2,7 +2,7 @@
# - --model=o3-deep-research needs verification : https://platform.openai.com/settings/organization/general
kbot-d "Create a comprehensive list of OLED displays, with buttons - to be used with a ESP-32, as Markdown table (links, prices, types, features, pros and cons). Elaborate on the features, and the pros and cons of each." \
kbot-d "Create a comprehensive list of OLED displays, with buttons - to be used with a ESP-32. The output should be a JSON object that follows the provided schema. Elaborate on the features, and the pros and cons of each." \
--router=openai \
--model=gpt-4.1 \
--model_rs_1=o4-mini-deep-research \
@ -10,6 +10,8 @@ kbot-d "Create a comprehensive list of OLED displays, with buttons - to be used
--disable=npm,terminal,interact,git,search,web,user,email \
--preferences=none \
--mode=responses \
--dst=./tests/research/oled-displays.md \
--filters=code \
--dst=./tests/research/oled-displays.json \
--format=./tests/research-format.json \
--logLevel=2

View File

@ -0,0 +1,49 @@
{
"displays": [
{
"model_name": "TouchEye Dual Round OLED Display",
"link": "https://www.diyelectronics.us/2025/02/toucheye-compact-open-source-dual-oled.html",
"price": 49.0,
"type": "I2C",
"features": "Dual 1.28” round touch displays with 240x240 resolution, ESP32-S3 microcontroller, Wi-Fi and Bluetooth connectivity, microSD card slot, two programmable buttons, USB Type-C interface, battery connector with charging management.",
"pros": "Compact design with dual touch displays, wireless connectivity, expandable storage, and user-friendly interface.",
"cons": "Limited to round display format, higher price point compared to single-display modules."
},
{
"model_name": "ESP32-CAM with Capacitive Touch Buttons and OLED",
"link": "https://robotzero.one/esp32-cam-oled-capacitive-touch-buttons/",
"price": 30.0,
"type": "I2C",
"features": "0.96” OLED display, ESP32-CAM module with camera, three capacitive touch buttons, microSD card slot, USB Type-C interface, battery-powered operation.",
"pros": "Integrated camera and display, touch button interface, portable design with battery operation.",
"cons": "Smaller display size, limited to three touch buttons, requires assembly and 3D printing for enclosure."
},
{
"model_name": "FireBeetle Covers-OLED12864 Display",
"link": "https://community.dfrobot.com/makelog-313920.html",
"price": 20.0,
"type": "I2C",
"features": "1.3” OLED display with 128x64 resolution, two buttons, 5-way joystick, 3-axis accelerometer, compatible with FireBeetle ESP8266 board.",
"pros": "Comprehensive input options with joystick and buttons, integrated accelerometer for motion sensing, compact and stackable design.",
"cons": "Requires FireBeetle board for compatibility, limited to specific ecosystem, smaller display size."
},
{
"model_name": "ESP32-S3 SuperMini with SSD1306 OLED and Button",
"link": "https://www.espboards.dev/blog/ssd1306-esp32-s3-super-mini-setup/",
"price": 15.0,
"type": "I2C",
"features": "0.96” OLED display with 128x64 resolution, single push button, ESP32-S3 microcontroller, USB Type-C interface.",
"pros": "Minimalist design, easy to integrate, cost-effective solution for simple interfaces.",
"cons": "Limited input options with only one button, smaller display size, basic functionality."
},
{
"model_name": "Norvi IIOT-AE01-R with Built-in OLED and Push Buttons",
"link": "https://www.instructables.com/Working-With-Built-in-Display-and-Push-Buttons-of-/",
"price": 60.0,
"type": "I2C",
"features": "0.96” OLED SSD1306 display with 128x64 resolution, three push buttons connected via analog input, ESP32 microcontroller, industrial-grade design.",
"pros": "Industrial-grade build quality, integrated display and buttons, suitable for automation applications.",
"cons": "Higher price point, limited to three buttons, analog input method for buttons may require calibration."
}
]
}