@agentica/core 0.32.9 → 0.33.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/lib/events/AgenticaCallEvent.d.ts +0 -4
- package/lib/events/AgenticaExecuteEvent.d.ts +1 -1
- package/lib/events/AgenticaJsonParseErrorEvent.d.ts +4 -0
- package/lib/events/AgenticaResponseEvent.d.ts +1 -0
- package/lib/events/AgenticaValidateEvent.d.ts +1 -1
- package/lib/factory/events.d.ts +4 -2
- package/lib/factory/events.js +11 -3
- package/lib/factory/events.js.map +1 -1
- package/lib/index.mjs +100 -85
- package/lib/index.mjs.map +1 -1
- package/lib/json/IAgenticaEventJson.d.ts +9 -5
- package/lib/orchestrate/call.js +9 -5
- package/lib/orchestrate/call.js.map +1 -1
- package/lib/orchestrate/cancel.js +1 -1
- package/lib/orchestrate/cancel.js.map +1 -1
- package/lib/orchestrate/describe.js +1 -1
- package/lib/orchestrate/describe.js.map +1 -1
- package/lib/orchestrate/initialize.js +1 -1
- package/lib/orchestrate/initialize.js.map +1 -1
- package/lib/orchestrate/internal/cancelFunctionFromContext.js +1 -1
- package/lib/orchestrate/internal/cancelFunctionFromContext.js.map +1 -1
- package/lib/orchestrate/internal/selectFunctionFromContext.js +1 -1
- package/lib/orchestrate/internal/selectFunctionFromContext.js.map +1 -1
- package/lib/orchestrate/select.js +1 -1
- package/lib/orchestrate/select.js.map +1 -1
- package/lib/utils/ChatGptCompletionMessageUtil.d.ts +2 -2
- package/lib/utils/ChatGptCompletionMessageUtil.js +3 -3
- package/lib/utils/ChatGptCompletionMessageUtil.js.map +1 -1
- package/lib/utils/ChatGptCompletionMessageUtil.spec.js +4 -4
- package/lib/utils/ChatGptCompletionMessageUtil.spec.js.map +1 -1
- package/lib/utils/ChatGptCompletionStreamingUtil.js.map +1 -1
- package/lib/utils/ChatGptCompletionStreamingUtil.spec.js +2 -1
- package/lib/utils/ChatGptCompletionStreamingUtil.spec.js.map +1 -1
- package/lib/utils/JsonUtil.js +1 -1
- package/lib/utils/JsonUtil.js.map +1 -1
- package/lib/utils/JsonUtil.spec.js +38 -38
- package/lib/utils/JsonUtil.spec.js.map +1 -1
- package/lib/utils/StreamUtil.spec.js.map +1 -1
- package/lib/utils/request.d.ts +7 -7
- package/lib/utils/request.js +67 -65
- package/lib/utils/request.js.map +1 -1
- package/package.json +7 -7
- package/src/events/AgenticaCallEvent.ts +0 -5
- package/src/events/AgenticaExecuteEvent.ts +1 -1
- package/src/events/AgenticaJsonParseErrorEvent.ts +4 -0
- package/src/events/AgenticaResponseEvent.ts +2 -0
- package/src/events/AgenticaValidateEvent.ts +1 -1
- package/src/factory/events.ts +15 -5
- package/src/json/IAgenticaEventJson.ts +11 -6
- package/src/orchestrate/call.ts +14 -7
- package/src/orchestrate/cancel.ts +1 -1
- package/src/orchestrate/describe.ts +1 -1
- package/src/orchestrate/initialize.ts +1 -1
- package/src/orchestrate/internal/cancelFunctionFromContext.ts +1 -1
- package/src/orchestrate/internal/selectFunctionFromContext.ts +1 -1
- package/src/orchestrate/select.ts +1 -1
- package/src/utils/ChatGptCompletionMessageUtil.spec.ts +4 -4
- package/src/utils/ChatGptCompletionMessageUtil.ts +5 -4
- package/src/utils/ChatGptCompletionStreamingUtil.spec.ts +437 -435
- package/src/utils/ChatGptCompletionStreamingUtil.ts +5 -4
- package/src/utils/JsonUtil.spec.ts +58 -60
- package/src/utils/JsonUtil.ts +1 -3
- package/src/utils/StreamUtil.spec.ts +1 -1
- package/src/utils/StreamUtil.ts +2 -2
- package/src/utils/request.ts +92 -85
|
@@ -23,7 +23,8 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
|
|
|
23
23
|
const context = streamContext.get(choice.index)!;
|
|
24
24
|
context.content += choice.delta.content;
|
|
25
25
|
context.mpsc.produce(choice.delta.content);
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
27
28
|
const mpsc = new MPSC<string>();
|
|
28
29
|
|
|
29
30
|
streamContext.set(choice.index, {
|
|
@@ -43,7 +44,7 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
|
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
// Handle finish_reason after content processing
|
|
48
49
|
if (choice.finish_reason != null) {
|
|
49
50
|
const context = streamContext.get(choice.index);
|
|
@@ -70,10 +71,10 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
|
|
|
70
71
|
);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
if((nullableCompletion.object as string) === "chat.completion.chunk") {
|
|
74
|
+
if ((nullableCompletion.object as string) === "chat.completion.chunk") {
|
|
74
75
|
const completion = ChatGptCompletionMessageUtil.merge([nullableCompletion as unknown as ChatCompletionChunk]);
|
|
75
76
|
completion.choices.forEach((choice) => {
|
|
76
|
-
if(choice.message.content != null && choice.message.content !== "") {
|
|
77
|
+
if (choice.message.content != null && choice.message.content !== "") {
|
|
77
78
|
eventProcessor({
|
|
78
79
|
stream: toAsyncGenerator(choice.message.content),
|
|
79
80
|
done: () => true,
|
|
@@ -1,185 +1,184 @@
|
|
|
1
1
|
import { JsonUtil } from "./JsonUtil";
|
|
2
2
|
|
|
3
|
-
describe("
|
|
3
|
+
describe("jsonUtil", () => {
|
|
4
4
|
describe("parse", () => {
|
|
5
|
-
|
|
6
|
-
describe("Normal Operations", () => {
|
|
5
|
+
describe("normal Operations", () => {
|
|
7
6
|
it("should parse standard valid JSON", () => {
|
|
8
|
-
const jsonString =
|
|
7
|
+
const jsonString = "{\"normal\": \"json\"}";
|
|
9
8
|
const result = JsonUtil.parse(jsonString);
|
|
10
|
-
|
|
9
|
+
|
|
11
10
|
expect(result).toEqual({ normal: "json" });
|
|
12
11
|
});
|
|
13
12
|
|
|
14
13
|
it("should handle object with '{}' prefix", () => {
|
|
15
|
-
const jsonString =
|
|
14
|
+
const jsonString = "{}{\"name\": \"test\", \"value\": 42}";
|
|
16
15
|
const result = JsonUtil.parse(jsonString);
|
|
17
|
-
|
|
16
|
+
|
|
18
17
|
expect(result).toEqual({ name: "test", value: 42 });
|
|
19
18
|
});
|
|
20
19
|
|
|
21
20
|
it("should handle array with '{}' prefix", () => {
|
|
22
|
-
const jsonString =
|
|
21
|
+
const jsonString = "{}[1, 2, 3, \"test\"]";
|
|
23
22
|
const result = JsonUtil.parse(jsonString);
|
|
24
|
-
|
|
23
|
+
|
|
25
24
|
expect(result).toEqual([1, 2, 3, "test"]);
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
it("should handle primitive values with '{}' prefix", () => {
|
|
29
|
-
expect(JsonUtil.parse(
|
|
30
|
-
expect(JsonUtil.parse(
|
|
31
|
-
expect(JsonUtil.parse(
|
|
32
|
-
expect(JsonUtil.parse(
|
|
28
|
+
expect(JsonUtil.parse("{}42")).toBe(42);
|
|
29
|
+
expect(JsonUtil.parse("{}\"hello\"")).toBe("hello");
|
|
30
|
+
expect(JsonUtil.parse("{}true")).toBe(true);
|
|
31
|
+
expect(JsonUtil.parse("{}null")).toBeNull();
|
|
33
32
|
});
|
|
34
33
|
|
|
35
34
|
it("should remove trailing comma in object", () => {
|
|
36
|
-
const jsonString =
|
|
35
|
+
const jsonString = "{\"name\": \"test\", \"value\": 42,}";
|
|
37
36
|
const result = JsonUtil.parse(jsonString);
|
|
38
|
-
|
|
37
|
+
|
|
39
38
|
expect(result).toEqual({ name: "test", value: 42 });
|
|
40
39
|
});
|
|
41
40
|
|
|
42
41
|
it("should remove trailing comma in array", () => {
|
|
43
|
-
const jsonString =
|
|
42
|
+
const jsonString = "[1, 2, 3, \"test\",]";
|
|
44
43
|
const result = JsonUtil.parse(jsonString);
|
|
45
|
-
|
|
44
|
+
|
|
46
45
|
expect(result).toEqual([1, 2, 3, "test"]);
|
|
47
46
|
});
|
|
48
47
|
|
|
49
48
|
it("should add missing closing brace in object", () => {
|
|
50
|
-
const jsonString =
|
|
49
|
+
const jsonString = "{\"name\": \"test\", \"value\": 42";
|
|
51
50
|
const result = JsonUtil.parse(jsonString);
|
|
52
|
-
|
|
51
|
+
|
|
53
52
|
expect(result).toEqual({ name: "test", value: 42 });
|
|
54
53
|
});
|
|
55
54
|
|
|
56
55
|
it("should add missing closing bracket in array", () => {
|
|
57
|
-
const jsonString =
|
|
56
|
+
const jsonString = "[1, 2, 3, \"test\"";
|
|
58
57
|
const result = JsonUtil.parse(jsonString);
|
|
59
|
-
|
|
58
|
+
|
|
60
59
|
expect(result).toEqual([1, 2, 3, "test"]);
|
|
61
60
|
});
|
|
62
61
|
});
|
|
63
62
|
|
|
64
|
-
describe("
|
|
63
|
+
describe("combined Features", () => {
|
|
65
64
|
it("should handle '{}' prefix and missing closing brace together", () => {
|
|
66
|
-
const jsonString =
|
|
65
|
+
const jsonString = "{}{\"name\": \"test\", \"value\": 42";
|
|
67
66
|
const result = JsonUtil.parse(jsonString);
|
|
68
|
-
|
|
67
|
+
|
|
69
68
|
expect(result).toEqual({ name: "test", value: 42 });
|
|
70
69
|
});
|
|
71
70
|
|
|
72
71
|
it("should handle '{}' prefix and missing closing bracket together", () => {
|
|
73
|
-
const jsonString =
|
|
72
|
+
const jsonString = "{}[1, 2, 3, \"test\"";
|
|
74
73
|
const result = JsonUtil.parse(jsonString);
|
|
75
|
-
|
|
74
|
+
|
|
76
75
|
expect(result).toEqual([1, 2, 3, "test"]);
|
|
77
76
|
});
|
|
78
77
|
|
|
79
78
|
it("should handle trailing comma in nested objects", () => {
|
|
80
|
-
const jsonString =
|
|
79
|
+
const jsonString = "{\"user\": {\"id\": 1, \"name\": \"John\",}, \"active\": true,}";
|
|
81
80
|
const result = JsonUtil.parse(jsonString);
|
|
82
|
-
|
|
81
|
+
|
|
83
82
|
expect(result).toEqual({
|
|
84
83
|
user: { id: 1, name: "John" },
|
|
85
|
-
active: true
|
|
84
|
+
active: true,
|
|
86
85
|
});
|
|
87
86
|
});
|
|
88
87
|
|
|
89
88
|
it("should handle missing closing brace in nested objects", () => {
|
|
90
|
-
const jsonString =
|
|
89
|
+
const jsonString = "{\"user\": {\"id\": 1, \"name\": \"John\"}";
|
|
91
90
|
const result = JsonUtil.parse(jsonString);
|
|
92
|
-
|
|
91
|
+
|
|
93
92
|
expect(result).toEqual({
|
|
94
|
-
user: { id: 1, name: "John" }
|
|
93
|
+
user: { id: 1, name: "John" },
|
|
95
94
|
});
|
|
96
95
|
});
|
|
97
96
|
|
|
98
97
|
it("should handle missing closing brace in complex nested structure", () => {
|
|
99
|
-
const jsonString =
|
|
98
|
+
const jsonString = "{\"users\": [{\"id\": 1, \"name\": \"John\"}, {\"id\": 2, \"name\": \"Jane\"}], \"count\": 2";
|
|
100
99
|
const result = JsonUtil.parse(jsonString);
|
|
101
|
-
|
|
100
|
+
|
|
102
101
|
expect(result).toEqual({
|
|
103
102
|
users: [
|
|
104
103
|
{ id: 1, name: "John" },
|
|
105
|
-
{ id: 2, name: "Jane" }
|
|
104
|
+
{ id: 2, name: "Jane" },
|
|
106
105
|
],
|
|
107
|
-
count: 2
|
|
106
|
+
count: 2,
|
|
108
107
|
});
|
|
109
108
|
});
|
|
110
109
|
|
|
111
110
|
it("should apply all correction features together", () => {
|
|
112
|
-
const jsonString =
|
|
111
|
+
const jsonString = "{}{\"name\": \"test\", \"items\": [1, 2, 3,], \"user\": {\"id\": 1, \"name\": \"John\",}";
|
|
113
112
|
const result = JsonUtil.parse(jsonString);
|
|
114
|
-
|
|
113
|
+
|
|
115
114
|
expect(result).toEqual({
|
|
116
115
|
name: "test",
|
|
117
116
|
items: [1, 2, 3],
|
|
118
|
-
user: { id: 1, name: "John" }
|
|
117
|
+
user: { id: 1, name: "John" },
|
|
119
118
|
});
|
|
120
119
|
});
|
|
121
120
|
|
|
122
121
|
it("should handle all issues simultaneously in complex nested structure", () => {
|
|
123
|
-
const jsonString =
|
|
122
|
+
const jsonString = "{}{\"data\": {\"users\": [{\"id\": 1, \"name\": \"John\",}, {\"id\": 2, \"name\": \"Jane\",}], \"meta\": {\"total\": 2, \"page\": 1,}}, \"status\": \"ok\",";
|
|
124
123
|
const result = JsonUtil.parse(jsonString);
|
|
125
|
-
|
|
124
|
+
|
|
126
125
|
expect(result).toEqual({
|
|
127
126
|
data: {
|
|
128
127
|
users: [
|
|
129
128
|
{ id: 1, name: "John" },
|
|
130
|
-
{ id: 2, name: "Jane" }
|
|
129
|
+
{ id: 2, name: "Jane" },
|
|
131
130
|
],
|
|
132
|
-
meta: { total: 2, page: 1 }
|
|
131
|
+
meta: { total: 2, page: 1 },
|
|
133
132
|
},
|
|
134
|
-
status: "ok"
|
|
133
|
+
status: "ok",
|
|
135
134
|
});
|
|
136
135
|
});
|
|
137
136
|
});
|
|
138
137
|
|
|
139
|
-
describe("
|
|
138
|
+
describe("edge Cases", () => {
|
|
140
139
|
it("should handle empty object with '{}' prefix", () => {
|
|
141
|
-
const jsonString =
|
|
140
|
+
const jsonString = "{}{}";
|
|
142
141
|
const result = JsonUtil.parse(jsonString);
|
|
143
|
-
|
|
142
|
+
|
|
144
143
|
expect(result).toEqual({});
|
|
145
144
|
});
|
|
146
145
|
|
|
147
146
|
it("should handle empty array with '{}' prefix", () => {
|
|
148
|
-
const jsonString =
|
|
147
|
+
const jsonString = "{}[]";
|
|
149
148
|
const result = JsonUtil.parse(jsonString);
|
|
150
|
-
|
|
149
|
+
|
|
151
150
|
expect(result).toEqual([]);
|
|
152
151
|
});
|
|
153
152
|
|
|
154
153
|
it("should handle nested object with '{}' prefix", () => {
|
|
155
|
-
const jsonString =
|
|
154
|
+
const jsonString = "{}{\"user\": {\"id\": 1, \"name\": \"John\"}}";
|
|
156
155
|
const result = JsonUtil.parse(jsonString);
|
|
157
|
-
|
|
156
|
+
|
|
158
157
|
expect(result).toEqual({
|
|
159
|
-
user: { id: 1, name: "John" }
|
|
158
|
+
user: { id: 1, name: "John" },
|
|
160
159
|
});
|
|
161
160
|
});
|
|
162
161
|
|
|
163
162
|
it("should handle multiple trailing commas", () => {
|
|
164
|
-
const jsonString =
|
|
163
|
+
const jsonString = "{\"items\": [1, 2, 3,,,], \"count\": 3,,,}";
|
|
165
164
|
const result = JsonUtil.parse(jsonString);
|
|
166
|
-
|
|
165
|
+
|
|
167
166
|
expect(result).toEqual({
|
|
168
167
|
items: [1, 2, 3],
|
|
169
|
-
count: 3
|
|
168
|
+
count: 3,
|
|
170
169
|
});
|
|
171
170
|
});
|
|
172
171
|
|
|
173
172
|
it("should handle JSON with whitespace and formatting issues", () => {
|
|
174
|
-
const jsonString =
|
|
173
|
+
const jsonString = "{} { \"name\" : \"test\" , \"value\" : 42 , } ";
|
|
175
174
|
const result = JsonUtil.parse(jsonString);
|
|
176
|
-
|
|
175
|
+
|
|
177
176
|
expect(result).toEqual({ name: "test", value: 42 });
|
|
178
177
|
});
|
|
179
178
|
|
|
180
179
|
it("should throw error for completely invalid JSON", () => {
|
|
181
|
-
const invalidJson =
|
|
182
|
-
|
|
180
|
+
const invalidJson = "{invalid: json without quotes}";
|
|
181
|
+
|
|
183
182
|
expect(() => JsonUtil.parse(invalidJson)).toThrow();
|
|
184
183
|
});
|
|
185
184
|
|
|
@@ -187,6 +186,5 @@ describe("JsonUtil", () => {
|
|
|
187
186
|
expect(() => JsonUtil.parse("")).toThrow();
|
|
188
187
|
});
|
|
189
188
|
});
|
|
190
|
-
|
|
191
189
|
});
|
|
192
190
|
});
|
package/src/utils/JsonUtil.ts
CHANGED
|
@@ -4,10 +4,8 @@ export const JsonUtil = {
|
|
|
4
4
|
parse,
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
const pipe = (...fns: ((str: string) => string)[]) => (str: string) => fns.reduce((acc, fn) => fn(acc), str);
|
|
7
8
|
function parse(str: string) {
|
|
8
9
|
const corrected = pipe(removeEmptyObjectPrefix, addMissingBraces, removeTrailingCommas)(str);
|
|
9
10
|
return JSON.parse(corrected);
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
const pipe = (...fns: ((str: string) => string)[]) => (str: string) => fns.reduce((acc, fn) => fn(acc), str);
|
|
13
|
-
|
package/src/utils/StreamUtil.ts
CHANGED
|
@@ -17,7 +17,7 @@ async function readAll<T>(stream: ReadableStream<T>, abortSignal?: AbortSignal):
|
|
|
17
17
|
return result;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async function reduce<T, R = T>(stream: ReadableStream<T>, reducer: (acc: T | R, cur: T) => R, options: { initial?: R
|
|
20
|
+
async function reduce<T, R = T>(stream: ReadableStream<T>, reducer: (acc: T | R, cur: T) => R, options: { initial?: R; abortSignal?: AbortSignal }): Promise<R | null> {
|
|
21
21
|
const reader = stream.getReader();
|
|
22
22
|
const iterator = streamDefaultReaderToAsyncGenerator(reader);
|
|
23
23
|
let acc = (options.initial ?? null) as R | null | T;
|
|
@@ -73,7 +73,7 @@ function transform<T, R>(stream: ReadableStream<T>, transformer: (value: T) => R
|
|
|
73
73
|
controller.close();
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
controller.enqueue(transformer(value));
|
|
78
78
|
},
|
|
79
79
|
});
|
package/src/utils/request.ts
CHANGED
|
@@ -1,101 +1,108 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import type { ILlmSchema } from "@samchon/openapi";
|
|
2
|
+
import type OpenAI from "openai";
|
|
3
|
+
|
|
4
|
+
import { v4 } from "uuid";
|
|
5
|
+
|
|
6
|
+
import type { AgenticaTokenUsage } from "../context/AgenticaTokenUsage";
|
|
7
|
+
import type { AgenticaEventSource, AgenticaRequestEvent, AgenticaResponseEvent } from "../events";
|
|
8
|
+
import type { IAgenticaConfig, IAgenticaVendor, IMicroAgenticaConfig } from "../structures";
|
|
9
|
+
|
|
10
|
+
import { AgenticaTokenUsageAggregator } from "../context/internal/AgenticaTokenUsageAggregator";
|
|
11
|
+
import { createRequestEvent } from "../factory";
|
|
12
|
+
|
|
3
13
|
import { ChatGptCompletionMessageUtil } from "./ChatGptCompletionMessageUtil";
|
|
4
14
|
import { streamDefaultReaderToAsyncGenerator, StreamUtil } from "./StreamUtil";
|
|
5
|
-
import { createRequestEvent } from "../factory";
|
|
6
|
-
import { IAgenticaConfig, IAgenticaVendor, IMicroAgenticaConfig } from "../structures";
|
|
7
|
-
import { ILlmSchema } from "@samchon/openapi";
|
|
8
|
-
import { AgenticaTokenUsageAggregator } from "../context/internal/AgenticaTokenUsageAggregator";
|
|
9
|
-
import { AgenticaTokenUsage } from "../context/AgenticaTokenUsage";
|
|
10
|
-
import { v4 } from "uuid";
|
|
11
15
|
|
|
12
|
-
export
|
|
16
|
+
export function getChatCompletionWithStreamingFunction<Model extends ILlmSchema.Model>(props: {
|
|
13
17
|
vendor: IAgenticaVendor;
|
|
14
18
|
config?: IAgenticaConfig<Model> | IMicroAgenticaConfig<Model>;
|
|
15
19
|
dispatch: (event: AgenticaRequestEvent | AgenticaResponseEvent) => Promise<void>;
|
|
16
20
|
abortSignal?: AbortSignal;
|
|
17
21
|
usage: AgenticaTokenUsage;
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
}) {
|
|
23
|
+
return async (
|
|
24
|
+
source: AgenticaEventSource,
|
|
25
|
+
body: Omit<OpenAI.ChatCompletionCreateParamsStreaming, "model" | "stream">,
|
|
26
|
+
) => {
|
|
27
|
+
const event: AgenticaRequestEvent = createRequestEvent({
|
|
28
|
+
source,
|
|
29
|
+
body: {
|
|
30
|
+
...body,
|
|
31
|
+
model: props.vendor.model,
|
|
32
|
+
stream: true,
|
|
33
|
+
stream_options: {
|
|
34
|
+
include_usage: true,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
options: {
|
|
38
|
+
...props.vendor.options,
|
|
39
|
+
signal: props.abortSignal,
|
|
30
40
|
},
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
...props.vendor.options,
|
|
34
|
-
signal: props.abortSignal,
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
await props.dispatch(event);
|
|
41
|
+
});
|
|
42
|
+
await props.dispatch(event);
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
// completion
|
|
45
|
+
const backoffStrategy = props.config?.backoffStrategy ?? ((props) => {
|
|
46
|
+
throw props.error;
|
|
47
|
+
});
|
|
48
|
+
const completion = await (async () => {
|
|
49
|
+
let count = 0;
|
|
50
|
+
while (true) {
|
|
51
|
+
try {
|
|
52
|
+
return await props.vendor.api.chat.completions.create(
|
|
53
|
+
event.body,
|
|
54
|
+
event.options,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const waiting = backoffStrategy({ count, error });
|
|
59
|
+
await new Promise(resolve => setTimeout(resolve, waiting));
|
|
60
|
+
count++;
|
|
61
|
+
}
|
|
51
62
|
}
|
|
52
|
-
|
|
53
|
-
const waiting = backoffStrategy({ count, error });
|
|
54
|
-
await new Promise(resolve => setTimeout(resolve, waiting));
|
|
55
|
-
count++;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
})();
|
|
63
|
+
})();
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
const [streamForEvent, temporaryStream] = StreamUtil.transform(
|
|
66
|
+
completion.toReadableStream() as ReadableStream<Uint8Array>,
|
|
67
|
+
value =>
|
|
68
|
+
ChatGptCompletionMessageUtil.transformCompletionChunk(value),
|
|
69
|
+
props.abortSignal,
|
|
70
|
+
).tee();
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
const [streamForAggregate, streamForReturn] = temporaryStream.tee();
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
(async () => {
|
|
75
|
+
const reader = streamForAggregate.getReader();
|
|
76
|
+
while (true) {
|
|
77
|
+
const chunk = await reader.read();
|
|
78
|
+
if (chunk.done || props.abortSignal?.aborted === true) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (chunk.value.usage != null) {
|
|
82
|
+
AgenticaTokenUsageAggregator.aggregate({
|
|
83
|
+
kind: source,
|
|
84
|
+
completionUsage: chunk.value.usage,
|
|
85
|
+
usage: props.usage,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
82
88
|
}
|
|
83
|
-
}
|
|
84
|
-
})().catch(() => {});
|
|
89
|
+
})().catch(() => {});
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
const [streamForStream, streamForJoin] = streamForEvent.tee();
|
|
92
|
+
void props.dispatch({
|
|
93
|
+
id: v4(),
|
|
94
|
+
type: "response",
|
|
95
|
+
request_id: event.id,
|
|
96
|
+
source,
|
|
97
|
+
stream: streamDefaultReaderToAsyncGenerator(streamForStream.getReader(), props.abortSignal),
|
|
98
|
+
body: event.body,
|
|
99
|
+
options: event.options,
|
|
100
|
+
join: async () => {
|
|
101
|
+
const chunks = await StreamUtil.readAll(streamForJoin, props.abortSignal);
|
|
102
|
+
return ChatGptCompletionMessageUtil.merge(chunks);
|
|
103
|
+
},
|
|
104
|
+
created_at: new Date().toISOString(),
|
|
105
|
+
}).catch(() => {});
|
|
106
|
+
return streamForReturn;
|
|
107
|
+
};
|
|
108
|
+
}
|