{"_id":"@elimeleth/builderbot-langchain","_rev":"4-709bc1d694e77870f8178ea401706fbd","name":"@elimeleth/builderbot-langchain","dist-tags":{"dev":"1.3.2-alpha.1","latest":"1.0.0-alpha.0"},"versions":{"1.0.0-alpha.0":{"name":"@elimeleth/builderbot-langchain","version":"1.0.0-alpha.0","description":"Interface para crear chatbot con Builderbot & LangChain","main":"dist/index.cjs","types":"dist/index.d.ts","type":"module","keywords":["chatbot","builderbot","langchain","whatsapp","telegram"],"author":{"name":"Elimeleth Capuano","email":"elimeleth.contacto@gmail.com"},"scripts":{"test":"jest","build":"rimraf dist && npx rollup --config","dev":"tsm src/index.ts","start":"pnpm run build && node dist/index.cjs","local:build":"pnpm run build && npm pack"},"dependencies":{"@builderbot-plugins/fast-embedding":"1.0.0-alpha.0","@builderbot-plugins/telegram":"2.0.11-alpha.0","@builderbot/bot":"1.1.0","@builderbot/provider-meta":"^1.1.0","@langchain/community":"^0.0.47","@langchain/core":"^0.1.57","@langchain/google-genai":"^0.0.11","@langchain/openai":"^0.0.28","@oramacloud/client":"^1.0.14","axios":"^1.6.8","d3-dsv":"2","dotenv":"^16.4.5","hnswlib-node":"^3.0.0","langchain":"^0.1.33","pdf-parse":"^1.1.1","tslib":"^2.6.2","zod":"^3.22.4"},"devDependencies":{"@jest/globals":"29.7.0","@rollup/plugin-commonjs":"25.0.7","@rollup/plugin-node-resolve":"15.2.3","@types/node":"^20.12.5","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","rimraf":"5.0.5","rollup-plugin-typescript2":"0.36.0","tsm":"^2.3.0","typescript":"^5.4.4"},"gitHead":"d1d79d49d59cddc835e78f5ebd5f77f3137770a5","_id":"@elimeleth/builderbot-langchain@1.0.0-alpha.0","_nodeVersion":"18.13.0","_npmVersion":"9.2.0","dist":{"integrity":"sha512-4A5WfkxyWfiEeEw5GN/Ukk7lhef0qMvmlvBQ/8ZXB2JDTJN+Whej1TMMg3cIV254BaNpMnrnHfWZxuZs1tyiRw==","shasum":"77ce6feae8b648b320950fa8b32adef99c6ce8d0","tarball":"https://registry.npmjs.org/@elimeleth/builderbot-langchain/-/builderbot-langchain-1.0.0-alpha.0.tgz","fileCount":65,"unpackedSize":83546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDqK0op0TRr1Sn1tcXQ259jat9VKHNz9tXEkCL3UGwD7AiBC7ZX1UMpV1QCo1ZarjqnijrGwygrfpXE7nFjdIXiutg=="}]},"_npmUser":{"name":"elimeleth","email":"juancapuanolopez@gmail.com"},"directories":{},"maintainers":[{"name":"elimeleth","email":"juancapuanolopez@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/builderbot-langchain_1.0.0-alpha.0_1713107386028_0.22804291586047198"},"_hasShrinkwrap":false},"1.0.1-alpha.0":{"name":"@elimeleth/builderbot-langchain","version":"1.0.1-alpha.0","description":"Interface para crear chatbot con Builderbot & LangChain","main":"dist/index.cjs","types":"dist/index.d.ts","type":"module","keywords":["chatbot","builderbot","langchain","whatsapp","telegram"],"author":{"name":"Elimeleth Capuano","email":"elimeleth.contacto@gmail.com"},"scripts":{"test":"jest","build":"rimraf dist && npx rollup --config","dev":"tsm src/index.ts","start":"pnpm run build && node dist/index.cjs","local:build":"pnpm run build && npm pack"},"dependencies":{"@builderbot-plugins/fast-embedding":"1.0.0-alpha.0","@builderbot-plugins/telegram":"2.0.11-alpha.0","@builderbot/bot":"1.1.0","@builderbot/provider-meta":"^1.1.0","@langchain/community":"^0.0.47","@langchain/core":"^0.1.57","@langchain/google-genai":"^0.0.11","@langchain/openai":"^0.0.28","@oramacloud/client":"^1.0.14","axios":"^1.6.8","d3-dsv":"2","dotenv":"^16.4.5","hnswlib-node":"^3.0.0","langchain":"^0.1.33","pdf-parse":"^1.1.1","tslib":"^2.6.2","zod":"^3.22.4"},"devDependencies":{"@jest/globals":"29.7.0","@rollup/plugin-commonjs":"25.0.7","@rollup/plugin-node-resolve":"15.2.3","@types/node":"^20.12.5","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","rimraf":"5.0.5","rollup-plugin-typescript2":"0.36.0","tsm":"^2.3.0","typescript":"^5.4.4"},"gitHead":"8c1084036b63fe784d7a91f84d73b5cda2cb1d16","readme":"ERROR: No README data found!","_id":"@elimeleth/builderbot-langchain@1.0.1-alpha.0","_nodeVersion":"18.13.0","_npmVersion":"9.2.0","dist":{"integrity":"sha512-AQktvuFyDrPkQnjMq5rDBG4efG+sZ63jnV+ieJW1uIxzLXl+zTOpWLyTWs8lOZ7Ie5aE0Qkjp9afVGFaAflTCA==","shasum":"43150afc18b73da9d85f42bb95c0658dab031687","tarball":"https://registry.npmjs.org/@elimeleth/builderbot-langchain/-/builderbot-langchain-1.0.1-alpha.0.tgz","fileCount":64,"unpackedSize":68631,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCcuIXYmQJK605/BdMjKb0Gt9ijpMsxUX/+b7GBr1DpoQIhAPdcgok9N2Wus3DshJxcumso5CsDU0nQQJQshl2zZfWW"}]},"_npmUser":{"name":"elimeleth","email":"juancapuanolopez@gmail.com"},"directories":{},"maintainers":[{"name":"elimeleth","email":"juancapuanolopez@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/builderbot-langchain_1.0.1-alpha.0_1713133461638_0.2392951078759773"},"_hasShrinkwrap":false},"1.2.0-alpha.0":{"name":"@elimeleth/builderbot-langchain","version":"1.2.0-alpha.0","description":"Interface para crear chatbot con Builderbot & LangChain","main":"dist/index.cjs","types":"dist/index.d.ts","type":"module","keywords":["chatbot","builderbot","langchain","whatsapp","telegram"],"author":{"name":"Elimeleth Capuano","email":"elimeleth.contacto@gmail.com"},"scripts":{"test":"jest","build":"rimraf dist && npx rollup --config","dev":"tsm src/index.ts","start":"pnpm run build && node dist/index.cjs","local:build":"pnpm run build && npm pack"},"dependencies":{"@builderbot-plugins/fast-embedding":"1.0.0-alpha.0","@builderbot/bot":"1.1.0","@langchain/community":"^0.0.47","@langchain/core":"^0.1.57","@langchain/google-genai":"^0.0.11","@langchain/openai":"^0.0.28","@oramacloud/client":"^1.0.14","axios":"^1.6.8","d3-dsv":"2","dotenv":"^16.4.5","hnswlib-node":"^3.0.0","langchain":"^0.1.33","pdf-parse":"^1.1.1","tslib":"^2.6.2","zod":"^3.22.4"},"devDependencies":{"@jest/globals":"29.7.0","@builderbot-plugins/telegram":"2.0.11-alpha.0","@rollup/plugin-commonjs":"25.0.7","@rollup/plugin-node-resolve":"15.2.3","@types/node":"^20.12.5","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","rimraf":"5.0.5","rollup-plugin-typescript2":"0.36.0","tsm":"^2.3.0","typescript":"^5.4.4"},"_id":"@elimeleth/builderbot-langchain@1.2.0-alpha.0","readme":"\nThis is a mockup with a shopify store client and Orama retriever\n\n```ts\nimport \"dotenv/config\"\nimport { createBot, createProvider, createFlow, EVENTS } from '@builderbot/bot'\nimport { MemoryDB as Database } from '@builderbot/bot'\nimport { TelegramProvider as Provider } from \"@builderbot-plugins/telegram\"\n\nimport z from \"zod\"\nimport { createAIFlow } from \"./src/index\"\n\nimport { OramaClient } from '@oramacloud/client' \nimport { Product } from \"./src/types\"\n\nconst client = new OramaClient({ \n    endpoint: 'https://cloud.orama.run/v1/indexes/my-shopify-irxv20', \n    api_key: 'YOUR-ORAMA-API-KEY' \n  }) \n\nconst aiflow = createAIFlow\n    .setKeyword(EVENTS.WELCOME)\n    .setAIModel({ modelName: 'openai' })\n    .pipe(({ addAnswer }) => {\n        return addAnswer('Hola!, dejame buscar entre el stock...')\n    })\n    .setCatchLayer(z.object({ \n        intention: z.enum(['SALES']).describe(`La intención del cliente:\n            SALES: Si el cliente pregunta, quiere informacion o esta interesado en uno o mas productos\n        \n        `)\n    }), async (ctx, { endFlow }) => {\n        console.log(ctx?.schema)\n        if (ctx?.schema) {\n            const { intention } = ctx.schema\n            \n            if (intention !== 'SALES') {\n                return endFlow('Lo siento, Intenta preguntando sobre un producto')\n            }\n        }\n    })\n    .setTransformLayer(\n        z.object({\n            product_name: z.string().describe('El producto que busca el cliente'),\n         }),\n        async (ctx) => {\n            console.log({ details: ctx?.context })\n        }\n    )\n    .setStore({\n        searchFn: async (term) => {\n            if (typeof term === 'object') {\n                term = Object.values(term).join(' ')\n            }else if (Array.isArray(term)) {\n                term = term.join(' ')\n            }\n\n            const { hits } = await client.search({ term, limit: 7 }) as any\n            const products = hits.map(hit => hit.document) as Product[]\n\n            const mapProducts = products.map(({ \n                title,\n                variants,\n                priceRange,\n                options,\n                description, \n                featuredImage,  }) => ({\n                    product_description: description,\n                    product_image: featuredImage.url,\n                    product_name: title,\n                    // product_variants: variants\n                    // .map(({ price, selectedOptions }) => ({ price, options: selectedOptions })),\n                    product_price: priceRange.min,\n                    // product_options: options,\n                }))\n\n            return mapProducts\n        }\n    })\n    .createRunnable({\n         answerSchema: z.object({\n            answer: z\n              .string()\n              .describe('Agrega una respuesta breve y clara sobre el producto.'),\n            metadata: z.array(z.object({\n            product_image: z.string()\n                .describe('La url de la imagen del producto'),\n            product_name: z\n              .string()\n              .describe(\"Nombre exacto del producto (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"),\n            product_price: z\n              .string()\n              .describe(\n                \"precio exacto del producto (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"\n              ),\n            product_description: z\n              .string()\n              .describe(\n                \"Dale un breve pitch de venta a la descripcion del producto indica beneficios y caracteristicas (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"\n              )\n          }))\n          .nullable().default([])\n          .describe('Dado los siguientes productos, estructura los que tengan relación con la busqueda')\n          }).describe('El formato de respuesta debe ser el siguiente')\n    }, {\n        onFailure: (err) => {\n            console.log({ err })\n        }\n    })\n    .pipe(({ addAction }) => {\n        return addAction(async (_, { state, endFlow }) => {\n            const answer = state.get('answer')\n            console.log('answer', answer)\n            if (!answer?.metadata?.length) {\n                return endFlow('Lo siento, Intenta preguntando sobre otro producto')\n            }\n\n            await state.update({ purchase: answer.metadata })\n        })\n        .addAction(async (_, { state, flowDynamic }) => {\n            const purchase = state.get('purchase')\n\n            const template = purchase.map((p: any, i: number) => `${i+1}. ${p.product_name}\\nPrecio: $${p.product_price} c/u`).join('\\n\\n')\n\n            await flowDynamic(`Estos son algunos de nuestros productos: \\n\\n ${template}`, { delay: 700 })\n            flowDynamic(`Indicame cual deseas ver, ${Array.from({ length: purchase.length}, (_, i) => i + 1).join(' o ')}`)\n        })\n        .addAction({ capture: true }, async (ctx, { state, flowDynamic }) => {\n            const purchase = state.get('purchase') as Array<any>\n\n            const product  = purchase.at(Number(ctx.body) -1)\n            await state.update({ product })\n            flowDynamic([\n                {\n                    body: `${product.product_name} - $${product.product_price} c/u\\n\\n${product.product_description}`,\n                    media: product.product_image\n                }\n            ])\n        })\n        .addAnswer('¿Deseas comprar el producto (SI / NO)?')\n    })\n    .setCatchLayer(z.object({\n        intention: z.enum(['SI', 'NO']).describe('Repuesta del ususario')\n    }), async (ctx, { endFlow, state, flowDynamic }) => {\n        const product = state.get('product') as any\n        if (ctx?.schema?.intention !== 'SI') {\n            return endFlow('Estare acá por si deseas preguntar sobre otro producto')\n        }\n\n        const sc = [\n            {    \n                name: product?.product_name,\n                price: product?.product_price\n            }\n        ] \n        if (state.getMyState()?.sc?.length) {\n            await state.update({\n                sc: [\n                    ...state.getMyState()?.sc,\n                    // @ts-ignore\n                    {    \n                        name: product?.product_name,\n                        price: product?.product_price\n                    }\n                ]\n            })\n        } else {\n            // @ts-ignore\n            await state.update({ \n                sc\n            })\n        }\n\n        const products = sc.map((p) => `${product.product_name.trim()} $${product.product_price} c/u\\n`).join('\\n')\n        const total = sc.map(p => Number(product.product_price)).reduce((a, b) => Math.abs(a + b))\n        const template = `Tu compra es:\\n${products}\\nTotal: $${total} dolares.`\n\n        await flowDynamic(template)\n\n        return endFlow()\n    },true)\n    .createFlow()\n\nconst main = async () => {\n    \n    const PORT = process.env.PORT ?? 3008\n    const adapterFlow = createFlow([aiflow])\n\n    const adapterProvider = createProvider(Provider)\n    adapterProvider.on('message', (ctx) => console.log('new message', ctx.body))\n    const adapterDB = new Database()\n\n    const { httpServer, handleCtx } = await createBot({\n        flow: adapterFlow,\n        provider: adapterProvider,\n        database: adapterDB,\n    })\n    httpServer(+PORT)\n\n\n    adapterProvider.server.post(\n        '/v1/loyalty',\n        handleCtx(async (bot, req, res) => {\n            const { number, name } = req.body\n            await bot?.dispatch('L0Y4LTY', { from: number, name })\n            return res.end('trigger')\n        })\n    )\n  \n}\n\nmain()\n\n```","readmeFilename":"README.md","gitHead":"39fbdc2204362534dbdb5e8fbbbffeeb79136cf4","_nodeVersion":"20.10.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-6OJpv6lsvkprdjpG0hltiA03gxk8sUOz46NWMl5EjxqrSB6pdUfnoj1VP9r++diUK9RcFHwFDxTe3H41wKCzHg==","shasum":"0fc190806589aef40f8808348ef03c4c1c06b4f0","tarball":"https://registry.npmjs.org/@elimeleth/builderbot-langchain/-/builderbot-langchain-1.2.0-alpha.0.tgz","fileCount":59,"unpackedSize":78758,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHenjSMztx3+X6rj6un/e3K/wZbPjZ1E7oPok/C0WbKiAiAO185YQSvZ8G0QZgZPzA8/BvKA6AzpzdZVyM0pQuZsUw=="}]},"_npmUser":{"name":"elimeleth","email":"juancapuanolopez@gmail.com"},"directories":{},"maintainers":[{"name":"elimeleth","email":"juancapuanolopez@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/builderbot-langchain_1.2.0-alpha.0_1713217714262_0.45330338605032217"},"_hasShrinkwrap":false},"1.3.1-alpha.1":{"name":"@elimeleth/builderbot-langchain","version":"1.3.1-alpha.1","description":"Interface para crear chatbot con Builderbot & LangChain","main":"dist/index.cjs","types":"dist/index.d.ts","type":"module","keywords":["chatbot","builderbot","langchain","whatsapp","telegram"],"author":{"name":"Elimeleth Capuano","email":"elimeleth.contacto@gmail.com"},"scripts":{"test":"jest","build":"rimraf dist && npx rollup --config","dev":"tsm src/index.ts","start":"pnpm run build && node dist/index.cjs","local:build":"pnpm run build && npm pack"},"dependencies":{"@builderbot-plugins/fast-embedding":"1.0.0-alpha.0","@builderbot/bot":"1.1.0","@langchain/cloudflare":"^0.0.4","@langchain/community":"^0.0.47","@langchain/core":"^0.1.57","@langchain/google-genai":"^0.0.11","@langchain/openai":"^0.0.28","@oramacloud/client":"^1.0.14","axios":"^1.6.8","d3-dsv":"2","dotenv":"^16.4.5","hnswlib-node":"^3.0.0","langchain":"^0.1.33","pdf-parse":"^1.1.1","tslib":"^2.6.2","zod":"^3.22.4"},"devDependencies":{"@builderbot-plugins/telegram":"2.0.11-alpha.0","@jest/globals":"29.7.0","@rollup/plugin-commonjs":"25.0.7","@rollup/plugin-node-resolve":"15.2.3","@types/node":"^20.12.5","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","rimraf":"5.0.5","rollup-plugin-typescript2":"0.36.0","tsm":"^2.3.0","typescript":"^5.4.4"},"_id":"@elimeleth/builderbot-langchain@1.3.1-alpha.1","readme":"\nThis is a mockup with a shopify store client and Orama retriever\n\n```ts\nimport \"dotenv/config\"\nimport { createBot, createProvider, createFlow, EVENTS } from '@builderbot/bot'\nimport { MemoryDB as Database } from '@builderbot/bot'\nimport { TelegramProvider as Provider } from \"@builderbot-plugins/telegram\"\n\nimport z from \"zod\"\nimport { createAIFlow } from \"./src/index\"\n\nimport { OramaClient } from '@oramacloud/client' \nimport { Product } from \"./src/types\"\n\nconst client = new OramaClient({ \n    endpoint: 'https://cloud.orama.run/v1/indexes/my-shopify-irxv20', \n    api_key: 'YOUR-ORAMA-API-KEY' \n  }) \n\nconst aiflow = createAIFlow\n    .setKeyword(EVENTS.WELCOME)\n    .pipe(({ addAnswer }) => {\n        return addAnswer('Hola!, dejame buscar entre el stock...')\n    })\n    .setStructuredLayer(z.object({ \n        intention: z.enum(['SALES']).describe(`La intención del cliente:\n            SALES: Si el cliente pregunta, quiere informacion o esta interesado en uno o mas productos\n        \n        `)\n    }), async (ctx, { endFlow }) => {\n        console.log(ctx?.schema)\n        if (ctx?.schema) {\n            const { intention } = ctx.schema\n            \n            if (intention !== 'SALES') {\n                return endFlow('Lo siento, Intenta preguntando sobre un producto')\n            }\n        }\n    })\n    .setContextLayer(\n        z.object({\n            product_name: z.string().describe('El producto que busca el cliente'),\n         }),\n        async (ctx) => {\n            console.log({ details: ctx?.context })\n        }\n    )\n    .setStore({\n        searchFn: async (term) => {\n            console.log({ term })\n\n            const { hits } = await client.search({ term, limit: 7 }) as any\n            const products = hits.map(hit => hit.document) as Product[]\n\n            const mapProducts = products.map(({ \n                title,\n                variants,\n                priceRange,\n                options,\n                description, \n                featuredImage,  }) => ({\n                    product_description: description,\n                    product_image: featuredImage.url,\n                    product_name: title,\n                    // product_variants: variants\n                    // .map(({ price, selectedOptions }) => ({ price, options: selectedOptions })),\n                    product_price: priceRange.min,\n                    // product_options: options,\n                }))\n\n            return mapProducts\n        }\n    })\n    .createRunnable({\n         answerSchema: z.object({\n            answer: z\n              .string()\n              .describe('Agrega una respuesta breve y clara sobre el producto.'),\n            metadata: z.array(z.object({\n            product_image: z.string()\n                .describe('La url de la imagen del producto'),\n            product_name: z\n              .string()\n              .describe(\"Nombre exacto del producto (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"),\n            product_price: z\n              .string()\n              .describe(\n                \"precio exacto del producto (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"\n              ),\n            product_description: z\n              .string()\n              .describe(\n                \"Dale un breve pitch de venta a la descripcion del producto indica beneficios y caracteristicas (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"\n              )\n          }))\n          .nullable().default([])\n          .describe('Dado los siguientes productos, estructura los que tengan relación con la busqueda')\n          }).describe('El formato de respuesta debe ser el siguiente')\n    }, {\n        onFailure: (err) => {\n            console.log({ err })\n        }\n    })\n    .pipe(({ addAction }) => {\n        return addAction(async (_, { state, endFlow }) => {\n            const answer = state.get('answer')\n            console.log('answer', answer)\n            if (!answer?.metadata?.length) {\n                return endFlow('Lo siento, Intenta preguntando sobre otro producto')\n            }\n\n            await state.update({ purchase: answer.metadata })\n        })\n        .addAction(async (_, { state, flowDynamic }) => {\n            const purchase = state.get('purchase')\n\n            const template = purchase.map((p: any, i: number) => `${i+1}. ${p.product_name}\\nPrecio: $${p.product_price} c/u`).join('\\n\\n')\n\n            await flowDynamic(`Estos son algunos de nuestros productos: \\n\\n ${template}`, { delay: 700 })\n            flowDynamic(`Indicame cual deseas ver, ${Array.from({ length: purchase.length}, (_, i) => i + 1).join(' o ')}`)\n        })\n        .addAction({ capture: true }, async (ctx, { state, flowDynamic }) => {\n            const purchase = state.get('purchase') as Array<any>\n\n            const product  = purchase.at(Number(ctx.body) -1)\n            await state.update({ product })\n            flowDynamic([\n                {\n                    body: `${product.product_name} - $${product.product_price} c/u\\n\\n${product.product_description}`,\n                    media: product.product_image\n                }\n            ])\n        })\n        .addAnswer('¿Deseas comprar el producto (SI / NO)?')\n    })\n    .setStructuredLayer(z.object({\n        intention: z.enum(['SI', 'NO']).describe('Repuesta del ususario')\n    }), async (ctx, { endFlow, state, flowDynamic }) => {\n        const product = state.get('product') as any\n        if (ctx?.schema?.intention !== 'SI') {\n            return endFlow('Estare acá por si deseas preguntar sobre otro producto')\n        }\n\n        const sc = [\n            {    \n                name: product?.product_name,\n                price: product?.product_price\n            }\n        ] \n        if (state.getMyState()?.sc?.length) {\n            await state.update({\n                sc: [\n                    ...state.getMyState()?.sc,\n                    // @ts-ignore\n                    {    \n                        name: product?.product_name,\n                        price: product?.product_price\n                    }\n                ]\n            })\n        } else {\n            // @ts-ignore\n            await state.update({ \n                sc\n            })\n        }\n\n        const products = sc.map((p) => `${product.product_name.trim()} $${product.product_price} c/u\\n`).join('\\n')\n        const total = sc.map(p => Number(product.product_price)).reduce((a, b) => Math.abs(a + b))\n        const template = `Tu compra es:\\n${products}\\nTotal: $${total} dolares.`\n\n        await flowDynamic(template)\n\n        return endFlow()\n    }, { capture: true })\n    .createFlow()\n\nconst main = async () => {\n    \n    const PORT = process.env.PORT ?? 3008\n    const adapterFlow = createFlow([aiflow])\n\n    const adapterProvider = createProvider(Provider)\n    adapterProvider.on('message', (ctx) => console.log('new message', ctx.body))\n    const adapterDB = new Database()\n\n    const { httpServer, handleCtx } = await createBot({\n        flow: adapterFlow,\n        provider: adapterProvider,\n        database: adapterDB,\n    })\n    httpServer(+PORT)\n\n\n    adapterProvider.server.post(\n        '/v1/loyalty',\n        handleCtx(async (bot, req, res) => {\n            const { number, name } = req.body\n            await bot?.dispatch('L0Y4LTY', { from: number, name })\n            return res.end('trigger')\n        })\n    )\n  \n}\n\nmain()\n\n```","readmeFilename":"README.md","gitHead":"e79dd31a2306e981cea5834d381b4238e9797bc4","_nodeVersion":"20.10.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-kKlC+QyEnL6bEorx/9aYBpM16SVjwFvG+W+t9wPJkjqjAqY0XIJRbevonEeR87bl/vfCUn+J8hbUsUNbruZVXQ==","shasum":"3709ef1bece2391a51a676ea13e7713865c6fbf7","tarball":"https://registry.npmjs.org/@elimeleth/builderbot-langchain/-/builderbot-langchain-1.3.1-alpha.1.tgz","fileCount":62,"unpackedSize":82085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC/itWiUhC3sgZ8edF4jxGRHIJkzukJS6EW9YILESpQVgIgXZv/VQzFU1KKOdZC6JPD5LNpeAZ2v+U3urtv7isVlEA="}]},"_npmUser":{"name":"elimeleth","email":"juancapuanolopez@gmail.com"},"directories":{},"maintainers":[{"name":"elimeleth","email":"juancapuanolopez@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/builderbot-langchain_1.3.1-alpha.1_1713282091599_0.2271380928863378"},"_hasShrinkwrap":false},"1.3.2-alpha.1":{"name":"@elimeleth/builderbot-langchain","version":"1.3.2-alpha.1","description":"Interface para crear chatbot con Builderbot & LangChain","main":"dist/index.cjs","types":"dist/index.d.ts","type":"module","keywords":["chatbot","builderbot","langchain","whatsapp","telegram"],"author":{"name":"Elimeleth Capuano","email":"elimeleth.contacto@gmail.com"},"scripts":{"test":"jest","build":"rimraf dist && npx rollup --config","dev":"tsm src/index.ts","start":"pnpm run build && node dist/index.cjs","local:build":"pnpm run build && npm pack"},"dependencies":{"@builderbot-plugins/fast-embedding":"1.0.0-alpha.0","@builderbot/bot":"1.1.0","@langchain/cloudflare":"^0.0.4","@langchain/community":"^0.0.47","@langchain/core":"^0.1.57","@langchain/google-genai":"^0.0.11","@langchain/openai":"^0.0.28","@oramacloud/client":"^1.0.14","axios":"^1.6.8","d3-dsv":"2","dotenv":"^16.4.5","hnswlib-node":"^3.0.0","langchain":"^0.1.33","pdf-parse":"^1.1.1","tslib":"^2.6.2","zod":"^3.22.4"},"devDependencies":{"@builderbot-plugins/telegram":"2.0.11-alpha.0","@jest/globals":"29.7.0","@rollup/plugin-commonjs":"25.0.7","@rollup/plugin-node-resolve":"15.2.3","@types/node":"^20.12.5","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","rimraf":"5.0.5","rollup-plugin-typescript2":"0.36.0","tsm":"^2.3.0","typescript":"^5.4.4"},"_id":"@elimeleth/builderbot-langchain@1.3.2-alpha.1","readme":"\nThis is a mockup with a shopify store client and Orama retriever\n\n```ts\nimport \"dotenv/config\"\nimport { createBot, createProvider, createFlow, EVENTS } from '@builderbot/bot'\nimport { MemoryDB as Database } from '@builderbot/bot'\nimport { TelegramProvider as Provider } from \"@builderbot-plugins/telegram\"\n\nimport z from \"zod\"\nimport { createAIFlow } from \"./src/index\"\n\nimport { OramaClient } from '@oramacloud/client' \nimport { Product } from \"./src/types\"\n\nconst client = new OramaClient({ \n    endpoint: 'https://cloud.orama.run/v1/indexes/my-shopify-irxv20', \n    api_key: 'YOUR-ORAMA-API-KEY' \n  }) \n\nconst aiflow = createAIFlow\n    .setKeyword(EVENTS.WELCOME)\n    .pipe(({ addAnswer }) => {\n        return addAnswer('Hola!, dejame buscar entre el stock...')\n    })\n    .setStructuredLayer(z.object({ \n        intention: z.enum(['SALES']).describe(`La intención del cliente:\n            SALES: Si el cliente pregunta, quiere informacion o esta interesado en uno o mas productos\n        \n        `)\n    }), async (ctx, { endFlow }) => {\n        console.log(ctx?.schema)\n        if (ctx?.schema) {\n            const { intention } = ctx.schema\n            \n            if (intention !== 'SALES') {\n                return endFlow('Lo siento, Intenta preguntando sobre un producto')\n            }\n        }\n    })\n    .setContextLayer(\n        z.object({\n            product_name: z.string().describe('El producto que busca el cliente'),\n         }),\n        async (ctx) => {\n            console.log({ details: ctx?.context })\n        }\n    )\n    .setStore({\n        searchFn: async (term) => {\n            console.log({ term })\n\n            const { hits } = await client.search({ term, limit: 7 }) as any\n            const products = hits.map(hit => hit.document) as Product[]\n\n            const mapProducts = products.map(({ \n                title,\n                variants,\n                priceRange,\n                options,\n                description, \n                featuredImage,  }) => ({\n                    product_description: description,\n                    product_image: featuredImage.url,\n                    product_name: title,\n                    // product_variants: variants\n                    // .map(({ price, selectedOptions }) => ({ price, options: selectedOptions })),\n                    product_price: priceRange.min,\n                    // product_options: options,\n                }))\n\n            return mapProducts\n        }\n    })\n    .createRunnable({\n         answerSchema: z.object({\n            answer: z\n              .string()\n              .describe('Agrega una respuesta breve y clara sobre el producto.'),\n            metadata: z.array(z.object({\n            product_image: z.string()\n                .describe('La url de la imagen del producto'),\n            product_name: z\n              .string()\n              .describe(\"Nombre exacto del producto (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"),\n            product_price: z\n              .string()\n              .describe(\n                \"precio exacto del producto (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"\n              ),\n            product_description: z\n              .string()\n              .describe(\n                \"Dale un breve pitch de venta a la descripcion del producto indica beneficios y caracteristicas (SIN ALTERAR) que pregunta el cliente debe venir del contexto.\"\n              )\n          }))\n          .nullable().default([])\n          .describe('Dado los siguientes productos, estructura los que tengan relación con la busqueda')\n          }).describe('El formato de respuesta debe ser el siguiente')\n    }, {\n        onFailure: (err) => {\n            console.log({ err })\n        }\n    })\n    .pipe(({ addAction }) => {\n        return addAction(async (_, { state, endFlow }) => {\n            const answer = state.get('answer')\n            console.log('answer', answer)\n            if (!answer?.metadata?.length) {\n                return endFlow('Lo siento, Intenta preguntando sobre otro producto')\n            }\n\n            await state.update({ purchase: answer.metadata })\n        })\n        .addAction(async (_, { state, flowDynamic }) => {\n            const purchase = state.get('purchase')\n\n            const template = purchase.map((p: any, i: number) => `${i+1}. ${p.product_name}\\nPrecio: $${p.product_price} c/u`).join('\\n\\n')\n\n            await flowDynamic(`Estos son algunos de nuestros productos: \\n\\n ${template}`, { delay: 700 })\n            flowDynamic(`Indicame cual deseas ver, ${Array.from({ length: purchase.length}, (_, i) => i + 1).join(' o ')}`)\n        })\n        .addAction({ capture: true }, async (ctx, { state, flowDynamic }) => {\n            const purchase = state.get('purchase') as Array<any>\n\n            const product  = purchase.at(Number(ctx.body) -1)\n            await state.update({ product })\n            flowDynamic([\n                {\n                    body: `${product.product_name} - $${product.product_price} c/u\\n\\n${product.product_description}`,\n                    media: product.product_image\n                }\n            ])\n        })\n        .addAnswer('¿Deseas comprar el producto (SI / NO)?')\n    })\n    .setStructuredLayer(z.object({\n        intention: z.enum(['SI', 'NO']).describe('Repuesta del ususario')\n    }), async (ctx, { endFlow, state, flowDynamic }) => {\n        const product = state.get('product') as any\n        if (ctx?.schema?.intention !== 'SI') {\n            return endFlow('Estare acá por si deseas preguntar sobre otro producto')\n        }\n\n        const sc = [\n            {    \n                name: product?.product_name,\n                price: product?.product_price\n            }\n        ] \n        if (state.getMyState()?.sc?.length) {\n            await state.update({\n                sc: [\n                    ...state.getMyState()?.sc,\n                    // @ts-ignore\n                    {    \n                        name: product?.product_name,\n                        price: product?.product_price\n                    }\n                ]\n            })\n        } else {\n            // @ts-ignore\n            await state.update({ \n                sc\n            })\n        }\n\n        const products = sc.map((p) => `${product.product_name.trim()} $${product.product_price} c/u\\n`).join('\\n')\n        const total = sc.map(p => Number(product.product_price)).reduce((a, b) => Math.abs(a + b))\n        const template = `Tu compra es:\\n${products}\\nTotal: $${total} dolares.`\n\n        await flowDynamic(template)\n\n        return endFlow()\n    }, { capture: true })\n    .createFlow()\n\nconst main = async () => {\n    \n    const PORT = process.env.PORT ?? 3008\n    const adapterFlow = createFlow([aiflow])\n\n    const adapterProvider = createProvider(Provider)\n    adapterProvider.on('message', (ctx) => console.log('new message', ctx.body))\n    const adapterDB = new Database()\n\n    const { httpServer, handleCtx } = await createBot({\n        flow: adapterFlow,\n        provider: adapterProvider,\n        database: adapterDB,\n    })\n    httpServer(+PORT)\n\n\n    adapterProvider.server.post(\n        '/v1/loyalty',\n        handleCtx(async (bot, req, res) => {\n            const { number, name } = req.body\n            await bot?.dispatch('L0Y4LTY', { from: number, name })\n            return res.end('trigger')\n        })\n    )\n  \n}\n\nmain()\n\n```","readmeFilename":"README.md","gitHead":"ea2725a908ffa0f87efd92bbe06de838efc63b0f","_nodeVersion":"20.10.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-k6yCpaMwHLbwa+Y+LiMGNv2oVQw8Kv4+f9pe+O12BnQ8brRf5uRiJdlXekbAjzENBD238eCDCIiKKoPnH1pP0g==","shasum":"0d67e37cbecf20755e2f610680d476f67a9c10b2","tarball":"https://registry.npmjs.org/@elimeleth/builderbot-langchain/-/builderbot-langchain-1.3.2-alpha.1.tgz","fileCount":62,"unpackedSize":82320,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG3ZDYWeH7UJBTI0bIHpm5YRlQ/Y/jjQRBJt8CSWfi4SAiATF0ThYXYgxgTD5R6iR2uD6tVPQEQKywUOSZr83ZC8MQ=="}]},"_npmUser":{"name":"elimeleth","email":"juancapuanolopez@gmail.com"},"directories":{},"maintainers":[{"name":"elimeleth","email":"juancapuanolopez@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/builderbot-langchain_1.3.2-alpha.1_1713537075820_0.9248986414411673"},"_hasShrinkwrap":false}},"time":{"created":"2024-04-14T15:09:45.923Z","1.0.0-alpha.0":"2024-04-14T15:09:46.239Z","modified":"2024-04-19T14:31:16.203Z","1.0.1-alpha.0":"2024-04-14T22:24:21.795Z","1.2.0-alpha.0":"2024-04-15T21:48:34.465Z","1.3.1-alpha.1":"2024-04-16T15:41:31.769Z","1.3.2-alpha.1":"2024-04-19T14:31:15.995Z"},"maintainers":[{"name":"elimeleth","email":"juancapuanolopez@gmail.com"}],"description":"Interface para crear chatbot con Builderbot & LangChain","keywords":["chatbot","builderbot","langchain","whatsapp","telegram"],"author":{"name":"Elimeleth Capuano","email":"elimeleth.contacto@gmail.com"},"readme":"","readmeFilename":""}