@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;
|
|
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
|
-
|
|
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:
|
|
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
|
|
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
|
|
92
|
-
|
|
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 =
|
|
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
|
|
161
|
-
const
|
|
162
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
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;
|