@effect/ai-openai 4.0.0-beta.50 → 4.0.0-beta.52
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/OpenAiClient.d.ts +9 -9
- package/dist/OpenAiClient.d.ts.map +1 -1
- package/dist/OpenAiClient.js +27 -32
- 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/OpenAiEmbeddingModel.d.ts.map +1 -1
- package/dist/OpenAiEmbeddingModel.js +3 -0
- package/dist/OpenAiEmbeddingModel.js.map +1 -1
- package/dist/OpenAiLanguageModel.d.ts +17 -35
- package/dist/OpenAiLanguageModel.d.ts.map +1 -1
- package/dist/OpenAiLanguageModel.js +54 -74
- package/dist/OpenAiLanguageModel.js.map +1 -1
- package/dist/OpenAiSchema.d.ts +1921 -0
- package/dist/OpenAiSchema.d.ts.map +1 -0
- package/dist/OpenAiSchema.js +533 -0
- package/dist/OpenAiSchema.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/OpenAiClient.ts +90 -59
- package/src/OpenAiClientGenerated.ts +202 -0
- package/src/OpenAiEmbeddingModel.ts +6 -3
- package/src/OpenAiLanguageModel.ts +145 -60
- package/src/OpenAiSchema.ts +873 -0
- package/src/index.ts +12 -0
|
@@ -19,7 +19,7 @@ import * as Schema from "effect/Schema"
|
|
|
19
19
|
import * as AST from "effect/SchemaAST"
|
|
20
20
|
import * as Stream from "effect/Stream"
|
|
21
21
|
import type { Span } from "effect/Tracer"
|
|
22
|
-
import type { DeepMutable, Simplify } from "effect/Types"
|
|
22
|
+
import type { DeepMutable, Mutable, Simplify } from "effect/Types"
|
|
23
23
|
import * as AiError from "effect/unstable/ai/AiError"
|
|
24
24
|
import * as IdGenerator from "effect/unstable/ai/IdGenerator"
|
|
25
25
|
import * as LanguageModel from "effect/unstable/ai/LanguageModel"
|
|
@@ -33,6 +33,7 @@ import type * as HttpClientResponse from "effect/unstable/http/HttpClientRespons
|
|
|
33
33
|
import * as Generated from "./Generated.ts"
|
|
34
34
|
import * as InternalUtilities from "./internal/utilities.ts"
|
|
35
35
|
import { OpenAiClient } from "./OpenAiClient.ts"
|
|
36
|
+
import type * as OpenAiSchema from "./OpenAiSchema.ts"
|
|
36
37
|
import { addGenAIAnnotations } from "./OpenAiTelemetry.ts"
|
|
37
38
|
import type * as OpenAiTool from "./OpenAiTool.ts"
|
|
38
39
|
|
|
@@ -65,7 +66,7 @@ export class Config extends Context.Service<
|
|
|
65
66
|
Simplify<
|
|
66
67
|
& Partial<
|
|
67
68
|
Omit<
|
|
68
|
-
typeof
|
|
69
|
+
typeof OpenAiSchema.CreateResponse.Encoded,
|
|
69
70
|
"input" | "tools" | "tool_choice" | "stream" | "text"
|
|
70
71
|
>
|
|
71
72
|
>
|
|
@@ -140,7 +141,7 @@ declare module "effect/unstable/ai/Prompt" {
|
|
|
140
141
|
/**
|
|
141
142
|
* The status of item.
|
|
142
143
|
*/
|
|
143
|
-
readonly status?: typeof
|
|
144
|
+
readonly status?: typeof OpenAiSchema.MessageStatus.Encoded | null
|
|
144
145
|
/**
|
|
145
146
|
* The ID of the approval request.
|
|
146
147
|
*/
|
|
@@ -157,7 +158,7 @@ declare module "effect/unstable/ai/Prompt" {
|
|
|
157
158
|
/**
|
|
158
159
|
* The status of item.
|
|
159
160
|
*/
|
|
160
|
-
readonly status?: typeof
|
|
161
|
+
readonly status?: typeof OpenAiSchema.MessageStatus.Encoded | null
|
|
161
162
|
/**
|
|
162
163
|
* The ID of the approval request.
|
|
163
164
|
*/
|
|
@@ -174,11 +175,11 @@ declare module "effect/unstable/ai/Prompt" {
|
|
|
174
175
|
/**
|
|
175
176
|
* The status of item.
|
|
176
177
|
*/
|
|
177
|
-
readonly status?: typeof
|
|
178
|
+
readonly status?: typeof OpenAiSchema.MessageStatus.Encoded | null
|
|
178
179
|
/**
|
|
179
180
|
* A list of annotations that apply to the output text.
|
|
180
181
|
*/
|
|
181
|
-
readonly annotations?: ReadonlyArray<typeof
|
|
182
|
+
readonly annotations?: ReadonlyArray<typeof OpenAiSchema.Annotation.Encoded> | null
|
|
182
183
|
} | null
|
|
183
184
|
}
|
|
184
185
|
}
|
|
@@ -196,11 +197,11 @@ declare module "effect/unstable/ai/Response" {
|
|
|
196
197
|
/**
|
|
197
198
|
* The status of item.
|
|
198
199
|
*/
|
|
199
|
-
readonly status?: typeof
|
|
200
|
+
readonly status?: typeof OpenAiSchema.MessageStatus.Encoded | null
|
|
200
201
|
/**
|
|
201
202
|
* The text content part annotations.
|
|
202
203
|
*/
|
|
203
|
-
readonly annotations?: ReadonlyArray<typeof
|
|
204
|
+
readonly annotations?: ReadonlyArray<typeof OpenAiSchema.Annotation.Encoded> | null
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
|
|
@@ -213,7 +214,7 @@ declare module "effect/unstable/ai/Response" {
|
|
|
213
214
|
export interface TextEndPartMetadata extends ProviderMetadata {
|
|
214
215
|
readonly openai?: {
|
|
215
216
|
readonly itemId?: string | null
|
|
216
|
-
readonly annotations?: ReadonlyArray<typeof
|
|
217
|
+
readonly annotations?: ReadonlyArray<typeof OpenAiSchema.Annotation.Encoded> | null
|
|
217
218
|
} | null
|
|
218
219
|
}
|
|
219
220
|
|
|
@@ -356,9 +357,9 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig
|
|
|
356
357
|
readonly config: typeof Config.Service
|
|
357
358
|
readonly options: LanguageModel.ProviderOptions
|
|
358
359
|
readonly toolNameMapper: Tool.NameMapper<Tools>
|
|
359
|
-
}): Effect.fn.Return<typeof
|
|
360
|
-
const include = new Set<typeof
|
|
361
|
-
const capabilities = getModelCapabilities(config.model
|
|
360
|
+
}): Effect.fn.Return<typeof OpenAiSchema.CreateResponse.Encoded, AiError.AiError> {
|
|
361
|
+
const include = new Set<typeof OpenAiSchema.IncludeEnum.Encoded>()
|
|
362
|
+
const capabilities = getModelCapabilities(config.model as string)
|
|
362
363
|
const messages = yield* prepareMessages({
|
|
363
364
|
config,
|
|
364
365
|
options,
|
|
@@ -375,18 +376,18 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig
|
|
|
375
376
|
config,
|
|
376
377
|
options
|
|
377
378
|
})
|
|
378
|
-
const request: typeof
|
|
379
|
+
const request: Mutable<typeof OpenAiSchema.CreateResponse.Encoded> = {
|
|
379
380
|
...config,
|
|
380
381
|
input: messages,
|
|
381
382
|
include: include.size > 0 ? Array.from(include) : null,
|
|
382
383
|
text: {
|
|
383
384
|
verbosity: config.text?.verbosity ?? null,
|
|
384
385
|
format: responseFormat
|
|
385
|
-
}
|
|
386
|
-
...(tools ? { tools } : undefined),
|
|
387
|
-
...(toolChoice ? { tool_choice: toolChoice } : undefined),
|
|
388
|
-
...(options.previousResponseId ? { previous_response_id: options.previousResponseId } : undefined)
|
|
386
|
+
}
|
|
389
387
|
}
|
|
388
|
+
if (tools) request.tools = tools
|
|
389
|
+
if (toolChoice) request.tool_choice = toolChoice
|
|
390
|
+
if (options.previousResponseId) request.previous_response_id = options.previousResponseId
|
|
390
391
|
return request
|
|
391
392
|
}
|
|
392
393
|
)
|
|
@@ -516,10 +517,10 @@ const prepareMessages = Effect.fnUntraced(
|
|
|
516
517
|
}: {
|
|
517
518
|
readonly config: typeof Config.Service
|
|
518
519
|
readonly options: LanguageModel.ProviderOptions
|
|
519
|
-
readonly include: Set<typeof
|
|
520
|
+
readonly include: Set<typeof OpenAiSchema.IncludeEnum.Encoded>
|
|
520
521
|
readonly capabilities: ModelCapabilities
|
|
521
522
|
readonly toolNameMapper: Tool.NameMapper<Tools>
|
|
522
|
-
}): Effect.fn.Return<ReadonlyArray<typeof
|
|
523
|
+
}): Effect.fn.Return<ReadonlyArray<typeof OpenAiSchema.InputItem.Encoded>, AiError.AiError> {
|
|
523
524
|
const processedApprovalIds = new Set<string>()
|
|
524
525
|
|
|
525
526
|
const hasConversation = Predicate.isNotNullish(config.conversation)
|
|
@@ -558,21 +559,21 @@ const prepareMessages = Effect.fnUntraced(
|
|
|
558
559
|
include.add("web_search_call.action.sources")
|
|
559
560
|
}
|
|
560
561
|
|
|
561
|
-
const messages: Array<typeof
|
|
562
|
+
const messages: Array<typeof OpenAiSchema.InputItem.Encoded> = []
|
|
562
563
|
const prompt = options.incrementalPrompt ?? options.prompt
|
|
563
564
|
|
|
564
565
|
for (const message of prompt.content) {
|
|
565
566
|
switch (message.role) {
|
|
566
567
|
case "system": {
|
|
567
568
|
messages.push({
|
|
568
|
-
role: getSystemMessageMode(config.model
|
|
569
|
+
role: getSystemMessageMode(config.model as string),
|
|
569
570
|
content: message.content
|
|
570
571
|
})
|
|
571
572
|
break
|
|
572
573
|
}
|
|
573
574
|
|
|
574
575
|
case "user": {
|
|
575
|
-
const content: Array<typeof
|
|
576
|
+
const content: Array<typeof OpenAiSchema.InputContent.Encoded> = []
|
|
576
577
|
|
|
577
578
|
for (let index = 0; index < message.content.length; index++) {
|
|
578
579
|
const part = message.content[index]
|
|
@@ -635,7 +636,7 @@ const prepareMessages = Effect.fnUntraced(
|
|
|
635
636
|
}
|
|
636
637
|
|
|
637
638
|
case "assistant": {
|
|
638
|
-
const reasoningMessages: Record<string, DeepMutable<typeof
|
|
639
|
+
const reasoningMessages: Record<string, DeepMutable<typeof OpenAiSchema.ReasoningItem.Encoded>> = {}
|
|
639
640
|
|
|
640
641
|
for (const part of message.content) {
|
|
641
642
|
switch (part.type) {
|
|
@@ -694,7 +695,7 @@ const prepareMessages = Effect.fnUntraced(
|
|
|
694
695
|
}
|
|
695
696
|
}
|
|
696
697
|
} else {
|
|
697
|
-
const summaryParts: Array<typeof
|
|
698
|
+
const summaryParts: Array<typeof OpenAiSchema.SummaryTextContent.Encoded> = []
|
|
698
699
|
|
|
699
700
|
if (part.text.length > 0) {
|
|
700
701
|
summaryParts.push({ type: "summary_text", text: part.text })
|
|
@@ -705,7 +706,9 @@ const prepareMessages = Effect.fnUntraced(
|
|
|
705
706
|
type: "reasoning",
|
|
706
707
|
id,
|
|
707
708
|
summary: summaryParts,
|
|
708
|
-
|
|
709
|
+
...(Predicate.isNotNull(encryptedContent)
|
|
710
|
+
? { encrypted_content: encryptedContent }
|
|
711
|
+
: undefined)
|
|
709
712
|
}
|
|
710
713
|
|
|
711
714
|
messages.push(reasoningMessages[id])
|
|
@@ -941,7 +944,56 @@ const buildHttpResponseDetails = (
|
|
|
941
944
|
// Response Conversion
|
|
942
945
|
// =============================================================================
|
|
943
946
|
|
|
944
|
-
type ResponseStreamEvent = typeof
|
|
947
|
+
type ResponseStreamEvent = typeof OpenAiSchema.ResponseStreamEvent.Type
|
|
948
|
+
|
|
949
|
+
type KnownResponseStreamEventType =
|
|
950
|
+
| "response.created"
|
|
951
|
+
| "response.completed"
|
|
952
|
+
| "response.incomplete"
|
|
953
|
+
| "response.failed"
|
|
954
|
+
| "response.output_item.added"
|
|
955
|
+
| "response.output_item.done"
|
|
956
|
+
| "response.output_text.delta"
|
|
957
|
+
| "response.output_text.annotation.added"
|
|
958
|
+
| "response.reasoning_summary_part.added"
|
|
959
|
+
| "response.reasoning_summary_part.done"
|
|
960
|
+
| "response.reasoning_summary_text.delta"
|
|
961
|
+
| "response.function_call_arguments.delta"
|
|
962
|
+
| "response.function_call_arguments.done"
|
|
963
|
+
| "response.code_interpreter_call_code.delta"
|
|
964
|
+
| "response.code_interpreter_call_code.done"
|
|
965
|
+
| "response.apply_patch_call_operation_diff.delta"
|
|
966
|
+
| "response.apply_patch_call_operation_diff.done"
|
|
967
|
+
| "response.image_generation_call.partial_image"
|
|
968
|
+
| "error"
|
|
969
|
+
|
|
970
|
+
type KnownResponseStreamEvent = Extract<ResponseStreamEvent, { readonly type: KnownResponseStreamEventType }>
|
|
971
|
+
|
|
972
|
+
const knownResponseStreamEventTypes = new Set<KnownResponseStreamEventType>([
|
|
973
|
+
"response.created",
|
|
974
|
+
"response.completed",
|
|
975
|
+
"response.incomplete",
|
|
976
|
+
"response.failed",
|
|
977
|
+
"response.output_item.added",
|
|
978
|
+
"response.output_item.done",
|
|
979
|
+
"response.output_text.delta",
|
|
980
|
+
"response.output_text.annotation.added",
|
|
981
|
+
"response.reasoning_summary_part.added",
|
|
982
|
+
"response.reasoning_summary_part.done",
|
|
983
|
+
"response.reasoning_summary_text.delta",
|
|
984
|
+
"response.function_call_arguments.delta",
|
|
985
|
+
"response.function_call_arguments.done",
|
|
986
|
+
"response.code_interpreter_call_code.delta",
|
|
987
|
+
"response.code_interpreter_call_code.done",
|
|
988
|
+
"response.apply_patch_call_operation_diff.delta",
|
|
989
|
+
"response.apply_patch_call_operation_diff.done",
|
|
990
|
+
"response.image_generation_call.partial_image",
|
|
991
|
+
"error"
|
|
992
|
+
])
|
|
993
|
+
|
|
994
|
+
const isKnownResponseStreamEvent = (
|
|
995
|
+
event: ResponseStreamEvent
|
|
996
|
+
): event is KnownResponseStreamEvent => knownResponseStreamEventTypes.has(event.type as KnownResponseStreamEventType)
|
|
945
997
|
|
|
946
998
|
const makeResponse = Effect.fnUntraced(
|
|
947
999
|
function*<Tools extends ReadonlyArray<Tool.Any>>({
|
|
@@ -951,7 +1003,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
951
1003
|
toolNameMapper
|
|
952
1004
|
}: {
|
|
953
1005
|
readonly options: LanguageModel.ProviderOptions
|
|
954
|
-
readonly rawResponse:
|
|
1006
|
+
readonly rawResponse: OpenAiSchema.Response
|
|
955
1007
|
readonly response: HttpClientResponse.HttpClientResponse
|
|
956
1008
|
readonly toolNameMapper: Tool.NameMapper<Tools>
|
|
957
1009
|
}): Effect.fn.Return<
|
|
@@ -990,7 +1042,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
990
1042
|
id: part.call_id,
|
|
991
1043
|
name: toolName,
|
|
992
1044
|
params: { call_id: part.call_id, operation: part.operation },
|
|
993
|
-
metadata: { openai:
|
|
1045
|
+
metadata: { openai: makeItemIdMetadata(part.id) }
|
|
994
1046
|
})
|
|
995
1047
|
break
|
|
996
1048
|
}
|
|
@@ -1065,7 +1117,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
1065
1117
|
id: part.call_id,
|
|
1066
1118
|
name: toolName,
|
|
1067
1119
|
params,
|
|
1068
|
-
metadata: { openai:
|
|
1120
|
+
metadata: { openai: makeItemIdMetadata(part.id) }
|
|
1069
1121
|
})
|
|
1070
1122
|
break
|
|
1071
1123
|
}
|
|
@@ -1096,7 +1148,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
1096
1148
|
id: part.call_id,
|
|
1097
1149
|
name: toolName,
|
|
1098
1150
|
params: { action: part.action },
|
|
1099
|
-
metadata: { openai:
|
|
1151
|
+
metadata: { openai: makeItemIdMetadata(part.id) }
|
|
1100
1152
|
})
|
|
1101
1153
|
break
|
|
1102
1154
|
}
|
|
@@ -1130,7 +1182,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
1130
1182
|
...(Predicate.isNotNullish(part.output) ? { output: part.output } : undefined),
|
|
1131
1183
|
...(Predicate.isNotNullish(part.error) ? { error: part.error } : undefined)
|
|
1132
1184
|
},
|
|
1133
|
-
metadata: { openai:
|
|
1185
|
+
metadata: { openai: makeItemIdMetadata(part.id) }
|
|
1134
1186
|
})
|
|
1135
1187
|
|
|
1136
1188
|
break
|
|
@@ -1147,7 +1199,12 @@ const makeResponse = Effect.fnUntraced(
|
|
|
1147
1199
|
const toolName = `mcp.${part.name}`
|
|
1148
1200
|
|
|
1149
1201
|
const params = yield* Effect.try({
|
|
1150
|
-
try: () =>
|
|
1202
|
+
try: () =>
|
|
1203
|
+
Tool.unsafeSecureJsonParse(
|
|
1204
|
+
typeof part.arguments === "string"
|
|
1205
|
+
? part.arguments
|
|
1206
|
+
: JSON.stringify(part.arguments)
|
|
1207
|
+
),
|
|
1151
1208
|
catch: (cause) =>
|
|
1152
1209
|
AiError.make({
|
|
1153
1210
|
module: "OpenAiLanguageModel",
|
|
@@ -1305,7 +1362,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
1305
1362
|
id: part.call_id,
|
|
1306
1363
|
name: toolName,
|
|
1307
1364
|
params: { action: part.action },
|
|
1308
|
-
metadata: { openai:
|
|
1365
|
+
metadata: { openai: makeItemIdMetadata(part.id) }
|
|
1309
1366
|
})
|
|
1310
1367
|
break
|
|
1311
1368
|
}
|
|
@@ -1344,7 +1401,7 @@ const makeResponse = Effect.fnUntraced(
|
|
|
1344
1401
|
reason: finishReason,
|
|
1345
1402
|
usage: getUsage(rawResponse.usage),
|
|
1346
1403
|
response: buildHttpResponseDetails(response),
|
|
1347
|
-
...(rawResponse.service_tier
|
|
1404
|
+
...toServiceTier(rawResponse.service_tier)
|
|
1348
1405
|
})
|
|
1349
1406
|
|
|
1350
1407
|
return parts
|
|
@@ -1377,7 +1434,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1377
1434
|
let hasToolCalls = false
|
|
1378
1435
|
|
|
1379
1436
|
// Track annotations for current message to include in text-end metadata
|
|
1380
|
-
const activeAnnotations: Array<typeof
|
|
1437
|
+
const activeAnnotations: Array<typeof OpenAiSchema.Annotation.Encoded> = []
|
|
1381
1438
|
|
|
1382
1439
|
type ReasoningSummaryPartStatus = "active" | "can-conclude" | "concluded"
|
|
1383
1440
|
type ReasoningPart = {
|
|
@@ -1434,6 +1491,10 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1434
1491
|
Stream.mapEffect(Effect.fnUntraced(function*(event) {
|
|
1435
1492
|
const parts: Array<Response.StreamPartEncoded> = []
|
|
1436
1493
|
|
|
1494
|
+
if (!isKnownResponseStreamEvent(event)) {
|
|
1495
|
+
return parts
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1437
1498
|
switch (event.type) {
|
|
1438
1499
|
case "response.created": {
|
|
1439
1500
|
const createdAt = new Date(event.response.created_at * 1000)
|
|
@@ -1463,7 +1524,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1463
1524
|
),
|
|
1464
1525
|
usage: getUsage(event.response.usage),
|
|
1465
1526
|
response: buildHttpResponseDetails(response),
|
|
1466
|
-
...(event.response.service_tier
|
|
1527
|
+
...toServiceTier(event.response.service_tier)
|
|
1467
1528
|
})
|
|
1468
1529
|
break
|
|
1469
1530
|
}
|
|
@@ -1602,7 +1663,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1602
1663
|
parts.push({
|
|
1603
1664
|
type: "text-start",
|
|
1604
1665
|
id: event.item.id,
|
|
1605
|
-
metadata: { openai:
|
|
1666
|
+
metadata: { openai: makeItemIdMetadata(event.item.id) }
|
|
1606
1667
|
})
|
|
1607
1668
|
break
|
|
1608
1669
|
}
|
|
@@ -1628,7 +1689,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1628
1689
|
case "shell_call": {
|
|
1629
1690
|
const toolName = toolNameMapper.getCustomName("shell")
|
|
1630
1691
|
activeToolCalls[event.output_index] = {
|
|
1631
|
-
id: event.item.id,
|
|
1692
|
+
id: event.item.id ?? event.item.call_id,
|
|
1632
1693
|
name: toolName
|
|
1633
1694
|
}
|
|
1634
1695
|
break
|
|
@@ -1679,7 +1740,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1679
1740
|
parts.push({
|
|
1680
1741
|
type: "tool-params-delta",
|
|
1681
1742
|
id: toolCall.id,
|
|
1682
|
-
delta: InternalUtilities.escapeJSONDelta(event.item.operation.diff)
|
|
1743
|
+
delta: InternalUtilities.escapeJSONDelta(event.item.operation.diff ?? "")
|
|
1683
1744
|
})
|
|
1684
1745
|
}
|
|
1685
1746
|
parts.push({
|
|
@@ -1701,7 +1762,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1701
1762
|
id: toolCall.id,
|
|
1702
1763
|
name: toolName,
|
|
1703
1764
|
params: { call_id: event.item.call_id, operation: event.item.operation },
|
|
1704
|
-
metadata: { openai:
|
|
1765
|
+
metadata: { openai: makeItemIdMetadata(event.item.id) }
|
|
1705
1766
|
})
|
|
1706
1767
|
}
|
|
1707
1768
|
delete activeToolCalls[event.output_index]
|
|
@@ -1802,7 +1863,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1802
1863
|
id: event.item.call_id,
|
|
1803
1864
|
name: toolName,
|
|
1804
1865
|
params,
|
|
1805
|
-
metadata: { openai:
|
|
1866
|
+
metadata: { openai: makeItemIdMetadata(event.item.id) }
|
|
1806
1867
|
})
|
|
1807
1868
|
|
|
1808
1869
|
break
|
|
@@ -1828,7 +1889,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1828
1889
|
id: event.item.call_id,
|
|
1829
1890
|
name: toolName,
|
|
1830
1891
|
params: { action: event.item.action },
|
|
1831
|
-
metadata: { openai:
|
|
1892
|
+
metadata: { openai: makeItemIdMetadata(event.item.id) }
|
|
1832
1893
|
})
|
|
1833
1894
|
break
|
|
1834
1895
|
}
|
|
@@ -1866,7 +1927,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1866
1927
|
...(Predicate.isNotNullish(event.item.output) ? { output: event.item.output } : undefined),
|
|
1867
1928
|
...(Predicate.isNotNullish(event.item.error) ? { error: event.item.error } : undefined)
|
|
1868
1929
|
},
|
|
1869
|
-
metadata: { openai:
|
|
1930
|
+
metadata: { openai: makeItemIdMetadata(event.item.id) }
|
|
1870
1931
|
})
|
|
1871
1932
|
|
|
1872
1933
|
break
|
|
@@ -1934,10 +1995,10 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1934
1995
|
const toolName = toolNameMapper.getCustomName("shell")
|
|
1935
1996
|
parts.push({
|
|
1936
1997
|
type: "tool-call",
|
|
1937
|
-
id: event.item.id,
|
|
1998
|
+
id: event.item.id ?? event.item.call_id,
|
|
1938
1999
|
name: toolName,
|
|
1939
2000
|
params: { action: event.item.action },
|
|
1940
|
-
metadata: { openai:
|
|
2001
|
+
metadata: { openai: makeItemIdMetadata(event.item.id) }
|
|
1941
2002
|
})
|
|
1942
2003
|
break
|
|
1943
2004
|
}
|
|
@@ -1972,7 +2033,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
1972
2033
|
}
|
|
1973
2034
|
|
|
1974
2035
|
case "response.output_text.annotation.added": {
|
|
1975
|
-
const annotation = event.annotation as typeof
|
|
2036
|
+
const annotation = event.annotation as typeof OpenAiSchema.Annotation.Encoded
|
|
1976
2037
|
// Track annotation for text-end metadata
|
|
1977
2038
|
activeAnnotations.push(annotation)
|
|
1978
2039
|
if (annotation.type === "container_file_citation") {
|
|
@@ -2088,7 +2149,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
2088
2149
|
id: toolCall.id,
|
|
2089
2150
|
name: toolCall.name,
|
|
2090
2151
|
params,
|
|
2091
|
-
metadata: { openai:
|
|
2152
|
+
metadata: { openai: makeItemIdMetadata(event.item_id) }
|
|
2092
2153
|
})
|
|
2093
2154
|
|
|
2094
2155
|
toolCall.functionCall.emitted = true
|
|
@@ -2226,7 +2287,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
2226
2287
|
type: "reasoning-delta",
|
|
2227
2288
|
id: `${event.item_id}:${event.summary_index}`,
|
|
2228
2289
|
delta: event.delta,
|
|
2229
|
-
metadata: { openai:
|
|
2290
|
+
metadata: { openai: makeItemIdMetadata(event.item_id) }
|
|
2230
2291
|
})
|
|
2231
2292
|
break
|
|
2232
2293
|
}
|
|
@@ -2239,7 +2300,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
2239
2300
|
parts.push({
|
|
2240
2301
|
type: "reasoning-end",
|
|
2241
2302
|
id: `${event.item_id}:${event.summary_index}`,
|
|
2242
|
-
metadata: { openai:
|
|
2303
|
+
metadata: { openai: makeItemIdMetadata(event.item_id) }
|
|
2243
2304
|
})
|
|
2244
2305
|
// Mark the summary part concluded
|
|
2245
2306
|
reasoningPart.summaryParts[event.summary_index] = "concluded"
|
|
@@ -2265,7 +2326,7 @@ const makeStreamResponse = Effect.fnUntraced(
|
|
|
2265
2326
|
|
|
2266
2327
|
const annotateRequest = (
|
|
2267
2328
|
span: Span,
|
|
2268
|
-
request: typeof
|
|
2329
|
+
request: typeof OpenAiSchema.CreateResponse.Encoded
|
|
2269
2330
|
): void => {
|
|
2270
2331
|
addGenAIAnnotations(span, {
|
|
2271
2332
|
system: "openai",
|
|
@@ -2285,7 +2346,7 @@ const annotateRequest = (
|
|
|
2285
2346
|
})
|
|
2286
2347
|
}
|
|
2287
2348
|
|
|
2288
|
-
const annotateResponse = (span: Span, response:
|
|
2349
|
+
const annotateResponse = (span: Span, response: OpenAiSchema.Response): void => {
|
|
2289
2350
|
const finishReason = response.incomplete_details?.reason as string | undefined
|
|
2290
2351
|
addGenAIAnnotations(span, {
|
|
2291
2352
|
response: {
|
|
@@ -2335,7 +2396,7 @@ const annotateStreamResponse = (span: Span, part: Response.StreamPartEncoded) =>
|
|
|
2335
2396
|
// Tool Conversion
|
|
2336
2397
|
// =============================================================================
|
|
2337
2398
|
|
|
2338
|
-
type OpenAiToolChoice = typeof
|
|
2399
|
+
type OpenAiToolChoice = typeof OpenAiSchema.CreateResponse.Encoded["tool_choice"]
|
|
2339
2400
|
|
|
2340
2401
|
const prepareTools = Effect.fnUntraced(function*<Tools extends ReadonlyArray<Tool.Any>>({
|
|
2341
2402
|
config,
|
|
@@ -2346,7 +2407,7 @@ const prepareTools = Effect.fnUntraced(function*<Tools extends ReadonlyArray<Too
|
|
|
2346
2407
|
readonly options: LanguageModel.ProviderOptions
|
|
2347
2408
|
readonly toolNameMapper: Tool.NameMapper<Tools>
|
|
2348
2409
|
}): Effect.fn.Return<{
|
|
2349
|
-
readonly tools: ReadonlyArray<typeof
|
|
2410
|
+
readonly tools: ReadonlyArray<typeof OpenAiSchema.Tool.Encoded> | undefined
|
|
2350
2411
|
readonly toolChoice: OpenAiToolChoice | undefined
|
|
2351
2412
|
}, AiError.AiError> {
|
|
2352
2413
|
// Return immediately if no tools are in the toolkit
|
|
@@ -2354,7 +2415,7 @@ const prepareTools = Effect.fnUntraced(function*<Tools extends ReadonlyArray<Too
|
|
|
2354
2415
|
return { tools: undefined, toolChoice: undefined }
|
|
2355
2416
|
}
|
|
2356
2417
|
|
|
2357
|
-
const tools: Array<typeof
|
|
2418
|
+
const tools: Array<typeof OpenAiSchema.Tool.Encoded> = []
|
|
2358
2419
|
let toolChoice: OpenAiToolChoice | undefined = undefined
|
|
2359
2420
|
|
|
2360
2421
|
// Filter the incoming tools down to the set of allowed tools as indicated by
|
|
@@ -2561,14 +2622,14 @@ const getStatus = (
|
|
|
2561
2622
|
| Prompt.TextPart
|
|
2562
2623
|
| Prompt.ToolCallPart
|
|
2563
2624
|
| Prompt.ToolResultPart
|
|
2564
|
-
): typeof
|
|
2625
|
+
): typeof OpenAiSchema.MessageStatus.Encoded | null => part.options.openai?.status ?? null
|
|
2565
2626
|
const getEncryptedContent = (
|
|
2566
2627
|
part: Prompt.ReasoningPart
|
|
2567
2628
|
): string | null => part.options.openai?.encryptedContent ?? null
|
|
2568
2629
|
|
|
2569
2630
|
const getImageDetail = (part: Prompt.FilePart): ImageDetail => part.options.openai?.imageDetail ?? "auto"
|
|
2570
2631
|
|
|
2571
|
-
const makeItemIdMetadata = (itemId: string | undefined) => Predicate.isNotUndefined(itemId) ? { itemId } :
|
|
2632
|
+
const makeItemIdMetadata = (itemId: string | undefined) => Predicate.isNotUndefined(itemId) ? { itemId } : {}
|
|
2572
2633
|
|
|
2573
2634
|
const makeEncryptedContentMetadata = (encryptedContent: string | null | undefined) =>
|
|
2574
2635
|
Predicate.isNotNullish(encryptedContent) ? { encryptedContent } : undefined
|
|
@@ -2603,7 +2664,7 @@ const tryToolJsonSchema = <T extends Tool.Any>(tool: T, method: string) =>
|
|
|
2603
2664
|
const prepareResponseFormat = Effect.fnUntraced(function*({ config, options }: {
|
|
2604
2665
|
readonly config: typeof Config.Service
|
|
2605
2666
|
readonly options: LanguageModel.ProviderOptions
|
|
2606
|
-
}): Effect.fn.Return<typeof
|
|
2667
|
+
}): Effect.fn.Return<typeof OpenAiSchema.TextResponseFormatConfiguration.Encoded, AiError.AiError> {
|
|
2607
2668
|
if (options.responseFormat.type === "json") {
|
|
2608
2669
|
const name = options.responseFormat.objectName
|
|
2609
2670
|
const schema = options.responseFormat.schema
|
|
@@ -2691,7 +2752,7 @@ const getApprovalRequestIdMapping = (prompt: Prompt.Prompt): ReadonlyMap<string,
|
|
|
2691
2752
|
return mapping
|
|
2692
2753
|
}
|
|
2693
2754
|
|
|
2694
|
-
const getUsage = (usage:
|
|
2755
|
+
const getUsage = (usage: OpenAiSchema.ResponseUsage | null | undefined): Response.Usage => {
|
|
2695
2756
|
if (Predicate.isNullish(usage)) {
|
|
2696
2757
|
return {
|
|
2697
2758
|
inputTokens: {
|
|
@@ -2710,8 +2771,8 @@ const getUsage = (usage: Generated.ResponseUsage | null | undefined): Response.U
|
|
|
2710
2771
|
|
|
2711
2772
|
const inputTokens = usage.input_tokens
|
|
2712
2773
|
const outputTokens = usage.output_tokens
|
|
2713
|
-
const cachedTokens = usage.input_tokens_details
|
|
2714
|
-
const reasoningTokens = usage.output_tokens_details
|
|
2774
|
+
const cachedTokens = getUsageTokenDetail(usage.input_tokens_details, "cached_tokens")
|
|
2775
|
+
const reasoningTokens = getUsageTokenDetail(usage.output_tokens_details, "reasoning_tokens")
|
|
2715
2776
|
|
|
2716
2777
|
return {
|
|
2717
2778
|
inputTokens: {
|
|
@@ -2728,6 +2789,30 @@ const getUsage = (usage: Generated.ResponseUsage | null | undefined): Response.U
|
|
|
2728
2789
|
}
|
|
2729
2790
|
}
|
|
2730
2791
|
|
|
2792
|
+
type ServiceTier = "default" | "auto" | "flex" | "scale" | "priority" | null
|
|
2793
|
+
|
|
2794
|
+
const toServiceTier = (value: string | undefined): {
|
|
2795
|
+
readonly metadata: {
|
|
2796
|
+
readonly openai: {
|
|
2797
|
+
readonly serviceTier: ServiceTier
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
} | undefined => {
|
|
2801
|
+
switch (value) {
|
|
2802
|
+
case "default":
|
|
2803
|
+
case "auto":
|
|
2804
|
+
case "flex":
|
|
2805
|
+
case "scale":
|
|
2806
|
+
case "priority":
|
|
2807
|
+
return { metadata: { openai: { serviceTier: value } } }
|
|
2808
|
+
default:
|
|
2809
|
+
return undefined
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
const getUsageTokenDetail = (details: unknown, key: string): number =>
|
|
2814
|
+
Predicate.hasProperty(details, key) && typeof details[key] === "number" ? details[key] : 0
|
|
2815
|
+
|
|
2731
2816
|
const transformToolCallParams = Effect.fnUntraced(function*<Tools extends ReadonlyArray<Tool.Any>>(
|
|
2732
2817
|
tools: Tools,
|
|
2733
2818
|
toolName: string,
|