@soederpop/luca 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/CLAUDE.md +71 -0
  2. package/README.md +78 -0
  3. package/bun.lock +2928 -0
  4. package/bunfig.toml +3 -0
  5. package/commands/audit-docs.ts +740 -0
  6. package/commands/build-scaffolds.ts +154 -0
  7. package/commands/generate-api-docs.ts +114 -0
  8. package/commands/update-introspection.ts +67 -0
  9. package/docs/CLI.md +335 -0
  10. package/docs/README.md +88 -0
  11. package/docs/TABLE-OF-CONTENTS.md +157 -0
  12. package/docs/apis/clients/elevenlabs.md +84 -0
  13. package/docs/apis/clients/graph.md +56 -0
  14. package/docs/apis/clients/openai.md +69 -0
  15. package/docs/apis/clients/rest.md +41 -0
  16. package/docs/apis/clients/websocket.md +107 -0
  17. package/docs/apis/features/agi/assistant.md +471 -0
  18. package/docs/apis/features/agi/assistants-manager.md +154 -0
  19. package/docs/apis/features/agi/claude-code.md +602 -0
  20. package/docs/apis/features/agi/conversation-history.md +352 -0
  21. package/docs/apis/features/agi/conversation.md +333 -0
  22. package/docs/apis/features/agi/docs-reader.md +121 -0
  23. package/docs/apis/features/agi/openai-codex.md +318 -0
  24. package/docs/apis/features/agi/openapi.md +138 -0
  25. package/docs/apis/features/agi/semantic-search.md +387 -0
  26. package/docs/apis/features/agi/skills-library.md +216 -0
  27. package/docs/apis/features/node/container-link.md +133 -0
  28. package/docs/apis/features/node/content-db.md +313 -0
  29. package/docs/apis/features/node/disk-cache.md +379 -0
  30. package/docs/apis/features/node/dns.md +651 -0
  31. package/docs/apis/features/node/docker.md +705 -0
  32. package/docs/apis/features/node/downloader.md +81 -0
  33. package/docs/apis/features/node/esbuild.md +59 -0
  34. package/docs/apis/features/node/file-manager.md +182 -0
  35. package/docs/apis/features/node/fs.md +581 -0
  36. package/docs/apis/features/node/git.md +330 -0
  37. package/docs/apis/features/node/google-auth.md +174 -0
  38. package/docs/apis/features/node/google-calendar.md +187 -0
  39. package/docs/apis/features/node/google-docs.md +151 -0
  40. package/docs/apis/features/node/google-drive.md +225 -0
  41. package/docs/apis/features/node/google-sheets.md +179 -0
  42. package/docs/apis/features/node/grep.md +290 -0
  43. package/docs/apis/features/node/helpers.md +135 -0
  44. package/docs/apis/features/node/ink.md +334 -0
  45. package/docs/apis/features/node/ipc-socket.md +260 -0
  46. package/docs/apis/features/node/json-tree.md +86 -0
  47. package/docs/apis/features/node/launcher-app-command-listener.md +145 -0
  48. package/docs/apis/features/node/networking.md +281 -0
  49. package/docs/apis/features/node/nlp.md +133 -0
  50. package/docs/apis/features/node/opener.md +97 -0
  51. package/docs/apis/features/node/os.md +118 -0
  52. package/docs/apis/features/node/package-finder.md +402 -0
  53. package/docs/apis/features/node/postgres.md +212 -0
  54. package/docs/apis/features/node/proc.md +430 -0
  55. package/docs/apis/features/node/process-manager.md +210 -0
  56. package/docs/apis/features/node/python.md +278 -0
  57. package/docs/apis/features/node/repl.md +88 -0
  58. package/docs/apis/features/node/runpod.md +673 -0
  59. package/docs/apis/features/node/secure-shell.md +169 -0
  60. package/docs/apis/features/node/semantic-search.md +401 -0
  61. package/docs/apis/features/node/sqlite.md +211 -0
  62. package/docs/apis/features/node/telegram.md +254 -0
  63. package/docs/apis/features/node/tts.md +118 -0
  64. package/docs/apis/features/node/ui.md +703 -0
  65. package/docs/apis/features/node/vault.md +64 -0
  66. package/docs/apis/features/node/vm.md +84 -0
  67. package/docs/apis/features/node/window-manager.md +337 -0
  68. package/docs/apis/features/node/yaml-tree.md +85 -0
  69. package/docs/apis/features/node/yaml.md +176 -0
  70. package/docs/apis/features/web/asset-loader.md +47 -0
  71. package/docs/apis/features/web/container-link.md +133 -0
  72. package/docs/apis/features/web/esbuild.md +59 -0
  73. package/docs/apis/features/web/helpers.md +135 -0
  74. package/docs/apis/features/web/network.md +30 -0
  75. package/docs/apis/features/web/speech.md +55 -0
  76. package/docs/apis/features/web/vault.md +64 -0
  77. package/docs/apis/features/web/vm.md +84 -0
  78. package/docs/apis/features/web/voice.md +67 -0
  79. package/docs/apis/servers/express.md +127 -0
  80. package/docs/apis/servers/mcp.md +213 -0
  81. package/docs/apis/servers/websocket.md +99 -0
  82. package/docs/documentation-audit.md +134 -0
  83. package/docs/examples/content-db.md +77 -0
  84. package/docs/examples/disk-cache.md +83 -0
  85. package/docs/examples/docker.md +101 -0
  86. package/docs/examples/downloader.md +70 -0
  87. package/docs/examples/esbuild.md +80 -0
  88. package/docs/examples/file-manager.md +82 -0
  89. package/docs/examples/fs.md +83 -0
  90. package/docs/examples/git.md +85 -0
  91. package/docs/examples/google-auth.md +88 -0
  92. package/docs/examples/google-calendar.md +94 -0
  93. package/docs/examples/google-docs.md +82 -0
  94. package/docs/examples/google-drive.md +96 -0
  95. package/docs/examples/google-sheets.md +95 -0
  96. package/docs/examples/grep.md +85 -0
  97. package/docs/examples/ink-blocks.md +75 -0
  98. package/docs/examples/ink-renderer.md +41 -0
  99. package/docs/examples/ink.md +103 -0
  100. package/docs/examples/ipc-socket.md +103 -0
  101. package/docs/examples/json-tree.md +91 -0
  102. package/docs/examples/launcher-app-command-listener.md +120 -0
  103. package/docs/examples/networking.md +58 -0
  104. package/docs/examples/nlp.md +91 -0
  105. package/docs/examples/opener.md +78 -0
  106. package/docs/examples/os.md +72 -0
  107. package/docs/examples/package-finder.md +89 -0
  108. package/docs/examples/port-exposer.md +89 -0
  109. package/docs/examples/postgres.md +91 -0
  110. package/docs/examples/proc.md +81 -0
  111. package/docs/examples/process-manager.md +79 -0
  112. package/docs/examples/python.md +91 -0
  113. package/docs/examples/repl.md +93 -0
  114. package/docs/examples/runpod.md +119 -0
  115. package/docs/examples/secure-shell.md +92 -0
  116. package/docs/examples/sqlite.md +86 -0
  117. package/docs/examples/telegram.md +77 -0
  118. package/docs/examples/tts.md +86 -0
  119. package/docs/examples/ui.md +80 -0
  120. package/docs/examples/vault.md +70 -0
  121. package/docs/examples/vm.md +86 -0
  122. package/docs/examples/window-manager.md +125 -0
  123. package/docs/examples/yaml-tree.md +93 -0
  124. package/docs/examples/yaml.md +104 -0
  125. package/docs/ideas/class-registration-refactor-possibilities.md +197 -0
  126. package/docs/ideas/container-use-api.md +9 -0
  127. package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
  128. package/docs/ideas/feature-stacks.md +22 -0
  129. package/docs/ideas/luca-cli-self-sufficiency-demo.md +23 -0
  130. package/docs/ideas/mcp-design.md +9 -0
  131. package/docs/ideas/web-container-debugging-feature.md +13 -0
  132. package/docs/introspection-audit.md +49 -0
  133. package/docs/introspection.md +154 -0
  134. package/docs/mcp/readme.md +162 -0
  135. package/docs/models.ts +38 -0
  136. package/docs/philosophy.md +85 -0
  137. package/docs/principles.md +7 -0
  138. package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
  139. package/docs/prompts/mcp-test-easy-command.md +27 -0
  140. package/docs/reports/assistant-bugs.md +38 -0
  141. package/docs/reports/attach-pattern-usage.md +18 -0
  142. package/docs/reports/code-audit-results.md +391 -0
  143. package/docs/reports/introspection-audit-tasks.md +378 -0
  144. package/docs/reports/luca-mcp-improvements.md +128 -0
  145. package/docs/scaffolds/client.md +140 -0
  146. package/docs/scaffolds/command.md +106 -0
  147. package/docs/scaffolds/endpoint.md +176 -0
  148. package/docs/scaffolds/feature.md +148 -0
  149. package/docs/scaffolds/server.md +187 -0
  150. package/docs/tasks/web-container-helper-discovery.md +71 -0
  151. package/docs/todos.md +1 -0
  152. package/docs/tutorials/01-getting-started.md +106 -0
  153. package/docs/tutorials/02-container.md +210 -0
  154. package/docs/tutorials/03-scripts.md +194 -0
  155. package/docs/tutorials/04-features-overview.md +196 -0
  156. package/docs/tutorials/05-state-and-events.md +171 -0
  157. package/docs/tutorials/06-servers.md +157 -0
  158. package/docs/tutorials/07-endpoints.md +198 -0
  159. package/docs/tutorials/08-commands.md +171 -0
  160. package/docs/tutorials/09-clients.md +162 -0
  161. package/docs/tutorials/10-creating-features.md +198 -0
  162. package/docs/tutorials/11-contentbase.md +191 -0
  163. package/docs/tutorials/12-assistants.md +215 -0
  164. package/docs/tutorials/13-introspection.md +147 -0
  165. package/docs/tutorials/14-type-system.md +174 -0
  166. package/docs/tutorials/15-project-patterns.md +222 -0
  167. package/docs/tutorials/16-google-features.md +534 -0
  168. package/docs/tutorials/17-tui-blocks.md +530 -0
  169. package/docs/tutorials/18-semantic-search.md +334 -0
  170. package/index.ts +1 -0
  171. package/luca.console.ts +9 -0
  172. package/main.py +6 -0
  173. package/package.json +154 -0
  174. package/pyproject.toml +7 -0
  175. package/scripts/animations/chrome-glitch.ts +55 -0
  176. package/scripts/animations/index.ts +16 -0
  177. package/scripts/animations/neon-pulse.ts +64 -0
  178. package/scripts/animations/types.ts +6 -0
  179. package/scripts/build-web.ts +28 -0
  180. package/scripts/examples/ask-luca-expert.ts +42 -0
  181. package/scripts/examples/assistant-questions.ts +12 -0
  182. package/scripts/examples/excalidraw-expert.ts +75 -0
  183. package/scripts/examples/expert-chat.ts +0 -0
  184. package/scripts/examples/file-manager.ts +14 -0
  185. package/scripts/examples/ideas.ts +12 -0
  186. package/scripts/examples/interactive-chat.ts +20 -0
  187. package/scripts/examples/openai-tool-calls.ts +113 -0
  188. package/scripts/examples/opening-a-web-browser.ts +5 -0
  189. package/scripts/examples/telegram-bot.ts +79 -0
  190. package/scripts/examples/telegram-ink-ui.ts +302 -0
  191. package/scripts/examples/using-assistant-with-mcp.ts +560 -0
  192. package/scripts/examples/using-claude-code.ts +10 -0
  193. package/scripts/examples/using-contentdb.ts +35 -0
  194. package/scripts/examples/using-conversations.ts +35 -0
  195. package/scripts/examples/using-disk-cache.ts +10 -0
  196. package/scripts/examples/using-docker-shell.ts +75 -0
  197. package/scripts/examples/using-elevenlabs.ts +25 -0
  198. package/scripts/examples/using-google-calendar.ts +57 -0
  199. package/scripts/examples/using-google-docs.ts +74 -0
  200. package/scripts/examples/using-google-drive.ts +74 -0
  201. package/scripts/examples/using-google-sheets.ts +89 -0
  202. package/scripts/examples/using-nlp.ts +55 -0
  203. package/scripts/examples/using-ollama.ts +10 -0
  204. package/scripts/examples/using-openai-codex.ts +23 -0
  205. package/scripts/examples/using-postgres.ts +55 -0
  206. package/scripts/examples/using-runpod.ts +32 -0
  207. package/scripts/examples/using-tts.ts +40 -0
  208. package/scripts/examples/vm-loading-esm-modules.ts +16 -0
  209. package/scripts/scaffold.ts +391 -0
  210. package/scripts/scratch.ts +15 -0
  211. package/scripts/test-command-listener.ts +123 -0
  212. package/scripts/test-window-manager-lifecycle.ts +86 -0
  213. package/scripts/test-window-manager.ts +43 -0
  214. package/scripts/update-introspection-data.ts +58 -0
  215. package/src/agi/README.md +14 -0
  216. package/src/agi/container.server.ts +114 -0
  217. package/src/agi/endpoints/ask.ts +60 -0
  218. package/src/agi/endpoints/conversations/[id].ts +45 -0
  219. package/src/agi/endpoints/conversations.ts +31 -0
  220. package/src/agi/endpoints/experts.ts +37 -0
  221. package/src/agi/features/assistant.ts +767 -0
  222. package/src/agi/features/assistants-manager.ts +260 -0
  223. package/src/agi/features/claude-code.ts +1111 -0
  224. package/src/agi/features/conversation-history.ts +497 -0
  225. package/src/agi/features/conversation.ts +799 -0
  226. package/src/agi/features/openai-codex.ts +631 -0
  227. package/src/agi/features/openapi.ts +438 -0
  228. package/src/agi/features/skills-library.ts +425 -0
  229. package/src/agi/index.ts +6 -0
  230. package/src/agi/lib/token-counter.ts +122 -0
  231. package/src/browser.ts +25 -0
  232. package/src/bus.ts +100 -0
  233. package/src/cli/cli.ts +70 -0
  234. package/src/client.ts +461 -0
  235. package/src/clients/civitai/index.ts +541 -0
  236. package/src/clients/client-template.ts +41 -0
  237. package/src/clients/comfyui/index.ts +597 -0
  238. package/src/clients/elevenlabs/index.ts +291 -0
  239. package/src/clients/openai/index.ts +451 -0
  240. package/src/clients/supabase/index.ts +366 -0
  241. package/src/command.ts +164 -0
  242. package/src/commands/chat.ts +182 -0
  243. package/src/commands/console.ts +192 -0
  244. package/src/commands/describe.ts +433 -0
  245. package/src/commands/eval.ts +116 -0
  246. package/src/commands/help.ts +214 -0
  247. package/src/commands/index.ts +14 -0
  248. package/src/commands/mcp.ts +64 -0
  249. package/src/commands/prompt.ts +807 -0
  250. package/src/commands/run.ts +257 -0
  251. package/src/commands/sandbox-mcp.ts +439 -0
  252. package/src/commands/scaffold.ts +79 -0
  253. package/src/commands/serve.ts +172 -0
  254. package/src/container.ts +781 -0
  255. package/src/endpoint.ts +340 -0
  256. package/src/feature.ts +75 -0
  257. package/src/hash-object.ts +97 -0
  258. package/src/helper.ts +543 -0
  259. package/src/introspection/generated.agi.ts +23388 -0
  260. package/src/introspection/generated.node.ts +18899 -0
  261. package/src/introspection/generated.web.ts +2021 -0
  262. package/src/introspection/index.ts +256 -0
  263. package/src/introspection/scan.ts +912 -0
  264. package/src/node/container.ts +354 -0
  265. package/src/node/feature.ts +13 -0
  266. package/src/node/features/container-link.ts +558 -0
  267. package/src/node/features/content-db.ts +475 -0
  268. package/src/node/features/disk-cache.ts +382 -0
  269. package/src/node/features/dns.ts +655 -0
  270. package/src/node/features/docker.ts +912 -0
  271. package/src/node/features/downloader.ts +92 -0
  272. package/src/node/features/esbuild.ts +68 -0
  273. package/src/node/features/file-manager.ts +357 -0
  274. package/src/node/features/fs.ts +534 -0
  275. package/src/node/features/git.ts +492 -0
  276. package/src/node/features/google-auth.ts +502 -0
  277. package/src/node/features/google-calendar.ts +300 -0
  278. package/src/node/features/google-docs.ts +404 -0
  279. package/src/node/features/google-drive.ts +339 -0
  280. package/src/node/features/google-sheets.ts +279 -0
  281. package/src/node/features/grep.ts +406 -0
  282. package/src/node/features/helpers.ts +374 -0
  283. package/src/node/features/ink.ts +490 -0
  284. package/src/node/features/ipc-socket.ts +459 -0
  285. package/src/node/features/json-tree.ts +188 -0
  286. package/src/node/features/launcher-app-command-listener.ts +388 -0
  287. package/src/node/features/networking.ts +925 -0
  288. package/src/node/features/nlp.ts +211 -0
  289. package/src/node/features/opener.ts +166 -0
  290. package/src/node/features/os.ts +157 -0
  291. package/src/node/features/package-finder.ts +539 -0
  292. package/src/node/features/port-exposer.ts +342 -0
  293. package/src/node/features/postgres.ts +273 -0
  294. package/src/node/features/proc.ts +502 -0
  295. package/src/node/features/process-manager.ts +542 -0
  296. package/src/node/features/python.ts +444 -0
  297. package/src/node/features/repl.ts +194 -0
  298. package/src/node/features/runpod.ts +802 -0
  299. package/src/node/features/secure-shell.ts +248 -0
  300. package/src/node/features/semantic-search.ts +924 -0
  301. package/src/node/features/sqlite.ts +289 -0
  302. package/src/node/features/telegram.ts +342 -0
  303. package/src/node/features/tts.ts +184 -0
  304. package/src/node/features/ui.ts +857 -0
  305. package/src/node/features/vault.ts +164 -0
  306. package/src/node/features/vm.ts +312 -0
  307. package/src/node/features/window-manager.ts +804 -0
  308. package/src/node/features/yaml-tree.ts +149 -0
  309. package/src/node/features/yaml.ts +132 -0
  310. package/src/node.ts +70 -0
  311. package/src/react/index.ts +175 -0
  312. package/src/registry.ts +199 -0
  313. package/src/scaffolds/generated.ts +1613 -0
  314. package/src/scaffolds/template.ts +37 -0
  315. package/src/schemas/base.ts +255 -0
  316. package/src/server.ts +135 -0
  317. package/src/servers/express.ts +209 -0
  318. package/src/servers/mcp.ts +805 -0
  319. package/src/servers/socket.ts +120 -0
  320. package/src/state.ts +101 -0
  321. package/src/web/clients/socket.ts +82 -0
  322. package/src/web/container.ts +74 -0
  323. package/src/web/extension.ts +30 -0
  324. package/src/web/feature.ts +12 -0
  325. package/src/web/features/asset-loader.ts +64 -0
  326. package/src/web/features/container-link.ts +385 -0
  327. package/src/web/features/esbuild.ts +79 -0
  328. package/src/web/features/helpers.ts +267 -0
  329. package/src/web/features/network.ts +61 -0
  330. package/src/web/features/speech.ts +87 -0
  331. package/src/web/features/vault.ts +189 -0
  332. package/src/web/features/vm.ts +78 -0
  333. package/src/web/features/voice-recognition.ts +129 -0
  334. package/src/web/shims/isomorphic-vm.ts +149 -0
  335. package/test/bus.test.ts +134 -0
  336. package/test/clients-servers.test.ts +216 -0
  337. package/test/container-link.test.ts +274 -0
  338. package/test/features.test.ts +160 -0
  339. package/test/integration.test.ts +787 -0
  340. package/test/node-container.test.ts +121 -0
  341. package/test/rate-limit.test.ts +272 -0
  342. package/test/semantic-search.test.ts +550 -0
  343. package/test/state.test.ts +121 -0
  344. package/test-integration/assistant.test.ts +138 -0
  345. package/test-integration/assistants-manager.test.ts +123 -0
  346. package/test-integration/claude-code.test.ts +98 -0
  347. package/test-integration/conversation-history.test.ts +205 -0
  348. package/test-integration/conversation.test.ts +137 -0
  349. package/test-integration/elevenlabs.test.ts +55 -0
  350. package/test-integration/google-services.test.ts +80 -0
  351. package/test-integration/helpers.ts +89 -0
  352. package/test-integration/openai-codex.test.ts +93 -0
  353. package/test-integration/runpod.test.ts +58 -0
  354. package/test-integration/server-endpoints.test.ts +97 -0
  355. package/test-integration/skills-library.test.ts +157 -0
  356. package/test-integration/telegram.test.ts +46 -0
  357. package/tsconfig.json +58 -0
  358. package/uv.lock +8 -0
@@ -0,0 +1,451 @@
1
+ import { z } from 'zod'
2
+ import { ClientStateSchema, ClientOptionsSchema } from '@soederpop/luca/schemas/base.js'
3
+ import { clients, Client } from "@soederpop/luca/client";
4
+ import type { Container, ContainerContext } from "@soederpop/luca/container";
5
+ import type { ClientsInterface } from "@soederpop/luca/client";
6
+ import OpenAI from "openai";
7
+
8
+ export const OpenAIClientStateSchema = ClientStateSchema.extend({
9
+ requestCount: z.number().default(0).describe('Total number of API requests made'),
10
+ lastRequestTime: z.number().nullable().default(null).describe('Timestamp of the last API request'),
11
+ tokenUsage: z.object({
12
+ prompt: z.number().default(0).describe('Total prompt tokens consumed'),
13
+ completion: z.number().default(0).describe('Total completion tokens consumed'),
14
+ total: z.number().default(0).describe('Total tokens consumed (prompt + completion)'),
15
+ }).default({ prompt: 0, completion: 0, total: 0 }).describe('Cumulative token usage across all requests'),
16
+ })
17
+ export type OpenAIClientState = z.infer<typeof OpenAIClientStateSchema>
18
+
19
+ export const OpenAIClientOptionsSchema = ClientOptionsSchema.extend({
20
+ apiKey: z.string().optional().describe('OpenAI API key (falls back to OPENAI_API_KEY env var)'),
21
+ organization: z.string().optional().describe('OpenAI organization ID'),
22
+ project: z.string().optional().describe('OpenAI project ID'),
23
+ dangerouslyAllowBrowser: z.boolean().optional().describe('Allow usage in browser environments'),
24
+ defaultModel: z.string().optional().describe('Default model for completions (default: gpt-4o)'),
25
+ timeout: z.number().optional().describe('Request timeout in milliseconds'),
26
+ maxRetries: z.number().optional().describe('Maximum number of retries on failure'),
27
+ })
28
+ export type OpenAIClientOptions = z.infer<typeof OpenAIClientOptionsSchema>
29
+
30
+ /**
31
+ * OpenAI client — wraps the OpenAI SDK for chat completions, responses API, embeddings, and image generation.
32
+ *
33
+ * Provides convenience methods for common operations while tracking token usage and request counts.
34
+ * Supports both the Chat Completions API and the newer Responses API.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const openai = container.client('openai', { defaultModel: 'gpt-4o' })
39
+ * const answer = await openai.ask('What is the meaning of life?')
40
+ * console.log(answer)
41
+ * ```
42
+ */
43
+ export class OpenAIClient extends Client<OpenAIClientState, OpenAIClientOptions> {
44
+ private openai!: OpenAI;
45
+
46
+ static override shortcut = "clients.openai" as const
47
+ static override envVars = ['OPENAI_API_KEY']
48
+ static override stateSchema = OpenAIClientStateSchema
49
+ static override optionsSchema = OpenAIClientOptionsSchema
50
+
51
+ static override attach(container: Container & ClientsInterface): any {
52
+ return container;
53
+ }
54
+
55
+ /** Initial state with zeroed token usage counters. */
56
+ override get initialState(): OpenAIClientState {
57
+ return {
58
+ ...super.initialState,
59
+ requestCount: 0,
60
+ lastRequestTime: null,
61
+ tokenUsage: {
62
+ prompt: 0,
63
+ completion: 0,
64
+ total: 0
65
+ }
66
+ };
67
+ }
68
+
69
+ constructor(options: OpenAIClientOptions, context: ContainerContext) {
70
+ super(options, context);
71
+ this.initializeOpenAI();
72
+ }
73
+
74
+ private initializeOpenAI() {
75
+ this.openai = new OpenAI({
76
+ apiKey: this.options.apiKey || process.env.OPENAI_API_KEY,
77
+ organization: this.options.organization,
78
+ project: this.options.project,
79
+ dangerouslyAllowBrowser: this.options.dangerouslyAllowBrowser,
80
+ timeout: this.options.timeout,
81
+ maxRetries: this.options.maxRetries,
82
+ baseURL: this.options.baseURL,
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Test the API connection by listing models.
88
+ *
89
+ * @returns This client instance
90
+ * @throws If the API key is invalid or the connection fails
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * await openai.connect()
95
+ * ```
96
+ */
97
+ override async connect(): Promise<this> {
98
+ try {
99
+ // Test the connection by making a simple request
100
+ await this.openai.models.list();
101
+ await super.connect();
102
+ this.emit('connected');
103
+ return this;
104
+ } catch (error) {
105
+ this.emit('failure', error);
106
+ throw error;
107
+ }
108
+ }
109
+
110
+ /** The default model used for completions, from options or 'gpt-4o'. */
111
+ get defaultModel(): string {
112
+ return this.options.defaultModel || 'gpt-4o';
113
+ }
114
+
115
+ private updateTokenUsage(usage?: OpenAI.CompletionUsage | OpenAI.Embeddings.CreateEmbeddingResponse.Usage) {
116
+ if (usage) {
117
+ const currentUsage = this.state.get('tokenUsage') || { prompt: 0, completion: 0, total: 0 };
118
+ this.setState({
119
+ tokenUsage: {
120
+ prompt: currentUsage.prompt + (usage.prompt_tokens || 0),
121
+ completion: currentUsage.completion + ('completion_tokens' in usage ? usage.completion_tokens || 0 : 0),
122
+ total: currentUsage.total + (usage.total_tokens || 0)
123
+ }
124
+ });
125
+ }
126
+ }
127
+
128
+ private updateResponsesTokenUsage(usage?: OpenAI.Responses.ResponseUsage) {
129
+ if (usage) {
130
+ const currentUsage = this.state.get('tokenUsage') || { prompt: 0, completion: 0, total: 0 };
131
+ this.setState({
132
+ tokenUsage: {
133
+ prompt: currentUsage.prompt + (usage.input_tokens || 0),
134
+ completion: currentUsage.completion + (usage.output_tokens || 0),
135
+ total: currentUsage.total + (usage.total_tokens || 0),
136
+ }
137
+ });
138
+ }
139
+ }
140
+
141
+ private trackRequest() {
142
+ const requestCount = this.state.get('requestCount') || 0;
143
+ this.setState({
144
+ requestCount: requestCount + 1,
145
+ lastRequestTime: Date.now()
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Create a chat completion using the Chat Completions API.
151
+ *
152
+ * @param messages - Array of chat messages
153
+ * @param options - Additional parameters for the completion
154
+ * @returns The complete chat completion response
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const response = await openai.createChatCompletion([
159
+ * { role: 'system', content: 'You are a helpful assistant.' },
160
+ * { role: 'user', content: 'Hello!' }
161
+ * ])
162
+ * console.log(response.choices[0]?.message?.content)
163
+ * ```
164
+ */
165
+ async createChatCompletion(
166
+ messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[],
167
+ options: Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams> = {}
168
+ ): Promise<OpenAI.Chat.Completions.ChatCompletion> {
169
+ this.trackRequest();
170
+
171
+ try {
172
+ const response = await this.openai.chat.completions.create({
173
+ model: this.defaultModel,
174
+ messages,
175
+ stream: false, // Ensure non-streaming response
176
+ ...options
177
+ }) as OpenAI.Chat.Completions.ChatCompletion;
178
+
179
+ this.updateTokenUsage(response.usage);
180
+ this.emit('completion', response);
181
+
182
+ return response;
183
+ } catch (error) {
184
+ this.emit('failure', error);
185
+ throw error;
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Create a response using the Responses API.
191
+ *
192
+ * @param input - The input prompt or message array
193
+ * @param options - Additional parameters for the response
194
+ * @returns The complete response object
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * const response = await openai.createResponse('Explain quantum computing')
199
+ * ```
200
+ */
201
+ async createResponse(
202
+ input: OpenAI.Responses.ResponseInput | string,
203
+ options: Partial<OpenAI.Responses.ResponseCreateParamsNonStreaming> = {}
204
+ ): Promise<OpenAI.Responses.Response> {
205
+ this.trackRequest();
206
+
207
+ try {
208
+ const response = await this.openai.responses.create({
209
+ model: this.defaultModel as OpenAI.Responses.ResponseCreateParams['model'],
210
+ input,
211
+ ...options,
212
+ stream: false,
213
+ }) as OpenAI.Responses.Response;
214
+
215
+ this.updateResponsesTokenUsage(response.usage || undefined);
216
+ this.emit('completion', response);
217
+
218
+ return response;
219
+ } catch (error) {
220
+ this.emit('failure', error);
221
+ throw error;
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Stream a response using the Responses API.
227
+ *
228
+ * @param input - The input prompt or message array
229
+ * @param options - Additional parameters for the streaming response
230
+ * @returns An async iterable of response stream events
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * const stream = await openai.streamResponse('Write a poem')
235
+ * for await (const event of stream) {
236
+ * if (event.type === 'response.output_text.delta') {
237
+ * process.stdout.write(event.delta)
238
+ * }
239
+ * }
240
+ * ```
241
+ */
242
+ async streamResponse(
243
+ input: OpenAI.Responses.ResponseInput | string,
244
+ options: Partial<OpenAI.Responses.ResponseCreateParamsStreaming> = {}
245
+ ): Promise<AsyncIterable<OpenAI.Responses.ResponseStreamEvent>> {
246
+ this.trackRequest();
247
+
248
+ try {
249
+ const stream = await this.openai.responses.create({
250
+ model: this.defaultModel as OpenAI.Responses.ResponseCreateParams['model'],
251
+ input,
252
+ ...options,
253
+ stream: true,
254
+ }) as AsyncIterable<OpenAI.Responses.ResponseStreamEvent>;
255
+
256
+ return stream;
257
+ } catch (error) {
258
+ this.emit('failure', error);
259
+ throw error;
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Create a legacy text completion.
265
+ *
266
+ * @param prompt - The text prompt to complete
267
+ * @param options - Additional parameters for the completion
268
+ * @returns The complete completion response
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * const response = await openai.createCompletion('Once upon a time')
273
+ * ```
274
+ */
275
+ async createCompletion(
276
+ prompt: string,
277
+ options: Partial<OpenAI.Completions.CompletionCreateParams> = {}
278
+ ): Promise<OpenAI.Completions.Completion> {
279
+ this.trackRequest();
280
+
281
+ try {
282
+ const response = await this.openai.completions.create({
283
+ model: options.model || 'gpt-5',
284
+ prompt,
285
+ stream: false, // Ensure non-streaming response
286
+ ...options
287
+ }) as OpenAI.Completions.Completion;
288
+
289
+ this.updateTokenUsage(response.usage);
290
+ this.emit('completion', response);
291
+
292
+ return response;
293
+ } catch (error) {
294
+ this.emit('failure', error);
295
+ throw error;
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Create text embeddings for semantic search or similarity comparisons.
301
+ *
302
+ * @param input - A string or array of strings to embed
303
+ * @param options - Additional parameters (model, etc.)
304
+ * @returns The embedding response with vectors
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const response = await openai.createEmbedding('Hello world')
309
+ * console.log(response.data[0].embedding.length)
310
+ * ```
311
+ */
312
+ async createEmbedding(
313
+ input: string | string[],
314
+ options: Partial<OpenAI.Embeddings.EmbeddingCreateParams> = {}
315
+ ): Promise<OpenAI.Embeddings.CreateEmbeddingResponse> {
316
+ this.trackRequest();
317
+
318
+ try {
319
+ const response = await this.openai.embeddings.create({
320
+ model: options.model || 'text-embedding-ada-002',
321
+ input,
322
+ ...options
323
+ });
324
+
325
+ this.updateTokenUsage(response.usage);
326
+ this.emit('embedding', response);
327
+
328
+ return response;
329
+ } catch (error) {
330
+ this.emit('failure', error);
331
+ throw error;
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Generate an image from a text prompt using DALL-E.
337
+ *
338
+ * @param prompt - Description of the image to generate
339
+ * @param options - Additional parameters (size, n, etc.)
340
+ * @returns The image response with URLs or base64 data
341
+ *
342
+ * @example
343
+ * ```typescript
344
+ * const response = await openai.createImage('A sunset over mountains')
345
+ * console.log(response.data[0].url)
346
+ * ```
347
+ */
348
+ async createImage(
349
+ prompt: string,
350
+ options: Partial<OpenAI.Images.ImageGenerateParams> = {}
351
+ ): Promise<OpenAI.Images.ImagesResponse> {
352
+ this.trackRequest();
353
+
354
+ try {
355
+ const response = await this.openai.images.generate({
356
+ prompt,
357
+ n: 1,
358
+ size: '1024x1024',
359
+ ...options
360
+ });
361
+
362
+ this.emit('image', response);
363
+
364
+ return response;
365
+ } catch (error) {
366
+ this.emit('failure', error);
367
+ throw error;
368
+ }
369
+ }
370
+
371
+ /**
372
+ * List all available models.
373
+ *
374
+ * @returns Paginated list of available models
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * const models = await openai.listModels()
379
+ * ```
380
+ */
381
+ async listModels(): Promise<OpenAI.Models.ModelsPage> {
382
+ try {
383
+ const response = await this.openai.models.list();
384
+ this.emit('models', response);
385
+ return response;
386
+ } catch (error) {
387
+ this.emit('failure', error);
388
+ throw error;
389
+ }
390
+ }
391
+
392
+ /**
393
+ * Ask a single question and get a text response.
394
+ *
395
+ * Convenience wrapper around `createChatCompletion` for simple Q&A.
396
+ *
397
+ * @param question - The question to ask
398
+ * @param options - Additional completion parameters
399
+ * @returns The assistant's text response
400
+ *
401
+ * @example
402
+ * ```typescript
403
+ * const answer = await openai.ask('What is 2 + 2?')
404
+ * console.log(answer) // '4'
405
+ * ```
406
+ */
407
+ async ask(
408
+ question: string,
409
+ options: Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams> = {}
410
+ ): Promise<string> {
411
+ const response = await this.createChatCompletion([
412
+ { role: 'user', content: question }
413
+ ], options);
414
+
415
+ return response.choices[0]?.message?.content || '';
416
+ }
417
+
418
+ /**
419
+ * Send a multi-turn conversation and get a text response.
420
+ *
421
+ * Convenience wrapper around `createChatCompletion` that returns just the text.
422
+ *
423
+ * @param messages - Array of chat messages
424
+ * @param options - Additional completion parameters
425
+ * @returns The assistant's text response
426
+ *
427
+ * @example
428
+ * ```typescript
429
+ * const reply = await openai.chat([
430
+ * { role: 'system', content: 'You are a pirate.' },
431
+ * { role: 'user', content: 'Hello!' }
432
+ * ])
433
+ * ```
434
+ */
435
+ async chat(
436
+ messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[],
437
+ options: Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams> = {}
438
+ ): Promise<string> {
439
+ const response = await this.createChatCompletion(messages, options);
440
+ return response.choices[0]?.message?.content || '';
441
+ }
442
+
443
+ /** The underlying OpenAI SDK instance for advanced use cases. */
444
+ get raw(): OpenAI {
445
+ return this.openai;
446
+ }
447
+ }
448
+
449
+ clients.register("openai", OpenAIClient)
450
+
451
+ export default OpenAIClient;