@pellux/goodvibes-sdk 0.21.3 → 0.21.4

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.
@@ -14,6 +14,7 @@
14
14
  import type { ProviderRegistry } from '../../providers/registry.js';
15
15
  import type { ConfigManager } from '../../config/manager.js';
16
16
  import type { RuntimeEventBus } from '../../runtime/events/index.js';
17
+ import type { SecretsManager } from '../../config/secrets.js';
17
18
  export interface ProviderModelRef {
18
19
  readonly registryKey: string;
19
20
  readonly provider: string;
@@ -52,6 +53,7 @@ export interface ProviderRouteContext {
52
53
  readonly configManager: ConfigManager;
53
54
  readonly runtimeBus: RuntimeEventBus;
54
55
  readonly parseJsonBody: (req: Request) => Promise<Record<string, unknown> | Response>;
56
+ readonly secretsManager?: Pick<SecretsManager, 'get'> | null;
55
57
  }
56
58
  export declare function dispatchProviderRoutes(req: Request, context: ProviderRouteContext): Promise<Response | null>;
57
59
  //# sourceMappingURL=provider-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-routes.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/daemon/http/provider-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAyDrE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC;AAED,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAMD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;CACvF;AAyED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAiB1B"}
1
+ {"version":3,"file":"provider-routes.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/daemon/http/provider-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAyD9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC;AAED,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAMD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACtF,QAAQ,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;CAC9D;AAwFD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAiB1B"}
@@ -60,7 +60,27 @@ function getProviderLabel(providerId) {
60
60
  // ---------------------------------------------------------------------------
61
61
  // Helpers
62
62
  // ---------------------------------------------------------------------------
63
- function getConfiguredVia(providerId, envVars, providerRegistry) {
63
+ /**
64
+ * Pre-resolve all non-env secret keys stored in SecretsManager in one async
65
+ * batch. The resulting set is passed into the synchronous getConfiguredVia so
66
+ * that the secrets tier check remains pure/non-async.
67
+ */
68
+ async function resolveSecretKeys(secretsManager) {
69
+ if (!secretsManager)
70
+ return new Set();
71
+ // Enumerate all env var names that any known provider might use
72
+ const allEnvVarNames = Object.values(BUILTIN_PROVIDER_ENV_KEYS).flat();
73
+ const results = await Promise.all(allEnvVarNames.map(async (v) => {
74
+ if (typeof process.env[v] === 'string' && process.env[v].length > 0) {
75
+ // Already in env; skip the secrets lookup to avoid redundant I/O
76
+ return null;
77
+ }
78
+ const val = await secretsManager.get(v);
79
+ return val !== null ? v : null;
80
+ }));
81
+ return new Set(results.filter((v) => v !== null));
82
+ }
83
+ function getConfiguredVia(providerId, envVars, providerRegistry, secretKeys) {
64
84
  // Tier 1: env var present
65
85
  const hasEnvKey = envVars.some((v) => {
66
86
  const val = process.env[v];
@@ -68,17 +88,20 @@ function getConfiguredVia(providerId, envVars, providerRegistry) {
68
88
  });
69
89
  if (hasEnvKey)
70
90
  return 'env';
71
- // Tier 2: detect anonymous providers (no env vars required by design)
91
+ // Tier 2: SecretsManager has a stored value for any of the provider's env var names
92
+ if (secretKeys && envVars.some((v) => secretKeys.has(v)))
93
+ return 'secrets';
94
+ // Tier 3: detect anonymous providers (no env vars required by design)
72
95
  const catalogDef = BUILTIN_COMPAT_PROVIDERS.find((d) => d.id === providerId);
73
96
  if (catalogDef?.allowAnonymous && catalogDef?.anonymousConfigured)
74
97
  return 'anonymous';
75
- // Tier 3: present in configuredProviderIds but not env — subscription-backed
98
+ // Tier 4: present in configuredProviderIds but not env — subscription-backed
76
99
  const configuredIds = providerRegistry.getConfiguredProviderIds();
77
100
  if (configuredIds.includes(providerId))
78
101
  return 'subscription';
79
102
  return undefined;
80
103
  }
81
- function buildCurrentModelResponse(providerRegistry) {
104
+ function buildCurrentModelResponse(providerRegistry, secretKeys) {
82
105
  let model = null;
83
106
  let configured = false;
84
107
  let configuredVia;
@@ -88,27 +111,10 @@ function buildCurrentModelResponse(providerRegistry) {
88
111
  model = { registryKey, provider: current.provider, id: current.id };
89
112
  // Determine configured status for the current model's provider
90
113
  const envVars = (BUILTIN_PROVIDER_ENV_KEYS[current.provider] ?? []);
91
- const hasEnvKey = envVars.some((v) => {
92
- const val = process.env[v];
93
- return typeof val === 'string' && val.length > 0;
94
- });
95
- if (hasEnvKey) {
114
+ const via = getConfiguredVia(current.provider, envVars, providerRegistry, secretKeys);
115
+ if (via !== undefined) {
96
116
  configured = true;
97
- configuredVia = 'env';
98
- }
99
- else {
100
- const catalogDef = BUILTIN_COMPAT_PROVIDERS.find((d) => d.id === current.provider);
101
- if (catalogDef?.allowAnonymous && catalogDef?.anonymousConfigured) {
102
- configured = true;
103
- configuredVia = 'anonymous';
104
- }
105
- else {
106
- const configuredIds = providerRegistry.getConfiguredProviderIds();
107
- if (configuredIds.includes(current.provider)) {
108
- configured = true;
109
- configuredVia = 'subscription';
110
- }
111
- }
117
+ configuredVia = via;
112
118
  }
113
119
  }
114
120
  catch {
@@ -137,7 +143,9 @@ export async function dispatchProviderRoutes(req, context) {
137
143
  // GET /api/providers
138
144
  // ---------------------------------------------------------------------------
139
145
  async function handleListProviders(context) {
140
- const { providerRegistry } = context;
146
+ const { providerRegistry, secretsManager } = context;
147
+ // Pre-resolve which secret keys are stored (one async batch, then sync logic below)
148
+ const secretKeys = await resolveSecretKeys(secretsManager);
141
149
  const allModels = providerRegistry.listModels();
142
150
  const configuredIds = new Set(providerRegistry.getConfiguredProviderIds());
143
151
  // Group models by provider
@@ -157,10 +165,9 @@ async function handleListProviders(context) {
157
165
  const providers = [];
158
166
  for (const [providerId, models] of byProvider) {
159
167
  const envVars = (BUILTIN_PROVIDER_ENV_KEYS[providerId] ?? []);
160
- const configured = configuredIds.has(providerId);
161
- const configuredVia = configured
162
- ? getConfiguredVia(providerId, envVars, providerRegistry)
163
- : undefined;
168
+ const via = getConfiguredVia(providerId, envVars, providerRegistry, secretKeys);
169
+ const configured = via !== undefined;
170
+ const configuredVia = configured ? via : undefined;
164
171
  const label = getProviderLabel(providerId);
165
172
  providers.push({ id: providerId, label, configured, configuredVia, envVars, models });
166
173
  }
@@ -170,7 +177,7 @@ async function handleListProviders(context) {
170
177
  return a.configured ? -1 : 1;
171
178
  return a.id.localeCompare(b.id);
172
179
  });
173
- const currentModel = buildCurrentModelResponse(providerRegistry).model;
180
+ const currentModel = buildCurrentModelResponse(providerRegistry, secretKeys).model;
174
181
  const body = { providers, currentModel };
175
182
  return Response.json(body);
176
183
  }
@@ -178,7 +185,8 @@ async function handleListProviders(context) {
178
185
  // GET /api/providers/current
179
186
  // ---------------------------------------------------------------------------
180
187
  async function handleGetCurrentModel(context) {
181
- return Response.json(buildCurrentModelResponse(context.providerRegistry));
188
+ const secretKeys = await resolveSecretKeys(context.secretsManager);
189
+ return Response.json(buildCurrentModelResponse(context.providerRegistry, secretKeys));
182
190
  }
183
191
  // ---------------------------------------------------------------------------
184
192
  // PATCH /api/providers/current
@@ -231,5 +239,6 @@ async function handlePatchCurrentModel(req, context) {
231
239
  }
232
240
  // setCurrentModel emits MODEL_CHANGED synchronously on the same runtimeBus —
233
241
  // no second emission needed here.
234
- return Response.json({ ...buildCurrentModelResponse(providerRegistry), persisted });
242
+ const secretKeys = await resolveSecretKeys(context.secretsManager);
243
+ return Response.json({ ...buildCurrentModelResponse(providerRegistry, secretKeys), persisted });
235
244
  }
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- let version = '0.21.3';
3
+ let version = '0.21.4';
4
4
  try {
5
5
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', '..', 'package.json'), 'utf-8'));
6
6
  version = pkg.version ?? version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-sdk",
3
- "version": "0.21.3",
3
+ "version": "0.21.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/mgd34msu/goodvibes-sdk.git"