@aigne/openai 0.8.2 → 0.9.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/CHANGELOG.md +16 -0
- package/README.md +0 -2
- package/lib/cjs/openai-chat-model.d.ts +1 -0
- package/lib/cjs/openai-chat-model.js +40 -19
- package/lib/dts/openai-chat-model.d.ts +1 -0
- package/lib/esm/openai-chat-model.d.ts +1 -0
- package/lib/esm/openai-chat-model.js +40 -19
- package/package.json +5 -3
- package/README.zh.md +0 -114
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.0](https://github.com/AIGNE-io/aigne-framework/compare/openai-v0.8.2...openai-v0.9.0) (2025-07-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **model:** reduce unnecessary LLM requests for structured output ([#241](https://github.com/AIGNE-io/aigne-framework/issues/241)) ([e28813c](https://github.com/AIGNE-io/aigne-framework/commit/e28813c021ed35c0251e198e2e007e2d746ab3d8))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @aigne/core bumped to 1.33.0
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @aigne/test-utils bumped to 0.5.5
|
|
18
|
+
|
|
3
19
|
## [0.8.2](https://github.com/AIGNE-io/aigne-framework/compare/openai-v0.8.1...openai-v0.8.2) (2025-07-09)
|
|
4
20
|
|
|
5
21
|
|
package/README.md
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/@aigne/openai)
|
|
7
7
|
[](https://github.com/AIGNE-io/aigne-framework/blob/main/LICENSE.md)
|
|
8
8
|
|
|
9
|
-
**English** | [中文](README.zh.md)
|
|
10
|
-
|
|
11
9
|
AIGNE OpenAI SDK for integrating with OpenAI's GPT models and API services within the [AIGNE Framework](https://github.com/AIGNE-io/aigne-framework).
|
|
12
10
|
|
|
13
11
|
## Introduction
|
|
@@ -139,6 +139,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
139
139
|
* @returns The generated response
|
|
140
140
|
*/
|
|
141
141
|
process(input: ChatModelInput): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
142
|
+
private ajv;
|
|
142
143
|
private _process;
|
|
143
144
|
private getParallelToolCalls;
|
|
144
145
|
protected getRunMessages(input: ChatModelInput): Promise<ChatCompletionMessageParam[]>;
|
|
@@ -8,11 +8,13 @@ exports.contentsFromInputMessages = contentsFromInputMessages;
|
|
|
8
8
|
exports.toolsFromInputTools = toolsFromInputTools;
|
|
9
9
|
exports.jsonSchemaToOpenAIJsonSchema = jsonSchemaToOpenAIJsonSchema;
|
|
10
10
|
const core_1 = require("@aigne/core");
|
|
11
|
-
const
|
|
11
|
+
const logger_js_1 = require("@aigne/core/utils/logger.js");
|
|
12
12
|
const model_utils_js_1 = require("@aigne/core/utils/model-utils.js");
|
|
13
13
|
const prompts_js_1 = require("@aigne/core/utils/prompts.js");
|
|
14
14
|
const stream_utils_js_1 = require("@aigne/core/utils/stream-utils.js");
|
|
15
15
|
const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
|
|
16
|
+
const ajv_1 = require("ajv");
|
|
17
|
+
const jaison_1 = __importDefault(require("jaison"));
|
|
16
18
|
const nanoid_1 = require("nanoid");
|
|
17
19
|
const openai_1 = __importDefault(require("openai"));
|
|
18
20
|
const zod_1 = require("zod");
|
|
@@ -102,6 +104,7 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
102
104
|
process(input) {
|
|
103
105
|
return this._process(input);
|
|
104
106
|
}
|
|
107
|
+
ajv = new ajv_1.Ajv();
|
|
105
108
|
async _process(input) {
|
|
106
109
|
const messages = await this.getRunMessages(input);
|
|
107
110
|
const body = {
|
|
@@ -118,6 +121,11 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
118
121
|
},
|
|
119
122
|
stream: true,
|
|
120
123
|
};
|
|
124
|
+
// For models that do not support tools use with JSON schema in same request,
|
|
125
|
+
// so we need to handle the case where tools are not used and responseFormat is json
|
|
126
|
+
if (!input.tools?.length && input.responseFormat?.type === "json_schema") {
|
|
127
|
+
return await this.requestStructuredOutput(body, input.responseFormat);
|
|
128
|
+
}
|
|
121
129
|
const { jsonMode, responseFormat } = await this.getRunResponseFormat(input);
|
|
122
130
|
const stream = (await this.client.chat.completions.create({
|
|
123
131
|
...body,
|
|
@@ -132,14 +140,18 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
132
140
|
return await this.extractResultFromStream(stream, false, true);
|
|
133
141
|
}
|
|
134
142
|
const result = await this.extractResultFromStream(stream, jsonMode);
|
|
135
|
-
if
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
// Just return the result if it has tool calls
|
|
144
|
+
if (result.toolCalls?.length || result.json)
|
|
145
|
+
return result;
|
|
146
|
+
// Try to parse the text response as JSON
|
|
147
|
+
// If it matches the json_schema, return it as json
|
|
148
|
+
const json = safeParseJSON(result.text || "");
|
|
149
|
+
if (this.ajv.validate(input.responseFormat.jsonSchema.schema, json)) {
|
|
150
|
+
return { ...result, json, text: undefined };
|
|
141
151
|
}
|
|
142
|
-
|
|
152
|
+
logger_js_1.logger.warn(`${this.name}: Text response does not match JSON schema, trying to use tool to extract json `, { text: result.text });
|
|
153
|
+
const output = await this.requestStructuredOutput(body, input.responseFormat);
|
|
154
|
+
return { ...output, usage: (0, model_utils_js_1.mergeUsage)(result.usage, output.usage) };
|
|
143
155
|
}
|
|
144
156
|
getParallelToolCalls(input) {
|
|
145
157
|
if (!this.supportsParallelToolCalls)
|
|
@@ -150,15 +162,14 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
150
162
|
}
|
|
151
163
|
async getRunMessages(input) {
|
|
152
164
|
const messages = await contentsFromInputMessages(input.messages);
|
|
153
|
-
if (!this.supportsToolsUseWithJsonSchema && input.tools?.length)
|
|
154
|
-
return messages;
|
|
155
|
-
if (this.supportsNativeStructuredOutputs)
|
|
156
|
-
return messages;
|
|
157
165
|
if (input.responseFormat?.type === "json_schema") {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
if (!this.supportsNativeStructuredOutputs ||
|
|
167
|
+
(!this.supportsToolsUseWithJsonSchema && input.tools?.length)) {
|
|
168
|
+
messages.unshift({
|
|
169
|
+
role: "system",
|
|
170
|
+
content: (0, prompts_js_1.getJsonOutputPrompt)(input.responseFormat.jsonSchema.schema),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
162
173
|
}
|
|
163
174
|
return messages;
|
|
164
175
|
}
|
|
@@ -269,7 +280,7 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
269
280
|
controller.enqueue({
|
|
270
281
|
delta: {
|
|
271
282
|
json: {
|
|
272
|
-
json: (
|
|
283
|
+
json: safeParseJSON(text),
|
|
273
284
|
},
|
|
274
285
|
},
|
|
275
286
|
});
|
|
@@ -280,7 +291,7 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
280
291
|
json: {
|
|
281
292
|
toolCalls: toolCalls.map(({ args, ...c }) => ({
|
|
282
293
|
...c,
|
|
283
|
-
function: { ...c.function, arguments: (
|
|
294
|
+
function: { ...c.function, arguments: safeParseJSON(args) },
|
|
284
295
|
})),
|
|
285
296
|
},
|
|
286
297
|
},
|
|
@@ -408,7 +419,7 @@ function handleCompleteToolCall(toolCalls, call) {
|
|
|
408
419
|
type: "function",
|
|
409
420
|
function: {
|
|
410
421
|
name: call.function?.name || "",
|
|
411
|
-
arguments: (
|
|
422
|
+
arguments: safeParseJSON(call.function?.arguments || "{}"),
|
|
412
423
|
},
|
|
413
424
|
args: call.function?.arguments || "",
|
|
414
425
|
});
|
|
@@ -422,3 +433,13 @@ class CustomOpenAI extends openai_1.default {
|
|
|
422
433
|
return super.makeStatusError(status, error, message, headers);
|
|
423
434
|
}
|
|
424
435
|
}
|
|
436
|
+
function safeParseJSON(text) {
|
|
437
|
+
if (!text)
|
|
438
|
+
return null;
|
|
439
|
+
try {
|
|
440
|
+
return (0, jaison_1.default)(text);
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
@@ -139,6 +139,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
139
139
|
* @returns The generated response
|
|
140
140
|
*/
|
|
141
141
|
process(input: ChatModelInput): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
142
|
+
private ajv;
|
|
142
143
|
private _process;
|
|
143
144
|
private getParallelToolCalls;
|
|
144
145
|
protected getRunMessages(input: ChatModelInput): Promise<ChatCompletionMessageParam[]>;
|
|
@@ -139,6 +139,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
139
139
|
* @returns The generated response
|
|
140
140
|
*/
|
|
141
141
|
process(input: ChatModelInput): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
142
|
+
private ajv;
|
|
142
143
|
private _process;
|
|
143
144
|
private getParallelToolCalls;
|
|
144
145
|
protected getRunMessages(input: ChatModelInput): Promise<ChatCompletionMessageParam[]>;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ChatModel, } from "@aigne/core";
|
|
2
|
-
import {
|
|
2
|
+
import { logger } from "@aigne/core/utils/logger.js";
|
|
3
3
|
import { mergeUsage } from "@aigne/core/utils/model-utils.js";
|
|
4
4
|
import { getJsonOutputPrompt } from "@aigne/core/utils/prompts.js";
|
|
5
5
|
import { agentResponseStreamToObject } from "@aigne/core/utils/stream-utils.js";
|
|
6
6
|
import { checkArguments, isNonNullable, } from "@aigne/core/utils/type-utils.js";
|
|
7
|
+
import { Ajv } from "ajv";
|
|
8
|
+
import jaison from "jaison";
|
|
7
9
|
import { nanoid } from "nanoid";
|
|
8
10
|
import OpenAI from "openai";
|
|
9
11
|
import { z } from "zod";
|
|
@@ -93,6 +95,7 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
93
95
|
process(input) {
|
|
94
96
|
return this._process(input);
|
|
95
97
|
}
|
|
98
|
+
ajv = new Ajv();
|
|
96
99
|
async _process(input) {
|
|
97
100
|
const messages = await this.getRunMessages(input);
|
|
98
101
|
const body = {
|
|
@@ -109,6 +112,11 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
109
112
|
},
|
|
110
113
|
stream: true,
|
|
111
114
|
};
|
|
115
|
+
// For models that do not support tools use with JSON schema in same request,
|
|
116
|
+
// so we need to handle the case where tools are not used and responseFormat is json
|
|
117
|
+
if (!input.tools?.length && input.responseFormat?.type === "json_schema") {
|
|
118
|
+
return await this.requestStructuredOutput(body, input.responseFormat);
|
|
119
|
+
}
|
|
112
120
|
const { jsonMode, responseFormat } = await this.getRunResponseFormat(input);
|
|
113
121
|
const stream = (await this.client.chat.completions.create({
|
|
114
122
|
...body,
|
|
@@ -123,14 +131,18 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
123
131
|
return await this.extractResultFromStream(stream, false, true);
|
|
124
132
|
}
|
|
125
133
|
const result = await this.extractResultFromStream(stream, jsonMode);
|
|
126
|
-
if
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
// Just return the result if it has tool calls
|
|
135
|
+
if (result.toolCalls?.length || result.json)
|
|
136
|
+
return result;
|
|
137
|
+
// Try to parse the text response as JSON
|
|
138
|
+
// If it matches the json_schema, return it as json
|
|
139
|
+
const json = safeParseJSON(result.text || "");
|
|
140
|
+
if (this.ajv.validate(input.responseFormat.jsonSchema.schema, json)) {
|
|
141
|
+
return { ...result, json, text: undefined };
|
|
132
142
|
}
|
|
133
|
-
|
|
143
|
+
logger.warn(`${this.name}: Text response does not match JSON schema, trying to use tool to extract json `, { text: result.text });
|
|
144
|
+
const output = await this.requestStructuredOutput(body, input.responseFormat);
|
|
145
|
+
return { ...output, usage: mergeUsage(result.usage, output.usage) };
|
|
134
146
|
}
|
|
135
147
|
getParallelToolCalls(input) {
|
|
136
148
|
if (!this.supportsParallelToolCalls)
|
|
@@ -141,15 +153,14 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
141
153
|
}
|
|
142
154
|
async getRunMessages(input) {
|
|
143
155
|
const messages = await contentsFromInputMessages(input.messages);
|
|
144
|
-
if (!this.supportsToolsUseWithJsonSchema && input.tools?.length)
|
|
145
|
-
return messages;
|
|
146
|
-
if (this.supportsNativeStructuredOutputs)
|
|
147
|
-
return messages;
|
|
148
156
|
if (input.responseFormat?.type === "json_schema") {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
if (!this.supportsNativeStructuredOutputs ||
|
|
158
|
+
(!this.supportsToolsUseWithJsonSchema && input.tools?.length)) {
|
|
159
|
+
messages.unshift({
|
|
160
|
+
role: "system",
|
|
161
|
+
content: getJsonOutputPrompt(input.responseFormat.jsonSchema.schema),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
153
164
|
}
|
|
154
165
|
return messages;
|
|
155
166
|
}
|
|
@@ -260,7 +271,7 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
260
271
|
controller.enqueue({
|
|
261
272
|
delta: {
|
|
262
273
|
json: {
|
|
263
|
-
json:
|
|
274
|
+
json: safeParseJSON(text),
|
|
264
275
|
},
|
|
265
276
|
},
|
|
266
277
|
});
|
|
@@ -271,7 +282,7 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
271
282
|
json: {
|
|
272
283
|
toolCalls: toolCalls.map(({ args, ...c }) => ({
|
|
273
284
|
...c,
|
|
274
|
-
function: { ...c.function, arguments:
|
|
285
|
+
function: { ...c.function, arguments: safeParseJSON(args) },
|
|
275
286
|
})),
|
|
276
287
|
},
|
|
277
288
|
},
|
|
@@ -398,7 +409,7 @@ function handleCompleteToolCall(toolCalls, call) {
|
|
|
398
409
|
type: "function",
|
|
399
410
|
function: {
|
|
400
411
|
name: call.function?.name || "",
|
|
401
|
-
arguments:
|
|
412
|
+
arguments: safeParseJSON(call.function?.arguments || "{}"),
|
|
402
413
|
},
|
|
403
414
|
args: call.function?.arguments || "",
|
|
404
415
|
});
|
|
@@ -412,3 +423,13 @@ class CustomOpenAI extends OpenAI {
|
|
|
412
423
|
return super.makeStatusError(status, error, message, headers);
|
|
413
424
|
}
|
|
414
425
|
}
|
|
426
|
+
function safeParseJSON(text) {
|
|
427
|
+
if (!text)
|
|
428
|
+
return null;
|
|
429
|
+
try {
|
|
430
|
+
return jaison(text);
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/openai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "AIGNE OpenAI SDK for integrating with OpenAI's GPT models and API services",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -32,10 +32,12 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"ajv": "^8.17.1",
|
|
36
|
+
"jaison": "^2.0.2",
|
|
35
37
|
"nanoid": "^5.1.5",
|
|
36
38
|
"openai": "^5.8.2",
|
|
37
39
|
"zod": "^3.25.67",
|
|
38
|
-
"@aigne/core": "^1.
|
|
40
|
+
"@aigne/core": "^1.33.0"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@types/bun": "^1.2.17",
|
|
@@ -43,7 +45,7 @@
|
|
|
43
45
|
"npm-run-all": "^4.1.5",
|
|
44
46
|
"rimraf": "^6.0.1",
|
|
45
47
|
"typescript": "^5.8.3",
|
|
46
|
-
"@aigne/test-utils": "^0.5.
|
|
48
|
+
"@aigne/test-utils": "^0.5.5"
|
|
47
49
|
},
|
|
48
50
|
"scripts": {
|
|
49
51
|
"lint": "tsc --noEmit",
|
package/README.zh.md
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# @aigne/openai
|
|
2
|
-
|
|
3
|
-
[](https://star-history.com/#AIGNE-io/aigne-framework)
|
|
4
|
-
[](https://github.com/AIGNE-io/aigne-framework/issues)
|
|
5
|
-
[](https://codecov.io/gh/AIGNE-io/aigne-framework)
|
|
6
|
-
[](https://www.npmjs.com/package/@aigne/openai)
|
|
7
|
-
[](https://github.com/AIGNE-io/aigne-framework/blob/main/LICENSE.md)
|
|
8
|
-
|
|
9
|
-
[English](README.md) | **中文**
|
|
10
|
-
|
|
11
|
-
AIGNE OpenAI SDK,用于在 [AIGNE 框架](https://github.com/AIGNE-io/aigne-framework) 中集成 OpenAI 的 GPT 模型和 API 服务。
|
|
12
|
-
|
|
13
|
-
## 简介
|
|
14
|
-
|
|
15
|
-
`@aigne/openai` 提供了 AIGNE 框架与 OpenAI 强大的语言模型和 API 之间的无缝集成。该包使开发者能够在 AIGNE 应用程序中轻松利用 OpenAI 的 GPT 模型,同时提供框架内一致的接口,充分发挥 OpenAI 先进的 AI 能力。
|
|
16
|
-
|
|
17
|
-
## 特性
|
|
18
|
-
|
|
19
|
-
* **OpenAI API 集成**:使用官方 SDK 直接连接到 OpenAI 的 API 服务
|
|
20
|
-
* **聊天完成**:支持 OpenAI 的聊天完成 API 和所有可用模型
|
|
21
|
-
* **函数调用**:内置支持 OpenAI 的函数调用功能
|
|
22
|
-
* **流式响应**:支持流式响应,提供更高响应性的应用程序体验
|
|
23
|
-
* **类型安全**:为所有 API 和模型提供全面的 TypeScript 类型定义
|
|
24
|
-
* **一致接口**:兼容 AIGNE 框架的模型接口
|
|
25
|
-
* **错误处理**:健壮的错误处理和重试机制
|
|
26
|
-
* **完整配置**:丰富的配置选项用于微调行为
|
|
27
|
-
|
|
28
|
-
## 安装
|
|
29
|
-
|
|
30
|
-
### 使用 npm
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npm install @aigne/openai @aigne/core
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### 使用 yarn
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
yarn add @aigne/openai @aigne/core
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 使用 pnpm
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
pnpm add @aigne/openai @aigne/core
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## 基本用法
|
|
49
|
-
|
|
50
|
-
```typescript file="test/openai-chat-model.test.ts" region="example-openai-chat-model"
|
|
51
|
-
import { OpenAIChatModel } from "@aigne/openai";
|
|
52
|
-
|
|
53
|
-
const model = new OpenAIChatModel({
|
|
54
|
-
// Provide API key directly or use environment variable OPENAI_API_KEY
|
|
55
|
-
apiKey: "your-api-key", // Optional if set in env variables
|
|
56
|
-
model: "gpt-4o", // Defaults to "gpt-4o-mini" if not specified
|
|
57
|
-
modelOptions: {
|
|
58
|
-
temperature: 0.7,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const result = await model.invoke({
|
|
63
|
-
messages: [{ role: "user", content: "Hello, who are you?" }],
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
console.log(result);
|
|
67
|
-
/* Output:
|
|
68
|
-
{
|
|
69
|
-
text: "Hello! How can I assist you today?",
|
|
70
|
-
model: "gpt-4o",
|
|
71
|
-
usage: {
|
|
72
|
-
inputTokens: 10,
|
|
73
|
-
outputTokens: 9
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
*/
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## 流式响应
|
|
80
|
-
|
|
81
|
-
```typescript file="test/openai-chat-model.test.ts" region="example-openai-chat-model-stream"
|
|
82
|
-
import { isAgentResponseDelta } from "@aigne/core";
|
|
83
|
-
import { OpenAIChatModel } from "@aigne/openai";
|
|
84
|
-
|
|
85
|
-
const model = new OpenAIChatModel({
|
|
86
|
-
apiKey: "your-api-key",
|
|
87
|
-
model: "gpt-4o",
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
const stream = await model.invoke(
|
|
91
|
-
{
|
|
92
|
-
messages: [{ role: "user", content: "Hello, who are you?" }],
|
|
93
|
-
},
|
|
94
|
-
{ streaming: true },
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
let fullText = "";
|
|
98
|
-
const json = {};
|
|
99
|
-
|
|
100
|
-
for await (const chunk of stream) {
|
|
101
|
-
if (isAgentResponseDelta(chunk)) {
|
|
102
|
-
const text = chunk.delta.text?.text;
|
|
103
|
-
if (text) fullText += text;
|
|
104
|
-
if (chunk.delta.json) Object.assign(json, chunk.delta.json);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
console.log(fullText); // Output: "Hello! How can I assist you today?"
|
|
109
|
-
console.log(json); // { model: "gpt-4o", usage: { inputTokens: 10, outputTokens: 9 } }
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## 许可证
|
|
113
|
-
|
|
114
|
-
Elastic-2.0
|