From b2ef96e786294a6e7aa7b756ce9ee60bd32984e5 Mon Sep 17 00:00:00 2001 From: babayaga Date: Mon, 7 Apr 2025 16:01:06 +0200 Subject: [PATCH] kbot iterator callbacks --- packages/kbot/dist-in/async-iterator.d.ts | 17 +- packages/kbot/dist-in/async-iterator.js | 65 ++++++- .../examples/core/iterator-factory-example.js | 86 +++++++-- packages/kbot/dist-in/iterator.d.ts | 4 +- packages/kbot/dist-in/iterator.js | 9 +- packages/kbot/docs_/iterator.md | 174 +++++++++++++++++- packages/kbot/logs/params.json | 2 +- packages/kbot/src/async-iterator.ts | 76 ++++++-- .../examples/core/iterator-factory-example.ts | 105 ++++++++--- packages/kbot/src/iterator.ts | 13 +- .../test-data/core/iterator-factory-data.json | 8 +- 11 files changed, 483 insertions(+), 76 deletions(-) diff --git a/packages/kbot/dist-in/async-iterator.d.ts b/packages/kbot/dist-in/async-iterator.d.ts index 68c2b4c4..4e1c1b17 100644 --- a/packages/kbot/dist-in/async-iterator.d.ts +++ b/packages/kbot/dist-in/async-iterator.d.ts @@ -1,7 +1,10 @@ +import { IKBotTask } from '@polymech/ai-tools'; export type AsyncTransformer = (input: string, path: string) => Promise; export type ErrorCallback = (path: string, value: string, error: unknown) => void; export type FilterCallback = (input: string, path: string) => Promise; export type Filter = (input: string) => Promise; +export type OnTransformCallback = (jsonPath: string, value: string, options?: Partial) => Promise; +export type OnTransformedCallback = (jsonPath: string, transformedValue: string, options?: Partial) => Promise; export interface INetworkOptions { throttleDelay?: number; concurrentTasks?: number; @@ -21,14 +24,21 @@ export interface GlobalOptions { network?: INetworkOptions; errorCallback?: ErrorCallback; filterCallback?: FilterCallback; + onTransform?: OnTransformCallback; + onTransformed?: OnTransformedCallback; } export declare const isNumber: Filter; export declare const isBoolean: Filter; export declare const isValidString: Filter; export declare const testFilters: (filters: Filter[]) => FilterCallback; export declare const defaultFilters: (filters?: Filter[]) => Filter[]; -export declare function transformObject(obj: Record, transform: AsyncTransformer, path: string, networkOptions: Required, errorCallback: ErrorCallback, testCallback: FilterCallback): Promise; -export declare function transformPath(obj: Record, keys: string[], transform: AsyncTransformer, networkOptions: Required, currentPath: string, errorCallback: ErrorCallback, testCallback: FilterCallback): Promise; +export declare function transformObject(obj: Record, transform: AsyncTransformer, path: string, networkOptions: Required, errorCallback: ErrorCallback, testCallback: FilterCallback, onTransform: OnTransformCallback, // Pass callbacks down +onTransformed: OnTransformedCallback, // Pass callbacks down +options?: Partial): Promise; +export declare function transformPath(obj: Record, keys: string[], transform: AsyncTransformer, networkOptions: Required, currentPath: string, // Changed from jsonPointer to represent the logical path +errorCallback: ErrorCallback, testCallback: FilterCallback, onTransform: OnTransformCallback, // Receive callbacks +onTransformed: OnTransformedCallback, // Receive callbacks +options?: Partial): Promise; export declare const defaultError: ErrorCallback; export interface TransformWithOptionsInput { jsonPath: string; @@ -36,6 +46,9 @@ export interface TransformWithOptionsInput { network?: INetworkOptions; errorCallback?: ErrorCallback; filterCallback?: FilterCallback; + onTransform?: OnTransformCallback; + onTransformed?: OnTransformedCallback; + kbotOptions?: Partial; } export declare function transformObjectWithOptions(obj: Record, transform: AsyncTransformer, options: TransformWithOptionsInput): Promise; export declare const defaultOptions: (options?: Partial) => TransformOptions; diff --git a/packages/kbot/dist-in/async-iterator.js b/packages/kbot/dist-in/async-iterator.js index ac2375fe..ac327c5b 100644 --- a/packages/kbot/dist-in/async-iterator.js +++ b/packages/kbot/dist-in/async-iterator.js @@ -26,14 +26,24 @@ export const testFilters = (filters) => { export const defaultFilters = (filters = []) => [ isNumber, isBoolean, isValidString, ...filters ]; -export async function transformObject(obj, transform, path, networkOptions, errorCallback, testCallback) { +export async function transformObject(obj, transform, path, networkOptions, errorCallback, testCallback, onTransform, // Pass callbacks down +onTransformed, // Pass callbacks down +options // Pass options context if available +) { const paths = JSONPath({ path, json: obj, resultType: 'pointer' }); await pMap(paths, async (jsonPointer) => { const keys = jsonPointer.slice(1).split('/'); - await transformPath(obj, keys, transform, networkOptions, jsonPointer, errorCallback, testCallback); + await transformPath(obj, keys, transform, networkOptions, jsonPointer, errorCallback, testCallback, onTransform, // Pass callbacks down + onTransformed, // Pass callbacks down + options // Pass options context if available + ); }, { concurrency: networkOptions.concurrentTasks }); } -export async function transformPath(obj, keys, transform, networkOptions, currentPath, errorCallback, testCallback) { +export async function transformPath(obj, keys, transform, networkOptions, currentPath, // Changed from jsonPointer to represent the logical path +errorCallback, testCallback, onTransform, // Receive callbacks +onTransformed, // Receive callbacks +options // Pass options context if available +) { let current = obj; for (let i = 0; i < keys.length - 1; i++) { if (current[keys[i]] === undefined || current[keys[i]] === null) { @@ -53,9 +63,28 @@ export async function transformPath(obj, keys, transform, networkOptions, curren let attempts = 0; let success = false; let lastError; + let valueToTransform = current[lastKey]; + const fullJsonPath = `${currentPath}/${lastKey}`; // Construct full path + // Call onTransform before transformation + try { + valueToTransform = await onTransform(fullJsonPath, valueToTransform, options); + } + catch (error) { + console.error(`Error in onTransform callback for path ${fullJsonPath}:`, error); + // Decide if you want to proceed with the original value or stop + } while (attempts < networkOptions.maxRetries && !success) { try { - current[lastKey] = await throttle(transform)(current[lastKey], `${currentPath}/${lastKey}`); + let transformedValue = await throttle(transform)(valueToTransform, fullJsonPath); + // Call onTransformed after successful transformation + try { + transformedValue = await onTransformed(fullJsonPath, transformedValue, options); + } + catch (error) { + console.error(`Error in onTransformed callback for path ${fullJsonPath}:`, error); + // Decide if you want to proceed with the transformed value or stop/modify + } + current[lastKey] = transformedValue; // Assign potentially modified transformed value success = true; } catch (error) { @@ -69,32 +98,48 @@ export async function transformPath(obj, keys, transform, networkOptions, curren } } if (!success) { - errorCallback(currentPath, lastKey, lastError); + errorCallback(currentPath, lastKey, lastError); // Use currentPath (logical path) } } } else if (typeof current[lastKey] === 'object' && current[lastKey] !== null) { - await transformObject(current[lastKey], transform, '$.*', networkOptions, errorCallback, testCallback); + await transformObject(current[lastKey], transform, '$.*', // Recurse on all properties + networkOptions, errorCallback, testCallback, onTransform, // Pass callbacks down + onTransformed, // Pass callbacks down + options // Pass options context down + ); } } } export const defaultError = (path, value, error) => { console.error(`Error at path: ${path}, value: ${value}, error: ${error}`); }; +// Default no-op implementations for the new callbacks +const defaultOnTransform = async (_, value) => value; +const defaultOnTransformed = async (_, transformedValue) => transformedValue; export async function transformObjectWithOptions(obj, transform, options) { - const { jsonPath, targetPath = null, network = {}, errorCallback = defaultError, filterCallback = testFilters(defaultFilters()) } = options; + const { jsonPath, targetPath = null, network = {}, errorCallback = defaultError, filterCallback = testFilters(defaultFilters()), onTransform = defaultOnTransform, // Use default if not provided + onTransformed = defaultOnTransformed, // Use default if not provided + kbotOptions // Destructure kbot options + } = options; const networkOptions = { ...DEFAULT_NETWORK_OPTIONS, ...network }; // If targetPath is null, directly transform the object at jsonPath if (!targetPath) { - return transformObject(obj, transform, jsonPath, networkOptions, errorCallback, filterCallback); + return transformObject(obj, transform, jsonPath, networkOptions, errorCallback, filterCallback, onTransform, // Pass down + onTransformed, // Pass down + kbotOptions // Pass down kbot options + ); } // For targetPath case, create a deep clone and transform it const dataCopy = deepClone(obj); // Transform the copy - await transformObject(dataCopy, transform, jsonPath, networkOptions, errorCallback, filterCallback); + await transformObject(dataCopy, transform, jsonPath, networkOptions, errorCallback, filterCallback, onTransform, // Pass down + onTransformed, // Pass down + kbotOptions // Pass down kbot options + ); // Get paths from original object const paths = JSONPath({ path: jsonPath, json: obj, resultType: 'pointer' }); // Apply transformed values to original object with targetPath @@ -137,4 +182,4 @@ export const defaultOptions = (options = {}) => { targetPath: options.targetPath }; }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtaXRlcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYXN5bmMtaXRlcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLFNBQVMsTUFBTSxZQUFZLENBQUE7QUFDbEMsT0FBTyxJQUFJLE1BQU0sT0FBTyxDQUFBO0FBQ3hCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQWNsRCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBOEI7SUFDOUQsYUFBYSxFQUFFLElBQUk7SUFDbkIsZUFBZSxFQUFFLENBQUM7SUFDbEIsVUFBVSxFQUFFLENBQUM7SUFDYixVQUFVLEVBQUUsSUFBSTtDQUNuQixDQUFDO0FBaUJGLG9DQUFvQztBQUNwQyxNQUFNLEtBQUssR0FBRyxDQUFDLEVBQVUsRUFBRSxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFFOUUsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFXLEtBQUssRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7QUFDeEYsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFXLEtBQUssRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUN2RixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQVcsS0FBSyxFQUFFLEtBQWEsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQTtBQUVqRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxPQUFpQixFQUFrQixFQUFFO0lBQzdELE9BQU8sS0FBSyxFQUFF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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtaXRlcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYXN5bmMtaXRlcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLFNBQVMsTUFBTSxZQUFZLENBQUE7QUFDbEMsT0FBTyxJQUFJLE1BQU0sT0FBTyxDQUFBO0FBQ3hCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQWtCbEQsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQThCO0lBQzlELGFBQWEsRUFBRSxJQUFJO0lBQ25CLGVBQWUsRUFBRSxDQUFDO0lBQ2xCLFVBQVUsRUFBRSxDQUFDO0lBQ2IsVUFBVSxFQUFFLElBQUk7Q0FDbkIsQ0FBQztBQW1CRixvQ0FBb0M7QUFDcEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxFQUFVLEVBQUUsRUFBRSxDQUFDLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRTlFLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBVyxLQUFLLEVBQUUsS0FBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBQ3hGLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBVyxLQUFLLEVBQUUsS0FBYSxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDdkYsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFXLEtBQUssRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUE7QUFFakYsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBaUIsRUFBa0IsRUFBRTtJQUM3RCxPQUFPLEtBQUssRUFB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 \ No newline at end of file diff --git a/packages/kbot/dist-in/examples/core/iterator-factory-example.js b/packages/kbot/dist-in/examples/core/iterator-factory-example.js index 94302499..47fd72cc 100644 --- a/packages/kbot/dist-in/examples/core/iterator-factory-example.js +++ b/packages/kbot/dist-in/examples/core/iterator-factory-example.js @@ -3,7 +3,8 @@ import * as path from 'path'; import * as fs from 'fs'; import { E_OPENROUTER_MODEL } from '../../models/cache/openrouter-models.js'; import { E_Mode } from '../../zod_schema.js'; -import { createIterator, createLLMTransformer, transform } from '../../iterator.js'; +import { createIterator, createLLMTransformer, transform, removeEmptyObjects } from '../../iterator.js'; +import { rm_cached_object } from '@polymech/cache'; /** * Notes for LLM modifications * @@ -26,6 +27,9 @@ export async function simpleTransformExample() { model: MODEL, router: ROUTER, mode: E_Mode.COMPLETION + }, { + onTransform: simpleOnTransform, + onTransformed: simpleOnTransformed }); console.log("\nSimplified Transform Result:"); console.log(JSON.stringify(data.products.fruits[0], null, 2)); @@ -196,6 +200,33 @@ Do not add any extra fields not in the schema, and make sure to use the exact fi } } ]; +// Example onTransform callback +const exampleOnTransform = async (jsonPath, value, options) => { + console.log(` -> onTransform: Path='${jsonPath}', Original Value='${value.substring(0, 30)}...', Options Model='${options?.model}'`); + // Example: Prefix value before sending to LLM + if (jsonPath.includes('description')) { + return `[PRODUCT INFO] ${value}`; + } + return value; // Return original value if no modification needed +}; +// Example onTransformed callback +const exampleOnTransformed = async (jsonPath, transformedValue, options) => { + console.log(` <- onTransformed: Path='${jsonPath}', Transformed Value='${transformedValue.substring(0, 30)}...', Options Model='${options?.model}'`); + // Example: Post-process the LLM response + if (jsonPath.includes('nutrition')) { + return `${transformedValue} [HEALTH FOCUS]`; + } + return transformedValue; // Return transformed value if no modification needed +}; +// Simpler callbacks for the second example +const simpleOnTransform = async (jsonPath, value) => { + console.log(` -> simpleOnTransform: Path='${jsonPath}'`); + return value; +}; +const simpleOnTransformed = async (jsonPath, transformedValue) => { + console.log(` <- simpleOnTransformed: Path='${jsonPath}'`); + return transformedValue; +}; // Error handler const errorCallback = (path, value, error) => { logger.error(`Error transforming ${path}: ${error.message}`); @@ -226,8 +257,33 @@ export async function factoryExample() { logLevel: LOG_LEVEL, mode: E_Mode.COMPLETION }; - // Create an iterator factory instance - const iterator = createIterator(data, globalOptionsMixin, { + // --- Cache Clearing Logic --- + // Calculate the expected cache key for the object transformation + const objectCacheKey = removeEmptyObjects({ + data: JSON.stringify(exampleData), // Use the initial data state + mappings: fieldMappings.map(m => ({ + jsonPath: m.jsonPath, + targetPath: m.targetPath, + options: { + model: globalOptionsMixin.model, + router: globalOptionsMixin.router, + mode: globalOptionsMixin.mode, + prompt: m.options?.prompt + } + })) + }); + const objectCacheNamespace = 'transformed-objects'; + console.log(`Attempting to clear cache for key in namespace '${objectCacheNamespace}' before first run...`); + try { + await rm_cached_object({ ca_options: objectCacheKey }, objectCacheNamespace); + console.log('Cache cleared successfully (or key did not exist).'); + } + catch (error) { + console.warn('Failed to clear cache, proceeding anyway:', error); + } + // --- End Cache Clearing Logic --- + // Combine all options including callbacks for createIterator + const iteratorOptions = { network: networkOptions, errorCallback, filterCallback: async () => true, @@ -235,12 +291,15 @@ export async function factoryExample() { logger, cacheConfig: { ...cacheConfig, - // Force a new response for format testing enabled: process.argv.includes('--no-cache') ? false : cacheConfig.enabled - } - }); + }, + onTransform: exampleOnTransform, + onTransformed: exampleOnTransformed + }; + // Create an iterator factory instance + const iterator = createIterator(data, globalOptionsMixin, iteratorOptions); // Use the iterator to transform the data - console.log("First run - should transform and cache results:"); + console.log("First run - should transform, run callbacks, and cache results:"); await iterator.transform(fieldMappings); const outputPath = path.resolve('./tests/test-data/core/iterator-factory-data.json'); const outputDir = path.dirname(outputPath); @@ -275,15 +334,8 @@ export async function factoryExample() { console.log("Second run - should use cached results:"); console.log("========================================"); const data2 = JSON.parse(JSON.stringify(exampleData)); - const iterator2 = createIterator(data2, globalOptionsMixin, { - network: networkOptions, - errorCallback, - filterCallback: async () => true, - transformerFactory: (options) => createLLMTransformer(options, logger, cacheConfig), - logger, - cacheConfig - }); - // Should use cached values + const iterator2 = createIterator(data2, globalOptionsMixin, iteratorOptions); + // Should use cached values (callbacks won't run for cached object transform) await iterator2.transform(fieldMappings); console.log("\nBefore/After Comparison Example:"); console.log(`Original description: ${exampleData.products.fruits[0].description}`); @@ -337,4 +389,4 @@ if (process.argv[1] && process.argv[1].includes('iterator-factory-example')) { console.error("Unhandled error:", error); }); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3ItZmFjdG9yeS1leGFtcGxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2V4YW1wbGVzL2NvcmUvaXRlcmF0b3ItZmFjdG9yeS1leGFtcGxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFFekIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDN0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdDLE9BQU8sRUFBZ0IsY0FBYyxFQUFFLG9CQUFvQixFQUFnQyxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVoSTs7Ozs7Ozs7O0dBU0c7QUFHSCxNQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyw4QkFBOEIsQ0FBQztBQUNoRSxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUM7QUFFNUIsa0RBQWtEO0FBQ2xELE1BQU0sQ0FBQyxLQUFLLFVBQVUsc0JBQXNCO0lBQ3hDLElBQUksQ0FBQztRQUNELCtDQUErQztRQUMvQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUVyRCx5REFBeUQ7UUFDekQsTUFBTSxTQUFTLENBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRTtZQUNqQyxLQUFLLEVBQUUsS0FBSztZQUNaLE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1NBQzFCLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUM5QyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUks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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3ItZmFjdG9yeS1leGFtcGxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2V4YW1wbGVzL2NvcmUvaXRlcmF0b3ItZmFjdG9yeS1leGFtcGxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFFekIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDN0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdDLE9BQU8sRUFBZ0IsY0FBYyxFQUFFLG9CQUFvQixFQUFnQyxTQUFTLEVBQVksa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU5SixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVuRDs7Ozs7Ozs7O0dBU0c7QUFHSCxNQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyw4QkFBOEIsQ0FBQztBQUNoRSxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUM7QUFFNUIsa0RBQWtEO0FBQ2xELE1BQU0sQ0FBQyxLQUFLLFVBQVUsc0JBQXNCO0lBQ3hDLElBQUksQ0FBQztRQUNELCtDQUErQztRQUMvQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUVyRCx5REFBeUQ7UUFDekQsTUFBTSxTQUFTLENBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRTtZQUNqQyxLQUFLLEVBQUUsS0FBSztZQUNaLE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1NBQzFCLEVBQUU7WUFDQyxXQUFXLEVBQUUsaUJBQWlC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 \ No newline at end of file diff --git a/packages/kbot/dist-in/iterator.d.ts b/packages/kbot/dist-in/iterator.d.ts index a1e4813e..99e3b2aa 100644 --- a/packages/kbot/dist-in/iterator.d.ts +++ b/packages/kbot/dist-in/iterator.d.ts @@ -1,5 +1,5 @@ import { IKBotTask } from '@polymech/ai-tools'; -import { AsyncTransformer, ErrorCallback, FilterCallback, INetworkOptions } from './async-iterator.js'; +import { AsyncTransformer, ErrorCallback, FilterCallback, OnTransformCallback, OnTransformedCallback, INetworkOptions } from './async-iterator.js'; /** * Notes for LLM modifications * @@ -34,6 +34,8 @@ export interface IOptions { transformerFactory?: (options: IKBotTask) => AsyncTransformer; logger?: ILogger; cacheConfig?: CacheConfig; + onTransform?: OnTransformCallback; + onTransformed?: OnTransformedCallback; } export { INetworkOptions }; export declare function createLLMTransformer(options: IKBotTask, logger?: ILogger, cacheConfig?: CacheConfig): AsyncTransformer; diff --git a/packages/kbot/dist-in/iterator.js b/packages/kbot/dist-in/iterator.js index f3bc3441..890e394c 100644 --- a/packages/kbot/dist-in/iterator.js +++ b/packages/kbot/dist-in/iterator.js @@ -74,7 +74,7 @@ export function createLLMTransformer(options, logger = dummyLogger, cacheConfig) }; } export function createIterator(obj, optionsMixin, globalOptions = {}) { - const { network = {}, errorCallback = defaultError, filterCallback = testFilters(defaultFilters()), transformerFactory, logger = dummyLogger, cacheConfig } = globalOptions; + const { network = {}, errorCallback = defaultError, filterCallback = testFilters(defaultFilters()), transformerFactory, logger = dummyLogger, cacheConfig, onTransform, onTransformed } = globalOptions; const networkOptions = { ...DEFAULT_NETWORK_OPTIONS, ...network @@ -134,7 +134,10 @@ export function createIterator(obj, optionsMixin, globalOptions = {}) { targetPath, network: networkOptions, errorCallback, - filterCallback + filterCallback, + onTransform, + onTransformed, + kbotOptions: mergedOptions }); } // Cache the transformed object @@ -167,4 +170,4 @@ export async function transform(obj, mappings, optionsMixin = {}, options = {}) await iterator.transform(mappings); return obj; } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaXRlcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUlILFlBQVksRUFDWixjQUFjLEVBQ2QsV0FBVyxFQUNYLDBCQUEwQixFQUUxQix1QkFBdUIsRUFDMUIsTUFBTSxxQkFBcUIsQ0FBQTtBQUM1QixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFvQixNQUFNLGlCQUFpQixDQUFBO0FBaUJ4RixNQUFNLFdBQVcsR0FBWTtJQUN6QixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO0lBQ2QsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7Q0FDbEIsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBUSxFQUFPLEVBQUU7SUFDaEQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1FBQUUsT0FBTyxHQUFHLENBQUM7SUFDbEQsS0FBSyxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNwQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDcEIsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsU0FBUztRQUNoRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVE7WUFDdkIsQ0FBQyxHQUFHLElBQUksT0FBTyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxRQUFRLENBQUMsRUFDN0UsQ0FBQztZQUNDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMs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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaXRlcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQU1ILFlBQVksRUFDWixjQUFjLEVBQ2QsV0FBVyxFQUNYLDBCQUEwQixFQUUxQix1QkFBdUIsRUFDMUIsTUFBTSxxQkFBcUIsQ0FBQTtBQUM1QixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFvQixNQUFNLGlCQUFpQixDQUFBO0FBaUJ4RixNQUFNLFdBQVcsR0FBWTtJQUN6QixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO0lBQ2QsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7Q0FDbEIsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBUSxFQUFPLEVBQUU7SUFDaEQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1FBQUUsT0FBTyxHQUFHLENBQUM7SUFDbEQsS0FBSyxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNwQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDcEIsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsU0FBUztRQUNoRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVE7WUFDdkIsQ0FBQyxHQUFHLElBQUksT0FBTyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxRQUFRLENBQUMsRUFDN0UsQ0FBQztZQUNDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMs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 \ No newline at end of file diff --git a/packages/kbot/docs_/iterator.md b/packages/kbot/docs_/iterator.md index 0c3cf514..dd7c6b63 100644 --- a/packages/kbot/docs_/iterator.md +++ b/packages/kbot/docs_/iterator.md @@ -137,6 +137,160 @@ To keep the original value and add a transformed version, specify a `targetPath` This keeps the original `name` and adds a new `marketingName` field. +### Structured Output with Format Option + +The `format` option allows you to define a JSON schema that the LLM output should conform to. This is extremely useful for ensuring consistent, structured responses that can be easily parsed and used in your application. + +#### Basic Format Usage + +To request structured output, add a `format` property to your field mapping options: + +```typescript +{ + jsonPath: '$.productReview.reviewText', + targetPath: 'analysis', + options: { + prompt: 'Analyze this product review and extract key information', + format: { + type: "object", + properties: { + sentiment: { + type: "string", + enum: ["positive", "neutral", "negative"], + description: "The overall sentiment of the review" + }, + pros: { + type: "array", + items: { + type: "string" + }, + description: "Positive aspects mentioned in the review", + minItems: 1, + maxItems: 3 + }, + cons: { + type: "array", + items: { + type: "string" + }, + description: "Negative aspects mentioned in the review", + minItems: 0, + maxItems: 3 + } + }, + required: ["sentiment", "pros", "cons"] + } + } +} +``` + +#### Processing Structured Responses + +The formatted response may be returned as a JSON string. When working with formatted responses, it's good practice to handle potential string parsing: + +```typescript +// After transformation +if (data.productReview && data.productReview.analysis) { + try { + // Parse the JSON string if needed + const analysisJson = typeof data.productReview.analysis === 'string' + ? JSON.parse(data.productReview.analysis) + : data.productReview.analysis; + + // Now you can work with the structured data + console.log(`Sentiment: ${analysisJson.sentiment}`); + console.log(`Pros: ${analysisJson.pros.join(', ')}`); + console.log(`Cons: ${analysisJson.cons.join(', ')}`); + } catch (e) { + console.error("Error parsing structured output:", e); + } +} +``` + +#### Best Practices for Formatted Output + +1. **Clear Prompt Instructions**: Include explicit instructions in your prompt about the expected format. +2. **Schema Validation**: Use detailed JSON schemas with required fields and appropriate types. +3. **Parsing Handling**: Always include error handling when parsing the output. +4. **Schema Examples**: Consider including examples in your prompt for more complex schemas. + +#### Format Option Example + +Here's a complete example from the iterator-factory-example.ts file: + +```typescript +// Define a field mapping with format option +const fieldMappings = [ + { + jsonPath: '$.productReview.reviewText', + targetPath: 'analysis', + options: { + // Clear and explicit prompt that includes the schema format details + prompt: `Analyze this product review and extract key information using EXACTLY the schema specified below. + +The review: "Great selection of fruits with good prices and quality. Some items were out of stock." + +Your response MUST be a valid JSON object following this exact schema: +{ + "sentiment": "positive" | "neutral" | "negative", + "pros": ["string", "string"...], // 1-3 items + "cons": ["string"...] // 0-3 items +} + +Do not add any extra fields not in the schema, and make sure to use the exact field names as specified.`, + // Schema validation ensures structured output format + format: { + type: "object", + properties: { + sentiment: { + type: "string", + enum: ["positive", "neutral", "negative"], + description: "The overall sentiment of the review" + }, + pros: { + type: "array", + items: { + type: "string" + }, + description: "Positive aspects mentioned in the review", + minItems: 1, + maxItems: 3 + }, + cons: { + type: "array", + items: { + type: "string" + }, + description: "Negative aspects mentioned in the review", + minItems: 0, + maxItems: 3 + } + }, + required: ["sentiment", "pros", "cons"] + } + } + } +] +``` + +When run, this produces a structured output like: + +```json +{ + "sentiment": "positive", + "pros": [ + "great selection of fruits", + "good prices", + "good quality" + ], + "cons": [ + "some items were out of stock" + ] +} +``` + +This structured format is much easier to work with programmatically than free-form text responses. + ## Filtering Filters determine which values should be transformed: @@ -441,9 +595,15 @@ async function transformProductsWithCaching() { 8. **Use targetPath for non-destructive transformations**: When generating new content related to existing fields, use targetPath to preserve the original data. -9. **Implement custom cache for production**: For production scenarios, implement a persistent cache solution rather than relying on in-memory caching. +9. **Use format for structured outputs**: When you need consistent, structured data from LLMs, use the format option with clear JSON schemas. -10. **Use appropriate namespaces**: When multiple parts of your application use the same cache implementation, use distinct namespaces to prevent collisions. +10. **Include schema details in prompts**: For complex schemas, include the schema structure in your prompt to guide the LLM. + +11. **Handle string parsing**: Always add error handling when parsing structured responses, as they may be returned as string JSON. + +12. **Implement custom cache for production**: For production scenarios, implement a persistent cache solution rather than relying on in-memory caching. + +13. **Use appropriate namespaces**: When multiple parts of your application use the same cache implementation, use distinct namespaces to prevent collisions. ## API Reference @@ -465,7 +625,14 @@ async function transformProductsWithCaching() { - `FilterCallback`: Function that determines if a value should be transformed - `ErrorCallback`: Function that handles transformation errors - `FieldMapping`: Configuration for a transformation + - `jsonPath`: JSONPath expression to select values + - `targetPath`: Optional field to store transformed value (null for in-place) + - `options`: Configuration for the transformation including: + - `prompt`: The prompt for the LLM + - `format`: Optional JSON schema for structured output - `TransformOptions`: Options for the transformation process +- `CacheConfig`: Configuration for the caching mechanism +- `INetworkOptions`: Configuration for throttling and concurrency ## Limitations @@ -495,6 +662,9 @@ npm run examples:iterator-factory # Run with debug logging npm run examples:async-iterator -- --debug + +# Run with caching disabled (forces fresh responses) +npm run examples:iterator-factory -- --no-cache ``` The examples will transform sample JSON data and save the results to the `tests/test-data/core/` directory. diff --git a/packages/kbot/logs/params.json b/packages/kbot/logs/params.json index 1ece8737..86f8aa6f 100644 --- a/packages/kbot/logs/params.json +++ b/packages/kbot/logs/params.json @@ -3,7 +3,7 @@ "messages": [ { "role": "user", - "content": "Analyze this product review and extract key information using EXACTLY the schema specified below.\n\nThe review: \"Great selection of fruits with good prices and quality. Some items were out of stock.\"\n\nYour response MUST be a valid JSON object following this exact schema:\n{\n \"sentiment\": \"positive\" | \"neutral\" | \"negative\",\n \"pros\": [\"string\", \"string\"...], // 1-3 items\n \"cons\": [\"string\"...] // 0-3 items\n}\n\nDo not add any extra fields not in the schema, and make sure to use the exact field names as specified.\n\nText to transform: \"Great selection of fruits with good prices and quality. Some items were out of stock.\"" + "content": "Make this description more engaging and detailed, around 10 words\n\nText to transform: \"[PRODUCT INFO] A yellow tropical fruit\"" }, { "role": "user", diff --git a/packages/kbot/src/async-iterator.ts b/packages/kbot/src/async-iterator.ts index 8fe8e037..473ab72d 100644 --- a/packages/kbot/src/async-iterator.ts +++ b/packages/kbot/src/async-iterator.ts @@ -2,11 +2,15 @@ import { JSONPath } from 'jsonpath-plus' import pThrottle from 'p-throttle' import pMap from 'p-map' import { deepClone } from "@polymech/core/objects" +import { IKBotTask } from '@polymech/ai-tools'; // Assuming IKBotTask might be relevant context for callbacks export type AsyncTransformer = (input: string, path: string) => Promise export type ErrorCallback = (path: string, value: string, error: unknown) => void export type FilterCallback = (input: string, path: string) => Promise export type Filter = (input: string) => Promise +// Define the new callback types, passing IKBotTask options might be useful context +export type OnTransformCallback = (jsonPath: string, value: string, options?: Partial) => Promise; +export type OnTransformedCallback = (jsonPath: string, transformedValue: string, options?: Partial) => Promise; export interface INetworkOptions { throttleDelay?: number; @@ -35,6 +39,8 @@ export interface GlobalOptions { network?: INetworkOptions errorCallback?: ErrorCallback filterCallback?: FilterCallback + onTransform?: OnTransformCallback // Add pre-transform callback + onTransformed?: OnTransformedCallback // Add post-transform callback } // Sleep utility for retry mechanism @@ -66,7 +72,10 @@ export async function transformObject( path: string, networkOptions: Required, errorCallback: ErrorCallback, - testCallback: FilterCallback + testCallback: FilterCallback, + onTransform: OnTransformCallback, // Pass callbacks down + onTransformed: OnTransformedCallback, // Pass callbacks down + options?: Partial // Pass options context if available ): Promise { const paths = JSONPath({ path, json: obj, resultType: 'pointer' }); await pMap( @@ -80,7 +89,10 @@ export async function transformObject( networkOptions, jsonPointer, errorCallback, - testCallback + testCallback, + onTransform, // Pass callbacks down + onTransformed, // Pass callbacks down + options // Pass options context if available ) }, { concurrency: networkOptions.concurrentTasks } @@ -92,9 +104,12 @@ export async function transformPath( keys: string[], transform: AsyncTransformer, networkOptions: Required, - currentPath: string, + currentPath: string, // Changed from jsonPointer to represent the logical path errorCallback: ErrorCallback, - testCallback: FilterCallback + testCallback: FilterCallback, + onTransform: OnTransformCallback, // Receive callbacks + onTransformed: OnTransformedCallback, // Receive callbacks + options?: Partial // Pass options context if available ): Promise { let current: Record = obj @@ -117,10 +132,30 @@ export async function transformPath( let attempts = 0; let success = false; let lastError: unknown; + let valueToTransform = current[lastKey]; + const fullJsonPath = `${currentPath}/${lastKey}`; // Construct full path + + // Call onTransform before transformation + try { + valueToTransform = await onTransform(fullJsonPath, valueToTransform, options); + } catch (error) { + console.error(`Error in onTransform callback for path ${fullJsonPath}:`, error); + // Decide if you want to proceed with the original value or stop + } while (attempts < networkOptions.maxRetries && !success) { try { - current[lastKey] = await throttle(transform)(current[lastKey], `${currentPath}/${lastKey}`); + let transformedValue = await throttle(transform)(valueToTransform, fullJsonPath); + + // Call onTransformed after successful transformation + try { + transformedValue = await onTransformed(fullJsonPath, transformedValue, options); + } catch (error) { + console.error(`Error in onTransformed callback for path ${fullJsonPath}:`, error); + // Decide if you want to proceed with the transformed value or stop/modify + } + + current[lastKey] = transformedValue; // Assign potentially modified transformed value success = true; } catch (error) { lastError = error; @@ -135,17 +170,20 @@ export async function transformPath( } if (!success) { - errorCallback(currentPath, lastKey, lastError); + errorCallback(currentPath, lastKey, lastError); // Use currentPath (logical path) } } } else if (typeof current[lastKey] === 'object' && current[lastKey] !== null) { await transformObject( current[lastKey] as Record, transform, - '$.*', + '$.*', // Recurse on all properties networkOptions, errorCallback, - testCallback + testCallback, + onTransform, // Pass callbacks down + onTransformed, // Pass callbacks down + options // Pass options context down ) } } @@ -161,8 +199,15 @@ export interface TransformWithOptionsInput { network?: INetworkOptions errorCallback?: ErrorCallback filterCallback?: FilterCallback + onTransform?: OnTransformCallback // Add to options + onTransformed?: OnTransformedCallback // Add to options + kbotOptions?: Partial // Add kbot options context } +// Default no-op implementations for the new callbacks +const defaultOnTransform: OnTransformCallback = async (_, value) => value; +const defaultOnTransformed: OnTransformedCallback = async (_, transformedValue) => transformedValue; + export async function transformObjectWithOptions( obj: Record, transform: AsyncTransformer, @@ -173,7 +218,10 @@ export async function transformObjectWithOptions( targetPath = null, network = {}, errorCallback = defaultError, - filterCallback = testFilters(defaultFilters()) + filterCallback = testFilters(defaultFilters()), + onTransform = defaultOnTransform, // Use default if not provided + onTransformed = defaultOnTransformed, // Use default if not provided + kbotOptions // Destructure kbot options } = options; const networkOptions: Required = { @@ -189,7 +237,10 @@ export async function transformObjectWithOptions( jsonPath, networkOptions, errorCallback, - filterCallback + filterCallback, + onTransform, // Pass down + onTransformed, // Pass down + kbotOptions // Pass down kbot options ); } @@ -203,7 +254,10 @@ export async function transformObjectWithOptions( jsonPath, networkOptions, errorCallback, - filterCallback + filterCallback, + onTransform, // Pass down + onTransformed, // Pass down + kbotOptions // Pass down kbot options ); // Get paths from original object diff --git a/packages/kbot/src/examples/core/iterator-factory-example.ts b/packages/kbot/src/examples/core/iterator-factory-example.ts index d45c6fb2..7ce5d749 100644 --- a/packages/kbot/src/examples/core/iterator-factory-example.ts +++ b/packages/kbot/src/examples/core/iterator-factory-example.ts @@ -4,7 +4,9 @@ import * as fs from 'fs'; import type { IKBotTask } from '@polymech/ai-tools'; import { E_OPENROUTER_MODEL } from '../../models/cache/openrouter-models.js'; import { E_Mode } from '../../zod_schema.js'; -import { FieldMapping, createIterator, createLLMTransformer, CacheConfig, INetworkOptions, transform } from '../../iterator.js'; +import { FieldMapping, createIterator, createLLMTransformer, CacheConfig, INetworkOptions, transform, IOptions, removeEmptyObjects } from '../../iterator.js'; +import { OnTransformCallback, OnTransformedCallback } from '../../async-iterator.js'; +import { rm_cached_object } from '@polymech/cache'; /** * Notes for LLM modifications @@ -32,6 +34,9 @@ export async function simpleTransformExample() { model: MODEL, router: ROUTER, mode: E_Mode.COMPLETION + }, { + onTransform: simpleOnTransform, + onTransformed: simpleOnTransformed }); console.log("\nSimplified Transform Result:"); @@ -211,6 +216,37 @@ Do not add any extra fields not in the schema, and make sure to use the exact fi } ]; +// Example onTransform callback +const exampleOnTransform: OnTransformCallback = async (jsonPath, value, options) => { + console.log(` -> onTransform: Path='${jsonPath}', Original Value='${value.substring(0, 30)}...', Options Model='${options?.model}'`); + // Example: Prefix value before sending to LLM + if (jsonPath.includes('description')) { + return `[PRODUCT INFO] ${value}`; + } + return value; // Return original value if no modification needed +}; + +// Example onTransformed callback +const exampleOnTransformed: OnTransformedCallback = async (jsonPath, transformedValue, options) => { + console.log(` <- onTransformed: Path='${jsonPath}', Transformed Value='${transformedValue.substring(0, 30)}...', Options Model='${options?.model}'`); + // Example: Post-process the LLM response + if (jsonPath.includes('nutrition')) { + return `${transformedValue} [HEALTH FOCUS]`; + } + return transformedValue; // Return transformed value if no modification needed +}; + +// Simpler callbacks for the second example +const simpleOnTransform: OnTransformCallback = async (jsonPath, value) => { + console.log(` -> simpleOnTransform: Path='${jsonPath}'`); + return value; +}; + +const simpleOnTransformed: OnTransformedCallback = async (jsonPath, transformedValue) => { + console.log(` <- simpleOnTransformed: Path='${jsonPath}'`); + return transformedValue; +}; + // Error handler const errorCallback = (path: string, value: string, error: any) => { logger.error(`Error transforming ${path}: ${error.message}`); @@ -247,26 +283,56 @@ export async function factoryExample() { mode: E_Mode.COMPLETION }; + // --- Cache Clearing Logic --- + // Calculate the expected cache key for the object transformation + const objectCacheKey = removeEmptyObjects({ + data: JSON.stringify(exampleData), // Use the initial data state + mappings: fieldMappings.map(m => ({ + jsonPath: m.jsonPath, + targetPath: m.targetPath, + options: { + model: globalOptionsMixin.model, + router: globalOptionsMixin.router, + mode: globalOptionsMixin.mode, + prompt: m.options?.prompt + } + })) + }); + + const objectCacheNamespace = 'transformed-objects'; + console.log(`Attempting to clear cache for key in namespace '${objectCacheNamespace}' before first run...`); + try { + await rm_cached_object({ ca_options: objectCacheKey }, objectCacheNamespace); + console.log('Cache cleared successfully (or key did not exist).'); + } catch (error) { + console.warn('Failed to clear cache, proceeding anyway:', error); + } + // --- End Cache Clearing Logic --- + + // Combine all options including callbacks for createIterator + const iteratorOptions: IOptions = { + network: networkOptions, + errorCallback, + filterCallback: async () => true, + transformerFactory: (options) => createLLMTransformer(options, logger, cacheConfig), + logger, + cacheConfig: { + ...cacheConfig, + enabled: process.argv.includes('--no-cache') ? false : cacheConfig.enabled + }, + onTransform: exampleOnTransform, + onTransformed: exampleOnTransformed + }; + // Create an iterator factory instance const iterator = createIterator( data, globalOptionsMixin, - { - network: networkOptions, - errorCallback, - filterCallback: async () => true, - transformerFactory: (options) => createLLMTransformer(options, logger, cacheConfig), - logger, - cacheConfig: { - ...cacheConfig, - // Force a new response for format testing - enabled: process.argv.includes('--no-cache') ? false : cacheConfig.enabled - } - } + iteratorOptions ); // Use the iterator to transform the data - console.log("First run - should transform and cache results:"); + console.log("First run - should transform, run callbacks, and cache results:"); await iterator.transform(fieldMappings); const outputPath = path.resolve('./tests/test-data/core/iterator-factory-data.json'); @@ -309,17 +375,10 @@ export async function factoryExample() { const iterator2 = createIterator( data2, globalOptionsMixin, - { - network: networkOptions, - errorCallback, - filterCallback: async () => true, - transformerFactory: (options) => createLLMTransformer(options, logger, cacheConfig), - logger, - cacheConfig - } + iteratorOptions ); - // Should use cached values + // Should use cached values (callbacks won't run for cached object transform) await iterator2.transform(fieldMappings); console.log("\nBefore/After Comparison Example:"); diff --git a/packages/kbot/src/iterator.ts b/packages/kbot/src/iterator.ts index 87c22962..85ba97df 100644 --- a/packages/kbot/src/iterator.ts +++ b/packages/kbot/src/iterator.ts @@ -3,6 +3,8 @@ import { AsyncTransformer, ErrorCallback, FilterCallback, + OnTransformCallback, + OnTransformedCallback, defaultError, defaultFilters, testFilters, @@ -75,6 +77,8 @@ export interface IOptions { transformerFactory?: (options: IKBotTask) => AsyncTransformer; logger?: ILogger; cacheConfig?: CacheConfig; + onTransform?: OnTransformCallback; + onTransformed?: OnTransformedCallback; } const DEFAULT_CACHE_CONFIG: Required = { @@ -159,7 +163,9 @@ export function createIterator( filterCallback = testFilters(defaultFilters()), transformerFactory, logger = dummyLogger, - cacheConfig + cacheConfig, + onTransform, + onTransformed } = globalOptions; const networkOptions: Required = { @@ -234,7 +240,10 @@ export function createIterator( targetPath, network: networkOptions, errorCallback, - filterCallback + filterCallback, + onTransform, + onTransformed, + kbotOptions: mergedOptions } ); } diff --git a/packages/kbot/tests/test-data/core/iterator-factory-data.json b/packages/kbot/tests/test-data/core/iterator-factory-data.json index 9fafc397..29ee672f 100644 --- a/packages/kbot/tests/test-data/core/iterator-factory-data.json +++ b/packages/kbot/tests/test-data/core/iterator-factory-data.json @@ -4,22 +4,22 @@ { "id": "f1", "name": "apple", - "description": "A delightfully crisp and juicy fruit bursting with natural sweetness.", + "description": "A deliciously sweet, crisp, and refreshing fruit packed with flavor.", "details": { "color": "red", "origin": "Worldwide", - "nutrition": "Rich in fiber and vitamin D, this food supports healthy digestion, helps regulate blood sugar levels, and promotes strong bones by enhancing calcium absorption and supporting the immune system." + "nutrition": "Rich in fiber and vitamin D, this food supports healthy digestion, helps regulate blood sugar levels, and promotes strong bones by enhancing calcium absorption and supporting the immune system. [HEALTH FOCUS]" }, "marketingName": "Sure! Here are a few appealing marketing name options for \"apple\":\n\n1. Crimson Bliss\n2. Orchard Jewel\n3. Scarlet Crunch\n4. Nature’s Candy\n5. Ruby Crisp\n6. SweetHarvest\n7. Eden Bite\n8. Golden Orchard (if it’s a yellow variety)\n9. PurePom\n10. FreshMuse\n\nLet me know if you'd like names tailored to a specific apple variety or target audience!" }, { "id": "f2", "name": "banana", - "description": "A sweet, sun-ripened yellow fruit bursting with tropical flavor.", + "description": "Vibrant, sun-kissed yellow tropical fruit bursting with sweet flavor", "details": { "color": "yellow", "origin": "Southeast Asia", - "nutrition": "High in potassium, which helps regulate blood pressure, supports proper muscle function, and maintains fluid balance in the body, contributing to overall cardiovascular and muscular health." + "nutrition": "High in potassium, which helps regulate blood pressure, supports proper muscle function, and maintains fluid balance in the body, contributing to overall cardiovascular and muscular health. [HEALTH FOCUS]" }, "marketingName": "Golden Delight" }