From 181a655d9472dc8055f391a439559a3599dbfc34 Mon Sep 17 00:00:00 2001 From: babayaga Date: Mon, 7 Apr 2025 17:23:02 +0200 Subject: [PATCH] kbot iterator example: md-ast transformer --- packages/kbot/dist-in/commands/renderer.d.ts | 6 + packages/kbot/dist-in/commands/renderer.js | 51 ++ .../core/iterator-markdown-example.d.ts | 1 + .../core/iterator-markdown-example.js | 275 ++++++ packages/kbot/dist-in/examples/index.d.ts | 1 + packages/kbot/dist-in/examples/index.js | 3 +- packages/kbot/dist-in/index.d.ts | 2 +- packages/kbot/dist-in/iterator.js | 30 +- packages/kbot/dist-in/merge.d.ts | 4 + packages/kbot/dist-in/merge.js | 30 + .../models/cache/openai-models-free.d.ts | 2 + .../models/cache/openai-models-free.js | 4 + .../models/cache/openai-models-tools.d.ts | 2 + .../models/cache/openai-models-tools.js | 4 + .../models/cache/openrouter-models-tools.d.ts | 2 + .../models/cache/openrouter-models-tools.js | 4 + packages/kbot/dist-in/reference/kbot.d.ts | 7 + packages/kbot/dist-in/reference/kbot.js | 94 +++ packages/kbot/dist-in/splitter.d.ts | 1 + packages/kbot/dist-in/splitter.js | 33 + .../dist-in/utils/__tests__/array.test.d.ts | 1 + .../dist-in/utils/__tests__/array.test.js | 25 + .../dist-in/utils/__tests__/file.test.d.ts | 1 + .../kbot/dist-in/utils/__tests__/file.test.js | 31 + .../dist-in/utils/__tests__/input.test.d.ts | 1 + .../dist-in/utils/__tests__/input.test.js | 77 ++ .../dist-in/utils/__tests__/script.test.d.ts | 1 + .../dist-in/utils/__tests__/script.test.js | 31 + .../kbot/false/_update-notifier-last-checked | 0 packages/kbot/logs/params.json | 4 +- packages/kbot/package-lock.json | 785 +++++++++++++++++- packages/kbot/package.json | 8 +- .../core/iterator-markdown-example.ts | 298 +++++++ packages/kbot/src/examples/index.ts | 3 +- packages/kbot/src/index.ts | 3 +- packages/kbot/src/iterator.ts | 26 +- .../kbot/tests/test-data/core/md-test-out.md | 37 + packages/kbot/tests/test-data/core/md-test.md | 41 + packages/kbot/tsconfig.json | 18 +- 39 files changed, 1912 insertions(+), 35 deletions(-) create mode 100644 packages/kbot/dist-in/commands/renderer.d.ts create mode 100644 packages/kbot/dist-in/commands/renderer.js create mode 100644 packages/kbot/dist-in/examples/core/iterator-markdown-example.d.ts create mode 100644 packages/kbot/dist-in/examples/core/iterator-markdown-example.js create mode 100644 packages/kbot/dist-in/merge.d.ts create mode 100644 packages/kbot/dist-in/merge.js create mode 100644 packages/kbot/dist-in/models/cache/openai-models-free.d.ts create mode 100644 packages/kbot/dist-in/models/cache/openai-models-free.js create mode 100644 packages/kbot/dist-in/models/cache/openai-models-tools.d.ts create mode 100644 packages/kbot/dist-in/models/cache/openai-models-tools.js create mode 100644 packages/kbot/dist-in/models/cache/openrouter-models-tools.d.ts create mode 100644 packages/kbot/dist-in/models/cache/openrouter-models-tools.js create mode 100644 packages/kbot/dist-in/reference/kbot.d.ts create mode 100644 packages/kbot/dist-in/reference/kbot.js create mode 100644 packages/kbot/dist-in/splitter.d.ts create mode 100644 packages/kbot/dist-in/splitter.js create mode 100644 packages/kbot/dist-in/utils/__tests__/array.test.d.ts create mode 100644 packages/kbot/dist-in/utils/__tests__/array.test.js create mode 100644 packages/kbot/dist-in/utils/__tests__/file.test.d.ts create mode 100644 packages/kbot/dist-in/utils/__tests__/file.test.js create mode 100644 packages/kbot/dist-in/utils/__tests__/input.test.d.ts create mode 100644 packages/kbot/dist-in/utils/__tests__/input.test.js create mode 100644 packages/kbot/dist-in/utils/__tests__/script.test.d.ts create mode 100644 packages/kbot/dist-in/utils/__tests__/script.test.js create mode 100644 packages/kbot/false/_update-notifier-last-checked create mode 100644 packages/kbot/src/examples/core/iterator-markdown-example.ts create mode 100644 packages/kbot/tests/test-data/core/md-test-out.md create mode 100644 packages/kbot/tests/test-data/core/md-test.md diff --git a/packages/kbot/dist-in/commands/renderer.d.ts b/packages/kbot/dist-in/commands/renderer.d.ts new file mode 100644 index 00000000..bcb655da --- /dev/null +++ b/packages/kbot/dist-in/commands/renderer.d.ts @@ -0,0 +1,6 @@ +/** + * Renders the given Markdown string in a Blessed terminal UI. + * + * @param markdownContent - The Markdown content to display. + */ +export declare function displayMarkdown(markdownContent: string): void; diff --git a/packages/kbot/dist-in/commands/renderer.js b/packages/kbot/dist-in/commands/renderer.js new file mode 100644 index 00000000..3adedaca --- /dev/null +++ b/packages/kbot/dist-in/commands/renderer.js @@ -0,0 +1,51 @@ +// src/markdown-blessed.ts +import * as blessed from 'blessed'; +import { marked } from 'marked'; +/** + * Define a custom renderer where the `image` method + * uses Marked's new signature: image({ href, title, text }: Tokens.Image). + */ +const customRenderer = { + image({ href, title, text }) { + // Provide a textual placeholder instead of an actual image + return `\n[IMAGE: ${text || 'No Alt'}](${href || 'No Href'})\n`; + }, + // (Optional) you can override other renderer methods here +}; +// We tell Marked to use our custom renderer +// Alternatively, you can pass { renderer: customRenderer } directly to marked(). +marked.use({ renderer: customRenderer }); +/** + * Renders the given Markdown string in a Blessed terminal UI. + * + * @param markdownContent - The Markdown content to display. + */ +export function displayMarkdown(markdownContent) { + // 1) Create Blessed screen + const screen = blessed.screen({ + smartCSR: true, + title: 'Markdown Example with Blessed' + }); + // 2) Create a scrollable box for the text + const box = blessed.box({ + parent: screen, + top: 'center', + left: 'center', + width: '100%', + height: '100%', + keys: true, + vi: true, + mouse: true, + border: 'none', + alwaysScroll: true, + scrollable: true + }); + // 3) Parse the markdown into a string using our renderer + const parsedContent = marked(markdownContent); + // 4) Set the box content + box.setContent(parsedContent); + // 5) Focus and render + box.focus(); + screen.render(); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvcmVuZGVyZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEJBQTBCO0FBRTFCLE9BQU8sS0FBSyxPQUFPLE1BQU0sU0FBUyxDQUFBO0FBQ2xDLE9BQU8sRUFBRSxNQUFNLEVBQVUsTUFBTSxRQUFRLENBQUE7QUFDdkM7OztHQUdHO0FBQ0gsTUFBTSxjQUFjLEdBQUc7SUFDckIsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQWdCO1FBQ3ZDLDJEQUEyRDtRQUMzRCxPQUFPLGFBQWEsSUFBSSxJQUFJLFFBQVEsS0FBSyxJQUFJLElBQUksU0FBUyxLQUFLLENBQUM7SUFDbEUsQ0FBQztJQUNELDBEQUEwRDtDQUMzRCxDQUFDO0FBRUYsNENBQTRDO0FBQzVDLGlGQUFpRjtBQUNqRixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7QUFFekM7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsZUFBdUI7SUFDckQsMkJBQTJCO0lBQzNCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDNUIsUUFBUSxFQUFFLElBQUk7UUFDZCxLQUFLLEVBQUUsK0JBQStCO0tBQ3ZDLENBQUMsQ0FBQztJQUVILDBDQUEwQztJQUMxQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3RCLE1BQU0sRUFBRSxNQUFNO1FBQ2QsR0FBRyxFQUFFLFFBQVE7UUFDYixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxNQUFNO1FBQ2IsTUFBTSxFQUFFLE1BQU07UUFDZCxJQUFJLEVBQUUsSUFBSTtRQUNWLEVBQUUsRUFBRSxJQUFJO1FBQ1IsS0FBSyxFQUFFLElBQUk7UUFDWCxNQUFNLEVBQUUsTUFBTTtRQUNkLFlBQVksRUFBRSxJQUFJO1FBQ2xCLFVBQVUsRUFBRSxJQUFJO0tBQ2pCLENBQUMsQ0FBQztJQUVILHlEQUF5RDtJQUN6RCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7SUFFOUMseUJBQXlCO0lBQ3pCLEdBQUcsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7SUFFOUIsc0JBQXNCO0lBQ3RCLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNaLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUVsQixDQUFDIn0= \ No newline at end of file diff --git a/packages/kbot/dist-in/examples/core/iterator-markdown-example.d.ts b/packages/kbot/dist-in/examples/core/iterator-markdown-example.d.ts new file mode 100644 index 00000000..cb228352 --- /dev/null +++ b/packages/kbot/dist-in/examples/core/iterator-markdown-example.d.ts @@ -0,0 +1 @@ +export declare function markdownTransformExample(useCache?: boolean): Promise; diff --git a/packages/kbot/dist-in/examples/core/iterator-markdown-example.js b/packages/kbot/dist-in/examples/core/iterator-markdown-example.js new file mode 100644 index 00000000..bb6f3461 --- /dev/null +++ b/packages/kbot/dist-in/examples/core/iterator-markdown-example.js @@ -0,0 +1,275 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkStringify from 'remark-stringify'; +import { visit } from 'unist-util-visit'; +import { sync as write } from "@polymech/fs/write"; +import { E_OPENROUTER_MODEL } from '../../models/cache/openrouter-models.js'; +import { E_Mode } from '../../zod_schema.js'; +import { transform, createLLMTransformer } from '../../iterator.js'; +/** + * Notes for LLM modifications + * + * - to test it, use `npm run examples:iterator-markdown` (after adding the script) + * - demonstrates applying the iterator to a Markdown file parsed into an AST (mdast) + * - targets headings, paragraphs, and table cells for transformation + * - uses the 'format' option for structured data extraction + * - uses 'onTransform' callback + */ +const MODEL = E_OPENROUTER_MODEL.MODEL_OPENAI_GPT_4O_MINI; // Corrected model name +const ROUTER = 'openrouter'; +const INPUT_MD_PATH = path.resolve('./tests/test-data/core/md-test.md'); +const OUTPUT_MD_PATH = path.resolve('./tests/test-data/core/md-test-out.md'); +// Basic logger +const logger = { + info: (message) => console.log(`INFO: ${message}`), + warn: (message) => console.log(`WARN: ${message}`), + error: (message, error) => console.error(`ERROR: ${message}`, error) +}; +// This transformer factory uses the standard createLLMTransformer. +// It assumes the iterator passes the STRING value found at the JSONPath. +// It does NOT handle direct AST node modification for targetPath=null cases, +// because it only receives the string value, not the node context. +// In-place modification of the AST based on primitive value paths is complex +// with this generic iterator and requires a different approach (e.g., post-processing). +// Transformations using targetPath (like analysisResult) will work as expected +// if the JSONPath targets the NODE containing the text. +function getLLMTransformerForMdast(options, baseLogger = logger, cacheConfig) { + const llmTransformer = createLLMTransformer(options, baseLogger, cacheConfig); + // Just return the basic LLM transformer - it expects a string and returns a string. + return llmTransformer; +} +// Define field mappings for the mdast structure +const fieldMappings = [ + { + // Target text value within H1-H5 headings' children + jsonPath: '$.children[?(@.type=="heading" && @.depth <= 5)].children[?(@.type=="text")].value', + targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations) + options: { + prompt: 'Rewrite this heading to be more concise and impactful (max 5 words).' + } + }, + { + // Target the specific paragraph NODE in Chapter 4 for structured analysis. + // The transformer will extract text from the node passed to it. + // Using targetPath='analysisResult' stores the LLM output on the node itself. + jsonPath: '$.children[?(@.type=="paragraph" && @.children[0].value.includes("results"))]', + targetPath: 'analysisResult', // Store result in a new property on the paragraph node + options: { + prompt: 'Extract keywords and sentiment from this text.', + format: { + type: "object", + properties: { + sentiment: { + type: "string", + enum: ["positive", "neutral", "negative"], + description: "Overall sentiment" + }, + keywords: { + type: "array", + items: { type: "string" }, + description: "Main keywords (max 5)" + } + }, + required: ["sentiment", "keywords"] + } + } + }, + { + // Target text value within paragraphs' children + jsonPath: '$.children[?(@.type=="paragraph")].children[?(@.type=="text")].value', + targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations) + options: { + prompt: 'Summarize this paragraph in one short sentence (max 15 words).' + } + }, + { + // Target text value within table cells' children + jsonPath: '$.children[?(@.type=="table")].children[*].children[*].children[?(@.type=="text")].value', + targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations) + options: { + prompt: 'Rephrase this table cell content slightly.' + } + } +]; +// Example onTransform callback for Markdown +const mdOnTransform = async (jsonPath, value, options) => { + let textValue = typeof value === 'string' ? value : JSON.stringify(value); // Handle potential node objects if path isn't perfect + console.log(` -> mdOnTransform: Path='${jsonPath}', Original Value='${textValue.substring(0, 50)}...'`); + // No modification needed here, just logging + return textValue; // Must return the string value the LLM transformer expects +}; +export async function markdownTransformExample(useCache = true) { + console.log("========================================"); + console.log("Starting Markdown transform example"); + console.log(`Using cache: ${useCache}`); + console.log("========================================"); + try { + // 1. Read Markdown file + const markdownInput = fs.readFileSync(INPUT_MD_PATH, 'utf8'); + // 2. Parse Markdown to AST + const processor = unified().use(remarkParse); + const ast = processor.parse(markdownInput); + // Make a deep copy to avoid modifying the original AST if transform fails + // Note: Standard deepClone might not work perfectly with complex AST nodes (position, data fields). + // For this example, JSON stringify/parse is a common workaround, but beware of data loss. + let astToTransform = JSON.parse(JSON.stringify(ast)); + // 3. Define global options and iterator options + const globalOptionsMixin = { + model: MODEL, + router: ROUTER, + mode: E_Mode.COMPLETION, + }; + const iteratorOptions = { + // We provide our custom transformer factory + transformerFactory: (opts) => getLLMTransformerForMdast(opts, logger, { enabled: useCache }), + logger: logger, + cacheConfig: { enabled: useCache, namespace: 'markdown-transforms' }, + // onTransform receives the value matched by jsonPath (can be string or node). + // It must return the STRING to be transformed by the LLM. + onTransform: async (jsonPath, value, kbotOptions) => { + let textContent = ''; + // Check if the value is a node object or just a string + if (typeof value === 'string') { + textContent = value; + console.log(` -> onTransform String Value: Path='${jsonPath}', Value='${textContent.substring(0, 50)}...'`); + } + else if (typeof value === 'object' && value !== null) { + // Attempt to extract text if it's a node (e.g., for the analysisResult mapping) + const node = value; // Basic type assertion + if ((node.type === 'heading' || node.type === 'paragraph' || node.type === 'tableCell') && node.children?.length === 1 && node.children[0].type === 'text') { + textContent = node.children[0].value || ''; + } + else if (node.type === 'text') { + textContent = node.value || ''; + } + else if (Array.isArray(node.children)) { // Handle complex children + textContent = node.children + .filter((child) => child.type === 'text' || child.type === 'inlineCode') + .map((child) => child.value) + .join(''); + } + console.log(` -> onTransform AST Node: Path='${jsonPath}', Node Type='${node?.type}', Extracted Text='${textContent.substring(0, 50)}...'`); + } + else { + console.log(` -> onTransform Unexpected Value Type: Path='${jsonPath}', Type='${typeof value}'`); + } + // Return the extracted string for the LLM transformer + return textContent; + }, + errorCallback: (path, value, error) => { + if (error instanceof Error) { + logger.error(`Error processing path ${path}: ${error.message}`, error); + } + else { + logger.error(`Error processing path ${path}: ${error}`, error); + } + }, + filterCallback: async (value, jsonPath) => { + // Allow transformation if the value is an object (likely an AST node targeted directly) + if (typeof value === 'object' && value !== null) { + return true; + } + // If it's a string, apply the default string filter logic + if (typeof value === 'string') { + // Reuse the default isValidString filter logic for strings + const allow = value.trim() !== ''; + if (!allow) { + logger.info(`Filter: Skipping empty string at ${jsonPath}`); + } + return allow; + } + // Skip other types (numbers, booleans, null, undefined) + logger.warn(`Filter: Skipping non-string/non-object value type (${typeof value}) at ${jsonPath}`); + return false; + } + }; + // 4. Use the transform function + console.log("Applying transformations to AST..."); + // The 'transform' function iterates based on JSONPath and applies the transformerFactory's result + // It modifies the 'astToTransform' object in place. + await transform(astToTransform, // Pass the AST object + fieldMappings, globalOptionsMixin, iteratorOptions); + // *** Add logging before visit *** + console.log("\n[DEBUG] Inspecting AST before visit call:"); + try { + // Attempt to find the specific paragraph node expected to have analysisResult + // NOTE: This relies on index/structure and might be brittle + const potentialNode = astToTransform.children?.find((node) => node.type === 'paragraph' && + node.children?.[0]?.value?.includes("results")); + if (potentialNode) { + console.log("[DEBUG] Found potential node:", JSON.stringify(potentialNode, null, 2)); + console.log(`[DEBUG] Does potential node have analysisResult? ${potentialNode.hasOwnProperty('analysisResult')}`); + } + else { + console.log("[DEBUG] Could not find the target paragraph node directly before visit."); + } + console.log("---------------------------------------"); + } + catch (e) { + console.error("[DEBUG] Error during pre-visit inspection:", e); + } + // Retrieve the structured analysis result (if any) + // Note: The 'analysisResult' was added as a new property to the AST node by the mapping. + // We need to find that node again to see the result. This is clumsy. + let analysisData = null; + try { + visit(astToTransform, 'paragraph', (node) => { + if (node.analysisResult) { + analysisData = node.analysisResult; + // Optional: Remove the temporary property from the AST before stringifying + // delete node.analysisResult; + } + }); + if (analysisData) { + console.log("\nStructured Analysis Result:"); + // The LLM might return a stringified JSON, try parsing it + try { + const parsedResult = typeof analysisData === 'string' ? JSON.parse(analysisData) : analysisData; + console.log(JSON.stringify(parsedResult, null, 2)); + } + catch (e) { + console.log("Analysis result (raw):", analysisData); + } + } + else { + console.log("\nStructured Analysis Result not found on AST (check targetPath logic and LLM response)."); + } + } + catch (e) { + logger.error("Error visiting AST for analysis result retrieval:", e); + } + // 5. Stringify the modified AST back to Markdown + console.log("\nStringifying transformed AST..."); + const processorStringify = unified().use(remarkStringify); + // Stringify might fail if the AST structure became invalid during transformation + const outputMarkdown = processorStringify.stringify(astToTransform); + // 6. Write the output file + console.log(`Writing output to: ${OUTPUT_MD_PATH}`); + const outputDir = path.dirname(OUTPUT_MD_PATH); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + write(OUTPUT_MD_PATH, outputMarkdown); + console.log("Markdown transformation complete."); + return astToTransform; // Return the transformed AST + } + catch (error) { + logger.error("ERROR during Markdown transformation:", error); + throw error; + } +} +// Add run logic +if (process.argv[1] && process.argv[1].includes('iterator-markdown-example')) { + const noCache = process.argv.includes('--no-cache'); + markdownTransformExample(!noCache) + .then(() => { + console.log("\nMarkdown example finished successfully."); + }) + .catch(error => { + console.error("\nMarkdown example failed:", error); + process.exit(1); // Exit with error code + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3ItbWFya2Rvd24tZXhhbXBsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9leGFtcGxlcy9jb3JlL2l0ZXJhdG9yLW1hcmtkb3duLWV4YW1wbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxlQUFlLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDN0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdDLE9BQU8sRUFBZ0IsU0FBUyxFQUFZLG9CQUFvQixFQUF3QixNQUFNLG1CQUFtQixDQUFDO0FBR2xIOzs7Ozs7OztHQVFHO0FBRUgsTUFBTSxLQUFLLEdBQUcsa0JBQWtCLENBQUMsd0JBQXdCLENBQUMsQ0FBQyx1QkFBdUI7QUFDbEYsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDO0FBQzVCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsbUNBQW1DLENBQUMsQ0FBQztBQUN4RSxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7QUFFN0UsZUFBZTtBQUNmLE1BQU0sTUFBTSxHQUFZO0lBQ3BCLElBQUksRUFBRSxDQUFDLE9BQWUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLE9BQU8s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 \ No newline at end of file diff --git a/packages/kbot/dist-in/examples/index.d.ts b/packages/kbot/dist-in/examples/index.d.ts index 8ff22137..6854b611 100644 --- a/packages/kbot/dist-in/examples/index.d.ts +++ b/packages/kbot/dist-in/examples/index.d.ts @@ -1,2 +1,3 @@ export * from './core/async-iterator-example.js'; export * from './core/iterator-factory-example.js'; +export * from './core/iterator-markdown-example.js'; diff --git a/packages/kbot/dist-in/examples/index.js b/packages/kbot/dist-in/examples/index.js index c550245b..a5672f67 100644 --- a/packages/kbot/dist-in/examples/index.js +++ b/packages/kbot/dist-in/examples/index.js @@ -1,4 +1,5 @@ // Export examples export * from './core/async-iterator-example.js'; export * from './core/iterator-factory-example.js'; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXhhbXBsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0JBQWtCO0FBQ2xCLGNBQWMsa0NBQWtDLENBQUM7QUFDakQsY0FBYyxvQ0FBb0MsQ0FBQyJ9 \ No newline at end of file +export * from './core/iterator-markdown-example.js'; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXhhbXBsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0JBQWtCO0FBQ2xCLGNBQWMsa0NBQWtDLENBQUM7QUFDakQsY0FBYyxvQ0FBb0MsQ0FBQztBQUNuRCxjQUFjLHFDQUFxQyxDQUFDIn0= \ No newline at end of file diff --git a/packages/kbot/dist-in/index.d.ts b/packages/kbot/dist-in/index.d.ts index a758d85f..7bdd700d 100644 --- a/packages/kbot/dist-in/index.d.ts +++ b/packages/kbot/dist-in/index.d.ts @@ -11,4 +11,4 @@ export * from './zod_schema.js'; export { E_OPENAI_MODEL } from './models/cache/openai-models.js'; export { E_OPENROUTER_MODEL } from './models/cache/openrouter-models.js'; export { E_OPENROUTER_MODEL_FREE } from './models/cache/openrouter-models-free.js'; -export { IKBotTask } from '@polymech/ai-tools'; +export type { IKBotTask } from '@polymech/ai-tools'; diff --git a/packages/kbot/dist-in/iterator.js b/packages/kbot/dist-in/iterator.js index 890e394c..7f2fb55b 100644 --- a/packages/kbot/dist-in/iterator.js +++ b/packages/kbot/dist-in/iterator.js @@ -114,22 +114,29 @@ export function createIterator(obj, optionsMixin, globalOptions = {}) { return { createTransformer, transform: async (mappings) => { + // *** Object Cache Check (Start) *** + let objectCacheKey; if (config.enabled) { - const objectCacheKey = createObjectCacheKey(obj, mappings); + objectCacheKey = createObjectCacheKey(obj, mappings); // Key based on initial state const cachedObject = await get_cached_object({ ca_options: objectCacheKey }, 'transformed-objects'); if (cachedObject?.content) { logger.info('Using cached transformed object'); + // Clear the original object before merging cache to avoid partial states + Object.keys(obj).forEach(key => delete obj[key]); deepMerge(obj, cachedObject.content); return; } } - // If no cache hit or caching disabled, perform the transformations - const transformedObj = JSON.parse(JSON.stringify(obj)); + // *** Object Cache Check (End) *** + // If no cache hit or caching disabled, perform the transformations directly on 'obj' + // REMOVED: const transformedObj = JSON.parse(JSON.stringify(obj)); for (const mapping of mappings) { const mergedOptions = { ...optionsMixin, ...mapping.options }; const { jsonPath, targetPath = null } = mapping; const transformer = createTransformer(mergedOptions); - await transformObjectWithOptions(transformedObj, transformer, { + // Call transformObjectWithOptions directly on the original 'obj' + await transformObjectWithOptions(obj, // <<< Operate directly on obj + transformer, { jsonPath, targetPath, network: networkOptions, @@ -140,14 +147,15 @@ export function createIterator(obj, optionsMixin, globalOptions = {}) { kbotOptions: mergedOptions }); } - // Cache the transformed object - if (config.enabled) { - const objectCacheKey = createObjectCacheKey(obj, mappings); - await set_cached_object({ ca_options: objectCacheKey }, 'transformed-objects', { content: transformedObj }, { expiration: config.expiration }); + // *** Object Cache Setting (Start) *** + // Cache the final state of the modified 'obj' + if (config.enabled && objectCacheKey) { // Ensure key was generated + await set_cached_object({ ca_options: objectCacheKey }, 'transformed-objects', { content: obj }, // <<< Cache the final obj + { expiration: config.expiration }); logger.info('Cached transformed object'); } - // Apply the transformations to the original object - deepMerge(obj, transformedObj); + // *** Object Cache Setting (End) *** + // REMOVED: deepMerge(obj, transformedObj); } }; } @@ -170,4 +178,4 @@ export async function transform(obj, mappings, optionsMixin = {}, options = {}) await iterator.transform(mappings); return obj; } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaXRlcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQU1ILFlBQVksRUFDWixjQUFjLEVBQ2QsV0FBVyxFQUNYLDBCQUEwQixFQUUxQix1QkFBdUIsRUFDMUIsTUFBTSxxQkFBcUIsQ0FBQTtBQUM1QixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFvQixNQUFNLGlCQUFpQixDQUFBO0FBaUJ4RixNQUFNLFdBQVcsR0FBWTtJQUN6QixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO0lBQ2QsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7Q0FDbEIsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBUSxFQUFPLEVBQUU7SUFDaEQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1FBQUUsT0FBTyxHQUFHLENBQUM7SUFDbEQsS0FBSyxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNwQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDcEIsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsU0FBUztRQUNoRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVE7WUFDdkIsQ0FBQyxHQUFHLElBQUksT0FBTyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxRQUFRLENBQUMsRUFDN0UsQ0FBQztZQUNDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMs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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/dist-in/merge.d.ts b/packages/kbot/dist-in/merge.d.ts new file mode 100644 index 00000000..891029f3 --- /dev/null +++ b/packages/kbot/dist-in/merge.d.ts @@ -0,0 +1,4 @@ +export declare const deepMerge: (target: string, source: any) => Promise; +export declare const mergers: { + json: (target: string, source: any) => Promise; +}; diff --git a/packages/kbot/dist-in/merge.js b/packages/kbot/dist-in/merge.js new file mode 100644 index 00000000..5427aaf9 --- /dev/null +++ b/packages/kbot/dist-in/merge.js @@ -0,0 +1,30 @@ +import { isString } from '@polymech/core/primitives'; +import { sync as read } from '@polymech/fs/read'; +import { logger } from './index.js'; +import { deepmerge as merge } from 'deepmerge-ts'; +export const deepMerge = async (target, source) => { + if (!isString(target) || !source) { + logger.error(`Invalid deepmerge parameters:`, target, source); + return source; + } + target = read(target, 'json') || []; + try { + source = isString(source) ? JSON.parse(source) : source; + } + catch (e) { + logger.error('Error parsing completion:', e); + return source; + } + try { + const ret = merge(target, source); + return JSON.stringify(ret, null, 2); + } + catch (error) { + logger.error('Error merging completion:', error); + } + return target; +}; +export const mergers = { + json: deepMerge +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbWVyZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVuQyxPQUFPLEVBQUUsU0FBUyxJQUFJLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUNqRCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsS0FBSyxFQUFFLE1BQWMsRUFBRSxNQUFXLEVBQUUsRUFBRTtJQUMzRCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0IsTUFBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDN0QsT0FBTyxNQUFNLENBQUE7SUFDakIsQ0FBQztJQUNELE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBUSxJQUFJLEVBQUUsQ0FBQTtJQUMxQyxJQUFJLENBQUM7UUFDRCxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7SUFDM0QsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQzVDLE9BQU8sTUFBTSxDQUFBO0lBQ2pCLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ3ZDLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNwRCxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQyxDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUNwQjtJQUNJLElBQUksRUFBRSxTQUFTO0NBQ2xCLENBQUEifQ== \ No newline at end of file diff --git a/packages/kbot/dist-in/models/cache/openai-models-free.d.ts b/packages/kbot/dist-in/models/cache/openai-models-free.d.ts new file mode 100644 index 00000000..daffce17 --- /dev/null +++ b/packages/kbot/dist-in/models/cache/openai-models-free.d.ts @@ -0,0 +1,2 @@ +export declare enum E_OPENAI_MODEL_FREE { +} diff --git a/packages/kbot/dist-in/models/cache/openai-models-free.js b/packages/kbot/dist-in/models/cache/openai-models-free.js new file mode 100644 index 00000000..3e840ecc --- /dev/null +++ b/packages/kbot/dist-in/models/cache/openai-models-free.js @@ -0,0 +1,4 @@ +export var E_OPENAI_MODEL_FREE; +(function (E_OPENAI_MODEL_FREE) { +})(E_OPENAI_MODEL_FREE || (E_OPENAI_MODEL_FREE = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLW1vZGVscy1mcmVlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVscy9jYWNoZS9vcGVuYWktbW9kZWxzLWZyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFOLElBQVksbUJBRVg7QUFGRCxXQUFZLG1CQUFtQjtBQUUvQixDQUFDLEVBRlcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQUU5QiJ9 \ No newline at end of file diff --git a/packages/kbot/dist-in/models/cache/openai-models-tools.d.ts b/packages/kbot/dist-in/models/cache/openai-models-tools.d.ts new file mode 100644 index 00000000..9fea33c9 --- /dev/null +++ b/packages/kbot/dist-in/models/cache/openai-models-tools.d.ts @@ -0,0 +1,2 @@ +export declare enum E_OPENAI_MODEL { +} diff --git a/packages/kbot/dist-in/models/cache/openai-models-tools.js b/packages/kbot/dist-in/models/cache/openai-models-tools.js new file mode 100644 index 00000000..b2464fe4 --- /dev/null +++ b/packages/kbot/dist-in/models/cache/openai-models-tools.js @@ -0,0 +1,4 @@ +export var E_OPENAI_MODEL; +(function (E_OPENAI_MODEL) { +})(E_OPENAI_MODEL || (E_OPENAI_MODEL = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLW1vZGVscy10b29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2RlbHMvY2FjaGUvb3BlbmFpLW1vZGVscy10b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxjQUVYO0FBRkQsV0FBWSxjQUFjO0FBRTFCLENBQUMsRUFGVyxjQUFjLEtBQWQsY0FBYyxRQUV6QiJ9 \ No newline at end of file diff --git a/packages/kbot/dist-in/models/cache/openrouter-models-tools.d.ts b/packages/kbot/dist-in/models/cache/openrouter-models-tools.d.ts new file mode 100644 index 00000000..f9513892 --- /dev/null +++ b/packages/kbot/dist-in/models/cache/openrouter-models-tools.d.ts @@ -0,0 +1,2 @@ +export declare enum E_OPENROUTER_MODEL { +} diff --git a/packages/kbot/dist-in/models/cache/openrouter-models-tools.js b/packages/kbot/dist-in/models/cache/openrouter-models-tools.js new file mode 100644 index 00000000..0bed6e68 --- /dev/null +++ b/packages/kbot/dist-in/models/cache/openrouter-models-tools.js @@ -0,0 +1,4 @@ +export var E_OPENROUTER_MODEL; +(function (E_OPENROUTER_MODEL) { +})(E_OPENROUTER_MODEL || (E_OPENROUTER_MODEL = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbnJvdXRlci1tb2RlbHMtdG9vbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9kZWxzL2NhY2hlL29wZW5yb3V0ZXItbW9kZWxzLXRvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUVYO0FBRkQsV0FBWSxrQkFBa0I7QUFFOUIsQ0FBQyxFQUZXLGtCQUFrQixLQUFsQixrQkFBa0IsUUFFN0IifQ== \ No newline at end of file diff --git a/packages/kbot/dist-in/reference/kbot.d.ts b/packages/kbot/dist-in/reference/kbot.d.ts new file mode 100644 index 00000000..040639e6 --- /dev/null +++ b/packages/kbot/dist-in/reference/kbot.d.ts @@ -0,0 +1,7 @@ +import { TemplateProps, TemplateContext } from "./kbot-templates.js"; +export interface Props extends TemplateProps { + context?: TemplateContext; +} +export declare const filter: (content: string, tpl?: string, opts?: Props) => Promise; +export declare const template_filter: (text: string, template: string, context?: TemplateContext) => Promise; +export declare const getFilterOptions: (content: string, template: any, opts?: Props) => any; diff --git a/packages/kbot/dist-in/reference/kbot.js b/packages/kbot/dist-in/reference/kbot.js new file mode 100644 index 00000000..45cc11d4 --- /dev/null +++ b/packages/kbot/dist-in/reference/kbot.js @@ -0,0 +1,94 @@ +import { get_cached_object, set_cached_object, rm_cached_object } from "@polymech/cache"; +import { run, OptionsSchema } from "@polymech/kbot-d"; +import { resolveVariables } from "@polymech/commons/variables"; +import { logger, env } from "./index.js"; +import { removeEmptyObjects } from "@/base/objects.js"; +import { LLM_CACHE } from "@/config/config.js"; +import { TemplateContext, createTemplates } from "./kbot-templates.js"; +export const filter = async (content, tpl = 'howto', opts = {}) => { + if (!content || content.length < 20) { + return content; + } + const context = opts.context || TemplateContext.COMMONS; + const templates = createTemplates(context); + if (!templates[tpl]) { + return content; + } + const template = typeof templates[tpl] === 'function' ? templates[tpl]() : templates[tpl]; + const options = getFilterOptions(content, template, opts); + const cache_key_obj = { + content, + tpl, + context, + ...options, + filters: [], + tools: [] + }; + const ca_options = JSON.parse(JSON.stringify(removeEmptyObjects(cache_key_obj))); + let cached; + try { + cached = await get_cached_object({ ca_options }, 'kbot'); + } + catch (e) { + logger.error(`Failed to get cached object for ${content.substring(0, 20)}`, e); + } + if (cached) { + if (LLM_CACHE) { + return cached.content; + } + else { + rm_cached_object({ ca_options }, 'kbot'); + } + } + logger.info(`kbot: template:${tpl} : context:${context} @ ${options.model}`); + const result = await run(options); + if (!result || !result[0]) { + logger.error(`No result for ${content.substring(0, 20)}`); + return content; + } + if (template.format === 'json') { + try { + const jsonResult = JSON.parse(result[0]); + await set_cached_object(content, ca_options, { content: jsonResult }, 'kbot'); + return jsonResult; + } + catch (e) { + logger.error('Failed to parse JSON response:', e); + return result[0]; + } + } + await set_cached_object({ ca_options }, 'kbot', { content: result[0] }, {}); + logger.info(`kbot-result: template:${tpl} : context:${context} @ ${options.model} : ${result[0]}`); + return result[0]; +}; +export const template_filter = async (text, template, context = TemplateContext.COMMONS) => { + if (!text || text.length < 20) { + return text; + } + const templates = createTemplates(context); + if (!templates[template]) { + logger.warn(`No template found for ${template}`); + return text; + } + const templateConfig = templates[template](); + const resolvedTemplate = Object.fromEntries(Object.entries(templateConfig).map(([key, value]) => [ + key, + typeof value === 'string' ? resolveVariables(value, true) : value + ])); + const resolvedText = resolveVariables(text, true); + const ret = await filter(resolvedText, template, { + context, + ...resolvedTemplate, + prompt: `${resolvedTemplate.prompt}\n\nText to process:\n${resolvedText}`, + variables: env().variables + }); + return ret; +}; +export const getFilterOptions = (content, template, opts = {}) => { + return OptionsSchema().parse({ + ...template, + prompt: `${template.prompt || ""} : ${content}`, + ...opts, + }); +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2JvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWZlcmVuY2Uva2JvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUN4RixPQUFPLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFBO0FBRTlELE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQ3hDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ3RELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUU5QyxPQUFPLEVBRUgsZUFBZSxFQUNmLGVBQWUsRUFDbEIsTUFBTSxxQkFBcUIsQ0FBQztBQU03QixNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLE9BQWUsRUFBRSxNQUFjLE9BQU8sRUFBRSxPQUFjLEVBQUUsRUFBRSxFQUFFO0lBQ3JGLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUNsQyxPQUFPLE9BQU8sQ0FBQztJQUNuQixDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxlQUFlLENBQUMsT0FBTyxDQUFDO0lBQ3hELE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDbEIsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENB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 \ No newline at end of file diff --git a/packages/kbot/dist-in/splitter.d.ts b/packages/kbot/dist-in/splitter.d.ts new file mode 100644 index 00000000..69371dee --- /dev/null +++ b/packages/kbot/dist-in/splitter.d.ts @@ -0,0 +1 @@ +export declare const foo = 2; diff --git a/packages/kbot/dist-in/splitter.js b/packages/kbot/dist-in/splitter.js new file mode 100644 index 00000000..b1f5c055 --- /dev/null +++ b/packages/kbot/dist-in/splitter.js @@ -0,0 +1,33 @@ +export const foo = 2; +/* +import { Document } from "@langchain/core/documents"; +import { + CharacterTextSplitter, + LatexTextSplitter, + MarkdownTextSplitter, + RecursiveCharacterTextSplitter, + TokenTextSplitter, +} from "@langchain/textsplitters" + +/* + +export const splitter_text = async (text: string, options: any) => { + + const splitter = new CharacterTextSplitter({ + separator: " ", + chunkSize: 7, + chunkOverlap: 3, + }); + const output = await splitter.splitText(text); +} + +export const splitter_md = async (text: string, options: any) => { + + const splitter = new MarkdownTextSplitter({ + chunkSize: 60, + chunkOverlap: 3, + }); + const output = await splitter.splitText(text); +} +*/ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXR0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3BsaXR0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQTtBQUVwQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBOEJFIn0= \ No newline at end of file diff --git a/packages/kbot/dist-in/utils/__tests__/array.test.d.ts b/packages/kbot/dist-in/utils/__tests__/array.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/array.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/kbot/dist-in/utils/__tests__/array.test.js b/packages/kbot/dist-in/utils/__tests__/array.test.js new file mode 100644 index 00000000..ea6d84bd --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/array.test.js @@ -0,0 +1,25 @@ +import { describe, it, expect } from 'vitest'; +import { flatten } from '../array'; +describe('array utilities', () => { + describe('flatten', () => { + it('should handle undefined input', () => { + expect(flatten(undefined)).toEqual([]); + }); + it('should handle string input', () => { + expect(flatten('a,b,c')).toEqual(['a', 'b', 'c']); + }); + it('should handle array input', () => { + expect(flatten(['a', 'b,c'])).toEqual(['a', 'b', 'c']); + }); + it('should filter out numbers and booleans', () => { + expect(flatten(['a', 'true', '123', 'b'])).toEqual(['a', 'b']); + }); + it('should remove duplicates', () => { + expect(flatten('a,b,a,c,b')).toEqual(['a', 'b', 'c']); + }); + it('should trim whitespace', () => { + expect(flatten([' a ', ' b , c '])).toEqual(['a', 'b', 'c']); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXkudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9fX3Rlc3RzX18vYXJyYXkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUVsQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO0lBQy9CLFFBQVEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7WUFDdkMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUN4QyxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7WUFDcEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUNuRCxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7WUFDbkMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3hELENBQUMsQ0FBQyxDQUFBO1FBRUYsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtZQUNoRCxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ2hFLENBQUMsQ0FBQyxDQUFBO1FBRUYsRUFBRSxDQUFDLDBCQUEwQixFQUFFLEdBQUcsRUFBRTtZQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3ZELENBQUMsQ0FBQyxDQUFBO1FBRUYsRUFBRSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtZQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDOUQsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIn0= \ No newline at end of file diff --git a/packages/kbot/dist-in/utils/__tests__/file.test.d.ts b/packages/kbot/dist-in/utils/__tests__/file.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/file.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/kbot/dist-in/utils/__tests__/file.test.js b/packages/kbot/dist-in/utils/__tests__/file.test.js new file mode 100644 index 00000000..d6cbcd3e --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/file.test.js @@ -0,0 +1,31 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { readProjectFiles } from '../file'; +import { sync as dir } from '@polymech/fs/dir'; +import { sync as exists } from '@polymech/fs/exists'; +import { filesEx } from '@polymech/commons/_glob'; +vi.mock('@polymech/fs/dir'); +vi.mock('@polymech/fs/exists'); +vi.mock('@polymech/commons/_glob'); +vi.mock('@polymech/fs/read'); +vi.mock('path', async () => { + const actual = await vi.importActual('path'); + return { + ...actual, + relative: vi.fn((from, to) => to), + extname: vi.fn((path) => path ? path.includes('.ts') ? '.ts' : '.md' : '') + }; +}); +describe('file utilities', () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + describe('readProjectFiles', () => { + it('should create directory if it does not exist', async () => { + vi.mocked(exists).mockReturnValue(false); + await readProjectFiles('/test/path'); + expect(dir).toHaveBeenCalledWith('/test/path'); + expect(filesEx).not.toHaveBeenCalled(); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3V0aWxzL19fdGVzdHNfXy9maWxlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzFDLE9BQU8sRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDOUMsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFFakQsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO0FBQzNCLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQTtBQUM5QixFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUE7QUFDbEMsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0FBQzVCLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM1QyxPQUFPO1FBQ0wsR0FBSSxNQUFjO1FBQ2xCLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDM0UsQ0FBQTtBQUNILENBQUMsQ0FBQyxDQUFBO0FBRUYsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFBO0lBQ3BCLENBQUMsQ0FBQyxDQUFBO0lBRUYsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtRQUNoQyxFQUFFLENBQUMsOENBQThDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDNUQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7WUFFeEMsTUFBTSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQTtZQUVwQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLENBQUE7WUFDOUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1FBQ3hDLENBQUMsQ0FBQyxDQUFBO0lBR0osQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSJ9 \ No newline at end of file diff --git a/packages/kbot/dist-in/utils/__tests__/input.test.d.ts b/packages/kbot/dist-in/utils/__tests__/input.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/input.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/kbot/dist-in/utils/__tests__/input.test.js b/packages/kbot/dist-in/utils/__tests__/input.test.js new file mode 100644 index 00000000..69ef6b26 --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/input.test.js @@ -0,0 +1,77 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { resolveQuery, readStdin } from '../input'; +import { detectAndHandle } from '../../commands/handlers'; +import { sync as exists } from '@polymech/fs/exists'; +import { sync as read } from '@polymech/fs/read'; +vi.mock('@polymech/fs/exists'); +vi.mock('@polymech/fs/read'); +vi.mock('../../commands/handlers'); +vi.mock('path', async () => { + const actual = await vi.importActual('path'); + return { + ...actual, + resolve: vi.fn((p) => p), + extname: vi.fn(() => '.txt') + }; +}); +describe('input utilities', () => { + let mockStdin; + beforeEach(() => { + vi.resetAllMocks(); + mockStdin = { + isTTY: true, + on: vi.fn(), + }; + Object.defineProperty(process, 'stdin', { + value: mockStdin, + writable: true + }); + }); + afterEach(() => { + vi.restoreAllMocks(); + }); + describe('resolveQuery', () => { + it('should handle file path query', async () => { + const mockOptions = { query: 'test.txt' }; + vi.mocked(exists).mockReturnValue(true); + vi.mocked(read).mockReturnValue(Buffer.from('file content')); + vi.mocked(detectAndHandle).mockResolvedValue('processed file content'); + const result = await resolveQuery(mockOptions); + expect(result).toBe('processed file content'); + expect(detectAndHandle).toHaveBeenCalled(); + }); + it('should return direct query if not file path', async () => { + const mockOptions = { query: 'direct query' }; + vi.mocked(exists).mockReturnValue(false); + const result = await resolveQuery(mockOptions); + expect(result).toBe('direct query'); + }); + it('should throw error if no query provided', async () => { + await expect(resolveQuery({})).rejects.toThrow('No query provided'); + }); + }); + describe('readStdin', () => { + it('should handle TTY input', async () => { + mockStdin.isTTY = true; + const result = await readStdin(); + expect(result).toEqual(Buffer.from('')); + expect(mockStdin.on).not.toHaveBeenCalled(); + }); + it('should handle non-TTY input', async () => { + mockStdin.isTTY = false; + const mockData = Buffer.from('test input'); + // Simulate data events + mockStdin.on.mockImplementation((event, callback) => { + if (event === 'data') + callback(mockData); + if (event === 'end') + callback(); + }); + const result = await readStdin(); + expect(result).toEqual(mockData); + expect(mockStdin.on).toHaveBeenCalledWith('data', expect.any(Function)); + expect(mockStdin.on).toHaveBeenCalledWith('end', expect.any(Function)); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9fX3Rlc3RzX18vaW5wdXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDeEUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFBO0FBQ3pELE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDcEQsT0FBTyxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUdoRCxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDOUIsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0FBQzVCLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQTtBQUNsQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLElBQUksRUFBRTtJQUN6QixNQUFNLE1BQU0sR0FBRyxNQUFNLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDNUMsT0FBTztRQUNMLEdBQUcsTUFBYTtRQUNoQixPQUFPLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQztLQUM3QixDQUFBO0FBQ0gsQ0FBQyxDQUFDLENBQUE7QUFFRixRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO0lBQy9CLElBQUks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 \ No newline at end of file diff --git a/packages/kbot/dist-in/utils/__tests__/script.test.d.ts b/packages/kbot/dist-in/utils/__tests__/script.test.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/script.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/kbot/dist-in/utils/__tests__/script.test.js b/packages/kbot/dist-in/utils/__tests__/script.test.js new file mode 100644 index 00000000..1de2e3fd --- /dev/null +++ b/packages/kbot/dist-in/utils/__tests__/script.test.js @@ -0,0 +1,31 @@ +import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest'; +import { dumpAsScript } from '../script'; +import { sync as write } from '@polymech/fs/write'; +vi.mock('@polymech/fs/write'); +vi.mock('path', async () => { + const actual = await vi.importActual('path'); + return { + ...actual, + resolve: vi.fn((...args) => args.join('/')) + }; +}); +describe('script utilities', () => { + const originalArgv = process.argv; + beforeAll(() => { + process.argv = ['node', 'script.js', 'command', '--option=value', '--dump=output.sh']; + }); + afterAll(() => { + process.argv = originalArgv; + }); + describe('dumpAsScript', () => { + it('should not create script if dump option is not provided', async () => { + await dumpAsScript({ dump: undefined }); + expect(write).not.toHaveBeenCalled(); + }); + it('should create script file with quoted arguments', async () => { + await dumpAsScript({ dump: 'output.sh' }); + expect(write).toHaveBeenCalledWith('output.sh', 'kbot command --option="value"'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyaXB0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvX190ZXN0c19fL3NjcmlwdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ3hDLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFHbEQsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO0FBQzdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM1QyxPQUFPO1FBQ0wsR0FBRyxNQUFhO1FBQ2hCLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDNUMsQ0FBQTtBQUNILENBQUMsQ0FBQyxDQUFBO0FBRUYsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtJQUNoQyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFBO0lBRWpDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYixPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtJQUN2RixDQUFDLENBQUMsQ0FBQTtJQUVGLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDWixPQUFPLENBQUMsSUFBSSxHQUFHLFlBQVksQ0FBQTtJQUM3QixDQUFDLENBQUMsQ0FBQTtJQUVGLFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1FBQzVCLEVBQUUsQ0FBQyx5REFBeUQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN2RSxNQUFNLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFBO1lBQ3ZDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtRQUN0QyxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMvRCxNQUFNLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFBO1lBRXpDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxvQkFBb0IsQ0FDaEMsV0FBVyxFQUNYLCtCQUErQixDQUNoQyxDQUFBO1FBQ0gsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIn0= \ No newline at end of file diff --git a/packages/kbot/false/_update-notifier-last-checked b/packages/kbot/false/_update-notifier-last-checked new file mode 100644 index 00000000..e69de29b diff --git a/packages/kbot/logs/params.json b/packages/kbot/logs/params.json index 96250349..041bc522 100644 --- a/packages/kbot/logs/params.json +++ b/packages/kbot/logs/params.json @@ -1,9 +1,9 @@ { - "model": "openai/chatgpt-4o-latest", + "model": "openai/gpt-4o-mini", "messages": [ { "role": "user", - "content": "Analyze this product review and extract key information\n\nText to transform: \"Great selection of fruits with good prices and quality. Some items were out of stock.\"" + "content": "Summarize this paragraph in one short sentence (max 15 words).\n\nText to transform: \"A concluding paragraph summarizing the key findings.\"" }, { "role": "user", diff --git a/packages/kbot/package-lock.json b/packages/kbot/package-lock.json index ed8893ff..d1fdfdad 100644 --- a/packages/kbot/package-lock.json +++ b/packages/kbot/package-lock.json @@ -30,9 +30,13 @@ "openai": "4.91.0", "p-map": "7.0.3", "p-throttle": "7.0.0", + "remark-parse": "11.0.0", + "remark-stringify": "11.0.0", "ts-retry": "6.0.0", "tslog": "^4.9.3", "turndown": "7.2.0", + "unified": "11.0.5", + "unist-util-visit": "5.0.0", "yargs": "17.7.2", "zod": "3.24.2" }, @@ -1723,6 +1727,15 @@ "optional": true, "peer": true }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -1759,6 +1772,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", @@ -1809,6 +1837,12 @@ "integrity": "sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w==", "license": "MIT" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", @@ -2658,6 +2692,16 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2839,6 +2883,16 @@ "node": ">=10" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -3172,7 +3226,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3186,6 +3239,19 @@ } } }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -3221,6 +3287,28 @@ "node": ">=0.4.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3641,6 +3729,12 @@ "node": ">=12.0.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4418,6 +4512,18 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4718,6 +4824,16 @@ "dev": true, "license": "MIT" }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4837,6 +4953,78 @@ "node": ">= 0.4" } }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4854,6 +5042,448 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -5717,6 +6347,37 @@ "node": ">= 10.13.0" } }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6617,6 +7278,16 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", @@ -7365,6 +8036,80 @@ "node": ">=4" } }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -7438,6 +8183,34 @@ "dev": true, "license": "MIT" }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "5.4.14", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", @@ -7998,6 +8771,16 @@ "peerDependencies": { "zod": "^3.24.1" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/packages/kbot/package.json b/packages/kbot/package.json index cb34e117..51be3072 100644 --- a/packages/kbot/package.json +++ b/packages/kbot/package.json @@ -37,7 +37,9 @@ "exe:lnx": "cd dist && nexe -i main_node.js -o kbot --build --temp=../../temp-kbot --verbose", "examples:async-iterator": "node dist-in/examples/core/async-iterator-example.js", "examples:async-iterator:verbose": "node dist-in/examples/core/async-iterator-example.js --debug", - "examples:iterator-factory": "node dist-in/examples/core/iterator-factory-example.js --debug" + "examples:iterator-factory": "node dist-in/examples/core/iterator-factory-example.js --debug", + "examples:iterator-markdown": "node dist-in/examples/core/iterator-markdown-example.js", + "examples:iterator-markdown:no-cache": "node dist-in/examples/core/iterator-markdown-example.js --no-cache" }, "dependencies": { "@polymech/ai-tools": "file:../ai-tools", @@ -62,9 +64,13 @@ "openai": "4.91.0", "p-map": "7.0.3", "p-throttle": "7.0.0", + "remark-parse": "11.0.0", + "remark-stringify": "11.0.0", "ts-retry": "6.0.0", "tslog": "^4.9.3", "turndown": "7.2.0", + "unified": "11.0.5", + "unist-util-visit": "5.0.0", "yargs": "17.7.2", "zod": "3.24.2" }, diff --git a/packages/kbot/src/examples/core/iterator-markdown-example.ts b/packages/kbot/src/examples/core/iterator-markdown-example.ts new file mode 100644 index 00000000..a369f4f9 --- /dev/null +++ b/packages/kbot/src/examples/core/iterator-markdown-example.ts @@ -0,0 +1,298 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkStringify from 'remark-stringify'; +import { visit } from 'unist-util-visit'; +import { sync as write } from "@polymech/fs/write"; +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, transform, IOptions, createLLMTransformer, CacheConfig, ILogger } from '../../iterator.js'; +import { OnTransformCallback } from '../../async-iterator.js'; + +/** + * Notes for LLM modifications + * + * - to test it, use `npm run examples:iterator-markdown` (after adding the script) + * - demonstrates applying the iterator to a Markdown file parsed into an AST (mdast) + * - targets headings, paragraphs, and table cells for transformation + * - uses the 'format' option for structured data extraction + * - uses 'onTransform' callback + */ + +const MODEL = E_OPENROUTER_MODEL.MODEL_OPENAI_GPT_4O_MINI; // Corrected model name +const ROUTER = 'openrouter'; +const INPUT_MD_PATH = path.resolve('./tests/test-data/core/md-test.md'); +const OUTPUT_MD_PATH = path.resolve('./tests/test-data/core/md-test-out.md'); + +// Basic logger +const logger: ILogger = { + info: (message: string) => console.log(`INFO: ${message}`), + warn: (message: string) => console.log(`WARN: ${message}`), + error: (message: string, error?: any) => console.error(`ERROR: ${message}`, error) +}; + +// This transformer factory uses the standard createLLMTransformer. +// It assumes the iterator passes the STRING value found at the JSONPath. +// It does NOT handle direct AST node modification for targetPath=null cases, +// because it only receives the string value, not the node context. +// In-place modification of the AST based on primitive value paths is complex +// with this generic iterator and requires a different approach (e.g., post-processing). +// Transformations using targetPath (like analysisResult) will work as expected +// if the JSONPath targets the NODE containing the text. +function getLLMTransformerForMdast( + options: IKBotTask, + baseLogger: ILogger = logger, + cacheConfig?: CacheConfig +): (textValue: string, jsonPath: string) => Promise { + const llmTransformer = createLLMTransformer(options, baseLogger, cacheConfig); + // Just return the basic LLM transformer - it expects a string and returns a string. + return llmTransformer; +} + +// Define field mappings for the mdast structure +const fieldMappings: FieldMapping[] = [ + { + // Target text value within H1-H5 headings' children + jsonPath: '$.children[?(@.type=="heading" && @.depth <= 5)].children[?(@.type=="text")].value', + targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations) + options: { + prompt: 'Rewrite this heading to be more concise and impactful (max 5 words).' + } + }, + { + // Target the specific paragraph NODE in Chapter 4 for structured analysis. + // The transformer will extract text from the node passed to it. + // Using targetPath='analysisResult' stores the LLM output on the node itself. + jsonPath: '$.children[?(@.type=="paragraph" && @.children[0].value.includes("results"))]', + targetPath: 'analysisResult', // Store result in a new property on the paragraph node + options: { + prompt: 'Extract keywords and sentiment from this text.', + format: { + type: "object", + properties: { + sentiment: { + type: "string", + enum: ["positive", "neutral", "negative"], + description: "Overall sentiment" + }, + keywords: { + type: "array", + items: { type: "string" }, + description: "Main keywords (max 5)" + } + }, + required: ["sentiment", "keywords"] + } + } + }, + { + // Target text value within paragraphs' children + jsonPath: '$.children[?(@.type=="paragraph")].children[?(@.type=="text")].value', + targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations) + options: { + prompt: 'Summarize this paragraph in one short sentence (max 15 words).' + } + }, + { + // Target text value within table cells' children + jsonPath: '$.children[?(@.type=="table")].children[*].children[*].children[?(@.type=="text")].value', + targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations) + options: { + prompt: 'Rephrase this table cell content slightly.' + } + } +]; + +// Example onTransform callback for Markdown +const mdOnTransform: OnTransformCallback = async (jsonPath, value, options) => { + let textValue = typeof value === 'string' ? value : JSON.stringify(value); // Handle potential node objects if path isn't perfect + console.log(` -> mdOnTransform: Path='${jsonPath}', Original Value='${textValue.substring(0, 50)}...'`); + // No modification needed here, just logging + return textValue; // Must return the string value the LLM transformer expects +}; + +export async function markdownTransformExample(useCache = true) { + console.log("========================================"); + console.log("Starting Markdown transform example"); + console.log(`Using cache: ${useCache}`); + console.log("========================================"); + + try { + // 1. Read Markdown file + const markdownInput = fs.readFileSync(INPUT_MD_PATH, 'utf8'); + + // 2. Parse Markdown to AST + const processor = unified().use(remarkParse); + const ast = processor.parse(markdownInput); + + // Make a deep copy to avoid modifying the original AST if transform fails + // Note: Standard deepClone might not work perfectly with complex AST nodes (position, data fields). + // For this example, JSON stringify/parse is a common workaround, but beware of data loss. + let astToTransform = JSON.parse(JSON.stringify(ast)); + + + // 3. Define global options and iterator options + const globalOptionsMixin: Partial = { + model: MODEL, + router: ROUTER, + mode: E_Mode.COMPLETION, + }; + + const iteratorOptions: IOptions = { + // We provide our custom transformer factory + transformerFactory: (opts) => getLLMTransformerForMdast(opts, logger, { enabled: useCache }), + logger: logger, + cacheConfig: { enabled: useCache, namespace: 'markdown-transforms' }, + // onTransform receives the value matched by jsonPath (can be string or node). + // It must return the STRING to be transformed by the LLM. + onTransform: async (jsonPath, value, kbotOptions) => { + let textContent = ''; + // Check if the value is a node object or just a string + if (typeof value === 'string') { + textContent = value; + console.log(` -> onTransform String Value: Path='${jsonPath}', Value='${textContent.substring(0, 50)}...'`); + } else if (typeof value === 'object' && value !== null) { + // Attempt to extract text if it's a node (e.g., for the analysisResult mapping) + const node = value as any; // Basic type assertion + if ((node.type === 'heading' || node.type === 'paragraph' || node.type === 'tableCell') && node.children?.length === 1 && node.children[0].type === 'text') { + textContent = node.children[0].value || ''; + } else if (node.type === 'text') { + textContent = node.value || ''; + } else if (Array.isArray(node.children)) { // Handle complex children + textContent = node.children + .filter((child: any) => child.type === 'text' || child.type === 'inlineCode') + .map((child: any) => child.value) + .join(''); + } + console.log(` -> onTransform AST Node: Path='${jsonPath}', Node Type='${node?.type}', Extracted Text='${textContent.substring(0, 50)}...'`); + } else { + console.log(` -> onTransform Unexpected Value Type: Path='${jsonPath}', Type='${typeof value}'`); + } + + // Return the extracted string for the LLM transformer + return textContent; + }, + errorCallback: (path, value, error) => { + if (error instanceof Error) { + logger.error(`Error processing path ${path}: ${error.message}`, error); + } else { + logger.error(`Error processing path ${path}: ${error}`, error); + } + }, + filterCallback: async (value, jsonPath) => { + // Allow transformation if the value is an object (likely an AST node targeted directly) + if (typeof value === 'object' && value !== null) { + return true; + } + // If it's a string, apply the default string filter logic + if (typeof value === 'string') { + // Reuse the default isValidString filter logic for strings + const allow = value.trim() !== ''; + if (!allow) { + logger.info(`Filter: Skipping empty string at ${jsonPath}`); + } + return allow; + } + // Skip other types (numbers, booleans, null, undefined) + logger.warn(`Filter: Skipping non-string/non-object value type (${typeof value}) at ${jsonPath}`); + return false; + } + }; + + // 4. Use the transform function + console.log("Applying transformations to AST..."); + // The 'transform' function iterates based on JSONPath and applies the transformerFactory's result + // It modifies the 'astToTransform' object in place. + await transform( + astToTransform, // Pass the AST object + fieldMappings, + globalOptionsMixin, + iteratorOptions + ); + + // *** Add logging before visit *** + console.log("\n[DEBUG] Inspecting AST before visit call:"); + try { + // Attempt to find the specific paragraph node expected to have analysisResult + // NOTE: This relies on index/structure and might be brittle + const potentialNode = astToTransform.children?.find((node: any) => + node.type === 'paragraph' && + node.children?.[0]?.value?.includes("results") + ); + if (potentialNode) { + console.log("[DEBUG] Found potential node:", JSON.stringify(potentialNode, null, 2)); + console.log(`[DEBUG] Does potential node have analysisResult? ${potentialNode.hasOwnProperty('analysisResult')}`); + } else { + console.log("[DEBUG] Could not find the target paragraph node directly before visit."); + } + console.log("---------------------------------------"); + } catch (e) { + console.error("[DEBUG] Error during pre-visit inspection:", e); + } + + // Retrieve the structured analysis result (if any) + // Note: The 'analysisResult' was added as a new property to the AST node by the mapping. + // We need to find that node again to see the result. This is clumsy. + let analysisData: any = null; + try { + visit(astToTransform, 'paragraph', (node: any) => { + if (node.analysisResult) { + analysisData = node.analysisResult; + // Optional: Remove the temporary property from the AST before stringifying + // delete node.analysisResult; + } + }); + if (analysisData) { + console.log("\nStructured Analysis Result:"); + // The LLM might return a stringified JSON, try parsing it + try { + const parsedResult = typeof analysisData === 'string' ? JSON.parse(analysisData) : analysisData; + console.log(JSON.stringify(parsedResult, null, 2)); + } catch (e) { + console.log("Analysis result (raw):", analysisData); + } + } else { + console.log("\nStructured Analysis Result not found on AST (check targetPath logic and LLM response)."); + } + } catch (e) { + logger.error("Error visiting AST for analysis result retrieval:", e) + } + + + // 5. Stringify the modified AST back to Markdown + console.log("\nStringifying transformed AST..."); + const processorStringify = unified().use(remarkStringify); + // Stringify might fail if the AST structure became invalid during transformation + const outputMarkdown = processorStringify.stringify(astToTransform as any); + + // 6. Write the output file + console.log(`Writing output to: ${OUTPUT_MD_PATH}`); + const outputDir = path.dirname(OUTPUT_MD_PATH); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + write(OUTPUT_MD_PATH, outputMarkdown); + + console.log("Markdown transformation complete."); + return astToTransform; // Return the transformed AST + + } catch (error) { + logger.error("ERROR during Markdown transformation:", error); + throw error; + } +} + +// Add run logic +if (process.argv[1] && process.argv[1].includes('iterator-markdown-example')) { + const noCache = process.argv.includes('--no-cache'); + markdownTransformExample(!noCache) + .then(() => { + console.log("\nMarkdown example finished successfully."); + }) + .catch(error => { + console.error("\nMarkdown example failed:", error); + process.exit(1); // Exit with error code + }); +} \ No newline at end of file diff --git a/packages/kbot/src/examples/index.ts b/packages/kbot/src/examples/index.ts index 5232c327..b3c2cf2a 100644 --- a/packages/kbot/src/examples/index.ts +++ b/packages/kbot/src/examples/index.ts @@ -1,3 +1,4 @@ // Export examples export * from './core/async-iterator-example.js'; -export * from './core/iterator-factory-example.js'; \ No newline at end of file +export * from './core/iterator-factory-example.js'; +export * from './core/iterator-markdown-example.js'; \ No newline at end of file diff --git a/packages/kbot/src/index.ts b/packages/kbot/src/index.ts index c72f9052..ad7120f4 100644 --- a/packages/kbot/src/index.ts +++ b/packages/kbot/src/index.ts @@ -78,5 +78,4 @@ export * from './zod_schema.js' export { E_OPENAI_MODEL } from './models/cache/openai-models.js' export { E_OPENROUTER_MODEL } from './models/cache/openrouter-models.js' export { E_OPENROUTER_MODEL_FREE } from './models/cache/openrouter-models-free.js' - -export { IKBotTask } from '@polymech/ai-tools' \ No newline at end of file +export type { IKBotTask } from '@polymech/ai-tools' \ No newline at end of file diff --git a/packages/kbot/src/iterator.ts b/packages/kbot/src/iterator.ts index 85ba97df..c5c62dca 100644 --- a/packages/kbot/src/iterator.ts +++ b/packages/kbot/src/iterator.ts @@ -211,8 +211,10 @@ export function createIterator( return { createTransformer, transform: async (mappings: FieldMapping[]): Promise => { + // *** Object Cache Check (Start) *** + let objectCacheKey: any; if (config.enabled) { - const objectCacheKey = createObjectCacheKey(obj, mappings); + objectCacheKey = createObjectCacheKey(obj, mappings); // Key based on initial state const cachedObject = await get_cached_object( { ca_options: objectCacheKey }, 'transformed-objects' @@ -220,20 +222,24 @@ export function createIterator( if (cachedObject?.content) { logger.info('Using cached transformed object'); + // Clear the original object before merging cache to avoid partial states + Object.keys(obj).forEach(key => delete obj[key]); deepMerge(obj, cachedObject.content); return; } } + // *** Object Cache Check (End) *** - // If no cache hit or caching disabled, perform the transformations - const transformedObj = JSON.parse(JSON.stringify(obj)); + // If no cache hit or caching disabled, perform the transformations directly on 'obj' + // REMOVED: const transformedObj = JSON.parse(JSON.stringify(obj)); for (const mapping of mappings) { const mergedOptions = { ...optionsMixin, ...mapping.options } as IKBotTask; const { jsonPath, targetPath = null } = mapping; const transformer = createTransformer(mergedOptions); + // Call transformObjectWithOptions directly on the original 'obj' await transformObjectWithOptions( - transformedObj, + obj, // <<< Operate directly on obj transformer, { jsonPath, @@ -248,20 +254,20 @@ export function createIterator( ); } - // Cache the transformed object - if (config.enabled) { - const objectCacheKey = createObjectCacheKey(obj, mappings); + // *** Object Cache Setting (Start) *** + // Cache the final state of the modified 'obj' + if (config.enabled && objectCacheKey) { // Ensure key was generated await set_cached_object( { ca_options: objectCacheKey }, 'transformed-objects', - { content: transformedObj }, + { content: obj }, // <<< Cache the final obj { expiration: config.expiration } ); logger.info('Cached transformed object'); } + // *** Object Cache Setting (End) *** - // Apply the transformations to the original object - deepMerge(obj, transformedObj); + // REMOVED: deepMerge(obj, transformedObj); } }; } diff --git a/packages/kbot/tests/test-data/core/md-test-out.md b/packages/kbot/tests/test-data/core/md-test-out.md new file mode 100644 index 00000000..67b94139 --- /dev/null +++ b/packages/kbot/tests/test-data/core/md-test-out.md @@ -0,0 +1,37 @@ +# Intro Chapter + +The document introduces topics related to AI and Markdown processing. + +## Background Overview + +Markdown has an interesting history that we will explore. + +### "Early Days" + +Early days are described in the details provided. + +# Methodology Overview + +This chapter describes the employed methods. + +## "Markdown Parsing" + +User preferences indicate a focus on concise and direct responses.`unified`The paragraph consists only of an empty conjunction and lacks meaningful content.`remark-parse`To manage Markdown formatting. + +## Content Transformation + +The process entails navigating the AST and implementing LLM transformations. + +# Data Representation + +The table includes three headers and various data cells, highlighting important content in one cell. + +The table displays sample data with transformable cells. + +# Structured Output Analysis + +The text mentions sunny weather, making it ideal for a park walk. + +# Final Thoughts + +A summary of the key findings is presented in the concluding paragraph. diff --git a/packages/kbot/tests/test-data/core/md-test.md b/packages/kbot/tests/test-data/core/md-test.md new file mode 100644 index 00000000..8a312af5 --- /dev/null +++ b/packages/kbot/tests/test-data/core/md-test.md @@ -0,0 +1,41 @@ +# Chapter 1: Introduction + +This is the introductory paragraph. It sets the stage for the document. We will discuss various topics related to AI and Markdown processing. + +## Section 1.1: Background + +Here we provide some background information. The history of Markdown is quite interesting. + +### Subsection 1.1.1: Early Days + +Details about the early days go here. + +# Chapter 2: Methodology + +This chapter outlines the methods used. + +## Section 2.1: Parsing Markdown + +We use `unified` and `remark-parse` to handle Markdown. + +## Section 2.2: Transforming Content + +The core logic involves traversing the AST and applying LLM transformations. + +# Chapter 3: Data Representation + +| Header 1 | Header 2 | Header 3 | +|----------|----------|----------| +| Cell 1.1 | Cell 1.2 | Cell 1.3 | +| Cell 2.1 | Cell 2.2 | Cell 2.3: Contains important data | +| Cell 3.1 | Cell 3.2 | Cell 3.3 | + +This table shows sample data. Each cell can be targeted for transformation. + +# Chapter 4: Analysis with Structured Output + +This section discusses the results. We want to extract keywords and sentiment from this text. The weather today is sunny and warm, perfect for a walk in the park. + +# Chapter 5: Conclusion + +A concluding paragraph summarizing the key findings. \ No newline at end of file diff --git a/packages/kbot/tsconfig.json b/packages/kbot/tsconfig.json index 0ce2c1ac..62c1b0bc 100644 --- a/packages/kbot/tsconfig.json +++ b/packages/kbot/tsconfig.json @@ -14,9 +14,17 @@ ] } }, - "files": [ - "src/index.ts", - "src/main.ts", - "src/examples/index.ts" - ] + // "include": [ + // "src/**/*" + // ], + // "exclude": [ + // "node_modules", + // "dist", + // "dist-in" + // ], + "files": [ + "src/index.ts", + "src/main.ts", + "src/examples/index.ts" + ] } \ No newline at end of file