@tessar/openai 0.1.0-alpha.0 → 0.1.0
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 +131 -37
- package/dist/adapter.d.ts +7 -8
- package/dist/adapter.js +76 -24
- package/dist/adapter.js.map +1 -1
- package/dist/chat-adapter.d.ts +7 -0
- package/dist/chat-adapter.js +180 -0
- package/dist/chat-adapter.js.map +1 -0
- package/dist/chat-codec.d.ts +20 -0
- package/dist/chat-codec.js +157 -0
- package/dist/chat-codec.js.map +1 -0
- package/dist/codec.d.ts +3 -3
- package/dist/codec.js +15 -6
- package/dist/codec.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/provider.d.ts +43 -0
- package/dist/provider.js +106 -0
- package/dist/provider.js.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,37 +1,131 @@
|
|
|
1
|
-
# @tessar/openai
|
|
2
|
-
|
|
3
|
-
OpenAI Responses provider
|
|
4
|
-
Requires Node 24.14 or newer and uses the official OpenAI SDK.
|
|
5
|
-
|
|
6
|
-
```sh
|
|
7
|
-
npm install @tessar/core
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
```ts
|
|
11
|
-
import { Agent
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
model:
|
|
17
|
-
});
|
|
18
|
-
const
|
|
19
|
-
id: "
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
# @tessar/openai
|
|
2
|
+
|
|
3
|
+
OpenAI Responses and Chat Completions provider with model metadata integration.
|
|
4
|
+
Requires Node 24.14 or newer and uses the official OpenAI SDK.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install @tessar/core @tessar/openai
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { Agent } from "@tessar/core";
|
|
12
|
+
import { OpenAIProvider } from "@tessar/openai";
|
|
13
|
+
|
|
14
|
+
const model = new OpenAIProvider({
|
|
15
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
16
|
+
model: process.env.OPENAI_MODEL!,
|
|
17
|
+
});
|
|
18
|
+
const agent = new Agent({
|
|
19
|
+
id: "assistant",
|
|
20
|
+
model,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const result = await agent.generate("Hello");
|
|
24
|
+
console.log(result.output);
|
|
25
|
+
|
|
26
|
+
const stream = agent.stream("Explain briefly", {
|
|
27
|
+
modelOptions: { reasoning: { effort: "low" }, max_output_tokens: 2048 },
|
|
28
|
+
});
|
|
29
|
+
for await (const event of stream) console.log(event);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Agent runs without Controller or public init/dispose. A string `model` override
|
|
33
|
+
selects another model ID using the same client; another OpenAIProvider instance
|
|
34
|
+
can carry a different endpoint, API key and headers. Request overrides are
|
|
35
|
+
execution-local and replace nested objects rather than deep-merging them.
|
|
36
|
+
|
|
37
|
+
The constructor accepts official SDK client settings (`baseURL`,
|
|
38
|
+
`defaultHeaders`, `maxRetries`, `timeout`, etc.) and native options for its API.
|
|
39
|
+
`api` defaults to `"responses"`; select `"chat-completions"` for that endpoint:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const chat = new OpenAIProvider({
|
|
43
|
+
api: "chat-completions",
|
|
44
|
+
apiKey: process.env.PROVIDER_API_KEY!,
|
|
45
|
+
baseURL: process.env.PROVIDER_BASE_URL!,
|
|
46
|
+
model: process.env.PROVIDER_MODEL!,
|
|
47
|
+
reasoning_effort: "high",
|
|
48
|
+
max_completion_tokens: 2048,
|
|
49
|
+
});
|
|
50
|
+
const chatAgent = new Agent({ id: "chat", model: chat });
|
|
51
|
+
await chatAgent.generate("Hello", {
|
|
52
|
+
model: "another-model-on-this-connection",
|
|
53
|
+
modelOptions: { reasoning_effort: "low" },
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Choose fields supported by the target provider/model. Responses uses fields such
|
|
58
|
+
as `reasoning` and `max_output_tokens`; Chat Completions uses `reasoning_effort`
|
|
59
|
+
and `max_completion_tokens` (or legacy `max_tokens`). Types follow the selected
|
|
60
|
+
SDK protocol. `providerId` remains optional and defaults to `"openai"`, including
|
|
61
|
+
when using a compatible endpoint. It identifies a Controller registration, not
|
|
62
|
+
the HTTP protocol.
|
|
63
|
+
|
|
64
|
+
`withModel()` and model-ID overrides preserve the selected API and connection.
|
|
65
|
+
To change API, endpoint, credentials or headers, pass a different provider instance
|
|
66
|
+
as the execution's `model`. `api` never enters the request body and cannot be
|
|
67
|
+
changed through `modelOptions`.
|
|
68
|
+
|
|
69
|
+
Runtime-owned model/input/instructions/tools/stream fields cannot be overridden
|
|
70
|
+
through `modelOptions`. Background execution, provider-managed conversations and
|
|
71
|
+
`context_management` compaction are not supported by this loop. HTTP/SDK retries are not a mechanism
|
|
72
|
+
for silently restarting a stream that has already emitted output.
|
|
73
|
+
|
|
74
|
+
Unconfigured settings stay absent: Tessar does not inject temperature, reasoning,
|
|
75
|
+
output limits, store/include, or SDK retry/timeout defaults. The SDK applies its
|
|
76
|
+
own defaults. Configure `maxRetries` and `timeout` in the provider constructor
|
|
77
|
+
when needed. `generate()` preserves native provider exceptions on failure.
|
|
78
|
+
|
|
79
|
+
Ordered instruction sections are joined with `\n\n`: Responses receives one
|
|
80
|
+
`instructions` string; Chat Completions receives one leading system message.
|
|
81
|
+
Section IDs and orders are local metadata. Chat supports text, user images/files
|
|
82
|
+
and function tools, including fragmented parallel calls and native reasoning
|
|
83
|
+
continuity. Unsupported audio/deprecated function-call output is rejected. The
|
|
84
|
+
Agent consumes one completion choice; `n` may be omitted or set to `1`.
|
|
85
|
+
|
|
86
|
+
Chat usage is available only when the endpoint reports it. To request streamed
|
|
87
|
+
usage, explicitly configure `stream_options: { include_usage: true }`. Tessar
|
|
88
|
+
does not add this option; absent usage remains unavailable rather than zero.
|
|
89
|
+
|
|
90
|
+
Implicit prompt caching remains the provider default. Tessar adds no cache
|
|
91
|
+
markers, history breakpoints or cache policy. Stable sections can precede changing
|
|
92
|
+
sections using `order`; native cache options pass through only when configured.
|
|
93
|
+
Cache hits still depend on the endpoint/model and the actual prompt prefix.
|
|
94
|
+
|
|
95
|
+
`model.profile` reads a cached/bundled metadata snapshot without starting network
|
|
96
|
+
requests. `await model.refreshProfile()` explicitly refreshes provider metadata;
|
|
97
|
+
metadata may be incomplete and carries provenance.
|
|
98
|
+
|
|
99
|
+
OpenAIAdapter and OpenAIPlugin remain available for existing Controller/provider
|
|
100
|
+
registrations. Passing an executable model to Controller already registers its
|
|
101
|
+
provider; do not additionally register the same provider ID with a plugin.
|
|
102
|
+
|
|
103
|
+
Each new provider has a separate opaque connection identity; `withModel()` keeps
|
|
104
|
+
the existing client and identity. In-process suspension retains a per-call
|
|
105
|
+
connection until the execution ends. Rebinding these connections after process
|
|
106
|
+
restart is not yet supported by the Controller compatibility bridge.
|
|
107
|
+
|
|
108
|
+
This is an early 0.x release. See the
|
|
109
|
+
[repository](https://github.com/hphucdev-04/tessar) for complete contracts.
|
|
110
|
+
|
|
111
|
+
## Restoring native conversation state
|
|
112
|
+
|
|
113
|
+
For durable conversations, assign a stable, nonsecret connection identity:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const model = new OpenAIProvider({
|
|
117
|
+
connectionId: "primary-openai",
|
|
118
|
+
model: "your-model",
|
|
119
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Recreate that binding after restart. Stored continuity includes provider,
|
|
124
|
+
connection, protocol and effective endpoint; reusing the ID with a different
|
|
125
|
+
endpoint/protocol is rejected. API keys and transport headers are not included
|
|
126
|
+
in the descriptor. Unspecified connection IDs remain random and isolated.
|
|
127
|
+
|
|
128
|
+
Legacy native state has only its old connection ID. An application may explicitly
|
|
129
|
+
reuse that saved ID after verifying the original endpoint/protocol itself; Tessar
|
|
130
|
+
cannot infer or attest that binding during SQLite migration. Neither the
|
|
131
|
+
connection ID nor its descriptor is forwarded as a native request parameter.
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import OpenAI from "openai";
|
|
2
|
-
import { type ModelAdapter, type ModelChunk, type ModelRef, type ModelRequest } from "@tessar/core";
|
|
3
|
-
export interface OpenAIOptions {
|
|
4
|
-
apiKey: string;
|
|
5
|
-
baseURL?: string;
|
|
1
|
+
import OpenAI, { type ClientOptions } from "openai";
|
|
2
|
+
import { type ModelAdapter, type ModelChunk, type ModelRef, type ModelRequest, type ModelConnectionDescriptor } from "@tessar/core";
|
|
3
|
+
export interface OpenAIOptions extends ClientOptions {
|
|
6
4
|
providerId?: string;
|
|
7
|
-
fetch?: typeof fetch;
|
|
8
5
|
metadataPartition?: string;
|
|
9
6
|
}
|
|
7
|
+
export declare const clientKeys: readonly ["apiKey", "adminAPIKey", "organization", "project", "webhookSecret", "baseURL", "dataResidency", "timeout", "fetchOptions", "fetch", "maxRetries", "defaultHeaders", "defaultQuery", "dangerouslyAllowBrowser", "logLevel", "logger", "workloadIdentity", "credential", "provider", "x509Transport"];
|
|
10
8
|
export declare function createClient(options: OpenAIOptions): OpenAI;
|
|
11
9
|
export declare class OpenAIAdapter implements ModelAdapter {
|
|
12
10
|
readonly ref: ModelRef;
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
readonly connection?: ModelConnectionDescriptor | undefined;
|
|
12
|
+
protected readonly client: OpenAI;
|
|
13
|
+
constructor(options: OpenAIOptions, ref: ModelRef, client?: OpenAI, connection?: ModelConnectionDescriptor | undefined);
|
|
15
14
|
validate(request: ModelRequest): void;
|
|
16
15
|
stream(request: ModelRequest, context: {
|
|
17
16
|
signal: AbortSignal;
|
package/dist/adapter.js
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
import OpenAI, { OpenAIError } from "openai";
|
|
2
2
|
import { errorInfo, MessageCodec, fail, normalizeUsage, } from "@tessar/core";
|
|
3
3
|
import { decodeOutput, encodeInput } from "./codec.js";
|
|
4
|
+
// Connection settings must never enter either protocol's request body.
|
|
5
|
+
export const clientKeys = [
|
|
6
|
+
"apiKey",
|
|
7
|
+
"adminAPIKey",
|
|
8
|
+
"organization",
|
|
9
|
+
"project",
|
|
10
|
+
"webhookSecret",
|
|
11
|
+
"baseURL",
|
|
12
|
+
"dataResidency",
|
|
13
|
+
"timeout",
|
|
14
|
+
"fetchOptions",
|
|
15
|
+
"fetch",
|
|
16
|
+
"maxRetries",
|
|
17
|
+
"defaultHeaders",
|
|
18
|
+
"defaultQuery",
|
|
19
|
+
"dangerouslyAllowBrowser",
|
|
20
|
+
"logLevel",
|
|
21
|
+
"logger",
|
|
22
|
+
"workloadIdentity",
|
|
23
|
+
"credential",
|
|
24
|
+
"provider",
|
|
25
|
+
"x509Transport",
|
|
26
|
+
];
|
|
4
27
|
export function createClient(options) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
baseURL: options.baseURL,
|
|
8
|
-
fetch: options.fetch,
|
|
9
|
-
maxRetries: 0,
|
|
10
|
-
});
|
|
28
|
+
const { providerId, metadataPartition, ...clientOptions } = options;
|
|
29
|
+
return new OpenAI(clientOptions);
|
|
11
30
|
}
|
|
12
31
|
function usage(value) {
|
|
13
32
|
return normalizeUsage({
|
|
@@ -25,9 +44,11 @@ function usage(value) {
|
|
|
25
44
|
}
|
|
26
45
|
export class OpenAIAdapter {
|
|
27
46
|
ref;
|
|
47
|
+
connection;
|
|
28
48
|
client;
|
|
29
|
-
constructor(options, ref, client) {
|
|
49
|
+
constructor(options, ref, client, connection) {
|
|
30
50
|
this.ref = ref;
|
|
51
|
+
this.connection = connection;
|
|
31
52
|
this.client = client ?? createClient(options);
|
|
32
53
|
}
|
|
33
54
|
validate(request) {
|
|
@@ -35,7 +56,27 @@ export class OpenAIAdapter {
|
|
|
35
56
|
if (request.model.providerId !== this.ref.providerId ||
|
|
36
57
|
request.model.modelId !== this.ref.modelId)
|
|
37
58
|
fail("UnsupportedContext", "Model identity mismatch");
|
|
38
|
-
|
|
59
|
+
if (request.model.connectionId !== this.ref.connectionId)
|
|
60
|
+
fail("UnsupportedContext", "Model connection mismatch");
|
|
61
|
+
for (const key of [
|
|
62
|
+
"connectionId",
|
|
63
|
+
"api",
|
|
64
|
+
"model",
|
|
65
|
+
"input",
|
|
66
|
+
"messages",
|
|
67
|
+
"instructions",
|
|
68
|
+
"tools",
|
|
69
|
+
"stream",
|
|
70
|
+
...clientKeys,
|
|
71
|
+
])
|
|
72
|
+
if (request.options && key in request.options)
|
|
73
|
+
fail("UnsupportedOption", key + " is owned by the model connection or Agent runtime");
|
|
74
|
+
if (request.options?.background === true ||
|
|
75
|
+
request.options?.conversation != null ||
|
|
76
|
+
request.options?.previous_response_id != null ||
|
|
77
|
+
request.options?.context_management != null)
|
|
78
|
+
fail("UnsupportedOption", "Background, provider-managed conversations and compaction are not supported by the Agent loop");
|
|
79
|
+
encodeInput(request, this.connection);
|
|
39
80
|
}
|
|
40
81
|
catch (error) {
|
|
41
82
|
errorInfo(error, { source: "tessar", ...this.ref });
|
|
@@ -52,20 +93,27 @@ export class OpenAIAdapter {
|
|
|
52
93
|
};
|
|
53
94
|
try {
|
|
54
95
|
const stream = await this.client.responses.create({
|
|
96
|
+
...request.options,
|
|
55
97
|
model: this.ref.modelId,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
98
|
+
...(request.instructions.sections.some((section) => section.content.length > 0)
|
|
99
|
+
? {
|
|
100
|
+
instructions: request.instructions.sections
|
|
101
|
+
.map((s) => s.content)
|
|
102
|
+
.join("\n\n"),
|
|
103
|
+
}
|
|
104
|
+
: {}),
|
|
105
|
+
input: encodeInput(request, this.connection),
|
|
106
|
+
...(request.tools.length
|
|
107
|
+
? {
|
|
108
|
+
tools: request.tools.map((t) => ({
|
|
109
|
+
type: "function",
|
|
110
|
+
name: t.name,
|
|
111
|
+
description: t.description,
|
|
112
|
+
parameters: t.inputSchema,
|
|
113
|
+
strict: false,
|
|
114
|
+
})),
|
|
115
|
+
}
|
|
116
|
+
: {}),
|
|
69
117
|
stream: true,
|
|
70
118
|
}, { signal: context.signal });
|
|
71
119
|
let terminal = false;
|
|
@@ -97,7 +145,7 @@ export class OpenAIAdapter {
|
|
|
97
145
|
yield {
|
|
98
146
|
type: "response",
|
|
99
147
|
response: {
|
|
100
|
-
message: MessageCodec.encode(decodeOutput(event.response.output, this.ref, event.response.id)),
|
|
148
|
+
message: MessageCodec.encode(decodeOutput(event.response.output, this.ref, event.response.id, this.connection)),
|
|
101
149
|
usage: normalized,
|
|
102
150
|
finishReason: "completed",
|
|
103
151
|
providerRequestId: event.response.id,
|
|
@@ -108,7 +156,8 @@ export class OpenAIAdapter {
|
|
|
108
156
|
case "response.incomplete":
|
|
109
157
|
case "response.failed":
|
|
110
158
|
yield { type: "usage", usage: usage(event.response.usage) };
|
|
111
|
-
throw failure(event.response.error?.message ??
|
|
159
|
+
throw failure(event.response.error?.message ??
|
|
160
|
+
"OpenAI response did not complete", event.response.error?.code ?? "ProviderIncomplete");
|
|
112
161
|
case "error":
|
|
113
162
|
throw failure(event.message, event.code ?? "ProviderError");
|
|
114
163
|
}
|
|
@@ -119,7 +168,10 @@ export class OpenAIAdapter {
|
|
|
119
168
|
catch (error) {
|
|
120
169
|
if (context.signal.aborted)
|
|
121
170
|
throw context.signal.reason;
|
|
122
|
-
errorInfo(error, {
|
|
171
|
+
errorInfo(error, {
|
|
172
|
+
source: error instanceof OpenAIError ? "provider" : "tessar",
|
|
173
|
+
...this.ref,
|
|
174
|
+
});
|
|
123
175
|
throw error;
|
|
124
176
|
}
|
|
125
177
|
}
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ModelCallContext, type ModelChunk, type ModelRequest } from "@tessar/core";
|
|
2
|
+
import { OpenAIAdapter } from "./adapter.js";
|
|
3
|
+
/** Native Chat Completions transport; the Agent consumes the shared ModelChunk contract. */
|
|
4
|
+
export declare class OpenAIChatAdapter extends OpenAIAdapter {
|
|
5
|
+
validate(request: ModelRequest): void;
|
|
6
|
+
stream(request: ModelRequest, context: ModelCallContext): AsyncIterable<ModelChunk>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { errorInfo, fail, MessageCodec, normalizeUsage, TessarError, } from "@tessar/core";
|
|
2
|
+
import { OpenAIAdapter, clientKeys } from "./adapter.js";
|
|
3
|
+
import { chatResponseError, decodeChatMessage, encodeChatMessages, } from "./chat-codec.js";
|
|
4
|
+
function usage(value) {
|
|
5
|
+
const cached = value?.prompt_tokens_details?.cached_tokens;
|
|
6
|
+
return normalizeUsage({
|
|
7
|
+
inputTokens: value?.prompt_tokens,
|
|
8
|
+
outputTokens: value?.completion_tokens,
|
|
9
|
+
totalTokens: value?.total_tokens,
|
|
10
|
+
cacheReadInputTokens: cached,
|
|
11
|
+
cacheWriteInputTokens: value?.prompt_tokens_details?.cache_write_tokens,
|
|
12
|
+
reasoningOutputTokens: value?.completion_tokens_details?.reasoning_tokens,
|
|
13
|
+
uncachedInputTokens: value?.prompt_tokens !== undefined && cached !== undefined
|
|
14
|
+
? Math.max(0, value.prompt_tokens - cached)
|
|
15
|
+
: null,
|
|
16
|
+
}, value ? JSON.parse(JSON.stringify(value)) : null);
|
|
17
|
+
}
|
|
18
|
+
/** Native Chat Completions transport; the Agent consumes the shared ModelChunk contract. */
|
|
19
|
+
export class OpenAIChatAdapter extends OpenAIAdapter {
|
|
20
|
+
validate(request) {
|
|
21
|
+
if (request.model.providerId !== this.ref.providerId ||
|
|
22
|
+
request.model.modelId !== this.ref.modelId ||
|
|
23
|
+
request.model.connectionId !== this.ref.connectionId)
|
|
24
|
+
fail("UnsupportedContext", "Chat model or connection identity mismatch");
|
|
25
|
+
for (const key of [
|
|
26
|
+
"connectionId",
|
|
27
|
+
"api",
|
|
28
|
+
"model",
|
|
29
|
+
"input",
|
|
30
|
+
"messages",
|
|
31
|
+
"instructions",
|
|
32
|
+
"tools",
|
|
33
|
+
"stream",
|
|
34
|
+
"functions",
|
|
35
|
+
"function_call",
|
|
36
|
+
...clientKeys,
|
|
37
|
+
])
|
|
38
|
+
if (request.options && key in request.options)
|
|
39
|
+
fail("UnsupportedOption", key + " is owned by the connection or Agent runtime");
|
|
40
|
+
if (request.options?.n != null && request.options.n !== 1)
|
|
41
|
+
fail("UnsupportedOption", "An Agent consumes one Chat completion choice");
|
|
42
|
+
encodeChatMessages(request, this.connection);
|
|
43
|
+
}
|
|
44
|
+
async *stream(request, context) {
|
|
45
|
+
this.validate(request);
|
|
46
|
+
context.signal.throwIfAborted();
|
|
47
|
+
try {
|
|
48
|
+
const stream = await this.client.chat.completions.create({
|
|
49
|
+
...request.options,
|
|
50
|
+
model: this.ref.modelId,
|
|
51
|
+
messages: encodeChatMessages(request, this.connection),
|
|
52
|
+
...(request.tools.length
|
|
53
|
+
? {
|
|
54
|
+
tools: request.tools.map((tool) => ({
|
|
55
|
+
type: "function",
|
|
56
|
+
function: {
|
|
57
|
+
name: tool.name,
|
|
58
|
+
description: tool.description,
|
|
59
|
+
parameters: tool.inputSchema,
|
|
60
|
+
},
|
|
61
|
+
})),
|
|
62
|
+
}
|
|
63
|
+
: {}),
|
|
64
|
+
stream: true,
|
|
65
|
+
}, { signal: context.signal });
|
|
66
|
+
let responseId = "", finishReason = null, text = "", refusal = "";
|
|
67
|
+
let counts;
|
|
68
|
+
const thinking = {};
|
|
69
|
+
const calls = new Map();
|
|
70
|
+
for await (const chunk of stream) {
|
|
71
|
+
context.signal.throwIfAborted();
|
|
72
|
+
if (chunk.id)
|
|
73
|
+
responseId = chunk.id;
|
|
74
|
+
if (chunk.usage)
|
|
75
|
+
counts = chunk.usage;
|
|
76
|
+
for (const choice of chunk.choices) {
|
|
77
|
+
if (choice.index !== 0)
|
|
78
|
+
throw chatResponseError("Unexpected multiple Chat completion choices");
|
|
79
|
+
const delta = choice.delta;
|
|
80
|
+
if (delta.audio || delta.function_call)
|
|
81
|
+
fail("UnsupportedResponse", "Unsupported Chat audio or deprecated function-call output");
|
|
82
|
+
if (delta.content != null) {
|
|
83
|
+
if (typeof delta.content !== "string")
|
|
84
|
+
throw chatResponseError("Chat content must be text");
|
|
85
|
+
text += delta.content;
|
|
86
|
+
if (delta.content)
|
|
87
|
+
yield {
|
|
88
|
+
type: "message-delta",
|
|
89
|
+
messageId: responseId,
|
|
90
|
+
partId: "text-0",
|
|
91
|
+
partKind: "text",
|
|
92
|
+
delta: delta.content,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (delta.refusal) {
|
|
96
|
+
refusal += delta.refusal;
|
|
97
|
+
yield {
|
|
98
|
+
type: "message-delta",
|
|
99
|
+
messageId: responseId,
|
|
100
|
+
partId: "refusal",
|
|
101
|
+
partKind: "text",
|
|
102
|
+
delta: delta.refusal,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
for (const key of ["reasoning_content", "reasoning"]) {
|
|
106
|
+
if (delta[key] === undefined || delta[key] === null)
|
|
107
|
+
continue;
|
|
108
|
+
if (typeof delta[key] !== "string")
|
|
109
|
+
throw chatResponseError("Chat reasoning must be text");
|
|
110
|
+
thinking[key] = (thinking[key] ?? "") + delta[key];
|
|
111
|
+
if (delta[key])
|
|
112
|
+
yield {
|
|
113
|
+
type: "message-delta",
|
|
114
|
+
messageId: responseId,
|
|
115
|
+
partId: key,
|
|
116
|
+
partKind: "reasoning",
|
|
117
|
+
delta: delta[key],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
for (const call of delta.tool_calls ?? []) {
|
|
121
|
+
if (!Number.isInteger(call.index) ||
|
|
122
|
+
call.index < 0 ||
|
|
123
|
+
(call.type && call.type !== "function"))
|
|
124
|
+
throw chatResponseError("Invalid Chat function-call chunk");
|
|
125
|
+
const saved = calls.get(call.index) ?? {
|
|
126
|
+
id: "",
|
|
127
|
+
type: "function",
|
|
128
|
+
function: { name: "", arguments: "" },
|
|
129
|
+
};
|
|
130
|
+
saved.id += call.id ?? "";
|
|
131
|
+
saved.function.name += call.function?.name ?? "";
|
|
132
|
+
saved.function.arguments += call.function?.arguments ?? "";
|
|
133
|
+
calls.set(call.index, saved);
|
|
134
|
+
}
|
|
135
|
+
if (choice.finish_reason)
|
|
136
|
+
finishReason = choice.finish_reason;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (!responseId || !finishReason)
|
|
140
|
+
throw chatResponseError("Chat stream ended before completion", "ProviderIncomplete");
|
|
141
|
+
if (finishReason === "tool_calls" && !calls.size)
|
|
142
|
+
throw chatResponseError("Chat completion ended with missing function calls");
|
|
143
|
+
const message = {
|
|
144
|
+
role: "assistant",
|
|
145
|
+
content: text || null,
|
|
146
|
+
...thinking,
|
|
147
|
+
...(refusal ? { refusal } : {}),
|
|
148
|
+
...(calls.size
|
|
149
|
+
? {
|
|
150
|
+
tool_calls: [...calls]
|
|
151
|
+
.sort(([a], [b]) => a - b)
|
|
152
|
+
.map(([, call]) => call),
|
|
153
|
+
}
|
|
154
|
+
: {}),
|
|
155
|
+
};
|
|
156
|
+
const normalized = usage(counts);
|
|
157
|
+
const decoded = decodeChatMessage(message, this.ref, responseId, this.connection);
|
|
158
|
+
yield { type: "usage", usage: normalized };
|
|
159
|
+
yield {
|
|
160
|
+
type: "response",
|
|
161
|
+
response: {
|
|
162
|
+
message: MessageCodec.encode(decoded),
|
|
163
|
+
usage: normalized,
|
|
164
|
+
finishReason,
|
|
165
|
+
providerRequestId: responseId,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (context.signal.aborted)
|
|
171
|
+
throw context.signal.reason;
|
|
172
|
+
errorInfo(error, {
|
|
173
|
+
source: error instanceof TessarError ? "tessar" : "provider",
|
|
174
|
+
...this.ref,
|
|
175
|
+
});
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=chat-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-adapter.js","sourceRoot":"","sources":["../src/chat-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AssistantMessage, type ModelRef, type ModelRequest, type ModelConnectionDescriptor } from "@tessar/core";
|
|
2
|
+
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions/completions";
|
|
3
|
+
export interface ChatAssistant {
|
|
4
|
+
role: "assistant";
|
|
5
|
+
content: string | null;
|
|
6
|
+
refusal?: string;
|
|
7
|
+
reasoning_content?: string;
|
|
8
|
+
reasoning?: string;
|
|
9
|
+
tool_calls?: {
|
|
10
|
+
id: string;
|
|
11
|
+
type: "function";
|
|
12
|
+
function: {
|
|
13
|
+
name: string;
|
|
14
|
+
arguments: string;
|
|
15
|
+
};
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
export declare function chatResponseError(message: string, code?: string): Error;
|
|
19
|
+
export declare function encodeChatMessages(request: ModelRequest, connection?: ModelConnectionDescriptor): ChatCompletionMessageParam[];
|
|
20
|
+
export declare function decodeChatMessage(message: ChatAssistant, ref: ModelRef, id: string, connection?: ModelConnectionDescriptor): AssistantMessage;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { AssistantMessage, fail, } from "@tessar/core";
|
|
2
|
+
export function chatResponseError(message, code = "ProviderResponse") {
|
|
3
|
+
return Object.assign(new Error(message), { code });
|
|
4
|
+
}
|
|
5
|
+
function toolOutput(message) {
|
|
6
|
+
return message.content
|
|
7
|
+
.map((part) => {
|
|
8
|
+
if (part.type === "text")
|
|
9
|
+
return part.text;
|
|
10
|
+
if (part.type === "data")
|
|
11
|
+
return JSON.stringify(part.data);
|
|
12
|
+
return fail("UnsupportedContext", "Chat tool output requires text or JSON data");
|
|
13
|
+
})
|
|
14
|
+
.join("");
|
|
15
|
+
}
|
|
16
|
+
export function encodeChatMessages(request, connection) {
|
|
17
|
+
const messages = [];
|
|
18
|
+
const instructions = request.instructions.sections
|
|
19
|
+
.map((section) => section.content)
|
|
20
|
+
.join("\n\n");
|
|
21
|
+
if (request.instructions.sections.some((section) => section.content.length > 0))
|
|
22
|
+
messages.push({ role: "system", content: instructions });
|
|
23
|
+
for (const message of request.messages) {
|
|
24
|
+
if (message.providerState !== undefined) {
|
|
25
|
+
const state = message.providerState;
|
|
26
|
+
if (!state ||
|
|
27
|
+
state.codec !== "openai.chat-completions" ||
|
|
28
|
+
state.version !== 1 ||
|
|
29
|
+
state.providerId !== request.model.providerId ||
|
|
30
|
+
state.modelId !== request.model.modelId ||
|
|
31
|
+
state.connectionId !== request.model.connectionId ||
|
|
32
|
+
state.message?.role !== "assistant" ||
|
|
33
|
+
(state.connection !== undefined &&
|
|
34
|
+
(state.connection.endpoint !== connection?.endpoint ||
|
|
35
|
+
state.connection.protocol !== connection?.protocol)))
|
|
36
|
+
fail("UnsupportedContext", "Opaque Chat context requires its original model, connection and protocol");
|
|
37
|
+
messages.push(state.message);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (message.content.some((part) => part.type === "reasoning"))
|
|
41
|
+
fail("UnsupportedContext", "Reasoning history requires native provider continuity");
|
|
42
|
+
if (message.role === "tool") {
|
|
43
|
+
if (!message.toolCallId)
|
|
44
|
+
fail("InvalidMessage", "Tool history requires toolCallId");
|
|
45
|
+
messages.push({
|
|
46
|
+
role: "tool",
|
|
47
|
+
tool_call_id: message.toolCallId,
|
|
48
|
+
content: toolOutput(message),
|
|
49
|
+
});
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (message.role === "assistant") {
|
|
53
|
+
const text = [], calls = [];
|
|
54
|
+
for (const part of message.content) {
|
|
55
|
+
if (part.type === "text")
|
|
56
|
+
text.push(part.text);
|
|
57
|
+
else if (part.type === "tool-call")
|
|
58
|
+
calls.push({
|
|
59
|
+
id: part.toolCallId,
|
|
60
|
+
type: "function",
|
|
61
|
+
function: {
|
|
62
|
+
name: part.name,
|
|
63
|
+
arguments: JSON.stringify(part.arguments),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
else
|
|
67
|
+
fail("UnsupportedContext", "Unsupported Chat assistant content");
|
|
68
|
+
}
|
|
69
|
+
messages.push({
|
|
70
|
+
role: "assistant",
|
|
71
|
+
content: text.length ? text.join("") : null,
|
|
72
|
+
...(calls.length ? { tool_calls: calls } : {}),
|
|
73
|
+
});
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (message.role === "system") {
|
|
77
|
+
if (message.content.some((part) => part.type !== "text"))
|
|
78
|
+
fail("UnsupportedContext", "System content requires text");
|
|
79
|
+
messages.push({
|
|
80
|
+
role: "system",
|
|
81
|
+
content: message.content
|
|
82
|
+
.map((part) => part.text)
|
|
83
|
+
.join(""),
|
|
84
|
+
});
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (message.content.every((part) => part.type === "text")) {
|
|
88
|
+
messages.push({
|
|
89
|
+
role: "user",
|
|
90
|
+
content: message.content.map((part) => part.text).join(""),
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const content = message.content.map((part) => {
|
|
95
|
+
if (part.type === "text")
|
|
96
|
+
return { type: "text", text: part.text };
|
|
97
|
+
if (part.type === "image")
|
|
98
|
+
return {
|
|
99
|
+
type: "image_url",
|
|
100
|
+
image_url: {
|
|
101
|
+
url: /^(https?:|data:)/.test(part.data)
|
|
102
|
+
? part.data
|
|
103
|
+
: `data:${part.mediaType};base64,${part.data}`,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
if (part.type === "file")
|
|
107
|
+
return { type: "file", file: { file_data: part.data } };
|
|
108
|
+
return fail("UnsupportedContext", "Unsupported Chat user content");
|
|
109
|
+
});
|
|
110
|
+
messages.push({ role: "user", content });
|
|
111
|
+
}
|
|
112
|
+
return messages;
|
|
113
|
+
}
|
|
114
|
+
export function decodeChatMessage(message, ref, id, connection) {
|
|
115
|
+
const parts = [];
|
|
116
|
+
for (const text of [message.reasoning_content, message.reasoning])
|
|
117
|
+
if (text)
|
|
118
|
+
parts.push({ type: "reasoning", text });
|
|
119
|
+
if (message.content)
|
|
120
|
+
parts.push({ type: "text", text: message.content });
|
|
121
|
+
if (message.refusal)
|
|
122
|
+
parts.push({ type: "text", text: message.refusal });
|
|
123
|
+
const ids = new Set();
|
|
124
|
+
for (const call of message.tool_calls ?? []) {
|
|
125
|
+
if (!call.id || !call.function.name)
|
|
126
|
+
throw chatResponseError("Missing Chat function identity");
|
|
127
|
+
if (ids.has(call.id))
|
|
128
|
+
throw chatResponseError("Duplicate Chat function identity");
|
|
129
|
+
ids.add(call.id);
|
|
130
|
+
let args;
|
|
131
|
+
try {
|
|
132
|
+
args = JSON.parse(call.function.arguments);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
throw chatResponseError("Invalid Chat function arguments");
|
|
136
|
+
}
|
|
137
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
138
|
+
throw chatResponseError("Chat function arguments must be an object");
|
|
139
|
+
parts.push({
|
|
140
|
+
type: "tool-call",
|
|
141
|
+
toolCallId: call.id,
|
|
142
|
+
name: call.function.name,
|
|
143
|
+
arguments: args,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return new AssistantMessage(parts, {
|
|
147
|
+
id,
|
|
148
|
+
providerState: {
|
|
149
|
+
codec: "openai.chat-completions",
|
|
150
|
+
version: 1,
|
|
151
|
+
...ref,
|
|
152
|
+
message,
|
|
153
|
+
...(connection ? { connection: { ...connection } } : {}),
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=chat-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-codec.js","sourceRoot":"","sources":["../src/chat-codec.ts"],"names":[],"mappings":"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"}
|
package/dist/codec.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssistantMessage, type ModelRef, type ModelRequest } from "@tessar/core";
|
|
1
|
+
import { AssistantMessage, type ModelRef, type ModelRequest, type ModelConnectionDescriptor } from "@tessar/core";
|
|
2
2
|
import type { ResponseInput } from "openai/resources/responses/responses";
|
|
3
|
-
export declare function encodeInput(request: ModelRequest): ResponseInput;
|
|
4
|
-
export declare function decodeOutput(items: readonly unknown[], ref: ModelRef, responseId: string): AssistantMessage;
|
|
3
|
+
export declare function encodeInput(request: ModelRequest, connection?: ModelConnectionDescriptor): ResponseInput;
|
|
4
|
+
export declare function decodeOutput(items: readonly unknown[], ref: ModelRef, responseId: string, connection?: ModelConnectionDescriptor): AssistantMessage;
|
package/dist/codec.js
CHANGED
|
@@ -10,13 +10,17 @@ function continuity(value) {
|
|
|
10
10
|
fail("UnsupportedContext", "Unknown OpenAI continuity version");
|
|
11
11
|
return data;
|
|
12
12
|
}
|
|
13
|
-
export function encodeInput(request) {
|
|
13
|
+
export function encodeInput(request, connection) {
|
|
14
14
|
const input = [];
|
|
15
15
|
for (const message of request.messages) {
|
|
16
16
|
const state = continuity(message.providerState);
|
|
17
17
|
if (state) {
|
|
18
18
|
if (state.providerId !== request.model.providerId ||
|
|
19
|
-
state.modelId !== request.model.modelId
|
|
19
|
+
state.modelId !== request.model.modelId ||
|
|
20
|
+
state.connectionId !== request.model.connectionId ||
|
|
21
|
+
(state.connection !== undefined &&
|
|
22
|
+
(state.connection.endpoint !== connection?.endpoint ||
|
|
23
|
+
state.connection.protocol !== connection?.protocol)))
|
|
20
24
|
fail("UnsupportedContext", "Opaque OpenAI context requires its original model");
|
|
21
25
|
input.push(...state.items);
|
|
22
26
|
continue;
|
|
@@ -25,13 +29,17 @@ export function encodeInput(request) {
|
|
|
25
29
|
message.content.some((p) => p.type === "reasoning"))
|
|
26
30
|
fail("UnsupportedContext", "Unsupported provider continuity");
|
|
27
31
|
if (message.role === "tool") {
|
|
28
|
-
if (message.content.some((p) => p.type !== "text"))
|
|
29
|
-
fail("UnsupportedContext", "OpenAI tool output currently requires text parts");
|
|
32
|
+
if (message.content.some((p) => p.type !== "text" && p.type !== "data"))
|
|
33
|
+
fail("UnsupportedContext", "OpenAI tool output currently requires text or JSON data parts");
|
|
30
34
|
input.push({
|
|
31
35
|
type: "function_call_output",
|
|
32
36
|
call_id: message.toolCallId,
|
|
33
37
|
output: message.content
|
|
34
|
-
.map((p) =>
|
|
38
|
+
.map((p) => p.type === "text"
|
|
39
|
+
? p.text
|
|
40
|
+
: p.type === "data"
|
|
41
|
+
? JSON.stringify(p.data)
|
|
42
|
+
: "")
|
|
35
43
|
.join(""),
|
|
36
44
|
});
|
|
37
45
|
continue;
|
|
@@ -90,7 +98,7 @@ export function encodeInput(request) {
|
|
|
90
98
|
}
|
|
91
99
|
return input;
|
|
92
100
|
}
|
|
93
|
-
export function decodeOutput(items, ref, responseId) {
|
|
101
|
+
export function decodeOutput(items, ref, responseId, connection) {
|
|
94
102
|
assertJson(items);
|
|
95
103
|
const parts = [];
|
|
96
104
|
for (const raw of items) {
|
|
@@ -138,6 +146,7 @@ export function decodeOutput(items, ref, responseId) {
|
|
|
138
146
|
codec: "openai.responses",
|
|
139
147
|
version: 1,
|
|
140
148
|
...ref,
|
|
149
|
+
...(connection ? { connection: { ...connection } } : {}),
|
|
141
150
|
items: items,
|
|
142
151
|
},
|
|
143
152
|
});
|
package/dist/codec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,IAAI,EACJ,UAAU,
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,cAAc,GAKf,MAAM,eAAe,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -12,7 +12,7 @@ export class OpenAIPlugin {
|
|
|
12
12
|
setup(tessar) {
|
|
13
13
|
const options = this.options, id = this.providerId;
|
|
14
14
|
const client = createClient(options);
|
|
15
|
-
tessar.models.
|
|
15
|
+
tessar.models.register({
|
|
16
16
|
id,
|
|
17
17
|
endpoint: options.baseURL ?? "https://api.openai.com/v1",
|
|
18
18
|
metadataPartition: options.metadataPartition,
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,MAAM,OAAO,YAAY;IACd,EAAE,CAAS;IACH,UAAU,CAAS;IACnB,OAAO,CAAgB;IAExC,YAAY,OAAsB;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC;QACjD,IAAI,CAAC,EAAE,GAAG,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,MAAqB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,MAAM,OAAO,YAAY;IACd,EAAE,CAAS;IACH,UAAU,CAAS;IACnB,OAAO,CAAgB;IAExC,YAAY,OAAsB;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC;QACjD,IAAI,CAAC,EAAE,GAAG,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,MAAqB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAC1B,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;QACvB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;YACrB,EAAE;YACF,QAAQ,EAAE,OAAO,CAAC,OAAO,IAAI,2BAA2B;YACxD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC;YAClC,eAAe,EAAE,CAAC,GAAG,EAAE,EAAE,CACvB,CAAC,OAAO,CAAC,OAAO;gBAChB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,2BAA2B;gBAChE,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;gBAChD,CAAC,CAAC,IAAI;YACV,qBAAqB,EAAE,CAAC;YACxB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAClB,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC;SAClE,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type OpenAI from "openai";
|
|
2
|
+
import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses";
|
|
3
|
+
import type { ChatCompletionCreateParamsStreaming } from "openai/resources/chat/completions/completions";
|
|
4
|
+
import { ProfileResolver, type ModelProfile, type ModelRequest, type ModelCallContext, type ModelChunk } from "@tessar/core";
|
|
5
|
+
import { OpenAIAdapter, type OpenAIOptions } from "./adapter.js";
|
|
6
|
+
export type OpenAIModelOptions = Omit<ResponseCreateParamsStreaming, "model" | "input" | "instructions" | "tools" | "stream" | "background" | "conversation" | "previous_response_id" | "context_management">;
|
|
7
|
+
export type OpenAIAPI = "responses" | "chat-completions";
|
|
8
|
+
export type OpenAIChatModelOptions = Omit<ChatCompletionCreateParamsStreaming, "model" | "messages" | "tools" | "stream" | "functions" | "function_call" | "n"> & {
|
|
9
|
+
n?: 1;
|
|
10
|
+
};
|
|
11
|
+
type OptionsFor<A extends OpenAIAPI> = A extends "chat-completions" ? OpenAIChatModelOptions : OpenAIModelOptions;
|
|
12
|
+
export type OpenAIProviderOptions<A extends OpenAIAPI = OpenAIAPI> = OpenAIOptions & {
|
|
13
|
+
model: string;
|
|
14
|
+
connectionId?: string;
|
|
15
|
+
} & (A extends "chat-completions" ? {
|
|
16
|
+
api: "chat-completions";
|
|
17
|
+
} & OpenAIChatModelOptions : {
|
|
18
|
+
api?: "responses";
|
|
19
|
+
} & OpenAIModelOptions);
|
|
20
|
+
interface Connection {
|
|
21
|
+
client: OpenAI;
|
|
22
|
+
identity: string;
|
|
23
|
+
resolver: ProfileResolver;
|
|
24
|
+
}
|
|
25
|
+
export declare class OpenAIProvider<A extends OpenAIAPI = "responses"> extends OpenAIAdapter {
|
|
26
|
+
readonly options: Readonly<OptionsFor<A>>;
|
|
27
|
+
readonly api: A;
|
|
28
|
+
private readonly chat?;
|
|
29
|
+
private readonly clientOptions;
|
|
30
|
+
private readonly sharedConnection;
|
|
31
|
+
private readonly registration;
|
|
32
|
+
constructor(configuration: OpenAIProviderOptions<A> & {
|
|
33
|
+
api?: A;
|
|
34
|
+
}, connection?: Connection);
|
|
35
|
+
withModel(modelId: string): OpenAIProvider<A>;
|
|
36
|
+
validate(request: ModelRequest): void;
|
|
37
|
+
stream(request: ModelRequest, context: ModelCallContext): AsyncIterable<ModelChunk>;
|
|
38
|
+
get profile(): Readonly<ModelProfile>;
|
|
39
|
+
refreshProfile(options?: {
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
}): Promise<ModelProfile>;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ProfileResolver, snapshotModelOptions, requireId, fail, } from "@tessar/core";
|
|
2
|
+
import { OpenAIAdapter, createClient, clientKeys, } from "./adapter.js";
|
|
3
|
+
import { metadataResolver } from "./metadata.js";
|
|
4
|
+
import { OpenAIChatAdapter } from "./chat-adapter.js";
|
|
5
|
+
export class OpenAIProvider extends OpenAIAdapter {
|
|
6
|
+
options;
|
|
7
|
+
api;
|
|
8
|
+
chat;
|
|
9
|
+
clientOptions;
|
|
10
|
+
sharedConnection;
|
|
11
|
+
registration;
|
|
12
|
+
constructor(configuration, connection) {
|
|
13
|
+
const { model, providerId = "openai", metadataPartition, connectionId, api = "responses", ...fields } = configuration;
|
|
14
|
+
if (api !== "responses" && api !== "chat-completions")
|
|
15
|
+
fail("InvalidConfiguration", "Choose responses or chat-completions");
|
|
16
|
+
requireId(model, "model id");
|
|
17
|
+
requireId(providerId, "provider id");
|
|
18
|
+
const clientOptions = Object.fromEntries(clientKeys
|
|
19
|
+
.filter((key) => fields[key] !== undefined)
|
|
20
|
+
.map((key) => [key, fields[key]]));
|
|
21
|
+
const body = Object.fromEntries(Object.entries(fields).filter(([key, value]) => !clientKeys.includes(key) && value !== undefined));
|
|
22
|
+
for (const key of [
|
|
23
|
+
"input",
|
|
24
|
+
"messages",
|
|
25
|
+
"instructions",
|
|
26
|
+
"tools",
|
|
27
|
+
"stream",
|
|
28
|
+
"functions",
|
|
29
|
+
"function_call",
|
|
30
|
+
])
|
|
31
|
+
if (key in body)
|
|
32
|
+
fail("UnsupportedOption", key + " is owned by the Agent runtime");
|
|
33
|
+
if (body.background === true ||
|
|
34
|
+
body.conversation != null ||
|
|
35
|
+
body.previous_response_id != null ||
|
|
36
|
+
body.context_management != null)
|
|
37
|
+
fail("UnsupportedOption", "Background, provider-managed conversations and compaction are not supported by the Agent loop");
|
|
38
|
+
if (api === "chat-completions" && body.n != null && body.n !== 1)
|
|
39
|
+
fail("UnsupportedOption", "An Agent consumes one Chat completion choice");
|
|
40
|
+
const requestOptions = snapshotModelOptions(body);
|
|
41
|
+
const selected = connection ?? {
|
|
42
|
+
client: createClient(clientOptions),
|
|
43
|
+
identity: connectionId === undefined
|
|
44
|
+
? crypto.randomUUID()
|
|
45
|
+
: requireId(connectionId, "connection id"),
|
|
46
|
+
resolver: new ProfileResolver(),
|
|
47
|
+
};
|
|
48
|
+
const descriptor = Object.freeze({
|
|
49
|
+
providerId,
|
|
50
|
+
connectionId: selected.identity,
|
|
51
|
+
protocol: api,
|
|
52
|
+
endpoint: selected.client.baseURL.replace(/\/$/, ""),
|
|
53
|
+
});
|
|
54
|
+
super(clientOptions, Object.freeze({
|
|
55
|
+
providerId,
|
|
56
|
+
modelId: model,
|
|
57
|
+
connectionId: selected.identity,
|
|
58
|
+
}), selected.client, descriptor);
|
|
59
|
+
this.options = requestOptions;
|
|
60
|
+
this.api = api;
|
|
61
|
+
if (api === "chat-completions")
|
|
62
|
+
this.chat = new OpenAIChatAdapter(clientOptions, this.ref, selected.client, descriptor);
|
|
63
|
+
this.clientOptions = { ...clientOptions, providerId, metadataPartition };
|
|
64
|
+
this.sharedConnection = selected;
|
|
65
|
+
const officialEndpoint = !clientOptions.baseURL ||
|
|
66
|
+
clientOptions.baseURL.replace(/\/$/, "") === "https://api.openai.com/v1";
|
|
67
|
+
this.registration = {
|
|
68
|
+
id: providerId,
|
|
69
|
+
create: (modelId) => this.withModel(modelId),
|
|
70
|
+
endpoint: clientOptions.baseURL ?? "https://api.openai.com/v1",
|
|
71
|
+
metadataPartition: metadataPartition ?? selected.identity,
|
|
72
|
+
metadata: metadataResolver(selected.client),
|
|
73
|
+
catalogModelRef: (ref) => officialEndpoint
|
|
74
|
+
? { providerId: "openai", modelId: ref.modelId }
|
|
75
|
+
: null,
|
|
76
|
+
catalogMappingVersion: 1,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
withModel(modelId) {
|
|
80
|
+
return new OpenAIProvider({
|
|
81
|
+
...this.clientOptions,
|
|
82
|
+
...this.options,
|
|
83
|
+
api: this.api,
|
|
84
|
+
model: modelId,
|
|
85
|
+
}, this.sharedConnection);
|
|
86
|
+
}
|
|
87
|
+
validate(request) {
|
|
88
|
+
if (this.chat)
|
|
89
|
+
this.chat.validate(request);
|
|
90
|
+
else
|
|
91
|
+
super.validate(request);
|
|
92
|
+
}
|
|
93
|
+
async *stream(request, context) {
|
|
94
|
+
if (this.chat)
|
|
95
|
+
yield* this.chat.stream(request, context);
|
|
96
|
+
else
|
|
97
|
+
yield* super.stream(request, context);
|
|
98
|
+
}
|
|
99
|
+
get profile() {
|
|
100
|
+
return this.sharedConnection.resolver.current(this.ref, this.registration);
|
|
101
|
+
}
|
|
102
|
+
refreshProfile(options = {}) {
|
|
103
|
+
return this.sharedConnection.resolver.resolve(this.ref, this.registration, options.signal);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tessar/openai",
|
|
3
|
-
"version": "0.1.0
|
|
4
|
-
"description": "OpenAI Responses provider
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenAI Responses and Chat Completions provider with model metadata integration for Tessar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=24.14.0"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"openai": "7.34.0",
|
|
29
|
-
"@tessar/core": "0.1.0
|
|
29
|
+
"@tessar/core": "0.1.0"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsc -p tsconfig.json",
|