@ai-sdk/openai 4.0.109 → 4.0.110
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 +23 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +159 -36
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +146 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +148 -35
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +68 -0
- package/package.json +1 -1
- package/src/chat/map-openai-finish-reason.ts +11 -4
- package/src/chat/openai-chat-api.ts +36 -0
- package/src/chat/openai-chat-language-model.ts +101 -12
- package/src/internal/index.ts +2 -0
- package/src/openai-batch.ts +8 -0
- package/src/responses/map-openai-responses-finish-reason.ts +7 -1
- package/src/responses/openai-responses-api.ts +71 -48
- package/src/responses/openai-responses-language-model.ts +56 -1
|
@@ -923,6 +923,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
923
923
|
let hasFunctionCall = false;
|
|
924
924
|
const hostedToolSearchCallIds: string[] = [];
|
|
925
925
|
|
|
926
|
+
// flag that checks if the model refused to answer:
|
|
927
|
+
let hasRefusal = false;
|
|
928
|
+
|
|
926
929
|
let structuredOutputText: string | undefined;
|
|
927
930
|
|
|
928
931
|
// map response content to content array
|
|
@@ -1092,11 +1095,32 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1092
1095
|
part.phase === 'final_answer'
|
|
1093
1096
|
) {
|
|
1094
1097
|
structuredOutputText = part.content
|
|
1095
|
-
.map(contentPart =>
|
|
1098
|
+
.map(contentPart =>
|
|
1099
|
+
contentPart.type === 'output_text'
|
|
1100
|
+
? contentPart.text
|
|
1101
|
+
: contentPart.refusal,
|
|
1102
|
+
)
|
|
1096
1103
|
.join('');
|
|
1097
1104
|
}
|
|
1098
1105
|
|
|
1099
1106
|
for (const contentPart of part.content) {
|
|
1107
|
+
if (contentPart.type === 'refusal') {
|
|
1108
|
+
hasRefusal = true;
|
|
1109
|
+
|
|
1110
|
+
content.push({
|
|
1111
|
+
type: 'text',
|
|
1112
|
+
text: contentPart.refusal,
|
|
1113
|
+
providerMetadata: {
|
|
1114
|
+
[providerOptionsName]: {
|
|
1115
|
+
itemId: part.id,
|
|
1116
|
+
...(part.phase != null && { phase: part.phase }),
|
|
1117
|
+
} satisfies ResponsesTextProviderMetadata,
|
|
1118
|
+
},
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1100
1124
|
if (
|
|
1101
1125
|
options.providerOptions?.[providerOptionsName]?.logprobs &&
|
|
1102
1126
|
contentPart.logprobs
|
|
@@ -1529,6 +1553,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1529
1553
|
unified: mapOpenAIResponseFinishReason({
|
|
1530
1554
|
finishReason: response.incomplete_details?.reason,
|
|
1531
1555
|
hasFunctionCall,
|
|
1556
|
+
hasRefusal,
|
|
1532
1557
|
}),
|
|
1533
1558
|
raw: response.incomplete_details?.reason ?? undefined,
|
|
1534
1559
|
},
|
|
@@ -1658,6 +1683,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1658
1683
|
// flag that checks if there have been client-side tool calls (not executed by openai)
|
|
1659
1684
|
let hasFunctionCall = false;
|
|
1660
1685
|
|
|
1686
|
+
// flag that checks if the model refused to answer:
|
|
1687
|
+
let hasRefusal = false;
|
|
1688
|
+
|
|
1661
1689
|
const activeReasoning: Record<
|
|
1662
1690
|
string,
|
|
1663
1691
|
{
|
|
@@ -2772,6 +2800,20 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2772
2800
|
) {
|
|
2773
2801
|
logprobs.push(value.logprobs);
|
|
2774
2802
|
}
|
|
2803
|
+
} else if (isRefusalDeltaChunk(value)) {
|
|
2804
|
+
hasRefusal = true;
|
|
2805
|
+
|
|
2806
|
+
const itemId = resolveOutputItemId({
|
|
2807
|
+
itemId: value.item_id,
|
|
2808
|
+
outputIndex: value.output_index,
|
|
2809
|
+
});
|
|
2810
|
+
controller.enqueue({
|
|
2811
|
+
type: 'text-delta',
|
|
2812
|
+
id: itemId,
|
|
2813
|
+
delta: value.delta,
|
|
2814
|
+
});
|
|
2815
|
+
} else if (isRefusalDoneChunk(value)) {
|
|
2816
|
+
hasRefusal = true;
|
|
2775
2817
|
} else if (value.type === 'response.reasoning_summary_part.added') {
|
|
2776
2818
|
const itemId = resolveOutputItemId({
|
|
2777
2819
|
itemId: value.item_id,
|
|
@@ -2872,6 +2914,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2872
2914
|
unified: mapOpenAIResponseFinishReason({
|
|
2873
2915
|
finishReason: value.response.incomplete_details?.reason,
|
|
2874
2916
|
hasFunctionCall,
|
|
2917
|
+
hasRefusal,
|
|
2875
2918
|
}),
|
|
2876
2919
|
raw: value.response.incomplete_details?.reason ?? undefined,
|
|
2877
2920
|
};
|
|
@@ -3014,6 +3057,18 @@ function isTextDeltaChunk(
|
|
|
3014
3057
|
return chunk.type === 'response.output_text.delta';
|
|
3015
3058
|
}
|
|
3016
3059
|
|
|
3060
|
+
function isRefusalDeltaChunk(
|
|
3061
|
+
chunk: OpenAIResponsesChunk,
|
|
3062
|
+
): chunk is OpenAIResponsesChunk & { type: 'response.refusal.delta' } {
|
|
3063
|
+
return chunk.type === 'response.refusal.delta';
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
function isRefusalDoneChunk(
|
|
3067
|
+
chunk: OpenAIResponsesChunk,
|
|
3068
|
+
): chunk is OpenAIResponsesChunk & { type: 'response.refusal.done' } {
|
|
3069
|
+
return chunk.type === 'response.refusal.done';
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3017
3072
|
function isOpenAIChatCompletionChunk(value: unknown): boolean {
|
|
3018
3073
|
const chunk = asRecord(value);
|
|
3019
3074
|
|