@core-ai/core-ai 0.6.1 → 0.7.1

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/dist/index.d.ts CHANGED
@@ -315,6 +315,17 @@ declare class StructuredOutputValidationError extends StructuredOutputError {
315
315
 
316
316
  declare function defineTool(options: ToolDefinition): ToolDefinition;
317
317
 
318
+ /**
319
+ * Convert a Zod schema to a JSON Schema object using Zod 4's native
320
+ * `z.toJSONSchema()`.
321
+ */
322
+ declare function zodSchemaToJsonSchema(schema: z.ZodType): Record<string, unknown>;
323
+
324
+ declare function stripModelDateSuffix(modelId: string): string;
325
+
326
+ declare function asObject(value: unknown): Record<string, unknown>;
327
+ declare function safeParseJsonObject(json: string): Record<string, unknown>;
328
+
318
329
  type ResultToMessageOptions = {
319
330
  includeReasoning?: boolean;
320
331
  };
@@ -360,4 +371,4 @@ type GenerateImageParams = ImageGenerateOptions & {
360
371
  };
361
372
  declare function generateImage(params: GenerateImageParams): Promise<ImageGenerateResult>;
362
373
 
363
- export { type AssistantContentPart, type AssistantMessage, type AssistantTextPart, type BaseGenerateOptions, type ChatInputTokenDetails, type ChatModel, type ChatOutputTokenDetails, type ChatStream, type ChatUsage, type EmbedOptions, type EmbedProviderOptions, type EmbedResult, type EmbeddingModel, type EmbeddingUsage, type FilePart, type FinishReason, type GenerateObjectOptions, type GenerateObjectResult, type GenerateOptions, type GenerateProviderOptions, type GenerateResult, type GeneratedImage, type ImageGenerateOptions, type ImageGenerateResult, type ImageModel, type ImagePart, type ImageProviderOptions, LLMError, type Message, type ObjectStream, type ObjectStreamEvent, ProviderError, type ReasoningConfig, type ReasoningEffort, type ReasoningPart, StreamAbortedError, type StreamEvent, type StreamObjectOptions, StructuredOutputError, StructuredOutputNoObjectGeneratedError, StructuredOutputParseError, StructuredOutputValidationError, type SystemMessage, type TextPart, type ToolCall, type ToolCallPart, type ToolChoice, type ToolDefinition, type ToolResultMessage, type ToolSet, type UserContentPart, type UserMessage, assistantMessage, createChatStream, createObjectStream, defineTool, embed, generate, generateImage, generateObject, getProviderMetadata, resultToMessage, stream, streamObject };
374
+ export { type AssistantContentPart, type AssistantMessage, type AssistantTextPart, type BaseGenerateOptions, type ChatInputTokenDetails, type ChatModel, type ChatOutputTokenDetails, type ChatStream, type ChatUsage, type EmbedOptions, type EmbedProviderOptions, type EmbedResult, type EmbeddingModel, type EmbeddingUsage, type FilePart, type FinishReason, type GenerateObjectOptions, type GenerateObjectResult, type GenerateOptions, type GenerateProviderOptions, type GenerateResult, type GeneratedImage, type ImageGenerateOptions, type ImageGenerateResult, type ImageModel, type ImagePart, type ImageProviderOptions, LLMError, type Message, type ObjectStream, type ObjectStreamEvent, ProviderError, type ReasoningConfig, type ReasoningEffort, type ReasoningPart, StreamAbortedError, type StreamEvent, type StreamObjectOptions, StructuredOutputError, StructuredOutputNoObjectGeneratedError, StructuredOutputParseError, StructuredOutputValidationError, type SystemMessage, type TextPart, type ToolCall, type ToolCallPart, type ToolChoice, type ToolDefinition, type ToolResultMessage, type ToolSet, type UserContentPart, type UserMessage, asObject, assistantMessage, createChatStream, createObjectStream, defineTool, embed, generate, generateImage, generateObject, getProviderMetadata, resultToMessage, safeParseJsonObject, stream, streamObject, stripModelDateSuffix, zodSchemaToJsonSchema };
package/dist/index.js CHANGED
@@ -53,11 +53,39 @@ var StructuredOutputValidationError = class extends StructuredOutputError {
53
53
  };
54
54
 
55
55
  // src/tool.ts
56
- import { zodToJsonSchema } from "zod-to-json-schema";
57
56
  function defineTool(options) {
58
57
  return options;
59
58
  }
60
59
 
60
+ // src/json-schema.ts
61
+ import { z } from "zod";
62
+ function zodSchemaToJsonSchema(schema) {
63
+ return z.toJSONSchema(schema, {
64
+ io: "input"
65
+ });
66
+ }
67
+
68
+ // src/model-id.ts
69
+ var MODEL_DATE_SUFFIX_PATTERN = /-\d{8}$/;
70
+ function stripModelDateSuffix(modelId) {
71
+ return modelId.replace(MODEL_DATE_SUFFIX_PATTERN, "");
72
+ }
73
+
74
+ // src/provider-utils.ts
75
+ function asObject(value) {
76
+ if (value && typeof value === "object" && !Array.isArray(value)) {
77
+ return value;
78
+ }
79
+ return {};
80
+ }
81
+ function safeParseJsonObject(json) {
82
+ try {
83
+ return asObject(JSON.parse(json));
84
+ } catch {
85
+ return {};
86
+ }
87
+ }
88
+
61
89
  // src/result-to-message.ts
62
90
  function resultToMessage(result, options) {
63
91
  const includeReasoning = options?.includeReasoning ?? true;
@@ -104,26 +132,33 @@ function splitModelFromParams(params) {
104
132
  options
105
133
  };
106
134
  }
135
+ function callModelWithOptions(params, call) {
136
+ const { model, options } = splitModelFromParams(params);
137
+ return call(model, options);
138
+ }
107
139
 
108
140
  // src/generate.ts
109
141
  async function generate(params) {
110
142
  assertNonEmptyMessages(params.messages);
111
- const { model, options } = splitModelFromParams(params);
112
- return model.generate(options);
143
+ return callModelWithOptions(
144
+ params,
145
+ (model, options) => model.generate(options)
146
+ );
113
147
  }
114
148
 
115
149
  // src/generate-object.ts
116
150
  async function generateObject(params) {
117
151
  assertNonEmptyMessages(params.messages);
118
- const { model, options } = splitModelFromParams(params);
119
- return model.generateObject(options);
152
+ return callModelWithOptions(
153
+ params,
154
+ (model, options) => model.generateObject(options)
155
+ );
120
156
  }
121
157
 
122
158
  // src/stream-chat.ts
123
159
  async function stream(params) {
124
160
  assertNonEmptyMessages(params.messages);
125
- const { model, options } = splitModelFromParams(params);
126
- return model.stream(options);
161
+ return callModelWithOptions(params, (model, options) => model.stream(options));
127
162
  }
128
163
 
129
164
  // src/base-stream.ts
@@ -163,31 +198,31 @@ function createStream(options) {
163
198
  function cleanupSignalListener() {
164
199
  signal?.removeEventListener("abort", abortStream);
165
200
  }
166
- function settleCompleted(finalResult) {
201
+ function settleTerminalState(nextState) {
167
202
  if (terminalState.status !== "running") {
168
203
  return;
169
204
  }
170
- terminalState = {
171
- status: "completed",
172
- result: finalResult
173
- };
205
+ terminalState = nextState;
174
206
  cleanupSignalListener();
175
- resolveResult?.(finalResult);
207
+ if (nextState.status === "completed") {
208
+ resolveResult?.(nextState.result);
209
+ } else {
210
+ rejectResult?.(nextState.error);
211
+ }
176
212
  resolveEvents?.([...bufferedEvents]);
177
213
  notifyWaiters();
178
214
  }
215
+ function settleCompleted(finalResult) {
216
+ settleTerminalState({
217
+ status: "completed",
218
+ result: finalResult
219
+ });
220
+ }
179
221
  function settleRejected(error) {
180
- if (terminalState.status !== "running") {
181
- return;
182
- }
183
- terminalState = {
222
+ settleTerminalState({
184
223
  status: "rejected",
185
224
  error
186
- };
187
- cleanupSignalListener();
188
- rejectResult?.(error);
189
- resolveEvents?.([...bufferedEvents]);
190
- notifyWaiters();
225
+ });
191
226
  }
192
227
  function closeSourceIterator() {
193
228
  if (closeSourceIteratorPromise) {
@@ -241,6 +276,12 @@ function createStream(options) {
241
276
  }
242
277
  }
243
278
  void pump();
279
+ function getDoneResult() {
280
+ return {
281
+ done: true,
282
+ value: void 0
283
+ };
284
+ }
244
285
  return {
245
286
  [Symbol.asyncIterator]() {
246
287
  let index = 0;
@@ -248,17 +289,11 @@ function createStream(options) {
248
289
  return {
249
290
  async next() {
250
291
  if (closed) {
251
- return {
252
- done: true,
253
- value: void 0
254
- };
292
+ return getDoneResult();
255
293
  }
256
294
  while (!closed && index >= bufferedEvents.length) {
257
295
  if (terminalState.status === "completed") {
258
- return {
259
- done: true,
260
- value: void 0
261
- };
296
+ return getDoneResult();
262
297
  }
263
298
  if (terminalState.status === "rejected") {
264
299
  throw terminalState.error;
@@ -266,10 +301,7 @@ function createStream(options) {
266
301
  await resolveWhenUpdated();
267
302
  }
268
303
  if (closed) {
269
- return {
270
- done: true,
271
- value: void 0
272
- };
304
+ return getDoneResult();
273
305
  }
274
306
  const value = bufferedEvents[index];
275
307
  index += 1;
@@ -281,10 +313,7 @@ function createStream(options) {
281
313
  async return() {
282
314
  closed = true;
283
315
  notifyWaiters();
284
- return {
285
- done: true,
286
- value: void 0
287
- };
316
+ return getDoneResult();
288
317
  }
289
318
  };
290
319
  },
@@ -296,8 +325,10 @@ function createStream(options) {
296
325
  // src/stream-object.ts
297
326
  async function streamObject(params) {
298
327
  assertNonEmptyMessages(params.messages);
299
- const { model, ...options } = params;
300
- return model.streamObject(options);
328
+ return callModelWithOptions(
329
+ params,
330
+ (model, options) => model.streamObject(options)
331
+ );
301
332
  }
302
333
  function createObjectStream(source, options = {}) {
303
334
  const { signal } = options;
@@ -423,6 +454,31 @@ function createChatStream(source, options = {}) {
423
454
  finishReason = event.finishReason;
424
455
  usage = event.usage;
425
456
  };
457
+ const collectFinalizedData = () => {
458
+ const contentSegments = [];
459
+ const reasoningSegments = [];
460
+ const toolCalls = [];
461
+ for (const part of parts) {
462
+ if (part.type === "text") {
463
+ contentSegments.push(part.text);
464
+ continue;
465
+ }
466
+ if (part.type === "reasoning") {
467
+ reasoningSegments.push(part.text);
468
+ continue;
469
+ }
470
+ if (part.type === "tool-call") {
471
+ toolCalls.push(part.toolCall);
472
+ }
473
+ }
474
+ const content = contentSegments.join("");
475
+ const reasoning = reasoningSegments.join("");
476
+ return {
477
+ content: content.length > 0 ? content : null,
478
+ reasoning: reasoning.length > 0 ? reasoning : null,
479
+ toolCalls
480
+ };
481
+ };
426
482
  return createStream({
427
483
  source: resolvedSource,
428
484
  signal,
@@ -453,17 +509,11 @@ function createChatStream(source, options = {}) {
453
509
  finalizeResult() {
454
510
  flushText();
455
511
  flushReasoning();
456
- const content = parts.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
457
- const reasoning = parts.flatMap(
458
- (part) => part.type === "reasoning" ? [part.text] : []
459
- ).join("");
460
- const toolCalls = parts.flatMap(
461
- (part) => part.type === "tool-call" ? [part.toolCall] : []
462
- );
512
+ const { content, reasoning, toolCalls } = collectFinalizedData();
463
513
  return {
464
514
  parts,
465
- content: content.length > 0 ? content : null,
466
- reasoning: reasoning.length > 0 ? reasoning : null,
515
+ content,
516
+ reasoning,
467
517
  toolCalls,
468
518
  finishReason,
469
519
  usage
@@ -480,15 +530,16 @@ function getProviderMetadata(providerMetadata, provider) {
480
530
  // src/embed.ts
481
531
  async function embed(params) {
482
532
  assertNonEmptyEmbedInput(params.input);
483
- const { model, options } = splitModelFromParams(params);
484
- return model.embed(options);
533
+ return callModelWithOptions(params, (model, options) => model.embed(options));
485
534
  }
486
535
 
487
536
  // src/generate-image.ts
488
537
  async function generateImage(params) {
489
538
  assertNonEmptyPrompt(params.prompt);
490
- const { model, options } = splitModelFromParams(params);
491
- return model.generate(options);
539
+ return callModelWithOptions(
540
+ params,
541
+ (model, options) => model.generate(options)
542
+ );
492
543
  }
493
544
  export {
494
545
  LLMError,
@@ -498,6 +549,7 @@ export {
498
549
  StructuredOutputNoObjectGeneratedError,
499
550
  StructuredOutputParseError,
500
551
  StructuredOutputValidationError,
552
+ asObject,
501
553
  assistantMessage,
502
554
  createChatStream,
503
555
  createObjectStream,
@@ -508,6 +560,9 @@ export {
508
560
  generateObject,
509
561
  getProviderMetadata,
510
562
  resultToMessage,
563
+ safeParseJsonObject,
511
564
  stream,
512
- streamObject
565
+ streamObject,
566
+ stripModelDateSuffix,
567
+ zodSchemaToJsonSchema
513
568
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@core-ai/core-ai",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "Type-safe LLM abstraction layer over native provider SDKs",
5
5
  "license": "MIT",
6
6
  "author": "Omnifact (https://omnifact.ai)",
@@ -43,8 +43,7 @@
43
43
  "test:watch": "vitest"
44
44
  },
45
45
  "dependencies": {
46
- "zod": "^3.25.0 || ^4.0.0",
47
- "zod-to-json-schema": "^3.25.1"
46
+ "zod": "^4.0.0"
48
47
  },
49
48
  "devDependencies": {
50
49
  "@core-ai/eslint-config": "*",