@veryfront/ext-llm-openai 0.1.1185 → 0.1.1189
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/README.md +49 -2
- package/esm/_dnt.polyfills.d.ts +12 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +15 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +7 -1
- package/esm/openai-chat-request-builder.d.ts +5 -43
- package/esm/openai-chat-request-builder.d.ts.map +1 -1
- package/esm/openai-chat-request-builder.js +18 -4
- package/esm/openai-chat-stream.d.ts +8 -1
- package/esm/openai-chat-stream.d.ts.map +1 -1
- package/esm/openai-chat-stream.js +286 -104
- package/esm/openai-provider-options.d.ts +6 -0
- package/esm/openai-provider-options.d.ts.map +1 -0
- package/esm/openai-provider-options.js +14 -0
- package/esm/openai-provider.d.ts +6 -5
- package/esm/openai-provider.d.ts.map +1 -1
- package/esm/openai-provider.js +579 -129
- package/esm/openai-reasoning-models.d.ts +3 -6
- package/esm/openai-reasoning-models.d.ts.map +1 -1
- package/esm/openai-responses-request-builder.d.ts.map +1 -1
- package/esm/openai-responses-request-builder.js +240 -19
- package/esm/openai-responses-stream.d.ts +12 -1
- package/esm/openai-responses-stream.d.ts.map +1 -1
- package/esm/openai-responses-stream.js +1053 -113
- package/esm/openai-sse-buffer.d.ts +8 -0
- package/esm/openai-sse-buffer.d.ts.map +1 -0
- package/esm/openai-sse-buffer.js +47 -0
- package/esm/openai-stream-metadata.d.ts +6 -0
- package/esm/openai-stream-metadata.d.ts.map +1 -0
- package/esm/openai-stream-metadata.js +10 -0
- package/esm/openai-tool-input.d.ts +10 -0
- package/esm/openai-tool-input.d.ts.map +1 -0
- package/esm/openai-tool-input.js +30 -0
- package/esm/openai-web-search.d.ts +35 -0
- package/esm/openai-web-search.d.ts.map +1 -0
- package/esm/openai-web-search.js +369 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Category:** LLM | **Contract:** `LLMProvider` | **Built-in**
|
|
4
4
|
|
|
5
|
-
Provides OpenAI models for Veryfront agents and chat, enabling `openai/*` models for chat, embeddings,
|
|
5
|
+
Provides OpenAI models for Veryfront agents and chat, enabling `openai/*` models for chat, embeddings, the Responses API, and OpenAI-hosted web search via the `LLMProviderRegistry`.
|
|
6
6
|
|
|
7
7
|
## Registration
|
|
8
8
|
|
|
@@ -43,7 +43,8 @@ const result = await ai.embed("openai/text-embedding-3-small", {
|
|
|
43
43
|
|
|
44
44
|
### Responses API
|
|
45
45
|
|
|
46
|
-
For models that support OpenAI's Responses API (structured output,
|
|
46
|
+
For models that support OpenAI's Responses API (structured output, function
|
|
47
|
+
tools, and supported hosted tools):
|
|
47
48
|
|
|
48
49
|
```ts
|
|
49
50
|
const response = await ai.responses("openai/gpt-4.1", {
|
|
@@ -51,6 +52,52 @@ const response = await ai.responses("openai/gpt-4.1", {
|
|
|
51
52
|
});
|
|
52
53
|
```
|
|
53
54
|
|
|
55
|
+
### Hosted Web Search
|
|
56
|
+
|
|
57
|
+
The agent-facing tool name is `web_search`. It resolves to the current
|
|
58
|
+
`openai.web_search` provider tool and routes that request through the Responses
|
|
59
|
+
API, including for models that otherwise use Chat Completions:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { agent } from "veryfront/agent";
|
|
63
|
+
|
|
64
|
+
export default agent({
|
|
65
|
+
model: "openai/gpt-4.1",
|
|
66
|
+
providerTools: ["web_search"],
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Contract | Supported value |
|
|
71
|
+
| --------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
72
|
+
| Agent tool name | `web_search` |
|
|
73
|
+
| Current provider id | `openai.web_search` |
|
|
74
|
+
| Low-level compatibility ids | `openai.web_search_2025_08_26`, `openai.web_search_preview`, `openai.web_search_preview_2025_03_11` |
|
|
75
|
+
| Optional argument | `searchContextSize`: `"low"` \| `"medium"` \| `"high"` |
|
|
76
|
+
| Per-request limit | One OpenAI web-search provider tool |
|
|
77
|
+
|
|
78
|
+
Other OpenAI-hosted tool types are not normalized by this extension and fail
|
|
79
|
+
before the provider request. OpenAI-compatible base URLs can use this path only
|
|
80
|
+
when the endpoint implements OpenAI's Responses and hosted web-search
|
|
81
|
+
contracts.
|
|
82
|
+
|
|
83
|
+
Responses requests are stateless (`store: false`). The runtime retains the
|
|
84
|
+
complete ordered response output in provider metadata and replays it on the
|
|
85
|
+
next turn. Reasoning requests explicitly include encrypted reasoning content,
|
|
86
|
+
and web-search requests include source URLs, so manual callers must preserve
|
|
87
|
+
assistant-message provider metadata between turns. Raw replay is limited to
|
|
88
|
+
4,096 output items and 8 MiB. Whenever canonical calls or results survive,
|
|
89
|
+
their IDs, names, semantic values, multiplicity, and order must match the raw
|
|
90
|
+
output before transport.
|
|
91
|
+
|
|
92
|
+
Provider-executed Responses calls and results cannot be converted into Chat
|
|
93
|
+
Completions history. Switching a conversation containing those parts to a
|
|
94
|
+
Chat Completions-only route fails as a configuration error before transport;
|
|
95
|
+
keep that conversation on a Responses-capable route or begin a new compacted
|
|
96
|
+
history that no longer contains the provider-executed parts.
|
|
97
|
+
|
|
98
|
+
See [Providers: Enable OpenAI-hosted web search](../../docs/guides/providers.md#enable-openai-hosted-web-search)
|
|
99
|
+
for the agent setup.
|
|
100
|
+
|
|
54
101
|
## Supported Models
|
|
55
102
|
|
|
56
103
|
Any model accessible through the OpenAI Chat Completions, Responses, or Embeddings API:
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Object {
|
|
3
|
+
/**
|
|
4
|
+
* Determines whether an object has a property with the specified name.
|
|
5
|
+
* @param o An object.
|
|
6
|
+
* @param v A property name.
|
|
7
|
+
*/
|
|
8
|
+
hasOwn(o: object, v: PropertyKey): boolean;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=_dnt.polyfills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AAeA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd;;;;WAIG;QACH,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;KAC5C;CACF;AAED,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// https://github.com/tc39/proposal-accessible-object-hasownproperty/blob/main/polyfill.js
|
|
2
|
+
if (!Object.hasOwn) {
|
|
3
|
+
Object.defineProperty(Object, "hasOwn", {
|
|
4
|
+
value: function (object, property) {
|
|
5
|
+
if (object == null) {
|
|
6
|
+
throw new TypeError("Cannot convert undefined or null to object");
|
|
7
|
+
}
|
|
8
|
+
return Object.prototype.hasOwnProperty.call(Object(object), property);
|
|
9
|
+
},
|
|
10
|
+
configurable: true,
|
|
11
|
+
enumerable: false,
|
|
12
|
+
writable: true,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export {};
|
package/esm/index.d.ts
CHANGED
package/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,QAAA,MAAM,SAAS,EAAE,gBAyBhB,CAAC;AAEF,eAAe,SAAS,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
package/esm/index.js
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module extensions/ext-llm-openai
|
|
6
6
|
*/
|
|
7
|
+
import "./_dnt.polyfills.js";
|
|
7
8
|
import { LLMProviderRegistryName } from "veryfront/extensions/llm";
|
|
8
9
|
import { OpenAIProvider } from "./openai-provider.js";
|
|
9
10
|
const extOpenAI = () => {
|
|
10
11
|
const provider = new OpenAIProvider();
|
|
11
12
|
let registry;
|
|
13
|
+
let registeredProvider = false;
|
|
12
14
|
return {
|
|
13
15
|
name: "ext-llm-openai",
|
|
14
16
|
version: "0.1.0",
|
|
@@ -19,11 +21,15 @@ const extOpenAI = () => {
|
|
|
19
21
|
capabilities: [],
|
|
20
22
|
setup(ctx) {
|
|
21
23
|
registry = ctx.require(LLMProviderRegistryName);
|
|
24
|
+
registeredProvider = !registry.has(provider.id);
|
|
22
25
|
registry.register(provider);
|
|
26
|
+
ctx.provide("LLMProvider:openai", registry.get(provider.id) ?? provider);
|
|
23
27
|
ctx.logger.debug("[ext-llm-openai] OpenAI provider registered");
|
|
24
28
|
},
|
|
25
29
|
teardown() {
|
|
26
|
-
|
|
30
|
+
if (registeredProvider)
|
|
31
|
+
registry?.unregister(provider.id);
|
|
32
|
+
registeredProvider = false;
|
|
27
33
|
registry = undefined;
|
|
28
34
|
},
|
|
29
35
|
};
|
|
@@ -1,48 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export type RuntimeToolDefinition = {
|
|
4
|
-
type: "function";
|
|
5
|
-
name: string;
|
|
6
|
-
description?: string;
|
|
7
|
-
inputSchema: unknown;
|
|
8
|
-
} | {
|
|
9
|
-
type: "provider";
|
|
10
|
-
name: string;
|
|
11
|
-
id: `${string}.${string}`;
|
|
12
|
-
args: Record<string, unknown>;
|
|
13
|
-
};
|
|
14
|
-
export type OpenAICompatibleLanguageOptions = {
|
|
15
|
-
prompt: RuntimePromptMessage[];
|
|
16
|
-
maxOutputTokens?: number;
|
|
17
|
-
temperature?: number;
|
|
18
|
-
topP?: number;
|
|
19
|
-
topK?: number;
|
|
20
|
-
stopSequences?: string[];
|
|
21
|
-
tools?: RuntimeToolDefinition[];
|
|
22
|
-
toolChoice?: unknown;
|
|
23
|
-
seed?: number;
|
|
24
|
-
presencePenalty?: number;
|
|
25
|
-
frequencyPenalty?: number;
|
|
26
|
-
headers?: HeadersInit;
|
|
27
|
-
providerOptions?: Record<string, unknown>;
|
|
28
|
-
includeRawChunks?: boolean;
|
|
29
|
-
abortSignal?: AbortSignal;
|
|
30
|
-
reasoning?: OpenAIProviderReasoningOption;
|
|
31
|
-
userId?: string;
|
|
1
|
+
import type { ModelRuntimeCallOptions, ModelRuntimeToolDefinition, OpenAICompatibleChatRequest } from "veryfront/provider/shared";
|
|
2
|
+
export interface OpenAICompatibleLanguageOptions extends ModelRuntimeCallOptions {
|
|
32
3
|
serviceTier?: "auto" | "default" | "flex" | "scale";
|
|
33
4
|
parallelToolCalls?: boolean;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type: "json";
|
|
38
|
-
} | {
|
|
39
|
-
type: "json_schema";
|
|
40
|
-
name: string;
|
|
41
|
-
schema: unknown;
|
|
42
|
-
description?: string;
|
|
43
|
-
strict?: boolean;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
5
|
+
}
|
|
6
|
+
/** @deprecated Import `ModelRuntimeToolDefinition` from `veryfront/provider` instead. */
|
|
7
|
+
export type RuntimeToolDefinition = ModelRuntimeToolDefinition;
|
|
46
8
|
type WarningCollector = {
|
|
47
9
|
push(warning: {
|
|
48
10
|
type: "unsupported-setting" | "other";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-chat-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-chat-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"openai-chat-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-chat-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,2BAA2B,CAAC;AAOnC,MAAM,WAAW,+BAAgC,SAAQ,uBAAuB;IAC9E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,yFAAyF;AACzF,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAE/D,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAUF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,2BAA2B,CA+H7B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readProviderOptions, toOpenAICompatibleMessages, toOpenAICompatibleTools, unwrapToolInputSchema, } from "veryfront/provider/shared";
|
|
2
2
|
import { rejectsOpenAISamplingParams, resolveOpenAIReasoningConfig, } from "./openai-reasoning-models.js";
|
|
3
|
+
import { defineOpenAIProviderOptions } from "./openai-provider-options.js";
|
|
3
4
|
function isNativeOpenAIModel(modelId) {
|
|
4
5
|
return /^(gpt-|o[134](-|$)|chatgpt-)/.test(modelId);
|
|
5
6
|
}
|
|
@@ -12,6 +13,7 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
|
|
|
12
13
|
const samplingRejected = rejectsOpenAISamplingParams(modelId);
|
|
13
14
|
const fixedSampling = isFixedSamplingModel(modelId);
|
|
14
15
|
const dropSamplingParams = reasoningEnabled || samplingRejected || fixedSampling;
|
|
16
|
+
const messages = toOpenAICompatibleMessages(options.prompt);
|
|
15
17
|
// OpenAI Chat Completions has no top_k surface.
|
|
16
18
|
if (options.topK !== undefined) {
|
|
17
19
|
warnings.push({
|
|
@@ -47,7 +49,7 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
|
|
|
47
49
|
}
|
|
48
50
|
const body = {
|
|
49
51
|
model: modelId,
|
|
50
|
-
messages
|
|
52
|
+
messages,
|
|
51
53
|
...(stream ? { stream: true, stream_options: { include_usage: true } } : {}),
|
|
52
54
|
...(options.maxOutputTokens !== undefined
|
|
53
55
|
? isNativeOpenAIModel(modelId)
|
|
@@ -59,7 +61,7 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
|
|
|
59
61
|
: {}),
|
|
60
62
|
...(!dropSamplingParams && options.topP !== undefined ? { top_p: options.topP } : {}),
|
|
61
63
|
...(options.stopSequences && options.stopSequences.length > 0
|
|
62
|
-
? { stop: options.stopSequences }
|
|
64
|
+
? { stop: [...options.stopSequences] }
|
|
63
65
|
: {}),
|
|
64
66
|
...(toOpenAICompatibleTools(options.tools)
|
|
65
67
|
? { tools: toOpenAICompatibleTools(options.tools) }
|
|
@@ -109,9 +111,21 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
|
|
|
109
111
|
];
|
|
110
112
|
const providerOpts = {};
|
|
111
113
|
for (const bucketName of bucketNames) {
|
|
112
|
-
|
|
114
|
+
defineOpenAIProviderOptions(providerOpts, normalizeNativeMaxTokens(readProviderOptions(options.providerOptions, bucketName), modelId));
|
|
115
|
+
}
|
|
116
|
+
defineOpenAIProviderOptions(body, providerOpts);
|
|
117
|
+
// Provider-native options may tune request behavior, but they must not
|
|
118
|
+
// replace the runtime-owned transport mode, model, or conversation.
|
|
119
|
+
body.model = modelId;
|
|
120
|
+
body.messages = messages;
|
|
121
|
+
if (stream) {
|
|
122
|
+
body.stream = true;
|
|
123
|
+
body.stream_options = { include_usage: true };
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
delete body.stream;
|
|
127
|
+
delete body.stream_options;
|
|
113
128
|
}
|
|
114
|
-
Object.assign(body, providerOpts);
|
|
115
129
|
return body;
|
|
116
130
|
}
|
|
117
131
|
/** Normalizes max_tokens to max_completion_tokens for native OpenAI models. */
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
type OpenAICompatibleProviderKind = "openai" | "mistral" | "moonshotai";
|
|
2
|
+
type OpenAIChatStreamContext = {
|
|
3
|
+
providerKind?: OpenAICompatibleProviderKind;
|
|
4
|
+
providerLabel?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const MAX_OPENAI_STREAM_TOOL_CALLS = 1024;
|
|
7
|
+
export declare function streamOpenAICompatibleParts(stream: ReadableStream<Uint8Array>, context?: OpenAIChatStreamContext): AsyncIterable<unknown>;
|
|
8
|
+
export {};
|
|
2
9
|
//# sourceMappingURL=openai-chat-stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-chat-stream.d.ts","sourceRoot":"","sources":["../src/openai-chat-stream.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-chat-stream.d.ts","sourceRoot":"","sources":["../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,CAuVxB"}
|