langflower 0.0.7 → 0.0.8

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.
@@ -8,6 +8,30 @@ import { applyDraftPatch, buildDraftSnapshot, providerIndexesWithBaseUrl, seedSc
8
8
  import { bridgeEmit, clientEmit } from './bridge-outbound.js';
9
9
  import { buildLangflowerConfigSnapshot } from './build-langflower-config-snapshot.js';
10
10
  const isScope = (value) => value === 'project' || value === 'global';
11
+ /** Fill missing/empty Save keys from the session draft (write-only apiKey). */
12
+ const mergeProviderApiKeysFromSession = (payload, sessionDraft) => {
13
+ if (payload.provider === undefined || sessionDraft === undefined) {
14
+ return payload.providerApiKeys;
15
+ }
16
+ const merged = {
17
+ ...(payload.providerApiKeys ?? {}),
18
+ };
19
+ for (const row of sessionDraft.providers) {
20
+ const id = row.id.trim();
21
+ if (id.length === 0) {
22
+ continue;
23
+ }
24
+ const fromPayload = merged[id]?.trim() ?? '';
25
+ if (fromPayload.length > 0) {
26
+ continue;
27
+ }
28
+ const pending = row.apiKey.trim();
29
+ if (pending.length > 0) {
30
+ merged[id] = pending;
31
+ }
32
+ }
33
+ return Object.keys(merged).length > 0 ? merged : payload.providerApiKeys;
34
+ };
11
35
  const layerForScope = (layers, scope) => (scope === 'project' ? layers.project : layers.global);
12
36
  export const createSettingsDraftController = (bridge, context, session) => {
13
37
  const probeGeneration = new Map();
@@ -144,15 +168,14 @@ export const createSettingsDraftController = (bridge, context, session) => {
144
168
  if (payload === undefined || !isScope(payload.scope)) {
145
169
  return null;
146
170
  }
171
+ const providerApiKeys = mergeProviderApiKeysFromSession(payload, state?.draft);
147
172
  const layers = await context.langflowerConfigService.writeSettings({
148
173
  scope: payload.scope,
149
174
  ...(payload.model !== undefined ? { model: payload.model } : {}),
150
175
  ...(payload.provider !== undefined
151
176
  ? { provider: payload.provider }
152
177
  : {}),
153
- ...(payload.providerApiKeys !== undefined
154
- ? { providerApiKeys: payload.providerApiKeys }
155
- : {}),
178
+ ...(providerApiKeys !== undefined ? { providerApiKeys } : {}),
156
179
  ...('serverLogs' in payload
157
180
  ? { serverLogs: payload.serverLogs }
158
181
  : {}),
@@ -55,7 +55,17 @@
55
55
  },
56
56
  "options": {
57
57
  "type": "object",
58
- "additionalProperties": true
58
+ "additionalProperties": true,
59
+ "properties": {
60
+ "baseURL": {
61
+ "type": "string",
62
+ "description": "OpenAI-compatible API base URL (e.g. https://api.openai.com/v1 or http://127.0.0.1:1234/v1)."
63
+ },
64
+ "apiKey": {
65
+ "type": "string",
66
+ "description": "API key or `{env:VAR_NAME}` placeholder. Resolved on the server only; omitted from WebSocket snapshots. Prefer `{env:…}` over literals on disk."
67
+ }
68
+ }
59
69
  }
60
70
  }
61
71
  }