@cyrilmarin/dsh-lemonade 0.2.1 → 0.2.6
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.fr.md +6 -0
- package/README.md +6 -0
- package/lib/index.js +25 -20
- package/package.json +5 -1
- package/src/index.ts +23 -15
package/README.fr.md
CHANGED
|
@@ -32,6 +32,12 @@ Depuis le répertoire du profil (ex. `~/.dsh/profiles/web`) :
|
|
|
32
32
|
pnpm add file:../dsh-lemonade-provider
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
ou depuis npm (le paquet publié est `@cyrilmarin/dsh-lemonade`) :
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
pnpm add @cyrilmarin/dsh-lemonade@latest
|
|
39
|
+
```
|
|
40
|
+
|
|
35
41
|
ou, en ligne de commande dsh :
|
|
36
42
|
|
|
37
43
|
```sh
|
package/README.md
CHANGED
|
@@ -32,6 +32,12 @@ From the profile directory (e.g. `~/.dsh/profiles/web`):
|
|
|
32
32
|
pnpm add file:../dsh-lemonade-provider
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Or from npm (the published package is `@cyrilmarin/dsh-lemonade`):
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
pnpm add @cyrilmarin/dsh-lemonade@latest
|
|
39
|
+
```
|
|
40
|
+
|
|
35
41
|
Or, via the dsh command line:
|
|
36
42
|
|
|
37
43
|
```sh
|
package/lib/index.js
CHANGED
|
@@ -125,24 +125,39 @@ export function resolveAdapterOptions(config, environment) {
|
|
|
125
125
|
retryPolicy: resolveRetryPolicy(config.retryPolicy, 'llm-lemonade: retryPolicy'),
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
-
/**
|
|
128
|
+
/**
|
|
129
|
+
* Resolve one credential reference through the credentials seam, falling back
|
|
130
|
+
* to the launch environment. Never returns a blank value; `undefined` when the
|
|
131
|
+
* key is unconfigured. Shared by the adapter bearer-token resolver (which may
|
|
132
|
+
* additionally enforce `requireAuth`) and by the host proxy key resolver.
|
|
133
|
+
*/
|
|
134
|
+
async function resolveCredential(ctx, ref) {
|
|
135
|
+
let value;
|
|
136
|
+
const credentials = ctx.get('credentials');
|
|
137
|
+
if (credentials !== undefined)
|
|
138
|
+
value = (await credentials.resolve(ref))?.value;
|
|
139
|
+
if (value === undefined)
|
|
140
|
+
value = launchEnvironmentOf(ctx).get(ref)?.value;
|
|
141
|
+
if (value === undefined || value.length === 0)
|
|
142
|
+
return undefined;
|
|
143
|
+
return assertUsableApiKey(value, 'llm-lemonade', String(ref));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolve the optional bearer token, enforcing `requireAuth` when configured.
|
|
147
|
+
* The credentials-or-env resolution itself is delegated to resolveCredential.
|
|
148
|
+
*/
|
|
129
149
|
function makeResolveApiKey(ctx, options) {
|
|
130
150
|
return async () => {
|
|
131
151
|
const connection = options();
|
|
132
152
|
const ref = connection.apiKeyEnv;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (credentials !== undefined)
|
|
136
|
-
value = (await credentials.resolve(ref))?.value;
|
|
137
|
-
if (value === undefined)
|
|
138
|
-
value = launchEnvironmentOf(ctx).get(ref)?.value;
|
|
139
|
-
if (value === undefined || value.length === 0) {
|
|
153
|
+
const value = await resolveCredential(ctx, ref);
|
|
154
|
+
if (value === undefined) {
|
|
140
155
|
if (connection.requireAuth) {
|
|
141
156
|
throw new LlmError(`llm-lemonade: no API key for provider route "${PROVIDER}"; store ${String(ref)} through the credentials service (the web Models page writes it), or export ${String(ref)} in the launching environment`, 'MISSING_CREDENTIAL');
|
|
142
157
|
}
|
|
143
158
|
return undefined;
|
|
144
159
|
}
|
|
145
|
-
return
|
|
160
|
+
return value;
|
|
146
161
|
};
|
|
147
162
|
}
|
|
148
163
|
/**
|
|
@@ -211,17 +226,7 @@ export function apply(ctx, config) {
|
|
|
211
226
|
// Lemonade-specific API proxy: browser client half calls these routes
|
|
212
227
|
// same-origin; the keys are resolved host-side and never reach the browser.
|
|
213
228
|
// Per-endpoint key selection (regular vs admin) lives in server-api.ts.
|
|
214
|
-
const resolveKey =
|
|
215
|
-
let value;
|
|
216
|
-
const credentials = ctx.get('credentials');
|
|
217
|
-
if (credentials !== undefined)
|
|
218
|
-
value = (await credentials.resolve(ref))?.value;
|
|
219
|
-
if (value === undefined)
|
|
220
|
-
value = launchEnvironmentOf(ctx).get(ref)?.value;
|
|
221
|
-
if (value === undefined || value.length === 0)
|
|
222
|
-
return undefined;
|
|
223
|
-
return assertUsableApiKey(value, 'llm-lemonade', String(ref));
|
|
224
|
-
};
|
|
229
|
+
const resolveKey = (ref) => resolveCredential(ctx, ref);
|
|
225
230
|
const apiCfg = {
|
|
226
231
|
baseURL: () => options().baseURL,
|
|
227
232
|
requireAuth: () => options().requireAuth,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyrilmarin/dsh-lemonade",
|
|
3
3
|
"description": "Lemonade Server (OpenAI-compatible) LLM provider plugin for the DeepSeek Harness",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"lib/client.js"
|
|
25
25
|
],
|
|
26
26
|
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/ziouf/dsh-lemonade-provider"
|
|
30
|
+
},
|
|
27
31
|
"publishConfig": {
|
|
28
32
|
"access": "public"
|
|
29
33
|
},
|
package/src/index.ts
CHANGED
|
@@ -184,16 +184,31 @@ export function resolveAdapterOptions(
|
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* Resolve one credential reference through the credentials seam, falling back
|
|
189
|
+
* to the launch environment. Never returns a blank value; `undefined` when the
|
|
190
|
+
* key is unconfigured. Shared by the adapter bearer-token resolver (which may
|
|
191
|
+
* additionally enforce `requireAuth`) and by the host proxy key resolver.
|
|
192
|
+
*/
|
|
193
|
+
async function resolveCredential(ctx: Context, ref: CredentialRef): Promise<string | undefined> {
|
|
194
|
+
let value: string | undefined;
|
|
195
|
+
const credentials = ctx.get('credentials');
|
|
196
|
+
if (credentials !== undefined) value = (await credentials.resolve(ref))?.value;
|
|
197
|
+
if (value === undefined) value = launchEnvironmentOf(ctx).get(ref)?.value;
|
|
198
|
+
if (value === undefined || value.length === 0) return undefined;
|
|
199
|
+
return assertUsableApiKey(value, 'llm-lemonade', String(ref));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Resolve the optional bearer token, enforcing `requireAuth` when configured.
|
|
204
|
+
* The credentials-or-env resolution itself is delegated to resolveCredential.
|
|
205
|
+
*/
|
|
188
206
|
function makeResolveApiKey(ctx: Context, options: () => LemonadeOptions): () => Promise<string | undefined> {
|
|
189
207
|
return async () => {
|
|
190
208
|
const connection = options();
|
|
191
209
|
const ref = connection.apiKeyEnv;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (credentials !== undefined) value = (await credentials.resolve(ref))?.value;
|
|
195
|
-
if (value === undefined) value = launchEnvironmentOf(ctx).get(ref)?.value;
|
|
196
|
-
if (value === undefined || value.length === 0) {
|
|
210
|
+
const value = await resolveCredential(ctx, ref);
|
|
211
|
+
if (value === undefined) {
|
|
197
212
|
if (connection.requireAuth) {
|
|
198
213
|
throw new LlmError(
|
|
199
214
|
`llm-lemonade: no API key for provider route "${PROVIDER}"; store ${String(ref)} through the credentials service (the web Models page writes it), or export ${String(ref)} in the launching environment`,
|
|
@@ -202,7 +217,7 @@ function makeResolveApiKey(ctx: Context, options: () => LemonadeOptions): () =>
|
|
|
202
217
|
}
|
|
203
218
|
return undefined;
|
|
204
219
|
}
|
|
205
|
-
return
|
|
220
|
+
return value;
|
|
206
221
|
};
|
|
207
222
|
}
|
|
208
223
|
|
|
@@ -275,14 +290,7 @@ export function apply(ctx: Context, config: LemonadeRawConfig): void {
|
|
|
275
290
|
// Lemonade-specific API proxy: browser client half calls these routes
|
|
276
291
|
// same-origin; the keys are resolved host-side and never reach the browser.
|
|
277
292
|
// Per-endpoint key selection (regular vs admin) lives in server-api.ts.
|
|
278
|
-
const resolveKey =
|
|
279
|
-
let value: string | undefined;
|
|
280
|
-
const credentials = ctx.get('credentials');
|
|
281
|
-
if (credentials !== undefined) value = (await credentials.resolve(ref))?.value;
|
|
282
|
-
if (value === undefined) value = launchEnvironmentOf(ctx).get(ref)?.value;
|
|
283
|
-
if (value === undefined || value.length === 0) return undefined;
|
|
284
|
-
return assertUsableApiKey(value, 'llm-lemonade', String(ref));
|
|
285
|
-
};
|
|
293
|
+
const resolveKey = (ref: CredentialRef): Promise<string | undefined> => resolveCredential(ctx, ref);
|
|
286
294
|
const apiCfg = {
|
|
287
295
|
baseURL: () => options().baseURL,
|
|
288
296
|
requireAuth: () => options().requireAuth,
|