@glassly/llm-providers 0.3.5-dev.823 → 0.3.5-dev.826
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/package.json +2 -2
- package/src/index.ts +1 -1
- package/src/openai.ts +43 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassly/llm-providers",
|
|
3
|
-
"version": "0.3.5-dev.
|
|
3
|
+
"version": "0.3.5-dev.826",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"test": "bun test"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@glassly/cloud-protocol": "0.3.5-dev.
|
|
13
|
+
"@glassly/cloud-protocol": "0.3.5-dev.826"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"src",
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export {createAnthropicProvider} from "./anthropic";
|
|
9
9
|
export {createGeminiProvider} from "./gemini";
|
|
10
|
-
export {createOpenAiProvider} from "./openai";
|
|
10
|
+
export {createDeepSeekProvider, createOpenAiProvider} from "./openai";
|
|
11
11
|
export type {
|
|
12
12
|
LlmProviderCompleteArgs,
|
|
13
13
|
LlmProviderImpl,
|
package/src/openai.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
2
|
+
* @fileoverview Chat Completions providers: OpenAI, and DeepSeek which serves
|
|
3
|
+
* the same wire format at its own endpoint. One translator, a dialect table
|
|
4
|
+
* for what differs (URL, default model, token-limit field name).
|
|
3
5
|
*
|
|
4
6
|
* Raw `fetch` like the other providers — this code runs both server-side and
|
|
5
7
|
* on the phone (React Native), so no SDK and no Node APIs.
|
|
@@ -23,11 +25,31 @@
|
|
|
23
25
|
* it is the contract-correct degradation — the model answers from knowledge
|
|
24
26
|
* and the result carries no webSearchCount.
|
|
25
27
|
*/
|
|
26
|
-
import type { LlmStopReason, LlmToolCall } from "@glassly/cloud-protocol/llm";
|
|
28
|
+
import type { LlmProvider, LlmStopReason, LlmToolCall } from "@glassly/cloud-protocol/llm";
|
|
27
29
|
import type { LlmProviderCompleteArgs, LlmProviderImpl, LlmProviderOptions } from "./provider";
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
interface ChatCompletionsDialect {
|
|
32
|
+
name: LlmProvider;
|
|
33
|
+
url: string;
|
|
34
|
+
fallbackModel: string;
|
|
35
|
+
/** OpenAI retired `max_tokens` on current models; DeepSeek still takes it. */
|
|
36
|
+
maxTokensField: "max_completion_tokens" | "max_tokens";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const OPENAI: ChatCompletionsDialect = {
|
|
40
|
+
name: "openai",
|
|
41
|
+
url: "https://api.openai.com/v1/chat/completions",
|
|
42
|
+
fallbackModel: "gpt-5.1",
|
|
43
|
+
maxTokensField: "max_completion_tokens",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const DEEPSEEK: ChatCompletionsDialect = {
|
|
47
|
+
name: "deepseek",
|
|
48
|
+
url: "https://api.deepseek.com/chat/completions",
|
|
49
|
+
fallbackModel: "deepseek-chat",
|
|
50
|
+
maxTokensField: "max_tokens",
|
|
51
|
+
};
|
|
52
|
+
|
|
31
53
|
const DEFAULT_MAX_TOKENS = 2048;
|
|
32
54
|
|
|
33
55
|
interface OpenAiToolCall {
|
|
@@ -92,12 +114,12 @@ function toOpenAiMessages(args: LlmProviderCompleteArgs): unknown[] {
|
|
|
92
114
|
return out;
|
|
93
115
|
}
|
|
94
116
|
|
|
95
|
-
|
|
96
|
-
const defaultModel = opts.defaultModel?.trim() ||
|
|
117
|
+
function createChatCompletionsProvider(dialect: ChatCompletionsDialect, opts: LlmProviderOptions): LlmProviderImpl {
|
|
118
|
+
const defaultModel = opts.defaultModel?.trim() || dialect.fallbackModel;
|
|
97
119
|
const logger = opts.logger;
|
|
98
120
|
|
|
99
121
|
return {
|
|
100
|
-
name:
|
|
122
|
+
name: dialect.name,
|
|
101
123
|
defaultModel,
|
|
102
124
|
|
|
103
125
|
async complete(args) {
|
|
@@ -105,7 +127,7 @@ export function createOpenAiProvider(opts: LlmProviderOptions = {}): LlmProvider
|
|
|
105
127
|
|
|
106
128
|
const body: Record<string, unknown> = {
|
|
107
129
|
model,
|
|
108
|
-
|
|
130
|
+
[dialect.maxTokensField]: args.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
109
131
|
messages: toOpenAiMessages(args),
|
|
110
132
|
};
|
|
111
133
|
// `temperature` is deliberately dropped, like the Anthropic provider:
|
|
@@ -120,7 +142,7 @@ export function createOpenAiProvider(opts: LlmProviderOptions = {}): LlmProvider
|
|
|
120
142
|
}));
|
|
121
143
|
}
|
|
122
144
|
|
|
123
|
-
const res = await fetch(
|
|
145
|
+
const res = await fetch(dialect.url, {
|
|
124
146
|
method: "POST",
|
|
125
147
|
headers: {
|
|
126
148
|
"Content-Type": "application/json",
|
|
@@ -131,8 +153,8 @@ export function createOpenAiProvider(opts: LlmProviderOptions = {}): LlmProvider
|
|
|
131
153
|
|
|
132
154
|
if (!res.ok) {
|
|
133
155
|
const detail = await res.text().catch(() => "");
|
|
134
|
-
logger?.error({ status: res.status, model },
|
|
135
|
-
throw new Error(
|
|
156
|
+
logger?.error({ status: res.status, model }, `${dialect.name} completion failed`);
|
|
157
|
+
throw new Error(`${dialect.name} ${res.status}: ${detail.slice(0, 300)}`);
|
|
136
158
|
}
|
|
137
159
|
|
|
138
160
|
const data = (await res.json()) as OpenAiResponse;
|
|
@@ -161,9 +183,18 @@ export function createOpenAiProvider(opts: LlmProviderOptions = {}): LlmProvider
|
|
|
161
183
|
inputTokens: data.usage?.prompt_tokens ?? 0,
|
|
162
184
|
outputTokens: data.usage?.completion_tokens ?? 0,
|
|
163
185
|
},
|
|
164
|
-
provider:
|
|
186
|
+
provider: dialect.name,
|
|
165
187
|
model,
|
|
166
188
|
};
|
|
167
189
|
},
|
|
168
190
|
};
|
|
169
191
|
}
|
|
192
|
+
|
|
193
|
+
export function createOpenAiProvider(opts: LlmProviderOptions = {}): LlmProviderImpl {
|
|
194
|
+
return createChatCompletionsProvider(OPENAI, opts);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** DeepSeek: OpenAI-compatible Chat Completions. `deepseek-chat` / `deepseek-reasoner`. */
|
|
198
|
+
export function createDeepSeekProvider(opts: LlmProviderOptions = {}): LlmProviderImpl {
|
|
199
|
+
return createChatCompletionsProvider(DEEPSEEK, opts);
|
|
200
|
+
}
|