modelfusion 0.42.0 → 0.43.0
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/README.md +44 -2
- package/guard/fixStructure.cjs +21 -0
- package/guard/fixStructure.d.ts +10 -0
- package/guard/fixStructure.js +17 -0
- package/guard/guard.cjs +69 -0
- package/guard/guard.d.ts +28 -0
- package/guard/guard.js +65 -0
- package/guard/index.cjs +18 -0
- package/guard/index.d.ts +2 -0
- package/guard/index.js +2 -0
- package/index.cjs +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/model-function/generate-structure/StructureFromTextGenerationModel.cjs +15 -4
- package/model-function/generate-structure/StructureFromTextGenerationModel.d.ts +2 -1
- package/model-function/generate-structure/StructureFromTextGenerationModel.js +15 -4
- package/model-function/generate-structure/StructureGenerationModel.d.ts +2 -1
- package/model-function/generate-structure/StructureOrTextGenerationModel.d.ts +2 -0
- package/model-function/generate-structure/StructureParseError.cjs +34 -0
- package/model-function/generate-structure/StructureParseError.d.ts +10 -0
- package/model-function/generate-structure/StructureParseError.js +30 -0
- package/model-function/generate-structure/StructureValidationError.cjs +10 -3
- package/model-function/generate-structure/StructureValidationError.d.ts +3 -1
- package/model-function/generate-structure/StructureValidationError.js +10 -3
- package/model-function/generate-structure/generateStructure.cjs +2 -1
- package/model-function/generate-structure/generateStructure.js +2 -1
- package/model-function/generate-structure/generateStructureOrText.cjs +1 -0
- package/model-function/generate-structure/generateStructureOrText.js +1 -0
- package/model-function/index.cjs +1 -0
- package/model-function/index.d.ts +1 -0
- package/model-function/index.js +1 -0
- package/model-provider/openai/chat/OpenAIChatModel.cjs +47 -20
- package/model-provider/openai/chat/OpenAIChatModel.d.ts +36 -2
- package/model-provider/openai/chat/OpenAIChatModel.js +47 -20
- package/package.json +1 -1
package/README.md
CHANGED
@@ -19,8 +19,9 @@ ModelFusion is a library for building AI apps, chatbots, and agents. It provides
|
|
19
19
|
|
20
20
|
- **Multimodal Support**: Beyond just LLMs, ModelFusion encompasses a diverse array of models including text generation, text-to-speech, speech-to-text, and image generation, allowing you to build multifaceted AI applications with ease.
|
21
21
|
- **Flexibility and control**: AI application development can be complex and unique to each project. With ModelFusion, you have complete control over the prompts and model settings, and you can access the raw responses from the models quickly to build what you need.
|
22
|
-
- **Type inference and validation**: ModelFusion uses TypeScript and [Zod](https://github.com/colinhacks/zod)
|
23
|
-
- **
|
22
|
+
- **Type inference and validation**: ModelFusion uses TypeScript to infer types wherever possible and to validate model responses. By default, [Zod](https://github.com/colinhacks/zod) is used for type validation, but you can also use other libraries.
|
23
|
+
- **Guards**: ModelFusion provides a guard function that you can use to implement retry on error, redacting and changing reponses, etc.
|
24
|
+
- **Integrated support features**: Essential features like **observability**, logging, retries, throttling, tracing, and error handling are built-in, helping you focus more on building your application.
|
24
25
|
|
25
26
|
## Quick Install
|
26
27
|
|
@@ -454,6 +455,43 @@ const retrievedTexts = await retrieve(
|
|
454
455
|
|
455
456
|
Available Vector Stores: [Memory](https://modelfusion.dev/integration/vector-index/memory), [Pinecone](https://modelfusion.dev/integration/vector-index/pinecone)
|
456
457
|
|
458
|
+
### Guards
|
459
|
+
|
460
|
+
[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.
|
461
|
+
|
462
|
+
#### Retry structure parsing on error:
|
463
|
+
|
464
|
+
```ts
|
465
|
+
const result = await guard(
|
466
|
+
(input) =>
|
467
|
+
generateStructure(
|
468
|
+
new OpenAIChatModel({
|
469
|
+
// ...
|
470
|
+
}),
|
471
|
+
new ZodStructureDefinition({
|
472
|
+
// ...
|
473
|
+
}),
|
474
|
+
input
|
475
|
+
),
|
476
|
+
[
|
477
|
+
// ...
|
478
|
+
],
|
479
|
+
[
|
480
|
+
fixStructure({
|
481
|
+
modifyInputForRetry: async ({ input, error }) => [
|
482
|
+
...input,
|
483
|
+
OpenAIChatMessage.functionCall(null, {
|
484
|
+
name: error.structureName,
|
485
|
+
arguments: error.valueText,
|
486
|
+
}),
|
487
|
+
OpenAIChatMessage.user(error.message),
|
488
|
+
OpenAIChatMessage.user("Please fix the error and try again."),
|
489
|
+
],
|
490
|
+
}),
|
491
|
+
]
|
492
|
+
);
|
493
|
+
```
|
494
|
+
|
457
495
|
### Observability
|
458
496
|
|
459
497
|
Integrations: [Helicone](https://modelfusion.dev/integration/observability/helicone)
|
@@ -560,3 +598,7 @@ Extracts information about a topic from a PDF and writes a tweet in your own sty
|
|
560
598
|
### [Contributing Guide](https://github.com/lgrammel/modelfusion/blob/main/CONTRIBUTING.md)
|
561
599
|
|
562
600
|
Read the [ModelFusion contributing guide](https://github.com/lgrammel/modelfusion/blob/main/CONTRIBUTING.md) to learn about the development process, how to propose bugfixes and improvements, and how to build and test your changes.
|
601
|
+
|
602
|
+
```
|
603
|
+
|
604
|
+
```
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.fixStructure = void 0;
|
4
|
+
const StructureParseError_js_1 = require("../model-function/generate-structure/StructureParseError.cjs");
|
5
|
+
const StructureValidationError_js_1 = require("../model-function/generate-structure/StructureValidationError.cjs");
|
6
|
+
const fixStructure = ({ modifyInputForRetry }) => async (result) => {
|
7
|
+
if (result.type === "error" &&
|
8
|
+
(result.error instanceof StructureValidationError_js_1.StructureValidationError ||
|
9
|
+
result.error instanceof StructureParseError_js_1.StructureParseError)) {
|
10
|
+
return {
|
11
|
+
action: "retry",
|
12
|
+
input: await modifyInputForRetry({
|
13
|
+
type: "error",
|
14
|
+
input: result.input,
|
15
|
+
error: result.error,
|
16
|
+
}),
|
17
|
+
};
|
18
|
+
}
|
19
|
+
return undefined;
|
20
|
+
};
|
21
|
+
exports.fixStructure = fixStructure;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { StructureParseError } from "../model-function/generate-structure/StructureParseError.js";
|
2
|
+
import { StructureValidationError } from "../model-function/generate-structure/StructureValidationError.js";
|
3
|
+
import { Guard } from "./guard.js";
|
4
|
+
export declare const fixStructure: <INPUT, OUTPUT>(options: {
|
5
|
+
modifyInputForRetry: (options: {
|
6
|
+
type: "error";
|
7
|
+
input: INPUT;
|
8
|
+
error: StructureValidationError | StructureParseError;
|
9
|
+
}) => PromiseLike<INPUT>;
|
10
|
+
}) => Guard<INPUT, OUTPUT>;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { StructureParseError } from "../model-function/generate-structure/StructureParseError.js";
|
2
|
+
import { StructureValidationError } from "../model-function/generate-structure/StructureValidationError.js";
|
3
|
+
export const fixStructure = ({ modifyInputForRetry }) => async (result) => {
|
4
|
+
if (result.type === "error" &&
|
5
|
+
(result.error instanceof StructureValidationError ||
|
6
|
+
result.error instanceof StructureParseError)) {
|
7
|
+
return {
|
8
|
+
action: "retry",
|
9
|
+
input: await modifyInputForRetry({
|
10
|
+
type: "error",
|
11
|
+
input: result.input,
|
12
|
+
error: result.error,
|
13
|
+
}),
|
14
|
+
};
|
15
|
+
}
|
16
|
+
return undefined;
|
17
|
+
};
|
package/guard/guard.cjs
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.guard = void 0;
|
4
|
+
async function guard(execute, input, guards, options) {
|
5
|
+
const maxRetries = options?.maxRetries ?? 1;
|
6
|
+
let attempts = 0;
|
7
|
+
while (attempts <= maxRetries) {
|
8
|
+
let result;
|
9
|
+
try {
|
10
|
+
result = {
|
11
|
+
type: "value",
|
12
|
+
input,
|
13
|
+
output: await execute(input),
|
14
|
+
};
|
15
|
+
}
|
16
|
+
catch (error) {
|
17
|
+
result = {
|
18
|
+
type: "error",
|
19
|
+
input,
|
20
|
+
error,
|
21
|
+
};
|
22
|
+
}
|
23
|
+
let isValid = true;
|
24
|
+
for (const guard of guards) {
|
25
|
+
const guardResult = await guard(result);
|
26
|
+
if (guardResult === undefined) {
|
27
|
+
continue;
|
28
|
+
}
|
29
|
+
switch (guardResult.action) {
|
30
|
+
case "passThrough": {
|
31
|
+
break;
|
32
|
+
}
|
33
|
+
case "retry": {
|
34
|
+
input = guardResult.input;
|
35
|
+
isValid = false;
|
36
|
+
break;
|
37
|
+
}
|
38
|
+
case "return": {
|
39
|
+
result = {
|
40
|
+
type: "value",
|
41
|
+
input,
|
42
|
+
output: guardResult.output,
|
43
|
+
};
|
44
|
+
break;
|
45
|
+
}
|
46
|
+
case "throwError": {
|
47
|
+
result = {
|
48
|
+
type: "error",
|
49
|
+
input,
|
50
|
+
error: guardResult.error,
|
51
|
+
};
|
52
|
+
break;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
if (isValid) {
|
57
|
+
if (result.type === "value") {
|
58
|
+
return result.output;
|
59
|
+
}
|
60
|
+
else {
|
61
|
+
throw result.error;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
attempts++;
|
65
|
+
}
|
66
|
+
throw new Error(`Maximum retry attempts of ${maxRetries} reached ` +
|
67
|
+
`without producing a valid output or handling an error after ${attempts} attempts.`);
|
68
|
+
}
|
69
|
+
exports.guard = guard;
|
package/guard/guard.d.ts
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
type OutputResult<INPUT, OUTPUT> = {
|
2
|
+
type: "value";
|
3
|
+
input: INPUT;
|
4
|
+
output: OUTPUT;
|
5
|
+
error?: undefined;
|
6
|
+
} | {
|
7
|
+
type: "error";
|
8
|
+
input: INPUT;
|
9
|
+
output?: undefined;
|
10
|
+
error: unknown;
|
11
|
+
};
|
12
|
+
export type OutputValidator<INPUT, OUTPUT> = ({ type, input, output, error, }: OutputResult<INPUT, OUTPUT>) => PromiseLike<boolean>;
|
13
|
+
export type Guard<INPUT, OUTPUT> = ({ type, input, output, error, }: OutputResult<INPUT, OUTPUT>) => PromiseLike<{
|
14
|
+
action: "retry";
|
15
|
+
input: INPUT;
|
16
|
+
} | {
|
17
|
+
action: "return";
|
18
|
+
output: OUTPUT;
|
19
|
+
} | {
|
20
|
+
action: "throwError";
|
21
|
+
error: unknown;
|
22
|
+
} | {
|
23
|
+
action: "passThrough";
|
24
|
+
} | undefined>;
|
25
|
+
export declare function guard<INPUT, OUTPUT>(execute: (input: INPUT) => PromiseLike<OUTPUT>, input: INPUT, guards: Array<Guard<INPUT, OUTPUT>>, options?: {
|
26
|
+
maxRetries: number;
|
27
|
+
}): Promise<OUTPUT | undefined>;
|
28
|
+
export {};
|
package/guard/guard.js
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
export async function guard(execute, input, guards, options) {
|
2
|
+
const maxRetries = options?.maxRetries ?? 1;
|
3
|
+
let attempts = 0;
|
4
|
+
while (attempts <= maxRetries) {
|
5
|
+
let result;
|
6
|
+
try {
|
7
|
+
result = {
|
8
|
+
type: "value",
|
9
|
+
input,
|
10
|
+
output: await execute(input),
|
11
|
+
};
|
12
|
+
}
|
13
|
+
catch (error) {
|
14
|
+
result = {
|
15
|
+
type: "error",
|
16
|
+
input,
|
17
|
+
error,
|
18
|
+
};
|
19
|
+
}
|
20
|
+
let isValid = true;
|
21
|
+
for (const guard of guards) {
|
22
|
+
const guardResult = await guard(result);
|
23
|
+
if (guardResult === undefined) {
|
24
|
+
continue;
|
25
|
+
}
|
26
|
+
switch (guardResult.action) {
|
27
|
+
case "passThrough": {
|
28
|
+
break;
|
29
|
+
}
|
30
|
+
case "retry": {
|
31
|
+
input = guardResult.input;
|
32
|
+
isValid = false;
|
33
|
+
break;
|
34
|
+
}
|
35
|
+
case "return": {
|
36
|
+
result = {
|
37
|
+
type: "value",
|
38
|
+
input,
|
39
|
+
output: guardResult.output,
|
40
|
+
};
|
41
|
+
break;
|
42
|
+
}
|
43
|
+
case "throwError": {
|
44
|
+
result = {
|
45
|
+
type: "error",
|
46
|
+
input,
|
47
|
+
error: guardResult.error,
|
48
|
+
};
|
49
|
+
break;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
if (isValid) {
|
54
|
+
if (result.type === "value") {
|
55
|
+
return result.output;
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
throw result.error;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
attempts++;
|
62
|
+
}
|
63
|
+
throw new Error(`Maximum retry attempts of ${maxRetries} reached ` +
|
64
|
+
`without producing a valid output or handling an error after ${attempts} attempts.`);
|
65
|
+
}
|
package/guard/index.cjs
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./fixStructure.cjs"), exports);
|
18
|
+
__exportStar(require("./guard.cjs"), exports);
|
package/guard/index.d.ts
ADDED
package/guard/index.js
ADDED
package/index.cjs
CHANGED
@@ -18,6 +18,7 @@ __exportStar(require("./composed-function/index.cjs"), exports);
|
|
18
18
|
__exportStar(require("./core/index.cjs"), exports);
|
19
19
|
__exportStar(require("./cost/index.cjs"), exports);
|
20
20
|
__exportStar(require("./event-source/index.cjs"), exports);
|
21
|
+
__exportStar(require("./guard/index.cjs"), exports);
|
21
22
|
__exportStar(require("./model-function/index.cjs"), exports);
|
22
23
|
__exportStar(require("./model-provider/index.cjs"), exports);
|
23
24
|
__exportStar(require("./observability/index.cjs"), exports);
|
package/index.d.ts
CHANGED
@@ -2,6 +2,7 @@ export * from "./composed-function/index.js";
|
|
2
2
|
export * from "./core/index.js";
|
3
3
|
export * from "./cost/index.js";
|
4
4
|
export * from "./event-source/index.js";
|
5
|
+
export * from "./guard/index.js";
|
5
6
|
export * from "./model-function/index.js";
|
6
7
|
export * from "./model-provider/index.js";
|
7
8
|
export * from "./observability/index.js";
|
package/index.js
CHANGED
@@ -2,6 +2,7 @@ export * from "./composed-function/index.js";
|
|
2
2
|
export * from "./core/index.js";
|
3
3
|
export * from "./cost/index.js";
|
4
4
|
export * from "./event-source/index.js";
|
5
|
+
export * from "./guard/index.js";
|
5
6
|
export * from "./model-function/index.js";
|
6
7
|
export * from "./model-provider/index.js";
|
7
8
|
export * from "./observability/index.js";
|
@@ -2,6 +2,7 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.StructureFromTextGenerationModel = void 0;
|
4
4
|
const generateText_js_1 = require("../generate-text/generateText.cjs");
|
5
|
+
const StructureParseError_js_1 = require("./StructureParseError.cjs");
|
5
6
|
class StructureFromTextGenerationModel {
|
6
7
|
constructor({ model, format, }) {
|
7
8
|
Object.defineProperty(this, "model", {
|
@@ -30,10 +31,20 @@ class StructureFromTextGenerationModel {
|
|
30
31
|
}
|
31
32
|
async doGenerateStructure(structure, prompt, options) {
|
32
33
|
const { response, value } = await (0, generateText_js_1.generateText)(this.model, this.format.createPrompt(prompt, structure), options).asFullResponse();
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
try {
|
35
|
+
return {
|
36
|
+
response,
|
37
|
+
value: this.format.extractStructure(value),
|
38
|
+
valueText: value,
|
39
|
+
};
|
40
|
+
}
|
41
|
+
catch (error) {
|
42
|
+
throw new StructureParseError_js_1.StructureParseError({
|
43
|
+
structureName: structure.name,
|
44
|
+
valueText: value,
|
45
|
+
cause: error,
|
46
|
+
});
|
47
|
+
}
|
37
48
|
}
|
38
49
|
withSettings(additionalSettings) {
|
39
50
|
return new StructureFromTextGenerationModel({
|
@@ -18,7 +18,8 @@ export declare class StructureFromTextGenerationModel<PROMPT, MODEL extends Text
|
|
18
18
|
get settingsForEvent(): Partial<MODEL["settings"]>;
|
19
19
|
doGenerateStructure(structure: StructureDefinition<string, unknown>, prompt: PROMPT, options?: FunctionOptions): Promise<{
|
20
20
|
response: unknown;
|
21
|
-
|
21
|
+
value: unknown;
|
22
|
+
valueText: string;
|
22
23
|
}>;
|
23
24
|
withSettings(additionalSettings: Partial<MODEL["settings"]>): this;
|
24
25
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { generateText } from "../generate-text/generateText.js";
|
2
|
+
import { StructureParseError } from "./StructureParseError.js";
|
2
3
|
export class StructureFromTextGenerationModel {
|
3
4
|
constructor({ model, format, }) {
|
4
5
|
Object.defineProperty(this, "model", {
|
@@ -27,10 +28,20 @@ export class StructureFromTextGenerationModel {
|
|
27
28
|
}
|
28
29
|
async doGenerateStructure(structure, prompt, options) {
|
29
30
|
const { response, value } = await generateText(this.model, this.format.createPrompt(prompt, structure), options).asFullResponse();
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
try {
|
32
|
+
return {
|
33
|
+
response,
|
34
|
+
value: this.format.extractStructure(value),
|
35
|
+
valueText: value,
|
36
|
+
};
|
37
|
+
}
|
38
|
+
catch (error) {
|
39
|
+
throw new StructureParseError({
|
40
|
+
structureName: structure.name,
|
41
|
+
valueText: value,
|
42
|
+
cause: error,
|
43
|
+
});
|
44
|
+
}
|
34
45
|
}
|
35
46
|
withSettings(additionalSettings) {
|
36
47
|
return new StructureFromTextGenerationModel({
|
@@ -7,7 +7,8 @@ export interface StructureGenerationModelSettings extends ModelSettings {
|
|
7
7
|
export interface StructureGenerationModel<PROMPT, SETTINGS extends StructureGenerationModelSettings = StructureGenerationModelSettings> extends Model<SETTINGS> {
|
8
8
|
doGenerateStructure(structure: StructureDefinition<string, unknown>, prompt: PROMPT, options?: FunctionOptions): PromiseLike<{
|
9
9
|
response: unknown;
|
10
|
-
|
10
|
+
valueText: string;
|
11
|
+
value: unknown;
|
11
12
|
usage?: {
|
12
13
|
promptTokens: number;
|
13
14
|
completionTokens: number;
|
@@ -9,10 +9,12 @@ export interface StructureOrTextGenerationModel<PROMPT, SETTINGS extends Structu
|
|
9
9
|
structureAndText: {
|
10
10
|
structure: null;
|
11
11
|
value: null;
|
12
|
+
valueText: null;
|
12
13
|
text: string;
|
13
14
|
} | {
|
14
15
|
structure: string;
|
15
16
|
value: unknown;
|
17
|
+
valueText: string;
|
16
18
|
text: string | null;
|
17
19
|
};
|
18
20
|
usage?: {
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.StructureParseError = void 0;
|
4
|
+
const getErrorMessage_js_1 = require("../../util/getErrorMessage.cjs");
|
5
|
+
class StructureParseError extends Error {
|
6
|
+
constructor({ structureName, valueText, cause, }) {
|
7
|
+
super(`Structure parsing failed for '${structureName}'. ` +
|
8
|
+
`Value: ${valueText}.\n` +
|
9
|
+
`Error message: ${(0, getErrorMessage_js_1.getErrorMessage)(cause)}`);
|
10
|
+
Object.defineProperty(this, "structureName", {
|
11
|
+
enumerable: true,
|
12
|
+
configurable: true,
|
13
|
+
writable: true,
|
14
|
+
value: void 0
|
15
|
+
});
|
16
|
+
Object.defineProperty(this, "cause", {
|
17
|
+
enumerable: true,
|
18
|
+
configurable: true,
|
19
|
+
writable: true,
|
20
|
+
value: void 0
|
21
|
+
});
|
22
|
+
Object.defineProperty(this, "valueText", {
|
23
|
+
enumerable: true,
|
24
|
+
configurable: true,
|
25
|
+
writable: true,
|
26
|
+
value: void 0
|
27
|
+
});
|
28
|
+
this.name = "StructureParseError";
|
29
|
+
this.structureName = structureName;
|
30
|
+
this.cause = cause;
|
31
|
+
this.valueText = valueText;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
exports.StructureParseError = StructureParseError;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
export declare class StructureParseError extends Error {
|
2
|
+
readonly structureName: string;
|
3
|
+
readonly cause: unknown;
|
4
|
+
readonly valueText: string;
|
5
|
+
constructor({ structureName, valueText, cause, }: {
|
6
|
+
structureName: string;
|
7
|
+
valueText: string;
|
8
|
+
cause: unknown;
|
9
|
+
});
|
10
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { getErrorMessage } from "../../util/getErrorMessage.js";
|
2
|
+
export class StructureParseError extends Error {
|
3
|
+
constructor({ structureName, valueText, cause, }) {
|
4
|
+
super(`Structure parsing failed for '${structureName}'. ` +
|
5
|
+
`Value: ${valueText}.\n` +
|
6
|
+
`Error message: ${getErrorMessage(cause)}`);
|
7
|
+
Object.defineProperty(this, "structureName", {
|
8
|
+
enumerable: true,
|
9
|
+
configurable: true,
|
10
|
+
writable: true,
|
11
|
+
value: void 0
|
12
|
+
});
|
13
|
+
Object.defineProperty(this, "cause", {
|
14
|
+
enumerable: true,
|
15
|
+
configurable: true,
|
16
|
+
writable: true,
|
17
|
+
value: void 0
|
18
|
+
});
|
19
|
+
Object.defineProperty(this, "valueText", {
|
20
|
+
enumerable: true,
|
21
|
+
configurable: true,
|
22
|
+
writable: true,
|
23
|
+
value: void 0
|
24
|
+
});
|
25
|
+
this.name = "StructureParseError";
|
26
|
+
this.structureName = structureName;
|
27
|
+
this.cause = cause;
|
28
|
+
this.valueText = valueText;
|
29
|
+
}
|
30
|
+
}
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StructureValidationError = void 0;
|
4
4
|
const getErrorMessage_js_1 = require("../../util/getErrorMessage.cjs");
|
5
5
|
class StructureValidationError extends Error {
|
6
|
-
constructor({ structureName, value, cause, }) {
|
7
|
-
super(`Structure validation
|
8
|
-
`Value: ${
|
6
|
+
constructor({ structureName, value, valueText, cause, }) {
|
7
|
+
super(`Structure validation failed for '${structureName}'. ` +
|
8
|
+
`Value: ${valueText}.\n` +
|
9
9
|
`Error message: ${(0, getErrorMessage_js_1.getErrorMessage)(cause)}`);
|
10
10
|
Object.defineProperty(this, "structureName", {
|
11
11
|
enumerable: true,
|
@@ -19,6 +19,12 @@ class StructureValidationError extends Error {
|
|
19
19
|
writable: true,
|
20
20
|
value: void 0
|
21
21
|
});
|
22
|
+
Object.defineProperty(this, "valueText", {
|
23
|
+
enumerable: true,
|
24
|
+
configurable: true,
|
25
|
+
writable: true,
|
26
|
+
value: void 0
|
27
|
+
});
|
22
28
|
Object.defineProperty(this, "value", {
|
23
29
|
enumerable: true,
|
24
30
|
configurable: true,
|
@@ -29,6 +35,7 @@ class StructureValidationError extends Error {
|
|
29
35
|
this.structureName = structureName;
|
30
36
|
this.cause = cause;
|
31
37
|
this.value = value;
|
38
|
+
this.valueText = valueText;
|
32
39
|
}
|
33
40
|
}
|
34
41
|
exports.StructureValidationError = StructureValidationError;
|
@@ -1,10 +1,12 @@
|
|
1
1
|
export declare class StructureValidationError extends Error {
|
2
2
|
readonly structureName: string;
|
3
3
|
readonly cause: unknown;
|
4
|
+
readonly valueText: string;
|
4
5
|
readonly value: unknown;
|
5
|
-
constructor({ structureName, value, cause, }: {
|
6
|
+
constructor({ structureName, value, valueText, cause, }: {
|
6
7
|
structureName: string;
|
7
8
|
value: unknown;
|
9
|
+
valueText: string;
|
8
10
|
cause: unknown;
|
9
11
|
});
|
10
12
|
}
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { getErrorMessage } from "../../util/getErrorMessage.js";
|
2
2
|
export class StructureValidationError extends Error {
|
3
|
-
constructor({ structureName, value, cause, }) {
|
4
|
-
super(`Structure validation
|
5
|
-
`Value: ${
|
3
|
+
constructor({ structureName, value, valueText, cause, }) {
|
4
|
+
super(`Structure validation failed for '${structureName}'. ` +
|
5
|
+
`Value: ${valueText}.\n` +
|
6
6
|
`Error message: ${getErrorMessage(cause)}`);
|
7
7
|
Object.defineProperty(this, "structureName", {
|
8
8
|
enumerable: true,
|
@@ -16,6 +16,12 @@ export class StructureValidationError extends Error {
|
|
16
16
|
writable: true,
|
17
17
|
value: void 0
|
18
18
|
});
|
19
|
+
Object.defineProperty(this, "valueText", {
|
20
|
+
enumerable: true,
|
21
|
+
configurable: true,
|
22
|
+
writable: true,
|
23
|
+
value: void 0
|
24
|
+
});
|
19
25
|
Object.defineProperty(this, "value", {
|
20
26
|
enumerable: true,
|
21
27
|
configurable: true,
|
@@ -26,5 +32,6 @@ export class StructureValidationError extends Error {
|
|
26
32
|
this.structureName = structureName;
|
27
33
|
this.cause = cause;
|
28
34
|
this.value = value;
|
35
|
+
this.valueText = valueText;
|
29
36
|
}
|
30
37
|
}
|
@@ -15,11 +15,12 @@ function generateStructure(model, structureDefinition, prompt, options) {
|
|
15
15
|
options,
|
16
16
|
generateResponse: async (options) => {
|
17
17
|
const result = await model.doGenerateStructure(structureDefinition, expandedPrompt, options);
|
18
|
-
const structure = result.
|
18
|
+
const structure = result.value;
|
19
19
|
const parseResult = structureDefinition.schema.validate(structure);
|
20
20
|
if (!parseResult.success) {
|
21
21
|
throw new StructureValidationError_js_1.StructureValidationError({
|
22
22
|
structureName: structureDefinition.name,
|
23
|
+
valueText: result.valueText,
|
23
24
|
value: structure,
|
24
25
|
cause: parseResult.error,
|
25
26
|
});
|
@@ -12,11 +12,12 @@ export function generateStructure(model, structureDefinition, prompt, options) {
|
|
12
12
|
options,
|
13
13
|
generateResponse: async (options) => {
|
14
14
|
const result = await model.doGenerateStructure(structureDefinition, expandedPrompt, options);
|
15
|
-
const structure = result.
|
15
|
+
const structure = result.value;
|
16
16
|
const parseResult = structureDefinition.schema.validate(structure);
|
17
17
|
if (!parseResult.success) {
|
18
18
|
throw new StructureValidationError({
|
19
19
|
structureName: structureDefinition.name,
|
20
|
+
valueText: result.valueText,
|
20
21
|
value: structure,
|
21
22
|
cause: parseResult.error,
|
22
23
|
});
|
@@ -34,6 +34,7 @@ function generateStructureOrText(model, structureDefinitions, prompt, options) {
|
|
34
34
|
throw new StructureValidationError_js_1.StructureValidationError({
|
35
35
|
structureName: structure,
|
36
36
|
value,
|
37
|
+
valueText: result.structureAndText.valueText,
|
37
38
|
cause: parseResult.error,
|
38
39
|
});
|
39
40
|
}
|
package/model-function/index.cjs
CHANGED
@@ -34,6 +34,7 @@ __exportStar(require("./generate-structure/StructureFromTextGenerationModel.cjs"
|
|
34
34
|
__exportStar(require("./generate-structure/StructureGenerationEvent.cjs"), exports);
|
35
35
|
__exportStar(require("./generate-structure/StructureGenerationModel.cjs"), exports);
|
36
36
|
__exportStar(require("./generate-structure/StructureOrTextGenerationModel.cjs"), exports);
|
37
|
+
__exportStar(require("./generate-structure/StructureParseError.cjs"), exports);
|
37
38
|
__exportStar(require("./generate-structure/StructureStreamingEvent.cjs"), exports);
|
38
39
|
__exportStar(require("./generate-structure/StructureValidationError.cjs"), exports);
|
39
40
|
__exportStar(require("./generate-structure/generateStructure.cjs"), exports);
|
@@ -18,6 +18,7 @@ export * from "./generate-structure/StructureFromTextGenerationModel.js";
|
|
18
18
|
export * from "./generate-structure/StructureGenerationEvent.js";
|
19
19
|
export * from "./generate-structure/StructureGenerationModel.js";
|
20
20
|
export * from "./generate-structure/StructureOrTextGenerationModel.js";
|
21
|
+
export * from "./generate-structure/StructureParseError.js";
|
21
22
|
export * from "./generate-structure/StructureStreamingEvent.js";
|
22
23
|
export * from "./generate-structure/StructureValidationError.js";
|
23
24
|
export * from "./generate-structure/generateStructure.js";
|
package/model-function/index.js
CHANGED
@@ -18,6 +18,7 @@ export * from "./generate-structure/StructureFromTextGenerationModel.js";
|
|
18
18
|
export * from "./generate-structure/StructureGenerationEvent.js";
|
19
19
|
export * from "./generate-structure/StructureGenerationModel.js";
|
20
20
|
export * from "./generate-structure/StructureOrTextGenerationModel.js";
|
21
|
+
export * from "./generate-structure/StructureParseError.js";
|
21
22
|
export * from "./generate-structure/StructureStreamingEvent.js";
|
22
23
|
export * from "./generate-structure/StructureValidationError.js";
|
23
24
|
export * from "./generate-structure/generateStructure.js";
|
@@ -9,6 +9,7 @@ const zod_1 = __importDefault(require("zod"));
|
|
9
9
|
const callWithRetryAndThrottle_js_1 = require("../../../core/api/callWithRetryAndThrottle.cjs");
|
10
10
|
const postToApi_js_1 = require("../../../core/api/postToApi.cjs");
|
11
11
|
const AbstractModel_js_1 = require("../../../model-function/AbstractModel.cjs");
|
12
|
+
const StructureParseError_js_1 = require("../../../model-function/generate-structure/StructureParseError.cjs");
|
12
13
|
const parsePartialJson_js_1 = require("../../../model-function/generate-structure/parsePartialJson.cjs");
|
13
14
|
const PromptFormatTextStreamingModel_js_1 = require("../../../prompt/PromptFormatTextStreamingModel.cjs");
|
14
15
|
const OpenAIApiConfiguration_js_1 = require("../OpenAIApiConfiguration.cjs");
|
@@ -256,11 +257,22 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
256
257
|
},
|
257
258
|
],
|
258
259
|
});
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
260
|
+
const valueText = response.choices[0].message.function_call.arguments;
|
261
|
+
try {
|
262
|
+
return {
|
263
|
+
response,
|
264
|
+
valueText,
|
265
|
+
value: secure_json_parse_1.default.parse(valueText),
|
266
|
+
usage: this.extractUsage(response),
|
267
|
+
};
|
268
|
+
}
|
269
|
+
catch (error) {
|
270
|
+
throw new StructureParseError_js_1.StructureParseError({
|
271
|
+
structureName: structureDefinition.name,
|
272
|
+
valueText: valueText,
|
273
|
+
cause: error,
|
274
|
+
});
|
275
|
+
}
|
264
276
|
}
|
265
277
|
async doStreamStructure(structureDefinition, prompt, options) {
|
266
278
|
return this.callAPI(prompt, {
|
@@ -290,22 +302,37 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
290
302
|
const message = response.choices[0].message;
|
291
303
|
const content = message.content;
|
292
304
|
const functionCall = message.function_call;
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
305
|
+
if (functionCall == null) {
|
306
|
+
return {
|
307
|
+
response,
|
308
|
+
structureAndText: {
|
309
|
+
structure: null,
|
310
|
+
value: null,
|
311
|
+
valueText: null,
|
312
|
+
text: content ?? "",
|
313
|
+
},
|
314
|
+
usage: this.extractUsage(response),
|
303
315
|
};
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
316
|
+
}
|
317
|
+
try {
|
318
|
+
return {
|
319
|
+
response,
|
320
|
+
structureAndText: {
|
321
|
+
structure: functionCall.name,
|
322
|
+
value: secure_json_parse_1.default.parse(functionCall.arguments),
|
323
|
+
valueText: functionCall.arguments,
|
324
|
+
text: content,
|
325
|
+
},
|
326
|
+
usage: this.extractUsage(response),
|
327
|
+
};
|
328
|
+
}
|
329
|
+
catch (error) {
|
330
|
+
throw new StructureParseError_js_1.StructureParseError({
|
331
|
+
structureName: functionCall.name,
|
332
|
+
valueText: functionCall.arguments,
|
333
|
+
cause: error,
|
334
|
+
});
|
335
|
+
}
|
309
336
|
}
|
310
337
|
extractUsage(response) {
|
311
338
|
return {
|
@@ -220,7 +220,8 @@ export declare class OpenAIChatModel extends AbstractModel<OpenAIChatSettings> i
|
|
220
220
|
logprobs?: any;
|
221
221
|
}[];
|
222
222
|
};
|
223
|
-
|
223
|
+
valueText: string;
|
224
|
+
value: any;
|
224
225
|
usage: {
|
225
226
|
promptTokens: number;
|
226
227
|
completionTokens: number;
|
@@ -256,10 +257,43 @@ export declare class OpenAIChatModel extends AbstractModel<OpenAIChatSettings> i
|
|
256
257
|
structureAndText: {
|
257
258
|
structure: null;
|
258
259
|
value: null;
|
260
|
+
valueText: null;
|
259
261
|
text: string;
|
260
|
-
}
|
262
|
+
};
|
263
|
+
usage: {
|
264
|
+
promptTokens: number;
|
265
|
+
completionTokens: number;
|
266
|
+
totalTokens: number;
|
267
|
+
};
|
268
|
+
} | {
|
269
|
+
response: {
|
270
|
+
object: "chat.completion";
|
271
|
+
model: string;
|
272
|
+
usage: {
|
273
|
+
prompt_tokens: number;
|
274
|
+
completion_tokens: number;
|
275
|
+
total_tokens: number;
|
276
|
+
};
|
277
|
+
id: string;
|
278
|
+
created: number;
|
279
|
+
choices: {
|
280
|
+
message: {
|
281
|
+
content: string | null;
|
282
|
+
role: "assistant";
|
283
|
+
function_call?: {
|
284
|
+
name: string;
|
285
|
+
arguments: string;
|
286
|
+
} | undefined;
|
287
|
+
};
|
288
|
+
finish_reason: string;
|
289
|
+
index: number;
|
290
|
+
logprobs?: any;
|
291
|
+
}[];
|
292
|
+
};
|
293
|
+
structureAndText: {
|
261
294
|
structure: string;
|
262
295
|
value: any;
|
296
|
+
valueText: string;
|
263
297
|
text: string | null;
|
264
298
|
};
|
265
299
|
usage: {
|
@@ -3,6 +3,7 @@ import z from "zod";
|
|
3
3
|
import { callWithRetryAndThrottle } from "../../../core/api/callWithRetryAndThrottle.js";
|
4
4
|
import { createJsonResponseHandler, postJsonToApi, } from "../../../core/api/postToApi.js";
|
5
5
|
import { AbstractModel } from "../../../model-function/AbstractModel.js";
|
6
|
+
import { StructureParseError } from "../../../model-function/generate-structure/StructureParseError.js";
|
6
7
|
import { parsePartialJson } from "../../../model-function/generate-structure/parsePartialJson.js";
|
7
8
|
import { PromptFormatTextStreamingModel } from "../../../prompt/PromptFormatTextStreamingModel.js";
|
8
9
|
import { OpenAIApiConfiguration } from "../OpenAIApiConfiguration.js";
|
@@ -247,11 +248,22 @@ export class OpenAIChatModel extends AbstractModel {
|
|
247
248
|
},
|
248
249
|
],
|
249
250
|
});
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
251
|
+
const valueText = response.choices[0].message.function_call.arguments;
|
252
|
+
try {
|
253
|
+
return {
|
254
|
+
response,
|
255
|
+
valueText,
|
256
|
+
value: SecureJSON.parse(valueText),
|
257
|
+
usage: this.extractUsage(response),
|
258
|
+
};
|
259
|
+
}
|
260
|
+
catch (error) {
|
261
|
+
throw new StructureParseError({
|
262
|
+
structureName: structureDefinition.name,
|
263
|
+
valueText: valueText,
|
264
|
+
cause: error,
|
265
|
+
});
|
266
|
+
}
|
255
267
|
}
|
256
268
|
async doStreamStructure(structureDefinition, prompt, options) {
|
257
269
|
return this.callAPI(prompt, {
|
@@ -281,22 +293,37 @@ export class OpenAIChatModel extends AbstractModel {
|
|
281
293
|
const message = response.choices[0].message;
|
282
294
|
const content = message.content;
|
283
295
|
const functionCall = message.function_call;
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
296
|
+
if (functionCall == null) {
|
297
|
+
return {
|
298
|
+
response,
|
299
|
+
structureAndText: {
|
300
|
+
structure: null,
|
301
|
+
value: null,
|
302
|
+
valueText: null,
|
303
|
+
text: content ?? "",
|
304
|
+
},
|
305
|
+
usage: this.extractUsage(response),
|
294
306
|
};
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
307
|
+
}
|
308
|
+
try {
|
309
|
+
return {
|
310
|
+
response,
|
311
|
+
structureAndText: {
|
312
|
+
structure: functionCall.name,
|
313
|
+
value: SecureJSON.parse(functionCall.arguments),
|
314
|
+
valueText: functionCall.arguments,
|
315
|
+
text: content,
|
316
|
+
},
|
317
|
+
usage: this.extractUsage(response),
|
318
|
+
};
|
319
|
+
}
|
320
|
+
catch (error) {
|
321
|
+
throw new StructureParseError({
|
322
|
+
structureName: functionCall.name,
|
323
|
+
valueText: functionCall.arguments,
|
324
|
+
cause: error,
|
325
|
+
});
|
326
|
+
}
|
300
327
|
}
|
301
328
|
extractUsage(response) {
|
302
329
|
return {
|
package/package.json
CHANGED