@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 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
- /** Resolve the optional bearer token, enforcing `requireAuth` when configured. */
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
- let value;
134
- const credentials = ctx.get('credentials');
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 assertUsableApiKey(value, 'llm-lemonade', String(ref));
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 = async (ref) => {
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.1",
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
- /** Resolve the optional bearer token, enforcing `requireAuth` when configured. */
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
- let value: string | undefined;
193
- const credentials = ctx.get('credentials');
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 assertUsableApiKey(value, 'llm-lemonade', String(ref));
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 = async (ref: CredentialRef): Promise<string | undefined> => {
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,