call-ai 0.10.2 → 0.11.0-dev-preview3

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 (71) hide show
  1. package/README.md +60 -58
  2. package/api-core.d.ts +13 -0
  3. package/{dist/api-core.js → api-core.js} +51 -126
  4. package/api-core.js.map +1 -0
  5. package/api.d.ts +4 -0
  6. package/api.js +364 -0
  7. package/api.js.map +1 -0
  8. package/api.ts.off +595 -0
  9. package/{dist/error-handling.d.ts → error-handling.d.ts} +4 -2
  10. package/{dist/error-handling.js → error-handling.js} +34 -70
  11. package/error-handling.js.map +1 -0
  12. package/image.d.ts +2 -0
  13. package/{dist/image.js → image.js} +10 -33
  14. package/image.js.map +1 -0
  15. package/index.d.ts +6 -0
  16. package/index.js +7 -0
  17. package/index.js.map +1 -0
  18. package/index.ts.bak +16 -0
  19. package/key-management.d.ts +29 -0
  20. package/key-management.js +189 -0
  21. package/key-management.js.map +1 -0
  22. package/{dist/non-streaming.d.ts → non-streaming.d.ts} +5 -8
  23. package/{dist/non-streaming.js → non-streaming.js} +28 -87
  24. package/non-streaming.js.map +1 -0
  25. package/package.json +15 -31
  26. package/response-metadata.d.ts +6 -0
  27. package/response-metadata.js +22 -0
  28. package/response-metadata.js.map +1 -0
  29. package/strategies/index.d.ts +2 -0
  30. package/strategies/index.js +3 -0
  31. package/strategies/index.js.map +1 -0
  32. package/strategies/model-strategies.d.ts +6 -0
  33. package/{dist/strategies → strategies}/model-strategies.js +26 -72
  34. package/strategies/model-strategies.js.map +1 -0
  35. package/strategies/strategy-selector.d.ts +2 -0
  36. package/strategies/strategy-selector.js +66 -0
  37. package/strategies/strategy-selector.js.map +1 -0
  38. package/streaming.d.ts +4 -0
  39. package/{dist/streaming.js → streaming.js} +66 -184
  40. package/streaming.js.map +1 -0
  41. package/streaming.ts.off +571 -0
  42. package/tsconfig.json +18 -0
  43. package/types.d.ts +226 -0
  44. package/types.js +33 -0
  45. package/types.js.map +1 -0
  46. package/utils.d.ts +32 -0
  47. package/utils.js +129 -0
  48. package/utils.js.map +1 -0
  49. package/version.d.ts +1 -0
  50. package/version.js +2 -0
  51. package/version.js.map +1 -0
  52. package/dist/api-core.d.ts +0 -40
  53. package/dist/api.d.ts +0 -15
  54. package/dist/api.js +0 -498
  55. package/dist/image.d.ts +0 -12
  56. package/dist/index.d.ts +0 -7
  57. package/dist/index.js +0 -32
  58. package/dist/key-management.d.ts +0 -43
  59. package/dist/key-management.js +0 -312
  60. package/dist/response-metadata.d.ts +0 -18
  61. package/dist/response-metadata.js +0 -44
  62. package/dist/strategies/index.d.ts +0 -5
  63. package/dist/strategies/index.js +0 -21
  64. package/dist/strategies/model-strategies.d.ts +0 -24
  65. package/dist/strategies/strategy-selector.d.ts +0 -8
  66. package/dist/strategies/strategy-selector.js +0 -79
  67. package/dist/streaming.d.ts +0 -7
  68. package/dist/types.d.ts +0 -226
  69. package/dist/types.js +0 -5
  70. package/dist/utils.d.ts +0 -8
  71. package/dist/utils.js +0 -52
package/README.md CHANGED
@@ -15,22 +15,22 @@ pnpm add call-ai
15
15
  ## Usage
16
16
 
17
17
  ```typescript
18
- import { callAi } from 'call-ai';
18
+ import { callAi } from "call-ai";
19
19
 
20
20
  // Basic usage with string prompt (non-streaming by default)
21
- const response = await callAi('Explain quantum computing in simple terms', {
22
- apiKey: 'your-api-key',
23
- model: 'gpt-4'
21
+ const response = await callAi("Explain quantum computing in simple terms", {
22
+ apiKey: "your-api-key",
23
+ model: "gpt-4",
24
24
  });
25
25
 
26
26
  // The response is the complete text
27
27
  console.log(response);
28
28
 
29
29
  // With streaming enabled (returns an AsyncGenerator)
30
- const generator = callAi('Tell me a story', {
31
- apiKey: 'your-api-key',
32
- model: 'gpt-4',
33
- stream: true
30
+ const generator = callAi("Tell me a story", {
31
+ apiKey: "your-api-key",
32
+ model: "gpt-4",
33
+ stream: true,
34
34
  });
35
35
 
36
36
  // Process streaming updates
@@ -40,13 +40,13 @@ for await (const chunk of generator) {
40
40
 
41
41
  // Using message array for more control
42
42
  const messages = [
43
- { role: 'system', content: 'You are a helpful assistant.' },
44
- { role: 'user', content: 'Explain quantum computing in simple terms' }
43
+ { role: "system", content: "You are a helpful assistant." },
44
+ { role: "user", content: "Explain quantum computing in simple terms" },
45
45
  ];
46
46
 
47
47
  const response = await callAi(messages, {
48
- apiKey: 'your-api-key',
49
- model: 'gpt-4'
48
+ apiKey: "your-api-key",
49
+ model: "gpt-4",
50
50
  });
51
51
 
52
52
  console.log(response);
@@ -55,16 +55,16 @@ console.log(response);
55
55
  const schema = {
56
56
  name: "exercise_summary",
57
57
  properties: {
58
- title: { type: 'string' },
59
- summary: { type: 'string' },
60
- points: { type: 'array', items: { type: 'string' } }
58
+ title: { type: "string" },
59
+ summary: { type: "string" },
60
+ points: { type: "array", items: { type: "string" } },
61
61
  },
62
- required: ['title', 'summary']
62
+ required: ["title", "summary"],
63
63
  };
64
64
 
65
- const response = await callAi('Summarize the benefits of exercise', {
66
- apiKey: 'your-api-key',
67
- schema: schema
65
+ const response = await callAi("Summarize the benefits of exercise", {
66
+ apiKey: "your-api-key",
67
+ schema: schema,
68
68
  });
69
69
 
70
70
  const structuredOutput = JSON.parse(response);
@@ -73,24 +73,24 @@ console.log(structuredOutput.title);
73
73
  // Streaming with schema for OpenRouter structured JSON output
74
74
  const schema = {
75
75
  properties: {
76
- title: { type: 'string' },
77
- items: {
78
- type: 'array',
79
- items: {
80
- type: 'object',
76
+ title: { type: "string" },
77
+ items: {
78
+ type: "array",
79
+ items: {
80
+ type: "object",
81
81
  properties: {
82
- name: { type: 'string' },
83
- description: { type: 'string' }
84
- }
85
- }
86
- }
87
- }
82
+ name: { type: "string" },
83
+ description: { type: "string" },
84
+ },
85
+ },
86
+ },
87
+ },
88
88
  };
89
89
 
90
- const generator = callAi('Create a list of sci-fi books', {
91
- apiKey: 'your-api-key',
90
+ const generator = callAi("Create a list of sci-fi books", {
91
+ apiKey: "your-api-key",
92
92
  stream: true,
93
- schema: schema
93
+ schema: schema,
94
94
  });
95
95
 
96
96
  for await (const chunk of generator) {
@@ -124,20 +124,20 @@ Different LLMs have different strengths when working with structured data. Based
124
124
 
125
125
  ### Schema Complexity Guide
126
126
 
127
- | Model Family | Grade | Simple Flat Schema | Complex Flat Schema | Nested Schema | Best For |
128
- |--------------|-------|-------------------|---------------------|---------------|----------|
129
- | OpenAI | A | ✅ Excellent | ✅ Excellent | ✅ Excellent | Most reliable for all schema types |
130
- | Gemini | A | ✅ Excellent | ✅ Excellent | ✅ Good | Good all-around performance, especially with flat schemas |
131
- | Claude | B | ✅ Excellent | ⚠️ Good (occasional JSON errors) | ✅ Good | Simple schemas, robust handling of complex prompts |
132
- | Llama 3 | C | ✅ Good | ✅ Good | ❌ Poor | Simpler flat schemas, may struggle with nested structures |
133
- | Deepseek | C | ✅ Good | ✅ Good | ❌ Poor | Basic flat schemas only |
127
+ | Model Family | Grade | Simple Flat Schema | Complex Flat Schema | Nested Schema | Best For |
128
+ | ------------ | ----- | ------------------ | -------------------------------- | ------------- | --------------------------------------------------------- |
129
+ | OpenAI | A | ✅ Excellent | ✅ Excellent | ✅ Excellent | Most reliable for all schema types |
130
+ | Gemini | A | ✅ Excellent | ✅ Excellent | ✅ Good | Good all-around performance, especially with flat schemas |
131
+ | Claude | B | ✅ Excellent | ⚠️ Good (occasional JSON errors) | ✅ Good | Simple schemas, robust handling of complex prompts |
132
+ | Llama 3 | C | ✅ Good | ✅ Good | ❌ Poor | Simpler flat schemas, may struggle with nested structures |
133
+ | Deepseek | C | ✅ Good | ✅ Good | ❌ Poor | Basic flat schemas only |
134
134
 
135
135
  ### Schema Structure Recommendations
136
136
 
137
137
  1. **Flat schemas perform better across all models**. If you need maximum compatibility, avoid deeply nested structures.
138
138
 
139
139
  2. **Field names matter**. Some models have preferences for certain property naming patterns:
140
- - Use simple, common naming patterns like `name`, `type`, `items`, `price`
140
+ - Use simple, common naming patterns like `name`, `type`, `items`, `price`
141
141
  - Avoid deeply nested object hierarchies (more than 2 levels deep)
142
142
  - Keep array items simple (strings or flat objects)
143
143
 
@@ -154,36 +154,36 @@ Different LLMs have different strengths when working with structured data. Based
154
154
  You can provide your API key in three ways:
155
155
 
156
156
  1. Directly in the options:
157
+
157
158
  ```typescript
158
- const response = await callAi('Hello', { apiKey: 'your-api-key' });
159
+ const response = await callAi("Hello", { apiKey: "your-api-key" });
159
160
  ```
160
161
 
161
162
  2. Set globally in the browser:
163
+
162
164
  ```typescript
163
- window.CALLAI_API_KEY = 'your-api-key';
164
- const response = await callAi('Hello');
165
+ window.CALLAI_API_KEY = "your-api-key";
166
+ const response = await callAi("Hello");
165
167
  ```
166
168
 
167
169
  3. Use environment variables in Node.js (with a custom implementation):
170
+
168
171
  ```typescript
169
172
  // Example of environment variable integration
170
- import { callAi } from 'call-ai';
173
+ import { callAi } from "call-ai";
171
174
  const apiKey = process.env.OPENAI_API_KEY || process.env.OPENROUTER_API_KEY;
172
- const response = await callAi('Hello', { apiKey });
175
+ const response = await callAi("Hello", { apiKey });
173
176
  ```
174
177
 
175
178
  ## API
176
179
 
177
180
  ```typescript
178
181
  // Main function
179
- function callAi(
180
- prompt: string | Message[],
181
- options?: CallAIOptions
182
- ): Promise<string> | AsyncGenerator<string, string, unknown>
182
+ function callAi(prompt: string | Message[], options?: CallAIOptions): Promise<string> | AsyncGenerator<string, string, unknown>;
183
183
 
184
184
  // Types
185
185
  type Message = {
186
- role: 'user' | 'system' | 'assistant';
186
+ role: "user" | "system" | "assistant";
187
187
  content: string;
188
188
  };
189
189
 
@@ -209,12 +209,12 @@ interface CallAIOptions {
209
209
 
210
210
  ### Options
211
211
 
212
- * `apiKey`: Your API key (can also be set via window.CALLAI_API_KEY)
213
- * `model`: Model identifier (default: 'openrouter/auto')
214
- * `endpoint`: API endpoint (default: 'https://openrouter.ai/api/v1/chat/completions')
215
- * `stream`: Enable streaming responses (default: false)
216
- * `schema`: Optional JSON schema for structured output
217
- * Any other options are passed directly to the API (temperature, max_tokens, etc.)
212
+ - `apiKey`: Your API key (can also be set via window.CALLAI_API_KEY)
213
+ - `model`: Model identifier (default: 'openrouter/auto')
214
+ - `endpoint`: API endpoint (default: 'https://openrouter.ai/api/v1/chat/completions')
215
+ - `stream`: Enable streaming responses (default: false)
216
+ - `schema`: Optional JSON schema for structured output
217
+ - Any other options are passed directly to the API (temperature, max_tokens, etc.)
218
218
 
219
219
  ## License
220
220
 
@@ -251,12 +251,14 @@ This library uses GitHub Actions to automate the release process:
251
251
  5. Push changes and tag: `git push origin main vX.Y.Z`
252
252
 
253
253
  The GitHub workflow in `.github/workflows/publish.yml` will:
254
+
254
255
  - Automatically trigger when a new tag is pushed
255
256
  - Run tests and type checking
256
257
  - Verify the tag signature
257
258
  - Publish the package to npm
258
259
 
259
260
  When making significant changes, remember to:
261
+
260
262
  - Document breaking changes in the changelog
261
263
  - Update documentation to reflect API changes
262
- - Update TypeScript types
264
+ - Update TypeScript types
package/api-core.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { CallAIOptions, Message, StreamResponse, ThenableStreamResponse } from "./types.js";
2
+ import { PACKAGE_VERSION } from "./version.js";
3
+ declare function callAi(prompt: string | Message[], options?: CallAIOptions): Promise<string> | ThenableStreamResponse;
4
+ declare function bufferStreamingResults(generator: AsyncGenerator<string, string, unknown>): Promise<string>;
5
+ declare function createBackwardCompatStreamingProxy(promise: Promise<StreamResponse>): ThenableStreamResponse;
6
+ declare function prepareRequestParams(prompt: string | Message[], options?: CallAIOptions): {
7
+ messages: Message[] | {
8
+ role: string;
9
+ content: string;
10
+ }[];
11
+ apiKey: string;
12
+ };
13
+ export { callAi, bufferStreamingResults, createBackwardCompatStreamingProxy, prepareRequestParams, PACKAGE_VERSION };
@@ -1,72 +1,49 @@
1
- "use strict";
2
- /**
3
- * Core API implementation for call-ai
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PACKAGE_VERSION = void 0;
7
- exports.callAi = callAi;
8
- exports.bufferStreamingResults = bufferStreamingResults;
9
- exports.createBackwardCompatStreamingProxy = createBackwardCompatStreamingProxy;
10
- exports.prepareRequestParams = prepareRequestParams;
11
- const key_management_1 = require("./key-management");
12
- const non_streaming_1 = require("./non-streaming");
13
- const streaming_1 = require("./streaming");
14
- // Import package version for debugging
15
- // eslint-disable-next-line @typescript-eslint/no-var-requires
16
- const PACKAGE_VERSION = require("../package.json").version;
17
- exports.PACKAGE_VERSION = PACKAGE_VERSION;
18
- /**
19
- * Main API interface function for making AI API calls
20
- *
21
- * @param prompt The prompt to send to the AI, either a string or a Message array
22
- * @param options Configuration options for the API call
23
- * @returns Promise<string> for non-streaming or AsyncGenerator for streaming
24
- */
25
- // Main API interface function - must match original signature exactly
1
+ import { isToolUseType, isToolUseResponse, isOpenAIArray, CallAIError, } from "./types.js";
2
+ import { globalDebug } from "./key-management.js";
3
+ import { callAINonStreaming } from "./non-streaming.js";
4
+ import { callAIStreaming } from "./streaming.js";
5
+ import { PACKAGE_VERSION } from "./version.js";
6
+ import { callAiEnv } from "./utils.js";
26
7
  function callAi(prompt, options = {}) {
27
- // Use the global debug flag if not specified in options
28
- const debug = options.debug === undefined ? key_management_1.globalDebug : options.debug;
29
- // Validate and prepare parameters (including API key validation)
8
+ const debug = options.debug === undefined ? globalDebug : options.debug;
30
9
  prepareRequestParams(prompt, options);
31
- // Handle schema strategy based on model or explicitly provided strategy
32
10
  let schemaStrategy = {
33
11
  strategy: "none",
34
12
  model: options.model || "openai/gpt-3.5-turbo",
35
- prepareRequest: () => ({}),
13
+ prepareRequest: () => {
14
+ throw new Error("Schema strategy not implemented");
15
+ },
36
16
  processResponse: (response) => {
37
- // If response is an object, stringify it to match expected test output
38
17
  if (response && typeof response === "object") {
39
18
  return JSON.stringify(response);
40
19
  }
20
+ if (typeof response !== "string") {
21
+ throw new Error(`Unexpected response type: ${typeof response}`);
22
+ }
41
23
  return response;
42
24
  },
43
25
  shouldForceStream: false,
44
26
  };
45
- // If a schema is provided, determine the appropriate strategy
46
27
  if (options.schema) {
47
28
  const model = options.model || "openai/gpt-3.5-turbo";
48
- // Choose function calling strategy based on model
49
29
  if (/claude/i.test(model) || /anthropic/i.test(model)) {
50
30
  schemaStrategy = {
51
31
  strategy: "tool_mode",
52
32
  model,
53
33
  shouldForceStream: false,
54
34
  prepareRequest: (schema) => {
55
- // Parse the schema to extract the function definition
56
35
  let toolDef = {};
57
36
  if (typeof schema === "string") {
58
37
  try {
59
38
  toolDef = JSON.parse(schema);
60
39
  }
61
40
  catch (e) {
62
- // If it's not valid JSON, we'll use it as a plain description
63
41
  toolDef = { description: schema };
64
42
  }
65
43
  }
66
44
  else if (schema) {
67
45
  toolDef = schema;
68
46
  }
69
- // Build a tools array compatible with Claude's format
70
47
  const tools = [
71
48
  {
72
49
  type: "function",
@@ -89,41 +66,30 @@ function callAi(prompt, options = {}) {
89
66
  };
90
67
  },
91
68
  processResponse: (response) => {
92
- // Handle different response formats
93
69
  if (typeof response === "string") {
94
70
  return response;
95
71
  }
96
- // Handle direct tool_use format
97
- if (response && response.type === "tool_use") {
72
+ if (isToolUseType(response)) {
98
73
  return response.input || "{}";
99
74
  }
100
- // Handle object with tool_use property
101
- if (response && response.tool_use) {
75
+ if (isToolUseResponse(response)) {
102
76
  return response.tool_use.input || "{}";
103
77
  }
104
- // Handle array of tool calls (OpenAI format)
105
- if (Array.isArray(response)) {
106
- if (response.length > 0 &&
107
- response[0].function &&
108
- response[0].function.arguments) {
78
+ if (isOpenAIArray(response)) {
79
+ if (response.length > 0 && response[0].function && response[0].function.arguments) {
109
80
  return response[0].function.arguments;
110
81
  }
111
82
  }
112
- // For all other cases, return string representation
113
- return typeof response === "string"
114
- ? response
115
- : JSON.stringify(response);
83
+ return typeof response === "string" ? response : JSON.stringify(response);
116
84
  },
117
85
  };
118
86
  }
119
87
  else {
120
- // For OpenAI compatible models, use json_schema format
121
88
  schemaStrategy = {
122
89
  strategy: "json_schema",
123
90
  model,
124
91
  shouldForceStream: false,
125
92
  prepareRequest: (schema) => {
126
- // Create a properly formatted JSON schema request
127
93
  const schemaObj = schema || {};
128
94
  return {
129
95
  response_format: {
@@ -133,129 +99,107 @@ function callAi(prompt, options = {}) {
133
99
  schema: {
134
100
  type: "object",
135
101
  properties: schemaObj.properties || {},
136
- required: schemaObj.required ||
137
- Object.keys(schemaObj.properties || {}),
138
- additionalProperties: schemaObj.additionalProperties !== undefined
139
- ? schemaObj.additionalProperties
140
- : false,
102
+ required: schemaObj.required || Object.keys(schemaObj.properties || {}),
103
+ additionalProperties: schemaObj.additionalProperties !== undefined ? schemaObj.additionalProperties : false,
141
104
  },
142
105
  },
143
106
  },
144
107
  };
145
108
  },
146
109
  processResponse: (response) => {
147
- // Handle different response formats
148
110
  if (typeof response === "string") {
149
- // Keep string responses as is
150
111
  return response;
151
112
  }
152
- // If it's an object, convert to string to match test expectations
153
113
  return JSON.stringify(response);
154
114
  },
155
115
  };
156
116
  }
157
117
  }
158
- // Check if this should be a streaming or non-streaming call
159
118
  if (options.stream) {
160
119
  if (debug) {
161
120
  console.log(`[callAi:${PACKAGE_VERSION}] Making streaming request`);
162
121
  }
163
- // Handle streaming mode - return a Promise that resolves to an AsyncGenerator
164
- // but also supports legacy non-awaited usage for backward compatibility
165
122
  const streamPromise = (async () => {
166
- // This exact pattern matches the original implementation in api.ts
167
- return (0, streaming_1.callAIStreaming)(prompt, {
123
+ return callAIStreaming(prompt, {
168
124
  ...options,
169
125
  schemaStrategy,
170
126
  });
171
127
  })();
172
- // Create a proxy object that acts both as a Promise and an AsyncGenerator for backward compatibility
173
- // @ts-ignore - We're deliberately implementing a proxy with dual behavior
174
128
  return createBackwardCompatStreamingProxy(streamPromise);
175
129
  }
176
130
  else {
177
131
  if (debug) {
178
132
  console.log(`[callAi:${PACKAGE_VERSION}] Making non-streaming request`);
179
133
  }
180
- // Pass schemaStrategy through options to avoid type error
181
134
  const optionsWithSchema = {
182
135
  ...options,
183
136
  schemaStrategy,
184
137
  };
185
- // Make a non-streaming API call
186
- return (0, non_streaming_1.callAINonStreaming)(prompt, optionsWithSchema);
138
+ return callAINonStreaming(prompt, optionsWithSchema);
187
139
  }
188
140
  }
189
- /**
190
- * Buffers the results of a streaming generator into a single string
191
- *
192
- * @param generator The streaming generator returned by callAi
193
- * @returns Promise<string> with the complete response
194
- */
195
141
  async function bufferStreamingResults(generator) {
196
142
  let result = "";
197
143
  try {
198
- // Iterate through the generator and collect results
199
144
  for await (const chunk of generator) {
200
145
  result += chunk;
201
146
  }
202
147
  return result;
203
148
  }
204
149
  catch (error) {
205
- // If we already collected some content, attach it to the error
206
150
  if (error instanceof Error) {
207
- const enhancedError = new Error(`${error.message} (Partial content: ${result.slice(0, 100)}...)`);
208
- enhancedError.partialContent = result;
209
- enhancedError.originalError = error;
151
+ const enhancedError = new CallAIError({
152
+ message: `${error.message} (Partial content: ${result.slice(0, 100)}...)`,
153
+ status: 511,
154
+ partialContent: result,
155
+ originalError: error,
156
+ });
210
157
  throw enhancedError;
211
158
  }
212
159
  else {
213
- // For non-Error objects, create an Error with info
214
- const newError = new Error(`Streaming error: ${String(error)}`);
215
- newError.partialContent = result;
216
- newError.originalError = error;
160
+ const newError = new CallAIError({
161
+ message: `Streaming error: ${String(error)}`,
162
+ status: 511,
163
+ partialContent: result,
164
+ originalError: error,
165
+ });
217
166
  throw newError;
218
167
  }
219
168
  }
220
169
  }
221
- /**
222
- * Create a proxy that acts both as a Promise and an AsyncGenerator for backward compatibility
223
- * @internal This is for internal use only, not part of public API
224
- */
225
170
  function createBackwardCompatStreamingProxy(promise) {
226
- // Create a proxy that forwards methods to the Promise or AsyncGenerator as appropriate
227
171
  return new Proxy({}, {
228
172
  get(_target, prop) {
229
- // First check if it's an AsyncGenerator method (needed for for-await)
230
- if (prop === "next" ||
231
- prop === "throw" ||
232
- prop === "return" ||
233
- prop === Symbol.asyncIterator) {
234
- // Create wrapper functions that await the Promise first
173
+ if (prop === "next" || prop === "throw" || prop === "return" || prop === Symbol.asyncIterator) {
235
174
  if (prop === Symbol.asyncIterator) {
236
175
  return function () {
237
176
  return {
238
- // Implement async iterator that gets the generator first
239
177
  async next(value) {
240
178
  try {
241
179
  const generator = await promise;
242
180
  return generator.next(value);
243
181
  }
244
182
  catch (error) {
245
- // Turn Promise rejection into iterator result with error thrown
246
183
  return Promise.reject(error);
247
184
  }
248
185
  },
249
186
  };
250
187
  };
251
188
  }
252
- // Methods like next, throw, return
253
189
  return async function (value) {
254
190
  const generator = await promise;
255
- return generator[prop](value);
191
+ switch (prop) {
192
+ case "next":
193
+ return generator.next(value);
194
+ case "throw":
195
+ return generator.throw(value);
196
+ case "return":
197
+ return generator.return(value);
198
+ default:
199
+ throw new Error(`Unknown method: ${String(prop)}`);
200
+ }
256
201
  };
257
202
  }
258
- // Then check if it's a Promise method
259
203
  if (prop === "then" || prop === "catch" || prop === "finally") {
260
204
  return promise[prop].bind(promise);
261
205
  }
@@ -263,51 +207,32 @@ function createBackwardCompatStreamingProxy(promise) {
263
207
  },
264
208
  });
265
209
  }
266
- /**
267
- * Validates and prepares request parameters for API calls
268
- *
269
- * @param prompt User prompt (string or Message array)
270
- * @param options Call options
271
- * @returns Validated and processed parameters including apiKey
272
- */
273
210
  function prepareRequestParams(prompt, options = {}) {
274
- // Get API key from options or window.CALLAI_API_KEY (exactly matching original)
275
- const apiKey = options.apiKey ||
276
- (typeof window !== "undefined" ? window.CALLAI_API_KEY : null);
277
- // Validate API key with original error message
211
+ const apiKey = options.apiKey || callAiEnv.CALLAI_API_KEY;
278
212
  if (!apiKey) {
279
213
  throw new Error("API key is required. Provide it via options.apiKey or set window.CALLAI_API_KEY");
280
214
  }
281
- // Validate and process input parameters
282
215
  if (!prompt || (typeof prompt !== "string" && !Array.isArray(prompt))) {
283
216
  throw new Error(`Invalid prompt: ${prompt}. Must be a string or an array of message objects.`);
284
217
  }
285
- // Convert simple string prompts to message array format
286
- const messages = Array.isArray(prompt)
287
- ? prompt
288
- : [{ role: "user", content: prompt }];
289
- // Validate message structure if array provided
218
+ const messages = Array.isArray(prompt) ? prompt : [{ role: "user", content: prompt }];
290
219
  if (Array.isArray(prompt)) {
291
220
  for (const message of prompt) {
292
221
  if (!message.role || !message.content) {
293
222
  throw new Error(`Invalid message format. Each message must have 'role' and 'content' properties. Received: ${JSON.stringify(message)}`);
294
223
  }
295
- if (typeof message.role !== "string" ||
296
- (typeof message.content !== "string" && !Array.isArray(message.content))) {
224
+ if (typeof message.role !== "string" || (typeof message.content !== "string" && !Array.isArray(message.content))) {
297
225
  throw new Error(`Invalid message format. 'role' must be a string and 'content' must be a string or array. Received role: ${typeof message.role}, content: ${typeof message.content}`);
298
226
  }
299
227
  }
300
228
  }
301
- // If provider-specific options are given, check for conflicts
302
- if (options.provider &&
303
- options.provider !== "auto" &&
304
- options.model &&
305
- !options.model.startsWith(options.provider + "/")) {
229
+ if (options.provider && options.provider !== "auto" && options.model && !options.model.startsWith(options.provider + "/")) {
306
230
  console.warn(`[callAi:${PACKAGE_VERSION}] WARNING: Specified provider '${options.provider}' doesn't match model '${options.model}'. Using model as specified.`);
307
231
  }
308
- // Return the validated parameters including API key
309
232
  return {
310
233
  messages,
311
234
  apiKey,
312
235
  };
313
236
  }
237
+ export { callAi, bufferStreamingResults, createBackwardCompatStreamingProxy, prepareRequestParams, PACKAGE_VERSION };
238
+ //# sourceMappingURL=api-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-core.js","sourceRoot":"","sources":["../jsr/api-core.ts"],"names":[],"mappings":"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"}
package/api.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { CallAIOptions, Message, StreamResponse } from "./types.js";
2
+ import { getMeta } from "./response-metadata.js";
3
+ export { getMeta };
4
+ export declare function callAi(prompt: string | Message[], options?: CallAIOptions): Promise<string | StreamResponse>;