@oscharko-dev/keiko-server 0.2.0 → 0.2.2

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/dist/deps.d.ts CHANGED
@@ -22,6 +22,13 @@ export interface RuntimeGatewayConfig {
22
22
  present(): boolean;
23
23
  set(config: GatewayConfig | undefined, present: boolean): void;
24
24
  }
25
+ export interface GatewayDiscoveredModels {
26
+ readonly modelIds: readonly string[];
27
+ readonly chatModelIds: readonly string[];
28
+ readonly embeddingModelIds: readonly string[];
29
+ readonly imageInputModelIds?: readonly string[];
30
+ }
31
+ export type GatewayModelDiscoveryOutput = readonly string[] | GatewayDiscoveredModels;
25
32
  export interface UiHandlerDeps {
26
33
  readonly config: GatewayConfig | undefined;
27
34
  readonly configPresent: boolean;
@@ -41,7 +48,7 @@ export interface UiHandlerDeps {
41
48
  readonly consolidationJobs?: ConsolidationJobRegistry | undefined;
42
49
  readonly gatewayConfig?: RuntimeGatewayConfig | undefined;
43
50
  readonly gatewaySetupTester?: ((config: GatewayConfig, candidateModelIds: readonly string[]) => Promise<readonly string[]>) | undefined;
44
- readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<readonly string[]>) | undefined;
51
+ readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<GatewayModelDiscoveryOutput>) | undefined;
45
52
  readonly figmaCredentialTester?: ((accessToken: string, egress?: GatewayEgressConfig) => Promise<void>) | undefined;
46
53
  readonly editorLanguageRouteOptions?: EditorLanguageRouteOptions | undefined;
47
54
  readonly localKnowledgeEmbeddingRequest?: ((request: OpenAIEmbeddingRequest) => Promise<OpenAIEmbeddingOutcome>) | undefined;
@@ -60,7 +67,7 @@ export interface BuildHandlerDepsOptions {
60
67
  readonly store?: UiStore | undefined;
61
68
  readonly initialProjectPath?: string | undefined;
62
69
  readonly gatewaySetupTester?: ((config: GatewayConfig, candidateModelIds: readonly string[]) => Promise<readonly string[]>) | undefined;
63
- readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<readonly string[]>) | undefined;
70
+ readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<GatewayModelDiscoveryOutput>) | undefined;
64
71
  readonly figmaCredentialTester?: ((accessToken: string, egress?: GatewayEgressConfig) => Promise<void>) | undefined;
65
72
  readonly qiRetentionAuditSink?: QiRetentionAuditSink | undefined;
66
73
  readonly qiRetentionNow?: (() => number) | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../src/deps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../src/deps.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  import type { RouteContext, RouteResult } from "./routes.js";
2
- import type { UiHandlerDeps } from "./deps.js";
2
+ import type { GatewayDiscoveredModels, UiHandlerDeps } from "./deps.js";
3
3
  export declare const MAX_DISCOVERED_MODELS = 100;
4
4
  export declare function isExplicitlyNonChatModel(item: Record<string, unknown>): boolean;
5
5
  export declare function modelIdFromDiscoveryItem(item: unknown): string | undefined;
6
+ export declare function parseModelDiscovery(payload: unknown): GatewayDiscoveredModels;
6
7
  export declare function parseModelList(payload: unknown): readonly string[];
7
8
  export declare function normalizeDiscoveryPayload(payload: unknown): readonly string[];
9
+ export declare function normalizeDiscoveryPayloadForSetup(payload: unknown): GatewayDiscoveredModels;
8
10
  export declare function smokeTestCandidates(candidates: readonly string[], probe: (modelId: string) => Promise<void>, concurrency: number): Promise<readonly string[]>;
9
11
  export declare function handleGatewaySetup(ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
10
12
  //# sourceMappingURL=gateway-setup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-setup.d.ts","sourceRoot":"","sources":["../src/gateway-setup.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,WAAW,CAAC;AAcrE,eAAO,MAAM,qBAAqB,MAAM,CAAC;AA2SzC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO/E;AAKD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK1E;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAgBlE;AAOD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAE7E;AAyJD,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CA2B5B;AA4nBD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkBtB"}
1
+ {"version":3,"file":"gateway-setup.d.ts","sourceRoot":"","sources":["../src/gateway-setup.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EACV,uBAAuB,EAGvB,aAAa,EACd,MAAM,WAAW,CAAC;AAcnB,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAoXzC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO/E;AAoCD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE1E;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,CA2B7E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAElE;AAOD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAE7E;AAED,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,CAE3F;AA2JD,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CA2B5B;AA+vBD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkBtB"}
@@ -25,6 +25,7 @@ const FIGMA_CREDENTIAL_SMOKE_RESPONSE_BYTES = 64_000;
25
25
  const SETUP_SMOKE_CONCURRENCY = 4;
26
26
  const CHAT_COMPATIBLE_MODES = new Set(["chat", "completion", "responses"]);
27
27
  const EMBEDDING_ID_PATTERN = /(?:^|[-_/. ])(?:text-)?embed(?:ding)?s?(?:[-_/. ]|$)|ada-002(?:$|[-_/. ])/i;
28
+ const IMAGE_INPUT_ID_PATTERN = /(?:^|[-_/. ])(?:vision|multimodal|multi-modal|llava|pixtral|omni|gpt-4o)(?:$|[-_/. ])|(?:^|[-_/. ])vl(?:$|[-_/. ])|qwen(?:2(?:\.5)?|3)?[-_/. ]?vl(?:$|[-_/. ])/i;
28
29
  class BodyTooLargeError extends Error {
29
30
  constructor() {
30
31
  super("request body too large");
@@ -127,6 +128,54 @@ function providerRaw(modelId, baseUrl, apiKey, options = {}) {
127
128
  function isLikelyEmbeddingModelId(modelId) {
128
129
  return EMBEDDING_ID_PATTERN.test(modelId);
129
130
  }
131
+ function isLikelyImageInputModelId(modelId) {
132
+ return IMAGE_INPUT_ID_PATTERN.test(modelId);
133
+ }
134
+ function discoveryRecords(item) {
135
+ return [
136
+ item,
137
+ nestedRecord(item, "model_info"),
138
+ nestedRecord(item, "litellm_params"),
139
+ nestedRecord(item, "capabilities"),
140
+ ].filter((record) => record !== undefined);
141
+ }
142
+ function booleanFieldFromRecords(records, fields) {
143
+ return records.some((record) => fields.some((field) => record[field] === true));
144
+ }
145
+ function stringsFromValue(value) {
146
+ if (typeof value === "string")
147
+ return [value];
148
+ if (Array.isArray(value)) {
149
+ return value.filter((entry) => typeof entry === "string");
150
+ }
151
+ return [];
152
+ }
153
+ function stringListFieldFromRecords(records, fields) {
154
+ return records.flatMap((record) => fields.flatMap((field) => stringsFromValue(record[field]).map((value) => value.toLowerCase())));
155
+ }
156
+ function supportsImageInputFromDiscoveryItem(item, modelId) {
157
+ const records = discoveryRecords(item);
158
+ if (booleanFieldFromRecords(records, [
159
+ "supports_vision",
160
+ "supportsVision",
161
+ "vision",
162
+ "image_input",
163
+ "imageInput",
164
+ "supports_image_input",
165
+ "supportsImageInput",
166
+ ])) {
167
+ return true;
168
+ }
169
+ const modalities = stringListFieldFromRecords(records, [
170
+ "input_modalities",
171
+ "inputModalities",
172
+ "modalities",
173
+ ]);
174
+ if (modalities.some((entry) => entry === "image" || entry === "vision")) {
175
+ return true;
176
+ }
177
+ return isLikelyImageInputModelId(modelId);
178
+ }
130
179
  function createDefaultEmbeddingCapabilityForSetup(modelId) {
131
180
  return {
132
181
  id: modelId,
@@ -148,11 +197,11 @@ function createDefaultEmbeddingCapabilityForSetup(modelId) {
148
197
  ],
149
198
  };
150
199
  }
151
- function mergeChatAndEmbeddingModelIds(chatModelIds, deploymentNames) {
200
+ function mergeChatAndEmbeddingModelIds(chatModelIds, embeddingModelIds) {
152
201
  const merged = [...chatModelIds];
153
202
  const seen = new Set(merged);
154
- for (const modelId of deploymentNames) {
155
- if (!isLikelyEmbeddingModelId(modelId) || seen.has(modelId)) {
203
+ for (const modelId of embeddingModelIds) {
204
+ if (seen.has(modelId)) {
156
205
  continue;
157
206
  }
158
207
  seen.add(modelId);
@@ -174,7 +223,7 @@ function currentImageInputModelIds(config) {
174
223
  ?.filter((capability) => capability.kind === "chat" && capability.supportsImageInput)
175
224
  .map((capability) => capability.id) ?? []);
176
225
  }
177
- function rawConfigFromCurrent(config, figmaAccessToken) {
226
+ function rawConfigFromCurrent(config, figmaAccessToken, timeoutMs) {
178
227
  return {
179
228
  providers: config.providers.map((provider) => {
180
229
  const capability = config.capabilities?.find((item) => item.id === provider.modelId);
@@ -183,7 +232,7 @@ function rawConfigFromCurrent(config, figmaAccessToken) {
183
232
  baseUrl: provider.baseUrl,
184
233
  apiKey: provider.apiKey,
185
234
  apiKeyHeaderName: provider.apiKeyHeaderName ?? DEFAULT_API_KEY_HEADER_NAME,
186
- timeoutMs: provider.timeoutMs,
235
+ timeoutMs: timeoutMs ?? provider.timeoutMs,
187
236
  maxRetries: provider.maxRetries,
188
237
  retryBaseDelayMs: provider.retryBaseDelayMs,
189
238
  ...(capability === undefined ? {} : { capability }),
@@ -250,6 +299,9 @@ function modelModeFromDiscoveryItem(item) {
250
299
  }
251
300
  return undefined;
252
301
  }
302
+ function isExplicitlyEmbeddingModel(item) {
303
+ return modelModeFromDiscoveryItem(item) === "embedding";
304
+ }
253
305
  // Issue #144: exported as part of the discovery-normalization seam so a
254
306
  // sibling test file can drive it with synthetic payloads. Behaviour unchanged
255
307
  // — only the visibility is widened.
@@ -261,35 +313,67 @@ export function isExplicitlyNonChatModel(item) {
261
313
  const mode = modelModeFromDiscoveryItem(item);
262
314
  return mode !== undefined && !CHAT_COMPATIBLE_MODES.has(mode);
263
315
  }
264
- // Issue #144: exported as part of the discovery-normalization seam. Behaviour
265
- // unchanged. Returns undefined for unknown/non-record/non-chat/malformed input
266
- // so callers can drop the entry silently and keep healthy peers.
267
- export function modelIdFromDiscoveryItem(item) {
268
- if (!isRecord(item) || isExplicitlyNonChatModel(item)) {
316
+ function classifyDiscoveryItem(item) {
317
+ if (!isRecord(item)) {
318
+ return undefined;
319
+ }
320
+ const id = modelIdFromKnownFields(item);
321
+ if (id === undefined) {
269
322
  return undefined;
270
323
  }
271
- return modelIdFromKnownFields(item);
324
+ if (isExplicitlyEmbeddingModel(item)) {
325
+ return { id, kind: "embedding", supportsImageInput: false };
326
+ }
327
+ if (isExplicitlyNonChatModel(item)) {
328
+ return isLikelyEmbeddingModelId(id)
329
+ ? { id, kind: "embedding", supportsImageInput: false }
330
+ : undefined;
331
+ }
332
+ return isLikelyEmbeddingModelId(id)
333
+ ? { id, kind: "embedding", supportsImageInput: false }
334
+ : { id, kind: "chat", supportsImageInput: supportsImageInputFromDiscoveryItem(item, id) };
272
335
  }
273
- // Issue #144: exported as part of the discovery-normalization seam. Behaviour
274
- // unchanged. Throws on schema-level malformation (no data array) and on the
275
- // "every entry filtered" terminal case so the caller (production path) returns
276
- // an honest error rather than a silently-empty model list.
277
- export function parseModelList(payload) {
336
+ // Issue #144: exported as part of the discovery-normalization seam. Gateway setup now returns
337
+ // embedding-capable records so setup can persist them for Local Knowledge while keeping them out of
338
+ // chat.
339
+ // Returns undefined for unknown/non-record/unsupported/malformed input so
340
+ // callers can drop the entry silently and keep healthy peers.
341
+ export function modelIdFromDiscoveryItem(item) {
342
+ return classifyDiscoveryItem(item)?.id;
343
+ }
344
+ // Issue #144: exported as part of the discovery-normalization seam. Throws on schema-level
345
+ // malformation (no data array) and on the "every entry filtered" terminal case so the caller
346
+ // (production path) returns an honest error rather than a silently-empty model list.
347
+ export function parseModelDiscovery(payload) {
278
348
  if (!isRecord(payload) || !Array.isArray(payload.data)) {
279
349
  throw new Error("model discovery response must contain a data array");
280
350
  }
281
- const ids = [];
351
+ const entries = [];
352
+ const seen = new Set();
282
353
  for (const item of payload.data) {
283
- const id = modelIdFromDiscoveryItem(item);
284
- if (id !== undefined) {
285
- ids.push(id);
354
+ const classified = classifyDiscoveryItem(item);
355
+ if (classified !== undefined && !seen.has(classified.id)) {
356
+ seen.add(classified.id);
357
+ entries.push(classified);
286
358
  }
287
359
  }
288
- const unique = Array.from(new Set(ids));
289
- if (unique.length === 0) {
360
+ const limited = entries.slice(0, MAX_DISCOVERED_MODELS);
361
+ if (limited.length === 0) {
290
362
  throw new Error("model discovery returned no model ids");
291
363
  }
292
- return unique.slice(0, MAX_DISCOVERED_MODELS);
364
+ return {
365
+ modelIds: limited.map((entry) => entry.id),
366
+ chatModelIds: limited.filter((entry) => entry.kind === "chat").map((entry) => entry.id),
367
+ embeddingModelIds: limited
368
+ .filter((entry) => entry.kind === "embedding")
369
+ .map((entry) => entry.id),
370
+ imageInputModelIds: limited
371
+ .filter((entry) => entry.kind === "chat" && entry.supportsImageInput)
372
+ .map((entry) => entry.id),
373
+ };
374
+ }
375
+ export function parseModelList(payload) {
376
+ return parseModelDiscovery(payload).modelIds;
293
377
  }
294
378
  // Issue #144 AC #4: the public discovery-normalization seam. Test target. Pure
295
379
  // wrapper around `parseModelList` so the AC ("Discovery handles additional
@@ -299,6 +383,9 @@ export function parseModelList(payload) {
299
383
  export function normalizeDiscoveryPayload(payload) {
300
384
  return parseModelList(payload);
301
385
  }
386
+ export function normalizeDiscoveryPayloadForSetup(payload) {
387
+ return parseModelDiscovery(payload);
388
+ }
302
389
  async function fetchDiscoveryJson(url, apiKey, apiKeyHeaderName, egress) {
303
390
  const response = await gatewayFetch(url, {
304
391
  method: "GET",
@@ -319,7 +406,7 @@ async function fetchDiscoveryJson(url, apiKey, apiKeyHeaderName, egress) {
319
406
  async function discoverLiteLlmModelInfo(baseUrl, apiKey, apiKeyHeaderName, egress) {
320
407
  for (const endpoint of modelInfoEndpointCandidates(baseUrl)) {
321
408
  try {
322
- return parseModelList(await fetchDiscoveryJson(endpoint, apiKey, apiKeyHeaderName, egress));
409
+ return parseModelDiscovery(await fetchDiscoveryJson(endpoint, apiKey, apiKeyHeaderName, egress));
323
410
  }
324
411
  catch {
325
412
  // /model/info is a LiteLLM-specific enrichment endpoint. If it is absent or blocked,
@@ -333,7 +420,7 @@ async function defaultGatewayModelDiscovery(baseUrl, apiKey, apiKeyHeaderName =
333
420
  if (litellmModels !== undefined) {
334
421
  return litellmModels;
335
422
  }
336
- return parseModelList(await fetchDiscoveryJson(modelsEndpoint(baseUrl), apiKey, apiKeyHeaderName, egress));
423
+ return parseModelDiscovery(await fetchDiscoveryJson(modelsEndpoint(baseUrl), apiKey, apiKeyHeaderName, egress));
337
424
  }
338
425
  function deploymentNameValues(value) {
339
426
  if (typeof value === "string") {
@@ -544,6 +631,15 @@ function optionalSetupSecret(value, path) {
544
631
  const trimmed = value.trim();
545
632
  return trimmed.length === 0 ? undefined : trimmed;
546
633
  }
634
+ function optionalSetupPositiveInt(value, path) {
635
+ if (value === undefined) {
636
+ return undefined;
637
+ }
638
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
639
+ return { status: 400, body: errorBody("BAD_REQUEST", `${path} must be a positive integer.`) };
640
+ }
641
+ return value;
642
+ }
547
643
  function hasNonBlankStringField(raw, key) {
548
644
  const value = raw[key];
549
645
  return typeof value === "string" && value.trim().length > 0;
@@ -623,6 +719,10 @@ function readSetupRequest(raw, env, current) {
623
719
  if (isRouteResult(credentials)) {
624
720
  return credentials;
625
721
  }
722
+ const timeoutMs = optionalSetupPositiveInt(raw.timeoutMs, "timeoutMs");
723
+ if (isRouteResult(timeoutMs)) {
724
+ return timeoutMs;
725
+ }
626
726
  const modelLists = readSetupModelLists(raw);
627
727
  if (isRouteResult(modelLists)) {
628
728
  return modelLists;
@@ -634,6 +734,7 @@ function readSetupRequest(raw, env, current) {
634
734
  const resolvedModelLists = resolveSetupModelLists(modelLists, current, preserveExisting);
635
735
  return {
636
736
  ...credentials,
737
+ timeoutMs,
637
738
  deploymentNames: resolvedModelLists.deploymentNames,
638
739
  imageInputModelIds: resolvedModelLists.imageInputModelIds,
639
740
  figmaAccessToken: figmaAccessToken ?? current?.figma?.accessToken,
@@ -656,25 +757,80 @@ function assertImageInputModelsWereTested(imageInputModelIds, testedModelIds) {
656
757
  throw new Error("imageInputModelIds must match tested chat-callable model ids.");
657
758
  }
658
759
  }
760
+ function testedImageInputModelIds(manualModelIds, discoveredModelIds, testedModelIds) {
761
+ const tested = new Set(testedModelIds);
762
+ const merged = [];
763
+ const seen = new Set();
764
+ for (const modelId of [...manualModelIds, ...discoveredModelIds]) {
765
+ if (!tested.has(modelId) || seen.has(modelId)) {
766
+ continue;
767
+ }
768
+ seen.add(modelId);
769
+ merged.push(modelId);
770
+ }
771
+ return merged;
772
+ }
659
773
  function validationConfigForSetup(input) {
660
774
  const validationRawConfig = buildRawConfig(input.baseUrl, input.apiKey, ["setup-validation"], {
661
775
  apiKeyHeaderName: input.apiKeyHeaderName,
662
776
  imageInputModelIds: input.imageInputModelIds,
777
+ timeoutMs: input.timeoutMs,
663
778
  });
664
779
  return parseGatewayConfig(withInheritedEgress(validationRawConfig, input.egress), input.env);
665
780
  }
781
+ function normalizeLegacyDiscoveryResult(modelIds) {
782
+ const embeddingModelIds = embeddingModelIdsFromDeployments(modelIds);
783
+ const embeddingSet = new Set(embeddingModelIds);
784
+ return {
785
+ modelIds,
786
+ chatModelIds: modelIds.filter((modelId) => !embeddingSet.has(modelId)),
787
+ embeddingModelIds,
788
+ imageInputModelIds: [],
789
+ };
790
+ }
791
+ function isStructuredDiscoveryResult(result) {
792
+ if (Array.isArray(result)) {
793
+ return false;
794
+ }
795
+ const candidate = result;
796
+ return (Array.isArray(candidate.modelIds) &&
797
+ Array.isArray(candidate.chatModelIds) &&
798
+ Array.isArray(candidate.embeddingModelIds));
799
+ }
800
+ function normalizeDiscoveryResult(result) {
801
+ if (isStructuredDiscoveryResult(result)) {
802
+ return {
803
+ modelIds: result.modelIds,
804
+ chatModelIds: result.chatModelIds,
805
+ embeddingModelIds: result.embeddingModelIds,
806
+ imageInputModelIds: result.imageInputModelIds ?? [],
807
+ };
808
+ }
809
+ return normalizeLegacyDiscoveryResult(result);
810
+ }
811
+ function candidateModelsFromDeploymentNames(deploymentNames) {
812
+ const embeddingModelIds = embeddingModelIdsFromDeployments(deploymentNames);
813
+ const embeddingSet = new Set(embeddingModelIds);
814
+ return {
815
+ modelIds: deploymentNames,
816
+ chatModelIds: deploymentNames.filter((modelId) => !embeddingSet.has(modelId)),
817
+ embeddingModelIds,
818
+ imageInputModelIds: [],
819
+ };
820
+ }
666
821
  async function candidateModelIdsForSetup(input, validationConfig) {
667
- return input.deploymentNames.length > 0
668
- ? input.deploymentNames
669
- : input.discovery(input.baseUrl, input.apiKey, input.apiKeyHeaderName, validationConfig.egress);
822
+ if (input.deploymentNames.length > 0) {
823
+ return candidateModelsFromDeploymentNames(input.deploymentNames);
824
+ }
825
+ return normalizeDiscoveryResult(await input.discovery(input.baseUrl, input.apiKey, input.apiKeyHeaderName, validationConfig.egress));
670
826
  }
671
- function finalRawConfigForSetup(input, testedModelIds) {
672
- const embeddingModelIds = embeddingModelIdsFromDeployments(input.deploymentNames);
673
- const configuredModelIds = mergeChatAndEmbeddingModelIds(testedModelIds, input.deploymentNames);
827
+ function finalRawConfigForSetup(input, testedModelIds, embeddingModelIds, imageInputModelIds) {
828
+ const configuredModelIds = mergeChatAndEmbeddingModelIds(testedModelIds, embeddingModelIds);
674
829
  const rawConfig = buildRawConfig(input.baseUrl, input.apiKey, configuredModelIds, {
675
830
  apiKeyHeaderName: input.apiKeyHeaderName,
676
- imageInputModelIds: input.imageInputModelIds,
831
+ imageInputModelIds,
677
832
  embeddingModelIds,
833
+ timeoutMs: input.timeoutMs,
678
834
  });
679
835
  return {
680
836
  ...rawConfig,
@@ -684,23 +840,24 @@ function finalRawConfigForSetup(input, testedModelIds) {
684
840
  : { figma: { accessToken: input.figmaAccessToken } }),
685
841
  };
686
842
  }
687
- function skippedModelIdsForSetup(candidateModelIds, testedModelIds, deploymentNames) {
688
- const acceptedModelIds = new Set([
689
- ...testedModelIds,
690
- ...embeddingModelIdsFromDeployments(deploymentNames),
691
- ]);
843
+ function skippedModelIdsForSetup(candidateModelIds, testedModelIds, embeddingModelIds) {
844
+ const acceptedModelIds = new Set([...testedModelIds, ...embeddingModelIds]);
692
845
  return candidateModelIds.filter((modelId) => !acceptedModelIds.has(modelId));
693
846
  }
847
+ function finalRawConfigForTestedSetup(input, testedModelIds, candidateModels) {
848
+ const imageInputModelIds = testedImageInputModelIds(input.imageInputModelIds, candidateModels.imageInputModelIds, testedModelIds);
849
+ return finalRawConfigForSetup(input, testedModelIds, candidateModels.embeddingModelIds, imageInputModelIds);
850
+ }
694
851
  async function verifySetupCandidate(input) {
695
852
  // Defence-in-depth: never send the credential to a candidate URL that has not passed the same
696
853
  // scheme/credential/loopback validation as the originally submitted base URL.
697
854
  validateBaseUrl(input.baseUrl, "candidate");
698
855
  const validationConfig = validationConfigForSetup(input);
699
- const candidateModelIds = await candidateModelIdsForSetup(input, validationConfig);
856
+ const candidateModels = await candidateModelIdsForSetup(input, validationConfig);
700
857
  const smokeTimeoutMs = input.deploymentNames.length > 0
701
858
  ? DEPLOYMENT_SMOKE_TIMEOUT_MS
702
859
  : DISCOVERED_MODEL_SMOKE_TIMEOUT_MS;
703
- const candidateRawConfig = buildRawConfig(input.baseUrl, input.apiKey, candidateModelIds, {
860
+ const candidateRawConfig = buildRawConfig(input.baseUrl, input.apiKey, candidateModels.chatModelIds, {
704
861
  apiKeyHeaderName: input.apiKeyHeaderName,
705
862
  timeoutMs: smokeTimeoutMs,
706
863
  // One retry (not zero) so a single transient blip — 429 rate-limit, brief timeout, momentary
@@ -710,15 +867,15 @@ async function verifySetupCandidate(input) {
710
867
  imageInputModelIds: input.imageInputModelIds,
711
868
  });
712
869
  const candidateConfig = parseGatewayConfig(withInheritedEgress(candidateRawConfig, input.egress), input.env);
713
- const testedModelIds = await input.tester(candidateConfig, candidateModelIds);
870
+ const testedModelIds = await input.tester(candidateConfig, candidateModels.chatModelIds);
714
871
  assertImageInputModelsWereTested(input.imageInputModelIds, testedModelIds);
715
- const rawConfigWithOptionalBlocks = finalRawConfigForSetup(input, testedModelIds);
872
+ const rawConfigWithOptionalBlocks = finalRawConfigForTestedSetup(input, testedModelIds, candidateModels);
716
873
  const config = parseGatewayConfig(withInheritedEgress(rawConfigWithOptionalBlocks, input.egress), input.env);
717
874
  return {
718
875
  rawConfig: rawConfigWithOptionalBlocks,
719
876
  config,
720
877
  testedModelIds,
721
- skippedModelIds: skippedModelIdsForSetup(candidateModelIds, testedModelIds, input.deploymentNames),
878
+ skippedModelIds: skippedModelIdsForSetup(candidateModels.modelIds, testedModelIds, candidateModels.embeddingModelIds),
722
879
  };
723
880
  }
724
881
  function setupSuccessResult(config, testedModelIds, skippedModelIds) {
@@ -819,6 +976,7 @@ async function trySetupCandidate(baseUrl, request, deps, gatewayConfig, tester,
819
976
  baseUrl,
820
977
  apiKey: request.apiKey,
821
978
  apiKeyHeaderName: request.apiKeyHeaderName,
979
+ timeoutMs: request.timeoutMs,
822
980
  deploymentNames: request.deploymentNames,
823
981
  imageInputModelIds: request.imageInputModelIds,
824
982
  tester,
@@ -836,7 +994,7 @@ function setupCandidateError(error, request, baseUrl) {
836
994
  return safeError(error, [request.apiKey, request.baseUrl, baseUrl, request.figmaAccessToken]);
837
995
  }
838
996
  function saveExistingConfigUpdate(request, current, deps, gatewayConfig) {
839
- const rawConfig = rawConfigFromCurrent(current, request.figmaAccessToken);
997
+ const rawConfig = rawConfigFromCurrent(current, request.figmaAccessToken, request.timeoutMs);
840
998
  const config = parseGatewayConfig(withInheritedEgress(rawConfig, currentGatewayEgressConfig(deps)), deps.env);
841
999
  persistGatewayConfig(rawConfig, gatewayConfig.storagePath, deps);
842
1000
  gatewayConfig.set(config, true);
@@ -1,6 +1,6 @@
1
1
  import { type UiHandlerDeps } from "./deps.js";
2
2
  import type { RouteContext, RouteResult } from "./routes.js";
3
- import { type GatewayConfig } from "@oscharko-dev/keiko-model-gateway";
3
+ import { type GatewayConfig, type ModelProviderConfig } from "@oscharko-dev/keiko-model-gateway";
4
4
  interface EmbeddingSelectionConfig {
5
5
  readonly providers: readonly {
6
6
  readonly modelId: string;
@@ -8,6 +8,8 @@ interface EmbeddingSelectionConfig {
8
8
  readonly capabilities?: GatewayConfig["capabilities"];
9
9
  }
10
10
  export declare function selectEmbeddingModelId(config: EmbeddingSelectionConfig | null | undefined): string | undefined;
11
+ export declare function configuredEmbeddingModelIds(config: EmbeddingSelectionConfig | null | undefined): readonly string[];
12
+ export declare function configuredEmbeddingProviders(config: GatewayConfig | undefined): readonly ModelProviderConfig[];
11
13
  export declare function handleListLocalKnowledgeCapsules(_ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
12
14
  export declare function handleListLocalKnowledgeCapsuleSets(_ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
13
15
  export declare function handleCreateLocalKnowledgeCapsuleSet(ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"local-knowledge-handlers.d.ts","sourceRoot":"","sources":["../src/local-knowledge-handlers.ts"],"names":[],"mappings":"AAqDA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAKL,KAAK,aAAa,EAOnB,MAAM,mCAAmC,CAAC;AAiO3C,UAAU,wBAAwB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CACvD;AAgqBD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,wBAAwB,GAAG,IAAI,GAAG,SAAS,GAClD,MAAM,GAAG,SAAS,CAIpB;AAiSD,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,wBAAsB,mCAAmC,CACvD,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAetB;AA4CD,wBAAsB,oCAAoC,CACxD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAmCD,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAetB;AAED,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkCtB;AAED,wBAAsB,8BAA8B,CAClD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAiBtB;AAED,wBAAsB,wCAAwC,CAC5D,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CA2CtB;AAED,wBAAsB,yCAAyC,CAC7D,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkBtB;AAqFD,wBAAsB,kCAAkC,CACtD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CA4CtB;AAED,wBAAsB,qCAAqC,CACzD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED,wBAAsB,kCAAkC,CACtD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CA+CtB"}
1
+ {"version":3,"file":"local-knowledge-handlers.d.ts","sourceRoot":"","sources":["../src/local-knowledge-handlers.ts"],"names":[],"mappings":"AAuDA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,mBAAmB,EAMzB,MAAM,mCAAmC,CAAC;AAiO3C,UAAU,wBAAwB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CACvD;AA0uBD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,wBAAwB,GAAG,IAAI,GAAG,SAAS,GAClD,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,wBAAwB,GAAG,IAAI,GAAG,SAAS,GAClD,SAAS,MAAM,EAAE,CAKnB;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,aAAa,GAAG,SAAS,GAChC,SAAS,mBAAmB,EAAE,CAGhC;AAoTD,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,wBAAsB,mCAAmC,CACvD,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAetB;AA4CD,wBAAsB,oCAAoC,CACxD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAmCD,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAetB;AAED,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkCtB;AAED,wBAAsB,8BAA8B,CAClD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAiBtB;AAED,wBAAsB,wCAAwC,CAC5D,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAuCtB;AAED,wBAAsB,yCAAyC,CAC7D,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkBtB;AAqFD,wBAAsB,kCAAkC,CACtD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CA4CtB;AAED,wBAAsB,qCAAqC,CACzD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED,wBAAsB,kCAAkC,CACtD,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CA2CtB"}