@effect/ai-openai 4.0.0-beta.6 → 4.0.0-beta.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Generated.d.ts +66011 -38686
- package/dist/Generated.d.ts.map +1 -1
- package/dist/Generated.js +1 -1
- package/dist/Generated.js.map +1 -1
- package/dist/OpenAiClient.d.ts +63 -17
- package/dist/OpenAiClient.d.ts.map +1 -1
- package/dist/OpenAiClient.js +210 -33
- package/dist/OpenAiClient.js.map +1 -1
- package/dist/OpenAiClientGenerated.d.ts +91 -0
- package/dist/OpenAiClientGenerated.d.ts.map +1 -0
- package/dist/OpenAiClientGenerated.js +84 -0
- package/dist/OpenAiClientGenerated.js.map +1 -0
- package/dist/OpenAiConfig.d.ts +2 -2
- package/dist/OpenAiConfig.d.ts.map +1 -1
- package/dist/OpenAiConfig.js +3 -3
- package/dist/OpenAiConfig.js.map +1 -1
- package/dist/OpenAiEmbeddingModel.d.ts +85 -0
- package/dist/OpenAiEmbeddingModel.d.ts.map +1 -0
- package/dist/OpenAiEmbeddingModel.js +119 -0
- package/dist/OpenAiEmbeddingModel.js.map +1 -0
- package/dist/OpenAiError.d.ts +22 -32
- package/dist/OpenAiError.d.ts.map +1 -1
- package/dist/OpenAiLanguageModel.d.ts +43 -49
- package/dist/OpenAiLanguageModel.d.ts.map +1 -1
- package/dist/OpenAiLanguageModel.js +296 -152
- package/dist/OpenAiLanguageModel.js.map +1 -1
- package/dist/OpenAiSchema.d.ts +1920 -0
- package/dist/OpenAiSchema.d.ts.map +1 -0
- package/dist/OpenAiSchema.js +536 -0
- package/dist/OpenAiSchema.js.map +1 -0
- package/dist/OpenAiTool.d.ts +8 -7
- package/dist/OpenAiTool.d.ts.map +1 -1
- package/dist/OpenAiTool.js +2 -1
- package/dist/OpenAiTool.js.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/errors.js +4 -4
- package/dist/internal/errors.js.map +1 -1
- package/package.json +3 -3
- package/src/Generated.ts +7416 -4257
- package/src/OpenAiClient.ts +377 -81
- package/src/OpenAiClientGenerated.ts +202 -0
- package/src/OpenAiConfig.ts +3 -3
- package/src/OpenAiEmbeddingModel.ts +203 -0
- package/src/OpenAiError.ts +24 -32
- package/src/OpenAiLanguageModel.ts +420 -144
- package/src/OpenAiSchema.ts +875 -0
- package/src/OpenAiTool.ts +2 -1
- package/src/index.ts +21 -0
- package/src/internal/errors.ts +6 -4
|
@@ -6,21 +6,23 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @since 1.0.0
|
|
8
8
|
*/
|
|
9
|
+
import * as Context from "effect/Context";
|
|
9
10
|
import * as DateTime from "effect/DateTime";
|
|
10
11
|
import * as Effect from "effect/Effect";
|
|
11
12
|
import * as Encoding from "effect/Encoding";
|
|
12
13
|
import { dual } from "effect/Function";
|
|
13
14
|
import * as Layer from "effect/Layer";
|
|
15
|
+
import * as Option from "effect/Option";
|
|
14
16
|
import * as Predicate from "effect/Predicate";
|
|
15
17
|
import * as Redactable from "effect/Redactable";
|
|
16
18
|
import * as Schema from "effect/Schema";
|
|
17
19
|
import * as AST from "effect/SchemaAST";
|
|
18
|
-
import * as ServiceMap from "effect/ServiceMap";
|
|
19
20
|
import * as Stream from "effect/Stream";
|
|
20
21
|
import * as AiError from "effect/unstable/ai/AiError";
|
|
21
22
|
import * as IdGenerator from "effect/unstable/ai/IdGenerator";
|
|
22
23
|
import * as LanguageModel from "effect/unstable/ai/LanguageModel";
|
|
23
24
|
import * as AiModel from "effect/unstable/ai/Model";
|
|
25
|
+
import { toCodecOpenAI } from "effect/unstable/ai/OpenAiStructuredOutput";
|
|
24
26
|
import * as Tool from "effect/unstable/ai/Tool";
|
|
25
27
|
import * as Generated from "./Generated.js";
|
|
26
28
|
import * as InternalUtilities from "./internal/utilities.js";
|
|
@@ -37,7 +39,7 @@ const SharedModelIds = Generated.ModelIdsShared.members[1];
|
|
|
37
39
|
* @since 1.0.0
|
|
38
40
|
* @category services
|
|
39
41
|
*/
|
|
40
|
-
export class Config extends /*#__PURE__*/
|
|
42
|
+
export class Config extends /*#__PURE__*/Context.Service()("@effect/ai-openai/OpenAiLanguageModel/Config") {}
|
|
41
43
|
// =============================================================================
|
|
42
44
|
// Language Model
|
|
43
45
|
// =============================================================================
|
|
@@ -45,7 +47,7 @@ export class Config extends /*#__PURE__*/ServiceMap.Service()("@effect/ai-openai
|
|
|
45
47
|
* @since 1.0.0
|
|
46
48
|
* @category constructors
|
|
47
49
|
*/
|
|
48
|
-
export const model = (model, config) => AiModel.make("openai", layer({
|
|
50
|
+
export const model = (model, config) => AiModel.make("openai", model, layer({
|
|
49
51
|
model,
|
|
50
52
|
config
|
|
51
53
|
}));
|
|
@@ -58,7 +60,7 @@ export const model = (model, config) => AiModel.make("openai", layer({
|
|
|
58
60
|
// model: (string & {}) | Model,
|
|
59
61
|
// config?: Omit<typeof Config.Service, "model">
|
|
60
62
|
// ): AiModel.Model<"openai", LanguageModel.LanguageModel | Tokenizer.Tokenizer, OpenAiClient> =>
|
|
61
|
-
// AiModel.make("openai", layerWithTokenizer({ model, config }))
|
|
63
|
+
// AiModel.make("openai", model, layerWithTokenizer({ model, config }))
|
|
62
64
|
/**
|
|
63
65
|
* Creates an OpenAI language model service.
|
|
64
66
|
*
|
|
@@ -71,7 +73,7 @@ export const make = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
71
73
|
}) {
|
|
72
74
|
const client = yield* OpenAiClient;
|
|
73
75
|
const makeConfig = Effect.gen(function* () {
|
|
74
|
-
const services = yield* Effect.
|
|
76
|
+
const services = yield* Effect.context();
|
|
75
77
|
return {
|
|
76
78
|
model,
|
|
77
79
|
...providerConfig,
|
|
@@ -100,28 +102,26 @@ export const make = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
100
102
|
options,
|
|
101
103
|
toolNameMapper
|
|
102
104
|
});
|
|
103
|
-
const responseFormat = prepareResponseFormat({
|
|
105
|
+
const responseFormat = yield* prepareResponseFormat({
|
|
104
106
|
config,
|
|
105
107
|
options
|
|
106
108
|
});
|
|
107
109
|
const request = {
|
|
108
110
|
...config,
|
|
109
111
|
input: messages,
|
|
110
|
-
include: include.size > 0 ? Array.from(include) :
|
|
112
|
+
include: include.size > 0 ? Array.from(include) : undefined,
|
|
111
113
|
text: {
|
|
112
|
-
verbosity: config.text?.verbosity ??
|
|
114
|
+
verbosity: config.text?.verbosity ?? undefined,
|
|
113
115
|
format: responseFormat
|
|
114
|
-
}
|
|
115
|
-
...(Predicate.isNotUndefined(tools) ? {
|
|
116
|
-
tools
|
|
117
|
-
} : undefined),
|
|
118
|
-
...(Predicate.isNotUndefined(toolChoice) ? {
|
|
119
|
-
tool_choice: toolChoice
|
|
120
|
-
} : undefined)
|
|
116
|
+
}
|
|
121
117
|
};
|
|
118
|
+
if (tools) request.tools = tools;
|
|
119
|
+
if (toolChoice) request.tool_choice = toolChoice;
|
|
120
|
+
if (options.previousResponseId) request.previous_response_id = options.previousResponseId;
|
|
122
121
|
return request;
|
|
123
122
|
});
|
|
124
123
|
return yield* LanguageModel.make({
|
|
124
|
+
codecTransformer: toCodecOpenAI,
|
|
125
125
|
generateText: Effect.fnUntraced(function* (options) {
|
|
126
126
|
const config = yield* makeConfig;
|
|
127
127
|
const toolNameMapper = new Tool.NameMapper(options.tools);
|
|
@@ -207,14 +207,15 @@ const prepareMessages = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
207
207
|
if (config.store === false && capabilities.isReasoningModel) {
|
|
208
208
|
include.add("reasoning.encrypted_content");
|
|
209
209
|
}
|
|
210
|
-
if (
|
|
210
|
+
if (codeInterpreterTool) {
|
|
211
211
|
include.add("code_interpreter_call.outputs");
|
|
212
212
|
}
|
|
213
|
-
if (
|
|
213
|
+
if (webSearchTool || webSearchPreviewTool) {
|
|
214
214
|
include.add("web_search_call.action.sources");
|
|
215
215
|
}
|
|
216
216
|
const messages = [];
|
|
217
|
-
|
|
217
|
+
const prompt = options.incrementalPrompt ?? options.prompt;
|
|
218
|
+
for (const message of prompt.content) {
|
|
218
219
|
switch (message.role) {
|
|
219
220
|
case "system":
|
|
220
221
|
{
|
|
@@ -378,7 +379,9 @@ const prepareMessages = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
378
379
|
type: "reasoning",
|
|
379
380
|
id,
|
|
380
381
|
summary: summaryParts,
|
|
381
|
-
|
|
382
|
+
...(Predicate.isNotNull(encryptedContent) ? {
|
|
383
|
+
encrypted_content: encryptedContent
|
|
384
|
+
} : undefined)
|
|
382
385
|
};
|
|
383
386
|
messages.push(reasoningMessages[id]);
|
|
384
387
|
} else {
|
|
@@ -569,13 +572,15 @@ const buildHttpRequestDetails = request => ({
|
|
|
569
572
|
method: request.method,
|
|
570
573
|
url: request.url,
|
|
571
574
|
urlParams: Array.from(request.urlParams),
|
|
572
|
-
hash: request.hash,
|
|
575
|
+
hash: Option.getOrUndefined(request.hash),
|
|
573
576
|
headers: Redactable.redact(request.headers)
|
|
574
577
|
});
|
|
575
578
|
const buildHttpResponseDetails = response => ({
|
|
576
579
|
status: response.status,
|
|
577
580
|
headers: Redactable.redact(response.headers)
|
|
578
581
|
});
|
|
582
|
+
const knownResponseStreamEventTypes = /*#__PURE__*/new Set(["response.created", "response.completed", "response.incomplete", "response.failed", "response.output_item.added", "response.output_item.done", "response.output_text.delta", "response.output_text.annotation.added", "response.reasoning_summary_part.added", "response.reasoning_summary_part.done", "response.reasoning_summary_text.delta", "response.function_call_arguments.delta", "response.function_call_arguments.done", "response.code_interpreter_call_code.delta", "response.code_interpreter_call_code.done", "response.apply_patch_call_operation_diff.delta", "response.apply_patch_call_operation_diff.done", "response.image_generation_call.partial_image", "error"]);
|
|
583
|
+
const isKnownResponseStreamEvent = event => knownResponseStreamEventTypes.has(event.type);
|
|
579
584
|
const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
580
585
|
options,
|
|
581
586
|
rawResponse,
|
|
@@ -609,9 +614,7 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
609
614
|
operation: part.operation
|
|
610
615
|
},
|
|
611
616
|
metadata: {
|
|
612
|
-
openai:
|
|
613
|
-
...makeItemIdMetadata(part.id)
|
|
614
|
-
}
|
|
617
|
+
openai: makeItemIdMetadata(part.id)
|
|
615
618
|
}
|
|
616
619
|
});
|
|
617
620
|
break;
|
|
@@ -669,9 +672,8 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
669
672
|
{
|
|
670
673
|
hasToolCalls = true;
|
|
671
674
|
const toolName = part.name;
|
|
672
|
-
const toolParams =
|
|
673
|
-
|
|
674
|
-
try: () => Tool.unsafeSecureJsonParse(toolParams),
|
|
675
|
+
const toolParams = yield* Effect.try({
|
|
676
|
+
try: () => Tool.unsafeSecureJsonParse(part.arguments),
|
|
675
677
|
catch: cause => AiError.make({
|
|
676
678
|
module: "OpenAiLanguageModel",
|
|
677
679
|
method: "makeResponse",
|
|
@@ -682,15 +684,14 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
682
684
|
})
|
|
683
685
|
})
|
|
684
686
|
});
|
|
687
|
+
const params = yield* transformToolCallParams(options.tools, part.name, toolParams);
|
|
685
688
|
parts.push({
|
|
686
689
|
type: "tool-call",
|
|
687
690
|
id: part.call_id,
|
|
688
691
|
name: toolName,
|
|
689
692
|
params,
|
|
690
693
|
metadata: {
|
|
691
|
-
openai:
|
|
692
|
-
...makeItemIdMetadata(part.id)
|
|
693
|
-
}
|
|
694
|
+
openai: makeItemIdMetadata(part.id)
|
|
694
695
|
}
|
|
695
696
|
});
|
|
696
697
|
break;
|
|
@@ -727,9 +728,7 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
727
728
|
action: part.action
|
|
728
729
|
},
|
|
729
730
|
metadata: {
|
|
730
|
-
openai:
|
|
731
|
-
...makeItemIdMetadata(part.id)
|
|
732
|
-
}
|
|
731
|
+
openai: makeItemIdMetadata(part.id)
|
|
733
732
|
}
|
|
734
733
|
});
|
|
735
734
|
break;
|
|
@@ -737,12 +736,19 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
737
736
|
case "mcp_call":
|
|
738
737
|
{
|
|
739
738
|
const toolId = Predicate.isNotNullish(part.approval_request_id) ? approvalRequests.get(part.approval_request_id) ?? part.id : part.id;
|
|
740
|
-
const
|
|
739
|
+
const {
|
|
740
|
+
toolName,
|
|
741
|
+
params
|
|
742
|
+
} = yield* normalizeMcpToolCall({
|
|
743
|
+
toolNameMapper,
|
|
744
|
+
toolParams: part.arguments,
|
|
745
|
+
method: "makeResponse"
|
|
746
|
+
});
|
|
741
747
|
parts.push({
|
|
742
748
|
type: "tool-call",
|
|
743
749
|
id: toolId,
|
|
744
750
|
name: toolName,
|
|
745
|
-
params
|
|
751
|
+
params,
|
|
746
752
|
providerExecuted: true
|
|
747
753
|
});
|
|
748
754
|
parts.push({
|
|
@@ -752,7 +758,7 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
752
758
|
isFailure: false,
|
|
753
759
|
providerExecuted: true,
|
|
754
760
|
result: {
|
|
755
|
-
type: "
|
|
761
|
+
type: "mcp_call",
|
|
756
762
|
name: part.name,
|
|
757
763
|
arguments: part.arguments,
|
|
758
764
|
server_label: part.server_label,
|
|
@@ -764,9 +770,7 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
764
770
|
} : undefined)
|
|
765
771
|
},
|
|
766
772
|
metadata: {
|
|
767
|
-
openai:
|
|
768
|
-
...makeItemIdMetadata(part.id)
|
|
769
|
-
}
|
|
773
|
+
openai: makeItemIdMetadata(part.id)
|
|
770
774
|
}
|
|
771
775
|
});
|
|
772
776
|
break;
|
|
@@ -780,18 +784,13 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
780
784
|
{
|
|
781
785
|
const approvalRequestId = part.approval_request_id ?? part.id;
|
|
782
786
|
const toolId = yield* idGenerator.generateId();
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
toolName,
|
|
791
|
-
toolParams: {},
|
|
792
|
-
description: `Failed securely JSON parse tool parameters: ${cause}`
|
|
793
|
-
})
|
|
794
|
-
})
|
|
787
|
+
const {
|
|
788
|
+
toolName,
|
|
789
|
+
params
|
|
790
|
+
} = yield* normalizeMcpToolCall({
|
|
791
|
+
toolNameMapper,
|
|
792
|
+
toolParams: part.arguments,
|
|
793
|
+
method: "makeResponse"
|
|
795
794
|
});
|
|
796
795
|
parts.push({
|
|
797
796
|
type: "tool-call",
|
|
@@ -952,9 +951,7 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
952
951
|
action: part.action
|
|
953
952
|
},
|
|
954
953
|
metadata: {
|
|
955
|
-
openai:
|
|
956
|
-
...makeItemIdMetadata(part.id)
|
|
957
|
-
}
|
|
954
|
+
openai: makeItemIdMetadata(part.id)
|
|
958
955
|
}
|
|
959
956
|
});
|
|
960
957
|
break;
|
|
@@ -990,13 +987,7 @@ const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
990
987
|
reason: finishReason,
|
|
991
988
|
usage: getUsage(rawResponse.usage),
|
|
992
989
|
response: buildHttpResponseDetails(response),
|
|
993
|
-
...(rawResponse.service_tier
|
|
994
|
-
metadata: {
|
|
995
|
-
openai: {
|
|
996
|
-
serviceTier: rawResponse.service_tier
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
})
|
|
990
|
+
...toServiceTier(rawResponse.service_tier)
|
|
1000
991
|
});
|
|
1001
992
|
return parts;
|
|
1002
993
|
});
|
|
@@ -1015,11 +1006,29 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1015
1006
|
const activeAnnotations = [];
|
|
1016
1007
|
// Track active reasoning items with state machine for proper concluding logic
|
|
1017
1008
|
const activeReasoning = {};
|
|
1009
|
+
const getOrCreateReasoningPart = (itemId, encryptedContent) => {
|
|
1010
|
+
const activePart = activeReasoning[itemId];
|
|
1011
|
+
if (Predicate.isNotUndefined(activePart)) {
|
|
1012
|
+
if (Predicate.isNotNullish(encryptedContent)) {
|
|
1013
|
+
activePart.encryptedContent = encryptedContent;
|
|
1014
|
+
}
|
|
1015
|
+
return activePart;
|
|
1016
|
+
}
|
|
1017
|
+
const reasoningPart = {
|
|
1018
|
+
encryptedContent: Predicate.isNotNullish(encryptedContent) ? encryptedContent : undefined,
|
|
1019
|
+
summaryParts: {}
|
|
1020
|
+
};
|
|
1021
|
+
activeReasoning[itemId] = reasoningPart;
|
|
1022
|
+
return reasoningPart;
|
|
1023
|
+
};
|
|
1018
1024
|
// Track active tool calls with optional provider-specific state
|
|
1019
1025
|
const activeToolCalls = {};
|
|
1020
1026
|
const webSearchTool = options.tools.find(tool => Tool.isProviderDefined(tool) && (tool.name === "OpenAiWebSearch" || tool.name === "OpenAiWebSearchPreview"));
|
|
1021
1027
|
return stream.pipe(Stream.mapEffect(Effect.fnUntraced(function* (event) {
|
|
1022
1028
|
const parts = [];
|
|
1029
|
+
if (!isKnownResponseStreamEvent(event)) {
|
|
1030
|
+
return parts;
|
|
1031
|
+
}
|
|
1023
1032
|
switch (event.type) {
|
|
1024
1033
|
case "response.created":
|
|
1025
1034
|
{
|
|
@@ -1050,13 +1059,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1050
1059
|
reason: InternalUtilities.resolveFinishReason(event.response.incomplete_details?.reason, hasToolCalls),
|
|
1051
1060
|
usage: getUsage(event.response.usage),
|
|
1052
1061
|
response: buildHttpResponseDetails(response),
|
|
1053
|
-
...(event.response.service_tier
|
|
1054
|
-
metadata: {
|
|
1055
|
-
openai: {
|
|
1056
|
-
serviceTier: event.response.service_tier
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
})
|
|
1062
|
+
...toServiceTier(event.response.service_tier)
|
|
1060
1063
|
});
|
|
1061
1064
|
break;
|
|
1062
1065
|
}
|
|
@@ -1157,7 +1160,10 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1157
1160
|
{
|
|
1158
1161
|
activeToolCalls[event.output_index] = {
|
|
1159
1162
|
id: event.item.call_id,
|
|
1160
|
-
name: event.item.name
|
|
1163
|
+
name: event.item.name,
|
|
1164
|
+
functionCall: {
|
|
1165
|
+
emitted: false
|
|
1166
|
+
}
|
|
1161
1167
|
};
|
|
1162
1168
|
parts.push({
|
|
1163
1169
|
type: "tool-params-start",
|
|
@@ -1195,39 +1201,34 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1195
1201
|
type: "text-start",
|
|
1196
1202
|
id: event.item.id,
|
|
1197
1203
|
metadata: {
|
|
1198
|
-
openai:
|
|
1199
|
-
...makeItemIdMetadata(event.item.id)
|
|
1200
|
-
}
|
|
1204
|
+
openai: makeItemIdMetadata(event.item.id)
|
|
1201
1205
|
}
|
|
1202
1206
|
});
|
|
1203
1207
|
break;
|
|
1204
1208
|
}
|
|
1205
1209
|
case "reasoning":
|
|
1206
1210
|
{
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
openai: {
|
|
1219
|
-
...makeItemIdMetadata(event.item.id),
|
|
1220
|
-
...makeEncryptedContentMetadata(event.item.encrypted_content)
|
|
1211
|
+
const reasoningPart = getOrCreateReasoningPart(event.item.id, event.item.encrypted_content);
|
|
1212
|
+
if (Predicate.isUndefined(reasoningPart.summaryParts[0])) {
|
|
1213
|
+
reasoningPart.summaryParts[0] = "active";
|
|
1214
|
+
parts.push({
|
|
1215
|
+
type: "reasoning-start",
|
|
1216
|
+
id: `${event.item.id}:0`,
|
|
1217
|
+
metadata: {
|
|
1218
|
+
openai: {
|
|
1219
|
+
...makeItemIdMetadata(event.item.id),
|
|
1220
|
+
...makeEncryptedContentMetadata(reasoningPart.encryptedContent)
|
|
1221
|
+
}
|
|
1221
1222
|
}
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1224
1225
|
break;
|
|
1225
1226
|
}
|
|
1226
1227
|
case "shell_call":
|
|
1227
1228
|
{
|
|
1228
1229
|
const toolName = toolNameMapper.getCustomName("shell");
|
|
1229
1230
|
activeToolCalls[event.output_index] = {
|
|
1230
|
-
id: event.item.id,
|
|
1231
|
+
id: event.item.id ?? event.item.call_id,
|
|
1231
1232
|
name: toolName
|
|
1232
1233
|
};
|
|
1233
1234
|
break;
|
|
@@ -1272,7 +1273,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1272
1273
|
parts.push({
|
|
1273
1274
|
type: "tool-params-delta",
|
|
1274
1275
|
id: toolCall.id,
|
|
1275
|
-
delta: InternalUtilities.escapeJSONDelta(event.item.operation.diff)
|
|
1276
|
+
delta: InternalUtilities.escapeJSONDelta(event.item.operation.diff ?? "")
|
|
1276
1277
|
});
|
|
1277
1278
|
}
|
|
1278
1279
|
parts.push({
|
|
@@ -1298,9 +1299,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1298
1299
|
operation: event.item.operation
|
|
1299
1300
|
},
|
|
1300
1301
|
metadata: {
|
|
1301
|
-
openai:
|
|
1302
|
-
...makeItemIdMetadata(event.item.id)
|
|
1303
|
-
}
|
|
1302
|
+
openai: makeItemIdMetadata(event.item.id)
|
|
1304
1303
|
}
|
|
1305
1304
|
});
|
|
1306
1305
|
}
|
|
@@ -1372,12 +1371,17 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1372
1371
|
}
|
|
1373
1372
|
case "function_call":
|
|
1374
1373
|
{
|
|
1374
|
+
const toolCall = activeToolCalls[event.output_index];
|
|
1375
|
+
if (Predicate.isNotUndefined(toolCall?.functionCall?.emitted) && toolCall.functionCall.emitted) {
|
|
1376
|
+
delete activeToolCalls[event.output_index];
|
|
1377
|
+
break;
|
|
1378
|
+
}
|
|
1375
1379
|
delete activeToolCalls[event.output_index];
|
|
1376
1380
|
hasToolCalls = true;
|
|
1377
1381
|
const toolName = event.item.name;
|
|
1378
|
-
const
|
|
1379
|
-
const
|
|
1380
|
-
try: () => Tool.unsafeSecureJsonParse(
|
|
1382
|
+
const toolArgs = event.item.arguments;
|
|
1383
|
+
const toolParams = yield* Effect.try({
|
|
1384
|
+
try: () => Tool.unsafeSecureJsonParse(toolArgs),
|
|
1381
1385
|
catch: cause => AiError.make({
|
|
1382
1386
|
module: "OpenAiLanguageModel",
|
|
1383
1387
|
method: "makeStreamResponse",
|
|
@@ -1388,6 +1392,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1388
1392
|
})
|
|
1389
1393
|
})
|
|
1390
1394
|
});
|
|
1395
|
+
const params = yield* transformToolCallParams(options.tools, toolName, toolParams);
|
|
1391
1396
|
parts.push({
|
|
1392
1397
|
type: "tool-params-end",
|
|
1393
1398
|
id: event.item.call_id
|
|
@@ -1398,9 +1403,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1398
1403
|
name: toolName,
|
|
1399
1404
|
params,
|
|
1400
1405
|
metadata: {
|
|
1401
|
-
openai:
|
|
1402
|
-
...makeItemIdMetadata(event.item.id)
|
|
1403
|
-
}
|
|
1406
|
+
openai: makeItemIdMetadata(event.item.id)
|
|
1404
1407
|
}
|
|
1405
1408
|
});
|
|
1406
1409
|
break;
|
|
@@ -1431,9 +1434,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1431
1434
|
action: event.item.action
|
|
1432
1435
|
},
|
|
1433
1436
|
metadata: {
|
|
1434
|
-
openai:
|
|
1435
|
-
...makeItemIdMetadata(event.item.id)
|
|
1436
|
-
}
|
|
1437
|
+
openai: makeItemIdMetadata(event.item.id)
|
|
1437
1438
|
}
|
|
1438
1439
|
});
|
|
1439
1440
|
break;
|
|
@@ -1443,12 +1444,19 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1443
1444
|
const approvalRequestId = event.item.approval_request_id;
|
|
1444
1445
|
// Track approval with our own tool call identifiers
|
|
1445
1446
|
const toolId = Predicate.isNotNullish(approvalRequestId) ? streamApprovalRequests.get(approvalRequestId) ?? approvalRequests.get(approvalRequestId) ?? event.item.id : event.item.id;
|
|
1446
|
-
const
|
|
1447
|
+
const {
|
|
1448
|
+
toolName,
|
|
1449
|
+
params
|
|
1450
|
+
} = yield* normalizeMcpToolCall({
|
|
1451
|
+
toolNameMapper,
|
|
1452
|
+
toolParams: event.item.arguments,
|
|
1453
|
+
method: "makeStreamResponse"
|
|
1454
|
+
});
|
|
1447
1455
|
parts.push({
|
|
1448
1456
|
type: "tool-call",
|
|
1449
1457
|
id: toolId,
|
|
1450
1458
|
name: toolName,
|
|
1451
|
-
params
|
|
1459
|
+
params,
|
|
1452
1460
|
providerExecuted: true
|
|
1453
1461
|
});
|
|
1454
1462
|
parts.push({
|
|
@@ -1458,7 +1466,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1458
1466
|
isFailure: false,
|
|
1459
1467
|
providerExecuted: true,
|
|
1460
1468
|
result: {
|
|
1461
|
-
type: "
|
|
1469
|
+
type: "mcp_call",
|
|
1462
1470
|
name: event.item.name,
|
|
1463
1471
|
arguments: event.item.arguments,
|
|
1464
1472
|
server_label: event.item.server_label,
|
|
@@ -1470,9 +1478,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1470
1478
|
} : undefined)
|
|
1471
1479
|
},
|
|
1472
1480
|
metadata: {
|
|
1473
|
-
openai:
|
|
1474
|
-
...makeItemIdMetadata(event.item.id)
|
|
1475
|
-
}
|
|
1481
|
+
openai: makeItemIdMetadata(event.item.id)
|
|
1476
1482
|
}
|
|
1477
1483
|
});
|
|
1478
1484
|
break;
|
|
@@ -1487,12 +1493,19 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1487
1493
|
const toolId = yield* idGenerator.generateId();
|
|
1488
1494
|
const approvalRequestId = event.item.approval_request_id ?? event.item.id;
|
|
1489
1495
|
streamApprovalRequests.set(approvalRequestId, toolId);
|
|
1490
|
-
const
|
|
1496
|
+
const {
|
|
1497
|
+
toolName,
|
|
1498
|
+
params
|
|
1499
|
+
} = yield* normalizeMcpToolCall({
|
|
1500
|
+
toolNameMapper,
|
|
1501
|
+
toolParams: event.item.arguments,
|
|
1502
|
+
method: "makeStreamResponse"
|
|
1503
|
+
});
|
|
1491
1504
|
parts.push({
|
|
1492
1505
|
type: "tool-call",
|
|
1493
1506
|
id: toolId,
|
|
1494
1507
|
name: toolName,
|
|
1495
|
-
params
|
|
1508
|
+
params,
|
|
1496
1509
|
providerExecuted: true
|
|
1497
1510
|
});
|
|
1498
1511
|
parts.push({
|
|
@@ -1521,7 +1534,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1521
1534
|
}
|
|
1522
1535
|
case "reasoning":
|
|
1523
1536
|
{
|
|
1524
|
-
const reasoningPart =
|
|
1537
|
+
const reasoningPart = getOrCreateReasoningPart(event.item.id, event.item.encrypted_content);
|
|
1525
1538
|
for (const [summaryIndex, status] of Object.entries(reasoningPart.summaryParts)) {
|
|
1526
1539
|
if (status === "active" || status === "can-conclude") {
|
|
1527
1540
|
parts.push({
|
|
@@ -1530,7 +1543,7 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1530
1543
|
metadata: {
|
|
1531
1544
|
openai: {
|
|
1532
1545
|
...makeItemIdMetadata(event.item.id),
|
|
1533
|
-
...makeEncryptedContentMetadata(
|
|
1546
|
+
...makeEncryptedContentMetadata(reasoningPart.encryptedContent)
|
|
1534
1547
|
}
|
|
1535
1548
|
}
|
|
1536
1549
|
});
|
|
@@ -1545,15 +1558,13 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1545
1558
|
const toolName = toolNameMapper.getCustomName("shell");
|
|
1546
1559
|
parts.push({
|
|
1547
1560
|
type: "tool-call",
|
|
1548
|
-
id: event.item.id,
|
|
1561
|
+
id: event.item.id ?? event.item.call_id,
|
|
1549
1562
|
name: toolName,
|
|
1550
1563
|
params: {
|
|
1551
1564
|
action: event.item.action
|
|
1552
1565
|
},
|
|
1553
1566
|
metadata: {
|
|
1554
|
-
openai:
|
|
1555
|
-
...makeItemIdMetadata(event.item.id)
|
|
1556
|
-
}
|
|
1567
|
+
openai: makeItemIdMetadata(event.item.id)
|
|
1557
1568
|
}
|
|
1558
1569
|
});
|
|
1559
1570
|
break;
|
|
@@ -1670,6 +1681,41 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1670
1681
|
}
|
|
1671
1682
|
break;
|
|
1672
1683
|
}
|
|
1684
|
+
case "response.function_call_arguments.done":
|
|
1685
|
+
{
|
|
1686
|
+
const toolCall = activeToolCalls[event.output_index];
|
|
1687
|
+
if (Predicate.isNotUndefined(toolCall?.functionCall) && !toolCall.functionCall.emitted) {
|
|
1688
|
+
hasToolCalls = true;
|
|
1689
|
+
const toolParams = yield* Effect.try({
|
|
1690
|
+
try: () => Tool.unsafeSecureJsonParse(event.arguments),
|
|
1691
|
+
catch: cause => AiError.make({
|
|
1692
|
+
module: "OpenAiLanguageModel",
|
|
1693
|
+
method: "makeStreamResponse",
|
|
1694
|
+
reason: new AiError.ToolParameterValidationError({
|
|
1695
|
+
toolName: toolCall.name,
|
|
1696
|
+
toolParams: {},
|
|
1697
|
+
description: `Failed securely JSON parse tool parameters: ${cause}`
|
|
1698
|
+
})
|
|
1699
|
+
})
|
|
1700
|
+
});
|
|
1701
|
+
const params = yield* transformToolCallParams(options.tools, toolCall.name, toolParams);
|
|
1702
|
+
parts.push({
|
|
1703
|
+
type: "tool-params-end",
|
|
1704
|
+
id: toolCall.id
|
|
1705
|
+
});
|
|
1706
|
+
parts.push({
|
|
1707
|
+
type: "tool-call",
|
|
1708
|
+
id: toolCall.id,
|
|
1709
|
+
name: toolCall.name,
|
|
1710
|
+
params,
|
|
1711
|
+
metadata: {
|
|
1712
|
+
openai: makeItemIdMetadata(event.item_id)
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
toolCall.functionCall.emitted = true;
|
|
1716
|
+
}
|
|
1717
|
+
break;
|
|
1718
|
+
}
|
|
1673
1719
|
case "response.apply_patch_call_operation_diff.delta":
|
|
1674
1720
|
{
|
|
1675
1721
|
const toolCall = activeToolCalls[event.output_index];
|
|
@@ -1765,28 +1811,27 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1765
1811
|
}
|
|
1766
1812
|
case "response.reasoning_summary_part.added":
|
|
1767
1813
|
{
|
|
1768
|
-
|
|
1814
|
+
const reasoningPart = getOrCreateReasoningPart(event.item_id);
|
|
1769
1815
|
if (event.summary_index > 0) {
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
...makeItemIdMetadata(event.item_id),
|
|
1781
|
-
...makeEncryptedContentMetadata(reasoningPart.encryptedContent)
|
|
1782
|
-
}
|
|
1816
|
+
// Conclude all can-conclude parts before starting new one
|
|
1817
|
+
for (const [summaryIndex, status] of Object.entries(reasoningPart.summaryParts)) {
|
|
1818
|
+
if (status === "can-conclude") {
|
|
1819
|
+
parts.push({
|
|
1820
|
+
type: "reasoning-end",
|
|
1821
|
+
id: `${event.item_id}:${summaryIndex}`,
|
|
1822
|
+
metadata: {
|
|
1823
|
+
openai: {
|
|
1824
|
+
...makeItemIdMetadata(event.item_id),
|
|
1825
|
+
...makeEncryptedContentMetadata(reasoningPart.encryptedContent)
|
|
1783
1826
|
}
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
|
|
1827
|
+
}
|
|
1828
|
+
});
|
|
1829
|
+
reasoningPart.summaryParts[Number(summaryIndex)] = "concluded";
|
|
1787
1830
|
}
|
|
1788
|
-
reasoningPart.summaryParts[event.summary_index] = "active";
|
|
1789
1831
|
}
|
|
1832
|
+
}
|
|
1833
|
+
if (Predicate.isUndefined(reasoningPart.summaryParts[event.summary_index])) {
|
|
1834
|
+
reasoningPart.summaryParts[event.summary_index] = "active";
|
|
1790
1835
|
parts.push({
|
|
1791
1836
|
type: "reasoning-start",
|
|
1792
1837
|
id: `${event.item_id}:${event.summary_index}`,
|
|
@@ -1807,15 +1852,14 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1807
1852
|
id: `${event.item_id}:${event.summary_index}`,
|
|
1808
1853
|
delta: event.delta,
|
|
1809
1854
|
metadata: {
|
|
1810
|
-
openai:
|
|
1811
|
-
...makeItemIdMetadata(event.item_id)
|
|
1812
|
-
}
|
|
1855
|
+
openai: makeItemIdMetadata(event.item_id)
|
|
1813
1856
|
}
|
|
1814
1857
|
});
|
|
1815
1858
|
break;
|
|
1816
1859
|
}
|
|
1817
1860
|
case "response.reasoning_summary_part.done":
|
|
1818
1861
|
{
|
|
1862
|
+
const reasoningPart = getOrCreateReasoningPart(event.item_id);
|
|
1819
1863
|
// When OpenAI stores message data, we can immediately conclude the
|
|
1820
1864
|
// reasoning part given that we do not need the encrypted content
|
|
1821
1865
|
if (config.store === true) {
|
|
@@ -1823,17 +1867,15 @@ const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1823
1867
|
type: "reasoning-end",
|
|
1824
1868
|
id: `${event.item_id}:${event.summary_index}`,
|
|
1825
1869
|
metadata: {
|
|
1826
|
-
openai:
|
|
1827
|
-
...makeItemIdMetadata(event.item_id)
|
|
1828
|
-
}
|
|
1870
|
+
openai: makeItemIdMetadata(event.item_id)
|
|
1829
1871
|
}
|
|
1830
1872
|
});
|
|
1831
1873
|
// Mark the summary part concluded
|
|
1832
|
-
|
|
1874
|
+
reasoningPart.summaryParts[event.summary_index] = "concluded";
|
|
1833
1875
|
} else {
|
|
1834
1876
|
// Mark the summary part as can-conclude given we still need a
|
|
1835
1877
|
// final summary part with the encrypted content
|
|
1836
|
-
|
|
1878
|
+
reasoningPart.summaryParts[event.summary_index] = "can-conclude";
|
|
1837
1879
|
}
|
|
1838
1880
|
break;
|
|
1839
1881
|
}
|
|
@@ -1936,14 +1978,18 @@ const prepareTools = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
|
1936
1978
|
}
|
|
1937
1979
|
// Convert the tools in the toolkit to the provider-defined format
|
|
1938
1980
|
for (const tool of allowedTools) {
|
|
1939
|
-
if (Tool.isUserDefined(tool)) {
|
|
1981
|
+
if (Tool.isUserDefined(tool) || Tool.isDynamic(tool)) {
|
|
1940
1982
|
const strict = Tool.getStrictMode(tool) ?? config.strictJsonSchema ?? true;
|
|
1983
|
+
const description = Tool.getDescription(tool);
|
|
1984
|
+
const parameters = yield* tryToolJsonSchema(tool, "prepareTools");
|
|
1941
1985
|
tools.push({
|
|
1942
1986
|
type: "function",
|
|
1943
1987
|
name: tool.name,
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1988
|
+
parameters,
|
|
1989
|
+
strict,
|
|
1990
|
+
...(Predicate.isNotUndefined(description) ? {
|
|
1991
|
+
description
|
|
1992
|
+
} : undefined)
|
|
1947
1993
|
});
|
|
1948
1994
|
}
|
|
1949
1995
|
if (Tool.isProviderDefined(tool)) {
|
|
@@ -2111,29 +2157,53 @@ const getEncryptedContent = part => part.options.openai?.encryptedContent ?? nul
|
|
|
2111
2157
|
const getImageDetail = part => part.options.openai?.imageDetail ?? "auto";
|
|
2112
2158
|
const makeItemIdMetadata = itemId => Predicate.isNotUndefined(itemId) ? {
|
|
2113
2159
|
itemId
|
|
2114
|
-
} :
|
|
2160
|
+
} : {};
|
|
2115
2161
|
const makeEncryptedContentMetadata = encryptedContent => Predicate.isNotNullish(encryptedContent) ? {
|
|
2116
2162
|
encryptedContent
|
|
2117
2163
|
} : undefined;
|
|
2118
|
-
const
|
|
2164
|
+
const unsupportedSchemaError = (error, method) => AiError.make({
|
|
2165
|
+
module: "OpenAiLanguageModel",
|
|
2166
|
+
method,
|
|
2167
|
+
reason: new AiError.UnsupportedSchemaError({
|
|
2168
|
+
description: error instanceof Error ? error.message : String(error)
|
|
2169
|
+
})
|
|
2170
|
+
});
|
|
2171
|
+
const tryCodecTransform = (schema, method) => Effect.try({
|
|
2172
|
+
try: () => toCodecOpenAI(schema),
|
|
2173
|
+
catch: error => unsupportedSchemaError(error, method)
|
|
2174
|
+
});
|
|
2175
|
+
const tryJsonSchema = (schema, method) => Effect.try({
|
|
2176
|
+
try: () => Tool.getJsonSchemaFromSchema(schema, {
|
|
2177
|
+
transformer: toCodecOpenAI
|
|
2178
|
+
}),
|
|
2179
|
+
catch: error => unsupportedSchemaError(error, method)
|
|
2180
|
+
});
|
|
2181
|
+
const tryToolJsonSchema = (tool, method) => Effect.try({
|
|
2182
|
+
try: () => Tool.getJsonSchema(tool, {
|
|
2183
|
+
transformer: toCodecOpenAI
|
|
2184
|
+
}),
|
|
2185
|
+
catch: error => unsupportedSchemaError(error, method)
|
|
2186
|
+
});
|
|
2187
|
+
const prepareResponseFormat = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
2119
2188
|
config,
|
|
2120
2189
|
options
|
|
2121
|
-
})
|
|
2190
|
+
}) {
|
|
2122
2191
|
if (options.responseFormat.type === "json") {
|
|
2123
2192
|
const name = options.responseFormat.objectName;
|
|
2124
2193
|
const schema = options.responseFormat.schema;
|
|
2194
|
+
const jsonSchema = yield* tryJsonSchema(schema, "prepareResponseFormat");
|
|
2125
2195
|
return {
|
|
2126
2196
|
type: "json_schema",
|
|
2127
2197
|
name,
|
|
2128
2198
|
description: AST.resolveDescription(schema.ast) ?? "Response with a JSON object",
|
|
2129
|
-
schema:
|
|
2199
|
+
schema: jsonSchema,
|
|
2130
2200
|
strict: config.strictJsonSchema ?? true
|
|
2131
2201
|
};
|
|
2132
2202
|
}
|
|
2133
2203
|
return {
|
|
2134
2204
|
type: "text"
|
|
2135
2205
|
};
|
|
2136
|
-
};
|
|
2206
|
+
});
|
|
2137
2207
|
const getModelCapabilities = modelId => {
|
|
2138
2208
|
const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
|
|
2139
2209
|
const supportsPriorityProcessing = modelId.startsWith("gpt-4") || modelId.startsWith("gpt-5-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-nano") && !modelId.startsWith("gpt-5-chat") || modelId.startsWith("o3") || modelId.startsWith("o4-mini");
|
|
@@ -2170,6 +2240,35 @@ const getApprovalRequestIdMapping = prompt => {
|
|
|
2170
2240
|
}
|
|
2171
2241
|
return mapping;
|
|
2172
2242
|
};
|
|
2243
|
+
const normalizeMcpToolCall = /*#__PURE__*/Effect.fnUntraced(function* ({
|
|
2244
|
+
toolNameMapper,
|
|
2245
|
+
toolParams,
|
|
2246
|
+
method
|
|
2247
|
+
}) {
|
|
2248
|
+
const toolName = toolNameMapper.getCustomName("mcp");
|
|
2249
|
+
if (typeof toolParams !== "string") {
|
|
2250
|
+
return {
|
|
2251
|
+
toolName,
|
|
2252
|
+
params: toolParams
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
const params = yield* Effect.try({
|
|
2256
|
+
try: () => Tool.unsafeSecureJsonParse(toolParams),
|
|
2257
|
+
catch: cause => AiError.make({
|
|
2258
|
+
module: "OpenAiLanguageModel",
|
|
2259
|
+
method,
|
|
2260
|
+
reason: new AiError.ToolParameterValidationError({
|
|
2261
|
+
toolName,
|
|
2262
|
+
toolParams,
|
|
2263
|
+
description: `Failed to securely JSON parse tool parameters: ${cause}`
|
|
2264
|
+
})
|
|
2265
|
+
})
|
|
2266
|
+
});
|
|
2267
|
+
return {
|
|
2268
|
+
toolName,
|
|
2269
|
+
params
|
|
2270
|
+
};
|
|
2271
|
+
});
|
|
2173
2272
|
const getUsage = usage => {
|
|
2174
2273
|
if (Predicate.isNullish(usage)) {
|
|
2175
2274
|
return {
|
|
@@ -2188,8 +2287,8 @@ const getUsage = usage => {
|
|
|
2188
2287
|
}
|
|
2189
2288
|
const inputTokens = usage.input_tokens;
|
|
2190
2289
|
const outputTokens = usage.output_tokens;
|
|
2191
|
-
const cachedTokens = usage.input_tokens_details
|
|
2192
|
-
const reasoningTokens = usage.output_tokens_details
|
|
2290
|
+
const cachedTokens = getUsageTokenDetail(usage.input_tokens_details, "cached_tokens");
|
|
2291
|
+
const reasoningTokens = getUsageTokenDetail(usage.output_tokens_details, "reasoning_tokens");
|
|
2193
2292
|
return {
|
|
2194
2293
|
inputTokens: {
|
|
2195
2294
|
uncached: inputTokens - cachedTokens,
|
|
@@ -2204,4 +2303,49 @@ const getUsage = usage => {
|
|
|
2204
2303
|
}
|
|
2205
2304
|
};
|
|
2206
2305
|
};
|
|
2306
|
+
const toServiceTier = value => {
|
|
2307
|
+
switch (value) {
|
|
2308
|
+
case "default":
|
|
2309
|
+
case "auto":
|
|
2310
|
+
case "flex":
|
|
2311
|
+
case "scale":
|
|
2312
|
+
case "priority":
|
|
2313
|
+
return {
|
|
2314
|
+
metadata: {
|
|
2315
|
+
openai: {
|
|
2316
|
+
serviceTier: value
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
};
|
|
2320
|
+
default:
|
|
2321
|
+
return undefined;
|
|
2322
|
+
}
|
|
2323
|
+
};
|
|
2324
|
+
const getUsageTokenDetail = (details, key) => Predicate.hasProperty(details, key) && typeof details[key] === "number" ? details[key] : 0;
|
|
2325
|
+
const transformToolCallParams = /*#__PURE__*/Effect.fnUntraced(function* (tools, toolName, toolParams) {
|
|
2326
|
+
const tool = tools.find(tool => tool.name === toolName);
|
|
2327
|
+
if (Predicate.isUndefined(tool)) {
|
|
2328
|
+
return yield* AiError.make({
|
|
2329
|
+
module: "OpenAiLanguageModel",
|
|
2330
|
+
method: "makeResponse",
|
|
2331
|
+
reason: new AiError.ToolNotFoundError({
|
|
2332
|
+
toolName,
|
|
2333
|
+
availableTools: tools.map(tool => tool.name)
|
|
2334
|
+
})
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
const {
|
|
2338
|
+
codec
|
|
2339
|
+
} = yield* tryCodecTransform(tool.parametersSchema, "makeResponse");
|
|
2340
|
+
const transform = Schema.decodeEffect(codec);
|
|
2341
|
+
return yield* transform(toolParams).pipe(Effect.mapError(error => AiError.make({
|
|
2342
|
+
module: "OpenAiLanguageModel",
|
|
2343
|
+
method: "makeResponse",
|
|
2344
|
+
reason: new AiError.ToolParameterValidationError({
|
|
2345
|
+
toolName,
|
|
2346
|
+
toolParams,
|
|
2347
|
+
description: error.issue.toString()
|
|
2348
|
+
})
|
|
2349
|
+
})));
|
|
2350
|
+
});
|
|
2207
2351
|
//# sourceMappingURL=OpenAiLanguageModel.js.map
|