From 2be8a59103af77fe618f9d74cf57a619136c403e Mon Sep 17 00:00:00 2001 From: babayaga Date: Sun, 6 Apr 2025 21:36:09 +0200 Subject: [PATCH] kbot - async it transformer example --- .../examples/core/async-iterator-example.js | 60 +++------------- packages/kbot/logs/params.json | 2 +- .../examples/core/async-iterator-example.ts | 68 +++---------------- 3 files changed, 18 insertions(+), 112 deletions(-) diff --git a/packages/kbot/dist-in/examples/core/async-iterator-example.js b/packages/kbot/dist-in/examples/core/async-iterator-example.js index e10e417a..1cc42fd3 100644 --- a/packages/kbot/dist-in/examples/core/async-iterator-example.js +++ b/packages/kbot/dist-in/examples/core/async-iterator-example.js @@ -1,12 +1,9 @@ import { sync as write } from "@polymech/fs/write"; -// Import path but not the logger import * as path from 'path'; import { E_OPENROUTER_MODEL } from '../../models/cache/openrouter-models.js'; -// Configurable constants const MODEL = E_OPENROUTER_MODEL.MODEL_OPENROUTER_QUASAR_ALPHA; const ROUTER = 'openrouter'; -const LOG_LEVEL = 2; // 0=trace, 1=debug, 2=info, 3=warn, 4=error, 5=fatal -// Create a simple console logger +const LOG_LEVEL = 2; let logger = { info: (message) => console.log(`INFO: ${message}`), warn: (message) => console.log(`WARN: ${message}`), @@ -14,11 +11,8 @@ let logger = { debug: (message) => console.log(`DEBUG: ${message}`), trace: (message) => console.log(`TRACE: ${message}`) }; -// Import the actual kbot modules directly from source import { transformObject } from '../../async-iterator.js'; -// Import run function from commands import { run } from '../../commands/run.js'; -// Example data structure with fields to be transformed const exampleData = { products: { fruits: [ @@ -72,20 +66,16 @@ const exampleData = { description: 'Collection of common fruits and vegetables' } }; -// Create a mapping of fields to transform with JSONPath const fieldMappings = [ { - // Transform all product descriptions jsonPath: '$..description', - // Target field to store LLM result - same as source in this case - targetPath: null, // null means replace in place + targetPath: null, options: { model: MODEL, prompt: 'Make this description more engaging and detailed, around 20-30 words' } }, { - // Transform nutrition information jsonPath: '$..nutrition', targetPath: null, options: { @@ -94,96 +84,75 @@ const fieldMappings = [ } }, { - // Transform product names and store in a new 'marketingName' field jsonPath: '$..name', - targetPath: 'marketingName', // will create a new field called marketingName + targetPath: 'marketingName', options: { model: MODEL, prompt: 'Generate a more appealing marketing name for this product' } } ]; -// Create an async transformer function that uses an LLM to transform text const createLLMTransformer = (options) => { return async (input, jsonPath) => { logger.info(`Transforming field at path: ${jsonPath}`); logger.info(`Input: ${input}`); logger.info(`Using prompt: ${options.prompt}`); - // Configure the task for kbot const kbotTask = { model: options.model || MODEL, router: ROUTER, prompt: `${options.prompt}\n\nText to transform: "${input}"`, logLevel: LOG_LEVEL, - path: path.resolve('./'), // Fix: provide absolute path + path: path.resolve('./'), mode: 'completion' }; try { - // Run kbot with the configured task const results = await run(kbotTask); if (results && results.length > 0 && typeof results[0] === 'string') { const result = results[0].trim(); logger.info(`Result: ${result}`); return result; } - // Return original if transformation fails logger.warn(`No valid result received for ${jsonPath}, returning original`); return input; } catch (error) { console.error(`Error calling LLM API: ${error.message}`, error); - return input; // Return original on error + return input; } }; }; -// Function to handle field transformation for a specific mapping export async function transformField(data, mapping) { const { jsonPath, targetPath, options } = mapping; - // Create a transformer for this specific field const transformer = createLLMTransformer(options); - // Set up error callback const errorCallback = (path, value, error) => { logger.error(`Error transforming ${path}: ${error.message}`); - // Don't throw to allow continued processing }; - // Set up filter callback - always return true to transform all matching fields const filterCallback = async () => true; - // Try/catch to handle any JSONPath or transformation errors try { if (!targetPath) { - // Transform in place - await transformObject(data, transformer, jsonPath, 1000, // throttle delay - higher for real API calls - 1, // concurrent tasks - limit for API rate limits - errorCallback, filterCallback); + await transformObject(data, transformer, jsonPath, 1000, 1, errorCallback, filterCallback); } else { - // Create a copy of the data to transform const dataCopy = JSON.parse(JSON.stringify(data)); - // Transform the copy await transformObject(dataCopy, transformer, jsonPath, 1000, 1, errorCallback, filterCallback); - // Extract transformed values and store in target fields const { JSONPath } = await import('jsonpath-plus'); const paths = JSONPath({ path: jsonPath, json: dataCopy, resultType: 'pointer' }); for (const p of paths) { const keys = p.slice(1).split('/'); - // Navigate to the value in the transformed copy let value = dataCopy; for (const key of keys) { if (key === '') - continue; // Skip empty segments + continue; value = value[key]; } - // Store in target path in the original data const originalKeys = p.slice(1).split('/'); const parentKeys = originalKeys.slice(0, -1); - // Navigate to parent object in original data let target = data; for (const key of parentKeys) { if (key === '') continue; target = target[key]; } - // Set the new field with transformed value target[targetPath] = value; } } @@ -192,28 +161,23 @@ export async function transformField(data, mapping) { logger.error(`Error in field transformation: ${error.message}`); } } -// Main function to demonstrate the transformation export async function transformExample() { console.log("========================================"); console.log("Starting async-iterator example transformation"); console.log("========================================"); try { - // Clone the data to avoid modifying the original const data = JSON.parse(JSON.stringify(exampleData)); logger.info("Starting transformation of data fields with LLM..."); console.log("Processing field mappings..."); - // Process each field mapping for (const mapping of fieldMappings) { console.log(`Processing mapping: ${mapping.jsonPath} -> ${mapping.targetPath || 'in-place'}`); logger.info(`Processing field mapping: ${mapping.jsonPath} -> ${mapping.targetPath || 'in-place'}`); await transformField(data, mapping); } - // Save the result to a file const outputPath = path.resolve('./tests/test-data/core/async-iterator-data.json'); write(outputPath, JSON.stringify(data, null, 2)); console.log(`Transformation complete. Results saved to ${outputPath}`); logger.info(`Transformation complete. Results saved to ${outputPath}`); - // Display before/after comparison for a sample field console.log("\nBefore/After Comparison Example:"); console.log(`Original description: ${exampleData.products.fruits[0].description}`); console.log(`Transformed description: ${data.products.fruits[0].description}`); @@ -232,24 +196,17 @@ export async function transformExample() { throw error; } } -// Run directly with Node.js -// This section checks if this module is being executed directly (not imported) console.log("Module loading, checking if this is direct execution"); console.log("process.argv[1]:", process.argv[1]); console.log("import.meta.url:", import.meta.url); -// Directly check if file is run directly const isDirectExecution = process.argv[1] && process.argv[1].includes('async-iterator-example'); console.log("Is direct execution:", isDirectExecution); if (isDirectExecution) { - // Process command line arguments const isDebug = process.argv.includes('--debug'); console.log('Starting async-iterator example...'); console.log(`Command arguments: ${process.argv.slice(2).join(', ')}`); console.log(`Debug mode: ${isDebug ? 'enabled' : 'disabled'}`); - // Use more verbose logging if debug mode is enabled if (isDebug) { - // Override the LOG_LEVEL constant for debug mode - // @ts-ignore logger = { info: (message) => console.log(`DEBUG-INFO: ${message}`), warn: (message) => console.log(`DEBUG-WARN: ${message}`), @@ -263,6 +220,5 @@ if (isDirectExecution) { console.error("Unhandled error:", error); }); } -// Export for potential reuse export { createLLMTransformer, exampleData }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtaXRlcmF0b3ItZXhhbXBsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9leGFtcGxlcy9jb3JlL2FzeW5jLWl0ZXJhdG9yLWV4YW1wbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxpQ0FBaUM7QUFDakMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFFN0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUE7QUFFNUUseUJBQXlCO0FBQ3pCLE1BQU0sS0FBSyxHQUFHLGtCQUFrQixDQUFDLDZCQUE2QixDQUFDO0FBQy9ELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQztBQUU1QixNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxxREFBcUQ7QUFFMUUsaUNBQWlDO0FBQ2pDLElBQUksTUFBTSxHQUFHO0lBQ1QsSUFBSSxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUM7SUFDMUQsSUFBSSxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUM7SUFDMUQsS0FBSyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUM7SUFDOUQsS0FBSyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUM7SUFDNUQsS0FBSyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUM7Q0FDL0QsQ0FBQztBQUVGLHNEQUFzRDtBQUN0RCxPQUFPLEVBQ0gsZUFBZSxFQU1sQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLG9DQUFvQztBQUNwQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFNUMsdURBQXVEO0FBQ3ZELE1BQU0sV0FBVyxHQUFHO0lBQ2hCLFFBQVEsRUFBRTtRQUNOLE1BQU0sRUFBRTtZQUNKO2dCQUNJLEVBQUUsRUFBRSxJQUFJO2dCQUNSLElBQUksRUFBRSxPQUFPO2dCQUNiLFdBQVcsRUFBRSwyQkFBMkI7Z0JBQ3hDLE9BQU8sRUFBRTtvQkFDTCxLQUFLLEVBQUUsS0FBSztvQkFDWixNQUFNLEVBQUUsV0FBVztvQkFDbkIsU0FBUyxFQUFFLDZCQUE2QjtpQkFDM0M7YUFDSjtZQUNEO2dCQUNJLEVBQUUsRUFBRSxJQUFJO2dCQUNSLElBQUksRUFBRSxRQUFRO2dCQUNkLFdBQVcsRUFBRSx5QkFBeUI7Z0JBQ3RDLE9BQU8sRUFBRTtvQkFDTCxLQUFLLEVBQUUsUUFBUTtvQkFDZixNQUFNLEVBQUUsZ0JBQWdCO29CQUN4QixTQUFTLEVBQUUsbUJBQW1CO2lCQUNqQzthQUNKO1NBQ0o7UUFDRCxVQUFVLEVBQUU7WUFDUjtnQkFDSSxFQUFFLEVBQUUsSUFBSTtnQkFDUixJQUFJLEVBQUUsUUFBUTtnQkFDZCxXQUFXLEVBQUUsMEJBQTBCO2dCQUN2QyxPQUFPLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLFFBQVE7b0JBQ2YsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLFNBQVMsRUFBRSx3QkFBd0I7aUJBQ3RDO2FBQ0o7WUFDRDtnQkFDSSxFQUFFLEVBQUUsSUFBSTtnQkFDUixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsV0FBVyxFQUFFLCtCQUErQjtnQkFDNUMsT0FBTyxFQUFFO29CQUNMLEtBQUssRUFBRSxPQUFPO29CQUNkLE1BQU0sRUFBRSxPQUFPO29CQUNmLFNBQVMsRUFBRSwwQkFBMEI7aUJBQ3hDO2FBQ0o7U0FDSjtLQUNKO0lBQ0QsUUFBUSxFQUFFO1FBQ04sV0FBVyxFQUFFLFlBQVk7UUFDekIsTUFBTSxFQUFFLGdCQUFnQjtRQUN4QixXQUFXLEVBQUUsNENBQTRDO0tBQzVEO0NBQ0osQ0FBQztBQUVGLHdEQUF3RDtBQUN4RCxNQUFNLGFBQWEsR0FBRztJQUNsQjtRQUNJLHFDQUFxQztRQUNyQyxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLGlFQUFpRTtRQUNqRSxVQUFVLEVBQUUsSUFBSSxFQUFFLDhCQUE4QjtRQUNoRCxPQUFPLEVBQUU7WUFDTCxLQUFLLEVBQUUsS0FBSztZQUNaLE1BQU0sRUFBRSxzRUFBc0U7U0FDakY7S0FDSjtJQUNEO1FBQ0ksa0NBQWtDO1FBQ2xDLFFBQVEsRUFBRSxjQUFjO1FBQ3hCLFVBQVUsRUFBRSxJQUFJO1FBQ2hCLE9BQU8sRUFBRTtZQUNMLEtBQUssRUFBRSxLQUFLO1lBQ1osTUFBTSxFQUFFLHlGQUF5RjtTQUNwRztLQUNKO0lBQ0Q7UUFDSSxtRUFBbUU7UUFDbkUsUUFBUSxFQUFFLFNBQVM7UUFDbkIsVUFBVSxFQUFFLGVBQWUsRUFBRSwrQ0FBK0M7UUFDNUUsT0FBTyxFQUFFO1lBQ0wsS0FBSyxFQUFFLEtBQUs7WUFDWixNQUFNLEVBQUUsMkRBQTJEO1NBQ3RFO0tBQ0o7Q0FDSixDQUFDO0FBRUYsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxPQUFZLEVBQW9CLEVBQUU7SUFDNUQsT0FBTyxLQUFLLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQW1CLEVBQUU7UUFDOUQsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMvQixNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUUvQyw4QkFBOEI7UUFDOUIsTUFBTSxRQUFRLEdBQWM7WUFDeEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLElBQUksS0FBSztZQUM3QixNQUFNLEVBQUUsTUFBTTtZQUNkLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLDJCQUEyQixLQUFLLEdBQUc7WUFDNUQsUUFBUSxFQUFFLFNBQVM7WUFDbkIsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsNkJBQTZCO1lBQ3ZELElBQUksRUFBRSxZQUFtQjtTQUM1QixDQUFDO1FBRUYsSUFBSSxDQUFDO1lBQ0Qsb0NBQW9DO1lBQ3BDLE1BQU0sT0FBTyxHQUFHLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXBDLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUNsRSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUNqQyxPQUFPLE1BQU0sQ0FBQztZQUNsQixDQUFDO1lBRUQsMENBQTBDO1lBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLFFBQVEsc0JBQXNCLENBQUMsQ0FBQztZQUM1RSxPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNoRSxPQUFPLEtBQUssQ0FBQyxDQUFDLDJCQUEyQjtRQUM3QyxDQUFDO0lBQ0wsQ0FBQyxDQUFDO0FBQ04sQ0FBQyxDQUFDO0FBRUYsaUVBQWlFO0FBQ2pFLE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUFDLElBQVMsRUFBRSxPQUFzRTtJQUNsSCxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFFbEQsK0NBQStDO0lBQy9DLE1BQU0sV0FBVyxHQUFHLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRWxELHdCQUF3QjtJQUN4QixNQUFNLGFBQWEsR0FBRyxDQUFDLElBQVksRUFBRSxLQUFhLEVBQUUsS0FBVSxFQUFFLEVBQUU7UUFDOUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsSUFBSSxLQUFLLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzdELDRDQUE0QztJQUNoRCxDQUFDLENBQUM7SUFFRiwrRUFBK0U7SUFDL0UsTUFBTSxjQUFjLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUM7SUFFeEMsNERBQTREO0lBQzVELElBQUksQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNkLHFCQUFxQjtZQUNyQixNQUFNLGVBQWUsQ0FDakIsSUFBSSxFQUNKLFdBQVcsRUFDWCxRQUFRLEVBQ1IsSUFBSSxFQUFFLDZDQUE2QztZQUNuRCxDQUFDLEVBQUssK0NBQStDO1lBQ3JELGFBQWEsRUFDYixjQUFjLENBQ2pCLENBQUM7UUFDTixDQUFDO2FBQU0sQ0FBQztZQUNKLHlDQUF5QztZQUN6QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUVsRCxxQkFBcUI7WUFDckIsTUFBTSxlQUFlLENBQ2pCLFFBQVEsRUFDUixXQUFXLEVBQ1gsUUFBUSxFQUNSLElBQUksRUFDSixDQUFDLEVBQ0QsYUFBYSxFQUNiLGNBQWMsQ0FDakIsQ0FBQztZQUVGLHdEQUF3RDtZQUN4RCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDbkQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBRWxGLEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUVuQyxnREFBZ0Q7Z0JBQ2hELElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQztnQkFDckIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztvQkFDckIsSUFBSSxHQUFHLEtBQUssRUFBRTt3QkFBRSxTQUFTLENBQUMsc0JBQXNCO29CQUNoRCxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN2QixDQUFDO2dCQUVELDRDQUE0QztnQkFDNUMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzNDLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRTdDLDZDQUE2QztnQkFDN0MsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDO2dCQUNsQixLQUFLLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO29CQUMzQixJQUFJLEdBQUcsS0FBSyxFQUFFO3dCQUFFLFNBQVM7b0JBQ3pCLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3pCLENBQUM7Z0JBRUQsMkNBQTJDO2dCQUMzQyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQy9CLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNwRSxDQUFDO0FBQ0wsQ0FBQztBQUVELGtEQUFrRDtBQUNsRCxNQUFNLENBQUMsS0FBSyxVQUFVLGdCQUFnQjtJQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO0lBQzlELE9BQU8sQ0FBQyxHQUFHLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUV4RCxJQUFJLENBQUM7UUFDRCxpREFBaUQ7UUFDakQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFFckQsTUFBTSxDQUFDLElBQUksQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ2xFLE9BQU8sQ0FBQyxHQUFHLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUU1Qyw2QkFBNkI7UUFDN0IsS0FBSyxNQUFNLE9BQU8sSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixPQUFPLENBQUMsUUFBUSxPQUFPLE9BQU8sQ0FBQyxVQUFVLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQztZQUM5RixNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixPQUFPLENBQUMsUUFBUSxPQUFPLE9BQU8sQ0FBQyxVQUFVLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNwRyxNQUFNLGNBQWMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUVELDRCQUE0QjtRQUM1QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7UUFDbkYsS0FBSyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVqRCxPQUFPLENBQUMsR0FBRyxDQUFDLDZDQUE2QyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sQ0FBQyxJQUFJLENBQUMsNkNBQTZDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFFdkUscURBQXFEO1FBQ3JELE9BQU8sQ0FBQyxHQUFHLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUNsRCxPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ25GLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDL0UsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNyRSxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUNsRCxNQUFNLENBQUMsSUFBSSxDQUFDLHlCQUF5QixXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ25GLE1BQU0sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDL0UsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNyRSxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNyRCxNQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM5RCxNQUFNLEtBQUssQ0FBQztJQUNoQixDQUFDO0FBQ0wsQ0FBQztBQUVELDRCQUE0QjtBQUM1QiwrRUFBK0U7QUFDL0UsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO0FBQ3BFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pELE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUVqRCx5Q0FBeUM7QUFDekMsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFDaEcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0FBRXZELElBQUksaUJBQWlCLEVBQUUsQ0FBQztJQUNwQixpQ0FBaUM7SUFDakMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ2xELE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBRS9ELG9EQUFvRDtJQUNwRCxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ1YsaURBQWlEO1FBQ2pELGFBQWE7UUFDYixNQUFNLEdBQUc7WUFDTCxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxPQUFPLEVBQUUsQ0FBQztZQUN4RCxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxPQUFPLEVBQUUsQ0FBQztZQUN4RCxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLE9BQU8sRUFBRSxDQUFDO1lBQzVELEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsT0FBTyxFQUFFLENBQUM7WUFDMUQsS0FBSyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixPQUFPLEVBQUUsQ0FBQztTQUM3RCxDQUFDO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRCxnQkFBZ0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUM3QixPQUFPLENBQUMsS0FBSyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzdDLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUVELDZCQUE2QjtBQUM3QixPQUFPLEVBQ0gsb0JBQW9CLEVBQ3BCLFdBQVcsRUFDZCxDQUFDIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtaXRlcmF0b3ItZXhhbXBsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9leGFtcGxlcy9jb3JlL2FzeW5jLWl0ZXJhdG9yLWV4YW1wbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU1RSxNQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyw2QkFBNkIsQ0FBQztBQUMvRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUM7QUFDNUIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0FBRXBCLElBQUksTUFBTSxHQUFHO0lBQ1QsSUFBSSxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUM7SUFDMUQsSUFBSSxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUM7SUFDMUQsS0FBSyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUM7SUFDOUQsS0FBSyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUM7SUFDNUQsS0FBSyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsT0FBTyxFQUFFLENBQUM7Q0FDL0QsQ0FBQztBQUVGLE9BQU8sRUFDSCxlQUFlLEVBTWxCLE1BQU0seUJBQXlCLENBQUM7QUFFakMsT0FBTyxFQUFFLEdBQUcsRUFBRSxN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 \ No newline at end of file diff --git a/packages/kbot/logs/params.json b/packages/kbot/logs/params.json index ca1fa4ea..8f996877 100644 --- a/packages/kbot/logs/params.json +++ b/packages/kbot/logs/params.json @@ -3,7 +3,7 @@ "messages": [ { "role": "user", - "content": "Expand this nutrition information with 2-3 specific health benefits, around 25-35 words\n\nText to transform: \"Rich in fiber and vitamin C\"" + "content": "Generate a more appealing marketing name for this product\n\nText to transform: \"broccoli\"" }, { "role": "user", diff --git a/packages/kbot/src/examples/core/async-iterator-example.ts b/packages/kbot/src/examples/core/async-iterator-example.ts index cd2c2a11..2dc6112a 100644 --- a/packages/kbot/src/examples/core/async-iterator-example.ts +++ b/packages/kbot/src/examples/core/async-iterator-example.ts @@ -1,16 +1,12 @@ import { sync as write } from "@polymech/fs/write"; -// Import path but not the logger import * as path from 'path'; import type { IKBotTask } from '@polymech/ai-tools'; import { E_OPENROUTER_MODEL } from '../../models/cache/openrouter-models.js' -// Configurable constants const MODEL = E_OPENROUTER_MODEL.MODEL_OPENROUTER_QUASAR_ALPHA; const ROUTER = 'openrouter'; +const LOG_LEVEL = 2; -const LOG_LEVEL = 2; // 0=trace, 1=debug, 2=info, 3=warn, 4=error, 5=fatal - -// Create a simple console logger let logger = { info: (message: string) => console.log(`INFO: ${message}`), warn: (message: string) => console.log(`WARN: ${message}`), @@ -19,7 +15,6 @@ let logger = { trace: (message: string) => console.log(`TRACE: ${message}`) }; -// Import the actual kbot modules directly from source import { transformObject, defaultOptions, @@ -29,10 +24,8 @@ import { AsyncTransformer } from '../../async-iterator.js'; -// Import run function from commands import { run } from '../../commands/run.js'; -// Example data structure with fields to be transformed const exampleData = { products: { fruits: [ @@ -87,20 +80,16 @@ const exampleData = { } }; -// Create a mapping of fields to transform with JSONPath const fieldMappings = [ { - // Transform all product descriptions jsonPath: '$..description', - // Target field to store LLM result - same as source in this case - targetPath: null, // null means replace in place + targetPath: null, options: { model: MODEL, prompt: 'Make this description more engaging and detailed, around 20-30 words' } }, { - // Transform nutrition information jsonPath: '$..nutrition', targetPath: null, options: { @@ -109,9 +98,8 @@ const fieldMappings = [ } }, { - // Transform product names and store in a new 'marketingName' field jsonPath: '$..name', - targetPath: 'marketingName', // will create a new field called marketingName + targetPath: 'marketingName', options: { model: MODEL, prompt: 'Generate a more appealing marketing name for this product' @@ -119,25 +107,22 @@ const fieldMappings = [ } ]; -// Create an async transformer function that uses an LLM to transform text const createLLMTransformer = (options: any): AsyncTransformer => { return async (input: string, jsonPath: string): Promise => { logger.info(`Transforming field at path: ${jsonPath}`); logger.info(`Input: ${input}`); logger.info(`Using prompt: ${options.prompt}`); - // Configure the task for kbot const kbotTask: IKBotTask = { model: options.model || MODEL, router: ROUTER, prompt: `${options.prompt}\n\nText to transform: "${input}"`, logLevel: LOG_LEVEL, - path: path.resolve('./'), // Fix: provide absolute path + path: path.resolve('./'), mode: 'completion' as any }; try { - // Run kbot with the configured task const results = await run(kbotTask); if (results && results.length > 0 && typeof results[0] === 'string') { @@ -146,50 +131,37 @@ const createLLMTransformer = (options: any): AsyncTransformer => { return result; } - // Return original if transformation fails logger.warn(`No valid result received for ${jsonPath}, returning original`); return input; } catch (error) { console.error(`Error calling LLM API: ${error.message}`, error); - return input; // Return original on error + return input; } }; }; -// Function to handle field transformation for a specific mapping export async function transformField(data: any, mapping: { jsonPath: string, targetPath: string | null, options: any }) { const { jsonPath, targetPath, options } = mapping; - - // Create a transformer for this specific field const transformer = createLLMTransformer(options); - - // Set up error callback const errorCallback = (path: string, value: string, error: any) => { logger.error(`Error transforming ${path}: ${error.message}`); - // Don't throw to allow continued processing }; - - // Set up filter callback - always return true to transform all matching fields const filterCallback = async () => true; - // Try/catch to handle any JSONPath or transformation errors try { if (!targetPath) { - // Transform in place await transformObject( data, transformer, jsonPath, - 1000, // throttle delay - higher for real API calls - 1, // concurrent tasks - limit for API rate limits + 1000, + 1, errorCallback, filterCallback ); } else { - // Create a copy of the data to transform const dataCopy = JSON.parse(JSON.stringify(data)); - // Transform the copy await transformObject( dataCopy, transformer, @@ -200,32 +172,25 @@ export async function transformField(data: any, mapping: { jsonPath: string, tar filterCallback ); - // Extract transformed values and store in target fields const { JSONPath } = await import('jsonpath-plus'); const paths = JSONPath({ path: jsonPath, json: dataCopy, resultType: 'pointer' }); for (const p of paths) { const keys = p.slice(1).split('/'); - - // Navigate to the value in the transformed copy let value = dataCopy; for (const key of keys) { - if (key === '') continue; // Skip empty segments + if (key === '') continue; value = value[key]; } - // Store in target path in the original data const originalKeys = p.slice(1).split('/'); const parentKeys = originalKeys.slice(0, -1); - - // Navigate to parent object in original data let target = data; for (const key of parentKeys) { if (key === '') continue; target = target[key]; } - // Set the new field with transformed value target[targetPath] = value; } } @@ -234,34 +199,28 @@ export async function transformField(data: any, mapping: { jsonPath: string, tar } } -// Main function to demonstrate the transformation export async function transformExample() { console.log("========================================"); console.log("Starting async-iterator example transformation"); console.log("========================================"); try { - // Clone the data to avoid modifying the original const data = JSON.parse(JSON.stringify(exampleData)); - logger.info("Starting transformation of data fields with LLM..."); console.log("Processing field mappings..."); - // Process each field mapping for (const mapping of fieldMappings) { console.log(`Processing mapping: ${mapping.jsonPath} -> ${mapping.targetPath || 'in-place'}`); logger.info(`Processing field mapping: ${mapping.jsonPath} -> ${mapping.targetPath || 'in-place'}`); await transformField(data, mapping); } - // Save the result to a file const outputPath = path.resolve('./tests/test-data/core/async-iterator-data.json'); write(outputPath, JSON.stringify(data, null, 2)); console.log(`Transformation complete. Results saved to ${outputPath}`); logger.info(`Transformation complete. Results saved to ${outputPath}`); - // Display before/after comparison for a sample field console.log("\nBefore/After Comparison Example:"); console.log(`Original description: ${exampleData.products.fruits[0].description}`); console.log(`Transformed description: ${data.products.fruits[0].description}`); @@ -282,28 +241,20 @@ export async function transformExample() { } } -// Run directly with Node.js -// This section checks if this module is being executed directly (not imported) console.log("Module loading, checking if this is direct execution"); console.log("process.argv[1]:", process.argv[1]); console.log("import.meta.url:", import.meta.url); -// Directly check if file is run directly const isDirectExecution = process.argv[1] && process.argv[1].includes('async-iterator-example'); console.log("Is direct execution:", isDirectExecution); if (isDirectExecution) { - // Process command line arguments const isDebug = process.argv.includes('--debug'); - console.log('Starting async-iterator example...'); console.log(`Command arguments: ${process.argv.slice(2).join(', ')}`); console.log(`Debug mode: ${isDebug ? 'enabled' : 'disabled'}`); - // Use more verbose logging if debug mode is enabled if (isDebug) { - // Override the LOG_LEVEL constant for debug mode - // @ts-ignore logger = { info: (message) => console.log(`DEBUG-INFO: ${message}`), warn: (message) => console.log(`DEBUG-WARN: ${message}`), @@ -319,8 +270,7 @@ if (isDirectExecution) { }); } -// Export for potential reuse export { createLLMTransformer, exampleData -}; \ No newline at end of file +}; \ No newline at end of file