@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/.tsbuildinfo +1 -1
- package/dist/deps.d.ts +9 -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 +201 -43
- 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 +90 -23
- package/dist/memory-embedding.d.ts.map +1 -1
- package/dist/memory-embedding.js +23 -25
- package/package.json +19 -19
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { statSync } from "node:fs";
|
|
3
3
|
import { basename, dirname } from "node:path";
|
|
4
|
-
import { addSourceToCapsule, checkpointToProgress, composeCapsules, CompositionError, createSqliteAuditSink, createDefaultParserRegistry, createCapsule, deleteCapsule, getCapsule, listCapsuleSets, listCapsuleSources, listCapsules, listExtractionCheckpoints, listResumableDocuments, openKnowledgeStore, removeSourceFromCapsule, resolveKnowledgeStorePath, runIndexingJob, updateCapsuleDetails, updateCapsuleState, } from "@oscharko-dev/keiko-local-knowledge";
|
|
4
|
+
import { addSourceToCapsule, checkpointToProgress, composeCapsules, CompositionError, createSqliteAuditSink, createDefaultParserRegistry, createCapsule, deleteCapsule, getCapsule, listCapsuleSets, listCapsuleSources, listCapsules, listExtractionCheckpoints, listResumableDocuments, openKnowledgeStore, removeSourceFromCapsule, resolveKnowledgeStorePath, runIndexingJob, updateCapsuleEmbeddingModelIdentity, updateCapsuleDetails, updateCapsuleState, } from "@oscharko-dev/keiko-local-knowledge";
|
|
5
5
|
import { KnowledgeNotFoundError, KnowledgeStoreError } from "@oscharko-dev/keiko-local-knowledge";
|
|
6
6
|
import { localKnowledgeProtectionOptions } from "./localKnowledgeKeyProvider.js";
|
|
7
7
|
import { CAPSULE_SET_MAX_MEMBERS, DEFAULT_EXTRACTION_CAPABILITY_AVAILABILITY, DEFAULT_LARGE_DOCUMENT_RESOURCE_POLICY, isSafeDisplaySummary, isSafeQualityWarning, validateCapsuleReindexRequest, validateKnowledgeSourceScope, } from "@oscharko-dev/keiko-contracts";
|
|
@@ -218,6 +218,52 @@ function configuredProviderForCapsule(deps, capsule) {
|
|
|
218
218
|
? provider
|
|
219
219
|
: undefined;
|
|
220
220
|
}
|
|
221
|
+
function embeddingIdentityMatchesCapsuleAlias(stored, current) {
|
|
222
|
+
if (stored.provider !== current.provider ||
|
|
223
|
+
stored.vectorDimensions !== current.vectorDimensions ||
|
|
224
|
+
stored.vectorMetric !== current.vectorMetric) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
if (stored.modelId === current.modelId) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
return current.modelRevision !== undefined && stored.modelId === current.modelRevision;
|
|
231
|
+
}
|
|
232
|
+
async function probeConfiguredProviderForCapsule(deps, provider, capsule) {
|
|
233
|
+
const adapter = createEmbeddingAdapter(provider, requestEmbeddingImpl(deps), requestEmbeddingBatchImpl(deps));
|
|
234
|
+
try {
|
|
235
|
+
const result = await verifyEmbeddingCapability(adapter, {
|
|
236
|
+
modelId: provider.modelId,
|
|
237
|
+
provider: embeddingProviderIdentity(provider),
|
|
238
|
+
vectorMetric: capsule.embeddingModelIdentity.vectorMetric,
|
|
239
|
+
expectedDimensions: capsule.embeddingModelIdentity.vectorDimensions,
|
|
240
|
+
timeoutMs: provider.timeoutMs,
|
|
241
|
+
});
|
|
242
|
+
return result.ok ? result.identity : undefined;
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
async function resolveIndexingProviderForCapsule(deps, store, capsule) {
|
|
249
|
+
const exact = configuredProviderForCapsule(deps, capsule);
|
|
250
|
+
if (exact !== undefined) {
|
|
251
|
+
return { capsule, provider: exact };
|
|
252
|
+
}
|
|
253
|
+
const providers = configuredEmbeddingProviders(currentGatewayConfig(deps));
|
|
254
|
+
for (const provider of providers) {
|
|
255
|
+
if (!storedProviderMatchesConfiguredProvider(capsule.embeddingModelIdentity.provider, provider)) {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const identity = await probeConfiguredProviderForCapsule(deps, provider, capsule);
|
|
259
|
+
if (identity !== undefined &&
|
|
260
|
+
embeddingIdentityMatchesCapsuleAlias(capsule.embeddingModelIdentity, identity)) {
|
|
261
|
+
const repaired = updateCapsuleEmbeddingModelIdentity(store, capsule.id, identity);
|
|
262
|
+
return { capsule: repaired, provider };
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
221
267
|
function embeddingCompatibilityReason(config, capsule) {
|
|
222
268
|
if (config === undefined)
|
|
223
269
|
return undefined;
|
|
@@ -656,10 +702,19 @@ function storedProviderMatchesConfiguredProvider(storedProvider, provider) {
|
|
|
656
702
|
// Issue #621 / #677: select the first provider whose resolved capability is embedding-capable.
|
|
657
703
|
// Falling back to a chat model creates capsules that can never index successfully.
|
|
658
704
|
export function selectEmbeddingModelId(config) {
|
|
705
|
+
return configuredEmbeddingModelIds(config)[0];
|
|
706
|
+
}
|
|
707
|
+
export function configuredEmbeddingModelIds(config) {
|
|
659
708
|
if (config === undefined || config === null || config.providers.length === 0)
|
|
660
|
-
return
|
|
661
|
-
return config.providers
|
|
662
|
-
|
|
709
|
+
return [];
|
|
710
|
+
return config.providers
|
|
711
|
+
.filter((provider) => isConfiguredEmbeddingModel(config, provider.modelId))
|
|
712
|
+
.map((provider) => provider.modelId);
|
|
713
|
+
}
|
|
714
|
+
export function configuredEmbeddingProviders(config) {
|
|
715
|
+
if (config === undefined || config.providers.length === 0)
|
|
716
|
+
return [];
|
|
717
|
+
return config.providers.filter((provider) => isConfiguredEmbeddingModel(config, provider.modelId));
|
|
663
718
|
}
|
|
664
719
|
function createCapsuleStorageReference(capsuleId) {
|
|
665
720
|
return `capsules/${capsuleId}`;
|
|
@@ -687,21 +742,28 @@ async function verifiedNewCapsuleEmbeddingIdentity(deps, provider) {
|
|
|
687
742
|
}
|
|
688
743
|
async function resolveNewCapsuleEmbeddingIdentity(deps) {
|
|
689
744
|
const config = currentGatewayConfig(deps);
|
|
690
|
-
const
|
|
691
|
-
if (
|
|
745
|
+
const providers = configuredEmbeddingProviders(config);
|
|
746
|
+
if (providers.length === 0) {
|
|
692
747
|
return {
|
|
693
748
|
ok: false,
|
|
694
749
|
result: conflict("No configured embedding-capable model is available for new capsules. Configure the Model Gateway first."),
|
|
695
750
|
};
|
|
696
751
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
}
|
|
752
|
+
let lastFailure;
|
|
753
|
+
for (const provider of providers) {
|
|
754
|
+
const verified = await verifiedNewCapsuleEmbeddingIdentity(deps, provider);
|
|
755
|
+
if (verified.ok) {
|
|
756
|
+
return verified;
|
|
757
|
+
}
|
|
758
|
+
lastFailure = verified.result;
|
|
703
759
|
}
|
|
704
|
-
|
|
760
|
+
if (lastFailure !== undefined) {
|
|
761
|
+
return { ok: false, result: lastFailure };
|
|
762
|
+
}
|
|
763
|
+
return {
|
|
764
|
+
ok: false,
|
|
765
|
+
result: conflict("No configured embedding-capable model is available for new capsules. Configure the Model Gateway first."),
|
|
766
|
+
};
|
|
705
767
|
}
|
|
706
768
|
function latestRunningJobId(store, capsuleId) {
|
|
707
769
|
const row = store._internal.db
|
|
@@ -764,6 +826,9 @@ function indexingCompletionResponse(capsuleId, terminal, failedMessage) {
|
|
|
764
826
|
}
|
|
765
827
|
return actionResponse(capsuleId);
|
|
766
828
|
}
|
|
829
|
+
function runningIndexingJobConflict(capsuleId, runningJobId) {
|
|
830
|
+
return indexingConflict("indexing-already-running", "An indexing job is already running for this capsule.", capsuleId, runningJobId);
|
|
831
|
+
}
|
|
767
832
|
function buildIndexingOptions(store, capsule, adapter, options, sourceSelection, signal) {
|
|
768
833
|
return {
|
|
769
834
|
capsuleId: capsule.id,
|
|
@@ -1058,21 +1123,22 @@ export async function handleStartLocalKnowledgeCapsuleIndexing(ctx, deps) {
|
|
|
1058
1123
|
if (capsule.sourceIds.length === 0) {
|
|
1059
1124
|
return emptyCapsuleIndexingConflict();
|
|
1060
1125
|
}
|
|
1061
|
-
|
|
1126
|
+
const resolved = await resolveIndexingProviderForCapsule(deps, env.store, capsule);
|
|
1127
|
+
if (resolved === undefined) {
|
|
1062
1128
|
return conflict("No configured embedding-capable model matches this capsule. Update the Model Gateway configuration before indexing it.");
|
|
1063
1129
|
}
|
|
1064
1130
|
// LK-003 (Epic #189): refuse to start a second concurrent indexer for the same
|
|
1065
1131
|
// capsule — the orchestrator persists running jobs, so a duplicate POST would
|
|
1066
1132
|
// race the in-flight one and corrupt vector counts.
|
|
1067
|
-
const runningJobId = latestRunningJobId(env.store, capsule.id);
|
|
1133
|
+
const runningJobId = latestRunningJobId(env.store, resolved.capsule.id);
|
|
1068
1134
|
if (runningJobId !== undefined) {
|
|
1069
|
-
return
|
|
1135
|
+
return runningIndexingJobConflict(resolved.capsule.id, runningJobId);
|
|
1070
1136
|
}
|
|
1071
|
-
const terminal = await runCapsuleIndexingJob(deps, env.store, capsule, {
|
|
1137
|
+
const terminal = await runCapsuleIndexingJob(deps, env.store, resolved.capsule, {
|
|
1072
1138
|
mode: undefined,
|
|
1073
1139
|
force: false,
|
|
1074
1140
|
});
|
|
1075
|
-
return indexingCompletionResponse(capsule.id, terminal, "Capsule indexing failed. Review the capsule health diagnostics and job history for details.");
|
|
1141
|
+
return indexingCompletionResponse(resolved.capsule.id, terminal, "Capsule indexing failed. Review the capsule health diagnostics and job history for details.");
|
|
1076
1142
|
}
|
|
1077
1143
|
finally {
|
|
1078
1144
|
env.close();
|
|
@@ -1264,19 +1330,20 @@ export async function handleReindexLocalKnowledgeCapsule(ctx, deps) {
|
|
|
1264
1330
|
if (capsule.sourceIds.length === 0) {
|
|
1265
1331
|
return emptyCapsuleIndexingConflict();
|
|
1266
1332
|
}
|
|
1267
|
-
|
|
1333
|
+
const resolved = await resolveIndexingProviderForCapsule(deps, env.store, capsule);
|
|
1334
|
+
if (resolved === undefined) {
|
|
1268
1335
|
return conflict("No configured embedding-capable model matches this capsule. Update the Model Gateway configuration before refreshing it.");
|
|
1269
1336
|
}
|
|
1270
1337
|
// LK-003 (Epic #189): same concurrent-run guard as the start handler.
|
|
1271
|
-
const runningJobId = latestRunningJobId(env.store, capsule.id);
|
|
1338
|
+
const runningJobId = latestRunningJobId(env.store, resolved.capsule.id);
|
|
1272
1339
|
if (runningJobId !== undefined) {
|
|
1273
|
-
return
|
|
1340
|
+
return runningIndexingJobConflict(resolved.capsule.id, runningJobId);
|
|
1274
1341
|
}
|
|
1275
|
-
const terminal = await runCapsuleIndexingJob(deps, env.store, capsule, {
|
|
1342
|
+
const terminal = await runCapsuleIndexingJob(deps, env.store, resolved.capsule, {
|
|
1276
1343
|
mode,
|
|
1277
1344
|
force,
|
|
1278
1345
|
});
|
|
1279
|
-
return indexingCompletionResponse(capsule.id, terminal, "Capsule refresh failed. Review the capsule health diagnostics and job history for details.");
|
|
1346
|
+
return indexingCompletionResponse(resolved.capsule.id, terminal, "Capsule refresh failed. Review the capsule health diagnostics and job history for details.");
|
|
1280
1347
|
}
|
|
1281
1348
|
finally {
|
|
1282
1349
|
env.close();
|
|
@@ -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.2",
|
|
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.2",
|
|
33
|
+
"@oscharko-dev/keiko-security": "0.2.2",
|
|
34
|
+
"@oscharko-dev/keiko-model-gateway": "0.2.2",
|
|
35
|
+
"@oscharko-dev/keiko-quality-intelligence": "0.2.2",
|
|
36
|
+
"@oscharko-dev/keiko-local-knowledge": "0.2.2",
|
|
37
|
+
"@oscharko-dev/keiko-workspace": "0.2.2",
|
|
38
|
+
"@oscharko-dev/keiko-sandbox": "0.2.2",
|
|
39
|
+
"@oscharko-dev/keiko-tools": "0.2.2",
|
|
40
|
+
"@oscharko-dev/keiko-evidence": "0.2.2",
|
|
41
|
+
"@oscharko-dev/keiko-verification": "0.2.2",
|
|
42
|
+
"@oscharko-dev/keiko-harness": "0.2.2",
|
|
43
|
+
"@oscharko-dev/keiko-sdk": "0.2.2",
|
|
44
|
+
"@oscharko-dev/keiko-workflows": "0.2.2",
|
|
45
|
+
"@oscharko-dev/keiko-memory-vault": "0.2.2",
|
|
46
|
+
"@oscharko-dev/keiko-memory-governance": "0.2.2",
|
|
47
|
+
"@oscharko-dev/keiko-memory-retrieval": "0.2.2",
|
|
48
|
+
"@oscharko-dev/keiko-memory-capture": "0.2.2",
|
|
49
|
+
"@oscharko-dev/keiko-memory-consolidation": "0.2.2",
|
|
50
50
|
"typescript": "^6.0.3"
|
|
51
51
|
}
|
|
52
52
|
}
|