@oscharko-dev/keiko-server 0.2.0 → 0.2.1
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/.tsbuildinfo +1 -1
- package/dist/deps.d.ts +8 -2
- package/dist/deps.d.ts.map +1 -1
- package/dist/gateway-setup.d.ts +3 -1
- package/dist/gateway-setup.d.ts.map +1 -1
- package/dist/gateway-setup.js +124 -42
- package/dist/local-knowledge-handlers.d.ts +3 -1
- package/dist/local-knowledge-handlers.d.ts.map +1 -1
- package/dist/local-knowledge-handlers.js +28 -12
- package/dist/memory-embedding.d.ts.map +1 -1
- package/dist/memory-embedding.js +23 -25
- package/package.json +19 -19
package/dist/deps.d.ts
CHANGED
|
@@ -22,6 +22,12 @@ 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
|
+
}
|
|
30
|
+
export type GatewayModelDiscoveryOutput = readonly string[] | GatewayDiscoveredModels;
|
|
25
31
|
export interface UiHandlerDeps {
|
|
26
32
|
readonly config: GatewayConfig | undefined;
|
|
27
33
|
readonly configPresent: boolean;
|
|
@@ -41,7 +47,7 @@ export interface UiHandlerDeps {
|
|
|
41
47
|
readonly consolidationJobs?: ConsolidationJobRegistry | undefined;
|
|
42
48
|
readonly gatewayConfig?: RuntimeGatewayConfig | undefined;
|
|
43
49
|
readonly gatewaySetupTester?: ((config: GatewayConfig, candidateModelIds: readonly string[]) => Promise<readonly string[]>) | undefined;
|
|
44
|
-
readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<
|
|
50
|
+
readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<GatewayModelDiscoveryOutput>) | undefined;
|
|
45
51
|
readonly figmaCredentialTester?: ((accessToken: string, egress?: GatewayEgressConfig) => Promise<void>) | undefined;
|
|
46
52
|
readonly editorLanguageRouteOptions?: EditorLanguageRouteOptions | undefined;
|
|
47
53
|
readonly localKnowledgeEmbeddingRequest?: ((request: OpenAIEmbeddingRequest) => Promise<OpenAIEmbeddingOutcome>) | undefined;
|
|
@@ -60,7 +66,7 @@ export interface BuildHandlerDepsOptions {
|
|
|
60
66
|
readonly store?: UiStore | undefined;
|
|
61
67
|
readonly initialProjectPath?: string | undefined;
|
|
62
68
|
readonly gatewaySetupTester?: ((config: GatewayConfig, candidateModelIds: readonly string[]) => Promise<readonly string[]>) | undefined;
|
|
63
|
-
readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<
|
|
69
|
+
readonly gatewayModelDiscovery?: ((baseUrl: string, apiKey: string, apiKeyHeaderName?: string, egress?: GatewayEgressConfig) => Promise<GatewayModelDiscoveryOutput>) | undefined;
|
|
64
70
|
readonly figmaCredentialTester?: ((accessToken: string, egress?: GatewayEgressConfig) => Promise<void>) | undefined;
|
|
65
71
|
readonly qiRetentionAuditSink?: QiRetentionAuditSink | undefined;
|
|
66
72
|
readonly qiRetentionNow?: (() => number) | undefined;
|
package/dist/deps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../src/deps.ts"],"names":[],"mappings":"AAQA,OAAO,EAML,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAQ7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAML,KAAK,OAAO,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAkC,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,EAA+B,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACpG,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGzE,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EACV,2BAA2B,EAC3B,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAG7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,+CAA+C,CAAC;AAIvD,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAMnD,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;AAC1E,KAAK,mBAAmB,GAAG,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEhE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,OAAO,IAAI,aAAa,GAAG,SAAS,CAAC;IACrC,OAAO,IAAI,OAAO,CAAC;IACnB,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAChE;AAED,MAAM,WAAW,aAAa;IAE5B,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAE3C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IAExB,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAElD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAE/B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAE5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAG1D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAGxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAGvC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAGnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAGzD,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAGrD,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAEpD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAGlE,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAE1D,QAAQ,CAAC,kBAAkB,CAAC,EACxB,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC,GAC7F,SAAS,CAAC;IAEd,QAAQ,CAAC,qBAAqB,CAAC,EAC3B,CAAC,CACC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,gBAAgB,CAAC,EAAE,MAAM,EACzB,MAAM,CAAC,EAAE,mBAAmB,KACzB,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../src/deps.ts"],"names":[],"mappings":"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"}
|
package/dist/gateway-setup.d.ts
CHANGED
|
@@ -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,
|
|
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;AAgTzC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO/E;AA+BD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE1E;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,CAwB7E;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;AAstBD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAkBtB"}
|
package/dist/gateway-setup.js
CHANGED
|
@@ -148,11 +148,11 @@ function createDefaultEmbeddingCapabilityForSetup(modelId) {
|
|
|
148
148
|
],
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
-
function mergeChatAndEmbeddingModelIds(chatModelIds,
|
|
151
|
+
function mergeChatAndEmbeddingModelIds(chatModelIds, embeddingModelIds) {
|
|
152
152
|
const merged = [...chatModelIds];
|
|
153
153
|
const seen = new Set(merged);
|
|
154
|
-
for (const modelId of
|
|
155
|
-
if (
|
|
154
|
+
for (const modelId of embeddingModelIds) {
|
|
155
|
+
if (seen.has(modelId)) {
|
|
156
156
|
continue;
|
|
157
157
|
}
|
|
158
158
|
seen.add(modelId);
|
|
@@ -174,7 +174,7 @@ function currentImageInputModelIds(config) {
|
|
|
174
174
|
?.filter((capability) => capability.kind === "chat" && capability.supportsImageInput)
|
|
175
175
|
.map((capability) => capability.id) ?? []);
|
|
176
176
|
}
|
|
177
|
-
function rawConfigFromCurrent(config, figmaAccessToken) {
|
|
177
|
+
function rawConfigFromCurrent(config, figmaAccessToken, timeoutMs) {
|
|
178
178
|
return {
|
|
179
179
|
providers: config.providers.map((provider) => {
|
|
180
180
|
const capability = config.capabilities?.find((item) => item.id === provider.modelId);
|
|
@@ -183,7 +183,7 @@ function rawConfigFromCurrent(config, figmaAccessToken) {
|
|
|
183
183
|
baseUrl: provider.baseUrl,
|
|
184
184
|
apiKey: provider.apiKey,
|
|
185
185
|
apiKeyHeaderName: provider.apiKeyHeaderName ?? DEFAULT_API_KEY_HEADER_NAME,
|
|
186
|
-
timeoutMs: provider.timeoutMs,
|
|
186
|
+
timeoutMs: timeoutMs ?? provider.timeoutMs,
|
|
187
187
|
maxRetries: provider.maxRetries,
|
|
188
188
|
retryBaseDelayMs: provider.retryBaseDelayMs,
|
|
189
189
|
...(capability === undefined ? {} : { capability }),
|
|
@@ -250,6 +250,9 @@ function modelModeFromDiscoveryItem(item) {
|
|
|
250
250
|
}
|
|
251
251
|
return undefined;
|
|
252
252
|
}
|
|
253
|
+
function isExplicitlyEmbeddingModel(item) {
|
|
254
|
+
return modelModeFromDiscoveryItem(item) === "embedding";
|
|
255
|
+
}
|
|
253
256
|
// Issue #144: exported as part of the discovery-normalization seam so a
|
|
254
257
|
// sibling test file can drive it with synthetic payloads. Behaviour unchanged
|
|
255
258
|
// — only the visibility is widened.
|
|
@@ -261,35 +264,60 @@ export function isExplicitlyNonChatModel(item) {
|
|
|
261
264
|
const mode = modelModeFromDiscoveryItem(item);
|
|
262
265
|
return mode !== undefined && !CHAT_COMPATIBLE_MODES.has(mode);
|
|
263
266
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
// so callers can drop the entry silently and keep healthy peers.
|
|
267
|
-
export function modelIdFromDiscoveryItem(item) {
|
|
268
|
-
if (!isRecord(item) || isExplicitlyNonChatModel(item)) {
|
|
267
|
+
function classifyDiscoveryItem(item) {
|
|
268
|
+
if (!isRecord(item)) {
|
|
269
269
|
return undefined;
|
|
270
270
|
}
|
|
271
|
-
|
|
271
|
+
const id = modelIdFromKnownFields(item);
|
|
272
|
+
if (id === undefined) {
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
if (isExplicitlyEmbeddingModel(item)) {
|
|
276
|
+
return { id, kind: "embedding" };
|
|
277
|
+
}
|
|
278
|
+
if (isExplicitlyNonChatModel(item)) {
|
|
279
|
+
return isLikelyEmbeddingModelId(id) ? { id, kind: "embedding" } : undefined;
|
|
280
|
+
}
|
|
281
|
+
return isLikelyEmbeddingModelId(id) ? { id, kind: "embedding" } : { id, kind: "chat" };
|
|
272
282
|
}
|
|
273
|
-
// Issue #144: exported as part of the discovery-normalization seam.
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
|
|
283
|
+
// Issue #144: exported as part of the discovery-normalization seam. Gateway setup now returns
|
|
284
|
+
// embedding-capable records so setup can persist them for Local Knowledge while keeping them out of
|
|
285
|
+
// chat.
|
|
286
|
+
// Returns undefined for unknown/non-record/unsupported/malformed input so
|
|
287
|
+
// callers can drop the entry silently and keep healthy peers.
|
|
288
|
+
export function modelIdFromDiscoveryItem(item) {
|
|
289
|
+
return classifyDiscoveryItem(item)?.id;
|
|
290
|
+
}
|
|
291
|
+
// Issue #144: exported as part of the discovery-normalization seam. Throws on schema-level
|
|
292
|
+
// malformation (no data array) and on the "every entry filtered" terminal case so the caller
|
|
293
|
+
// (production path) returns an honest error rather than a silently-empty model list.
|
|
294
|
+
export function parseModelDiscovery(payload) {
|
|
278
295
|
if (!isRecord(payload) || !Array.isArray(payload.data)) {
|
|
279
296
|
throw new Error("model discovery response must contain a data array");
|
|
280
297
|
}
|
|
281
|
-
const
|
|
298
|
+
const entries = [];
|
|
299
|
+
const seen = new Set();
|
|
282
300
|
for (const item of payload.data) {
|
|
283
|
-
const
|
|
284
|
-
if (
|
|
285
|
-
|
|
301
|
+
const classified = classifyDiscoveryItem(item);
|
|
302
|
+
if (classified !== undefined && !seen.has(classified.id)) {
|
|
303
|
+
seen.add(classified.id);
|
|
304
|
+
entries.push(classified);
|
|
286
305
|
}
|
|
287
306
|
}
|
|
288
|
-
const
|
|
289
|
-
if (
|
|
307
|
+
const limited = entries.slice(0, MAX_DISCOVERED_MODELS);
|
|
308
|
+
if (limited.length === 0) {
|
|
290
309
|
throw new Error("model discovery returned no model ids");
|
|
291
310
|
}
|
|
292
|
-
return
|
|
311
|
+
return {
|
|
312
|
+
modelIds: limited.map((entry) => entry.id),
|
|
313
|
+
chatModelIds: limited.filter((entry) => entry.kind === "chat").map((entry) => entry.id),
|
|
314
|
+
embeddingModelIds: limited
|
|
315
|
+
.filter((entry) => entry.kind === "embedding")
|
|
316
|
+
.map((entry) => entry.id),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
export function parseModelList(payload) {
|
|
320
|
+
return parseModelDiscovery(payload).modelIds;
|
|
293
321
|
}
|
|
294
322
|
// Issue #144 AC #4: the public discovery-normalization seam. Test target. Pure
|
|
295
323
|
// wrapper around `parseModelList` so the AC ("Discovery handles additional
|
|
@@ -299,6 +327,9 @@ export function parseModelList(payload) {
|
|
|
299
327
|
export function normalizeDiscoveryPayload(payload) {
|
|
300
328
|
return parseModelList(payload);
|
|
301
329
|
}
|
|
330
|
+
export function normalizeDiscoveryPayloadForSetup(payload) {
|
|
331
|
+
return parseModelDiscovery(payload);
|
|
332
|
+
}
|
|
302
333
|
async function fetchDiscoveryJson(url, apiKey, apiKeyHeaderName, egress) {
|
|
303
334
|
const response = await gatewayFetch(url, {
|
|
304
335
|
method: "GET",
|
|
@@ -319,7 +350,7 @@ async function fetchDiscoveryJson(url, apiKey, apiKeyHeaderName, egress) {
|
|
|
319
350
|
async function discoverLiteLlmModelInfo(baseUrl, apiKey, apiKeyHeaderName, egress) {
|
|
320
351
|
for (const endpoint of modelInfoEndpointCandidates(baseUrl)) {
|
|
321
352
|
try {
|
|
322
|
-
return
|
|
353
|
+
return parseModelDiscovery(await fetchDiscoveryJson(endpoint, apiKey, apiKeyHeaderName, egress));
|
|
323
354
|
}
|
|
324
355
|
catch {
|
|
325
356
|
// /model/info is a LiteLLM-specific enrichment endpoint. If it is absent or blocked,
|
|
@@ -333,7 +364,7 @@ async function defaultGatewayModelDiscovery(baseUrl, apiKey, apiKeyHeaderName =
|
|
|
333
364
|
if (litellmModels !== undefined) {
|
|
334
365
|
return litellmModels;
|
|
335
366
|
}
|
|
336
|
-
return
|
|
367
|
+
return parseModelDiscovery(await fetchDiscoveryJson(modelsEndpoint(baseUrl), apiKey, apiKeyHeaderName, egress));
|
|
337
368
|
}
|
|
338
369
|
function deploymentNameValues(value) {
|
|
339
370
|
if (typeof value === "string") {
|
|
@@ -544,6 +575,15 @@ function optionalSetupSecret(value, path) {
|
|
|
544
575
|
const trimmed = value.trim();
|
|
545
576
|
return trimmed.length === 0 ? undefined : trimmed;
|
|
546
577
|
}
|
|
578
|
+
function optionalSetupPositiveInt(value, path) {
|
|
579
|
+
if (value === undefined) {
|
|
580
|
+
return undefined;
|
|
581
|
+
}
|
|
582
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
583
|
+
return { status: 400, body: errorBody("BAD_REQUEST", `${path} must be a positive integer.`) };
|
|
584
|
+
}
|
|
585
|
+
return value;
|
|
586
|
+
}
|
|
547
587
|
function hasNonBlankStringField(raw, key) {
|
|
548
588
|
const value = raw[key];
|
|
549
589
|
return typeof value === "string" && value.trim().length > 0;
|
|
@@ -623,6 +663,10 @@ function readSetupRequest(raw, env, current) {
|
|
|
623
663
|
if (isRouteResult(credentials)) {
|
|
624
664
|
return credentials;
|
|
625
665
|
}
|
|
666
|
+
const timeoutMs = optionalSetupPositiveInt(raw.timeoutMs, "timeoutMs");
|
|
667
|
+
if (isRouteResult(timeoutMs)) {
|
|
668
|
+
return timeoutMs;
|
|
669
|
+
}
|
|
626
670
|
const modelLists = readSetupModelLists(raw);
|
|
627
671
|
if (isRouteResult(modelLists)) {
|
|
628
672
|
return modelLists;
|
|
@@ -634,6 +678,7 @@ function readSetupRequest(raw, env, current) {
|
|
|
634
678
|
const resolvedModelLists = resolveSetupModelLists(modelLists, current, preserveExisting);
|
|
635
679
|
return {
|
|
636
680
|
...credentials,
|
|
681
|
+
timeoutMs,
|
|
637
682
|
deploymentNames: resolvedModelLists.deploymentNames,
|
|
638
683
|
imageInputModelIds: resolvedModelLists.imageInputModelIds,
|
|
639
684
|
figmaAccessToken: figmaAccessToken ?? current?.figma?.accessToken,
|
|
@@ -660,21 +705,60 @@ function validationConfigForSetup(input) {
|
|
|
660
705
|
const validationRawConfig = buildRawConfig(input.baseUrl, input.apiKey, ["setup-validation"], {
|
|
661
706
|
apiKeyHeaderName: input.apiKeyHeaderName,
|
|
662
707
|
imageInputModelIds: input.imageInputModelIds,
|
|
708
|
+
timeoutMs: input.timeoutMs,
|
|
663
709
|
});
|
|
664
710
|
return parseGatewayConfig(withInheritedEgress(validationRawConfig, input.egress), input.env);
|
|
665
711
|
}
|
|
712
|
+
function normalizeLegacyDiscoveryResult(modelIds) {
|
|
713
|
+
const embeddingModelIds = embeddingModelIdsFromDeployments(modelIds);
|
|
714
|
+
const embeddingSet = new Set(embeddingModelIds);
|
|
715
|
+
return {
|
|
716
|
+
modelIds,
|
|
717
|
+
chatModelIds: modelIds.filter((modelId) => !embeddingSet.has(modelId)),
|
|
718
|
+
embeddingModelIds,
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
function isStructuredDiscoveryResult(result) {
|
|
722
|
+
if (Array.isArray(result)) {
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
const candidate = result;
|
|
726
|
+
return (Array.isArray(candidate.modelIds) &&
|
|
727
|
+
Array.isArray(candidate.chatModelIds) &&
|
|
728
|
+
Array.isArray(candidate.embeddingModelIds));
|
|
729
|
+
}
|
|
730
|
+
function normalizeDiscoveryResult(result) {
|
|
731
|
+
if (isStructuredDiscoveryResult(result)) {
|
|
732
|
+
return {
|
|
733
|
+
modelIds: result.modelIds,
|
|
734
|
+
chatModelIds: result.chatModelIds,
|
|
735
|
+
embeddingModelIds: result.embeddingModelIds,
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
return normalizeLegacyDiscoveryResult(result);
|
|
739
|
+
}
|
|
740
|
+
function candidateModelsFromDeploymentNames(deploymentNames) {
|
|
741
|
+
const embeddingModelIds = embeddingModelIdsFromDeployments(deploymentNames);
|
|
742
|
+
const embeddingSet = new Set(embeddingModelIds);
|
|
743
|
+
return {
|
|
744
|
+
modelIds: deploymentNames,
|
|
745
|
+
chatModelIds: deploymentNames.filter((modelId) => !embeddingSet.has(modelId)),
|
|
746
|
+
embeddingModelIds,
|
|
747
|
+
};
|
|
748
|
+
}
|
|
666
749
|
async function candidateModelIdsForSetup(input, validationConfig) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
750
|
+
if (input.deploymentNames.length > 0) {
|
|
751
|
+
return candidateModelsFromDeploymentNames(input.deploymentNames);
|
|
752
|
+
}
|
|
753
|
+
return normalizeDiscoveryResult(await input.discovery(input.baseUrl, input.apiKey, input.apiKeyHeaderName, validationConfig.egress));
|
|
670
754
|
}
|
|
671
|
-
function finalRawConfigForSetup(input, testedModelIds) {
|
|
672
|
-
const
|
|
673
|
-
const configuredModelIds = mergeChatAndEmbeddingModelIds(testedModelIds, input.deploymentNames);
|
|
755
|
+
function finalRawConfigForSetup(input, testedModelIds, embeddingModelIds) {
|
|
756
|
+
const configuredModelIds = mergeChatAndEmbeddingModelIds(testedModelIds, embeddingModelIds);
|
|
674
757
|
const rawConfig = buildRawConfig(input.baseUrl, input.apiKey, configuredModelIds, {
|
|
675
758
|
apiKeyHeaderName: input.apiKeyHeaderName,
|
|
676
759
|
imageInputModelIds: input.imageInputModelIds,
|
|
677
760
|
embeddingModelIds,
|
|
761
|
+
timeoutMs: input.timeoutMs,
|
|
678
762
|
});
|
|
679
763
|
return {
|
|
680
764
|
...rawConfig,
|
|
@@ -684,11 +768,8 @@ function finalRawConfigForSetup(input, testedModelIds) {
|
|
|
684
768
|
: { figma: { accessToken: input.figmaAccessToken } }),
|
|
685
769
|
};
|
|
686
770
|
}
|
|
687
|
-
function skippedModelIdsForSetup(candidateModelIds, testedModelIds,
|
|
688
|
-
const acceptedModelIds = new Set([
|
|
689
|
-
...testedModelIds,
|
|
690
|
-
...embeddingModelIdsFromDeployments(deploymentNames),
|
|
691
|
-
]);
|
|
771
|
+
function skippedModelIdsForSetup(candidateModelIds, testedModelIds, embeddingModelIds) {
|
|
772
|
+
const acceptedModelIds = new Set([...testedModelIds, ...embeddingModelIds]);
|
|
692
773
|
return candidateModelIds.filter((modelId) => !acceptedModelIds.has(modelId));
|
|
693
774
|
}
|
|
694
775
|
async function verifySetupCandidate(input) {
|
|
@@ -696,11 +777,11 @@ async function verifySetupCandidate(input) {
|
|
|
696
777
|
// scheme/credential/loopback validation as the originally submitted base URL.
|
|
697
778
|
validateBaseUrl(input.baseUrl, "candidate");
|
|
698
779
|
const validationConfig = validationConfigForSetup(input);
|
|
699
|
-
const
|
|
780
|
+
const candidateModels = await candidateModelIdsForSetup(input, validationConfig);
|
|
700
781
|
const smokeTimeoutMs = input.deploymentNames.length > 0
|
|
701
782
|
? DEPLOYMENT_SMOKE_TIMEOUT_MS
|
|
702
783
|
: DISCOVERED_MODEL_SMOKE_TIMEOUT_MS;
|
|
703
|
-
const candidateRawConfig = buildRawConfig(input.baseUrl, input.apiKey,
|
|
784
|
+
const candidateRawConfig = buildRawConfig(input.baseUrl, input.apiKey, candidateModels.chatModelIds, {
|
|
704
785
|
apiKeyHeaderName: input.apiKeyHeaderName,
|
|
705
786
|
timeoutMs: smokeTimeoutMs,
|
|
706
787
|
// One retry (not zero) so a single transient blip — 429 rate-limit, brief timeout, momentary
|
|
@@ -710,15 +791,15 @@ async function verifySetupCandidate(input) {
|
|
|
710
791
|
imageInputModelIds: input.imageInputModelIds,
|
|
711
792
|
});
|
|
712
793
|
const candidateConfig = parseGatewayConfig(withInheritedEgress(candidateRawConfig, input.egress), input.env);
|
|
713
|
-
const testedModelIds = await input.tester(candidateConfig,
|
|
794
|
+
const testedModelIds = await input.tester(candidateConfig, candidateModels.chatModelIds);
|
|
714
795
|
assertImageInputModelsWereTested(input.imageInputModelIds, testedModelIds);
|
|
715
|
-
const rawConfigWithOptionalBlocks = finalRawConfigForSetup(input, testedModelIds);
|
|
796
|
+
const rawConfigWithOptionalBlocks = finalRawConfigForSetup(input, testedModelIds, candidateModels.embeddingModelIds);
|
|
716
797
|
const config = parseGatewayConfig(withInheritedEgress(rawConfigWithOptionalBlocks, input.egress), input.env);
|
|
717
798
|
return {
|
|
718
799
|
rawConfig: rawConfigWithOptionalBlocks,
|
|
719
800
|
config,
|
|
720
801
|
testedModelIds,
|
|
721
|
-
skippedModelIds: skippedModelIdsForSetup(
|
|
802
|
+
skippedModelIds: skippedModelIdsForSetup(candidateModels.modelIds, testedModelIds, candidateModels.embeddingModelIds),
|
|
722
803
|
};
|
|
723
804
|
}
|
|
724
805
|
function setupSuccessResult(config, testedModelIds, skippedModelIds) {
|
|
@@ -819,6 +900,7 @@ async function trySetupCandidate(baseUrl, request, deps, gatewayConfig, tester,
|
|
|
819
900
|
baseUrl,
|
|
820
901
|
apiKey: request.apiKey,
|
|
821
902
|
apiKeyHeaderName: request.apiKeyHeaderName,
|
|
903
|
+
timeoutMs: request.timeoutMs,
|
|
822
904
|
deploymentNames: request.deploymentNames,
|
|
823
905
|
imageInputModelIds: request.imageInputModelIds,
|
|
824
906
|
tester,
|
|
@@ -836,7 +918,7 @@ function setupCandidateError(error, request, baseUrl) {
|
|
|
836
918
|
return safeError(error, [request.apiKey, request.baseUrl, baseUrl, request.figmaAccessToken]);
|
|
837
919
|
}
|
|
838
920
|
function saveExistingConfigUpdate(request, current, deps, gatewayConfig) {
|
|
839
|
-
const rawConfig = rawConfigFromCurrent(current, request.figmaAccessToken);
|
|
921
|
+
const rawConfig = rawConfigFromCurrent(current, request.figmaAccessToken, request.timeoutMs);
|
|
840
922
|
const config = parseGatewayConfig(withInheritedEgress(rawConfig, currentGatewayEgressConfig(deps)), deps.env);
|
|
841
923
|
persistGatewayConfig(rawConfig, gatewayConfig.storagePath, deps);
|
|
842
924
|
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,
|
|
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,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;AAgqBD,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;AAwSD,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"}
|
|
@@ -656,10 +656,19 @@ function storedProviderMatchesConfiguredProvider(storedProvider, provider) {
|
|
|
656
656
|
// Issue #621 / #677: select the first provider whose resolved capability is embedding-capable.
|
|
657
657
|
// Falling back to a chat model creates capsules that can never index successfully.
|
|
658
658
|
export function selectEmbeddingModelId(config) {
|
|
659
|
+
return configuredEmbeddingModelIds(config)[0];
|
|
660
|
+
}
|
|
661
|
+
export function configuredEmbeddingModelIds(config) {
|
|
659
662
|
if (config === undefined || config === null || config.providers.length === 0)
|
|
660
|
-
return
|
|
661
|
-
return config.providers
|
|
662
|
-
|
|
663
|
+
return [];
|
|
664
|
+
return config.providers
|
|
665
|
+
.filter((provider) => isConfiguredEmbeddingModel(config, provider.modelId))
|
|
666
|
+
.map((provider) => provider.modelId);
|
|
667
|
+
}
|
|
668
|
+
export function configuredEmbeddingProviders(config) {
|
|
669
|
+
if (config === undefined || config.providers.length === 0)
|
|
670
|
+
return [];
|
|
671
|
+
return config.providers.filter((provider) => isConfiguredEmbeddingModel(config, provider.modelId));
|
|
663
672
|
}
|
|
664
673
|
function createCapsuleStorageReference(capsuleId) {
|
|
665
674
|
return `capsules/${capsuleId}`;
|
|
@@ -687,21 +696,28 @@ async function verifiedNewCapsuleEmbeddingIdentity(deps, provider) {
|
|
|
687
696
|
}
|
|
688
697
|
async function resolveNewCapsuleEmbeddingIdentity(deps) {
|
|
689
698
|
const config = currentGatewayConfig(deps);
|
|
690
|
-
const
|
|
691
|
-
if (
|
|
699
|
+
const providers = configuredEmbeddingProviders(config);
|
|
700
|
+
if (providers.length === 0) {
|
|
692
701
|
return {
|
|
693
702
|
ok: false,
|
|
694
703
|
result: conflict("No configured embedding-capable model is available for new capsules. Configure the Model Gateway first."),
|
|
695
704
|
};
|
|
696
705
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
}
|
|
706
|
+
let lastFailure;
|
|
707
|
+
for (const provider of providers) {
|
|
708
|
+
const verified = await verifiedNewCapsuleEmbeddingIdentity(deps, provider);
|
|
709
|
+
if (verified.ok) {
|
|
710
|
+
return verified;
|
|
711
|
+
}
|
|
712
|
+
lastFailure = verified.result;
|
|
703
713
|
}
|
|
704
|
-
|
|
714
|
+
if (lastFailure !== undefined) {
|
|
715
|
+
return { ok: false, result: lastFailure };
|
|
716
|
+
}
|
|
717
|
+
return {
|
|
718
|
+
ok: false,
|
|
719
|
+
result: conflict("No configured embedding-capable model is available for new capsules. Configure the Model Gateway first."),
|
|
720
|
+
};
|
|
705
721
|
}
|
|
706
722
|
function latestRunningJobId(store, capsuleId) {
|
|
707
723
|
const row = store._internal.db
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-embedding.d.ts","sourceRoot":"","sources":["../src/memory-embedding.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,KAAK,aAAa,EAGlB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAEV,QAAQ,EACR,YAAY,EAEb,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-embedding.d.ts","sourceRoot":"","sources":["../src/memory-embedding.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,KAAK,aAAa,EAGlB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAEV,QAAQ,EACR,YAAY,EAEb,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAOrE,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,aAAa,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAEpB;AAkDD,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;AAKpF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,WAAW,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,sBAAsB,CAAC,GAChF,cAAc,GAAG,IAAI,CAyBvB;AAKD,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAItC;AAKD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAQf;AAKD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CAgBzE;AAiBD,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAKpD,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,oBAAoB,GAAG,IAAI,EACtC,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EACpD,SAAS,GAAE,MAAwC,GAClD,QAAQ,GAAG,IAAI,CAYjB;AAeD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAGlD,eAAO,MAAM,cAAc,IAAI,CAAC;AAMhC,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,oBAAoB,GAAG,IAAI,EACtC,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EACpD,KAAK,GAAE,MAAsC,EAC7C,KAAK,GAAE,MAAwC,EAC/C,QAAQ,GAAE,MAAuB,GAChC,SAAS,QAAQ,EAAE,CAWrB;AA+CD,MAAM,WAAW,mBAAmB;IAElC,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAEvC,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,IAAI,CAAC;CACtC;AAOD,wBAAsB,mCAAmC,CACvD,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAoB9B"}
|
package/dist/memory-embedding.js
CHANGED
|
@@ -16,14 +16,11 @@
|
|
|
16
16
|
import { requestOpenAIEmbedding, } from "@oscharko-dev/keiko-model-gateway";
|
|
17
17
|
import { randomUUID } from "node:crypto";
|
|
18
18
|
import { currentGatewayConfig } from "./deps.js";
|
|
19
|
-
import { selectEmbeddingModelId } from "./local-knowledge-handlers.js";
|
|
19
|
+
import { configuredEmbeddingProviders, selectEmbeddingModelId, } from "./local-knowledge-handlers.js";
|
|
20
20
|
const MEMORY_VECTOR_METRIC = "cosine";
|
|
21
21
|
export function selectMemoryEmbeddingModelId(config) {
|
|
22
22
|
return selectEmbeddingModelId(config);
|
|
23
23
|
}
|
|
24
|
-
function providerForModel(config, modelId) {
|
|
25
|
-
return config?.providers.find((provider) => provider.modelId === modelId);
|
|
26
|
-
}
|
|
27
24
|
function requestEmbeddingImpl(deps) {
|
|
28
25
|
// Reuses the same gateway seam as Local Knowledge so a single injected adapter drives both.
|
|
29
26
|
return deps.localKnowledgeEmbeddingRequest ?? requestOpenAIEmbedding;
|
|
@@ -62,32 +59,33 @@ function toEmbeddingInput(provider, outcome) {
|
|
|
62
59
|
// configured (or its provider is absent). The CLI backfill and the conversation paths both compose
|
|
63
60
|
// through this single factory so capability-aware model selection lives in one place.
|
|
64
61
|
export function createMemoryEmbedder(config, requestImpl) {
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
67
|
-
return null;
|
|
68
|
-
const provider = providerForModel(config, modelId);
|
|
69
|
-
if (provider === undefined)
|
|
62
|
+
const providers = configuredEmbeddingProviders(config);
|
|
63
|
+
if (providers.length === 0)
|
|
70
64
|
return null;
|
|
71
|
-
const
|
|
65
|
+
const candidates = providers.map((provider) => ({
|
|
66
|
+
provider,
|
|
67
|
+
adapter: buildAdapter(provider, requestImpl),
|
|
68
|
+
}));
|
|
72
69
|
return async (text) => {
|
|
73
70
|
if (text.length === 0)
|
|
74
71
|
return null;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
72
|
+
for (const { provider, adapter } of candidates) {
|
|
73
|
+
try {
|
|
74
|
+
const outcome = await adapter.request({
|
|
75
|
+
endpoint: provider.baseUrl,
|
|
76
|
+
apiKey: provider.apiKey,
|
|
77
|
+
modelId: provider.modelId,
|
|
78
|
+
input: text,
|
|
79
|
+
...(provider.egress !== undefined ? { egress: provider.egress } : {}),
|
|
80
|
+
});
|
|
81
|
+
if (outcome.ok)
|
|
82
|
+
return toEmbeddingInput("openai", outcome);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Model/transport boundary: a thrown adapter degrades to the next embedding provider.
|
|
86
|
+
}
|
|
90
87
|
}
|
|
88
|
+
return null;
|
|
91
89
|
};
|
|
92
90
|
}
|
|
93
91
|
// Embeds `text` against the configured embedding model. Returns null when no embedding-capable
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscharko-dev/keiko-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Internal server package: local loopback BFF runtime (HTTP/SSE/WebSocket router, CSP, host check, CSRF gate, terminal, browser, files, run engine, SQLite-backed UI store) that mediates the browser presentation tier and the Node-side domain packages (ADR-0019). Not published independently.",
|
|
@@ -29,24 +29,24 @@
|
|
|
29
29
|
"node": ">=22"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@oscharko-dev/keiko-contracts": "0.2.
|
|
33
|
-
"@oscharko-dev/keiko-security": "0.2.
|
|
34
|
-
"@oscharko-dev/keiko-model-gateway": "0.2.
|
|
35
|
-
"@oscharko-dev/keiko-quality-intelligence": "0.2.
|
|
36
|
-
"@oscharko-dev/keiko-local-knowledge": "0.2.
|
|
37
|
-
"@oscharko-dev/keiko-workspace": "0.2.
|
|
38
|
-
"@oscharko-dev/keiko-sandbox": "0.2.
|
|
39
|
-
"@oscharko-dev/keiko-tools": "0.2.
|
|
40
|
-
"@oscharko-dev/keiko-evidence": "0.2.
|
|
41
|
-
"@oscharko-dev/keiko-verification": "0.2.
|
|
42
|
-
"@oscharko-dev/keiko-harness": "0.2.
|
|
43
|
-
"@oscharko-dev/keiko-sdk": "0.2.
|
|
44
|
-
"@oscharko-dev/keiko-workflows": "0.2.
|
|
45
|
-
"@oscharko-dev/keiko-memory-vault": "0.2.
|
|
46
|
-
"@oscharko-dev/keiko-memory-governance": "0.2.
|
|
47
|
-
"@oscharko-dev/keiko-memory-retrieval": "0.2.
|
|
48
|
-
"@oscharko-dev/keiko-memory-capture": "0.2.
|
|
49
|
-
"@oscharko-dev/keiko-memory-consolidation": "0.2.
|
|
32
|
+
"@oscharko-dev/keiko-contracts": "0.2.1",
|
|
33
|
+
"@oscharko-dev/keiko-security": "0.2.1",
|
|
34
|
+
"@oscharko-dev/keiko-model-gateway": "0.2.1",
|
|
35
|
+
"@oscharko-dev/keiko-quality-intelligence": "0.2.1",
|
|
36
|
+
"@oscharko-dev/keiko-local-knowledge": "0.2.1",
|
|
37
|
+
"@oscharko-dev/keiko-workspace": "0.2.1",
|
|
38
|
+
"@oscharko-dev/keiko-sandbox": "0.2.1",
|
|
39
|
+
"@oscharko-dev/keiko-tools": "0.2.1",
|
|
40
|
+
"@oscharko-dev/keiko-evidence": "0.2.1",
|
|
41
|
+
"@oscharko-dev/keiko-verification": "0.2.1",
|
|
42
|
+
"@oscharko-dev/keiko-harness": "0.2.1",
|
|
43
|
+
"@oscharko-dev/keiko-sdk": "0.2.1",
|
|
44
|
+
"@oscharko-dev/keiko-workflows": "0.2.1",
|
|
45
|
+
"@oscharko-dev/keiko-memory-vault": "0.2.1",
|
|
46
|
+
"@oscharko-dev/keiko-memory-governance": "0.2.1",
|
|
47
|
+
"@oscharko-dev/keiko-memory-retrieval": "0.2.1",
|
|
48
|
+
"@oscharko-dev/keiko-memory-capture": "0.2.1",
|
|
49
|
+
"@oscharko-dev/keiko-memory-consolidation": "0.2.1",
|
|
50
50
|
"typescript": "^6.0.3"
|
|
51
51
|
}
|
|
52
52
|
}
|