@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.
- package/CLAUDE.md +71 -0
- package/README.md +78 -0
- package/bun.lock +2928 -0
- package/bunfig.toml +3 -0
- package/commands/audit-docs.ts +740 -0
- package/commands/build-scaffolds.ts +154 -0
- package/commands/generate-api-docs.ts +114 -0
- package/commands/update-introspection.ts +67 -0
- package/docs/CLI.md +335 -0
- package/docs/README.md +88 -0
- package/docs/TABLE-OF-CONTENTS.md +157 -0
- package/docs/apis/clients/elevenlabs.md +84 -0
- package/docs/apis/clients/graph.md +56 -0
- package/docs/apis/clients/openai.md +69 -0
- package/docs/apis/clients/rest.md +41 -0
- package/docs/apis/clients/websocket.md +107 -0
- package/docs/apis/features/agi/assistant.md +471 -0
- package/docs/apis/features/agi/assistants-manager.md +154 -0
- package/docs/apis/features/agi/claude-code.md +602 -0
- package/docs/apis/features/agi/conversation-history.md +352 -0
- package/docs/apis/features/agi/conversation.md +333 -0
- package/docs/apis/features/agi/docs-reader.md +121 -0
- package/docs/apis/features/agi/openai-codex.md +318 -0
- package/docs/apis/features/agi/openapi.md +138 -0
- package/docs/apis/features/agi/semantic-search.md +387 -0
- package/docs/apis/features/agi/skills-library.md +216 -0
- package/docs/apis/features/node/container-link.md +133 -0
- package/docs/apis/features/node/content-db.md +313 -0
- package/docs/apis/features/node/disk-cache.md +379 -0
- package/docs/apis/features/node/dns.md +651 -0
- package/docs/apis/features/node/docker.md +705 -0
- package/docs/apis/features/node/downloader.md +81 -0
- package/docs/apis/features/node/esbuild.md +59 -0
- package/docs/apis/features/node/file-manager.md +182 -0
- package/docs/apis/features/node/fs.md +581 -0
- package/docs/apis/features/node/git.md +330 -0
- package/docs/apis/features/node/google-auth.md +174 -0
- package/docs/apis/features/node/google-calendar.md +187 -0
- package/docs/apis/features/node/google-docs.md +151 -0
- package/docs/apis/features/node/google-drive.md +225 -0
- package/docs/apis/features/node/google-sheets.md +179 -0
- package/docs/apis/features/node/grep.md +290 -0
- package/docs/apis/features/node/helpers.md +135 -0
- package/docs/apis/features/node/ink.md +334 -0
- package/docs/apis/features/node/ipc-socket.md +260 -0
- package/docs/apis/features/node/json-tree.md +86 -0
- package/docs/apis/features/node/launcher-app-command-listener.md +145 -0
- package/docs/apis/features/node/networking.md +281 -0
- package/docs/apis/features/node/nlp.md +133 -0
- package/docs/apis/features/node/opener.md +97 -0
- package/docs/apis/features/node/os.md +118 -0
- package/docs/apis/features/node/package-finder.md +402 -0
- package/docs/apis/features/node/postgres.md +212 -0
- package/docs/apis/features/node/proc.md +430 -0
- package/docs/apis/features/node/process-manager.md +210 -0
- package/docs/apis/features/node/python.md +278 -0
- package/docs/apis/features/node/repl.md +88 -0
- package/docs/apis/features/node/runpod.md +673 -0
- package/docs/apis/features/node/secure-shell.md +169 -0
- package/docs/apis/features/node/semantic-search.md +401 -0
- package/docs/apis/features/node/sqlite.md +211 -0
- package/docs/apis/features/node/telegram.md +254 -0
- package/docs/apis/features/node/tts.md +118 -0
- package/docs/apis/features/node/ui.md +703 -0
- package/docs/apis/features/node/vault.md +64 -0
- package/docs/apis/features/node/vm.md +84 -0
- package/docs/apis/features/node/window-manager.md +337 -0
- package/docs/apis/features/node/yaml-tree.md +85 -0
- package/docs/apis/features/node/yaml.md +176 -0
- package/docs/apis/features/web/asset-loader.md +47 -0
- package/docs/apis/features/web/container-link.md +133 -0
- package/docs/apis/features/web/esbuild.md +59 -0
- package/docs/apis/features/web/helpers.md +135 -0
- package/docs/apis/features/web/network.md +30 -0
- package/docs/apis/features/web/speech.md +55 -0
- package/docs/apis/features/web/vault.md +64 -0
- package/docs/apis/features/web/vm.md +84 -0
- package/docs/apis/features/web/voice.md +67 -0
- package/docs/apis/servers/express.md +127 -0
- package/docs/apis/servers/mcp.md +213 -0
- package/docs/apis/servers/websocket.md +99 -0
- package/docs/documentation-audit.md +134 -0
- package/docs/examples/content-db.md +77 -0
- package/docs/examples/disk-cache.md +83 -0
- package/docs/examples/docker.md +101 -0
- package/docs/examples/downloader.md +70 -0
- package/docs/examples/esbuild.md +80 -0
- package/docs/examples/file-manager.md +82 -0
- package/docs/examples/fs.md +83 -0
- package/docs/examples/git.md +85 -0
- package/docs/examples/google-auth.md +88 -0
- package/docs/examples/google-calendar.md +94 -0
- package/docs/examples/google-docs.md +82 -0
- package/docs/examples/google-drive.md +96 -0
- package/docs/examples/google-sheets.md +95 -0
- package/docs/examples/grep.md +85 -0
- package/docs/examples/ink-blocks.md +75 -0
- package/docs/examples/ink-renderer.md +41 -0
- package/docs/examples/ink.md +103 -0
- package/docs/examples/ipc-socket.md +103 -0
- package/docs/examples/json-tree.md +91 -0
- package/docs/examples/launcher-app-command-listener.md +120 -0
- package/docs/examples/networking.md +58 -0
- package/docs/examples/nlp.md +91 -0
- package/docs/examples/opener.md +78 -0
- package/docs/examples/os.md +72 -0
- package/docs/examples/package-finder.md +89 -0
- package/docs/examples/port-exposer.md +89 -0
- package/docs/examples/postgres.md +91 -0
- package/docs/examples/proc.md +81 -0
- package/docs/examples/process-manager.md +79 -0
- package/docs/examples/python.md +91 -0
- package/docs/examples/repl.md +93 -0
- package/docs/examples/runpod.md +119 -0
- package/docs/examples/secure-shell.md +92 -0
- package/docs/examples/sqlite.md +86 -0
- package/docs/examples/telegram.md +77 -0
- package/docs/examples/tts.md +86 -0
- package/docs/examples/ui.md +80 -0
- package/docs/examples/vault.md +70 -0
- package/docs/examples/vm.md +86 -0
- package/docs/examples/window-manager.md +125 -0
- package/docs/examples/yaml-tree.md +93 -0
- package/docs/examples/yaml.md +104 -0
- package/docs/ideas/class-registration-refactor-possibilities.md +197 -0
- package/docs/ideas/container-use-api.md +9 -0
- package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
- package/docs/ideas/feature-stacks.md +22 -0
- package/docs/ideas/luca-cli-self-sufficiency-demo.md +23 -0
- package/docs/ideas/mcp-design.md +9 -0
- package/docs/ideas/web-container-debugging-feature.md +13 -0
- package/docs/introspection-audit.md +49 -0
- package/docs/introspection.md +154 -0
- package/docs/mcp/readme.md +162 -0
- package/docs/models.ts +38 -0
- package/docs/philosophy.md +85 -0
- package/docs/principles.md +7 -0
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
- package/docs/prompts/mcp-test-easy-command.md +27 -0
- package/docs/reports/assistant-bugs.md +38 -0
- package/docs/reports/attach-pattern-usage.md +18 -0
- package/docs/reports/code-audit-results.md +391 -0
- package/docs/reports/introspection-audit-tasks.md +378 -0
- package/docs/reports/luca-mcp-improvements.md +128 -0
- package/docs/scaffolds/client.md +140 -0
- package/docs/scaffolds/command.md +106 -0
- package/docs/scaffolds/endpoint.md +176 -0
- package/docs/scaffolds/feature.md +148 -0
- package/docs/scaffolds/server.md +187 -0
- package/docs/tasks/web-container-helper-discovery.md +71 -0
- package/docs/todos.md +1 -0
- package/docs/tutorials/01-getting-started.md +106 -0
- package/docs/tutorials/02-container.md +210 -0
- package/docs/tutorials/03-scripts.md +194 -0
- package/docs/tutorials/04-features-overview.md +196 -0
- package/docs/tutorials/05-state-and-events.md +171 -0
- package/docs/tutorials/06-servers.md +157 -0
- package/docs/tutorials/07-endpoints.md +198 -0
- package/docs/tutorials/08-commands.md +171 -0
- package/docs/tutorials/09-clients.md +162 -0
- package/docs/tutorials/10-creating-features.md +198 -0
- package/docs/tutorials/11-contentbase.md +191 -0
- package/docs/tutorials/12-assistants.md +215 -0
- package/docs/tutorials/13-introspection.md +147 -0
- package/docs/tutorials/14-type-system.md +174 -0
- package/docs/tutorials/15-project-patterns.md +222 -0
- package/docs/tutorials/16-google-features.md +534 -0
- package/docs/tutorials/17-tui-blocks.md +530 -0
- package/docs/tutorials/18-semantic-search.md +334 -0
- package/index.ts +1 -0
- package/luca.console.ts +9 -0
- package/main.py +6 -0
- package/package.json +154 -0
- package/pyproject.toml +7 -0
- package/scripts/animations/chrome-glitch.ts +55 -0
- package/scripts/animations/index.ts +16 -0
- package/scripts/animations/neon-pulse.ts +64 -0
- package/scripts/animations/types.ts +6 -0
- package/scripts/build-web.ts +28 -0
- package/scripts/examples/ask-luca-expert.ts +42 -0
- package/scripts/examples/assistant-questions.ts +12 -0
- package/scripts/examples/excalidraw-expert.ts +75 -0
- package/scripts/examples/expert-chat.ts +0 -0
- package/scripts/examples/file-manager.ts +14 -0
- package/scripts/examples/ideas.ts +12 -0
- package/scripts/examples/interactive-chat.ts +20 -0
- package/scripts/examples/openai-tool-calls.ts +113 -0
- package/scripts/examples/opening-a-web-browser.ts +5 -0
- package/scripts/examples/telegram-bot.ts +79 -0
- package/scripts/examples/telegram-ink-ui.ts +302 -0
- package/scripts/examples/using-assistant-with-mcp.ts +560 -0
- package/scripts/examples/using-claude-code.ts +10 -0
- package/scripts/examples/using-contentdb.ts +35 -0
- package/scripts/examples/using-conversations.ts +35 -0
- package/scripts/examples/using-disk-cache.ts +10 -0
- package/scripts/examples/using-docker-shell.ts +75 -0
- package/scripts/examples/using-elevenlabs.ts +25 -0
- package/scripts/examples/using-google-calendar.ts +57 -0
- package/scripts/examples/using-google-docs.ts +74 -0
- package/scripts/examples/using-google-drive.ts +74 -0
- package/scripts/examples/using-google-sheets.ts +89 -0
- package/scripts/examples/using-nlp.ts +55 -0
- package/scripts/examples/using-ollama.ts +10 -0
- package/scripts/examples/using-openai-codex.ts +23 -0
- package/scripts/examples/using-postgres.ts +55 -0
- package/scripts/examples/using-runpod.ts +32 -0
- package/scripts/examples/using-tts.ts +40 -0
- package/scripts/examples/vm-loading-esm-modules.ts +16 -0
- package/scripts/scaffold.ts +391 -0
- package/scripts/scratch.ts +15 -0
- package/scripts/test-command-listener.ts +123 -0
- package/scripts/test-window-manager-lifecycle.ts +86 -0
- package/scripts/test-window-manager.ts +43 -0
- package/scripts/update-introspection-data.ts +58 -0
- package/src/agi/README.md +14 -0
- package/src/agi/container.server.ts +114 -0
- package/src/agi/endpoints/ask.ts +60 -0
- package/src/agi/endpoints/conversations/[id].ts +45 -0
- package/src/agi/endpoints/conversations.ts +31 -0
- package/src/agi/endpoints/experts.ts +37 -0
- package/src/agi/features/assistant.ts +767 -0
- package/src/agi/features/assistants-manager.ts +260 -0
- package/src/agi/features/claude-code.ts +1111 -0
- package/src/agi/features/conversation-history.ts +497 -0
- package/src/agi/features/conversation.ts +799 -0
- package/src/agi/features/openai-codex.ts +631 -0
- package/src/agi/features/openapi.ts +438 -0
- package/src/agi/features/skills-library.ts +425 -0
- package/src/agi/index.ts +6 -0
- package/src/agi/lib/token-counter.ts +122 -0
- package/src/browser.ts +25 -0
- package/src/bus.ts +100 -0
- package/src/cli/cli.ts +70 -0
- package/src/client.ts +461 -0
- package/src/clients/civitai/index.ts +541 -0
- package/src/clients/client-template.ts +41 -0
- package/src/clients/comfyui/index.ts +597 -0
- package/src/clients/elevenlabs/index.ts +291 -0
- package/src/clients/openai/index.ts +451 -0
- package/src/clients/supabase/index.ts +366 -0
- package/src/command.ts +164 -0
- package/src/commands/chat.ts +182 -0
- package/src/commands/console.ts +192 -0
- package/src/commands/describe.ts +433 -0
- package/src/commands/eval.ts +116 -0
- package/src/commands/help.ts +214 -0
- package/src/commands/index.ts +14 -0
- package/src/commands/mcp.ts +64 -0
- package/src/commands/prompt.ts +807 -0
- package/src/commands/run.ts +257 -0
- package/src/commands/sandbox-mcp.ts +439 -0
- package/src/commands/scaffold.ts +79 -0
- package/src/commands/serve.ts +172 -0
- package/src/container.ts +781 -0
- package/src/endpoint.ts +340 -0
- package/src/feature.ts +75 -0
- package/src/hash-object.ts +97 -0
- package/src/helper.ts +543 -0
- package/src/introspection/generated.agi.ts +23388 -0
- package/src/introspection/generated.node.ts +18899 -0
- package/src/introspection/generated.web.ts +2021 -0
- package/src/introspection/index.ts +256 -0
- package/src/introspection/scan.ts +912 -0
- package/src/node/container.ts +354 -0
- package/src/node/feature.ts +13 -0
- package/src/node/features/container-link.ts +558 -0
- package/src/node/features/content-db.ts +475 -0
- package/src/node/features/disk-cache.ts +382 -0
- package/src/node/features/dns.ts +655 -0
- package/src/node/features/docker.ts +912 -0
- package/src/node/features/downloader.ts +92 -0
- package/src/node/features/esbuild.ts +68 -0
- package/src/node/features/file-manager.ts +357 -0
- package/src/node/features/fs.ts +534 -0
- package/src/node/features/git.ts +492 -0
- package/src/node/features/google-auth.ts +502 -0
- package/src/node/features/google-calendar.ts +300 -0
- package/src/node/features/google-docs.ts +404 -0
- package/src/node/features/google-drive.ts +339 -0
- package/src/node/features/google-sheets.ts +279 -0
- package/src/node/features/grep.ts +406 -0
- package/src/node/features/helpers.ts +374 -0
- package/src/node/features/ink.ts +490 -0
- package/src/node/features/ipc-socket.ts +459 -0
- package/src/node/features/json-tree.ts +188 -0
- package/src/node/features/launcher-app-command-listener.ts +388 -0
- package/src/node/features/networking.ts +925 -0
- package/src/node/features/nlp.ts +211 -0
- package/src/node/features/opener.ts +166 -0
- package/src/node/features/os.ts +157 -0
- package/src/node/features/package-finder.ts +539 -0
- package/src/node/features/port-exposer.ts +342 -0
- package/src/node/features/postgres.ts +273 -0
- package/src/node/features/proc.ts +502 -0
- package/src/node/features/process-manager.ts +542 -0
- package/src/node/features/python.ts +444 -0
- package/src/node/features/repl.ts +194 -0
- package/src/node/features/runpod.ts +802 -0
- package/src/node/features/secure-shell.ts +248 -0
- package/src/node/features/semantic-search.ts +924 -0
- package/src/node/features/sqlite.ts +289 -0
- package/src/node/features/telegram.ts +342 -0
- package/src/node/features/tts.ts +184 -0
- package/src/node/features/ui.ts +857 -0
- package/src/node/features/vault.ts +164 -0
- package/src/node/features/vm.ts +312 -0
- package/src/node/features/window-manager.ts +804 -0
- package/src/node/features/yaml-tree.ts +149 -0
- package/src/node/features/yaml.ts +132 -0
- package/src/node.ts +70 -0
- package/src/react/index.ts +175 -0
- package/src/registry.ts +199 -0
- package/src/scaffolds/generated.ts +1613 -0
- package/src/scaffolds/template.ts +37 -0
- package/src/schemas/base.ts +255 -0
- package/src/server.ts +135 -0
- package/src/servers/express.ts +209 -0
- package/src/servers/mcp.ts +805 -0
- package/src/servers/socket.ts +120 -0
- package/src/state.ts +101 -0
- package/src/web/clients/socket.ts +82 -0
- package/src/web/container.ts +74 -0
- package/src/web/extension.ts +30 -0
- package/src/web/feature.ts +12 -0
- package/src/web/features/asset-loader.ts +64 -0
- package/src/web/features/container-link.ts +385 -0
- package/src/web/features/esbuild.ts +79 -0
- package/src/web/features/helpers.ts +267 -0
- package/src/web/features/network.ts +61 -0
- package/src/web/features/speech.ts +87 -0
- package/src/web/features/vault.ts +189 -0
- package/src/web/features/vm.ts +78 -0
- package/src/web/features/voice-recognition.ts +129 -0
- package/src/web/shims/isomorphic-vm.ts +149 -0
- package/test/bus.test.ts +134 -0
- package/test/clients-servers.test.ts +216 -0
- package/test/container-link.test.ts +274 -0
- package/test/features.test.ts +160 -0
- package/test/integration.test.ts +787 -0
- package/test/node-container.test.ts +121 -0
- package/test/rate-limit.test.ts +272 -0
- package/test/semantic-search.test.ts +550 -0
- package/test/state.test.ts +121 -0
- package/test-integration/assistant.test.ts +138 -0
- package/test-integration/assistants-manager.test.ts +123 -0
- package/test-integration/claude-code.test.ts +98 -0
- package/test-integration/conversation-history.test.ts +205 -0
- package/test-integration/conversation.test.ts +137 -0
- package/test-integration/elevenlabs.test.ts +55 -0
- package/test-integration/google-services.test.ts +80 -0
- package/test-integration/helpers.ts +89 -0
- package/test-integration/openai-codex.test.ts +93 -0
- package/test-integration/runpod.test.ts +58 -0
- package/test-integration/server-endpoints.test.ts +97 -0
- package/test-integration/skills-library.test.ts +157 -0
- package/test-integration/telegram.test.ts +46 -0
- package/tsconfig.json +58 -0
- 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;
|