@axiom-lattice/core 8.0.2 → 8.1.0
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/index.d.mts +236 -2
- package/dist/index.d.ts +236 -2
- package/dist/index.js +487 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +479 -135
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1616,6 +1616,7 @@ __export(index_exports, {
|
|
|
1616
1616
|
BUILTIN_PLUGINS: () => BUILTIN_PLUGINS,
|
|
1617
1617
|
BUILTIN_SKILLS: () => BUILTIN_SKILLS,
|
|
1618
1618
|
CAPABILITY_TOOL_NAME_CONFLICT: () => CAPABILITY_TOOL_NAME_CONFLICT,
|
|
1619
|
+
COLLECTION_CHANGED_TOPIC: () => COLLECTION_CHANGED_TOPIC,
|
|
1619
1620
|
CapabilityBundleMergeError: () => CapabilityBundleMergeError,
|
|
1620
1621
|
CapabilityBundleMerger: () => CapabilityBundleMerger,
|
|
1621
1622
|
CapabilityBundleValidationError: () => CapabilityBundleValidationError,
|
|
@@ -1635,6 +1636,7 @@ __export(index_exports, {
|
|
|
1635
1636
|
DEFAULT_DELAY_MS: () => DEFAULT_DELAY_MS,
|
|
1636
1637
|
DEFAULT_HANDLER_TIMEOUT_MS: () => DEFAULT_HANDLER_TIMEOUT_MS,
|
|
1637
1638
|
DEFAULT_MAX_ATTEMPTS: () => DEFAULT_MAX_ATTEMPTS,
|
|
1639
|
+
DEFAULT_MODEL_EXTRA: () => DEFAULT_MODEL_EXTRA,
|
|
1638
1640
|
DEFAULT_RESIDENT_INVOKE_TIMEOUT_MS: () => DEFAULT_RESIDENT_INVOKE_TIMEOUT_MS,
|
|
1639
1641
|
DaytonaInstance: () => DaytonaInstance,
|
|
1640
1642
|
DaytonaProvider: () => DaytonaProvider,
|
|
@@ -1790,7 +1792,10 @@ __export(index_exports, {
|
|
|
1790
1792
|
buildGrepResultsDict: () => buildGrepResultsDict,
|
|
1791
1793
|
buildHandlerCommand: () => buildHandlerCommand,
|
|
1792
1794
|
buildInput: () => buildInput,
|
|
1795
|
+
buildModelConfig: () => buildModelConfig,
|
|
1796
|
+
buildModelEmbeddingsConfig: () => buildModelEmbeddingsConfig,
|
|
1793
1797
|
buildModelLlmConfig: () => buildModelLlmConfig,
|
|
1798
|
+
buildModelSttConfig: () => buildModelSttConfig,
|
|
1794
1799
|
buildNamedVolumeName: () => buildNamedVolumeName,
|
|
1795
1800
|
buildRemotePackDirectoryCommand: () => buildRemotePackDirectoryCommand,
|
|
1796
1801
|
buildSandboxMetadataEnv: () => buildSandboxMetadataEnv,
|
|
@@ -1811,6 +1816,7 @@ __export(index_exports, {
|
|
|
1811
1816
|
compileSandboxPlugin: () => compileSandboxPlugin,
|
|
1812
1817
|
compileWorkflow: () => compileWorkflow,
|
|
1813
1818
|
computeSandboxName: () => computeSandboxName,
|
|
1819
|
+
configureCollectionSync: () => configureCollectionSync,
|
|
1814
1820
|
configureCoordinationLeaseStore: () => configureCoordinationLeaseStore,
|
|
1815
1821
|
configurePluginCatalogSync: () => configurePluginCatalogSync,
|
|
1816
1822
|
configureStores: () => configureStores,
|
|
@@ -1988,6 +1994,7 @@ __export(index_exports, {
|
|
|
1988
1994
|
projectRoomPlugin: () => projectRoomPlugin,
|
|
1989
1995
|
projectTaskAdmissionNotifier: () => projectTaskAdmissionNotifier,
|
|
1990
1996
|
provisionSandboxOpenClient: () => provisionSandboxOpenClient,
|
|
1997
|
+
publishCollectionChanged: () => publishCollectionChanged,
|
|
1991
1998
|
publishPluginCatalogChanged: () => publishPluginCatalogChanged,
|
|
1992
1999
|
queueLatticeManager: () => queueLatticeManager,
|
|
1993
2000
|
readLoopBreakerConfig: () => readLoopBreakerConfig,
|
|
@@ -2281,9 +2288,6 @@ var ModelLattice = class extends import_chat_models.BaseChatModel {
|
|
|
2281
2288
|
}
|
|
2282
2289
|
};
|
|
2283
2290
|
|
|
2284
|
-
// src/model_lattice/ModelLatticeManager.ts
|
|
2285
|
-
var import_protocols10 = require("@axiom-lattice/protocols");
|
|
2286
|
-
|
|
2287
2291
|
// src/store_lattice/StoreLatticeManager.ts
|
|
2288
2292
|
init_BaseLatticeManager();
|
|
2289
2293
|
|
|
@@ -3883,6 +3887,9 @@ var InMemoryModelProviderStore = class {
|
|
|
3883
3887
|
// explicit flag marks one.
|
|
3884
3888
|
stale: model.stale ?? false,
|
|
3885
3889
|
extra: carried && Object.keys(carried).length > 0 ? carried : void 0,
|
|
3890
|
+
// Same rule as `extra`: an omitted kind keeps the stored one, and a new
|
|
3891
|
+
// row — which discovery creates without a kind — starts as chat.
|
|
3892
|
+
kind: model.kind ?? existing?.kind ?? "chat",
|
|
3886
3893
|
isDefault: model.isDefault ?? (namesDefault ? false : existing?.isDefault) ?? false,
|
|
3887
3894
|
discoveredAt: now
|
|
3888
3895
|
};
|
|
@@ -7941,7 +7948,136 @@ var SimpleMemoryVectorStore = class extends import_vectorstores.VectorStore {
|
|
|
7941
7948
|
};
|
|
7942
7949
|
|
|
7943
7950
|
// src/embeddings_lattice/EmbeddingsLatticeManager.ts
|
|
7951
|
+
var import_openai2 = require("@langchain/openai");
|
|
7944
7952
|
init_BaseLatticeManager();
|
|
7953
|
+
|
|
7954
|
+
// src/model_lattice/buildModelLlmConfig.ts
|
|
7955
|
+
var ALLOWED_LLM_PROVIDERS = /* @__PURE__ */ new Set(["openai"]);
|
|
7956
|
+
var UnsupportedModelProviderError = class extends Error {
|
|
7957
|
+
constructor(llmProvider) {
|
|
7958
|
+
super(`Unsupported LLM provider: ${llmProvider}`);
|
|
7959
|
+
this.llmProvider = llmProvider;
|
|
7960
|
+
this.code = "UNSUPPORTED_PROTOCOL";
|
|
7961
|
+
this.name = "UnsupportedModelProviderError";
|
|
7962
|
+
}
|
|
7963
|
+
};
|
|
7964
|
+
var DEFAULT_MODEL_EXTRA = {
|
|
7965
|
+
disableThinking: true
|
|
7966
|
+
};
|
|
7967
|
+
function buildModelLlmConfig(provider2, model) {
|
|
7968
|
+
if (!ALLOWED_LLM_PROVIDERS.has(provider2.llmProvider)) {
|
|
7969
|
+
throw new UnsupportedModelProviderError(provider2.llmProvider);
|
|
7970
|
+
}
|
|
7971
|
+
const extra = { ...model.extra ?? {} };
|
|
7972
|
+
delete extra.apiKeyEnvName;
|
|
7973
|
+
const disableThinking = extra.disableThinking === true;
|
|
7974
|
+
delete extra.disableThinking;
|
|
7975
|
+
if (disableThinking) {
|
|
7976
|
+
extra.modelKwargs = {
|
|
7977
|
+
enable_thinking: false,
|
|
7978
|
+
thinking: { type: "disabled" },
|
|
7979
|
+
...extra.modelKwargs ?? {}
|
|
7980
|
+
};
|
|
7981
|
+
}
|
|
7982
|
+
return {
|
|
7983
|
+
...extra,
|
|
7984
|
+
provider: provider2.llmProvider,
|
|
7985
|
+
model: model.modelId,
|
|
7986
|
+
displayName: model.displayName ?? model.modelId,
|
|
7987
|
+
streaming: true,
|
|
7988
|
+
apiKey: provider2.apiKey,
|
|
7989
|
+
// A provider without a key talks to an upstream that needs no
|
|
7990
|
+
// credentials. Saying so explicitly keeps `initChatModel` from falling
|
|
7991
|
+
// back to `process.env[...]` and handing the gateway's own deployment key
|
|
7992
|
+
// to the tenant's host.
|
|
7993
|
+
noAuth: !provider2.apiKey,
|
|
7994
|
+
baseURL: provider2.baseURL,
|
|
7995
|
+
// Chat Completions and the Responses API are different routes with
|
|
7996
|
+
// different request fields; without this the gateway would post
|
|
7997
|
+
// `messages` to an endpoint expecting `input`.
|
|
7998
|
+
...provider2.apiStyle === "responses" ? { useResponsesApi: true } : {}
|
|
7999
|
+
};
|
|
8000
|
+
}
|
|
8001
|
+
|
|
8002
|
+
// src/model_lattice/buildModelConfig.ts
|
|
8003
|
+
function numberOrUndefined(value) {
|
|
8004
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8005
|
+
}
|
|
8006
|
+
function buildModelEmbeddingsConfig(provider2, model) {
|
|
8007
|
+
const extra = { ...model.extra ?? {} };
|
|
8008
|
+
delete extra.apiKeyEnvName;
|
|
8009
|
+
const encodingFormat = extra.encodingFormat === "float" || extra.encodingFormat === "base64" ? extra.encodingFormat : void 0;
|
|
8010
|
+
return {
|
|
8011
|
+
...extra,
|
|
8012
|
+
model: model.modelId,
|
|
8013
|
+
baseURL: provider2.baseURL,
|
|
8014
|
+
apiKey: provider2.apiKey || "EMPTY",
|
|
8015
|
+
dimensions: numberOrUndefined(extra.dimensions),
|
|
8016
|
+
timeout: numberOrUndefined(extra.timeout),
|
|
8017
|
+
batchSize: numberOrUndefined(extra.batchSize),
|
|
8018
|
+
encodingFormat
|
|
8019
|
+
};
|
|
8020
|
+
}
|
|
8021
|
+
function buildModelSttConfig(provider2, model) {
|
|
8022
|
+
const extra = { ...model.extra ?? {} };
|
|
8023
|
+
delete extra.apiKeyEnvName;
|
|
8024
|
+
return {
|
|
8025
|
+
...extra,
|
|
8026
|
+
apiMode: extra.apiMode === "chat" ? "chat" : "whisper",
|
|
8027
|
+
model: model.modelId,
|
|
8028
|
+
// Placeholder for the same reason as embeddings: `STTModelLattice` falls
|
|
8029
|
+
// back to `process.env.OPENAI_API_KEY` when this is empty.
|
|
8030
|
+
apiKey: provider2.apiKey || "EMPTY",
|
|
8031
|
+
baseURL: provider2.baseURL
|
|
8032
|
+
};
|
|
8033
|
+
}
|
|
8034
|
+
function buildModelConfig(provider2, model) {
|
|
8035
|
+
switch (model.kind) {
|
|
8036
|
+
case "embedding":
|
|
8037
|
+
return {
|
|
8038
|
+
kind: "embedding",
|
|
8039
|
+
config: buildModelEmbeddingsConfig(provider2, model)
|
|
8040
|
+
};
|
|
8041
|
+
case "asr":
|
|
8042
|
+
return { kind: "asr", config: buildModelSttConfig(provider2, model) };
|
|
8043
|
+
case "chat":
|
|
8044
|
+
default:
|
|
8045
|
+
return { kind: "chat", config: buildModelLlmConfig(provider2, model) };
|
|
8046
|
+
}
|
|
8047
|
+
}
|
|
8048
|
+
|
|
8049
|
+
// src/model_lattice/loadTenantModelRow.ts
|
|
8050
|
+
var import_protocols10 = require("@axiom-lattice/protocols");
|
|
8051
|
+
async function loadTenantModelRow(tenantId2, key5) {
|
|
8052
|
+
try {
|
|
8053
|
+
const { store } = getStoreLattice("default", "modelProvider");
|
|
8054
|
+
const parsed = (0, import_protocols10.parseModelKey)(key5);
|
|
8055
|
+
if (!parsed) {
|
|
8056
|
+
return void 0;
|
|
8057
|
+
}
|
|
8058
|
+
const provider2 = await store.getProviderById(tenantId2, parsed.providerId);
|
|
8059
|
+
if (!provider2 || !provider2.enabled) {
|
|
8060
|
+
return void 0;
|
|
8061
|
+
}
|
|
8062
|
+
const model = await store.getModel(
|
|
8063
|
+
tenantId2,
|
|
8064
|
+
parsed.providerId,
|
|
8065
|
+
parsed.modelId
|
|
8066
|
+
);
|
|
8067
|
+
if (!model || !model.enabled) {
|
|
8068
|
+
return void 0;
|
|
8069
|
+
}
|
|
8070
|
+
return { provider: provider2, model };
|
|
8071
|
+
} catch (error) {
|
|
8072
|
+
console.error(
|
|
8073
|
+
`[model_lattice] Failed to load model "${key5}" for tenant "${tenantId2}":`,
|
|
8074
|
+
error
|
|
8075
|
+
);
|
|
8076
|
+
return void 0;
|
|
8077
|
+
}
|
|
8078
|
+
}
|
|
8079
|
+
|
|
8080
|
+
// src/embeddings_lattice/EmbeddingsLatticeManager.ts
|
|
7945
8081
|
var EmbeddingsLatticeManager = class _EmbeddingsLatticeManager extends BaseLatticeManager {
|
|
7946
8082
|
/**
|
|
7947
8083
|
* Get EmbeddingsLatticeManager singleton instance
|
|
@@ -7973,6 +8109,37 @@ var EmbeddingsLatticeManager = class _EmbeddingsLatticeManager extends BaseLatti
|
|
|
7973
8109
|
};
|
|
7974
8110
|
this.register(key5, embeddingsLattice);
|
|
7975
8111
|
}
|
|
8112
|
+
/**
|
|
8113
|
+
* Materialise a tenant embedding model that this process has never seen.
|
|
8114
|
+
*
|
|
8115
|
+
* Called by `BaseLatticeManager` on a registry miss. Only `kind: "embedding"`
|
|
8116
|
+
* rows are accepted: a chat or ASR model key must resolve to nothing here, so
|
|
8117
|
+
* a caller asking for an embedding client can never silently get the wrong
|
|
8118
|
+
* kind of model.
|
|
8119
|
+
*
|
|
8120
|
+
* @param tenantId Tenant scope
|
|
8121
|
+
* @param key `${providerId}/${modelId}`
|
|
8122
|
+
*/
|
|
8123
|
+
async loadItemFromStore(tenantId2, key5) {
|
|
8124
|
+
const row = await loadTenantModelRow(tenantId2, key5);
|
|
8125
|
+
if (!row || row.model.kind !== "embedding") {
|
|
8126
|
+
return void 0;
|
|
8127
|
+
}
|
|
8128
|
+
const config = buildModelEmbeddingsConfig(row.provider, row.model);
|
|
8129
|
+
return {
|
|
8130
|
+
key: key5,
|
|
8131
|
+
client: new import_openai2.OpenAIEmbeddings({
|
|
8132
|
+
model: config.model,
|
|
8133
|
+
apiKey: config.apiKey,
|
|
8134
|
+
dimensions: config.dimensions,
|
|
8135
|
+
timeout: config.timeout,
|
|
8136
|
+
batchSize: config.batchSize,
|
|
8137
|
+
encodingFormat: config.encodingFormat,
|
|
8138
|
+
configuration: { baseURL: config.baseURL }
|
|
8139
|
+
}),
|
|
8140
|
+
label: row.model.displayName ?? row.model.modelId
|
|
8141
|
+
};
|
|
8142
|
+
}
|
|
7976
8143
|
/**
|
|
7977
8144
|
* Get all registered embeddings as { key, label } info list
|
|
7978
8145
|
*/
|
|
@@ -7990,6 +8157,53 @@ var EmbeddingsLatticeManager = class _EmbeddingsLatticeManager extends BaseLatti
|
|
|
7990
8157
|
}
|
|
7991
8158
|
return embeddingsLattice;
|
|
7992
8159
|
}
|
|
8160
|
+
/**
|
|
8161
|
+
* Drop this replica's cached embedding clients for one provider.
|
|
8162
|
+
*
|
|
8163
|
+
* The provider's config (apiKey, baseURL, model `extra`) is baked into the
|
|
8164
|
+
* client at construction, and a resolved entry never re-reads the store. So a
|
|
8165
|
+
* model-provider change reaches this replica only if the entry is evicted
|
|
8166
|
+
* first — the same rule `ModelLatticeManager.evictProviderCache` applies to
|
|
8167
|
+
* chat models, and the same keys the model-provider outbox event covers.
|
|
8168
|
+
*
|
|
8169
|
+
* Unlike the chat manager this deliberately leaves the `"default"` key alone:
|
|
8170
|
+
* here it is a *deployment registration*, not a tenant resolution, so evicting
|
|
8171
|
+
* it would remove the global fallback every tenant relies on.
|
|
8172
|
+
*
|
|
8173
|
+
* @param tenantId Tenant scope
|
|
8174
|
+
* @param providerId Provider whose `${providerId}/` keys are stale
|
|
8175
|
+
*/
|
|
8176
|
+
evictProviderCache(tenantId2, providerId) {
|
|
8177
|
+
if (!providerId) {
|
|
8178
|
+
return;
|
|
8179
|
+
}
|
|
8180
|
+
const prefix = `${providerId}/`;
|
|
8181
|
+
for (const key5 of this.keysByTenant(tenantId2)) {
|
|
8182
|
+
if (key5.startsWith(prefix)) {
|
|
8183
|
+
this.removeWithTenant(tenantId2, key5);
|
|
8184
|
+
}
|
|
8185
|
+
}
|
|
8186
|
+
}
|
|
8187
|
+
/**
|
|
8188
|
+
* Resolve an embeddings client for a tenant, loading a miss from the store.
|
|
8189
|
+
*
|
|
8190
|
+
* Mirrors `resolveModelLatticeForTenant`: the tenant's own model first, then
|
|
8191
|
+
* the deployment namespace, which is where boot-time registrations live.
|
|
8192
|
+
* Returns `undefined` rather than throwing, so a caller can fall back.
|
|
8193
|
+
*
|
|
8194
|
+
* @param tenantId Tenant scope
|
|
8195
|
+
* @param key `${providerId}/${modelId}` or a bare deployment key
|
|
8196
|
+
*/
|
|
8197
|
+
async getEmbeddingsClientWithTenant(tenantId2, key5) {
|
|
8198
|
+
const own = await this.getOrLoadWithTenant(tenantId2, key5);
|
|
8199
|
+
if (own) {
|
|
8200
|
+
return own.client;
|
|
8201
|
+
}
|
|
8202
|
+
if (tenantId2 !== "default") {
|
|
8203
|
+
return (await this.getOrLoadWithTenant("default", key5))?.client;
|
|
8204
|
+
}
|
|
8205
|
+
return void 0;
|
|
8206
|
+
}
|
|
7993
8207
|
/**
|
|
7994
8208
|
* Get all Lattices
|
|
7995
8209
|
*/
|
|
@@ -8045,20 +8259,18 @@ var getEmbeddingsClient = (key5) => embeddingsLatticeManager.getEmbeddingsClient
|
|
|
8045
8259
|
// src/vectorstore_lattice/VectorStoreProviderManager.ts
|
|
8046
8260
|
var MemoryVectorStoreProvider = class {
|
|
8047
8261
|
async create(params) {
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
);
|
|
8061
|
-
}
|
|
8262
|
+
const tenantId2 = params.tenantId ?? "default";
|
|
8263
|
+
const embeddings = await embeddingsLatticeManager.getEmbeddingsClientWithTenant(
|
|
8264
|
+
tenantId2,
|
|
8265
|
+
params.embeddingKey
|
|
8266
|
+
) ?? await embeddingsLatticeManager.getEmbeddingsClientWithTenant(
|
|
8267
|
+
tenantId2,
|
|
8268
|
+
"default"
|
|
8269
|
+
);
|
|
8270
|
+
if (!embeddings) {
|
|
8271
|
+
throw new Error(
|
|
8272
|
+
`No embedding model "${params.embeddingKey}" registered for tenant "${tenantId2}", and no deployment default. Configure one in the model provider panel.`
|
|
8273
|
+
);
|
|
8062
8274
|
}
|
|
8063
8275
|
return new SimpleMemoryVectorStore(embeddings);
|
|
8064
8276
|
}
|
|
@@ -12418,42 +12630,6 @@ var InMemoryMenuStore = class {
|
|
|
12418
12630
|
}
|
|
12419
12631
|
};
|
|
12420
12632
|
|
|
12421
|
-
// src/model_lattice/buildModelLlmConfig.ts
|
|
12422
|
-
var ALLOWED_LLM_PROVIDERS = /* @__PURE__ */ new Set(["openai"]);
|
|
12423
|
-
var UnsupportedModelProviderError = class extends Error {
|
|
12424
|
-
constructor(llmProvider) {
|
|
12425
|
-
super(`Unsupported LLM provider: ${llmProvider}`);
|
|
12426
|
-
this.llmProvider = llmProvider;
|
|
12427
|
-
this.code = "UNSUPPORTED_PROTOCOL";
|
|
12428
|
-
this.name = "UnsupportedModelProviderError";
|
|
12429
|
-
}
|
|
12430
|
-
};
|
|
12431
|
-
function buildModelLlmConfig(provider2, model) {
|
|
12432
|
-
if (!ALLOWED_LLM_PROVIDERS.has(provider2.llmProvider)) {
|
|
12433
|
-
throw new UnsupportedModelProviderError(provider2.llmProvider);
|
|
12434
|
-
}
|
|
12435
|
-
const extra = { ...model.extra ?? {} };
|
|
12436
|
-
delete extra.apiKeyEnvName;
|
|
12437
|
-
return {
|
|
12438
|
-
...extra,
|
|
12439
|
-
provider: provider2.llmProvider,
|
|
12440
|
-
model: model.modelId,
|
|
12441
|
-
displayName: model.displayName ?? model.modelId,
|
|
12442
|
-
streaming: true,
|
|
12443
|
-
apiKey: provider2.apiKey,
|
|
12444
|
-
// A provider without a key talks to an upstream that needs no
|
|
12445
|
-
// credentials. Saying so explicitly keeps `initChatModel` from falling
|
|
12446
|
-
// back to `process.env[...]` and handing the gateway's own deployment key
|
|
12447
|
-
// to the tenant's host.
|
|
12448
|
-
noAuth: !provider2.apiKey,
|
|
12449
|
-
baseURL: provider2.baseURL,
|
|
12450
|
-
// Chat Completions and the Responses API are different routes with
|
|
12451
|
-
// different request fields; without this the gateway would post
|
|
12452
|
-
// `messages` to an endpoint expecting `input`.
|
|
12453
|
-
...provider2.apiStyle === "responses" ? { useResponsesApi: true } : {}
|
|
12454
|
-
};
|
|
12455
|
-
}
|
|
12456
|
-
|
|
12457
12633
|
// src/model_lattice/ModelLatticeManager.ts
|
|
12458
12634
|
var DEFAULT_MODEL_KEY = "default";
|
|
12459
12635
|
var TENANT_DEFAULT_MISS_TTL_MS = 3e4;
|
|
@@ -12626,38 +12802,26 @@ var ModelLatticeManager = class _ModelLatticeManager extends BaseLatticeManager
|
|
|
12626
12802
|
* @param key Lattice键名(`${providerId}/${modelId}`)
|
|
12627
12803
|
*/
|
|
12628
12804
|
async loadItemFromStore(tenantId2, key5) {
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12805
|
+
if (key5 === DEFAULT_MODEL_KEY) {
|
|
12806
|
+
try {
|
|
12807
|
+
const { store } = getStoreLattice("default", "modelProvider");
|
|
12632
12808
|
return await this.loadTenantDefault(store, tenantId2);
|
|
12633
|
-
}
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
const provider2 = await store.getProviderById(tenantId2, parsed.providerId);
|
|
12639
|
-
if (!provider2 || !provider2.enabled) {
|
|
12640
|
-
return void 0;
|
|
12641
|
-
}
|
|
12642
|
-
const model = await store.getModel(
|
|
12643
|
-
tenantId2,
|
|
12644
|
-
parsed.providerId,
|
|
12645
|
-
parsed.modelId
|
|
12646
|
-
);
|
|
12647
|
-
if (!model || !model.enabled) {
|
|
12809
|
+
} catch (error) {
|
|
12810
|
+
console.error(
|
|
12811
|
+
`[ModelLatticeManager] Failed to load model "${key5}" for tenant "${tenantId2}":`,
|
|
12812
|
+
error
|
|
12813
|
+
);
|
|
12648
12814
|
return void 0;
|
|
12649
12815
|
}
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
};
|
|
12654
|
-
} catch (error) {
|
|
12655
|
-
console.error(
|
|
12656
|
-
`[ModelLatticeManager] Failed to load model "${key5}" for tenant "${tenantId2}":`,
|
|
12657
|
-
error
|
|
12658
|
-
);
|
|
12816
|
+
}
|
|
12817
|
+
const row = await loadTenantModelRow(tenantId2, key5);
|
|
12818
|
+
if (!row || row.model.kind !== "chat") {
|
|
12659
12819
|
return void 0;
|
|
12660
12820
|
}
|
|
12821
|
+
return {
|
|
12822
|
+
key: key5,
|
|
12823
|
+
client: new ModelLattice(buildModelLlmConfig(row.provider, row.model))
|
|
12824
|
+
};
|
|
12661
12825
|
}
|
|
12662
12826
|
/**
|
|
12663
12827
|
* Forget that a tenant had no default model.
|
|
@@ -12689,7 +12853,9 @@ var ModelLatticeManager = class _ModelLatticeManager extends BaseLatticeManager
|
|
|
12689
12853
|
return void 0;
|
|
12690
12854
|
}
|
|
12691
12855
|
const models = await store.listModels(tenantId2);
|
|
12692
|
-
const marked = models.find(
|
|
12856
|
+
const marked = models.find(
|
|
12857
|
+
(model) => model.isDefault === true && model.kind === "chat"
|
|
12858
|
+
);
|
|
12693
12859
|
if (!marked || !marked.enabled) {
|
|
12694
12860
|
this.tenantDefaultMissAt.set(tenantId2, Date.now());
|
|
12695
12861
|
return void 0;
|
|
@@ -12730,6 +12896,37 @@ var ModelLatticeManager = class _ModelLatticeManager extends BaseLatticeManager
|
|
|
12730
12896
|
removeLatticeWithTenant(tenantId2, key5) {
|
|
12731
12897
|
return this.removeWithTenant(tenantId2, key5);
|
|
12732
12898
|
}
|
|
12899
|
+
/**
|
|
12900
|
+
* 驱逐一个 provider 贡献的缓存,外加本租户已解析的 `default` 哨兵。
|
|
12901
|
+
*
|
|
12902
|
+
* 改了配置(apiKey / baseURL / extra)却还在走旧客户端,根因就是
|
|
12903
|
+
* `BaseLatticeManager.registry` 的**正向条目没有 TTL**:命中一次之后
|
|
12904
|
+
* `loadItemFromStore` 再也不会被调用。驱逐之后,下一次解析会从**共享的**
|
|
12905
|
+
* store 重新物化 —— 这正是多副本「正确性不靠副本之间同步、靠共享库」那条不变式。
|
|
12906
|
+
*
|
|
12907
|
+
* 只驱逐、不重注册:`loadItemFromStore` 已经知道怎么按 key 物化,删掉就够,
|
|
12908
|
+
* 而且这里不需要读库。
|
|
12909
|
+
*
|
|
12910
|
+
* 为什么连哨兵一起删:`default` 是本租户默认模型的**解析结果**,同样被永久缓存。
|
|
12911
|
+
* 不删它,租户换了默认模型就得重启才生效(单副本也一样)。删掉只让下一次解析
|
|
12912
|
+
* 多读一次库。
|
|
12913
|
+
*
|
|
12914
|
+
* @param tenantId 租户ID
|
|
12915
|
+
* @param providerId 该 provider 的 `${providerId}/` 前缀会被清掉;省略则只清
|
|
12916
|
+
* 哨兵(例如只换了默认模型)
|
|
12917
|
+
*/
|
|
12918
|
+
evictProviderCache(tenantId2, providerId) {
|
|
12919
|
+
if (providerId) {
|
|
12920
|
+
const prefix = `${providerId}/`;
|
|
12921
|
+
for (const key5 of this.keysByTenant(tenantId2)) {
|
|
12922
|
+
if (key5.startsWith(prefix)) {
|
|
12923
|
+
this.removeWithTenant(tenantId2, key5);
|
|
12924
|
+
}
|
|
12925
|
+
}
|
|
12926
|
+
}
|
|
12927
|
+
this.removeWithTenant(tenantId2, DEFAULT_MODEL_KEY);
|
|
12928
|
+
this.forgetTenantDefaultMiss(tenantId2);
|
|
12929
|
+
}
|
|
12733
12930
|
};
|
|
12734
12931
|
var modelLatticeManager = ModelLatticeManager.getInstance();
|
|
12735
12932
|
var registerModelLattice = (key5, config) => modelLatticeManager.registerLattice(key5, config);
|
|
@@ -17732,7 +17929,7 @@ async function describeImage(options) {
|
|
|
17732
17929
|
init_BaseLatticeManager();
|
|
17733
17930
|
|
|
17734
17931
|
// src/stt_model_lattice/STTModelLattice.ts
|
|
17735
|
-
var
|
|
17932
|
+
var import_openai3 = require("@langchain/openai");
|
|
17736
17933
|
var STTModelLattice = class {
|
|
17737
17934
|
constructor(key5, config) {
|
|
17738
17935
|
this.key = key5;
|
|
@@ -17742,7 +17939,7 @@ var STTModelLattice = class {
|
|
|
17742
17939
|
if (!apiKey) {
|
|
17743
17940
|
throw new Error("No API key configured for STT. Set apiKey, apiKeyEnvName, or OPENAI_API_KEY.");
|
|
17744
17941
|
}
|
|
17745
|
-
this.openaiClient = new
|
|
17942
|
+
this.openaiClient = new import_openai3.OpenAIClient({
|
|
17746
17943
|
apiKey,
|
|
17747
17944
|
baseURL: config.baseURL,
|
|
17748
17945
|
timeout: config.timeout || 3e4
|
|
@@ -17764,7 +17961,7 @@ var STTModelLattice = class {
|
|
|
17764
17961
|
*/
|
|
17765
17962
|
async transcribeViaWhisper(audio, format) {
|
|
17766
17963
|
const mimeType = formatToMimeType(format);
|
|
17767
|
-
const file = typeof File !== "undefined" ? new File([audio], `audio.${format}`, { type: mimeType }) : await (0,
|
|
17964
|
+
const file = typeof File !== "undefined" ? new File([audio], `audio.${format}`, { type: mimeType }) : await (0, import_openai3.toFile)(audio, `audio.${format}`, { type: mimeType });
|
|
17768
17965
|
const extra = this.config.extra || {};
|
|
17769
17966
|
const response = await this.openaiClient.audio.transcriptions.create({
|
|
17770
17967
|
file,
|
|
@@ -17858,6 +18055,26 @@ var STTModelLatticeManager = class _STTModelLatticeManager extends BaseLatticeMa
|
|
|
17858
18055
|
};
|
|
17859
18056
|
this.register(key5, sttLattice);
|
|
17860
18057
|
}
|
|
18058
|
+
/**
|
|
18059
|
+
* Materialise a tenant ASR model that this process has never seen.
|
|
18060
|
+
*
|
|
18061
|
+
* Only `kind: "asr"` rows are accepted, mirroring the embedding loader: a
|
|
18062
|
+
* chat key must never resolve to a speech client.
|
|
18063
|
+
*/
|
|
18064
|
+
async loadItemFromStore(tenantId2, key5) {
|
|
18065
|
+
const row = await loadTenantModelRow(tenantId2, key5);
|
|
18066
|
+
if (!row || row.model.kind !== "asr") {
|
|
18067
|
+
return void 0;
|
|
18068
|
+
}
|
|
18069
|
+
const config = buildModelSttConfig(row.provider, row.model);
|
|
18070
|
+
const client = new STTModelLattice(key5, config);
|
|
18071
|
+
return {
|
|
18072
|
+
key: key5,
|
|
18073
|
+
client,
|
|
18074
|
+
config,
|
|
18075
|
+
label: row.model.displayName ?? row.model.modelId
|
|
18076
|
+
};
|
|
18077
|
+
}
|
|
17861
18078
|
/**
|
|
17862
18079
|
* Get an STT model lattice by key.
|
|
17863
18080
|
*/
|
|
@@ -17889,6 +18106,49 @@ var STTModelLatticeManager = class _STTModelLatticeManager extends BaseLatticeMa
|
|
|
17889
18106
|
}
|
|
17890
18107
|
return lattice.client;
|
|
17891
18108
|
}
|
|
18109
|
+
/**
|
|
18110
|
+
* Resolve an STT client for a tenant, loading a miss from the store.
|
|
18111
|
+
*
|
|
18112
|
+
* The synchronous `getSTTClientWithTenant` stays as it is for
|
|
18113
|
+
* deployment-registered models; this one is for the tenant catalog, where the
|
|
18114
|
+
* model may exist only in the shared store. Same order as every other
|
|
18115
|
+
* resolver: tenant first, then the deployment namespace.
|
|
18116
|
+
*
|
|
18117
|
+
* @param tenantId Tenant scope
|
|
18118
|
+
* @param key `${providerId}/${modelId}` or a bare deployment key
|
|
18119
|
+
*/
|
|
18120
|
+
async getSTTClientWithTenantAsync(tenantId2, key5) {
|
|
18121
|
+
const own = await this.getOrLoadWithTenant(tenantId2, key5);
|
|
18122
|
+
if (own) {
|
|
18123
|
+
return own.client;
|
|
18124
|
+
}
|
|
18125
|
+
if (tenantId2 !== "default") {
|
|
18126
|
+
return (await this.getOrLoadWithTenant("default", key5))?.client;
|
|
18127
|
+
}
|
|
18128
|
+
return void 0;
|
|
18129
|
+
}
|
|
18130
|
+
/**
|
|
18131
|
+
* Drop this replica's cached STT clients for one provider.
|
|
18132
|
+
*
|
|
18133
|
+
* Same rule as the chat and embeddings managers: the provider's key and
|
|
18134
|
+
* address are baked into the client at construction, so a model-provider
|
|
18135
|
+
* change only reaches this replica if the cached entry is evicted first. The
|
|
18136
|
+
* deployment's `"default"` registration is left alone.
|
|
18137
|
+
*
|
|
18138
|
+
* @param tenantId Tenant scope
|
|
18139
|
+
* @param providerId Provider whose `${providerId}/` keys are stale
|
|
18140
|
+
*/
|
|
18141
|
+
evictProviderCache(tenantId2, providerId) {
|
|
18142
|
+
if (!providerId) {
|
|
18143
|
+
return;
|
|
18144
|
+
}
|
|
18145
|
+
const prefix = `${providerId}/`;
|
|
18146
|
+
for (const key5 of this.keysByTenant(tenantId2)) {
|
|
18147
|
+
if (key5.startsWith(prefix)) {
|
|
18148
|
+
this.removeWithTenant(tenantId2, key5);
|
|
18149
|
+
}
|
|
18150
|
+
}
|
|
18151
|
+
}
|
|
17892
18152
|
/**
|
|
17893
18153
|
* Get all registered STT models as info list.
|
|
17894
18154
|
*/
|
|
@@ -17927,13 +18187,16 @@ var getSTTClientWithTenant = (tenantId2, key5) => sttModelLatticeManager.getSTTC
|
|
|
17927
18187
|
|
|
17928
18188
|
// src/deep_agent_new/backends/transcribeAudio.ts
|
|
17929
18189
|
async function transcribeAudio(options) {
|
|
17930
|
-
const { audioBuffer, format } = options;
|
|
17931
|
-
|
|
18190
|
+
const { audioBuffer, format, tenantId: tenantId2 = "default", modelKey = "default" } = options;
|
|
18191
|
+
const client = await sttModelLatticeManager.getSTTClientWithTenantAsync(
|
|
18192
|
+
tenantId2,
|
|
18193
|
+
modelKey
|
|
18194
|
+
);
|
|
18195
|
+
if (!client) {
|
|
17932
18196
|
throw new Error(
|
|
17933
|
-
|
|
18197
|
+
`No STT model "${modelKey}" registered for tenant "${tenantId2}". Configure one in the model provider panel, or register a deployment default.`
|
|
17934
18198
|
);
|
|
17935
18199
|
}
|
|
17936
|
-
const client = sttModelLatticeManager.getSTTClient("default");
|
|
17937
18200
|
return await client.transcribe(audioBuffer, format);
|
|
17938
18201
|
}
|
|
17939
18202
|
|
|
@@ -18108,7 +18371,13 @@ The current backend does not support binary reading, unable to process audio.`;
|
|
|
18108
18371
|
${sizeWarning}`;
|
|
18109
18372
|
}
|
|
18110
18373
|
const format = detectAudioFormat(file_path);
|
|
18111
|
-
const result = await transcribeAudio({
|
|
18374
|
+
const result = await transcribeAudio({
|
|
18375
|
+
audioBuffer: buffer2,
|
|
18376
|
+
format,
|
|
18377
|
+
// Tenant first; the deployment's `"default"` registration is the
|
|
18378
|
+
// fallback, so existing deployments keep working unchanged.
|
|
18379
|
+
tenantId: runConfig?.tenantId || "default"
|
|
18380
|
+
});
|
|
18112
18381
|
let output = `[Audio] ${file_path} (${format}, ${(buffer2.length / 1024).toFixed(1)}KB)`;
|
|
18113
18382
|
if (result.confidence !== void 0) {
|
|
18114
18383
|
output += `
|
|
@@ -33992,6 +34261,28 @@ var VectorStoreLatticeManager = class _VectorStoreLatticeManager extends BaseLat
|
|
|
33992
34261
|
const vectorStoreLattice = this.getVectorStoreLattice(key5);
|
|
33993
34262
|
return vectorStoreLattice.client;
|
|
33994
34263
|
}
|
|
34264
|
+
/**
|
|
34265
|
+
* Drop every cached vector store belonging to a tenant.
|
|
34266
|
+
*
|
|
34267
|
+
* Stores are registered through the legacy key-only API with a
|
|
34268
|
+
* `${tenantId}:${collection}` key name, so they all live under the `default`
|
|
34269
|
+
* namespace. Matching has to be on the key name, not on the lattice's tenant
|
|
34270
|
+
* prefix — `clearByTenant` would find nothing here.
|
|
34271
|
+
*
|
|
34272
|
+
* The stores are rebuilt lazily on next use. Evicting is required whenever the
|
|
34273
|
+
* embedding client they were built with may have changed: a collection's
|
|
34274
|
+
* `embeddingKey`, or the model provider behind that key.
|
|
34275
|
+
*
|
|
34276
|
+
* @param tenantId Tenant whose vector stores to drop
|
|
34277
|
+
*/
|
|
34278
|
+
clearTenantVectorStores(tenantId2) {
|
|
34279
|
+
const prefix = `${tenantId2}:`;
|
|
34280
|
+
for (const lattice of this.getAllLattices()) {
|
|
34281
|
+
if (lattice.key.startsWith(prefix)) {
|
|
34282
|
+
this.removeLattice(lattice.key);
|
|
34283
|
+
}
|
|
34284
|
+
}
|
|
34285
|
+
}
|
|
33995
34286
|
};
|
|
33996
34287
|
var vectorStoreLatticeManager = VectorStoreLatticeManager.getInstance();
|
|
33997
34288
|
var registerVectorStoreLattice = (key5, vectorStore) => vectorStoreLatticeManager.registerLattice(key5, vectorStore);
|
|
@@ -34685,6 +34976,26 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
34685
34976
|
};
|
|
34686
34977
|
var skillLatticeManager = SkillLatticeManager.getInstance();
|
|
34687
34978
|
|
|
34979
|
+
// src/services/collectionSync.ts
|
|
34980
|
+
var COLLECTION_CHANGED_TOPIC = "collection-changed";
|
|
34981
|
+
var outbox;
|
|
34982
|
+
var owner = "unknown";
|
|
34983
|
+
function configureCollectionSync(next) {
|
|
34984
|
+
outbox = next?.outbox;
|
|
34985
|
+
owner = next?.owner ?? "unknown";
|
|
34986
|
+
}
|
|
34987
|
+
async function publishCollectionChanged(tenantId2) {
|
|
34988
|
+
if (!outbox || !tenantId2) return;
|
|
34989
|
+
try {
|
|
34990
|
+
await outbox.append({
|
|
34991
|
+
topic: COLLECTION_CHANGED_TOPIC,
|
|
34992
|
+
payload: { tenantId: tenantId2 },
|
|
34993
|
+
originReplicaId: owner
|
|
34994
|
+
});
|
|
34995
|
+
} catch {
|
|
34996
|
+
}
|
|
34997
|
+
}
|
|
34998
|
+
|
|
34688
34999
|
// src/collection_lattice/CollectionLatticeManager.ts
|
|
34689
35000
|
var CollectionLatticeManager = class _CollectionLatticeManager {
|
|
34690
35001
|
static getInstance() {
|
|
@@ -34697,8 +35008,25 @@ var CollectionLatticeManager = class _CollectionLatticeManager {
|
|
|
34697
35008
|
const lattice = storeLatticeManager.getStoreLattice("default", "collection");
|
|
34698
35009
|
return lattice.store;
|
|
34699
35010
|
}
|
|
35011
|
+
/**
|
|
35012
|
+
* Drop this replica's cached vector stores for the tenant, and tell peers.
|
|
35013
|
+
*
|
|
35014
|
+
* A vector store is constructed with one embedding client, so any collection
|
|
35015
|
+
* write can invalidate it — creating, renaming, changing `embeddingKey` or
|
|
35016
|
+
* deleting. Clearing the whole tenant is deliberate: the cache is small, and
|
|
35017
|
+
* a per-store match would still miss two collections sharing one client.
|
|
35018
|
+
*
|
|
35019
|
+
* Locally this must happen here because the outbox poller skips events this
|
|
35020
|
+
* replica published itself.
|
|
35021
|
+
*/
|
|
35022
|
+
invalidateVectorStores(tenantId2) {
|
|
35023
|
+
vectorStoreLatticeManager.clearTenantVectorStores(tenantId2);
|
|
35024
|
+
void publishCollectionChanged(tenantId2);
|
|
35025
|
+
}
|
|
34700
35026
|
async registerCollection(tenantId2, data) {
|
|
34701
|
-
|
|
35027
|
+
const collection = await this.getStore().createCollection(tenantId2, data);
|
|
35028
|
+
this.invalidateVectorStores(tenantId2);
|
|
35029
|
+
return collection;
|
|
34702
35030
|
}
|
|
34703
35031
|
async getCollection(tenantId2, name) {
|
|
34704
35032
|
return this.getStore().getCollectionByName(tenantId2, name);
|
|
@@ -34707,10 +35035,18 @@ var CollectionLatticeManager = class _CollectionLatticeManager {
|
|
|
34707
35035
|
return this.getStore().getAllCollections(tenantId2);
|
|
34708
35036
|
}
|
|
34709
35037
|
async removeCollection(tenantId2, name) {
|
|
34710
|
-
|
|
35038
|
+
const removed = await this.getStore().deleteCollection(tenantId2, name);
|
|
35039
|
+
if (removed) {
|
|
35040
|
+
this.invalidateVectorStores(tenantId2);
|
|
35041
|
+
}
|
|
35042
|
+
return removed;
|
|
34711
35043
|
}
|
|
34712
35044
|
async updateCollection(tenantId2, name, updates) {
|
|
34713
|
-
|
|
35045
|
+
const updated = await this.getStore().updateCollection(tenantId2, name, updates);
|
|
35046
|
+
if (updated) {
|
|
35047
|
+
this.invalidateVectorStores(tenantId2);
|
|
35048
|
+
}
|
|
35049
|
+
return updated;
|
|
34714
35050
|
}
|
|
34715
35051
|
};
|
|
34716
35052
|
var collectionLatticeManager = CollectionLatticeManager.getInstance();
|
|
@@ -34734,7 +35070,11 @@ async function getOrCreateCollectionVectorStore(name, embeddingKey, tenantId2, p
|
|
|
34734
35070
|
const initialization = (async () => {
|
|
34735
35071
|
const provider2 = vectorStoreProviderManager.getProvider(providerKey);
|
|
34736
35072
|
const tableName = buildTableName(tenantId2, name);
|
|
34737
|
-
const vectorStore = await provider2.create({
|
|
35073
|
+
const vectorStore = await provider2.create({
|
|
35074
|
+
tableName,
|
|
35075
|
+
embeddingKey,
|
|
35076
|
+
tenantId: tenantId2
|
|
35077
|
+
});
|
|
34738
35078
|
vectorStoreLatticeManager.registerLattice(storeKey, vectorStore);
|
|
34739
35079
|
return vectorStore;
|
|
34740
35080
|
})();
|
|
@@ -39136,8 +39476,8 @@ var TaskLifecycleNotifier = class {
|
|
|
39136
39476
|
this.tails = /* @__PURE__ */ new Map();
|
|
39137
39477
|
}
|
|
39138
39478
|
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
39139
|
-
setOutbox(
|
|
39140
|
-
this.outbox =
|
|
39479
|
+
setOutbox(outbox3) {
|
|
39480
|
+
this.outbox = outbox3;
|
|
39141
39481
|
}
|
|
39142
39482
|
/**
|
|
39143
39483
|
* Registers an async lifecycle listener.
|
|
@@ -39243,8 +39583,8 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
39243
39583
|
this.listenerTimeoutMs = timeout;
|
|
39244
39584
|
}
|
|
39245
39585
|
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
39246
|
-
setOutbox(
|
|
39247
|
-
this.outbox =
|
|
39586
|
+
setOutbox(outbox3) {
|
|
39587
|
+
this.outbox = outbox3;
|
|
39248
39588
|
}
|
|
39249
39589
|
/**
|
|
39250
39590
|
* Registers a Project task admission listener.
|
|
@@ -40091,9 +40431,9 @@ var BELIEF_OWNER_WRITE_ATTEMPTS = 3;
|
|
|
40091
40431
|
function isWellFormedImpact(impact) {
|
|
40092
40432
|
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(impact.key) && Number.isInteger(impact.after) && impact.after >= 0 && impact.after <= 100 && impact.basis.trim().length > 0 && impact.basis.length <= 1e3 && !/[\r\n]/.test(impact.basis);
|
|
40093
40433
|
}
|
|
40094
|
-
async function applyBeliefImpacts(taskStore,
|
|
40095
|
-
if (impacts.length === 0) return { description:
|
|
40096
|
-
let current =
|
|
40434
|
+
async function applyBeliefImpacts(taskStore, owner3, impacts) {
|
|
40435
|
+
if (impacts.length === 0) return { description: owner3.description ?? "" };
|
|
40436
|
+
let current = owner3;
|
|
40097
40437
|
for (let attempt = 0; attempt < BELIEF_OWNER_WRITE_ATTEMPTS; attempt += 1) {
|
|
40098
40438
|
const parsed = (0, import_protocols32.parseTaskBeliefState)(current.description ?? "");
|
|
40099
40439
|
const existingTable = parsed.success;
|
|
@@ -40222,14 +40562,14 @@ function sameBeliefOwner(left, right) {
|
|
|
40222
40562
|
function sameBeliefOwnerIdentity(left, right) {
|
|
40223
40563
|
return canonicalJson({ ...left, beliefState: void 0 }) === canonicalJson({ ...right, beliefState: void 0 });
|
|
40224
40564
|
}
|
|
40225
|
-
function canonicalBeliefOwner(
|
|
40565
|
+
function canonicalBeliefOwner(owner3) {
|
|
40226
40566
|
const beliefState = {
|
|
40227
|
-
entries:
|
|
40567
|
+
entries: owner3.beliefState.entries.map((entry) => ({
|
|
40228
40568
|
...entry,
|
|
40229
40569
|
basis: entry.basis.trim().replace(/\s+/g, " ")
|
|
40230
40570
|
})).sort((left, right) => left.key < right.key ? -1 : left.key > right.key ? 1 : 0)
|
|
40231
40571
|
};
|
|
40232
|
-
return { ...
|
|
40572
|
+
return { ...owner3, beliefState };
|
|
40233
40573
|
}
|
|
40234
40574
|
function eventKeyFor(taskId, result, impacts, beliefOwner) {
|
|
40235
40575
|
const base = `belief-impact:${taskId}:${buildBeliefCompletionEventKey(taskId, result, impacts)}`;
|
|
@@ -41600,8 +41940,8 @@ var TaskLifecycleService = class {
|
|
|
41600
41940
|
return { task: existing, parent: parentResult, eventKey, evidence, result, impacts };
|
|
41601
41941
|
}
|
|
41602
41942
|
beliefOwnerSnapshot(task, parent) {
|
|
41603
|
-
const
|
|
41604
|
-
const parsed = (0, import_protocols32.parseTaskBeliefState)(
|
|
41943
|
+
const owner3 = parent?.ownerType === "agent" ? parent : task;
|
|
41944
|
+
const parsed = (0, import_protocols32.parseTaskBeliefState)(owner3.description ?? "");
|
|
41605
41945
|
const beliefState = parsed.success ? parsed.state : { entries: [] };
|
|
41606
41946
|
if (parent?.ownerType === "agent") {
|
|
41607
41947
|
return {
|
|
@@ -43387,8 +43727,8 @@ function createTaskExecutionService(deps) {
|
|
|
43387
43727
|
var import_node_crypto14 = require("crypto");
|
|
43388
43728
|
async function runAsLeader(store, name, fn, options = {}) {
|
|
43389
43729
|
const key5 = `leader:${name}`;
|
|
43390
|
-
const
|
|
43391
|
-
const holder = `${
|
|
43730
|
+
const owner3 = options.owner ?? getReplicaId();
|
|
43731
|
+
const holder = `${owner3}#${(0, import_node_crypto14.randomUUID)()}`;
|
|
43392
43732
|
const ttlMs = options.ttlMs ?? 6e4;
|
|
43393
43733
|
if (!await store.tryAcquire(key5, holder, ttlMs)) return { ran: false };
|
|
43394
43734
|
const heartbeat = setInterval(() => {
|
|
@@ -43406,16 +43746,16 @@ async function runAsLeader(store, name, fn, options = {}) {
|
|
|
43406
43746
|
|
|
43407
43747
|
// src/services/pluginCatalogSync.ts
|
|
43408
43748
|
var PLUGIN_CATALOG_CHANGED_TOPIC = "plugin-catalog-changed";
|
|
43409
|
-
var
|
|
43410
|
-
var
|
|
43749
|
+
var outbox2;
|
|
43750
|
+
var owner2 = "unknown";
|
|
43411
43751
|
function configurePluginCatalogSync(next) {
|
|
43412
|
-
|
|
43413
|
-
|
|
43752
|
+
outbox2 = next?.outbox;
|
|
43753
|
+
owner2 = next?.owner ?? "unknown";
|
|
43414
43754
|
}
|
|
43415
43755
|
async function publishPluginCatalogChanged(tenantId2) {
|
|
43416
|
-
if (!
|
|
43756
|
+
if (!outbox2 || !tenantId2) return;
|
|
43417
43757
|
try {
|
|
43418
|
-
await
|
|
43758
|
+
await outbox2.append({ topic: PLUGIN_CATALOG_CHANGED_TOPIC, payload: { tenantId: tenantId2 }, originReplicaId: owner2 });
|
|
43419
43759
|
} catch {
|
|
43420
43760
|
}
|
|
43421
43761
|
}
|
|
@@ -43601,9 +43941,9 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
43601
43941
|
if (!skillName) continue;
|
|
43602
43942
|
if (await isPluginSkillManagedInSandbox(sandbox, skillName)) {
|
|
43603
43943
|
const enabledDefinition = pluginSkills?.[skillName];
|
|
43604
|
-
const
|
|
43605
|
-
const registered =
|
|
43606
|
-
if (!registered || registered.definition !== enabledDefinition || !
|
|
43944
|
+
const owner3 = pluginSkillOwners?.[skillName];
|
|
43945
|
+
const registered = owner3 && enabledDefinition ? PluginRegistry.getSkillForPlugin(owner3, skillName) : void 0;
|
|
43946
|
+
if (!registered || registered.definition !== enabledDefinition || !owner3 || !await isPluginSkillAuthorizedInSandbox(sandbox, skillName, owner3) || await getPluginSkillManifestVersion(sandbox, skillName) !== enabledDefinition.version) {
|
|
43607
43947
|
continue;
|
|
43608
43948
|
}
|
|
43609
43949
|
}
|
|
@@ -43629,8 +43969,8 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
43629
43969
|
const seenNames = new Set(filteredSkills.map((skill) => skill.name));
|
|
43630
43970
|
try {
|
|
43631
43971
|
for (const [name, definition] of Object.entries(pluginSkills ?? {})) {
|
|
43632
|
-
const
|
|
43633
|
-
const registered =
|
|
43972
|
+
const owner3 = pluginSkillOwners?.[name];
|
|
43973
|
+
const registered = owner3 ? PluginRegistry.getSkillForPlugin(owner3, name) : void 0;
|
|
43634
43974
|
if (!registered || registered.definition !== definition) continue;
|
|
43635
43975
|
const { meta } = parseSkillFrontmatter(definition.content);
|
|
43636
43976
|
if (!meta.name || !meta.description || seenNames.has(meta.name)) continue;
|
|
@@ -43667,24 +44007,24 @@ var import_zod52 = __toESM(require("zod"));
|
|
|
43667
44007
|
var import_langchain63 = require("langchain");
|
|
43668
44008
|
|
|
43669
44009
|
// src/sandbox_plugin/pluginSkillResolution.ts
|
|
43670
|
-
async function resolveTenantPluginSkill(tenantId2,
|
|
44010
|
+
async function resolveTenantPluginSkill(tenantId2, owner3, skillName) {
|
|
43671
44011
|
try {
|
|
43672
44012
|
const { plugins } = await getSandboxPluginCatalog().ensureLoaded(tenantId2);
|
|
43673
|
-
const plugin = plugins.find((candidate) => candidate.meta.type ===
|
|
44013
|
+
const plugin = plugins.find((candidate) => candidate.meta.type === owner3);
|
|
43674
44014
|
return plugin?.skills?.[skillName];
|
|
43675
44015
|
} catch {
|
|
43676
44016
|
return void 0;
|
|
43677
44017
|
}
|
|
43678
44018
|
}
|
|
43679
|
-
async function resolveEnabledPluginSkill(
|
|
43680
|
-
if (!
|
|
43681
|
-
const registered = PluginRegistry.getSkillForPlugin(
|
|
43682
|
-
if (registered && registered.pluginType ===
|
|
43683
|
-
return { pluginType:
|
|
44019
|
+
async function resolveEnabledPluginSkill(owner3, skillName, enabledDefinition, tenantId2) {
|
|
44020
|
+
if (!owner3 || !enabledDefinition) return void 0;
|
|
44021
|
+
const registered = PluginRegistry.getSkillForPlugin(owner3, skillName);
|
|
44022
|
+
if (registered && registered.pluginType === owner3 && registered.definition === enabledDefinition) {
|
|
44023
|
+
return { pluginType: owner3, definition: enabledDefinition };
|
|
43684
44024
|
}
|
|
43685
44025
|
if (!tenantId2) return void 0;
|
|
43686
|
-
const tenantDefinition = await resolveTenantPluginSkill(tenantId2,
|
|
43687
|
-
return tenantDefinition ? { pluginType:
|
|
44026
|
+
const tenantDefinition = await resolveTenantPluginSkill(tenantId2, owner3, skillName);
|
|
44027
|
+
return tenantDefinition ? { pluginType: owner3, definition: tenantDefinition } : void 0;
|
|
43688
44028
|
}
|
|
43689
44029
|
|
|
43690
44030
|
// src/tool_lattice/skill/load_skill_content.ts
|
|
@@ -43746,10 +44086,10 @@ var createLoadSkillContentTool = (pluginSkills, pluginSkillOwnersOrStaticSelecti
|
|
|
43746
44086
|
return result2;
|
|
43747
44087
|
}
|
|
43748
44088
|
const enabledDefinition = pluginSkills?.[input.skill_name];
|
|
43749
|
-
const
|
|
44089
|
+
const owner3 = pluginSkillOwners?.[input.skill_name];
|
|
43750
44090
|
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
43751
44091
|
const pluginSkill = await resolveEnabledPluginSkill(
|
|
43752
|
-
|
|
44092
|
+
owner3,
|
|
43753
44093
|
input.skill_name,
|
|
43754
44094
|
enabledDefinition,
|
|
43755
44095
|
runConfig.tenantId
|
|
@@ -43856,9 +44196,9 @@ var createLoadSkillResourceTool = (pluginSkills, pluginSkillOwners) => {
|
|
|
43856
44196
|
validateRelativePath(input.resource_path, "resource");
|
|
43857
44197
|
const sandbox = await getSandboxFromExeConfig3(_exe_config);
|
|
43858
44198
|
const definition = pluginSkills?.[input.skill_name];
|
|
43859
|
-
const
|
|
44199
|
+
const owner3 = pluginSkillOwners?.[input.skill_name];
|
|
43860
44200
|
const tenantId2 = _exe_config?.configurable?.runConfig?.tenantId;
|
|
43861
|
-
const resolved = await resolveEnabledPluginSkill(
|
|
44201
|
+
const resolved = await resolveEnabledPluginSkill(owner3, input.skill_name, definition, tenantId2);
|
|
43862
44202
|
if (definition) {
|
|
43863
44203
|
if (!resolved || !resolved.definition.resources?.[input.resource_path]) {
|
|
43864
44204
|
return `Resource "${input.resource_path}" not found for skill "${input.skill_name}".`;
|
|
@@ -44222,11 +44562,15 @@ var createSearchCollectionTool = (scope = { collectionKeys: [], connectAll: true
|
|
|
44222
44562
|
tenantId2
|
|
44223
44563
|
);
|
|
44224
44564
|
}
|
|
44225
|
-
|
|
44226
|
-
|
|
44227
|
-
|
|
44228
|
-
|
|
44229
|
-
|
|
44565
|
+
const embeddingsClient = await embeddingsLatticeManager.getEmbeddingsClientWithTenant(
|
|
44566
|
+
tenantId2,
|
|
44567
|
+
embeddingKey
|
|
44568
|
+
) ?? await embeddingsLatticeManager.getEmbeddingsClientWithTenant(
|
|
44569
|
+
tenantId2,
|
|
44570
|
+
"default"
|
|
44571
|
+
);
|
|
44572
|
+
if (!embeddingsClient) {
|
|
44573
|
+
return `No embedding model "${embeddingKey}" is available for this tenant.`;
|
|
44230
44574
|
}
|
|
44231
44575
|
const queryVector = await embeddingsClient.embedQuery(query);
|
|
44232
44576
|
const results = await vectorStore.similaritySearchVectorWithScore(
|
|
@@ -52326,6 +52670,7 @@ registerBuiltinPlugins();
|
|
|
52326
52670
|
BUILTIN_PLUGINS,
|
|
52327
52671
|
BUILTIN_SKILLS,
|
|
52328
52672
|
CAPABILITY_TOOL_NAME_CONFLICT,
|
|
52673
|
+
COLLECTION_CHANGED_TOPIC,
|
|
52329
52674
|
CapabilityBundleMergeError,
|
|
52330
52675
|
CapabilityBundleMerger,
|
|
52331
52676
|
CapabilityBundleValidationError,
|
|
@@ -52345,6 +52690,7 @@ registerBuiltinPlugins();
|
|
|
52345
52690
|
DEFAULT_DELAY_MS,
|
|
52346
52691
|
DEFAULT_HANDLER_TIMEOUT_MS,
|
|
52347
52692
|
DEFAULT_MAX_ATTEMPTS,
|
|
52693
|
+
DEFAULT_MODEL_EXTRA,
|
|
52348
52694
|
DEFAULT_RESIDENT_INVOKE_TIMEOUT_MS,
|
|
52349
52695
|
DaytonaInstance,
|
|
52350
52696
|
DaytonaProvider,
|
|
@@ -52500,7 +52846,10 @@ registerBuiltinPlugins();
|
|
|
52500
52846
|
buildGrepResultsDict,
|
|
52501
52847
|
buildHandlerCommand,
|
|
52502
52848
|
buildInput,
|
|
52849
|
+
buildModelConfig,
|
|
52850
|
+
buildModelEmbeddingsConfig,
|
|
52503
52851
|
buildModelLlmConfig,
|
|
52852
|
+
buildModelSttConfig,
|
|
52504
52853
|
buildNamedVolumeName,
|
|
52505
52854
|
buildRemotePackDirectoryCommand,
|
|
52506
52855
|
buildSandboxMetadataEnv,
|
|
@@ -52521,6 +52870,7 @@ registerBuiltinPlugins();
|
|
|
52521
52870
|
compileSandboxPlugin,
|
|
52522
52871
|
compileWorkflow,
|
|
52523
52872
|
computeSandboxName,
|
|
52873
|
+
configureCollectionSync,
|
|
52524
52874
|
configureCoordinationLeaseStore,
|
|
52525
52875
|
configurePluginCatalogSync,
|
|
52526
52876
|
configureStores,
|
|
@@ -52698,6 +53048,7 @@ registerBuiltinPlugins();
|
|
|
52698
53048
|
projectRoomPlugin,
|
|
52699
53049
|
projectTaskAdmissionNotifier,
|
|
52700
53050
|
provisionSandboxOpenClient,
|
|
53051
|
+
publishCollectionChanged,
|
|
52701
53052
|
publishPluginCatalogChanged,
|
|
52702
53053
|
queueLatticeManager,
|
|
52703
53054
|
readLoopBreakerConfig,
|