modelfusion 0.47.1 → 0.47.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 (92) hide show
  1. package/README.md +37 -36
  2. package/core/structure/Schema.d.ts +5 -5
  3. package/core/structure/UncheckedSchema.cjs +2 -2
  4. package/core/structure/UncheckedSchema.d.ts +2 -2
  5. package/core/structure/UncheckedSchema.js +2 -2
  6. package/core/structure/ZodSchema.cjs +2 -5
  7. package/core/structure/ZodSchema.d.ts +2 -2
  8. package/core/structure/ZodSchema.js +2 -5
  9. package/event-source/readEventSource.cjs +5 -8
  10. package/event-source/readEventSource.d.ts +1 -1
  11. package/event-source/readEventSource.js +5 -5
  12. package/event-source/readEventSourceStream.cjs +3 -6
  13. package/event-source/readEventSourceStream.js +3 -3
  14. package/guard/fixStructure.cjs +50 -0
  15. package/guard/fixStructure.d.ts +50 -0
  16. package/guard/fixStructure.js +50 -0
  17. package/guard/guard.d.ts +1 -1
  18. package/model-function/generate-structure/generateStructure.cjs +1 -1
  19. package/model-function/generate-structure/generateStructure.js +1 -1
  20. package/model-function/generate-structure/generateStructureOrText.cjs +1 -1
  21. package/model-function/generate-structure/generateStructureOrText.js +1 -1
  22. package/model-function/generate-structure/streamStructure.cjs +1 -1
  23. package/model-function/generate-structure/streamStructure.js +1 -1
  24. package/model-provider/anthropic/AnthropicError.cjs +7 -14
  25. package/model-provider/anthropic/AnthropicError.js +7 -11
  26. package/model-provider/anthropic/AnthropicTextGenerationModel.cjs +2 -15
  27. package/model-provider/anthropic/AnthropicTextGenerationModel.js +2 -12
  28. package/model-provider/automatic1111/Automatic1111Error.cjs +2 -5
  29. package/model-provider/automatic1111/Automatic1111Error.d.ts +1 -1
  30. package/model-provider/automatic1111/Automatic1111Error.js +2 -2
  31. package/model-provider/cohere/CohereError.cjs +2 -5
  32. package/model-provider/cohere/CohereError.js +2 -2
  33. package/model-provider/cohere/CohereTextEmbeddingModel.cjs +8 -11
  34. package/model-provider/cohere/CohereTextEmbeddingModel.d.ts +1 -1
  35. package/model-provider/cohere/CohereTextEmbeddingModel.js +1 -1
  36. package/model-provider/cohere/CohereTextGenerationModel.cjs +22 -21
  37. package/model-provider/cohere/CohereTextGenerationModel.js +22 -18
  38. package/model-provider/cohere/CohereTokenizer.cjs +12 -15
  39. package/model-provider/cohere/CohereTokenizer.d.ts +1 -1
  40. package/model-provider/cohere/CohereTokenizer.js +1 -1
  41. package/model-provider/huggingface/HuggingFaceError.cjs +7 -31
  42. package/model-provider/huggingface/HuggingFaceError.js +7 -28
  43. package/model-provider/huggingface/HuggingFaceImageDescriptionModel.cjs +3 -6
  44. package/model-provider/huggingface/HuggingFaceImageDescriptionModel.d.ts +1 -1
  45. package/model-provider/huggingface/HuggingFaceImageDescriptionModel.js +1 -1
  46. package/model-provider/huggingface/HuggingFaceTextEmbeddingModel.cjs +2 -5
  47. package/model-provider/huggingface/HuggingFaceTextEmbeddingModel.d.ts +1 -1
  48. package/model-provider/huggingface/HuggingFaceTextEmbeddingModel.js +1 -1
  49. package/model-provider/huggingface/HuggingFaceTextGenerationModel.cjs +3 -6
  50. package/model-provider/huggingface/HuggingFaceTextGenerationModel.d.ts +1 -1
  51. package/model-provider/huggingface/HuggingFaceTextGenerationModel.js +1 -1
  52. package/model-provider/llamacpp/LlamaCppError.cjs +7 -30
  53. package/model-provider/llamacpp/LlamaCppError.js +7 -27
  54. package/model-provider/llamacpp/LlamaCppTextEmbeddingModel.cjs +3 -6
  55. package/model-provider/llamacpp/LlamaCppTextEmbeddingModel.d.ts +1 -1
  56. package/model-provider/llamacpp/LlamaCppTextEmbeddingModel.js +1 -1
  57. package/model-provider/llamacpp/LlamaCppTextGenerationModel.cjs +53 -66
  58. package/model-provider/llamacpp/LlamaCppTextGenerationModel.d.ts +1 -1
  59. package/model-provider/llamacpp/LlamaCppTextGenerationModel.js +3 -13
  60. package/model-provider/llamacpp/LlamaCppTokenizer.cjs +3 -6
  61. package/model-provider/llamacpp/LlamaCppTokenizer.d.ts +1 -1
  62. package/model-provider/llamacpp/LlamaCppTokenizer.js +1 -1
  63. package/model-provider/openai/OpenAIError.cjs +2 -5
  64. package/model-provider/openai/OpenAIError.js +2 -2
  65. package/model-provider/openai/OpenAITextEmbeddingModel.cjs +11 -14
  66. package/model-provider/openai/OpenAITextEmbeddingModel.d.ts +1 -1
  67. package/model-provider/openai/OpenAITextEmbeddingModel.js +1 -1
  68. package/model-provider/openai/OpenAITextGenerationModel.cjs +26 -39
  69. package/model-provider/openai/OpenAITextGenerationModel.d.ts +1 -1
  70. package/model-provider/openai/OpenAITextGenerationModel.js +3 -13
  71. package/model-provider/openai/OpenAITranscriptionModel.cjs +20 -23
  72. package/model-provider/openai/OpenAITranscriptionModel.d.ts +1 -1
  73. package/model-provider/openai/OpenAITranscriptionModel.js +1 -1
  74. package/model-provider/openai/chat/OpenAIChatModel.cjs +21 -21
  75. package/model-provider/openai/chat/OpenAIChatModel.d.ts +1 -1
  76. package/model-provider/openai/chat/OpenAIChatModel.js +2 -2
  77. package/model-provider/openai/chat/OpenAIChatStreamIterable.cjs +2 -6
  78. package/model-provider/openai/chat/OpenAIChatStreamIterable.js +2 -3
  79. package/model-provider/stability/StabilityError.cjs +2 -5
  80. package/model-provider/stability/StabilityError.js +2 -2
  81. package/package.json +1 -1
  82. package/util/JSONParseError.cjs +33 -0
  83. package/util/JSONParseError.d.ts +9 -0
  84. package/util/JSONParseError.js +29 -0
  85. package/util/index.cjs +2 -0
  86. package/util/index.d.ts +2 -0
  87. package/util/index.js +2 -0
  88. package/util/parseJSON.cjs +67 -0
  89. package/util/parseJSON.d.ts +18 -0
  90. package/util/parseJSON.js +58 -0
  91. package/vector-index/memory/MemoryVectorIndex.cjs +7 -10
  92. package/vector-index/memory/MemoryVectorIndex.js +3 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ModelFusion
2
2
 
3
- > ### Build AI applications, chatbots, and agents with JavaScript and TypeScript.
3
+ > ### Build multi-modal AI apps, chatbots, and agents with JavaScript and TypeScript.
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/modelfusion?color=33cd56&logo=npm)](https://www.npmjs.com/package/modelfusion)
6
6
  [![MIT License](https://img.shields.io/github/license/lgrammel/modelfusion)](https://opensource.org/licenses/MIT)
@@ -360,6 +360,41 @@ const reconstructedText = await tokenizer.detokenize(tokens);
360
360
 
361
361
  Providers: [OpenAI](https://modelfusion.dev/integration/model-provider/openai), [Cohere](https://modelfusion.dev/integration/model-provider/cohere), [Llama.cpp](https://modelfusion.dev/integration/model-provider/llamacpp)
362
362
 
363
+ ### [Guards](https://modelfusion.dev/guide/guard)
364
+
365
+ Guard functions can be used to implement retry on error, redacting and changing reponses, etc.
366
+
367
+ #### Retry structure parsing on error
368
+
369
+ ```ts
370
+ const result = await guard(
371
+ (input) =>
372
+ generateStructure(
373
+ new OpenAIChatModel({
374
+ // ...
375
+ }),
376
+ new ZodStructureDefinition({
377
+ // ...
378
+ }),
379
+ input
380
+ ),
381
+ [
382
+ // ...
383
+ ],
384
+ fixStructure({
385
+ modifyInputForRetry: async ({ input, error }) => [
386
+ ...input,
387
+ OpenAIChatMessage.functionCall(null, {
388
+ name: error.structureName,
389
+ arguments: error.valueText,
390
+ }),
391
+ OpenAIChatMessage.user(error.message),
392
+ OpenAIChatMessage.user("Please fix the error and try again."),
393
+ ],
394
+ })
395
+ );
396
+ ```
397
+
363
398
  ### [Upserting and Retrieving Objects from Vector Indices](https://modelfusion.dev/guide/vector-index)
364
399
 
365
400
  ```ts
@@ -396,41 +431,6 @@ const retrievedTexts = await retrieve(
396
431
 
397
432
  Available Vector Stores: [Memory](https://modelfusion.dev/integration/vector-index/memory), [Pinecone](https://modelfusion.dev/integration/vector-index/pinecone)
398
433
 
399
- ### Guards
400
-
401
- [Guards](https://github.com/lgrammel/modelfusion/tree/main/examples/basic/src/guard) can be used to implement retry on error, redacting and changing reponses, etc.
402
-
403
- #### Retry structure parsing on error:
404
-
405
- ```ts
406
- const result = await guard(
407
- (input) =>
408
- generateStructure(
409
- new OpenAIChatModel({
410
- // ...
411
- }),
412
- new ZodStructureDefinition({
413
- // ...
414
- }),
415
- input
416
- ),
417
- [
418
- // ...
419
- ],
420
- fixStructure({
421
- modifyInputForRetry: async ({ input, error }) => [
422
- ...input,
423
- OpenAIChatMessage.functionCall(null, {
424
- name: error.structureName,
425
- arguments: error.valueText,
426
- }),
427
- OpenAIChatMessage.user(error.message),
428
- OpenAIChatMessage.user("Please fix the error and try again."),
429
- ],
430
- })
431
- );
432
- ```
433
-
434
434
  ### Prompt Formats
435
435
 
436
436
  Prompt formats let you use higher level prompt structures (such as instruction or chat prompts) for different models.
@@ -536,6 +536,7 @@ Integrations: [Helicone](https://modelfusion.dev/integration/observability/helic
536
536
  - [Describe Image](https://modelfusion.dev/guide/function/describe-image)
537
537
  - [Generate Image](https://modelfusion.dev/guide/function/generate-image)
538
538
  - [Prompt Format](https://modelfusion.dev/guide/function/generate-image/prompt-format)
539
+ - [Guards](https://modelfusion.dev/guide/guard)
539
540
  - [Tools](https://modelfusion.dev/guide/tools)
540
541
  - [Vector Indices](https://modelfusion.dev/guide/vector-index)
541
542
  - [Upsert](https://modelfusion.dev/guide/vector-index/upsert)
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Validates that the structure of `value` matches the structure of this schema.
2
+ * Validates that the structure of `data` matches the structure of this schema.
3
3
  */
4
4
  export interface Schema<STRUCTURE> {
5
5
  /**
6
- * Validates that the structure of `value` matches the structure of this schema,
7
- * and returns a typed version of value if it does.
6
+ * Validates that the structure of `data` matches the structure of this schema,
7
+ * and returns a typed version of data if it does.
8
8
  */
9
- validate(value: unknown): {
9
+ validate(data: unknown): {
10
10
  success: true;
11
- value: STRUCTURE;
11
+ data: STRUCTURE;
12
12
  } | {
13
13
  success: false;
14
14
  error: unknown;
@@ -16,8 +16,8 @@ class UncheckedSchema {
16
16
  value: void 0
17
17
  });
18
18
  }
19
- validate(value) {
20
- return { success: true, value: value };
19
+ validate(data) {
20
+ return { success: true, data: data };
21
21
  }
22
22
  getJsonSchema() {
23
23
  return this.jsonSchema;
@@ -2,9 +2,9 @@ import { Schema } from "./Schema.js";
2
2
  export declare class UncheckedSchema<STRUCTURE> implements Schema<STRUCTURE> {
3
3
  private readonly jsonSchema?;
4
4
  constructor(jsonSchema?: unknown);
5
- validate(value: unknown): {
5
+ validate(data: unknown): {
6
6
  success: true;
7
- value: STRUCTURE;
7
+ data: STRUCTURE;
8
8
  } | {
9
9
  success: false;
10
10
  error: unknown;
@@ -13,8 +13,8 @@ export class UncheckedSchema {
13
13
  value: void 0
14
14
  });
15
15
  }
16
- validate(value) {
17
- return { success: true, value: value };
16
+ validate(data) {
17
+ return { success: true, data: data };
18
18
  }
19
19
  getJsonSchema() {
20
20
  return this.jsonSchema;
@@ -18,11 +18,8 @@ class ZodSchema {
18
18
  });
19
19
  this.zodSchema = zodSchema;
20
20
  }
21
- validate(value) {
22
- const parseResult = this.zodSchema.safeParse(value);
23
- return parseResult.success
24
- ? { success: true, value: parseResult.data }
25
- : parseResult;
21
+ validate(data) {
22
+ return this.zodSchema.safeParse(data);
26
23
  }
27
24
  getJsonSchema() {
28
25
  return (0, zod_to_json_schema_1.zodToJsonSchema)(this.zodSchema);
@@ -3,9 +3,9 @@ import { Schema } from "./Schema.js";
3
3
  export declare class ZodSchema<STRUCTURE> implements Schema<STRUCTURE> {
4
4
  readonly zodSchema: z.Schema<STRUCTURE>;
5
5
  constructor(zodSchema: z.Schema<STRUCTURE>);
6
- validate(value: unknown): {
6
+ validate(data: unknown): {
7
7
  success: true;
8
- value: STRUCTURE;
8
+ data: STRUCTURE;
9
9
  } | {
10
10
  success: false;
11
11
  error: unknown;
@@ -15,11 +15,8 @@ export class ZodSchema {
15
15
  });
16
16
  this.zodSchema = zodSchema;
17
17
  }
18
- validate(value) {
19
- const parseResult = this.zodSchema.safeParse(value);
20
- return parseResult.success
21
- ? { success: true, value: parseResult.data }
22
- : parseResult;
18
+ validate(data) {
19
+ return this.zodSchema.safeParse(data);
23
20
  }
24
21
  getJsonSchema() {
25
22
  return zodToJsonSchema(this.zodSchema);
@@ -1,20 +1,17 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.readEventSource = void 0;
7
- const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
4
+ const parseJSON_js_1 = require("../util/parseJSON.cjs");
8
5
  function readEventSource({ url, schema, onEvent, onError = console.error, }) {
9
6
  const eventSource = new EventSource(url);
10
7
  eventSource.onmessage = (e) => {
11
8
  try {
12
- const validationResult = schema.validate(secure_json_parse_1.default.parse(e.data));
13
- if (!validationResult.success) {
14
- onError(validationResult.error, eventSource);
9
+ const parseResult = (0, parseJSON_js_1.safeParseJsonWithSchema)(e.data, schema);
10
+ if (!parseResult.success) {
11
+ onError(parseResult.error, eventSource);
15
12
  return;
16
13
  }
17
- onEvent(validationResult.value, eventSource);
14
+ onEvent(parseResult.data, eventSource);
18
15
  }
19
16
  catch (error) {
20
17
  onError(error, eventSource);
@@ -1,4 +1,4 @@
1
- import { Schema } from "../core/structure/Schema";
1
+ import { Schema } from "../core/structure/Schema.js";
2
2
  export declare function readEventSource<T>({ url, schema, onEvent, onError, }: {
3
3
  url: string;
4
4
  schema: Schema<T>;
@@ -1,14 +1,14 @@
1
- import SecureJSON from "secure-json-parse";
1
+ import { safeParseJsonWithSchema } from "../util/parseJSON.js";
2
2
  export function readEventSource({ url, schema, onEvent, onError = console.error, }) {
3
3
  const eventSource = new EventSource(url);
4
4
  eventSource.onmessage = (e) => {
5
5
  try {
6
- const validationResult = schema.validate(SecureJSON.parse(e.data));
7
- if (!validationResult.success) {
8
- onError(validationResult.error, eventSource);
6
+ const parseResult = safeParseJsonWithSchema(e.data, schema);
7
+ if (!parseResult.success) {
8
+ onError(parseResult.error, eventSource);
9
9
  return;
10
10
  }
11
- onEvent(validationResult.value, eventSource);
11
+ onEvent(parseResult.data, eventSource);
12
12
  }
13
13
  catch (error) {
14
14
  onError(error, eventSource);
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.readEventSourceStream = void 0;
7
- const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
4
+ const parseJSON_js_1 = require("../util/parseJSON.cjs");
8
5
  const AsyncQueue_js_1 = require("./AsyncQueue.cjs");
9
6
  const parseEventSourceStream_js_1 = require("./parseEventSourceStream.cjs");
10
7
  function readEventSourceStream({ stream, schema, errorHandler, }) {
@@ -14,12 +11,12 @@ function readEventSourceStream({ stream, schema, errorHandler, }) {
14
11
  .then(async (events) => {
15
12
  try {
16
13
  for await (const event of events) {
17
- const validationResult = schema.validate(secure_json_parse_1.default.parse(event.data));
14
+ const validationResult = (0, parseJSON_js_1.safeParseJsonWithSchema)(event.data, schema);
18
15
  if (!validationResult.success) {
19
16
  errorHandler?.(validationResult.error);
20
17
  continue;
21
18
  }
22
- queue.push(validationResult.value);
19
+ queue.push(validationResult.data);
23
20
  }
24
21
  }
25
22
  catch (error) {
@@ -1,4 +1,4 @@
1
- import SecureJSON from "secure-json-parse";
1
+ import { safeParseJsonWithSchema } from "../util/parseJSON.js";
2
2
  import { AsyncQueue } from "./AsyncQueue.js";
3
3
  import { parseEventSourceStream } from "./parseEventSourceStream.js";
4
4
  export function readEventSourceStream({ stream, schema, errorHandler, }) {
@@ -8,12 +8,12 @@ export function readEventSourceStream({ stream, schema, errorHandler, }) {
8
8
  .then(async (events) => {
9
9
  try {
10
10
  for await (const event of events) {
11
- const validationResult = schema.validate(SecureJSON.parse(event.data));
11
+ const validationResult = safeParseJsonWithSchema(event.data, schema);
12
12
  if (!validationResult.success) {
13
13
  errorHandler?.(validationResult.error);
14
14
  continue;
15
15
  }
16
- queue.push(validationResult.value);
16
+ queue.push(validationResult.data);
17
17
  }
18
18
  }
19
19
  catch (error) {
@@ -3,6 +3,56 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fixStructure = void 0;
4
4
  const StructureParseError_js_1 = require("../model-function/generate-structure/StructureParseError.cjs");
5
5
  const StructureValidationError_js_1 = require("../model-function/generate-structure/StructureValidationError.cjs");
6
+ /**
7
+ * Attempts to correct and retry structure generation when encountering parsing or validation errors.
8
+ *
9
+ * This function acts as a guard within the structure generation process. If the generation results in
10
+ * an error, identified as either a `StructureParseError` or `StructureValidationError`, the function
11
+ * triggers a retry mechanism. It uses the `modifyInputForRetry` method, provided via options, to adjust
12
+ * the input parameters, aiming to resolve the issue that caused the initial error. The process continues
13
+ * until a valid structure is generated, or it exhausts the predefined retry limits.
14
+ *
15
+ * @template INPUT - The expected format/type of the input data used for structure generation.
16
+ * @template OUTPUT - The expected format/type of the output data, i.e., the successfully generated structure.
17
+ *
18
+ * @param {Object} options - Configuration options for modifying the input before retrying structure generation.
19
+ * @param {function} options.modifyInputForRetry - A function that takes the error type, original input, and error object.
20
+ * It modifies the input data based on the error information, aiming to correct the issue for the retry attempt.
21
+ * This function must return a promise that resolves with the modified input.
22
+ *
23
+ * @returns {Guard<INPUT, OUTPUT>} A guard function that intercepts the structure generation process, checking for
24
+ * errors, and initiating retries by modifying the input parameters. The guard can trigger multiple retries
25
+ * if the issues persist. If the process succeeds, it returns the valid structure; otherwise, it returns
26
+ * undefined, indicating the exhaustion of retry attempts or a non-recoverable error.
27
+ *
28
+ * @example
29
+ * const result = await guard(
30
+ * (input) =>
31
+ * generateStructure(
32
+ * new OpenAIChatModel({
33
+ * // ...
34
+ * }),
35
+ * new ZodStructureDefinition({
36
+ * // ...
37
+ * }),
38
+ * input
39
+ * ),
40
+ * [
41
+ * // ...
42
+ * ],
43
+ * fixStructure({
44
+ * modifyInputForRetry: async ({ input, error }) => [
45
+ * ...input,
46
+ * OpenAIChatMessage.functionCall(null, {
47
+ * name: error.structureName,
48
+ * arguments: error.valueText,
49
+ * }),
50
+ * OpenAIChatMessage.user(error.message),
51
+ * OpenAIChatMessage.user("Please fix the error and try again."),
52
+ * ],
53
+ * })
54
+ * );
55
+ */
6
56
  const fixStructure = ({ modifyInputForRetry }) => async (result) => {
7
57
  if (result.type === "error" &&
8
58
  (result.error instanceof StructureValidationError_js_1.StructureValidationError ||
@@ -1,6 +1,56 @@
1
1
  import { StructureParseError } from "../model-function/generate-structure/StructureParseError.js";
2
2
  import { StructureValidationError } from "../model-function/generate-structure/StructureValidationError.js";
3
3
  import { Guard } from "./guard.js";
4
+ /**
5
+ * Attempts to correct and retry structure generation when encountering parsing or validation errors.
6
+ *
7
+ * This function acts as a guard within the structure generation process. If the generation results in
8
+ * an error, identified as either a `StructureParseError` or `StructureValidationError`, the function
9
+ * triggers a retry mechanism. It uses the `modifyInputForRetry` method, provided via options, to adjust
10
+ * the input parameters, aiming to resolve the issue that caused the initial error. The process continues
11
+ * until a valid structure is generated, or it exhausts the predefined retry limits.
12
+ *
13
+ * @template INPUT - The expected format/type of the input data used for structure generation.
14
+ * @template OUTPUT - The expected format/type of the output data, i.e., the successfully generated structure.
15
+ *
16
+ * @param {Object} options - Configuration options for modifying the input before retrying structure generation.
17
+ * @param {function} options.modifyInputForRetry - A function that takes the error type, original input, and error object.
18
+ * It modifies the input data based on the error information, aiming to correct the issue for the retry attempt.
19
+ * This function must return a promise that resolves with the modified input.
20
+ *
21
+ * @returns {Guard<INPUT, OUTPUT>} A guard function that intercepts the structure generation process, checking for
22
+ * errors, and initiating retries by modifying the input parameters. The guard can trigger multiple retries
23
+ * if the issues persist. If the process succeeds, it returns the valid structure; otherwise, it returns
24
+ * undefined, indicating the exhaustion of retry attempts or a non-recoverable error.
25
+ *
26
+ * @example
27
+ * const result = await guard(
28
+ * (input) =>
29
+ * generateStructure(
30
+ * new OpenAIChatModel({
31
+ * // ...
32
+ * }),
33
+ * new ZodStructureDefinition({
34
+ * // ...
35
+ * }),
36
+ * input
37
+ * ),
38
+ * [
39
+ * // ...
40
+ * ],
41
+ * fixStructure({
42
+ * modifyInputForRetry: async ({ input, error }) => [
43
+ * ...input,
44
+ * OpenAIChatMessage.functionCall(null, {
45
+ * name: error.structureName,
46
+ * arguments: error.valueText,
47
+ * }),
48
+ * OpenAIChatMessage.user(error.message),
49
+ * OpenAIChatMessage.user("Please fix the error and try again."),
50
+ * ],
51
+ * })
52
+ * );
53
+ */
4
54
  export declare const fixStructure: <INPUT, OUTPUT>(options: {
5
55
  modifyInputForRetry: (options: {
6
56
  type: "error";
@@ -1,5 +1,55 @@
1
1
  import { StructureParseError } from "../model-function/generate-structure/StructureParseError.js";
2
2
  import { StructureValidationError } from "../model-function/generate-structure/StructureValidationError.js";
3
+ /**
4
+ * Attempts to correct and retry structure generation when encountering parsing or validation errors.
5
+ *
6
+ * This function acts as a guard within the structure generation process. If the generation results in
7
+ * an error, identified as either a `StructureParseError` or `StructureValidationError`, the function
8
+ * triggers a retry mechanism. It uses the `modifyInputForRetry` method, provided via options, to adjust
9
+ * the input parameters, aiming to resolve the issue that caused the initial error. The process continues
10
+ * until a valid structure is generated, or it exhausts the predefined retry limits.
11
+ *
12
+ * @template INPUT - The expected format/type of the input data used for structure generation.
13
+ * @template OUTPUT - The expected format/type of the output data, i.e., the successfully generated structure.
14
+ *
15
+ * @param {Object} options - Configuration options for modifying the input before retrying structure generation.
16
+ * @param {function} options.modifyInputForRetry - A function that takes the error type, original input, and error object.
17
+ * It modifies the input data based on the error information, aiming to correct the issue for the retry attempt.
18
+ * This function must return a promise that resolves with the modified input.
19
+ *
20
+ * @returns {Guard<INPUT, OUTPUT>} A guard function that intercepts the structure generation process, checking for
21
+ * errors, and initiating retries by modifying the input parameters. The guard can trigger multiple retries
22
+ * if the issues persist. If the process succeeds, it returns the valid structure; otherwise, it returns
23
+ * undefined, indicating the exhaustion of retry attempts or a non-recoverable error.
24
+ *
25
+ * @example
26
+ * const result = await guard(
27
+ * (input) =>
28
+ * generateStructure(
29
+ * new OpenAIChatModel({
30
+ * // ...
31
+ * }),
32
+ * new ZodStructureDefinition({
33
+ * // ...
34
+ * }),
35
+ * input
36
+ * ),
37
+ * [
38
+ * // ...
39
+ * ],
40
+ * fixStructure({
41
+ * modifyInputForRetry: async ({ input, error }) => [
42
+ * ...input,
43
+ * OpenAIChatMessage.functionCall(null, {
44
+ * name: error.structureName,
45
+ * arguments: error.valueText,
46
+ * }),
47
+ * OpenAIChatMessage.user(error.message),
48
+ * OpenAIChatMessage.user("Please fix the error and try again."),
49
+ * ],
50
+ * })
51
+ * );
52
+ */
3
53
  export const fixStructure = ({ modifyInputForRetry }) => async (result) => {
4
54
  if (result.type === "error" &&
5
55
  (result.error instanceof StructureValidationError ||
package/guard/guard.d.ts CHANGED
@@ -22,7 +22,7 @@ export type Guard<INPUT, OUTPUT> = ({ type, input, output, error, }: OutputResul
22
22
  } | {
23
23
  action: "passThrough";
24
24
  } | undefined>;
25
- export declare function guard<INPUT, OUTPUT>(execute: (input: INPUT) => PromiseLike<OUTPUT>, input: INPUT, guards: Array<Guard<INPUT, OUTPUT>> | Guard<INPUT, OUTPUT>, options?: {
25
+ export declare function guard<INPUT, OUTPUT>(execute: (input: INPUT) => PromiseLike<OUTPUT>, input: INPUT, guards: Guard<INPUT, OUTPUT> | Array<Guard<INPUT, OUTPUT>>, options?: {
26
26
  maxRetries: number;
27
27
  }): Promise<OUTPUT | undefined>;
28
28
  export {};
@@ -26,7 +26,7 @@ function generateStructure(model, structureDefinition, prompt, options) {
26
26
  cause: parseResult.error,
27
27
  });
28
28
  }
29
- const value = parseResult.value;
29
+ const value = parseResult.data;
30
30
  return {
31
31
  response: result.response,
32
32
  extractedValue: value,
@@ -23,7 +23,7 @@ export function generateStructure(model, structureDefinition, prompt, options) {
23
23
  cause: parseResult.error,
24
24
  });
25
25
  }
26
- const value = parseResult.value;
26
+ const value = parseResult.data;
27
27
  return {
28
28
  response: result.response,
29
29
  extractedValue: value,
@@ -43,7 +43,7 @@ function generateStructureOrText(model, structureDefinitions, prompt, options) {
43
43
  response: result.response,
44
44
  extractedValue: {
45
45
  structure: structure,
46
- value: parseResult.value,
46
+ value: parseResult.data,
47
47
  text: text, // text is string | null, which is part of the response for schema values
48
48
  },
49
49
  usage: result.usage,
@@ -40,7 +40,7 @@ export function generateStructureOrText(model, structureDefinitions, prompt, opt
40
40
  response: result.response,
41
41
  extractedValue: {
42
42
  structure: structure,
43
- value: parseResult.value,
43
+ value: parseResult.data,
44
44
  text: text, // text is string | null, which is part of the response for schema values
45
45
  },
46
46
  usage: result.usage,
@@ -106,7 +106,7 @@ async function doStreamStructure(model, structureDefinition, prompt, options) {
106
106
  }
107
107
  yield {
108
108
  isComplete: true,
109
- value: parseResult.value,
109
+ value: parseResult.data,
110
110
  };
111
111
  const finishMetadata = {
112
112
  eventType: "finished",
@@ -102,7 +102,7 @@ async function doStreamStructure(model, structureDefinition, prompt, options) {
102
102
  }
103
103
  yield {
104
104
  isComplete: true,
105
- value: parseResult.value,
105
+ value: parseResult.data,
106
106
  };
107
107
  const finishMetadata = {
108
108
  eventType: "finished",
@@ -1,12 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.failedAnthropicCallResponseHandler = exports.AnthropicError = exports.anthropicErrorDataSchema = void 0;
7
- const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
8
4
  const zod_1 = require("zod");
9
5
  const ApiCallError_js_1 = require("../../core/api/ApiCallError.cjs");
6
+ const parseJSON_js_1 = require("../../util/parseJSON.cjs");
10
7
  exports.anthropicErrorDataSchema = zod_1.z.object({
11
8
  error: zod_1.z.object({
12
9
  type: zod_1.z.string(),
@@ -26,14 +23,10 @@ class AnthropicError extends ApiCallError_js_1.ApiCallError {
26
23
  }
27
24
  }
28
25
  exports.AnthropicError = AnthropicError;
29
- const failedAnthropicCallResponseHandler = async ({ response, url, requestBodyValues }) => {
30
- const responseBody = await response.text();
31
- const parsedError = exports.anthropicErrorDataSchema.parse(secure_json_parse_1.default.parse(responseBody));
32
- return new AnthropicError({
33
- url,
34
- requestBodyValues,
35
- statusCode: response.status,
36
- data: parsedError,
37
- });
38
- };
26
+ const failedAnthropicCallResponseHandler = async ({ response, url, requestBodyValues }) => new AnthropicError({
27
+ url,
28
+ requestBodyValues,
29
+ statusCode: response.status,
30
+ data: (0, parseJSON_js_1.parseJsonWithZod)(await response.text(), exports.anthropicErrorDataSchema),
31
+ });
39
32
  exports.failedAnthropicCallResponseHandler = failedAnthropicCallResponseHandler;
@@ -1,6 +1,6 @@
1
- import SecureJSON from "secure-json-parse";
2
1
  import { z } from "zod";
3
2
  import { ApiCallError } from "../../core/api/ApiCallError.js";
3
+ import { parseJsonWithZod } from "../../util/parseJSON.js";
4
4
  export const anthropicErrorDataSchema = z.object({
5
5
  error: z.object({
6
6
  type: z.string(),
@@ -19,13 +19,9 @@ export class AnthropicError extends ApiCallError {
19
19
  this.data = data;
20
20
  }
21
21
  }
22
- export const failedAnthropicCallResponseHandler = async ({ response, url, requestBodyValues }) => {
23
- const responseBody = await response.text();
24
- const parsedError = anthropicErrorDataSchema.parse(SecureJSON.parse(responseBody));
25
- return new AnthropicError({
26
- url,
27
- requestBodyValues,
28
- statusCode: response.status,
29
- data: parsedError,
30
- });
31
- };
22
+ export const failedAnthropicCallResponseHandler = async ({ response, url, requestBodyValues }) => new AnthropicError({
23
+ url,
24
+ requestBodyValues,
25
+ statusCode: response.status,
26
+ data: parseJsonWithZod(await response.text(), anthropicErrorDataSchema),
27
+ });
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.AnthropicTextGenerationResponseFormat = exports.AnthropicTextGenerationModel = exports.ANTHROPIC_TEXT_GENERATION_MODELS = void 0;
7
- const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
8
4
  const zod_1 = require("zod");
9
5
  const callWithRetryAndThrottle_js_1 = require("../../core/api/callWithRetryAndThrottle.cjs");
10
6
  const postToApi_js_1 = require("../../core/api/postToApi.cjs");
@@ -12,6 +8,7 @@ const AsyncQueue_js_1 = require("../../event-source/AsyncQueue.cjs");
12
8
  const parseEventSourceStream_js_1 = require("../../event-source/parseEventSourceStream.cjs");
13
9
  const AbstractModel_js_1 = require("../../model-function/AbstractModel.cjs");
14
10
  const PromptFormatTextStreamingModel_js_1 = require("../../model-function/generate-text/PromptFormatTextStreamingModel.cjs");
11
+ const parseJSON_js_1 = require("../../util/parseJSON.cjs");
15
12
  const AnthropicApiConfiguration_js_1 = require("./AnthropicApiConfiguration.cjs");
16
13
  const AnthropicError_js_1 = require("./AnthropicError.cjs");
17
14
  const AnthropicPromptFormat_js_1 = require("./AnthropicPromptFormat.cjs");
@@ -183,17 +180,7 @@ async function createAnthropicFullDeltaIterableQueue(stream) {
183
180
  continue;
184
181
  }
185
182
  const data = event.data;
186
- const json = secure_json_parse_1.default.parse(data);
187
- const parseResult = anthropicTextStreamingResponseSchema.safeParse(json);
188
- if (!parseResult.success) {
189
- queue.push({
190
- type: "error",
191
- error: parseResult.error,
192
- });
193
- queue.close();
194
- return;
195
- }
196
- const eventData = parseResult.data;
183
+ const eventData = (0, parseJSON_js_1.parseJsonWithZod)(data, anthropicTextStreamingResponseSchema);
197
184
  content += eventData.completion;
198
185
  queue.push({
199
186
  type: "delta",