{"_id":"@aeye/openai","_rev":"14-c8bbf7cfc64c9e1776f1a40b26517809","name":"@aeye/openai","dist-tags":{"latest":"0.3.10"},"versions":{"0.1.0":{"name":"@aeye/openai","version":"0.1.0","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"MIT","_id":"@aeye/openai@0.1.0","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"495dc3e1aaf879be8500182003a62694fb0d6730","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.1.0.tgz","fileCount":18,"integrity":"sha512-UmZ7H8upok9+uruLj90M9w7UU4y0QFvi8v3+uHsW4GZhrJ5sN14FFaqY3/ddodBp1pGgLDlyvSQ25tCrH2E9YA==","signatures":[{"sig":"MEQCIASTANIrquzpKKEjb8Hj9+Xv0y+Y8yVhsGjSAhf2ySmiAiARPVYInBb6euosXv/phq6ts/n2tfAYpK/HNo0iSjYbVg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":199165},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"7e1a90cc8ba4f871aaa577977959317604a10b08","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.1.0","@aeye/core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.1.0_1763393630052_0.3027397604144608","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aeye/openai","version":"0.1.1","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.1.1","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"23205227e42ee6b4af96ab5eb8db7cf0718fc362","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.1.1.tgz","fileCount":18,"integrity":"sha512-oVtpx+z+Go/tZTspSSVfX9t27hiMaB+3KPlco5QJzTIki8rXJR6xT4F7O0ngBxh5hemia42pai5r6kGHi4lV3A==","signatures":[{"sig":"MEYCIQDqAxb5Uq2NxcEBJEosCYvJ70FMDmfNt8lXwA2aQDW/LwIhAM4UvrSVvRKkhSPPmAQ51M1uj80PeM9eeGO+ByQ6dVx9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":214907},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"2515fffb0b757b7460c813024d78f3481ba58d10","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.1.0","@aeye/core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.1.1_1763671241722_0.8612161031179093","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@aeye/openai","version":"0.1.2","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.1.2","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"7e4afd2004671a093a30b47e68e38b0efb9cbb45","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.1.2.tgz","fileCount":18,"integrity":"sha512-RSSbrJoe4o5Yn7r78NESZxJBHZXmHZedt7ajsZ3fq8zv5yNYgQacdhFqpZbpoIBDvjBGbbZRW/NkfhleVJtITg==","signatures":[{"sig":"MEUCIQCuHwwHPZNT7ovnhQSfghG4UYbZDSE7h2cfbjPEIrrNRgIgdEBH2SGzoAJpoMalPd+7ET085DYe3HfOZQiX7UJfIXc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":214907},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"641945e342414d4b1e6a1f09ca46d23aa87c78f9","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.1.0","@aeye/core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.1.2_1763672827102_0.046160358311846617","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aeye/openai","version":"0.2.0","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.2.0","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"69db819779264c57d0ee4837cfa5e10855926d17","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.2.0.tgz","fileCount":18,"integrity":"sha512-x8NBVmoNAO/c6SuhNci4cUBmqpuQMn2IPj9lRvL3UMXOSYDmD/scItx2yag1mBRGGtsbxgUoAZR+iy3nkGrKUQ==","signatures":[{"sig":"MEUCIQDc/Tg+Dh8b6pigAtKhgtyiudoe27EUUGxoPb2zz0PahgIgYxAhFlX09jnXJgjMU68pFQf0p3rw13Jq/nPKGUWtbm0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200806},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"25679e42025ba167faec33e98d702939cc22f2c0","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.1.0","@aeye/core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.2.0_1764260296681_0.8227385094334494","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aeye/openai","version":"0.3.0","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.0","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"ad49f0b6698b904d3ff5f8f1e0d31884a17dd3dd","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.0.tgz","fileCount":18,"integrity":"sha512-qBRq6QkpOvBMLmSTCXGNNZI/RpU++IU8xeq2ZAvkNi2eLngHwAp31+VsSsmoudIoknSbom6js2NRnzr5ltMxaA==","signatures":[{"sig":"MEYCIQD4lJzHOmaHEdkeI2DTL60w/0eEMuwtXhiZK4+C64ZIlwIhAPBzOJxwBymDPjcfmtBVUB/v2vj3M0Rd9bTxVq9NrapB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206811},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"fe6afb5adb096a8de1dfc9a115bba1d48193612d","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.0","@aeye/core":"^0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.0_1764993451469_0.9561034120069638","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aeye/openai","version":"0.3.1","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.1","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"b0c830b0f29c1955584d321c59e976d65f9cc0e2","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.1.tgz","fileCount":18,"integrity":"sha512-Gvy1IO/r3nOJ1ZgtOurTtzlFWaKX0Qx1u50pYp3RnXmboT2fCGC2ECTAOJRIfXd1JQPKL2unpk+HovbPtGHCCA==","signatures":[{"sig":"MEQCIFQy+WUmQ0I3wDmRdMGXzQkcdbEzykRoKsgummBbzfLRAiAzIRPkV8Ar0gjxFLW8+xcufpsE2x+AHCrWZL5lKf1y9w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206805},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"cabd7c1d28f8048b51cb89b40efa8d07cead332d","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.1","@aeye/core":"^0.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.1_1765363624113_0.4488088702465014","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aeye/openai","version":"0.3.2","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.2","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"a4f6d61a03f9b03946a73d098cb01b4a7a1a0382","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.2.tgz","fileCount":18,"integrity":"sha512-HE3SwjcrGykvPvhKSa6LRDZQhl14bRNKI02xf94kDALU2oTSvjkW8U1W2xywKd/8VYHUnpIc4cgogbbgFMzo5Q==","signatures":[{"sig":"MEUCIQCkRlbjgmgPo9JmeSihpGMnIBgU1IIoD+4i8pxQZOiSeAIgZ+dDqtYATEXq/nykwfrW9Z3tVVnWTDlGcgQ6PGRwktk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206805},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"ae51c2a8249a968b210a64efc7c8bedb35fad70b","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.2","@aeye/core":"^0.3.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.2_1766336260664_0.9514371706537412","host":"s3://npm-registry-packages-npm-production"}},"0.3.4":{"name":"@aeye/openai","version":"0.3.4","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.4","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"92e4f08a43d6d35928cd781b5b11de1cb805adf4","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.4.tgz","fileCount":18,"integrity":"sha512-jtY1oNueyswkfjQuLc/jNZwb32LqtL2sNKhb4IW9NaFL6ZMWyIjD4hesEhQL8NDruqYONrBGe/aAk7BkpqyrFA==","signatures":[{"sig":"MEYCIQD+OIwLAiZGsyY9ajTW/ktr2bvZi5x329O1jEC5FZGW2AIhANOcevWBF63I3D8SdOs3NX2BMrY0n6zV7++SoQaexl2i","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206805},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"3f4fe5f9da6cad0851958297b5dd34b2c795d6d2","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.4","@aeye/core":"^0.3.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.4_1770754891444_0.34295052485048094","host":"s3://npm-registry-packages-npm-production"}},"0.3.5":{"name":"@aeye/openai","version":"0.3.5","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.5","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"4d589097263b577f633b2c0ceea6410de86cd7f5","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.5.tgz","fileCount":18,"integrity":"sha512-y26HfCTPAptyiw/+6qvARud4T5QUPykYbtB7cHfrFcLO7ho9sk2VYahADBxnU6wZPKyT8nf/77+aOo7ryFQgAQ==","signatures":[{"sig":"MEUCIQDWUn2Rb16BCWUTi1l4YD9JCBD20kJV5wkxKchVO7P6TwIgcgLYlugPh/WhRD5cMZU7URPbffm7AHcmomOfeREloLA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206805},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"gitHead":"1ca1832163262906c1ae12624a107c0652daeb68","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.5","@aeye/core":"^0.3.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.5_1770757034092_0.39101218779073754","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"@aeye/openai","version":"0.3.6","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.6","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"b16dc8fd9d16ecfceace03cba631ccd4f250e0ab","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.6.tgz","fileCount":18,"integrity":"sha512-ZeUdtGwbXGn1SP11lLQOymm4pPfUo+nBGYRk2m6QcysLnmK4StaJ3aXLz5l8l9YKiHd/zqNiklYOBWtIgwxmnw==","signatures":[{"sig":"MEUCIFjZvwWZjvJJPvTb9s/HaQ2FrEikwQtpEsYyz7lwXIvNAiEAlgDPSDT4INWTxFhUWrGgUrSwdj/0bDkNP0B7bHIeklo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":207082},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"default":"./dist/index.js","require":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"gitHead":"1ca1832163262906c1ae12624a107c0652daeb68","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.6","@aeye/core":"^0.3.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.6_1772640918734_0.5712276490358368","host":"s3://npm-registry-packages-npm-production"}},"0.3.7":{"name":"@aeye/openai","version":"0.3.7","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.7","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"727177bbc9c14a6497ff1aa4aaca1c7a317c799b","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.7.tgz","fileCount":18,"integrity":"sha512-RjLe7bU7jz3f+fDKblep3x6ot0inXlLKxk6JOiCzT4BsxVuEwYezED4jCfUCXn9cmscYFkOZNPrCjeiCe1YKtg==","signatures":[{"sig":"MEYCIQCCcXsM7pzmu4s/yl25p3J2BSzFvFSfljZm00e+75sgBgIhAMP5+X2ROzCdsBeN9r6rfS935eAR+uGzIlhWMUxKP+Xb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":207082},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"default":"./dist/index.js","require":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"gitHead":"a3490a88105713496870fbcf0a8d5ff9d85a3e6c","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.7","@aeye/core":"^0.3.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.7_1772642470336_0.5194806262284437","host":"s3://npm-registry-packages-npm-production"}},"0.3.8":{"name":"@aeye/openai","version":"0.3.8","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.8","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"39fad7d2e2a26c9ad2ddc82f159f06162b42c5e2","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.8.tgz","fileCount":18,"integrity":"sha512-PDly2kly/3ZGTr4sAScnGOgbjmvH/uDFY4jGP0izmwaKCa2w4gHc4F/2rFOyaS57Cwg56ArSHtAC1R2IYsnhrw==","signatures":[{"sig":"MEUCIQDTcu7YpMvAz0xxFTsCwuUcDCCJTf6enfxygUNi1jGFMQIgXW30r7DxP6YWoCgcsW8HaZYi3h9htKM4Sk3dDp8h73M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":212871},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"default":"./dist/index.js","require":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"gitHead":"04319fa907b4c219f0843292baa1bcd313a97c74","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.8.2","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"20.18.1","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.8","@aeye/core":"^0.3.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.8_1775335853022_0.22649988144596644","host":"s3://npm-registry-packages-npm-production"}},"0.3.9":{"name":"@aeye/openai","version":"0.3.9","keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","_id":"@aeye/openai@0.3.9","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"dist":{"shasum":"c64027d08dcb8aa7a28fb03c270da45adeb5a6fd","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.9.tgz","fileCount":19,"integrity":"sha512-WqGLK85vOda71qPwYLt7Ilrzb+R0H4tAGv3JrkxfoISGplBkrG/qgVkQVSZ+SBXDcnGwSTXLnjvnS4obQrKjcg==","signatures":[{"sig":"MEQCIFLZ2tSG0xY3LoOGRqsZ8gfnxcrxumybwUraae8DrTd6AiA6BYt2kZqJvEgYU0UhaerycTP3bFrARy9C/OiNuwA96Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":235726},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"default":"./dist/index.js","require":{"types":"./dist/index.d.ts","default":"./dist/index.js"}}},"gitHead":"7df3bae899c5a30cf17f4925fb7057e9a61e7332","scripts":{"test":"jest","build":"tsc","clean":"rimraf dist tsconfig.tsbuildinfo","test:unit":"jest --testPathIgnorePatterns=__integration__","typecheck":"tsc --noEmit","test:watch":"jest --watch","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__"},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"repository":{"url":"git+https://github.com/ClickerMonkey/aeye.git","type":"git","directory":"packages/openai"},"_npmVersion":"10.9.8","description":"@aeye OpenAI - OpenAI integration for @aeye","directories":{},"_nodeVersion":"22.22.3","dependencies":{"zod":"^4.1.12","openai":"^6.6.0","@aeye/ai":"^0.3.9","@aeye/core":"^0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3","@types/jest":"^30.0.0","@types/node":"^24.10.1"},"_npmOperationalInternal":{"tmp":"tmp/openai_0.3.9_1783858083596_0.846944098240076","host":"s3://npm-registry-packages-npm-production"}},"0.3.10":{"name":"@aeye/openai","version":"0.3.10","description":"@aeye OpenAI - OpenAI integration for @aeye","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"default":"./dist/index.js"}},"scripts":{"build":"tsc","test":"jest","test:unit":"jest --testPathIgnorePatterns=__integration__","test:integration":"jest --testPathPattern=__integration__","test:coverage":"jest --coverage --testPathIgnorePatterns=__integration__","test:watch":"jest --watch","clean":"rimraf dist tsconfig.tsbuildinfo","typecheck":"tsc --noEmit"},"keywords":["ai","openai","typescript"],"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/ClickerMonkey/aeye.git","directory":"packages/openai"},"dependencies":{"@aeye/ai":"^0.3.9","@aeye/core":"^0.3.9","openai":"^6.6.0","zod":"^4.1.12"},"devDependencies":{"@types/jest":"^30.0.0","@types/node":"^24.10.1","jest":"^30.2.0","ts-jest":"^29.4.5","typescript":"^5.9.3"},"publishConfig":{"access":"public"},"engines":{"node":">=16.0.0"},"homepage":"https://github.com/ClickerMonkey/aeye#readme","bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"_id":"@aeye/openai@0.3.10","gitHead":"4ad1dab1c6ee79a2d325b2b94c3fe1975741ea43","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-CV1Ug/tkFMBo/hy4bcswDUXgdNLnALUb75kchYVrNKQ9EtdAV5P19tPhaOX58b+53EovhRv812usJ0opFz+ecQ==","shasum":"95d0890ecdddbabf0ac1bab7465b12383858adb6","tarball":"https://registry.npmjs.org/@aeye/openai/-/openai-0.3.10.tgz","fileCount":19,"unpackedSize":236173,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGVOYPG7G/kSD60aFmexDA1p7a8ZEhM54n0TLsrx0e25AiEA+pYk+E87XyO8LowvySUvQL+2d7QZc+aS7JETQCwqJ4Y="}]},"_npmUser":{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"},"directories":{},"maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openai_0.3.10_1787434693455_0.9421704646468594"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-17T15:33:49.918Z","modified":"2026-08-22T21:38:13.835Z","0.1.0":"2025-11-17T15:33:50.283Z","0.1.1":"2025-11-20T20:40:41.919Z","0.1.2":"2025-11-20T21:07:07.285Z","0.2.0":"2025-11-27T16:18:16.882Z","0.3.0":"2025-12-06T03:57:31.635Z","0.3.1":"2025-12-10T10:47:04.255Z","0.3.2":"2025-12-21T16:57:40.813Z","0.3.4":"2026-02-10T20:21:31.601Z","0.3.5":"2026-02-10T20:57:14.234Z","0.3.6":"2026-03-04T16:15:18.900Z","0.3.7":"2026-03-04T16:41:10.568Z","0.3.8":"2026-04-04T20:50:53.166Z","0.3.9":"2026-07-12T12:08:03.782Z","0.3.10":"2026-08-22T21:38:13.600Z"},"bugs":{"url":"https://github.com/ClickerMonkey/aeye/issues"},"author":{"name":"ClickerMonkey"},"license":"GPL-3.0","homepage":"https://github.com/ClickerMonkey/aeye#readme","keywords":["ai","openai","typescript"],"repository":{"type":"git","url":"git+https://github.com/ClickerMonkey/aeye.git","directory":"packages/openai"},"description":"@aeye OpenAI - OpenAI integration for @aeye","maintainers":[{"name":"philip.diffenderfer","email":"pdiffenderfer@gmail.com"}],"readme":"# @aeye/openai\r\n\r\nOpenAI provider for the @aeye (AI TypeScript) framework. This package provides a comprehensive integration with OpenAI's API, supporting the full range of capabilities including chat completions, image generation, speech synthesis, transcription, and embeddings.\r\n\r\n## Features\r\n\r\n- **Chat Completions**: Support for GPT-4, GPT-4 Turbo, GPT-3.5 Turbo, and other chat models\r\n- **Vision**: GPT-4 Vision (GPT-4V) for image understanding\r\n- **Reasoning Models**: o1, o1-mini, o3-mini for advanced reasoning tasks\r\n- **Image Generation**: DALL-E 2 and DALL-E 3 for creating images from text\r\n- **Speech-to-Text**: Whisper models for audio transcription\r\n- **Text-to-Speech**: TTS models for voice synthesis\r\n- **Embeddings**: Text embeddings for semantic search and similarity\r\n- **Function Calling**: Tool/function calling with automatic schema conversion\r\n- **Structured Outputs**: JSON mode and schema-based structured outputs\r\n- **Streaming**: Real-time streaming responses for chat completions\r\n- **Multi-modal**: Support for text, images, audio, and files in conversations\r\n- **Extensible**: Base class for OpenAI-compatible providers (Azure OpenAI, OpenRouter, etc.)\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @aeye/openai @aeye/ai @aeye/core openai zod\r\n```\r\n\r\n## Quick Start\r\n\r\n```typescript\r\nimport { OpenAIProvider } from '@aeye/openai';\r\n\r\n// Create provider instance\r\nconst provider = new OpenAIProvider({\r\n  apiKey: process.env.OPENAI_API_KEY!,\r\n});\r\n\r\n// Create executor\r\nconst executor = provider.createExecutor();\r\n\r\n// Make a request\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      { role: 'user', content: 'Tell me a joke about TypeScript' }\r\n    ]\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n\r\nconsole.log(response.content);\r\n```\r\n\r\n## Configuration\r\n\r\n### Basic Configuration\r\n\r\n```typescript\r\nimport { OpenAIProvider, OpenAIConfig } from '@aeye/openai';\r\n\r\nconst config: OpenAIConfig = {\r\n  apiKey: process.env.OPENAI_API_KEY!,\r\n  organization: 'org-123456', // Optional: for multi-org accounts\r\n};\r\n\r\nconst provider = new OpenAIProvider(config);\r\n```\r\n\r\n### Custom Base URL (for Azure OpenAI or compatible APIs)\r\n\r\n```typescript\r\nconst provider = new OpenAIProvider({\r\n  apiKey: process.env.AZURE_API_KEY!,\r\n  baseURL: 'https://your-resource.openai.azure.com/openai/deployments/your-deployment',\r\n});\r\n```\r\n\r\n## Usage Examples\r\n\r\n### Chat Completions\r\n\r\n#### Basic Chat\r\n\r\n```typescript\r\nconst executor = provider.createExecutor();\r\n\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      { role: 'system', content: 'You are a helpful assistant.' },\r\n      { role: 'user', content: 'What is the capital of France?' }\r\n    ],\r\n    temperature: 0.7,\r\n    maxTokens: 150,\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n\r\nconsole.log(response.content);\r\nconsole.log('Tokens used:', response.usage.totalTokens);\r\n```\r\n\r\n#### Streaming Chat\r\n\r\n```typescript\r\nconst streamer = provider.createStreamer();\r\n\r\nfor await (const chunk of streamer(\r\n  {\r\n    messages: [\r\n      { role: 'user', content: 'Write a short story about a robot' }\r\n    ]\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n)) {\r\n  if (chunk.content) {\r\n    process.stdout.write(chunk.content);\r\n  }\r\n}\r\n```\r\n\r\n#### Multi-turn Conversation\r\n\r\n```typescript\r\nconst conversation = [\r\n  { role: 'system' as const, content: 'You are a helpful assistant.' },\r\n  { role: 'user' as const, content: 'What is TypeScript?' },\r\n];\r\n\r\n// First response\r\nlet response = await executor(\r\n  { messages: conversation },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n\r\nconversation.push({ role: 'assistant', content: response.content });\r\nconversation.push({ role: 'user', content: 'Can you give me an example?' });\r\n\r\n// Second response\r\nresponse = await executor(\r\n  { messages: conversation },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n```\r\n\r\n### Vision (GPT-4V)\r\n\r\n#### Analyze an Image\r\n\r\n```typescript\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      {\r\n        role: 'user',\r\n        content: [\r\n          { type: 'text', content: 'What is in this image?' },\r\n          {\r\n            type: 'image',\r\n            content: 'https://example.com/image.jpg',\r\n            // Or use base64: content: 'data:image/jpeg;base64,/9j/4AAQ...'\r\n          }\r\n        ]\r\n      }\r\n    ]\r\n  },\r\n  {},\r\n  { model: 'gpt-4-vision-preview' }\r\n);\r\n```\r\n\r\n#### Multiple Images\r\n\r\n```typescript\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      {\r\n        role: 'user',\r\n        content: [\r\n          { type: 'text', content: 'Compare these two images' },\r\n          { type: 'image', content: 'https://example.com/image1.jpg' },\r\n          { type: 'image', content: 'https://example.com/image2.jpg' }\r\n        ]\r\n      }\r\n    ]\r\n  },\r\n  {},\r\n  { model: 'gpt-4-vision-preview' }\r\n);\r\n```\r\n\r\n### Function Calling\r\n\r\n#### Define and Use Tools\r\n\r\n```typescript\r\nimport z from 'zod';\r\n\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      { role: 'user', content: 'What is the weather like in San Francisco?' }\r\n    ],\r\n    tools: [\r\n      {\r\n        name: 'get_current_weather',\r\n        description: 'Get the current weather in a given location',\r\n        parameters: z.object({\r\n          location: z.string().describe('The city and state, e.g., San Francisco, CA'),\r\n          unit: z.enum(['celsius', 'fahrenheit']).optional(),\r\n        }),\r\n      }\r\n    ],\r\n    toolChoice: 'auto', // Can be 'auto', 'required', 'none', or { tool: 'tool_name' }\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n\r\nif (response.toolCalls) {\r\n  for (const toolCall of response.toolCalls) {\r\n    console.log('Tool:', toolCall.name);\r\n    console.log('Arguments:', JSON.parse(toolCall.arguments));\r\n\r\n    // Execute the function and send result back\r\n    const functionResult = await getWeather(JSON.parse(toolCall.arguments));\r\n\r\n    const finalResponse = await executor(\r\n      {\r\n        messages: [\r\n          { role: 'user', content: 'What is the weather like in San Francisco?' },\r\n          { role: 'assistant', content: '', toolCalls: [toolCall] },\r\n          {\r\n            role: 'tool',\r\n            content: JSON.stringify(functionResult),\r\n            toolCallId: toolCall.id,\r\n          }\r\n        ]\r\n      },\r\n      {},\r\n      { model: 'gpt-4' }\r\n    );\r\n  }\r\n}\r\n```\r\n\r\n#### Force Specific Tool\r\n\r\n```typescript\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      { role: 'user', content: 'Get the weather for Boston' }\r\n    ],\r\n    tools: [\r\n      {\r\n        name: 'get_weather',\r\n        description: 'Get weather information',\r\n        parameters: z.object({\r\n          location: z.string(),\r\n        }),\r\n      }\r\n    ],\r\n    toolChoice: { tool: 'get_weather' }, // Force this specific tool\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n```\r\n\r\n### Structured Outputs\r\n\r\n#### JSON Mode\r\n\r\n```typescript\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      {\r\n        role: 'user',\r\n        content: 'List three famous scientists and their main contributions in JSON format'\r\n      }\r\n    ],\r\n    responseFormat: 'json', // Ensures valid JSON output\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n\r\nconst scientists = JSON.parse(response.content);\r\n```\r\n\r\n#### Schema-based Structured Output\r\n\r\n```typescript\r\nimport z from 'zod';\r\n\r\nconst PersonSchema = z.object({\r\n  name: z.string(),\r\n  age: z.number(),\r\n  occupation: z.string(),\r\n  hobbies: z.array(z.string()),\r\n});\r\n\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      {\r\n        role: 'user',\r\n        content: 'Generate a profile for a fictional software engineer'\r\n      }\r\n    ],\r\n    responseFormat: PersonSchema, // Strict schema enforcement\r\n  },\r\n  {},\r\n  { model: 'gpt-4' }\r\n);\r\n\r\n// Response is guaranteed to match the schema\r\nconst person = JSON.parse(response.content);\r\nconsole.log(person.name, person.age); // Type-safe\r\n```\r\n\r\n### Image Generation (DALL-E)\r\n\r\n#### Generate with DALL-E 3\r\n\r\n```typescript\r\nconst imageResponse = await provider.generateImage(\r\n  {\r\n    prompt: 'A serene landscape with mountains and a lake at sunset',\r\n    model: 'dall-e-3',\r\n    size: '1024x1024',\r\n    quality: 'hd', // 'standard' or 'hd'\r\n    style: 'vivid', // 'vivid' or 'natural'\r\n    n: 1,\r\n  },\r\n  {}\r\n);\r\n\r\nconsole.log('Generated image URL:', imageResponse.images[0].url);\r\nconsole.log('Revised prompt:', imageResponse.images[0].revisedPrompt);\r\n```\r\n\r\n#### Generate Multiple Images with DALL-E 2\r\n\r\n```typescript\r\nconst imageResponse = await provider.generateImage(\r\n  {\r\n    prompt: 'A cute robot playing with a puppy',\r\n    model: 'dall-e-2',\r\n    size: '512x512',\r\n    n: 3, // Generate 3 variations\r\n  },\r\n  {}\r\n);\r\n\r\nimageResponse.images.forEach((img, i) => {\r\n  console.log(`Image ${i + 1}:`, img.url);\r\n});\r\n```\r\n\r\n#### Get Base64 Image Data\r\n\r\n```typescript\r\nconst imageResponse = await provider.generateImage(\r\n  {\r\n    prompt: 'A futuristic city skyline',\r\n    model: 'dall-e-3',\r\n    responseFormat: 'b64_json', // Get base64 instead of URL\r\n  },\r\n  {}\r\n);\r\n\r\nconst base64Image = imageResponse.images[0].b64_json;\r\n// Save or process the base64 data\r\n```\r\n\r\n### Speech Synthesis (TTS)\r\n\r\n#### Generate Speech\r\n\r\n```typescript\r\nimport fs from 'fs';\r\n\r\nconst speechResponse = await provider.generateSpeech(\r\n  {\r\n    text: 'Hello! This is a text-to-speech example using OpenAI.',\r\n    model: 'tts-1', // or 'tts-1-hd' for higher quality\r\n    voice: 'alloy', // alloy, echo, fable, onyx, nova, shimmer\r\n    speed: 1.0, // 0.25 to 4.0\r\n    responseFormat: 'mp3', // mp3, opus, aac, flac, wav, pcm\r\n  },\r\n  {}\r\n);\r\n\r\n// Save to file\r\nfs.writeFileSync('output.mp3', speechResponse.audioBuffer);\r\nconsole.log('Audio saved to output.mp3');\r\n```\r\n\r\n#### Different Voices\r\n\r\n```typescript\r\nconst voices = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'];\r\n\r\nfor (const voice of voices) {\r\n  const response = await provider.generateSpeech(\r\n    {\r\n      text: `This is the ${voice} voice speaking.`,\r\n      voice,\r\n      model: 'tts-1',\r\n    },\r\n    {}\r\n  );\r\n\r\n  fs.writeFileSync(`voice_${voice}.mp3`, response.audioBuffer);\r\n}\r\n```\r\n\r\n### Transcription (Whisper)\r\n\r\n#### Transcribe Audio File\r\n\r\n```typescript\r\nimport fs from 'fs';\r\n\r\nconst audioBuffer = fs.readFileSync('audio.mp3');\r\n\r\nconst transcription = await provider.transcribe(\r\n  {\r\n    audio: audioBuffer,\r\n    model: 'whisper-1',\r\n    language: 'en', // Optional: ISO-639-1 language code\r\n    prompt: 'This is a podcast about AI and technology', // Optional: context\r\n  },\r\n  {}\r\n);\r\n\r\nconsole.log('Transcription:', transcription.text);\r\n```\r\n\r\n#### Transcribe with Timestamps\r\n\r\n```typescript\r\nconst transcription = await provider.transcribe(\r\n  {\r\n    audio: audioBuffer,\r\n    model: 'whisper-1',\r\n    responseFormat: 'verbose_json',\r\n    timestampGranularities: ['word', 'segment'],\r\n  },\r\n  {}\r\n);\r\n\r\nconsole.log('Full text:', transcription.text);\r\nconsole.log('Language:', transcription.language);\r\nconsole.log('Duration:', transcription.duration);\r\n\r\n// Word-level timestamps\r\ntranscription.words?.forEach(word => {\r\n  console.log(`${word.word}: ${word.start}s - ${word.end}s`);\r\n});\r\n\r\n// Segment-level timestamps\r\ntranscription.segments?.forEach(segment => {\r\n  console.log(`${segment.text}: ${segment.start}s - ${segment.end}s`);\r\n});\r\n```\r\n\r\n#### Different Output Formats\r\n\r\n```typescript\r\n// Plain text\r\nconst text = await provider.transcribe(\r\n  { audio: audioBuffer, responseFormat: 'text' },\r\n  {}\r\n);\r\n\r\n// SRT subtitles\r\nconst srt = await provider.transcribe(\r\n  { audio: audioBuffer, responseFormat: 'srt' },\r\n  {}\r\n);\r\n\r\n// VTT subtitles\r\nconst vtt = await provider.transcribe(\r\n  { audio: audioBuffer, responseFormat: 'vtt' },\r\n  {}\r\n);\r\n```\r\n\r\n### Embeddings\r\n\r\n#### Generate Embeddings\r\n\r\n```typescript\r\nconst embeddingResponse = await provider.embed(\r\n  {\r\n    texts: [\r\n      'The quick brown fox jumps over the lazy dog',\r\n      'Machine learning is a subset of artificial intelligence',\r\n      'OpenAI develops advanced AI models'\r\n    ],\r\n    model: 'text-embedding-3-small', // or 'text-embedding-3-large'\r\n  },\r\n  {}\r\n);\r\n\r\nembeddingResponse.embeddings.forEach((item, i) => {\r\n  console.log(`Embedding ${i}:`, item.embedding.length, 'dimensions');\r\n});\r\n\r\nconsole.log('Tokens used:', embeddingResponse.usage?.text?.input);\r\n```\r\n\r\n#### Custom Dimensions (for smaller embeddings)\r\n\r\n```typescript\r\nconst embeddingResponse = await provider.embed(\r\n  {\r\n    texts: ['Some text to embed'],\r\n    model: 'text-embedding-3-large',\r\n    dimensions: 256, // Reduce from default 3072 to 256\r\n  },\r\n  {}\r\n);\r\n```\r\n\r\n#### Calculate Similarity\r\n\r\n```typescript\r\nfunction cosineSimilarity(a: number[], b: number[]): number {\r\n  const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);\r\n  const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));\r\n  const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));\r\n  return dotProduct / (magnitudeA * magnitudeB);\r\n}\r\n\r\nconst response = await provider.embed(\r\n  {\r\n    texts: [\r\n      'I love programming in TypeScript',\r\n      'TypeScript is my favorite language',\r\n      'I enjoy cooking Italian food'\r\n    ],\r\n    model: 'text-embedding-3-small',\r\n  },\r\n  {}\r\n);\r\n\r\nconst [emb1, emb2, emb3] = response.embeddings.map(e => e.embedding);\r\n\r\nconsole.log('Similarity 1-2:', cosineSimilarity(emb1, emb2)); // High similarity\r\nconsole.log('Similarity 1-3:', cosineSimilarity(emb1, emb3)); // Low similarity\r\n```\r\n\r\n### Reasoning Models (o1, o3-mini)\r\n\r\n#### Using o1 Models\r\n\r\nThe o1 and o3-mini models use extended thinking to solve complex problems.\r\n\r\n```typescript\r\nconst response = await executor(\r\n  {\r\n    messages: [\r\n      {\r\n        role: 'user',\r\n        content: 'Solve this logic puzzle: There are 100 doors, all closed. You make 100 passes. On pass 1, toggle all doors. On pass 2, toggle every 2nd door. On pass 3, toggle every 3rd door, etc. Which doors are open after 100 passes?'\r\n      }\r\n    ],\r\n    // Note: o1 models don't support temperature or system messages\r\n  },\r\n  {},\r\n  { model: 'o1-preview' } // or 'o1-mini', 'o3-mini'\r\n);\r\n\r\nconsole.log('Reasoning:', response.reasoning); // Internal reasoning process\r\nconsole.log('Answer:', response.content);\r\n```\r\n\r\n**Important**: o1 models have different capabilities:\r\n- No system messages support (use user messages instead)\r\n- No temperature control (model uses internal reasoning)\r\n- No streaming support\r\n- Extended processing time for complex problems\r\n\r\n### Advanced Features\r\n\r\n#### Abort Requests\r\n\r\n```typescript\r\nconst controller = new AbortController();\r\n\r\n// Set timeout\r\nsetTimeout(() => controller.abort(), 5000);\r\n\r\ntry {\r\n  const response = await executor(\r\n    { messages: [{ role: 'user', content: 'Tell me a long story' }] },\r\n    {},\r\n    { model: 'gpt-4' },\r\n    controller.signal\r\n  );\r\n} catch (error) {\r\n  if (error.name === 'AbortError') {\r\n    console.log('Request was aborted');\r\n  }\r\n}\r\n```\r\n\r\n#### List Available Models\r\n\r\n```typescript\r\nconst models = await provider.listModels();\r\n\r\nmodels.forEach(model => {\r\n  console.log(`${model.id}: ${model.capabilities}`);\r\n  console.log(`  Context window: ${model.contextWindow}`);\r\n  console.log(`  Pricing: $${model.pricing.text.input}/1M input tokens`);\r\n});\r\n```\r\n\r\n#### Check Provider Health\r\n\r\n```typescript\r\nconst isHealthy = await provider.checkHealth();\r\nconsole.log('OpenAI API is', isHealthy ? 'accessible' : 'not accessible');\r\n```\r\n\r\n#### Default Metadata\r\n\r\n```typescript\r\n// Set default metadata for all requests\r\nprovider.defaultMetadata = {\r\n  model: 'gpt-4',\r\n  user: 'user-123',\r\n};\r\n\r\n// Now model is automatically set\r\nconst response = await executor(\r\n  { messages: [{ role: 'user', content: 'Hello' }] },\r\n  {}\r\n  // No need to pass { model: 'gpt-4' }\r\n);\r\n```\r\n\r\n## Extending for Custom Providers\r\n\r\nThe `OpenAIProvider` class can be extended to support OpenAI-compatible APIs like Azure OpenAI, OpenRouter, or custom deployments.\r\n\r\n### Example: Custom Provider\r\n\r\n```typescript\r\nimport { OpenAIProvider, OpenAIConfig } from '@aeye/openai';\r\nimport OpenAI from 'openai';\r\n\r\ninterface CustomConfig extends OpenAIConfig {\r\n  customOption?: string;\r\n}\r\n\r\nclass CustomProvider extends OpenAIProvider<CustomConfig> {\r\n  readonly name = 'custom-provider';\r\n\r\n  protected createClient(config: CustomConfig): OpenAI {\r\n    return new OpenAI({\r\n      apiKey: config.apiKey,\r\n      baseURL: 'https://api.custom-provider.com/v1',\r\n      defaultHeaders: {\r\n        'X-Custom-Header': config.customOption || '',\r\n      },\r\n    });\r\n  }\r\n\r\n  protected customizeChatParams(params: any, config: CustomConfig, request: any) {\r\n    // Add custom parameters\r\n    return {\r\n      ...params,\r\n      custom_param: config.customOption,\r\n    };\r\n  }\r\n}\r\n\r\n// Use the custom provider\r\nconst customProvider = new CustomProvider({\r\n  apiKey: process.env.CUSTOM_API_KEY!,\r\n  customOption: 'value',\r\n});\r\n```\r\n\r\n### Example: Azure OpenAI\r\n\r\n```typescript\r\nclass AzureOpenAIProvider extends OpenAIProvider {\r\n  readonly name = 'azure-openai';\r\n\r\n  protected createClient(config: OpenAIConfig): OpenAI {\r\n    return new OpenAI({\r\n      apiKey: config.apiKey,\r\n      baseURL: config.baseURL, // Azure endpoint\r\n      defaultQuery: { 'api-version': '2024-02-01' },\r\n    });\r\n  }\r\n}\r\n\r\nconst azureProvider = new AzureOpenAIProvider({\r\n  apiKey: process.env.AZURE_OPENAI_KEY!,\r\n  baseURL: 'https://your-resource.openai.azure.com/openai/deployments/your-deployment',\r\n});\r\n```\r\n\r\n## Configuration Options\r\n\r\n### OpenAIConfig\r\n\r\n| Property | Type | Required | Description |\r\n|----------|------|----------|-------------|\r\n| `apiKey` | `string` | Yes | OpenAI API key |\r\n| `baseURL` | `string` | No | Custom base URL for API endpoint |\r\n| `organization` | `string` | No | OpenAI organization ID |\r\n\r\n### Request Parameters\r\n\r\n#### Chat Completion Request\r\n\r\n| Parameter | Type | Description |\r\n|-----------|------|-------------|\r\n| `messages` | `Message[]` | Array of conversation messages |\r\n| `temperature` | `number` | Sampling temperature (0-2) |\r\n| `topP` | `number` | Nucleus sampling parameter |\r\n| `maxTokens` | `number` | Maximum tokens to generate |\r\n| `stop` | `string \\| string[]` | Stop sequences |\r\n| `tools` | `Tool[]` | Function definitions for tool calling |\r\n| `toolChoice` | `'auto' \\| 'required' \\| 'none' \\| { tool: string }` | Tool selection mode |\r\n| `responseFormat` | `'text' \\| 'json' \\| ZodSchema` | Response format constraint |\r\n\r\n#### Image Generation Request\r\n\r\n| Parameter | Type | Description |\r\n|-----------|------|-------------|\r\n| `prompt` | `string` | Text description of desired image |\r\n| `model` | `string` | Model to use (dall-e-2, dall-e-3) |\r\n| `size` | `string` | Image size (512x512, 1024x1024, etc.) |\r\n| `quality` | `'standard' \\| 'hd'` | Image quality (DALL-E 3 only) |\r\n| `style` | `'vivid' \\| 'natural'` | Image style (DALL-E 3 only) |\r\n| `n` | `number` | Number of images to generate |\r\n| `responseFormat` | `'url' \\| 'b64_json'` | Response format |\r\n\r\n#### Transcription Request\r\n\r\n| Parameter | Type | Description |\r\n|-----------|------|-------------|\r\n| `audio` | `Buffer \\| string \\| Blob` | Audio file to transcribe |\r\n| `model` | `string` | Model to use (whisper-1) |\r\n| `language` | `string` | ISO-639-1 language code |\r\n| `prompt` | `string` | Context for better accuracy |\r\n| `responseFormat` | `'json' \\| 'text' \\| 'srt' \\| 'vtt' \\| 'verbose_json'` | Output format |\r\n| `timestampGranularities` | `('word' \\| 'segment')[]` | Timestamp detail level |\r\n| `temperature` | `number` | Sampling temperature |\r\n\r\n#### Speech Synthesis Request\r\n\r\n| Parameter | Type | Description |\r\n|-----------|------|-------------|\r\n| `text` | `string` | Text to convert to speech |\r\n| `model` | `string` | Model to use (tts-1, tts-1-hd) |\r\n| `voice` | `string` | Voice ID (alloy, echo, fable, onyx, nova, shimmer) |\r\n| `speed` | `number` | Playback speed (0.25-4.0) |\r\n| `responseFormat` | `'mp3' \\| 'opus' \\| 'aac' \\| 'flac' \\| 'wav' \\| 'pcm'` | Audio format |\r\n\r\n#### Embedding Request\r\n\r\n| Parameter | Type | Description |\r\n|-----------|------|-------------|\r\n| `texts` | `string[]` | Texts to embed |\r\n| `model` | `string` | Model to use (text-embedding-3-small, text-embedding-3-large, text-embedding-ada-002) |\r\n| `dimensions` | `number` | Output dimensions (embedding-3 models only) |\r\n| `encodingFormat` | `'float' \\| 'base64'` | Encoding format |\r\n\r\n## Error Handling\r\n\r\nThe provider throws specific error types for different failure scenarios:\r\n\r\n```typescript\r\nimport { ProviderError, RateLimitError, ProviderAuthError } from '@aeye/openai';\r\n\r\ntry {\r\n  const response = await executor(\r\n    { messages: [{ role: 'user', content: 'Hello' }] },\r\n    {},\r\n    { model: 'gpt-4' }\r\n  );\r\n} catch (error) {\r\n  if (error instanceof RateLimitError) {\r\n    console.error('Rate limit exceeded');\r\n    if (error.retryAfter) {\r\n      console.log(`Retry after ${error.retryAfter} seconds`);\r\n    }\r\n  } else if (error instanceof ProviderAuthError) {\r\n    console.error('Authentication failed - check your API key');\r\n  } else if (error instanceof ProviderError) {\r\n    console.error(`Provider error: ${error.message}`);\r\n    console.error('Original error:', error.cause);\r\n  }\r\n}\r\n```\r\n\r\n### Error Types\r\n\r\n- **`ProviderError`**: Base error for all provider-related errors\r\n- **`ProviderAuthError`**: Authentication/authorization failures\r\n- **`RateLimitError`**: Rate limit exceeded (includes `retryAfter` if available)\r\n- **`ProviderRateLimitError`**: Specialized rate limit error\r\n- **`ProviderQuotaError`**: Quota/usage limit exceeded\r\n\r\n## API Reference\r\n\r\n### OpenAIProvider\r\n\r\nMain provider class implementing the @aeye Provider interface.\r\n\r\n**Constructor**: `new OpenAIProvider(config: OpenAIConfig)`\r\n\r\n**Methods**:\r\n- `listModels(config?: TConfig): Promise<ModelInfo[]>` - List available models\r\n- `checkHealth(config?: TConfig): Promise<boolean>` - Check API health\r\n- `createExecutor<TContext, TMetadata>(config?: TConfig): Executor` - Create chat executor\r\n- `createStreamer<TContext, TMetadata>(config?: TConfig): Streamer` - Create streaming executor\r\n- `generateImage<TContext>(request, ctx, config?): Promise<ImageGenerationResponse>` - Generate images\r\n- `transcribe<TContext>(request, ctx, config?): Promise<TranscriptionResponse>` - Transcribe audio\r\n- `generateSpeech<TContext>(request, ctx, config?): Promise<SpeechResponse>` - Generate speech\r\n- `embed<TContext>(request, ctx, config?): Promise<EmbeddingResponse>` - Generate embeddings\r\n\r\n**Protected Methods** (for extending):\r\n- `createClient(config): OpenAI` - Create OpenAI client\r\n- `convertModel(model): ModelInfo` - Convert model format\r\n- `convertMessages(request): OpenAI.ChatCompletionMessageParam[]` - Convert messages\r\n- `convertTools(request): OpenAI.ChatCompletionTool[]` - Convert tools\r\n- `convertToolChoice(request): OpenAI.ChatCompletionToolChoiceOption` - Convert tool choice\r\n- `convertResponseFormat(request): ResponseFormat` - Convert response format\r\n- `customizeChatParams(params, config, request)` - Customize chat params\r\n- `customizeImageParams(params, config)` - Customize image params\r\n- `customizeTranscriptionParams(params, config)` - Customize transcription params\r\n- `customizeSpeechParams(params, config)` - Customize speech params\r\n- `customizeEmbeddingParams(params, config)` - Customize embedding params\r\n\r\n## Model Support\r\n\r\n### Chat Models\r\n\r\n- **GPT-4 Turbo**: `gpt-4-turbo`, `gpt-4-turbo-preview`\r\n- **GPT-4**: `gpt-4`, `gpt-4-0613`, `gpt-4-32k`\r\n- **GPT-4 Vision**: `gpt-4-vision-preview`, `gpt-4-turbo-2024-04-09`\r\n- **GPT-3.5 Turbo**: `gpt-3.5-turbo`, `gpt-3.5-turbo-16k`\r\n- **Reasoning**: `o1-preview`, `o1-mini`, `o3-mini`\r\n\r\n### Image Models\r\n\r\n- **DALL-E 3**: `dall-e-3`\r\n- **DALL-E 2**: `dall-e-2`\r\n\r\n### Audio Models\r\n\r\n- **Whisper**: `whisper-1`\r\n- **TTS**: `tts-1`, `tts-1-hd`\r\n\r\n### Embedding Models\r\n\r\n- **Embedding v3**: `text-embedding-3-small`, `text-embedding-3-large`\r\n- **Embedding v2**: `text-embedding-ada-002`\r\n\r\n## Best Practices\r\n\r\n1. **API Key Security**: Never hardcode API keys. Use environment variables or secure key management.\r\n\r\n2. **Error Handling**: Always wrap API calls in try-catch blocks and handle rate limits gracefully.\r\n\r\n3. **Streaming for Long Responses**: Use streaming for better user experience with lengthy responses.\r\n\r\n4. **Token Management**: Monitor token usage to control costs. Use `maxTokens` to limit response length.\r\n\r\n5. **Model Selection**: Choose the appropriate model for your use case:\r\n   - GPT-4 for complex tasks requiring high accuracy\r\n   - GPT-3.5 Turbo for simpler tasks and faster responses\r\n   - o1/o3-mini for reasoning-heavy problems\r\n\r\n6. **Function Calling**: Use structured schemas with Zod for type-safe function definitions.\r\n\r\n7. **Retry Logic**: Implement exponential backoff for rate limit errors.\r\n\r\n8. **Context Window**: Be aware of model context limits and truncate messages if needed.\r\n\r\n## Related Packages\r\n\r\n- **[@aeye/core](../core)**: Core @aeye framework types and interfaces\r\n- **[@aeye/ai](../ai)**: AI abstractions and utilities\r\n- **[@aeye/anthropic](../anthropic)**: Anthropic Claude provider\r\n- **[@aeye/openrouter](../openrouter)**: OpenRouter multi-provider gateway\r\n\r\n## License\r\n\r\nGPL-3.0\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please see the main [@aeye repository](https://github.com/ClickerMonkey/aeye) for contribution guidelines.\r\n\r\n## Support\r\n\r\nFor issues and questions:\r\n- GitHub Issues: https://github.com/ClickerMonkey/aeye/issues\r\n- Documentation: https://github.com/ClickerMonkey/aeye\r\n\r\n## Changelog\r\n\r\nSee [CHANGELOG.md](CHANGELOG.md) for version history and updates.\r\n","readmeFilename":"README.md"}