@veryfront/ext-llm-openai 0.1.1240 → 0.1.1242
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/esm/extensions/ext-llm-openai/src/openai-chat-stream.d.ts.map +1 -1
- package/esm/extensions/ext-llm-openai/src/openai-chat-stream.js +22 -9
- package/esm/extensions/ext-llm-openai/src/openai-provider.d.ts.map +1 -1
- package/esm/extensions/ext-llm-openai/src/openai-provider.js +35 -2
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-chat-stream.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-chat-stream.ts"],"names":[],"mappings":"AA2BA,KAAK,4BAA4B,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;AAExE,KAAK,uBAAuB,GAAG;IAC7B,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AASF,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AA4KlD,wBAAuB,2BAA2B,CAChD,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,OAAO,GAAE,uBAA4B,GACpC,aAAa,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"openai-chat-stream.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-chat-stream.ts"],"names":[],"mappings":"AA2BA,KAAK,4BAA4B,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;AAExE,KAAK,uBAAuB,GAAG;IAC7B,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AASF,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AA4KlD,wBAAuB,2BAA2B,CAChD,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,OAAO,GAAE,uBAA4B,GACpC,aAAa,CAAC,OAAO,CAAC,CAyVxB"}
|
|
@@ -186,10 +186,13 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
|
|
|
186
186
|
if (!Array.isArray(record.choices)) {
|
|
187
187
|
throw invalidOpenAIStream(context, "choices was not an array");
|
|
188
188
|
}
|
|
189
|
+
// An empty `choices` array carries no content. Usage-only frames use this
|
|
190
|
+
// shape, and so does Azure OpenAI's `prompt_filter_results` preamble, which
|
|
191
|
+
// arrives before the first content chunk with neither choices nor usage.
|
|
192
|
+
// Both are informational, so skip the frame instead of failing the stream.
|
|
193
|
+
// The `choices` key being absent entirely is still rejected above — that is
|
|
194
|
+
// a malformed event rather than a content-free one.
|
|
189
195
|
if (record.choices.length === 0) {
|
|
190
|
-
if (!usageRecord) {
|
|
191
|
-
throw invalidOpenAIStream(context, "empty choices event had no usage");
|
|
192
|
-
}
|
|
193
196
|
return;
|
|
194
197
|
}
|
|
195
198
|
if (sawFinishReason) {
|
|
@@ -219,11 +222,16 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
|
|
|
219
222
|
}
|
|
220
223
|
delta = deltaRecord;
|
|
221
224
|
}
|
|
222
|
-
|
|
225
|
+
// Optional delta fields are `null` rather than absent on many
|
|
226
|
+
// OpenAI-compatible gateways (Moonshot/Kimi sends `reasoning_content: null`
|
|
227
|
+
// on both the opening and the finish chunk). Treat `null` as "not present
|
|
228
|
+
// on this chunk", matching how `content`, `refusal`, `tool_calls`, and
|
|
229
|
+
// `finish_reason` are already handled below.
|
|
230
|
+
if (delta.role !== undefined && delta.role !== null &&
|
|
223
231
|
delta.role !== "assistant") {
|
|
224
232
|
throw invalidOpenAIStream(context, "choice delta role was not assistant");
|
|
225
233
|
}
|
|
226
|
-
if (delta.reasoning_content !== undefined &&
|
|
234
|
+
if (delta.reasoning_content !== undefined && delta.reasoning_content !== null &&
|
|
227
235
|
typeof delta.reasoning_content !== "string") {
|
|
228
236
|
throw invalidOpenAIStream(context, "reasoning delta was malformed");
|
|
229
237
|
}
|
|
@@ -272,11 +280,15 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
|
|
|
272
280
|
throw invalidOpenAIStream(context, "tool call index was malformed");
|
|
273
281
|
}
|
|
274
282
|
const toolCallIndex = index;
|
|
275
|
-
|
|
283
|
+
// As with the reasoning delta above, gateways repeat `id`, `type`, and
|
|
284
|
+
// `function.name` as `null` on continuation fragments instead of omitting
|
|
285
|
+
// them; only the opening fragment carries real values. Treat `null` as
|
|
286
|
+
// absent so the fragment merges into the call already being assembled.
|
|
287
|
+
if (toolCallRecord.id !== undefined && toolCallRecord.id !== null &&
|
|
276
288
|
!isBoundedOpenAIStreamString(toolCallRecord.id, MAX_OPENAI_STREAM_IDENTIFIER_BYTES)) {
|
|
277
289
|
throw invalidOpenAIStream(context, "tool call id was malformed");
|
|
278
290
|
}
|
|
279
|
-
if (toolCallRecord.type !== undefined &&
|
|
291
|
+
if (toolCallRecord.type !== undefined && toolCallRecord.type !== null &&
|
|
280
292
|
toolCallRecord.type !== "function") {
|
|
281
293
|
throw invalidOpenAIStream(context, "tool call type was not function");
|
|
282
294
|
}
|
|
@@ -306,7 +318,7 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
|
|
|
306
318
|
if (!fn) {
|
|
307
319
|
throw invalidOpenAIStream(context, "tool call function was not an object");
|
|
308
320
|
}
|
|
309
|
-
if (fn.name !== undefined &&
|
|
321
|
+
if (fn.name !== undefined && fn.name !== null &&
|
|
310
322
|
!isBoundedOpenAIStreamString(fn.name, MAX_OPENAI_STREAM_TOOL_NAME_BYTES)) {
|
|
311
323
|
throw invalidOpenAIStream(context, "tool call function name was malformed");
|
|
312
324
|
}
|
|
@@ -324,7 +336,8 @@ export async function* streamOpenAICompatibleParts(stream, context = {}) {
|
|
|
324
336
|
toolName: current.name,
|
|
325
337
|
};
|
|
326
338
|
}
|
|
327
|
-
if (fn.arguments !== undefined &&
|
|
339
|
+
if (fn.arguments !== undefined && fn.arguments !== null &&
|
|
340
|
+
typeof fn.arguments !== "string") {
|
|
328
341
|
throw invalidOpenAIStream(context, "tool call arguments delta was malformed");
|
|
329
342
|
}
|
|
330
343
|
if (typeof fn.arguments === "string") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,EAMlB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EAOpB,+BAA+B,EAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,kCAAkC,CAAC;AA2B1C,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,+BAA+B,GAChC,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,EAMlB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EAOpB,+BAA+B,EAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,kCAAkC,CAAC;AA2B1C,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,+BAA+B,GAChC,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAs7BD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC,CAgF5E;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC,CA0F5E;AAwDD,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,gBAAgB,CA2ClB;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,EAAE,YAAY;IAEvB,WAAW,CACT,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,GACxB,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC;IAgC7E,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IAa7E,eAAe,CACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,GACxB,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC;CAY9E"}
|
|
@@ -38,6 +38,15 @@ function getRuntimeOpenAIProviderName(config) {
|
|
|
38
38
|
function getLLMOpenAIProviderName(config) {
|
|
39
39
|
return normalizeOpenAIProviderName(config.providerName) ?? "openai";
|
|
40
40
|
}
|
|
41
|
+
function getOpenAIModelTransport(config) {
|
|
42
|
+
const transport = config.openAITransport;
|
|
43
|
+
if (transport === undefined)
|
|
44
|
+
return "auto";
|
|
45
|
+
if (transport === "chat-completions" || transport === "responses") {
|
|
46
|
+
return transport;
|
|
47
|
+
}
|
|
48
|
+
throw new TypeError('OpenAI transport must be "chat-completions" or "responses"');
|
|
49
|
+
}
|
|
41
50
|
function getOpenAICompatibleProviderKind(config) {
|
|
42
51
|
const providerName = getRuntimeOpenAIProviderName(config).trim().toLowerCase();
|
|
43
52
|
return providerName === "mistral" || providerName === "moonshotai" ? providerName : "openai";
|
|
@@ -829,6 +838,24 @@ function requestUsesOpenAIHostedTool(optionsForRuntime) {
|
|
|
829
838
|
}
|
|
830
839
|
return resolveOpenAIWebSearchDescriptor(options.tools) !== undefined;
|
|
831
840
|
}
|
|
841
|
+
function createOpenAIChatCompletionsOnlyRuntime(chatRuntime) {
|
|
842
|
+
function assertHostedToolsSupported(options) {
|
|
843
|
+
if (requestUsesOpenAIHostedTool(options)) {
|
|
844
|
+
throw new TypeError("OpenAI hosted tools require the Responses API and are unavailable with Chat Completions");
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return {
|
|
848
|
+
...chatRuntime,
|
|
849
|
+
async doGenerate(optionsForRuntime) {
|
|
850
|
+
assertHostedToolsSupported(optionsForRuntime);
|
|
851
|
+
return await chatRuntime.doGenerate(optionsForRuntime);
|
|
852
|
+
},
|
|
853
|
+
async doStream(optionsForRuntime) {
|
|
854
|
+
assertHostedToolsSupported(optionsForRuntime);
|
|
855
|
+
return await chatRuntime.doStream(optionsForRuntime);
|
|
856
|
+
},
|
|
857
|
+
};
|
|
858
|
+
}
|
|
832
859
|
function createOpenAIAdaptiveModelRuntime(chatRuntime, responsesRuntime) {
|
|
833
860
|
return {
|
|
834
861
|
...chatRuntime,
|
|
@@ -900,10 +927,16 @@ export class OpenAIProvider {
|
|
|
900
927
|
fetch: config.fetch,
|
|
901
928
|
};
|
|
902
929
|
const responsesRuntime = createOpenAIResponsesRuntime(runtimeConfig, modelId);
|
|
903
|
-
|
|
930
|
+
const chatRuntime = createOpenAIModelRuntime(runtimeConfig, modelId);
|
|
931
|
+
const transport = getOpenAIModelTransport(config);
|
|
932
|
+
if (transport === "responses" ||
|
|
933
|
+
(transport === "auto" && isOpenAIReasoningModel(modelId, providerName))) {
|
|
904
934
|
return responsesRuntime;
|
|
905
935
|
}
|
|
906
|
-
|
|
936
|
+
if (transport === "chat-completions") {
|
|
937
|
+
return createOpenAIChatCompletionsOnlyRuntime(chatRuntime);
|
|
938
|
+
}
|
|
939
|
+
return createOpenAIAdaptiveModelRuntime(chatRuntime, responsesRuntime);
|
|
907
940
|
}
|
|
908
941
|
createEmbedding(modelId, config) {
|
|
909
942
|
return createOpenAIEmbeddingRuntime({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veryfront/ext-llm-openai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1242",
|
|
4
4
|
"description": "Veryfront first-party extension package for ext-llm-openai",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"veryfront",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"capabilities": []
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"veryfront": "^0.1.
|
|
48
|
+
"veryfront": "^0.1.1242"
|
|
49
49
|
},
|
|
50
50
|
"type": "module",
|
|
51
51
|
"types": "./esm/extensions/ext-llm-openai/src/index.d.ts",
|