@letta-ai/letta-code 0.29.3 → 0.29.5
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/letta.js +671 -586
- package/package.json +1 -1
- package/scripts/isolated-unit-tests.json +5 -0
- package/scripts/source-file-size-baseline.json +5 -5
package/letta.js
CHANGED
|
@@ -5462,7 +5462,7 @@ var package_default;
|
|
|
5462
5462
|
var init_package = __esm(() => {
|
|
5463
5463
|
package_default = {
|
|
5464
5464
|
name: "@letta-ai/letta-code",
|
|
5465
|
-
version: "0.29.
|
|
5465
|
+
version: "0.29.5",
|
|
5466
5466
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5467
5467
|
type: "module",
|
|
5468
5468
|
packageManager: "bun@1.3.0",
|
|
@@ -127383,6 +127383,9 @@ function validatePiProviderRegistration(providerName, config3) {
|
|
|
127383
127383
|
}
|
|
127384
127384
|
|
|
127385
127385
|
// src/backend/dev/pi-provider-mod-registry.ts
|
|
127386
|
+
function getPiProviderRegistryRevision() {
|
|
127387
|
+
return revisionCounter;
|
|
127388
|
+
}
|
|
127386
127389
|
function bumpProviderRevision(providerName) {
|
|
127387
127390
|
revisionCounter += 1;
|
|
127388
127391
|
providerRevisions.set(providerName, revisionCounter);
|
|
@@ -345981,6 +345984,7 @@ async function loadLocalMods(options3) {
|
|
|
345981
345984
|
const builtinCommandIds = new Set([...options3.builtinCommandIds ?? []]);
|
|
345982
345985
|
const reservedToolNames = new Set([...options3.reservedToolNames ?? []]);
|
|
345983
345986
|
const registry2 = createEmptyModRegistry(sources, generation2, capabilities, options3.registerCapabilitiesGlobally !== false);
|
|
345987
|
+
options3.onRegistryCreated?.(registry2);
|
|
345984
345988
|
for (const source2 of sources) {
|
|
345985
345989
|
for (const diagnostic of source2.diagnostics ?? []) {
|
|
345986
345990
|
const owner = createModOwner(diagnostic.path, source2, generation2);
|
|
@@ -346191,6 +346195,13 @@ function createModEngine(options3) {
|
|
|
346191
346195
|
const nextRegistry = await loadLocalMods({
|
|
346192
346196
|
...modOptions,
|
|
346193
346197
|
generation: loadGeneration,
|
|
346198
|
+
onRegistryCreated: (registry2) => {
|
|
346199
|
+
loadingRegistry = registry2;
|
|
346200
|
+
if (!disposed && loadGeneration === generation2) {
|
|
346201
|
+
activeRegistry = registry2;
|
|
346202
|
+
publish();
|
|
346203
|
+
}
|
|
346204
|
+
},
|
|
346194
346205
|
onChange: () => {
|
|
346195
346206
|
if (!disposed && loadingRegistry && loadGeneration === generation2) {
|
|
346196
346207
|
activeRegistry = loadingRegistry;
|
|
@@ -375875,7 +375886,7 @@ class LocalStore {
|
|
|
375875
375886
|
const agentsDir = join42(this.storageDir, "agents");
|
|
375876
375887
|
if (existsSync36(agentsDir)) {
|
|
375877
375888
|
for (const file3 of readdirSync13(agentsDir)) {
|
|
375878
|
-
if (!file3.endsWith(".json"))
|
|
375889
|
+
if (!file3.endsWith(".json") || file3.startsWith("._"))
|
|
375879
375890
|
continue;
|
|
375880
375891
|
const raw = readJsonFile2(join42(agentsDir, file3));
|
|
375881
375892
|
const agent2 = normalizeAgentRecord(raw, this.defaultAgentModel);
|
|
@@ -378334,6 +378345,8 @@ function createLocalEndpointPiProvider(options3) {
|
|
|
378334
378345
|
}
|
|
378335
378346
|
}
|
|
378336
378347
|
function buildModel(metadata) {
|
|
378348
|
+
const contextWindow = Math.min(metadata.contextLength ?? LOCAL_ENDPOINT_DEFAULT_CONTEXT_WINDOW, LOCAL_ENDPOINT_DEFAULT_CONTEXT_WINDOW);
|
|
378349
|
+
const maxTokens = Math.min(metadata.maxTokens ?? LOCAL_ENDPOINT_DEFAULT_MAX_TOKENS, contextWindow);
|
|
378337
378350
|
return {
|
|
378338
378351
|
id: metadata.id,
|
|
378339
378352
|
name: metadata.id,
|
|
@@ -378343,8 +378356,8 @@ function createLocalEndpointPiProvider(options3) {
|
|
|
378343
378356
|
reasoning: metadata.thinking === true,
|
|
378344
378357
|
input: metadata.vision === true ? ["text", "image"] : ["text"],
|
|
378345
378358
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
378346
|
-
contextWindow
|
|
378347
|
-
maxTokens
|
|
378359
|
+
contextWindow,
|
|
378360
|
+
maxTokens,
|
|
378348
378361
|
compat: {
|
|
378349
378362
|
supportsDeveloperRole: false,
|
|
378350
378363
|
supportsReasoningEffort: false,
|
|
@@ -378516,7 +378529,9 @@ function parseLmStudioModels(data) {
|
|
|
378516
378529
|
if (record5.type === "embeddings")
|
|
378517
378530
|
continue;
|
|
378518
378531
|
const capabilities = stringArray(record5.capabilities);
|
|
378519
|
-
const
|
|
378532
|
+
const loadedContextLength = record5.state === "loaded" && typeof record5.loaded_context_length === "number" && record5.loaded_context_length > 0 ? record5.loaded_context_length : undefined;
|
|
378533
|
+
const maxContextLength = typeof record5.max_context_length === "number" && record5.max_context_length > 0 ? record5.max_context_length : undefined;
|
|
378534
|
+
const contextLength = loadedContextLength ?? maxContextLength;
|
|
378520
378535
|
models3.push({
|
|
378521
378536
|
id: record5.id,
|
|
378522
378537
|
vision: record5.type === "vlm" || capabilities.includes("vision"),
|
|
@@ -379024,6 +379039,296 @@ var init_pi_models_runtime = __esm(() => {
|
|
|
379024
379039
|
]);
|
|
379025
379040
|
});
|
|
379026
379041
|
|
|
379042
|
+
// src/backend/dev/pi-model-factory.ts
|
|
379043
|
+
function isUnselectedLocalModelHandle(model) {
|
|
379044
|
+
return typeof model !== "string" || model.length === 0 || model === "auto" || model === UNSELECTED_LOCAL_MODEL_HANDLE || model.startsWith("letta/");
|
|
379045
|
+
}
|
|
379046
|
+
function normalizeOpenAICompatibleLocalModelHandle(model) {
|
|
379047
|
+
if (!model?.startsWith("openai/"))
|
|
379048
|
+
return model;
|
|
379049
|
+
const nestedHandle = model.slice("openai/".length);
|
|
379050
|
+
const nestedProvider = resolveProviderFromModelHandle(nestedHandle);
|
|
379051
|
+
if (!nestedProvider)
|
|
379052
|
+
return model;
|
|
379053
|
+
return getPiProviderSpec(nestedProvider).localModelDiscovery === "openai-compatible" ? nestedHandle : model;
|
|
379054
|
+
}
|
|
379055
|
+
function settingString(value) {
|
|
379056
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
379057
|
+
}
|
|
379058
|
+
function thinkingLevelSetting(value, preserveMax) {
|
|
379059
|
+
const effort = settingString(value);
|
|
379060
|
+
if (effort === "max")
|
|
379061
|
+
return preserveMax ? "max" : "xhigh";
|
|
379062
|
+
return effort === "minimal" || effort === "low" || effort === "medium" || effort === "high" || effort === "xhigh" ? effort : undefined;
|
|
379063
|
+
}
|
|
379064
|
+
function reasoningForSettings(modelSettings, modelHandle) {
|
|
379065
|
+
const thinking = isRecord(modelSettings.thinking) ? modelSettings.thinking : undefined;
|
|
379066
|
+
if (thinking?.type === "disabled")
|
|
379067
|
+
return;
|
|
379068
|
+
const nestedReasoning = isRecord(modelSettings.reasoning) ? modelSettings.reasoning : undefined;
|
|
379069
|
+
const modelId = modelHandle?.slice(modelHandle.indexOf("/") + 1);
|
|
379070
|
+
const preserveMax = modelId?.startsWith("gpt-5.6") === true;
|
|
379071
|
+
return thinkingLevelSetting(nestedReasoning?.reasoning_effort, preserveMax) ?? thinkingLevelSetting(modelSettings.effort, preserveMax) ?? thinkingLevelSetting(modelSettings.reasoning_effort, preserveMax);
|
|
379072
|
+
}
|
|
379073
|
+
function applyPiEnvOverrides(overrides) {
|
|
379074
|
+
if (!overrides)
|
|
379075
|
+
return () => {};
|
|
379076
|
+
const previous = new Map;
|
|
379077
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
379078
|
+
previous.set(key, process.env[key]);
|
|
379079
|
+
if (value === undefined) {
|
|
379080
|
+
delete process.env[key];
|
|
379081
|
+
} else {
|
|
379082
|
+
process.env[key] = value;
|
|
379083
|
+
}
|
|
379084
|
+
}
|
|
379085
|
+
return () => {
|
|
379086
|
+
for (const [key, value] of previous) {
|
|
379087
|
+
if (value === undefined) {
|
|
379088
|
+
delete process.env[key];
|
|
379089
|
+
} else {
|
|
379090
|
+
process.env[key] = value;
|
|
379091
|
+
}
|
|
379092
|
+
}
|
|
379093
|
+
};
|
|
379094
|
+
}
|
|
379095
|
+
function hasEnvValue2(value) {
|
|
379096
|
+
return typeof value === "string" && value.length > 0;
|
|
379097
|
+
}
|
|
379098
|
+
function inferDefaultProviderFromStandardKeys() {
|
|
379099
|
+
const hasOpenAIKey = hasEnvValue2(process.env.OPENAI_API_KEY);
|
|
379100
|
+
const hasAnthropicKey = hasEnvValue2(process.env.ANTHROPIC_API_KEY);
|
|
379101
|
+
if (!hasOpenAIKey && hasAnthropicKey)
|
|
379102
|
+
return "anthropic";
|
|
379103
|
+
return DEFAULT_PI_PROVIDER;
|
|
379104
|
+
}
|
|
379105
|
+
function resolvePiProvider(provider = process.env.LETTA_CODE_DEV_PI_PROVIDER ?? inferDefaultProviderFromStandardKeys()) {
|
|
379106
|
+
if (isPiProvider(provider))
|
|
379107
|
+
return provider;
|
|
379108
|
+
if (getRegisteredPiProvider(provider))
|
|
379109
|
+
return provider;
|
|
379110
|
+
throw new Error(`Unknown pi provider "${provider}". Expected ${expectedPiProviderList()}.`);
|
|
379111
|
+
}
|
|
379112
|
+
function resolvePiProviderFromAgent(model, modelSettings = {}) {
|
|
379113
|
+
const registeredProvider = resolveRegisteredPiProviderFromModelHandle(model);
|
|
379114
|
+
if (registeredProvider)
|
|
379115
|
+
return registeredProvider;
|
|
379116
|
+
const handleProvider = resolveProviderFromModelHandle(model);
|
|
379117
|
+
if (handleProvider)
|
|
379118
|
+
return handleProvider;
|
|
379119
|
+
const settingsProvider = resolveProviderFromProviderType(modelSettings.provider_type);
|
|
379120
|
+
if (settingsProvider)
|
|
379121
|
+
return settingsProvider;
|
|
379122
|
+
if (model && !isUnselectedLocalModelHandle(model)) {
|
|
379123
|
+
const slashIndex = model.indexOf("/");
|
|
379124
|
+
if (slashIndex > 0) {
|
|
379125
|
+
throw new Error(`Model provider "${model.slice(0, slashIndex)}" is not registered. Load or repair the provider mod, or choose another model with /model.`);
|
|
379126
|
+
}
|
|
379127
|
+
}
|
|
379128
|
+
return resolvePiProvider();
|
|
379129
|
+
}
|
|
379130
|
+
function resolvePiModelFromAgent(model, provider) {
|
|
379131
|
+
return stripProviderHandlePrefix(model, provider);
|
|
379132
|
+
}
|
|
379133
|
+
function localProviderRecord(providerNames, storageDir) {
|
|
379134
|
+
for (const providerName of providerNames) {
|
|
379135
|
+
const record5 = getLocalProviderRecordByName(providerName, storageDir);
|
|
379136
|
+
if (record5)
|
|
379137
|
+
return record5;
|
|
379138
|
+
}
|
|
379139
|
+
return null;
|
|
379140
|
+
}
|
|
379141
|
+
function localProviderConnection(providerNames, storageDir) {
|
|
379142
|
+
const record5 = localProviderRecord(providerNames, storageDir);
|
|
379143
|
+
return {
|
|
379144
|
+
baseURL: record5?.base_url,
|
|
379145
|
+
timeout: resolveLocalProviderTimeout({
|
|
379146
|
+
configuredTimeout: record5?.timeout,
|
|
379147
|
+
providerIds: providerNames
|
|
379148
|
+
}),
|
|
379149
|
+
...record5 ? { record: record5 } : {}
|
|
379150
|
+
};
|
|
379151
|
+
}
|
|
379152
|
+
function resolveZaiConnection(options3) {
|
|
379153
|
+
const regularRecord = localProviderRecord(["zai", LOCAL_ZAI_PROVIDER_NAME], options3.storageDir);
|
|
379154
|
+
const codingRecord = localProviderRecord(["zai_coding", LOCAL_ZAI_CODING_PROVIDER_NAME], options3.storageDir);
|
|
379155
|
+
const regularKey = localProviderApiKeyFromRecord(regularRecord) ?? process.env.ZAI_API_KEY ?? process.env.ZHIPU_API_KEY;
|
|
379156
|
+
const codingKey = localProviderApiKeyFromRecord(codingRecord) ?? process.env.ZAI_CODING_API_KEY;
|
|
379157
|
+
const regularConnection = {
|
|
379158
|
+
providerName: "zai",
|
|
379159
|
+
baseURL: regularRecord?.base_url ?? process.env.ZAI_BASE_URL ?? "https://api.z.ai/api/paas/v4",
|
|
379160
|
+
apiKey: regularKey,
|
|
379161
|
+
timeout: resolveLocalProviderTimeout({
|
|
379162
|
+
configuredTimeout: regularRecord?.timeout,
|
|
379163
|
+
providerIds: [LOCAL_ZAI_PROVIDER_NAME, "zai"]
|
|
379164
|
+
})
|
|
379165
|
+
};
|
|
379166
|
+
const codingConnection = {
|
|
379167
|
+
providerName: "zai-coding",
|
|
379168
|
+
baseURL: codingRecord?.base_url ?? process.env.ZAI_CODING_BASE_URL ?? "https://api.z.ai/api/coding/paas/v4",
|
|
379169
|
+
apiKey: codingKey,
|
|
379170
|
+
timeout: resolveLocalProviderTimeout({
|
|
379171
|
+
configuredTimeout: codingRecord?.timeout,
|
|
379172
|
+
providerIds: [LOCAL_ZAI_CODING_PROVIDER_NAME, "zai-coding"]
|
|
379173
|
+
})
|
|
379174
|
+
};
|
|
379175
|
+
if (options3.preferredProviderType === "zai_coding" && codingKey) {
|
|
379176
|
+
return codingConnection;
|
|
379177
|
+
}
|
|
379178
|
+
if (options3.preferredProviderType === "zai" && regularKey) {
|
|
379179
|
+
return regularConnection;
|
|
379180
|
+
}
|
|
379181
|
+
if (codingKey)
|
|
379182
|
+
return codingConnection;
|
|
379183
|
+
if (regularKey)
|
|
379184
|
+
return regularConnection;
|
|
379185
|
+
return codingConnection;
|
|
379186
|
+
}
|
|
379187
|
+
function fallbackCatalogModelId(provider, modelId) {
|
|
379188
|
+
if (provider !== "openai")
|
|
379189
|
+
return;
|
|
379190
|
+
const withoutReleaseDate = modelId.replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
379191
|
+
return withoutReleaseDate === modelId ? undefined : withoutReleaseDate;
|
|
379192
|
+
}
|
|
379193
|
+
function withOverrides(model, overrides) {
|
|
379194
|
+
return {
|
|
379195
|
+
...model,
|
|
379196
|
+
...overrides.baseURL ? { baseUrl: overrides.baseURL } : {},
|
|
379197
|
+
...overrides.headers ? { headers: { ...model.headers, ...overrides.headers } } : {},
|
|
379198
|
+
...overrides.contextWindow ? { contextWindow: overrides.contextWindow } : {},
|
|
379199
|
+
...overrides.maxTokens ? { maxTokens: overrides.maxTokens } : {}
|
|
379200
|
+
};
|
|
379201
|
+
}
|
|
379202
|
+
function nonNullHeaders(headers) {
|
|
379203
|
+
return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] !== null));
|
|
379204
|
+
}
|
|
379205
|
+
function mergeHeaders3(...headers) {
|
|
379206
|
+
const merged = {};
|
|
379207
|
+
for (const header of headers) {
|
|
379208
|
+
if (!header)
|
|
379209
|
+
continue;
|
|
379210
|
+
Object.assign(merged, header);
|
|
379211
|
+
}
|
|
379212
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
379213
|
+
}
|
|
379214
|
+
function numericSetting(value) {
|
|
379215
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
379216
|
+
}
|
|
379217
|
+
function bedrockLocalProviderOptions(record5) {
|
|
379218
|
+
if (!record5)
|
|
379219
|
+
return {};
|
|
379220
|
+
const providerOptions = {};
|
|
379221
|
+
const envOverrides = {};
|
|
379222
|
+
if (record5.region) {
|
|
379223
|
+
providerOptions.region = record5.region;
|
|
379224
|
+
envOverrides.AWS_REGION = record5.region;
|
|
379225
|
+
envOverrides.AWS_DEFAULT_REGION = record5.region;
|
|
379226
|
+
}
|
|
379227
|
+
if (record5.profile) {
|
|
379228
|
+
providerOptions.profile = record5.profile;
|
|
379229
|
+
envOverrides.AWS_PROFILE = record5.profile;
|
|
379230
|
+
}
|
|
379231
|
+
if (record5.auth.type === "api" && record5.auth.key) {
|
|
379232
|
+
if (record5.access_key) {
|
|
379233
|
+
envOverrides.AWS_ACCESS_KEY_ID = record5.access_key;
|
|
379234
|
+
envOverrides.AWS_SECRET_ACCESS_KEY = record5.auth.key;
|
|
379235
|
+
} else {
|
|
379236
|
+
providerOptions.bearerToken = record5.auth.key;
|
|
379237
|
+
envOverrides.AWS_BEARER_TOKEN_BEDROCK = record5.auth.key;
|
|
379238
|
+
}
|
|
379239
|
+
}
|
|
379240
|
+
return {
|
|
379241
|
+
...Object.keys(providerOptions).length > 0 ? { providerOptions } : {},
|
|
379242
|
+
...Object.keys(envOverrides).length > 0 ? { envOverrides } : {}
|
|
379243
|
+
};
|
|
379244
|
+
}
|
|
379245
|
+
async function resolvePiModelForAgent(modelHandle, modelSettings = {}, options3 = {}) {
|
|
379246
|
+
const concreteModelHandle = normalizeOpenAICompatibleLocalModelHandle(isUnselectedLocalModelHandle(modelHandle) ? undefined : modelHandle);
|
|
379247
|
+
const provider = options3.provider ? resolvePiProvider(options3.provider) : resolvePiProviderFromAgent(concreteModelHandle, modelSettings);
|
|
379248
|
+
const registeredProvider = getRegisteredPiProvider(provider);
|
|
379249
|
+
const spec = isPiProvider(provider) ? getPiProviderSpec(provider) : undefined;
|
|
379250
|
+
const modelId = options3.model ?? (registeredProvider ? stripRegisteredProviderHandlePrefix(concreteModelHandle, provider) : undefined) ?? (spec ? resolvePiModelFromAgent(concreteModelHandle, spec.id) : undefined) ?? registeredProvider?.config.models?.[0]?.id ?? (spec?.defaultModel ? resolvePiModelFromAgent(spec.defaultModel, spec.id) : undefined) ?? process.env.LETTA_CODE_DEV_PI_MODEL ?? "";
|
|
379251
|
+
const storageDir = options3.localProviderAuthStorageDir;
|
|
379252
|
+
const modelsRuntime = options3.modelsRuntime ?? new LocalPiModelsRuntime({
|
|
379253
|
+
...storageDir ? { storageDir } : {}
|
|
379254
|
+
});
|
|
379255
|
+
const preferredProviderType = typeof modelSettings.provider_type === "string" ? modelSettings.provider_type : options3.preferredProviderType;
|
|
379256
|
+
const localNames = registeredProvider ? localNamesForProviderId(provider) : spec?.localProviderNames ?? [provider];
|
|
379257
|
+
let connection = localProviderConnection(localNames, storageDir);
|
|
379258
|
+
let baseURL = connection.baseURL ?? spec?.baseUrlEnv?.() ?? spec?.defaultBaseURL ?? registeredProvider?.config.baseUrl;
|
|
379259
|
+
let headers = mergeHeaders3(spec?.headers?.());
|
|
379260
|
+
let providerOptions;
|
|
379261
|
+
let envOverrides;
|
|
379262
|
+
let oauthCredentials;
|
|
379263
|
+
if (!modelId) {
|
|
379264
|
+
throw new Error(`No model selected for provider "${provider}". Choose an available model with /model.`);
|
|
379265
|
+
}
|
|
379266
|
+
const runtimeProviderId = registeredProvider ? provider : spec && modelsRuntime.isRuntimeManagedProvider(spec.id) ? spec.id : spec?.piProvider;
|
|
379267
|
+
if (!runtimeProviderId) {
|
|
379268
|
+
throw new Error(`Unknown model "${modelId}" for provider "${provider}". ` + "Register the provider with models before using it.");
|
|
379269
|
+
}
|
|
379270
|
+
const fallbackModelId = !registeredProvider && spec?.piProvider ? fallbackCatalogModelId(spec.piProvider, modelId) : undefined;
|
|
379271
|
+
const { model: publishedModel, auth: authResult } = await modelsRuntime.resolveTurn(runtimeProviderId, modelId, fallbackModelId);
|
|
379272
|
+
connection = { ...connection, apiKey: authResult?.auth.apiKey };
|
|
379273
|
+
if (authResult?.auth.baseUrl)
|
|
379274
|
+
baseURL = authResult.auth.baseUrl;
|
|
379275
|
+
if (authResult?.auth.headers) {
|
|
379276
|
+
headers = mergeHeaders3(headers, nonNullHeaders(authResult.auth.headers));
|
|
379277
|
+
}
|
|
379278
|
+
if (connection.record?.auth.type === "oauth") {
|
|
379279
|
+
const stored = await modelsRuntime.getStoredCredential(runtimeProviderId);
|
|
379280
|
+
oauthCredentials = stored?.type === "oauth" ? stored : undefined;
|
|
379281
|
+
}
|
|
379282
|
+
if (provider === "zai") {
|
|
379283
|
+
const zai = resolveZaiConnection({
|
|
379284
|
+
storageDir,
|
|
379285
|
+
preferredProviderType: preferredProviderType === "zai" || preferredProviderType === "zai_coding" ? preferredProviderType : undefined
|
|
379286
|
+
});
|
|
379287
|
+
connection = {
|
|
379288
|
+
apiKey: zai.apiKey,
|
|
379289
|
+
baseURL: zai.baseURL,
|
|
379290
|
+
timeout: zai.timeout
|
|
379291
|
+
};
|
|
379292
|
+
baseURL = zai.baseURL;
|
|
379293
|
+
}
|
|
379294
|
+
if (provider === "amazon-bedrock") {
|
|
379295
|
+
const bedrock = bedrockLocalProviderOptions(connection.record);
|
|
379296
|
+
providerOptions = bedrock.providerOptions;
|
|
379297
|
+
envOverrides = bedrock.envOverrides;
|
|
379298
|
+
}
|
|
379299
|
+
if (!publishedModel) {
|
|
379300
|
+
throw new Error(`Unknown model "${modelId}" for provider "${provider}". ` + "Choose an available model with /model.");
|
|
379301
|
+
}
|
|
379302
|
+
const hookedModel = oauthCredentials && registeredProvider?.config.oauth?.modifyModels ? registeredProvider.config.oauth.modifyModels([structuredClone(publishedModel)], oauthCredentials)[0] ?? publishedModel : publishedModel;
|
|
379303
|
+
const contextWindow = numericSetting(modelSettings.context_window_limit);
|
|
379304
|
+
const maxTokens = numericSetting(modelSettings.max_tokens);
|
|
379305
|
+
const allowBaseUrlOverride = !registeredProvider && spec !== undefined && !modelsRuntime.isRuntimeManagedProvider(spec.id);
|
|
379306
|
+
const overrides = {
|
|
379307
|
+
...allowBaseUrlOverride && baseURL && baseURL !== hookedModel.baseUrl ? { baseURL } : {},
|
|
379308
|
+
...contextWindow && contextWindow !== hookedModel.contextWindow ? { contextWindow } : {},
|
|
379309
|
+
...maxTokens && maxTokens !== hookedModel.maxTokens ? { maxTokens } : {}
|
|
379310
|
+
};
|
|
379311
|
+
const model = Object.keys(overrides).length > 0 ? withOverrides(hookedModel, overrides) : hookedModel;
|
|
379312
|
+
return {
|
|
379313
|
+
provider,
|
|
379314
|
+
model,
|
|
379315
|
+
apiKey: connection.apiKey,
|
|
379316
|
+
timeout: connection.timeout,
|
|
379317
|
+
headers,
|
|
379318
|
+
providerOptions,
|
|
379319
|
+
envOverrides
|
|
379320
|
+
};
|
|
379321
|
+
}
|
|
379322
|
+
var DEFAULT_PI_PROVIDER = "openai", UNSELECTED_LOCAL_MODEL_HANDLE = "local/default";
|
|
379323
|
+
var init_pi_model_factory = __esm(() => {
|
|
379324
|
+
init_local_pi_credential_store();
|
|
379325
|
+
init_local_provider_auth_store();
|
|
379326
|
+
init_local_provider_timeout();
|
|
379327
|
+
init_pi_models_runtime();
|
|
379328
|
+
init_pi_provider_mod_registry();
|
|
379329
|
+
init_pi_provider_registry();
|
|
379330
|
+
});
|
|
379331
|
+
|
|
379027
379332
|
// src/backend/local/local-context-estimate.ts
|
|
379028
379333
|
function positiveUsageNumber(value) {
|
|
379029
379334
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
|
|
@@ -379147,561 +379452,6 @@ function estimateLocalContextTokens(messages) {
|
|
|
379147
379452
|
}
|
|
379148
379453
|
var IMAGE_TOKEN_ESTIMATE = 1200;
|
|
379149
379454
|
|
|
379150
|
-
// src/backend/dev/provider-turn-executor.ts
|
|
379151
|
-
var exports_provider_turn_executor = {};
|
|
379152
|
-
__export(exports_provider_turn_executor, {
|
|
379153
|
-
providerStreamPart: () => providerStreamPart,
|
|
379154
|
-
providerLocalMessage: () => providerLocalMessage,
|
|
379155
|
-
providerLettaChunk: () => providerLettaChunk,
|
|
379156
|
-
estimateProviderRequestBytes: () => estimateProviderRequestBytes,
|
|
379157
|
-
estimateProviderContextTokens: () => estimateProviderContextTokens,
|
|
379158
|
-
contextTokensFromUsage: () => contextTokensFromUsage,
|
|
379159
|
-
buildProviderTurnInput: () => buildProviderTurnInput,
|
|
379160
|
-
ProviderTurnExecutor: () => ProviderTurnExecutor
|
|
379161
|
-
});
|
|
379162
|
-
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
379163
|
-
function providerStreamPart(part) {
|
|
379164
|
-
return { type: "provider-part", part };
|
|
379165
|
-
}
|
|
379166
|
-
function providerLocalMessage(message) {
|
|
379167
|
-
return { type: "local-message", message };
|
|
379168
|
-
}
|
|
379169
|
-
function providerLettaChunk(chunk) {
|
|
379170
|
-
return { type: "letta-chunk", chunk };
|
|
379171
|
-
}
|
|
379172
|
-
|
|
379173
|
-
class MissingProviderStreamAdapter {
|
|
379174
|
-
async* stream() {
|
|
379175
|
-
yield {
|
|
379176
|
-
type: "error",
|
|
379177
|
-
error: new Error("Provider turn adapter is not configured for this dev backend")
|
|
379178
|
-
};
|
|
379179
|
-
}
|
|
379180
|
-
}
|
|
379181
|
-
function bodyListField(body, key) {
|
|
379182
|
-
const value = body[key];
|
|
379183
|
-
return Array.isArray(value) ? value : [];
|
|
379184
|
-
}
|
|
379185
|
-
function buildProviderTurnInput(input) {
|
|
379186
|
-
return {
|
|
379187
|
-
conversationId: input.conversationId,
|
|
379188
|
-
agentId: input.agentId,
|
|
379189
|
-
agent: input.agent,
|
|
379190
|
-
systemPrompt: input.systemPrompt,
|
|
379191
|
-
midConversationSystemPrompt: input.midConversationSystemPrompt,
|
|
379192
|
-
body: input.body,
|
|
379193
|
-
history: input.history,
|
|
379194
|
-
uiMessages: input.uiMessages,
|
|
379195
|
-
clientTools: bodyListField(input.body, "client_tools"),
|
|
379196
|
-
clientSkills: bodyListField(input.body, "client_skills")
|
|
379197
|
-
};
|
|
379198
|
-
}
|
|
379199
|
-
function stringifyToolInput(input) {
|
|
379200
|
-
if (typeof input === "string")
|
|
379201
|
-
return input;
|
|
379202
|
-
return JSON.stringify(input ?? {});
|
|
379203
|
-
}
|
|
379204
|
-
function createLocalMessageChunk(message) {
|
|
379205
|
-
return markLocalStateChunkOnly(attachLocalMessage({ message_type: "local_message" }, message));
|
|
379206
|
-
}
|
|
379207
|
-
function createProviderErrorChunks(error54) {
|
|
379208
|
-
const info = normalizeLocalProviderError(error54);
|
|
379209
|
-
return [
|
|
379210
|
-
{
|
|
379211
|
-
message_type: "error_message",
|
|
379212
|
-
message: info.message,
|
|
379213
|
-
detail: info.detail,
|
|
379214
|
-
error_type: info.error_type,
|
|
379215
|
-
retryable: info.retryable
|
|
379216
|
-
},
|
|
379217
|
-
{
|
|
379218
|
-
message_type: "stop_reason",
|
|
379219
|
-
stop_reason: info.stop_reason
|
|
379220
|
-
}
|
|
379221
|
-
];
|
|
379222
|
-
}
|
|
379223
|
-
function contextTokensFromUsage(usage) {
|
|
379224
|
-
return contextTokensFromLocalUsage(usage);
|
|
379225
|
-
}
|
|
379226
|
-
function estimateSerializedTokens(value) {
|
|
379227
|
-
if (value === undefined || value === null)
|
|
379228
|
-
return 0;
|
|
379229
|
-
try {
|
|
379230
|
-
const serialized = typeof value === "string" ? value : JSON.stringify(value) ?? "";
|
|
379231
|
-
return Math.ceil(serialized.length / 4);
|
|
379232
|
-
} catch {
|
|
379233
|
-
return 0;
|
|
379234
|
-
}
|
|
379235
|
-
}
|
|
379236
|
-
function estimateProviderContextTokens(input) {
|
|
379237
|
-
const contextEstimate = estimateLocalContextTokens(input.uiMessages);
|
|
379238
|
-
if (contextEstimate.lastUsageIndex !== null) {
|
|
379239
|
-
return contextEstimate.tokens > 0 ? contextEstimate.tokens : undefined;
|
|
379240
|
-
}
|
|
379241
|
-
const systemPromptTokens = estimateSerializedTokens(input.systemPrompt ?? input.agent.system);
|
|
379242
|
-
const messageTokens = contextEstimate.tokens;
|
|
379243
|
-
const toolTokens = estimateSerializedTokens(input.clientTools);
|
|
379244
|
-
const total = systemPromptTokens + messageTokens + toolTokens;
|
|
379245
|
-
return total > 0 ? total : undefined;
|
|
379246
|
-
}
|
|
379247
|
-
function serializedLength(value) {
|
|
379248
|
-
if (value === undefined || value === null)
|
|
379249
|
-
return 0;
|
|
379250
|
-
try {
|
|
379251
|
-
const serialized = typeof value === "string" ? value : JSON.stringify(value) ?? "";
|
|
379252
|
-
return serialized.length;
|
|
379253
|
-
} catch {
|
|
379254
|
-
return 0;
|
|
379255
|
-
}
|
|
379256
|
-
}
|
|
379257
|
-
function estimateProviderRequestBytes(input) {
|
|
379258
|
-
const systemPromptBytes = serializedLength(input.systemPrompt ?? input.agent.system);
|
|
379259
|
-
const messageBytes = serializedLength(input.uiMessages);
|
|
379260
|
-
const toolBytes = serializedLength(input.clientTools);
|
|
379261
|
-
const total = systemPromptBytes + messageBytes + toolBytes;
|
|
379262
|
-
return total > 0 ? total : undefined;
|
|
379263
|
-
}
|
|
379264
|
-
function createUsageStatisticsChunk(usage, contextTokensEstimate) {
|
|
379265
|
-
const promptTokens = usage?.input;
|
|
379266
|
-
const completionTokens = usage?.output;
|
|
379267
|
-
const totalTokens = usage?.totalTokens;
|
|
379268
|
-
const usageContextTokens = usage ? contextTokensFromUsage(usage) : undefined;
|
|
379269
|
-
const contextTokens = usageContextTokens ?? contextTokensEstimate;
|
|
379270
|
-
const cachedInputTokens = usage?.cacheRead;
|
|
379271
|
-
const cacheWriteTokens = usage?.cacheWrite;
|
|
379272
|
-
if (promptTokens === undefined && completionTokens === undefined && totalTokens === undefined && cachedInputTokens === undefined && cacheWriteTokens === undefined && contextTokens === undefined) {
|
|
379273
|
-
return;
|
|
379274
|
-
}
|
|
379275
|
-
return {
|
|
379276
|
-
message_type: "usage_statistics",
|
|
379277
|
-
...promptTokens !== undefined ? { prompt_tokens: promptTokens } : {},
|
|
379278
|
-
...completionTokens !== undefined ? { completion_tokens: completionTokens } : {},
|
|
379279
|
-
...totalTokens !== undefined ? { total_tokens: totalTokens } : {},
|
|
379280
|
-
...cachedInputTokens !== undefined ? { cached_input_tokens: cachedInputTokens } : {},
|
|
379281
|
-
...cacheWriteTokens !== undefined ? { cache_write_tokens: cacheWriteTokens } : {},
|
|
379282
|
-
...contextTokens !== undefined ? { context_tokens: contextTokens } : {}
|
|
379283
|
-
};
|
|
379284
|
-
}
|
|
379285
|
-
function errorFromAssistantEvent(part) {
|
|
379286
|
-
if (part.type !== "error")
|
|
379287
|
-
return new Error("Unknown provider stream error");
|
|
379288
|
-
return new Error(part.error.errorMessage ?? "Unknown local provider error");
|
|
379289
|
-
}
|
|
379290
|
-
function contentMatchesMessageType(content, messageType) {
|
|
379291
|
-
if (!content || typeof content !== "object" || !("type" in content)) {
|
|
379292
|
-
return false;
|
|
379293
|
-
}
|
|
379294
|
-
return messageType === "assistant_message" ? content.type === "text" : content.type === "thinking";
|
|
379295
|
-
}
|
|
379296
|
-
function contiguousContentStartIndex(partial4, contentIndex, messageType) {
|
|
379297
|
-
let startIndex = contentIndex;
|
|
379298
|
-
while (startIndex > 0 && contentMatchesMessageType(partial4.content[startIndex - 1], messageType)) {
|
|
379299
|
-
startIndex -= 1;
|
|
379300
|
-
}
|
|
379301
|
-
return startIndex;
|
|
379302
|
-
}
|
|
379303
|
-
function otidForContentSegment(otids, prefix, contentIndex, partial4, messageType) {
|
|
379304
|
-
const segmentStartIndex = contiguousContentStartIndex(partial4, contentIndex, messageType);
|
|
379305
|
-
const existing = otids.get(segmentStartIndex);
|
|
379306
|
-
if (existing)
|
|
379307
|
-
return existing;
|
|
379308
|
-
const otid = `${prefix}-${segmentStartIndex}-${randomUUID21()}`;
|
|
379309
|
-
otids.set(segmentStartIndex, otid);
|
|
379310
|
-
return otid;
|
|
379311
|
-
}
|
|
379312
|
-
function createProviderLettaStream(events, contextTokensEstimate) {
|
|
379313
|
-
const controller = new AbortController;
|
|
379314
|
-
return {
|
|
379315
|
-
controller,
|
|
379316
|
-
async* [Symbol.asyncIterator]() {
|
|
379317
|
-
let sawToolCall = false;
|
|
379318
|
-
let pendingStopReason;
|
|
379319
|
-
let sawUsageStatistics = false;
|
|
379320
|
-
const assistantOtids = new Map;
|
|
379321
|
-
const reasoningOtids = new Map;
|
|
379322
|
-
try {
|
|
379323
|
-
for await (const event2 of events) {
|
|
379324
|
-
if (event2.type === "error") {
|
|
379325
|
-
yield* createProviderErrorChunks(event2.error);
|
|
379326
|
-
return;
|
|
379327
|
-
}
|
|
379328
|
-
if (event2.type === "local-message") {
|
|
379329
|
-
yield createLocalMessageChunk(event2.message);
|
|
379330
|
-
continue;
|
|
379331
|
-
}
|
|
379332
|
-
if (event2.type === "letta-chunk") {
|
|
379333
|
-
yield event2.chunk;
|
|
379334
|
-
continue;
|
|
379335
|
-
}
|
|
379336
|
-
const { part } = event2;
|
|
379337
|
-
if (part.type === "text_delta") {
|
|
379338
|
-
yield {
|
|
379339
|
-
message_type: "assistant_message",
|
|
379340
|
-
otid: otidForContentSegment(assistantOtids, "provider-assistant", part.contentIndex, part.partial, "assistant_message"),
|
|
379341
|
-
content: [{ type: "text", text: part.delta }]
|
|
379342
|
-
};
|
|
379343
|
-
continue;
|
|
379344
|
-
}
|
|
379345
|
-
if (part.type === "thinking_delta") {
|
|
379346
|
-
yield {
|
|
379347
|
-
message_type: "reasoning_message",
|
|
379348
|
-
otid: otidForContentSegment(reasoningOtids, "provider-reasoning", part.contentIndex, part.partial, "reasoning_message"),
|
|
379349
|
-
reasoning: part.delta
|
|
379350
|
-
};
|
|
379351
|
-
continue;
|
|
379352
|
-
}
|
|
379353
|
-
if (part.type === "toolcall_end") {
|
|
379354
|
-
sawToolCall = true;
|
|
379355
|
-
yield {
|
|
379356
|
-
message_type: "approval_request_message",
|
|
379357
|
-
tool_call: {
|
|
379358
|
-
tool_call_id: part.toolCall.id,
|
|
379359
|
-
name: part.toolCall.name,
|
|
379360
|
-
arguments: stringifyToolInput(part.toolCall.arguments)
|
|
379361
|
-
}
|
|
379362
|
-
};
|
|
379363
|
-
continue;
|
|
379364
|
-
}
|
|
379365
|
-
if (part.type === "done") {
|
|
379366
|
-
if (!sawUsageStatistics) {
|
|
379367
|
-
const usageChunk = createUsageStatisticsChunk(part.message.usage, contextTokensEstimate);
|
|
379368
|
-
if (usageChunk) {
|
|
379369
|
-
sawUsageStatistics = true;
|
|
379370
|
-
yield usageChunk;
|
|
379371
|
-
}
|
|
379372
|
-
}
|
|
379373
|
-
pendingStopReason = {
|
|
379374
|
-
message_type: "stop_reason",
|
|
379375
|
-
stop_reason: sawToolCall || part.reason === "toolUse" ? "requires_approval" : part.reason === "length" ? "max_tokens_exceeded" : "end_turn"
|
|
379376
|
-
};
|
|
379377
|
-
continue;
|
|
379378
|
-
}
|
|
379379
|
-
if (part.type === "error") {
|
|
379380
|
-
yield* createProviderErrorChunks(errorFromAssistantEvent(part));
|
|
379381
|
-
return;
|
|
379382
|
-
}
|
|
379383
|
-
}
|
|
379384
|
-
if (pendingStopReason) {
|
|
379385
|
-
yield pendingStopReason;
|
|
379386
|
-
} else if (sawToolCall) {
|
|
379387
|
-
yield {
|
|
379388
|
-
message_type: "stop_reason",
|
|
379389
|
-
stop_reason: "requires_approval"
|
|
379390
|
-
};
|
|
379391
|
-
}
|
|
379392
|
-
} catch (error54) {
|
|
379393
|
-
yield* createProviderErrorChunks(error54);
|
|
379394
|
-
}
|
|
379395
|
-
}
|
|
379396
|
-
};
|
|
379397
|
-
}
|
|
379398
|
-
|
|
379399
|
-
class ProviderTurnExecutor {
|
|
379400
|
-
adapter;
|
|
379401
|
-
constructor(adapter = new MissingProviderStreamAdapter) {
|
|
379402
|
-
this.adapter = adapter;
|
|
379403
|
-
}
|
|
379404
|
-
async execute(input) {
|
|
379405
|
-
const providerInput = buildProviderTurnInput(input);
|
|
379406
|
-
const events = await this.adapter.stream(providerInput);
|
|
379407
|
-
return createProviderLettaStream(events, estimateProviderContextTokens(providerInput));
|
|
379408
|
-
}
|
|
379409
|
-
}
|
|
379410
|
-
var init_provider_turn_executor = __esm(() => {
|
|
379411
|
-
init_local_stream_chunks();
|
|
379412
|
-
init_local_provider_errors();
|
|
379413
|
-
});
|
|
379414
|
-
|
|
379415
|
-
// src/backend/dev/pi-model-factory.ts
|
|
379416
|
-
function isUnselectedLocalModelHandle(model) {
|
|
379417
|
-
return typeof model !== "string" || model.length === 0 || model === "auto" || model === UNSELECTED_LOCAL_MODEL_HANDLE || model.startsWith("letta/");
|
|
379418
|
-
}
|
|
379419
|
-
function normalizeOpenAICompatibleLocalModelHandle(model) {
|
|
379420
|
-
if (!model?.startsWith("openai/"))
|
|
379421
|
-
return model;
|
|
379422
|
-
const nestedHandle = model.slice("openai/".length);
|
|
379423
|
-
const nestedProvider = resolveProviderFromModelHandle(nestedHandle);
|
|
379424
|
-
if (!nestedProvider)
|
|
379425
|
-
return model;
|
|
379426
|
-
return getPiProviderSpec(nestedProvider).localModelDiscovery === "openai-compatible" ? nestedHandle : model;
|
|
379427
|
-
}
|
|
379428
|
-
function settingString(value) {
|
|
379429
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
379430
|
-
}
|
|
379431
|
-
function thinkingLevelSetting(value, preserveMax) {
|
|
379432
|
-
const effort = settingString(value);
|
|
379433
|
-
if (effort === "max")
|
|
379434
|
-
return preserveMax ? "max" : "xhigh";
|
|
379435
|
-
return effort === "minimal" || effort === "low" || effort === "medium" || effort === "high" || effort === "xhigh" ? effort : undefined;
|
|
379436
|
-
}
|
|
379437
|
-
function reasoningForSettings(modelSettings, modelHandle) {
|
|
379438
|
-
const thinking = isRecord(modelSettings.thinking) ? modelSettings.thinking : undefined;
|
|
379439
|
-
if (thinking?.type === "disabled")
|
|
379440
|
-
return;
|
|
379441
|
-
const nestedReasoning = isRecord(modelSettings.reasoning) ? modelSettings.reasoning : undefined;
|
|
379442
|
-
const modelId = modelHandle?.slice(modelHandle.indexOf("/") + 1);
|
|
379443
|
-
const preserveMax = modelId?.startsWith("gpt-5.6") === true;
|
|
379444
|
-
return thinkingLevelSetting(nestedReasoning?.reasoning_effort, preserveMax) ?? thinkingLevelSetting(modelSettings.effort, preserveMax) ?? thinkingLevelSetting(modelSettings.reasoning_effort, preserveMax);
|
|
379445
|
-
}
|
|
379446
|
-
function applyPiEnvOverrides(overrides) {
|
|
379447
|
-
if (!overrides)
|
|
379448
|
-
return () => {};
|
|
379449
|
-
const previous = new Map;
|
|
379450
|
-
for (const [key, value] of Object.entries(overrides)) {
|
|
379451
|
-
previous.set(key, process.env[key]);
|
|
379452
|
-
if (value === undefined) {
|
|
379453
|
-
delete process.env[key];
|
|
379454
|
-
} else {
|
|
379455
|
-
process.env[key] = value;
|
|
379456
|
-
}
|
|
379457
|
-
}
|
|
379458
|
-
return () => {
|
|
379459
|
-
for (const [key, value] of previous) {
|
|
379460
|
-
if (value === undefined) {
|
|
379461
|
-
delete process.env[key];
|
|
379462
|
-
} else {
|
|
379463
|
-
process.env[key] = value;
|
|
379464
|
-
}
|
|
379465
|
-
}
|
|
379466
|
-
};
|
|
379467
|
-
}
|
|
379468
|
-
function hasEnvValue2(value) {
|
|
379469
|
-
return typeof value === "string" && value.length > 0;
|
|
379470
|
-
}
|
|
379471
|
-
function inferDefaultProviderFromStandardKeys() {
|
|
379472
|
-
const hasOpenAIKey = hasEnvValue2(process.env.OPENAI_API_KEY);
|
|
379473
|
-
const hasAnthropicKey = hasEnvValue2(process.env.ANTHROPIC_API_KEY);
|
|
379474
|
-
if (!hasOpenAIKey && hasAnthropicKey)
|
|
379475
|
-
return "anthropic";
|
|
379476
|
-
return DEFAULT_PI_PROVIDER;
|
|
379477
|
-
}
|
|
379478
|
-
function resolvePiProvider(provider = process.env.LETTA_CODE_DEV_PI_PROVIDER ?? inferDefaultProviderFromStandardKeys()) {
|
|
379479
|
-
if (isPiProvider(provider))
|
|
379480
|
-
return provider;
|
|
379481
|
-
if (getRegisteredPiProvider(provider))
|
|
379482
|
-
return provider;
|
|
379483
|
-
throw new Error(`Unknown pi provider "${provider}". Expected ${expectedPiProviderList()}.`);
|
|
379484
|
-
}
|
|
379485
|
-
function resolvePiProviderFromAgent(model, modelSettings = {}) {
|
|
379486
|
-
const registeredProvider = resolveRegisteredPiProviderFromModelHandle(model);
|
|
379487
|
-
if (registeredProvider)
|
|
379488
|
-
return registeredProvider;
|
|
379489
|
-
const handleProvider = resolveProviderFromModelHandle(model);
|
|
379490
|
-
if (handleProvider)
|
|
379491
|
-
return handleProvider;
|
|
379492
|
-
const settingsProvider = resolveProviderFromProviderType(modelSettings.provider_type);
|
|
379493
|
-
if (settingsProvider)
|
|
379494
|
-
return settingsProvider;
|
|
379495
|
-
if (model && !isUnselectedLocalModelHandle(model)) {
|
|
379496
|
-
const slashIndex = model.indexOf("/");
|
|
379497
|
-
if (slashIndex > 0) {
|
|
379498
|
-
throw new Error(`Model provider "${model.slice(0, slashIndex)}" is not registered. Load or repair the provider mod, or choose another model with /model.`);
|
|
379499
|
-
}
|
|
379500
|
-
}
|
|
379501
|
-
return resolvePiProvider();
|
|
379502
|
-
}
|
|
379503
|
-
function resolvePiModelFromAgent(model, provider) {
|
|
379504
|
-
return stripProviderHandlePrefix(model, provider);
|
|
379505
|
-
}
|
|
379506
|
-
function localProviderRecord(providerNames, storageDir) {
|
|
379507
|
-
for (const providerName of providerNames) {
|
|
379508
|
-
const record5 = getLocalProviderRecordByName(providerName, storageDir);
|
|
379509
|
-
if (record5)
|
|
379510
|
-
return record5;
|
|
379511
|
-
}
|
|
379512
|
-
return null;
|
|
379513
|
-
}
|
|
379514
|
-
function localProviderConnection(providerNames, storageDir) {
|
|
379515
|
-
const record5 = localProviderRecord(providerNames, storageDir);
|
|
379516
|
-
return {
|
|
379517
|
-
baseURL: record5?.base_url,
|
|
379518
|
-
timeout: resolveLocalProviderTimeout({
|
|
379519
|
-
configuredTimeout: record5?.timeout,
|
|
379520
|
-
providerIds: providerNames
|
|
379521
|
-
}),
|
|
379522
|
-
...record5 ? { record: record5 } : {}
|
|
379523
|
-
};
|
|
379524
|
-
}
|
|
379525
|
-
function resolveZaiConnection(options3) {
|
|
379526
|
-
const regularRecord = localProviderRecord(["zai", LOCAL_ZAI_PROVIDER_NAME], options3.storageDir);
|
|
379527
|
-
const codingRecord = localProviderRecord(["zai_coding", LOCAL_ZAI_CODING_PROVIDER_NAME], options3.storageDir);
|
|
379528
|
-
const regularKey = localProviderApiKeyFromRecord(regularRecord) ?? process.env.ZAI_API_KEY ?? process.env.ZHIPU_API_KEY;
|
|
379529
|
-
const codingKey = localProviderApiKeyFromRecord(codingRecord) ?? process.env.ZAI_CODING_API_KEY;
|
|
379530
|
-
const regularConnection = {
|
|
379531
|
-
providerName: "zai",
|
|
379532
|
-
baseURL: regularRecord?.base_url ?? process.env.ZAI_BASE_URL ?? "https://api.z.ai/api/paas/v4",
|
|
379533
|
-
apiKey: regularKey,
|
|
379534
|
-
timeout: resolveLocalProviderTimeout({
|
|
379535
|
-
configuredTimeout: regularRecord?.timeout,
|
|
379536
|
-
providerIds: [LOCAL_ZAI_PROVIDER_NAME, "zai"]
|
|
379537
|
-
})
|
|
379538
|
-
};
|
|
379539
|
-
const codingConnection = {
|
|
379540
|
-
providerName: "zai-coding",
|
|
379541
|
-
baseURL: codingRecord?.base_url ?? process.env.ZAI_CODING_BASE_URL ?? "https://api.z.ai/api/coding/paas/v4",
|
|
379542
|
-
apiKey: codingKey,
|
|
379543
|
-
timeout: resolveLocalProviderTimeout({
|
|
379544
|
-
configuredTimeout: codingRecord?.timeout,
|
|
379545
|
-
providerIds: [LOCAL_ZAI_CODING_PROVIDER_NAME, "zai-coding"]
|
|
379546
|
-
})
|
|
379547
|
-
};
|
|
379548
|
-
if (options3.preferredProviderType === "zai_coding" && codingKey) {
|
|
379549
|
-
return codingConnection;
|
|
379550
|
-
}
|
|
379551
|
-
if (options3.preferredProviderType === "zai" && regularKey) {
|
|
379552
|
-
return regularConnection;
|
|
379553
|
-
}
|
|
379554
|
-
if (codingKey)
|
|
379555
|
-
return codingConnection;
|
|
379556
|
-
if (regularKey)
|
|
379557
|
-
return regularConnection;
|
|
379558
|
-
return codingConnection;
|
|
379559
|
-
}
|
|
379560
|
-
function fallbackCatalogModelId(provider, modelId) {
|
|
379561
|
-
if (provider !== "openai")
|
|
379562
|
-
return;
|
|
379563
|
-
const withoutReleaseDate = modelId.replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
379564
|
-
return withoutReleaseDate === modelId ? undefined : withoutReleaseDate;
|
|
379565
|
-
}
|
|
379566
|
-
function withOverrides(model, overrides) {
|
|
379567
|
-
return {
|
|
379568
|
-
...model,
|
|
379569
|
-
...overrides.baseURL ? { baseUrl: overrides.baseURL } : {},
|
|
379570
|
-
...overrides.headers ? { headers: { ...model.headers, ...overrides.headers } } : {},
|
|
379571
|
-
...overrides.contextWindow ? { contextWindow: overrides.contextWindow } : {},
|
|
379572
|
-
...overrides.maxTokens ? { maxTokens: overrides.maxTokens } : {}
|
|
379573
|
-
};
|
|
379574
|
-
}
|
|
379575
|
-
function nonNullHeaders(headers) {
|
|
379576
|
-
return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] !== null));
|
|
379577
|
-
}
|
|
379578
|
-
function mergeHeaders3(...headers) {
|
|
379579
|
-
const merged = {};
|
|
379580
|
-
for (const header of headers) {
|
|
379581
|
-
if (!header)
|
|
379582
|
-
continue;
|
|
379583
|
-
Object.assign(merged, header);
|
|
379584
|
-
}
|
|
379585
|
-
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
379586
|
-
}
|
|
379587
|
-
function numericSetting(value) {
|
|
379588
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
379589
|
-
}
|
|
379590
|
-
function bedrockLocalProviderOptions(record5) {
|
|
379591
|
-
if (!record5)
|
|
379592
|
-
return {};
|
|
379593
|
-
const providerOptions = {};
|
|
379594
|
-
const envOverrides = {};
|
|
379595
|
-
if (record5.region) {
|
|
379596
|
-
providerOptions.region = record5.region;
|
|
379597
|
-
envOverrides.AWS_REGION = record5.region;
|
|
379598
|
-
envOverrides.AWS_DEFAULT_REGION = record5.region;
|
|
379599
|
-
}
|
|
379600
|
-
if (record5.profile) {
|
|
379601
|
-
providerOptions.profile = record5.profile;
|
|
379602
|
-
envOverrides.AWS_PROFILE = record5.profile;
|
|
379603
|
-
}
|
|
379604
|
-
if (record5.auth.type === "api" && record5.auth.key) {
|
|
379605
|
-
if (record5.access_key) {
|
|
379606
|
-
envOverrides.AWS_ACCESS_KEY_ID = record5.access_key;
|
|
379607
|
-
envOverrides.AWS_SECRET_ACCESS_KEY = record5.auth.key;
|
|
379608
|
-
} else {
|
|
379609
|
-
providerOptions.bearerToken = record5.auth.key;
|
|
379610
|
-
envOverrides.AWS_BEARER_TOKEN_BEDROCK = record5.auth.key;
|
|
379611
|
-
}
|
|
379612
|
-
}
|
|
379613
|
-
return {
|
|
379614
|
-
...Object.keys(providerOptions).length > 0 ? { providerOptions } : {},
|
|
379615
|
-
...Object.keys(envOverrides).length > 0 ? { envOverrides } : {}
|
|
379616
|
-
};
|
|
379617
|
-
}
|
|
379618
|
-
async function resolvePiModelForAgent(modelHandle, modelSettings = {}, options3 = {}) {
|
|
379619
|
-
const concreteModelHandle = normalizeOpenAICompatibleLocalModelHandle(isUnselectedLocalModelHandle(modelHandle) ? undefined : modelHandle);
|
|
379620
|
-
const provider = options3.provider ? resolvePiProvider(options3.provider) : resolvePiProviderFromAgent(concreteModelHandle, modelSettings);
|
|
379621
|
-
const registeredProvider = getRegisteredPiProvider(provider);
|
|
379622
|
-
const spec = isPiProvider(provider) ? getPiProviderSpec(provider) : undefined;
|
|
379623
|
-
const modelId = options3.model ?? (registeredProvider ? stripRegisteredProviderHandlePrefix(concreteModelHandle, provider) : undefined) ?? (spec ? resolvePiModelFromAgent(concreteModelHandle, spec.id) : undefined) ?? registeredProvider?.config.models?.[0]?.id ?? (spec?.defaultModel ? resolvePiModelFromAgent(spec.defaultModel, spec.id) : undefined) ?? process.env.LETTA_CODE_DEV_PI_MODEL ?? "";
|
|
379624
|
-
const storageDir = options3.localProviderAuthStorageDir;
|
|
379625
|
-
const modelsRuntime = options3.modelsRuntime ?? new LocalPiModelsRuntime({
|
|
379626
|
-
...storageDir ? { storageDir } : {}
|
|
379627
|
-
});
|
|
379628
|
-
const preferredProviderType = typeof modelSettings.provider_type === "string" ? modelSettings.provider_type : options3.preferredProviderType;
|
|
379629
|
-
const localNames = registeredProvider ? localNamesForProviderId(provider) : spec?.localProviderNames ?? [provider];
|
|
379630
|
-
let connection = localProviderConnection(localNames, storageDir);
|
|
379631
|
-
let baseURL = connection.baseURL ?? spec?.baseUrlEnv?.() ?? spec?.defaultBaseURL ?? registeredProvider?.config.baseUrl;
|
|
379632
|
-
let headers = mergeHeaders3(spec?.headers?.());
|
|
379633
|
-
let providerOptions;
|
|
379634
|
-
let envOverrides;
|
|
379635
|
-
let oauthCredentials;
|
|
379636
|
-
if (!modelId) {
|
|
379637
|
-
throw new Error(`No model selected for provider "${provider}". Choose an available model with /model.`);
|
|
379638
|
-
}
|
|
379639
|
-
const runtimeProviderId = registeredProvider ? provider : spec && modelsRuntime.isRuntimeManagedProvider(spec.id) ? spec.id : spec?.piProvider;
|
|
379640
|
-
if (!runtimeProviderId) {
|
|
379641
|
-
throw new Error(`Unknown model "${modelId}" for provider "${provider}". ` + "Register the provider with models before using it.");
|
|
379642
|
-
}
|
|
379643
|
-
const fallbackModelId = !registeredProvider && spec?.piProvider ? fallbackCatalogModelId(spec.piProvider, modelId) : undefined;
|
|
379644
|
-
const { model: publishedModel, auth: authResult } = await modelsRuntime.resolveTurn(runtimeProviderId, modelId, fallbackModelId);
|
|
379645
|
-
connection = { ...connection, apiKey: authResult?.auth.apiKey };
|
|
379646
|
-
if (authResult?.auth.baseUrl)
|
|
379647
|
-
baseURL = authResult.auth.baseUrl;
|
|
379648
|
-
if (authResult?.auth.headers) {
|
|
379649
|
-
headers = mergeHeaders3(headers, nonNullHeaders(authResult.auth.headers));
|
|
379650
|
-
}
|
|
379651
|
-
if (connection.record?.auth.type === "oauth") {
|
|
379652
|
-
const stored = await modelsRuntime.getStoredCredential(runtimeProviderId);
|
|
379653
|
-
oauthCredentials = stored?.type === "oauth" ? stored : undefined;
|
|
379654
|
-
}
|
|
379655
|
-
if (provider === "zai") {
|
|
379656
|
-
const zai = resolveZaiConnection({
|
|
379657
|
-
storageDir,
|
|
379658
|
-
preferredProviderType: preferredProviderType === "zai" || preferredProviderType === "zai_coding" ? preferredProviderType : undefined
|
|
379659
|
-
});
|
|
379660
|
-
connection = {
|
|
379661
|
-
apiKey: zai.apiKey,
|
|
379662
|
-
baseURL: zai.baseURL,
|
|
379663
|
-
timeout: zai.timeout
|
|
379664
|
-
};
|
|
379665
|
-
baseURL = zai.baseURL;
|
|
379666
|
-
}
|
|
379667
|
-
if (provider === "amazon-bedrock") {
|
|
379668
|
-
const bedrock = bedrockLocalProviderOptions(connection.record);
|
|
379669
|
-
providerOptions = bedrock.providerOptions;
|
|
379670
|
-
envOverrides = bedrock.envOverrides;
|
|
379671
|
-
}
|
|
379672
|
-
if (!publishedModel) {
|
|
379673
|
-
throw new Error(`Unknown model "${modelId}" for provider "${provider}". ` + "Choose an available model with /model.");
|
|
379674
|
-
}
|
|
379675
|
-
const hookedModel = oauthCredentials && registeredProvider?.config.oauth?.modifyModels ? registeredProvider.config.oauth.modifyModels([structuredClone(publishedModel)], oauthCredentials)[0] ?? publishedModel : publishedModel;
|
|
379676
|
-
const contextWindow = numericSetting(modelSettings.context_window_limit);
|
|
379677
|
-
const maxTokens = numericSetting(modelSettings.max_tokens);
|
|
379678
|
-
const allowBaseUrlOverride = !registeredProvider && spec !== undefined && !modelsRuntime.isRuntimeManagedProvider(spec.id);
|
|
379679
|
-
const overrides = {
|
|
379680
|
-
...allowBaseUrlOverride && baseURL && baseURL !== hookedModel.baseUrl ? { baseURL } : {},
|
|
379681
|
-
...contextWindow && contextWindow !== hookedModel.contextWindow ? { contextWindow } : {},
|
|
379682
|
-
...maxTokens && maxTokens !== hookedModel.maxTokens ? { maxTokens } : {}
|
|
379683
|
-
};
|
|
379684
|
-
const model = Object.keys(overrides).length > 0 ? withOverrides(hookedModel, overrides) : hookedModel;
|
|
379685
|
-
return {
|
|
379686
|
-
provider,
|
|
379687
|
-
model,
|
|
379688
|
-
apiKey: connection.apiKey,
|
|
379689
|
-
timeout: connection.timeout,
|
|
379690
|
-
headers,
|
|
379691
|
-
providerOptions,
|
|
379692
|
-
envOverrides
|
|
379693
|
-
};
|
|
379694
|
-
}
|
|
379695
|
-
var DEFAULT_PI_PROVIDER = "openai", UNSELECTED_LOCAL_MODEL_HANDLE = "local/default";
|
|
379696
|
-
var init_pi_model_factory = __esm(() => {
|
|
379697
|
-
init_local_pi_credential_store();
|
|
379698
|
-
init_local_provider_auth_store();
|
|
379699
|
-
init_local_provider_timeout();
|
|
379700
|
-
init_pi_models_runtime();
|
|
379701
|
-
init_pi_provider_mod_registry();
|
|
379702
|
-
init_pi_provider_registry();
|
|
379703
|
-
});
|
|
379704
|
-
|
|
379705
379455
|
// src/backend/local/local-model-config.ts
|
|
379706
379456
|
function localProviderNamesFromRecords(records) {
|
|
379707
379457
|
return new Set(records.map((record5) => record5.name));
|
|
@@ -380358,6 +380108,285 @@ Write in first person as a factual record of what occurred. Be thorough and deta
|
|
|
380358
380108
|
Keep your summary under ${SLIDING_WORD_LIMIT} words. Only output the summary.`;
|
|
380359
380109
|
});
|
|
380360
380110
|
|
|
380111
|
+
// src/backend/dev/provider-turn-executor.ts
|
|
380112
|
+
var exports_provider_turn_executor = {};
|
|
380113
|
+
__export(exports_provider_turn_executor, {
|
|
380114
|
+
shouldCompactForContextPressure: () => shouldCompactForContextPressure,
|
|
380115
|
+
providerStreamPart: () => providerStreamPart,
|
|
380116
|
+
providerLocalMessage: () => providerLocalMessage,
|
|
380117
|
+
providerLettaChunk: () => providerLettaChunk,
|
|
380118
|
+
estimateProviderRequestBytes: () => estimateProviderRequestBytes,
|
|
380119
|
+
estimateProviderContextTokens: () => estimateProviderContextTokens,
|
|
380120
|
+
contextTokensFromUsage: () => contextTokensFromUsage,
|
|
380121
|
+
contextCompactionThreshold: () => contextCompactionThreshold,
|
|
380122
|
+
buildProviderTurnInput: () => buildProviderTurnInput,
|
|
380123
|
+
ProviderTurnExecutor: () => ProviderTurnExecutor
|
|
380124
|
+
});
|
|
380125
|
+
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
380126
|
+
function providerStreamPart(part) {
|
|
380127
|
+
return { type: "provider-part", part };
|
|
380128
|
+
}
|
|
380129
|
+
function providerLocalMessage(message) {
|
|
380130
|
+
return { type: "local-message", message };
|
|
380131
|
+
}
|
|
380132
|
+
function providerLettaChunk(chunk) {
|
|
380133
|
+
return { type: "letta-chunk", chunk };
|
|
380134
|
+
}
|
|
380135
|
+
|
|
380136
|
+
class MissingProviderStreamAdapter {
|
|
380137
|
+
async* stream() {
|
|
380138
|
+
yield {
|
|
380139
|
+
type: "error",
|
|
380140
|
+
error: new Error("Provider turn adapter is not configured for this dev backend")
|
|
380141
|
+
};
|
|
380142
|
+
}
|
|
380143
|
+
}
|
|
380144
|
+
function bodyListField(body, key) {
|
|
380145
|
+
const value = body[key];
|
|
380146
|
+
return Array.isArray(value) ? value : [];
|
|
380147
|
+
}
|
|
380148
|
+
function buildProviderTurnInput(input) {
|
|
380149
|
+
return {
|
|
380150
|
+
conversationId: input.conversationId,
|
|
380151
|
+
agentId: input.agentId,
|
|
380152
|
+
agent: input.agent,
|
|
380153
|
+
systemPrompt: input.systemPrompt,
|
|
380154
|
+
midConversationSystemPrompt: input.midConversationSystemPrompt,
|
|
380155
|
+
body: input.body,
|
|
380156
|
+
history: input.history,
|
|
380157
|
+
uiMessages: input.uiMessages,
|
|
380158
|
+
clientTools: bodyListField(input.body, "client_tools"),
|
|
380159
|
+
clientSkills: bodyListField(input.body, "client_skills")
|
|
380160
|
+
};
|
|
380161
|
+
}
|
|
380162
|
+
function stringifyToolInput(input) {
|
|
380163
|
+
if (typeof input === "string")
|
|
380164
|
+
return input;
|
|
380165
|
+
return JSON.stringify(input ?? {});
|
|
380166
|
+
}
|
|
380167
|
+
function createLocalMessageChunk(message) {
|
|
380168
|
+
return markLocalStateChunkOnly(attachLocalMessage({ message_type: "local_message" }, message));
|
|
380169
|
+
}
|
|
380170
|
+
function createProviderErrorChunks(error54) {
|
|
380171
|
+
const info = normalizeLocalProviderError(error54);
|
|
380172
|
+
return [
|
|
380173
|
+
{
|
|
380174
|
+
message_type: "error_message",
|
|
380175
|
+
message: info.message,
|
|
380176
|
+
detail: info.detail,
|
|
380177
|
+
error_type: info.error_type,
|
|
380178
|
+
retryable: info.retryable
|
|
380179
|
+
},
|
|
380180
|
+
{
|
|
380181
|
+
message_type: "stop_reason",
|
|
380182
|
+
stop_reason: info.stop_reason
|
|
380183
|
+
}
|
|
380184
|
+
];
|
|
380185
|
+
}
|
|
380186
|
+
function contextTokensFromUsage(usage) {
|
|
380187
|
+
return contextTokensFromLocalUsage(usage);
|
|
380188
|
+
}
|
|
380189
|
+
function estimateSerializedTokens(value) {
|
|
380190
|
+
if (value === undefined || value === null)
|
|
380191
|
+
return 0;
|
|
380192
|
+
try {
|
|
380193
|
+
const serialized = typeof value === "string" ? value : JSON.stringify(value) ?? "";
|
|
380194
|
+
return Math.ceil(serialized.length / 4);
|
|
380195
|
+
} catch {
|
|
380196
|
+
return 0;
|
|
380197
|
+
}
|
|
380198
|
+
}
|
|
380199
|
+
function estimateProviderContextTokens(input) {
|
|
380200
|
+
const contextEstimate = estimateLocalContextTokens(input.uiMessages);
|
|
380201
|
+
if (contextEstimate.lastUsageIndex !== null) {
|
|
380202
|
+
return contextEstimate.tokens > 0 ? contextEstimate.tokens : undefined;
|
|
380203
|
+
}
|
|
380204
|
+
const systemPromptTokens = estimateSerializedTokens(input.systemPrompt ?? input.agent.system);
|
|
380205
|
+
const messageTokens = contextEstimate.tokens;
|
|
380206
|
+
const toolTokens = estimateSerializedTokens(input.clientTools);
|
|
380207
|
+
const total = systemPromptTokens + messageTokens + toolTokens;
|
|
380208
|
+
return total > 0 ? total : undefined;
|
|
380209
|
+
}
|
|
380210
|
+
function contextCompactionThreshold(contextWindow) {
|
|
380211
|
+
if (typeof contextWindow !== "number" || !Number.isFinite(contextWindow) || contextWindow <= 0) {
|
|
380212
|
+
return;
|
|
380213
|
+
}
|
|
380214
|
+
const reserveTokens = Math.min(LOCAL_CONTEXT_COMPACTION_RESERVE_TOKENS, Math.max(1, Math.floor(contextWindow * LOCAL_SMALL_CONTEXT_COMPACTION_RESERVE_RATIO)));
|
|
380215
|
+
return Math.max(0, contextWindow - reserveTokens);
|
|
380216
|
+
}
|
|
380217
|
+
function shouldCompactForContextPressure(input) {
|
|
380218
|
+
const threshold = contextCompactionThreshold(input.contextWindow);
|
|
380219
|
+
return input.contextTokens !== undefined && threshold !== undefined && input.contextTokens > threshold;
|
|
380220
|
+
}
|
|
380221
|
+
function serializedLength(value) {
|
|
380222
|
+
if (value === undefined || value === null)
|
|
380223
|
+
return 0;
|
|
380224
|
+
try {
|
|
380225
|
+
const serialized = typeof value === "string" ? value : JSON.stringify(value) ?? "";
|
|
380226
|
+
return serialized.length;
|
|
380227
|
+
} catch {
|
|
380228
|
+
return 0;
|
|
380229
|
+
}
|
|
380230
|
+
}
|
|
380231
|
+
function estimateProviderRequestBytes(input) {
|
|
380232
|
+
const systemPromptBytes = serializedLength(input.systemPrompt ?? input.agent.system);
|
|
380233
|
+
const messageBytes = serializedLength(input.uiMessages);
|
|
380234
|
+
const toolBytes = serializedLength(input.clientTools);
|
|
380235
|
+
const total = systemPromptBytes + messageBytes + toolBytes;
|
|
380236
|
+
return total > 0 ? total : undefined;
|
|
380237
|
+
}
|
|
380238
|
+
function createUsageStatisticsChunk(usage, contextTokensEstimate) {
|
|
380239
|
+
const promptTokens = usage?.input;
|
|
380240
|
+
const completionTokens = usage?.output;
|
|
380241
|
+
const totalTokens = usage?.totalTokens;
|
|
380242
|
+
const usageContextTokens = usage ? contextTokensFromUsage(usage) : undefined;
|
|
380243
|
+
const contextTokens = usageContextTokens ?? contextTokensEstimate;
|
|
380244
|
+
const cachedInputTokens = usage?.cacheRead;
|
|
380245
|
+
const cacheWriteTokens = usage?.cacheWrite;
|
|
380246
|
+
if (promptTokens === undefined && completionTokens === undefined && totalTokens === undefined && cachedInputTokens === undefined && cacheWriteTokens === undefined && contextTokens === undefined) {
|
|
380247
|
+
return;
|
|
380248
|
+
}
|
|
380249
|
+
return {
|
|
380250
|
+
message_type: "usage_statistics",
|
|
380251
|
+
...promptTokens !== undefined ? { prompt_tokens: promptTokens } : {},
|
|
380252
|
+
...completionTokens !== undefined ? { completion_tokens: completionTokens } : {},
|
|
380253
|
+
...totalTokens !== undefined ? { total_tokens: totalTokens } : {},
|
|
380254
|
+
...cachedInputTokens !== undefined ? { cached_input_tokens: cachedInputTokens } : {},
|
|
380255
|
+
...cacheWriteTokens !== undefined ? { cache_write_tokens: cacheWriteTokens } : {},
|
|
380256
|
+
...contextTokens !== undefined ? { context_tokens: contextTokens } : {}
|
|
380257
|
+
};
|
|
380258
|
+
}
|
|
380259
|
+
function errorFromAssistantEvent(part) {
|
|
380260
|
+
if (part.type !== "error")
|
|
380261
|
+
return new Error("Unknown provider stream error");
|
|
380262
|
+
return new Error(part.error.errorMessage ?? "Unknown local provider error");
|
|
380263
|
+
}
|
|
380264
|
+
function contentMatchesMessageType(content, messageType) {
|
|
380265
|
+
if (!content || typeof content !== "object" || !("type" in content)) {
|
|
380266
|
+
return false;
|
|
380267
|
+
}
|
|
380268
|
+
return messageType === "assistant_message" ? content.type === "text" : content.type === "thinking";
|
|
380269
|
+
}
|
|
380270
|
+
function contiguousContentStartIndex(partial4, contentIndex, messageType) {
|
|
380271
|
+
let startIndex = contentIndex;
|
|
380272
|
+
while (startIndex > 0 && contentMatchesMessageType(partial4.content[startIndex - 1], messageType)) {
|
|
380273
|
+
startIndex -= 1;
|
|
380274
|
+
}
|
|
380275
|
+
return startIndex;
|
|
380276
|
+
}
|
|
380277
|
+
function otidForContentSegment(otids, prefix, contentIndex, partial4, messageType) {
|
|
380278
|
+
const segmentStartIndex = contiguousContentStartIndex(partial4, contentIndex, messageType);
|
|
380279
|
+
const existing = otids.get(segmentStartIndex);
|
|
380280
|
+
if (existing)
|
|
380281
|
+
return existing;
|
|
380282
|
+
const otid = `${prefix}-${segmentStartIndex}-${randomUUID21()}`;
|
|
380283
|
+
otids.set(segmentStartIndex, otid);
|
|
380284
|
+
return otid;
|
|
380285
|
+
}
|
|
380286
|
+
function createProviderLettaStream(events, contextTokensEstimate) {
|
|
380287
|
+
const controller = new AbortController;
|
|
380288
|
+
return {
|
|
380289
|
+
controller,
|
|
380290
|
+
async* [Symbol.asyncIterator]() {
|
|
380291
|
+
let sawToolCall = false;
|
|
380292
|
+
let pendingStopReason;
|
|
380293
|
+
let sawUsageStatistics = false;
|
|
380294
|
+
const assistantOtids = new Map;
|
|
380295
|
+
const reasoningOtids = new Map;
|
|
380296
|
+
try {
|
|
380297
|
+
for await (const event2 of events) {
|
|
380298
|
+
if (event2.type === "error") {
|
|
380299
|
+
yield* createProviderErrorChunks(event2.error);
|
|
380300
|
+
return;
|
|
380301
|
+
}
|
|
380302
|
+
if (event2.type === "local-message") {
|
|
380303
|
+
yield createLocalMessageChunk(event2.message);
|
|
380304
|
+
continue;
|
|
380305
|
+
}
|
|
380306
|
+
if (event2.type === "letta-chunk") {
|
|
380307
|
+
yield event2.chunk;
|
|
380308
|
+
continue;
|
|
380309
|
+
}
|
|
380310
|
+
const { part } = event2;
|
|
380311
|
+
if (part.type === "text_delta") {
|
|
380312
|
+
yield {
|
|
380313
|
+
message_type: "assistant_message",
|
|
380314
|
+
otid: otidForContentSegment(assistantOtids, "provider-assistant", part.contentIndex, part.partial, "assistant_message"),
|
|
380315
|
+
content: [{ type: "text", text: part.delta }]
|
|
380316
|
+
};
|
|
380317
|
+
continue;
|
|
380318
|
+
}
|
|
380319
|
+
if (part.type === "thinking_delta") {
|
|
380320
|
+
yield {
|
|
380321
|
+
message_type: "reasoning_message",
|
|
380322
|
+
otid: otidForContentSegment(reasoningOtids, "provider-reasoning", part.contentIndex, part.partial, "reasoning_message"),
|
|
380323
|
+
reasoning: part.delta
|
|
380324
|
+
};
|
|
380325
|
+
continue;
|
|
380326
|
+
}
|
|
380327
|
+
if (part.type === "toolcall_end") {
|
|
380328
|
+
sawToolCall = true;
|
|
380329
|
+
yield {
|
|
380330
|
+
message_type: "approval_request_message",
|
|
380331
|
+
tool_call: {
|
|
380332
|
+
tool_call_id: part.toolCall.id,
|
|
380333
|
+
name: part.toolCall.name,
|
|
380334
|
+
arguments: stringifyToolInput(part.toolCall.arguments)
|
|
380335
|
+
}
|
|
380336
|
+
};
|
|
380337
|
+
continue;
|
|
380338
|
+
}
|
|
380339
|
+
if (part.type === "done") {
|
|
380340
|
+
if (!sawUsageStatistics) {
|
|
380341
|
+
const usageChunk = createUsageStatisticsChunk(part.message.usage, contextTokensEstimate);
|
|
380342
|
+
if (usageChunk) {
|
|
380343
|
+
sawUsageStatistics = true;
|
|
380344
|
+
yield usageChunk;
|
|
380345
|
+
}
|
|
380346
|
+
}
|
|
380347
|
+
pendingStopReason = {
|
|
380348
|
+
message_type: "stop_reason",
|
|
380349
|
+
stop_reason: sawToolCall || part.reason === "toolUse" ? "requires_approval" : part.reason === "length" ? "max_tokens_exceeded" : "end_turn"
|
|
380350
|
+
};
|
|
380351
|
+
continue;
|
|
380352
|
+
}
|
|
380353
|
+
if (part.type === "error") {
|
|
380354
|
+
yield* createProviderErrorChunks(errorFromAssistantEvent(part));
|
|
380355
|
+
return;
|
|
380356
|
+
}
|
|
380357
|
+
}
|
|
380358
|
+
if (pendingStopReason) {
|
|
380359
|
+
yield pendingStopReason;
|
|
380360
|
+
} else if (sawToolCall) {
|
|
380361
|
+
yield {
|
|
380362
|
+
message_type: "stop_reason",
|
|
380363
|
+
stop_reason: "requires_approval"
|
|
380364
|
+
};
|
|
380365
|
+
}
|
|
380366
|
+
} catch (error54) {
|
|
380367
|
+
yield* createProviderErrorChunks(error54);
|
|
380368
|
+
}
|
|
380369
|
+
}
|
|
380370
|
+
};
|
|
380371
|
+
}
|
|
380372
|
+
|
|
380373
|
+
class ProviderTurnExecutor {
|
|
380374
|
+
adapter;
|
|
380375
|
+
constructor(adapter = new MissingProviderStreamAdapter) {
|
|
380376
|
+
this.adapter = adapter;
|
|
380377
|
+
}
|
|
380378
|
+
async execute(input) {
|
|
380379
|
+
const providerInput = buildProviderTurnInput(input);
|
|
380380
|
+
const events = await this.adapter.stream(providerInput);
|
|
380381
|
+
return createProviderLettaStream(events, estimateProviderContextTokens(providerInput));
|
|
380382
|
+
}
|
|
380383
|
+
}
|
|
380384
|
+
var LOCAL_CONTEXT_COMPACTION_RESERVE_TOKENS = 16384, LOCAL_SMALL_CONTEXT_COMPACTION_RESERVE_RATIO = 0.2;
|
|
380385
|
+
var init_provider_turn_executor = __esm(() => {
|
|
380386
|
+
init_local_stream_chunks();
|
|
380387
|
+
init_local_provider_errors();
|
|
380388
|
+
});
|
|
380389
|
+
|
|
380361
380390
|
// src/backend/dev/pi-image-elision.ts
|
|
380362
380391
|
function localProviderRequestByteLimit() {
|
|
380363
380392
|
const raw = process.env[LOCAL_PROVIDER_REQUEST_BYTE_LIMIT_ENV];
|
|
@@ -380743,7 +380772,7 @@ class PiStreamAdapter {
|
|
|
380743
380772
|
localProviderAuthStorageDir;
|
|
380744
380773
|
modelsRuntime;
|
|
380745
380774
|
onContextWindowOverflow;
|
|
380746
|
-
|
|
380775
|
+
onContextPressure;
|
|
380747
380776
|
onLlmStart;
|
|
380748
380777
|
onLlmEnd;
|
|
380749
380778
|
constructor(options3 = {}) {
|
|
@@ -380754,7 +380783,7 @@ class PiStreamAdapter {
|
|
|
380754
380783
|
this.abortSignal = options3.abortSignal;
|
|
380755
380784
|
this.localProviderAuthStorageDir = options3.localProviderAuthStorageDir;
|
|
380756
380785
|
this.onContextWindowOverflow = options3.onContextWindowOverflow;
|
|
380757
|
-
this.
|
|
380786
|
+
this.onContextPressure = options3.onContextPressure;
|
|
380758
380787
|
this.onLlmStart = options3.onLlmStart;
|
|
380759
380788
|
this.onLlmEnd = options3.onLlmEnd;
|
|
380760
380789
|
}
|
|
@@ -380771,6 +380800,33 @@ class PiStreamAdapter {
|
|
|
380771
380800
|
...compaction.stats ? { compaction_stats: compaction.stats } : {}
|
|
380772
380801
|
});
|
|
380773
380802
|
}
|
|
380803
|
+
async compactBeforeProviderCall(input) {
|
|
380804
|
+
if (!this.onContextPressure)
|
|
380805
|
+
return null;
|
|
380806
|
+
const contextTokens = estimateProviderContextTokens(input);
|
|
380807
|
+
if (contextTokens === undefined)
|
|
380808
|
+
return null;
|
|
380809
|
+
const localModel = await resolveAvailableLocalModelForTurn({
|
|
380810
|
+
model: input.agent.model,
|
|
380811
|
+
modelSettings: input.agent.model_settings,
|
|
380812
|
+
storageDir: this.localProviderAuthStorageDir,
|
|
380813
|
+
modelsRuntime: this.modelsRuntime
|
|
380814
|
+
});
|
|
380815
|
+
const resolved = await resolvePiModelForAgent(localModel.model, localModel.modelSettings, {
|
|
380816
|
+
localProviderAuthStorageDir: this.localProviderAuthStorageDir,
|
|
380817
|
+
modelsRuntime: this.modelsRuntime
|
|
380818
|
+
});
|
|
380819
|
+
const contextWindow = resolved.model.contextWindow;
|
|
380820
|
+
if (!shouldCompactForContextPressure({ contextTokens, contextWindow })) {
|
|
380821
|
+
return null;
|
|
380822
|
+
}
|
|
380823
|
+
return this.onContextPressure(input, {
|
|
380824
|
+
contextTokens,
|
|
380825
|
+
contextWindow,
|
|
380826
|
+
phase: "preflight",
|
|
380827
|
+
source: "estimate"
|
|
380828
|
+
});
|
|
380829
|
+
}
|
|
380774
380830
|
async* streamOnce(input) {
|
|
380775
380831
|
const tools = toPiTools(input.clientTools);
|
|
380776
380832
|
const localModel = await resolveAvailableLocalModelForTurn({
|
|
@@ -380839,6 +380895,7 @@ class PiStreamAdapter {
|
|
|
380839
380895
|
const result = this.runStream(resolved.model, context3, options3);
|
|
380840
380896
|
let streamError;
|
|
380841
380897
|
let finalMessage;
|
|
380898
|
+
let finalLocalMessage;
|
|
380842
380899
|
for await (const part of result) {
|
|
380843
380900
|
if (part.type === "error") {
|
|
380844
380901
|
const error54 = new PiProviderError(part.error);
|
|
@@ -380849,7 +380906,8 @@ class PiStreamAdapter {
|
|
|
380849
380906
|
}
|
|
380850
380907
|
if (part.type === "done") {
|
|
380851
380908
|
finalMessage = part.message;
|
|
380852
|
-
|
|
380909
|
+
finalLocalMessage = toLocalAssistantMessage(part.message, input);
|
|
380910
|
+
yield providerLocalMessage(finalLocalMessage);
|
|
380853
380911
|
}
|
|
380854
380912
|
yield providerStreamPart(part);
|
|
380855
380913
|
}
|
|
@@ -380869,8 +380927,22 @@ class PiStreamAdapter {
|
|
|
380869
380927
|
if (finalMessage.stopReason === "error" || finalMessage.stopReason === "aborted") {
|
|
380870
380928
|
throw new PiProviderError(finalMessage);
|
|
380871
380929
|
}
|
|
380872
|
-
if (this.
|
|
380873
|
-
const
|
|
380930
|
+
if (this.onContextPressure) {
|
|
380931
|
+
const usageContextTokens = contextTokensFromUsage(finalMessage.usage);
|
|
380932
|
+
const contextTokens = usageContextTokens ?? estimateProviderContextTokens({
|
|
380933
|
+
...input,
|
|
380934
|
+
uiMessages: [
|
|
380935
|
+
...input.uiMessages,
|
|
380936
|
+
finalLocalMessage ?? toLocalAssistantMessage(finalMessage, input)
|
|
380937
|
+
]
|
|
380938
|
+
});
|
|
380939
|
+
const contextWindow = resolved.model.contextWindow;
|
|
380940
|
+
const compaction = shouldCompactForContextPressure({ contextTokens, contextWindow }) && contextTokens !== undefined ? await this.onContextPressure(input, {
|
|
380941
|
+
contextTokens,
|
|
380942
|
+
contextWindow,
|
|
380943
|
+
phase: "post_turn",
|
|
380944
|
+
source: usageContextTokens === undefined ? "estimate" : "usage"
|
|
380945
|
+
}) : null;
|
|
380874
380946
|
if (compaction) {
|
|
380875
380947
|
yield* this.emitCompactionChunks(compaction, "context_window_limit");
|
|
380876
380948
|
}
|
|
@@ -380891,9 +380963,19 @@ class PiStreamAdapter {
|
|
|
380891
380963
|
}
|
|
380892
380964
|
async* stream(input) {
|
|
380893
380965
|
let activeInput = input;
|
|
380966
|
+
let preflightCompactionChecked = false;
|
|
380894
380967
|
let contextOverflowCompactions = 0;
|
|
380895
380968
|
let transientRetries = 0;
|
|
380896
380969
|
while (true) {
|
|
380970
|
+
if (!preflightCompactionChecked) {
|
|
380971
|
+
preflightCompactionChecked = true;
|
|
380972
|
+
const compaction = await this.compactBeforeProviderCall(activeInput);
|
|
380973
|
+
if (compaction) {
|
|
380974
|
+
activeInput = { ...activeInput, uiMessages: compaction.uiMessages };
|
|
380975
|
+
yield* this.emitCompactionChunks(compaction, "context_window_limit");
|
|
380976
|
+
continue;
|
|
380977
|
+
}
|
|
380978
|
+
}
|
|
380897
380979
|
let emittedModelOutput = false;
|
|
380898
380980
|
try {
|
|
380899
380981
|
for await (const event2 of this.streamOnce(activeInput)) {
|
|
@@ -380994,7 +381076,7 @@ var init_pi_stream_adapter = __esm(() => {
|
|
|
380994
381076
|
});
|
|
380995
381077
|
|
|
380996
381078
|
// src/backend/local/local-executor-factory.ts
|
|
380997
|
-
function createLocalExecutor(options3, modelsRuntime, onContextWindowOverflow,
|
|
381079
|
+
function createLocalExecutor(options3, modelsRuntime, onContextWindowOverflow, onContextPressure, onLlmStart, onLlmEnd) {
|
|
380998
381080
|
if (options3.executor)
|
|
380999
381081
|
return options3.executor;
|
|
381000
381082
|
if (options3.executionMode === "deterministic") {
|
|
@@ -381005,7 +381087,7 @@ function createLocalExecutor(options3, modelsRuntime, onContextWindowOverflow, o
|
|
|
381005
381087
|
localProviderAuthStorageDir: options3.storageDir,
|
|
381006
381088
|
modelsRuntime,
|
|
381007
381089
|
onContextWindowOverflow,
|
|
381008
|
-
|
|
381090
|
+
onContextPressure,
|
|
381009
381091
|
onLlmStart,
|
|
381010
381092
|
onLlmEnd
|
|
381011
381093
|
}));
|
|
@@ -381455,7 +381537,6 @@ var init_local_backend = __esm(() => {
|
|
|
381455
381537
|
init_memory_git();
|
|
381456
381538
|
init_headless_backend();
|
|
381457
381539
|
init_pi_models_runtime();
|
|
381458
|
-
init_provider_turn_executor();
|
|
381459
381540
|
init_compaction();
|
|
381460
381541
|
init_local_executor_factory();
|
|
381461
381542
|
init_local_model_config();
|
|
@@ -381495,7 +381576,7 @@ var init_local_backend = __esm(() => {
|
|
|
381495
381576
|
storedMessageIdPrefix: "letta-msg-",
|
|
381496
381577
|
localMessageIdPrefix: "ui-msg-"
|
|
381497
381578
|
};
|
|
381498
|
-
super(options3.defaultAgentId ?? "agent-local-default", createLocalExecutor(options3, runtime, (input, error54) => localBackendRef.current?.compactAfterContextOverflow(input, error54) ?? Promise.resolve(null), (input,
|
|
381579
|
+
super(options3.defaultAgentId ?? "agent-local-default", createLocalExecutor(options3, runtime, (input, error54) => localBackendRef.current?.compactAfterContextOverflow(input, error54) ?? Promise.resolve(null), (input, pressure) => localBackendRef.current?.compactForContextPressure(input, pressure) ?? Promise.resolve(null), (info) => localBackendRef.current?.emitLlmStart(info) ?? Promise.resolve(), (info) => localBackendRef.current?.emitLlmEnd(info) ?? Promise.resolve()), storeOptions, {
|
|
381499
381580
|
modelHandle: modelConfig.handle,
|
|
381500
381581
|
runIdPrefix: "local-run-",
|
|
381501
381582
|
runMetadataBackend: "local"
|
|
@@ -381654,12 +381735,7 @@ var init_local_backend = __esm(() => {
|
|
|
381654
381735
|
stats: result.stats
|
|
381655
381736
|
};
|
|
381656
381737
|
}
|
|
381657
|
-
async
|
|
381658
|
-
const contextTokens = contextTokensFromUsage(usage) ?? estimateProviderContextTokens(input);
|
|
381659
|
-
const contextWindow = this.effectiveContextWindow(input.conversationId, input.agentId);
|
|
381660
|
-
if (contextTokens === undefined || contextWindow === undefined || contextTokens <= contextWindow) {
|
|
381661
|
-
return null;
|
|
381662
|
-
}
|
|
381738
|
+
async compactForContextPressure(input, _pressure) {
|
|
381663
381739
|
const result = await this.compactLocalConversation(input.conversationId, input.agentId, "context_window_limit");
|
|
381664
381740
|
return {
|
|
381665
381741
|
uiMessages: this.store.listLocalMessages(input.conversationId, input.agentId),
|
|
@@ -470002,11 +470078,6 @@ async function startAppServer(options3 = {}) {
|
|
|
470002
470078
|
});
|
|
470003
470079
|
server2.on("upgrade", (request, socket, head2) => {
|
|
470004
470080
|
const requestUrl = getRequestUrl(request, listen.host);
|
|
470005
|
-
if (request.headers.origin) {
|
|
470006
|
-
options3.onLog?.(`Rejecting app-server websocket request with Origin header: ${request.url ?? "/"}`);
|
|
470007
|
-
rejectUpgrade(socket, 403, "Forbidden");
|
|
470008
|
-
return;
|
|
470009
|
-
}
|
|
470010
470081
|
if (requestUrl.pathname !== listen.path && requestUrl.pathname !== "/") {
|
|
470011
470082
|
rejectUpgrade(socket, 404, "Not Found");
|
|
470012
470083
|
return;
|
|
@@ -470022,6 +470093,11 @@ async function startAppServer(options3 = {}) {
|
|
|
470022
470093
|
rejectUpgrade(socket, authError.statusCode, authError.message);
|
|
470023
470094
|
return;
|
|
470024
470095
|
}
|
|
470096
|
+
if (request.headers.origin !== undefined && authPolicy.mode === undefined) {
|
|
470097
|
+
options3.onLog?.(`Rejecting unauthenticated app-server websocket request with Origin header: ${request.url ?? "/"}; native clients such as React Native must configure --ws-auth capability-token or --ws-auth signed-bearer-token`);
|
|
470098
|
+
rejectUpgrade(socket, 403, "Forbidden");
|
|
470099
|
+
return;
|
|
470100
|
+
}
|
|
470025
470101
|
wss.handleUpgrade(request, socket, head2, (websocket) => {
|
|
470026
470102
|
handleWebSocketConnection(websocket, channel);
|
|
470027
470103
|
});
|
|
@@ -470130,7 +470206,7 @@ Run the local App Server using native v2 WebSocket frames.
|
|
|
470130
470206
|
Options:
|
|
470131
470207
|
--listen [url] WebSocket listen URL. Defaults to an available loopback port
|
|
470132
470208
|
--openai-api Serve OpenAI-compatible /v1/models and /v1/chat/completions routes (each agent is a model)
|
|
470133
|
-
--ws-auth <mode> WebSocket auth
|
|
470209
|
+
--ws-auth <mode> WebSocket auth for non-loopback listeners and Origin-bearing native clients. Supported: capability-token, signed-bearer-token
|
|
470134
470210
|
--ws-token-file <path> Absolute path to the capability-token file
|
|
470135
470211
|
--ws-token-sha256 <hex> Hex-encoded SHA-256 digest of the capability token
|
|
470136
470212
|
--ws-shared-secret-file <path> Absolute path to the shared secret file for signed JWT bearer tokens
|
|
@@ -470250,7 +470326,7 @@ Remote environment options:
|
|
|
470250
470326
|
App Server options:
|
|
470251
470327
|
--listen [url] Accept App Server connections. If URL is omitted, binds to an available loopback port
|
|
470252
470328
|
--openai-api Serve OpenAI-compatible /v1/models and /v1/chat/completions routes (each agent is a model)
|
|
470253
|
-
--ws-auth <mode> Authentication for non-loopback listeners: capability-token or signed-bearer-token
|
|
470329
|
+
--ws-auth <mode> Authentication for non-loopback listeners and Origin-bearing native clients: capability-token or signed-bearer-token
|
|
470254
470330
|
--ws-token-file <path> Absolute path to the capability-token file
|
|
470255
470331
|
--ws-token-sha256 <hex> Hex-encoded SHA-256 digest of the capability token
|
|
470256
470332
|
--ws-shared-secret-file <path> Absolute path to the shared secret file for signed JWT bearer tokens
|
|
@@ -499449,6 +499525,8 @@ function ModelSelector({
|
|
|
499449
499525
|
const [byokProviderAliases, setByokProviderAliases] = import_react91.useState(() => buildByokProviderAliases([]));
|
|
499450
499526
|
const [openAICompatibleProxyHandles, setOpenAICompatibleProxyHandles] = import_react91.useState(() => getCachedOpenAICompatibleProxyHandles() ?? new Set);
|
|
499451
499527
|
const [openAICompatibleProxyProviders, setOpenAICompatibleProxyProviders] = import_react91.useState(new Set);
|
|
499528
|
+
const providerRegistryRevision = import_react91.useSyncExternalStore(subscribePiProviderRegistry, getPiProviderRegistryRevision, getPiProviderRegistryRevision);
|
|
499529
|
+
const previousProviderRegistryRevision = import_react91.useRef(providerRegistryRevision);
|
|
499452
499530
|
const mountedRef = import_react91.useRef(true);
|
|
499453
499531
|
import_react91.useEffect(() => {
|
|
499454
499532
|
mountedRef.current = true;
|
|
@@ -499511,8 +499589,12 @@ function ModelSelector({
|
|
|
499511
499589
|
}
|
|
499512
499590
|
});
|
|
499513
499591
|
import_react91.useEffect(() => {
|
|
499592
|
+
if (previousProviderRegistryRevision.current !== providerRegistryRevision) {
|
|
499593
|
+
previousProviderRegistryRevision.current = providerRegistryRevision;
|
|
499594
|
+
clearAvailableModelsCache();
|
|
499595
|
+
}
|
|
499514
499596
|
loadModels.current(forceRefreshOnMount ?? false);
|
|
499515
|
-
}, [forceRefreshOnMount]);
|
|
499597
|
+
}, [forceRefreshOnMount, providerRegistryRevision]);
|
|
499516
499598
|
import_react91.useEffect(() => {
|
|
499517
499599
|
if (localModelCatalog) {
|
|
499518
499600
|
setByokProviderAliases(buildByokProviderAliases([]));
|
|
@@ -500198,6 +500280,7 @@ var init_ModelSelector = __esm(async () => {
|
|
|
500198
500280
|
init_available_models();
|
|
500199
500281
|
init_model();
|
|
500200
500282
|
init_remote_model_catalog();
|
|
500283
|
+
init_pi_provider_mod_registry();
|
|
500201
500284
|
init_byok_providers();
|
|
500202
500285
|
init_settings_manager();
|
|
500203
500286
|
init_colors();
|
|
@@ -500484,8 +500567,9 @@ function ProviderSelector({
|
|
|
500484
500567
|
const [awsProfiles, setAwsProfiles] = import_react94.useState([]);
|
|
500485
500568
|
const [profileIndex, setProfileIndex] = import_react94.useState(0);
|
|
500486
500569
|
const [isLoadingProfiles, setIsLoadingProfiles] = import_react94.useState(false);
|
|
500487
|
-
|
|
500488
|
-
const
|
|
500570
|
+
import_react94.useSyncExternalStore(subscribePiProviderRegistry, getPiProviderRegistryRevision, getPiProviderRegistryRevision);
|
|
500571
|
+
const providers = getProviderConfigs(selectedTarget);
|
|
500572
|
+
const filteredProviders = filterProviderConfigs(providers, searchQuery);
|
|
500489
500573
|
const showProviderStoreTabs = shouldShowProviderStoreTabs(hasCloudCredentials2);
|
|
500490
500574
|
const connectedProviders = import_react94.useMemo(() => connectedProvidersByTarget[selectedTarget] ?? new Map, [connectedProvidersByTarget, selectedTarget]);
|
|
500491
500575
|
const isLoading = isProviderTargetLoading({
|
|
@@ -501759,6 +501843,7 @@ function ProviderSelector({
|
|
|
501759
501843
|
var import_react94, jsx_dev_runtime70, SOLID_LINE17 = "─", VISIBLE_PROVIDERS = 8;
|
|
501760
501844
|
var init_ProviderSelector = __esm(async () => {
|
|
501761
501845
|
init_available_models();
|
|
501846
|
+
init_pi_provider_mod_registry();
|
|
501762
501847
|
init_use_terminal_width();
|
|
501763
501848
|
init_byok_providers();
|
|
501764
501849
|
init_chatgpt_usage_service();
|
|
@@ -541232,4 +541317,4 @@ function registerBunOAuthFlows() {
|
|
|
541232
541317
|
registerBunOAuthFlows();
|
|
541233
541318
|
await init_src5().then(() => exports_src2);
|
|
541234
541319
|
|
|
541235
|
-
//# debugId=
|
|
541320
|
+
//# debugId=E5837E6C26403C1164756E2164756E21
|