@jmanuelcorral/openteam 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +7 -1
- package/README.md +6 -1
- package/dist/certificates/graph-release-certificate.json +2 -2
- package/dist/certificates/graph-shadow-certificate.json +2 -2
- package/dist/cli/setupAdapters.d.ts +2 -2
- package/dist/cli/setupAdapters.d.ts.map +1 -1
- package/dist/cli.js +826 -298
- package/dist/commands/agents.d.ts +6 -4
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/dispatch.d.ts +1 -1
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/setup.d.ts +22 -14
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +990 -281
- package/dist/local/lemonade.d.ts.map +1 -1
- package/dist/local/lemonadeRequestGuard.d.ts +11 -0
- package/dist/local/lemonadeRequestGuard.d.ts.map +1 -0
- package/dist/local/lemonadeResidency.d.ts +22 -0
- package/dist/local/lemonadeResidency.d.ts.map +1 -0
- package/dist/local/modelResidency.d.ts +4 -0
- package/dist/local/modelResidency.d.ts.map +1 -0
- package/dist/local/slotPool.d.ts +13 -7
- package/dist/local/slotPool.d.ts.map +1 -1
- package/dist/messages/executionSetup.d.ts +19 -0
- package/dist/messages/executionSetup.d.ts.map +1 -1
- package/dist/messages/modelResidency.d.ts +19 -0
- package/dist/messages/modelResidency.d.ts.map +1 -0
- package/dist/orchestrator/coordinator.d.ts.map +1 -1
- package/dist/orchestrator/runtimeSelection.d.ts +4 -3
- package/dist/orchestrator/runtimeSelection.d.ts.map +1 -1
- package/dist/plugin/availability.d.ts +4 -1
- package/dist/plugin/availability.d.ts.map +1 -1
- package/dist/plugin/hooks.d.ts +2 -0
- package/dist/plugin/hooks.d.ts.map +1 -1
- package/dist/plugin/memoryTool.d.ts +9 -3
- package/dist/plugin/memoryTool.d.ts.map +1 -1
- package/dist/plugin/modelResidency.d.ts +47 -0
- package/dist/plugin/modelResidency.d.ts.map +1 -0
- package/dist/router/types.d.ts +2 -0
- package/dist/router/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5743,7 +5743,7 @@ import { z as z15 } from "zod";
|
|
|
5743
5743
|
// package.json
|
|
5744
5744
|
var package_default = {
|
|
5745
5745
|
name: "@jmanuelcorral/openteam",
|
|
5746
|
-
version: "0.24.
|
|
5746
|
+
version: "0.24.1",
|
|
5747
5747
|
packageManager: "bun@1.3.14",
|
|
5748
5748
|
description: "Cost-aware, local-first routing plugin for opencode with cheapest-capable frontier fallback and multi-agent orchestration.",
|
|
5749
5749
|
license: "MIT",
|
|
@@ -6100,6 +6100,25 @@ var executionSetupMessages = {
|
|
|
6100
6100
|
`),
|
|
6101
6101
|
localOnlyTitle: "Local execution",
|
|
6102
6102
|
localRequiredError: "local execution requires an enabled local runtime",
|
|
6103
|
+
lemonadeDetectedHint: (loaded, advertised) => `detected - ${loaded} confirmed loaded of ${advertised} advertised text model(s)`,
|
|
6104
|
+
lemonadeNoLoadedModels: "Lemonade has no text models verified as loaded and ready. Keep the intended model active in Lemonade and rerun setup; inactive or unknown models cannot be selected or entered manually.",
|
|
6105
|
+
lemonadeModelNotLoaded: (model) => `Lemonade model "${model}" is not positively verified as loaded and ready. Keep that exact text model active and rerun setup; no substitute was selected and no implicit loading is allowed.`,
|
|
6106
|
+
lemonadeProbeRequired: "Lemonade setup requires a fresh read-only residency probe before writing configuration. Use the CLI with its runtime probe enabled; manual model IDs cannot bypass this requirement.",
|
|
6107
|
+
lemonadeProbeFailed: "Lemonade residency could not be verified at the configured endpoint. Check connectivity and the read-only /models, /health, and /internal/aliases responses, then rerun setup with the intended text models already active.",
|
|
6108
|
+
lemonadeEndpointMismatch: "Lemonade endpoint/provider mapping differs from the selected runtime. Reconcile the configured base URL and provider before rerunning setup; no model was substituted.",
|
|
6109
|
+
lemonadeModelIdentityUnknown: (model) => `Lemonade model "${model}" has no usable registered wire identity in the effective opencode configuration. Fix its model declaration before rerunning setup; setup will not replace or guess an alias.`,
|
|
6110
|
+
lemonadeEffectiveConfigLabel: "effective setup configuration",
|
|
6111
|
+
lemonadeEffectiveConfigAmbiguous: "Cannot establish one effective openteam configuration from the configured plugin loaders. Reconcile their options before rerunning setup; no provider identity was guessed.",
|
|
6112
|
+
lemonadeRetainedProviderUnprotected: (providerID) => `Cannot safely keep retained Lemonade provider "${providerID}": the effective configuration must retain one matching Lemonade runtime, disabled when deselected. Reconcile the plugin options or machine overlay, or explicitly remove the provider registration before rerunning setup; no configuration was written.`,
|
|
6113
|
+
lemonadeV2InvalidProvider: (providerID) => `Lemonade provider ${JSON.stringify(providerID)} cannot be represented as an exact native V2 policy resource. Choose a non-empty provider ID without wildcards, slashes, backslashes, or whitespace; setup will not broaden a deny rule.`,
|
|
6114
|
+
lemonadeV2InvalidPolicies: "Cannot safely preserve experimental.policies: experimental must be an object and policies must be an array of provider.use statements with a string resource and allow/deny effect. Fix the project configuration before rerunning setup.",
|
|
6115
|
+
lemonadeV2Title: "Lemonade transport compatibility",
|
|
6116
|
+
lemonadeV2Restriction: (providers) => `Project policies disable native V2 Lemonade access for: ${providers.join(", ")}. Ordinary guarded V1 configuration remains supported; V2 is not an openteam-hook execution path. Higher-precedence or global policies can override this project restriction; it is not a server-atomic no-autoload guarantee.`,
|
|
6117
|
+
lemonadeInventory: (instanceID, providerID, models) => {
|
|
6118
|
+
const inventory = models.map((model) => `${model.modelID} (${model.loaded === true ? "loaded" : model.loaded === false ? "inactive" : "residency unknown"})`).join(", ");
|
|
6119
|
+
return `Lemonade inventory ${instanceID} (provider ${providerID}): ${inventory || "no advertised text models"}. Only confirmed loaded text models count as ready.`;
|
|
6120
|
+
},
|
|
6121
|
+
lemonadeAgentResidency: (agent, model, state) => `Lemonade readiness: ${agent} (${model}): ${state === "not-loaded" ? "inactive (not ready)" : "residency unknown"}; advertised inventory is not loaded readiness. Keep this exact model active and verify residency before use; requests without verified readiness are blocked.`,
|
|
6103
6122
|
mixedPrimaryQuestion: "Primary coordinator model",
|
|
6104
6123
|
mixedPrimaryLocal: (model) => `Use local thinking model ${model}`,
|
|
6105
6124
|
mixedPrimaryFrontier: "Choose a frontier model",
|
|
@@ -9931,6 +9950,243 @@ function ensureFoundryV1BaseURL(endpoint) {
|
|
|
9931
9950
|
}
|
|
9932
9951
|
}
|
|
9933
9952
|
|
|
9953
|
+
// src/local/lemonadeResidency.ts
|
|
9954
|
+
import { z as z19 } from "zod";
|
|
9955
|
+
|
|
9956
|
+
// src/messages/modelResidency.ts
|
|
9957
|
+
var reasons = {
|
|
9958
|
+
unknown: "fresh residency metadata is unavailable, malformed, or ambiguous",
|
|
9959
|
+
inactive: "the requested model is not verified as resident and serving",
|
|
9960
|
+
identity: "the requested model identity can be rewritten or is ambiguous",
|
|
9961
|
+
destination: "the request destination does not match its configured runtime",
|
|
9962
|
+
transport: "this provider execution path cannot enforce the residency guard",
|
|
9963
|
+
request: "this is not a supported, explicit model inference request",
|
|
9964
|
+
cancelled: "the request was cancelled before residency could be verified",
|
|
9965
|
+
timeout: "the residency metadata deadline expired",
|
|
9966
|
+
configuration: "the residency guard configuration is invalid"
|
|
9967
|
+
};
|
|
9968
|
+
var modelResidencyMessages = {
|
|
9969
|
+
blocked: (reason) => `[openteam] Lemonade model request blocked: ${reasons[reason]}.`,
|
|
9970
|
+
providerDisabled: (providerID) => `[openteam] Lemonade provider "${providerID}" is disabled because its configured transport or runtime mapping cannot enforce loaded-only requests.`,
|
|
9971
|
+
extractionRuntimeUnavailable: "[openteam] Memory extraction requires one enabled local runtime matching the configured extraction provider."
|
|
9972
|
+
};
|
|
9973
|
+
|
|
9974
|
+
// src/local/lemonadeResidency.ts
|
|
9975
|
+
class ModelResidencyError extends Error {
|
|
9976
|
+
code;
|
|
9977
|
+
statusCode = 400;
|
|
9978
|
+
isRetryable = false;
|
|
9979
|
+
constructor(code) {
|
|
9980
|
+
super(modelResidencyMessages.blocked(code));
|
|
9981
|
+
this.code = code;
|
|
9982
|
+
this.name = "ModelResidencyError";
|
|
9983
|
+
}
|
|
9984
|
+
}
|
|
9985
|
+
var modelName = z19.string().min(1).refine((name) => name === name.trim());
|
|
9986
|
+
var LoadedModelSchema = z19.object({
|
|
9987
|
+
model_name: modelName,
|
|
9988
|
+
loaded: z19.boolean().optional(),
|
|
9989
|
+
status: z19.string().optional(),
|
|
9990
|
+
backend_alive: z19.boolean().optional(),
|
|
9991
|
+
backend_health: z19.string().optional(),
|
|
9992
|
+
watchdog_reset: z19.boolean().optional(),
|
|
9993
|
+
watchdog_reset_reason: z19.string().optional(),
|
|
9994
|
+
residency_class: z19.string().optional(),
|
|
9995
|
+
slot_pool: z19.string().optional(),
|
|
9996
|
+
checkpoint: z19.string().optional(),
|
|
9997
|
+
type: z19.string().optional(),
|
|
9998
|
+
device: z19.string().optional(),
|
|
9999
|
+
backend_url: z19.string().optional(),
|
|
10000
|
+
pid: z19.number().int().optional(),
|
|
10001
|
+
launch_command: z19.unknown().optional(),
|
|
10002
|
+
pinned: z19.boolean().optional(),
|
|
10003
|
+
recipe: z19.string().optional(),
|
|
10004
|
+
recipe_options: z19.unknown().optional(),
|
|
10005
|
+
is_busy: z19.boolean().optional(),
|
|
10006
|
+
is_streaming: z19.boolean().optional(),
|
|
10007
|
+
max_context_window: z19.number().optional(),
|
|
10008
|
+
cost_input_per_million: z19.number().optional(),
|
|
10009
|
+
cost_output_per_million: z19.number().optional(),
|
|
10010
|
+
last_use: z19.number().optional()
|
|
10011
|
+
}).strict();
|
|
10012
|
+
var TelemetrySchema = z19.object({
|
|
10013
|
+
enabled: z19.boolean(),
|
|
10014
|
+
captures: z19.array(z19.string()).optional()
|
|
10015
|
+
}).strict();
|
|
10016
|
+
var HealthSchema = z19.object({
|
|
10017
|
+
status: z19.literal("ok"),
|
|
10018
|
+
all_models_loaded: z19.array(LoadedModelSchema),
|
|
10019
|
+
version: z19.string().optional(),
|
|
10020
|
+
model_loaded: z19.string().nullable().optional(),
|
|
10021
|
+
telemetry: TelemetrySchema.optional(),
|
|
10022
|
+
max_models: z19.record(z19.string(), z19.number().int()).optional(),
|
|
10023
|
+
pinned_models: z19.record(z19.string(), z19.number().int()).optional(),
|
|
10024
|
+
pinned_helper_models: z19.record(z19.string(), z19.number().int()).optional(),
|
|
10025
|
+
websocket_port: z19.number().int().optional(),
|
|
10026
|
+
update_check_done: z19.boolean().optional()
|
|
10027
|
+
}).strict();
|
|
10028
|
+
var AliasSchema = z19.object({
|
|
10029
|
+
alias: modelName,
|
|
10030
|
+
target: modelName,
|
|
10031
|
+
downloaded: z19.boolean().optional(),
|
|
10032
|
+
recipe: z19.string().optional()
|
|
10033
|
+
}).strict();
|
|
10034
|
+
var AliasesSchema = z19.object({
|
|
10035
|
+
aliases: z19.array(AliasSchema)
|
|
10036
|
+
}).strict();
|
|
10037
|
+
var MetadataRecordSchema = z19.record(z19.string(), z19.unknown());
|
|
10038
|
+
var inactiveStates = new Set([
|
|
10039
|
+
"loading",
|
|
10040
|
+
"downsizing",
|
|
10041
|
+
"downsized",
|
|
10042
|
+
"evicting",
|
|
10043
|
+
"unloaded"
|
|
10044
|
+
]);
|
|
10045
|
+
var inactiveHealth = new Set(["stopped", "exited", "watchdog_reset"]);
|
|
10046
|
+
var standardPools = new Set([
|
|
10047
|
+
"standard/llm",
|
|
10048
|
+
"standard/embedding",
|
|
10049
|
+
"standard/reranking",
|
|
10050
|
+
"standard/transcription",
|
|
10051
|
+
"standard/image",
|
|
10052
|
+
"standard/tts",
|
|
10053
|
+
"standard/audio-generation",
|
|
10054
|
+
"standard/classification",
|
|
10055
|
+
"standard/mesh"
|
|
10056
|
+
]);
|
|
10057
|
+
function usableState(entry) {
|
|
10058
|
+
if (entry.loaded === false || entry.backend_alive === false || entry.watchdog_reset === true || typeof entry.status === "string" && inactiveStates.has(entry.status) || typeof entry.backend_health === "string" && inactiveHealth.has(entry.backend_health) || entry.residency_class === "routing_helper" || typeof entry.slot_pool === "string" && entry.slot_pool.startsWith("routing_helper/")) {
|
|
10059
|
+
return false;
|
|
10060
|
+
}
|
|
10061
|
+
if (entry.loaded !== true || entry.backend_alive !== true || entry.watchdog_reset !== false || entry.status !== "ready" && entry.status !== "in_use" || entry.backend_health !== "ready" && entry.backend_health !== "busy" || entry.watchdog_reset_reason !== undefined && entry.watchdog_reset_reason !== "" || entry.residency_class !== undefined && entry.residency_class !== "standard" || entry.slot_pool !== undefined && (typeof entry.slot_pool !== "string" || !standardPools.has(entry.slot_pool))) {
|
|
10062
|
+
return;
|
|
10063
|
+
}
|
|
10064
|
+
return true;
|
|
10065
|
+
}
|
|
10066
|
+
function projectMetadataObject(payload, keys) {
|
|
10067
|
+
const record = MetadataRecordSchema.safeParse(payload);
|
|
10068
|
+
if (!record.success)
|
|
10069
|
+
throw new ModelResidencyError("unknown");
|
|
10070
|
+
return Object.fromEntries(keys.filter((key) => Object.hasOwn(record.data, key)).map((key) => [key, record.data[key]]));
|
|
10071
|
+
}
|
|
10072
|
+
function parseResidency(healthPayload, aliasPayload) {
|
|
10073
|
+
const healthFields = projectMetadataObject(healthPayload, Object.keys(HealthSchema.shape));
|
|
10074
|
+
if (Array.isArray(healthFields.all_models_loaded)) {
|
|
10075
|
+
healthFields.all_models_loaded = healthFields.all_models_loaded.map((entry) => projectMetadataObject(entry, Object.keys(LoadedModelSchema.shape)));
|
|
10076
|
+
}
|
|
10077
|
+
if (healthFields.telemetry !== undefined) {
|
|
10078
|
+
healthFields.telemetry = projectMetadataObject(healthFields.telemetry, Object.keys(TelemetrySchema.shape));
|
|
10079
|
+
}
|
|
10080
|
+
const aliasFields = projectMetadataObject(aliasPayload, Object.keys(AliasesSchema.shape));
|
|
10081
|
+
if (Array.isArray(aliasFields.aliases)) {
|
|
10082
|
+
aliasFields.aliases = aliasFields.aliases.map((entry) => projectMetadataObject(entry, Object.keys(AliasSchema.shape)));
|
|
10083
|
+
}
|
|
10084
|
+
const health = HealthSchema.safeParse(healthFields);
|
|
10085
|
+
const aliases = AliasesSchema.safeParse(aliasFields);
|
|
10086
|
+
if (!health.success || !aliases.success)
|
|
10087
|
+
throw new ModelResidencyError("unknown");
|
|
10088
|
+
const result = new Map;
|
|
10089
|
+
for (const entry of health.data.all_models_loaded) {
|
|
10090
|
+
if (result.has(entry.model_name))
|
|
10091
|
+
throw new ModelResidencyError("unknown");
|
|
10092
|
+
result.set(entry.model_name, {
|
|
10093
|
+
loaded: entry.model_name.endsWith(":latest") ? undefined : usableState(entry),
|
|
10094
|
+
metadata: entry
|
|
10095
|
+
});
|
|
10096
|
+
}
|
|
10097
|
+
const seenAliases = new Set;
|
|
10098
|
+
for (const entry of aliases.data.aliases) {
|
|
10099
|
+
if (seenAliases.has(entry.alias))
|
|
10100
|
+
throw new ModelResidencyError("unknown");
|
|
10101
|
+
seenAliases.add(entry.alias);
|
|
10102
|
+
result.set(entry.alias, {
|
|
10103
|
+
loaded: undefined,
|
|
10104
|
+
metadata: result.get(entry.alias)?.metadata ?? {}
|
|
10105
|
+
});
|
|
10106
|
+
}
|
|
10107
|
+
return result;
|
|
10108
|
+
}
|
|
10109
|
+
function lemonadeBaseURL(value) {
|
|
10110
|
+
let url;
|
|
10111
|
+
try {
|
|
10112
|
+
url = new URL(value);
|
|
10113
|
+
} catch {
|
|
10114
|
+
throw new ModelResidencyError("destination");
|
|
10115
|
+
}
|
|
10116
|
+
if (url.protocol !== "http:" && url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "" || !/^\/(?:api\/)?v[01]\/?$/.test(url.pathname)) {
|
|
10117
|
+
throw new ModelResidencyError("destination");
|
|
10118
|
+
}
|
|
10119
|
+
return `${url.origin}${url.pathname.replace(/\/$/, "")}`;
|
|
10120
|
+
}
|
|
10121
|
+
async function withResidencyDeadline(operation, options) {
|
|
10122
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
10123
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
10124
|
+
throw new ModelResidencyError("configuration");
|
|
10125
|
+
}
|
|
10126
|
+
const controller = new AbortController;
|
|
10127
|
+
const cancel = () => controller.abort(new ModelResidencyError("cancelled"));
|
|
10128
|
+
if (options.signal?.aborted)
|
|
10129
|
+
throw new ModelResidencyError("cancelled");
|
|
10130
|
+
options.signal?.addEventListener("abort", cancel, { once: true });
|
|
10131
|
+
const schedule = options.scheduleTimeout ?? ((callback, ms) => {
|
|
10132
|
+
const timer = setTimeout(callback, ms);
|
|
10133
|
+
return () => clearTimeout(timer);
|
|
10134
|
+
});
|
|
10135
|
+
let onAbort = () => {};
|
|
10136
|
+
const aborted = new Promise((_, reject) => {
|
|
10137
|
+
onAbort = () => reject(controller.signal.reason);
|
|
10138
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
10139
|
+
});
|
|
10140
|
+
const clearTimer = schedule(() => controller.abort(new ModelResidencyError("timeout")), timeoutMs);
|
|
10141
|
+
try {
|
|
10142
|
+
controller.signal.throwIfAborted();
|
|
10143
|
+
return await Promise.race([operation(controller.signal), aborted]);
|
|
10144
|
+
} finally {
|
|
10145
|
+
clearTimer();
|
|
10146
|
+
options.signal?.removeEventListener("abort", cancel);
|
|
10147
|
+
controller.signal.removeEventListener("abort", onAbort);
|
|
10148
|
+
controller.abort();
|
|
10149
|
+
}
|
|
10150
|
+
}
|
|
10151
|
+
async function metadata(url, fetch, signal, headers) {
|
|
10152
|
+
signal.throwIfAborted();
|
|
10153
|
+
let payload;
|
|
10154
|
+
try {
|
|
10155
|
+
const response = await fetch(url, {
|
|
10156
|
+
method: "GET",
|
|
10157
|
+
headers,
|
|
10158
|
+
signal,
|
|
10159
|
+
redirect: "error",
|
|
10160
|
+
cache: "no-store"
|
|
10161
|
+
});
|
|
10162
|
+
signal.throwIfAborted();
|
|
10163
|
+
if (!response.ok || response.redirected || response.url !== "" && response.url !== url) {
|
|
10164
|
+
throw new ModelResidencyError("unknown");
|
|
10165
|
+
}
|
|
10166
|
+
payload = await response.json();
|
|
10167
|
+
} catch {
|
|
10168
|
+
signal.throwIfAborted();
|
|
10169
|
+
throw new ModelResidencyError("unknown");
|
|
10170
|
+
}
|
|
10171
|
+
signal.throwIfAborted();
|
|
10172
|
+
return payload;
|
|
10173
|
+
}
|
|
10174
|
+
async function readLemonadeResidency(baseURL, fetch, options = {}) {
|
|
10175
|
+
const base = lemonadeBaseURL(baseURL);
|
|
10176
|
+
const headers = new Headers(options.headers);
|
|
10177
|
+
headers.delete("content-type");
|
|
10178
|
+
headers.delete("content-length");
|
|
10179
|
+
headers.set("accept", "application/json");
|
|
10180
|
+
headers.set("cache-control", "no-cache, no-store");
|
|
10181
|
+
headers.delete("if-none-match");
|
|
10182
|
+
headers.delete("if-modified-since");
|
|
10183
|
+
return withResidencyDeadline(async (signal) => {
|
|
10184
|
+
const aliases = await metadata(`${new URL(base).origin}/internal/aliases`, fetch, signal, headers);
|
|
10185
|
+
const health = await metadata(`${base}/health`, fetch, signal, headers);
|
|
10186
|
+
return parseResidency(health, aliases);
|
|
10187
|
+
}, options);
|
|
10188
|
+
}
|
|
10189
|
+
|
|
9934
10190
|
// src/local/lemonade.ts
|
|
9935
10191
|
var LEMONADE_DEFAULT_BASE_URL = "http://localhost:13305/api/v1";
|
|
9936
10192
|
var NON_TEXT_LABELS = new Set([
|
|
@@ -10017,36 +10273,19 @@ function isNonTextModel(entry) {
|
|
|
10017
10273
|
return entry.labels.some((label) => typeof label === "string" && NON_TEXT_LABELS.has(label));
|
|
10018
10274
|
}
|
|
10019
10275
|
async function readLoadedModels(baseURL, fetch) {
|
|
10020
|
-
let payload;
|
|
10021
10276
|
try {
|
|
10022
|
-
const
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10277
|
+
const residency = await readLemonadeResidency(baseURL, fetch);
|
|
10278
|
+
return new Map([...residency].map(([name, entry]) => [
|
|
10279
|
+
name,
|
|
10280
|
+
{
|
|
10281
|
+
loaded: entry.loaded,
|
|
10282
|
+
slots: entry.loaded === true ? readSlotCount(entry.metadata) : undefined,
|
|
10283
|
+
totalContextWindow: entry.loaded === true ? readLoadedContextWindow(entry.metadata) : undefined
|
|
10284
|
+
}
|
|
10285
|
+
]));
|
|
10030
10286
|
} catch {
|
|
10031
10287
|
return;
|
|
10032
10288
|
}
|
|
10033
|
-
if (!isObject2(payload) || !Array.isArray(payload.all_models_loaded)) {
|
|
10034
|
-
return;
|
|
10035
|
-
}
|
|
10036
|
-
const loaded = new Map;
|
|
10037
|
-
for (const entry of payload.all_models_loaded) {
|
|
10038
|
-
if (!isObject2(entry) || typeof entry.model_name !== "string") {
|
|
10039
|
-
continue;
|
|
10040
|
-
}
|
|
10041
|
-
if (entry.loaded === false) {
|
|
10042
|
-
continue;
|
|
10043
|
-
}
|
|
10044
|
-
loaded.set(entry.model_name, {
|
|
10045
|
-
slots: readSlotCount(entry),
|
|
10046
|
-
totalContextWindow: readLoadedContextWindow(entry)
|
|
10047
|
-
});
|
|
10048
|
-
}
|
|
10049
|
-
return loaded;
|
|
10050
10289
|
}
|
|
10051
10290
|
function readSlotCount(entry) {
|
|
10052
10291
|
return slotsFromLlamacppArgs(entry) ?? slotsFromLaunchCommand(entry);
|
|
@@ -10193,6 +10432,9 @@ function enrichWithLoadState(models, loaded) {
|
|
|
10193
10432
|
if (hit === undefined) {
|
|
10194
10433
|
return { ...base, loaded: false };
|
|
10195
10434
|
}
|
|
10435
|
+
if (hit.loaded !== true) {
|
|
10436
|
+
return hit.loaded === false ? { ...base, loaded: false } : base;
|
|
10437
|
+
}
|
|
10196
10438
|
const contextWindow = derivedConservativeContextWindow(model.contextWindow, hit);
|
|
10197
10439
|
return {
|
|
10198
10440
|
...base,
|
|
@@ -10336,6 +10578,14 @@ function reportedModelSlotsByRuntime(snapshots) {
|
|
|
10336
10578
|
}
|
|
10337
10579
|
|
|
10338
10580
|
// src/local/slotPool.ts
|
|
10581
|
+
function localModelAliases(providerID, models) {
|
|
10582
|
+
const aliases = new Map;
|
|
10583
|
+
for (const model of models ?? []) {
|
|
10584
|
+
if (model.kind === "local" && model.providerID === providerID && model.runtimeModelID !== undefined && model.runtimeModelID !== model.modelID)
|
|
10585
|
+
aliases.set(model.modelID, model.runtimeModelID);
|
|
10586
|
+
}
|
|
10587
|
+
return aliases;
|
|
10588
|
+
}
|
|
10339
10589
|
var POOL_SEPARATOR = "::";
|
|
10340
10590
|
function slotPoolKey(runtime, modelID) {
|
|
10341
10591
|
if (modelID === undefined) {
|
|
@@ -10365,13 +10615,20 @@ function slotPoolReservedInteractive(runtime, modelID) {
|
|
|
10365
10615
|
function unknownPoolCapacity() {
|
|
10366
10616
|
return DEFAULT_LOCAL_MAX_CONCURRENCY;
|
|
10367
10617
|
}
|
|
10368
|
-
function withReportedModelSlots(runtime, reported) {
|
|
10369
|
-
|
|
10618
|
+
function withReportedModelSlots(runtime, reported, aliases) {
|
|
10619
|
+
const configured = Object.entries(runtime.modelConcurrency ?? {});
|
|
10620
|
+
const hasAliasLimits = configured.some(([modelID]) => aliases?.has(modelID) === true);
|
|
10621
|
+
if (!hasAliasLimits && (reported === undefined || Object.keys(reported).length === 0)) {
|
|
10370
10622
|
return runtime;
|
|
10371
10623
|
}
|
|
10624
|
+
const explicit = new Map;
|
|
10625
|
+
for (const [modelID, limit] of configured) {
|
|
10626
|
+
const physicalID = aliases?.get(modelID) ?? modelID;
|
|
10627
|
+
explicit.set(physicalID, Math.min(explicit.get(physicalID) ?? limit, limit));
|
|
10628
|
+
}
|
|
10372
10629
|
return {
|
|
10373
10630
|
...runtime,
|
|
10374
|
-
modelConcurrency: { ...reported, ...
|
|
10631
|
+
modelConcurrency: { ...reported, ...Object.fromEntries(explicit) }
|
|
10375
10632
|
};
|
|
10376
10633
|
}
|
|
10377
10634
|
|
|
@@ -10468,14 +10725,14 @@ var readReportArtifact = async (reportPath) => {
|
|
|
10468
10725
|
};
|
|
10469
10726
|
|
|
10470
10727
|
// src/orchestrator/roster.ts
|
|
10471
|
-
import { z as
|
|
10472
|
-
var RosterEntrySchema =
|
|
10473
|
-
roleID:
|
|
10474
|
-
agentName:
|
|
10728
|
+
import { z as z20 } from "zod";
|
|
10729
|
+
var RosterEntrySchema = z20.object({
|
|
10730
|
+
roleID: z20.string().min(1),
|
|
10731
|
+
agentName: z20.string().min(1)
|
|
10475
10732
|
}).strict();
|
|
10476
|
-
var RosterSchema =
|
|
10477
|
-
universe:
|
|
10478
|
-
entries:
|
|
10733
|
+
var RosterSchema = z20.object({
|
|
10734
|
+
universe: z20.string().min(1),
|
|
10735
|
+
entries: z20.array(RosterEntrySchema)
|
|
10479
10736
|
}).strict();
|
|
10480
10737
|
var ROSTER_JSON_FENCE = /```json\s*([\s\S]*?)```/;
|
|
10481
10738
|
|
|
@@ -11120,10 +11377,21 @@ async function runSubsession(client, req, deps) {
|
|
|
11120
11377
|
}
|
|
11121
11378
|
}
|
|
11122
11379
|
|
|
11380
|
+
// src/local/modelResidency.ts
|
|
11381
|
+
function hasRequiredModelResidency(kind, model) {
|
|
11382
|
+
return kind !== "lemonade" || model?.loaded === true;
|
|
11383
|
+
}
|
|
11384
|
+
|
|
11123
11385
|
// src/plugin/availability.ts
|
|
11124
11386
|
function modelKey2(model) {
|
|
11125
11387
|
return `${model.providerID}/${model.modelID}`;
|
|
11126
11388
|
}
|
|
11389
|
+
function availabilityMetadata({
|
|
11390
|
+
apiModelID: _apiModelID,
|
|
11391
|
+
...metadata2
|
|
11392
|
+
}) {
|
|
11393
|
+
return metadata2;
|
|
11394
|
+
}
|
|
11127
11395
|
function compareAvailableModels(left, right) {
|
|
11128
11396
|
const kindOrder = Number(left.kind === "frontier") - Number(right.kind === "frontier");
|
|
11129
11397
|
if (kindOrder !== 0) {
|
|
@@ -11141,6 +11409,9 @@ function uniqueSelections(models) {
|
|
|
11141
11409
|
function isConfiguredLocalModel(config, model) {
|
|
11142
11410
|
return config.local.runtimes.some((runtime) => runtime.defaultModel.providerID === model.providerID);
|
|
11143
11411
|
}
|
|
11412
|
+
function requiresModelResidency(config, model) {
|
|
11413
|
+
return config.local.runtimes.some((runtime) => runtime.defaultModel.providerID === model.providerID && !hasRequiredModelResidency(localRuntimeKind(runtime), undefined));
|
|
11414
|
+
}
|
|
11144
11415
|
function configuredFrontierProviderIDs(config) {
|
|
11145
11416
|
const providerIDs = new Set([config.baseline.hardDefault.providerID]);
|
|
11146
11417
|
if (config.baseline.mode === "pinned" && config.baseline.pinnedModel !== null) {
|
|
@@ -11235,7 +11506,7 @@ function frontierAvailableModels(config, configuredModels) {
|
|
|
11235
11506
|
for (const model of configuredModels ?? frontierBaselines(config)) {
|
|
11236
11507
|
if (!isConfiguredLocalModel(config, model)) {
|
|
11237
11508
|
frontierByKey.set(modelKey2(model), {
|
|
11238
|
-
...model,
|
|
11509
|
+
...availabilityMetadata(model),
|
|
11239
11510
|
kind: "frontier",
|
|
11240
11511
|
available: true
|
|
11241
11512
|
});
|
|
@@ -11251,7 +11522,7 @@ function defaultAvailableModels(config, configuredModels) {
|
|
|
11251
11522
|
...defaultLocalModels(config).map((model) => ({
|
|
11252
11523
|
...model,
|
|
11253
11524
|
kind: "local",
|
|
11254
|
-
available:
|
|
11525
|
+
available: !requiresModelResidency(config, model)
|
|
11255
11526
|
})),
|
|
11256
11527
|
...frontierAvailableModels(config, configuredModels)
|
|
11257
11528
|
].sort(compareAvailableModels);
|
|
@@ -11265,7 +11536,8 @@ function toAvailableModels(snapshots, config, configuredModels) {
|
|
|
11265
11536
|
continue;
|
|
11266
11537
|
}
|
|
11267
11538
|
localByKey.set(modelKey2(model), {
|
|
11268
|
-
...model,
|
|
11539
|
+
...availabilityMetadata(model),
|
|
11540
|
+
...model.apiModelID !== undefined && model.apiModelID !== model.modelID ? { runtimeModelID: model.apiModelID } : {},
|
|
11269
11541
|
kind: "local",
|
|
11270
11542
|
available: false
|
|
11271
11543
|
});
|
|
@@ -11276,27 +11548,25 @@ function toAvailableModels(snapshots, config, configuredModels) {
|
|
|
11276
11548
|
continue;
|
|
11277
11549
|
}
|
|
11278
11550
|
for (const model of snapshot.models) {
|
|
11279
|
-
const
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
|
|
11284
|
-
|
|
11285
|
-
|
|
11286
|
-
|
|
11287
|
-
|
|
11288
|
-
|
|
11289
|
-
|
|
11290
|
-
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
availableModel.contextWindow = model.contextWindow;
|
|
11551
|
+
const providerID = runtime.defaultModel.providerID;
|
|
11552
|
+
const refs = configuredModels === undefined ? [{ providerID, modelID: model.modelID }] : configuredModels.filter((registered) => registered.providerID === providerID && (registered.apiModelID ?? registered.modelID) === model.modelID);
|
|
11553
|
+
for (const ref of refs) {
|
|
11554
|
+
const existing = localByKey.get(modelKey2(ref));
|
|
11555
|
+
const availableModel = {
|
|
11556
|
+
...existing,
|
|
11557
|
+
providerID: ref.providerID,
|
|
11558
|
+
modelID: ref.modelID,
|
|
11559
|
+
kind: "local",
|
|
11560
|
+
available: snapshot.reachable && hasRequiredModelResidency(localRuntimeKind(runtime), model) || existing?.available === true
|
|
11561
|
+
};
|
|
11562
|
+
if (model.supportsTools !== "unknown") {
|
|
11563
|
+
availableModel.supportsTools = model.supportsTools;
|
|
11564
|
+
}
|
|
11565
|
+
if (model.contextWindow !== undefined) {
|
|
11566
|
+
availableModel.contextWindow = model.contextWindow;
|
|
11567
|
+
}
|
|
11568
|
+
localByKey.set(modelKey2(ref), availableModel);
|
|
11298
11569
|
}
|
|
11299
|
-
localByKey.set(modelKey2(ref), availableModel);
|
|
11300
11570
|
}
|
|
11301
11571
|
}
|
|
11302
11572
|
return [
|
|
@@ -11305,7 +11575,7 @@ function toAvailableModels(snapshots, config, configuredModels) {
|
|
|
11305
11575
|
].sort(compareAvailableModels);
|
|
11306
11576
|
}
|
|
11307
11577
|
function createAvailabilityCache(options) {
|
|
11308
|
-
let configuredModels = options.initialConfiguredModels === undefined ? undefined :
|
|
11578
|
+
let configuredModels = options.initialConfiguredModels === undefined ? undefined : options.initialConfiguredModels.map((model) => ({ ...model }));
|
|
11309
11579
|
let configuredProfiles = (options.initialConfiguredProfiles ?? []).map((profile) => profileForConfiguredDomain(options.config, profile));
|
|
11310
11580
|
let cached = defaultAvailableModels(options.config, configuredModels);
|
|
11311
11581
|
let inFlight;
|
|
@@ -11315,7 +11585,9 @@ function createAvailabilityCache(options) {
|
|
|
11315
11585
|
if (options.listConfiguredInventory !== undefined) {
|
|
11316
11586
|
const inventory = await options.listConfiguredInventory().then((value) => ({ kind: "models", value }), (error) => ({ kind: "error", error }));
|
|
11317
11587
|
if (inventory.kind === "models") {
|
|
11318
|
-
configuredModels = inventory.value.models
|
|
11588
|
+
configuredModels = inventory.value.models.map((model) => ({
|
|
11589
|
+
...model
|
|
11590
|
+
}));
|
|
11319
11591
|
configuredProfiles = inventory.value.profiles.map((profile) => profileForConfiguredDomain(options.config, profile));
|
|
11320
11592
|
} else {
|
|
11321
11593
|
options.onRefreshError?.(inventory.error);
|
|
@@ -11328,15 +11600,22 @@ function createAvailabilityCache(options) {
|
|
|
11328
11600
|
}
|
|
11329
11601
|
return {
|
|
11330
11602
|
get: () => cloneAvailableModels(cached),
|
|
11603
|
+
resolveApiModelID: (ref) => {
|
|
11604
|
+
const registered = configuredModels?.find((model) => model.providerID === ref.providerID && model.modelID === ref.modelID);
|
|
11605
|
+
return registered?.apiModelID ?? registered?.modelID;
|
|
11606
|
+
},
|
|
11331
11607
|
getProfiles: () => configuredProfiles.map((profile) => ({
|
|
11332
11608
|
...profile,
|
|
11333
11609
|
ref: { ...profile.ref },
|
|
11334
11610
|
costPer1M: { ...profile.costPer1M }
|
|
11335
11611
|
})),
|
|
11336
11612
|
refresh: () => {
|
|
11337
|
-
inFlight
|
|
11338
|
-
|
|
11339
|
-
|
|
11613
|
+
if (inFlight === undefined) {
|
|
11614
|
+
cached = cached.map((model) => requiresModelResidency(options.config, model) ? { ...model, available: false } : model);
|
|
11615
|
+
inFlight = refreshNow().finally(() => {
|
|
11616
|
+
inFlight = undefined;
|
|
11617
|
+
});
|
|
11618
|
+
}
|
|
11340
11619
|
return inFlight;
|
|
11341
11620
|
}
|
|
11342
11621
|
};
|
|
@@ -11504,7 +11783,7 @@ function planWorktreeReconciliation(input) {
|
|
|
11504
11783
|
}
|
|
11505
11784
|
|
|
11506
11785
|
// src/telemetry/otelConfig.ts
|
|
11507
|
-
import { z as
|
|
11786
|
+
import { z as z21 } from "zod";
|
|
11508
11787
|
|
|
11509
11788
|
// src/telemetry/fanout.ts
|
|
11510
11789
|
function createFanOutSink(deps) {
|
|
@@ -11582,10 +11861,10 @@ function createOtelSink(deps) {
|
|
|
11582
11861
|
}
|
|
11583
11862
|
|
|
11584
11863
|
// src/telemetry/otelConfig.ts
|
|
11585
|
-
var OtelBackendConfigSchema =
|
|
11586
|
-
backend:
|
|
11587
|
-
connectionEnv:
|
|
11588
|
-
serviceName:
|
|
11864
|
+
var OtelBackendConfigSchema = z21.object({
|
|
11865
|
+
backend: z21.literal("opentelemetry"),
|
|
11866
|
+
connectionEnv: z21.string().min(1),
|
|
11867
|
+
serviceName: z21.string().min(1).optional()
|
|
11589
11868
|
}).strict();
|
|
11590
11869
|
function parseConnectionString(raw) {
|
|
11591
11870
|
const pairs = new Map;
|
|
@@ -12010,7 +12289,7 @@ function parseOpencodeProviders(opencodeConfig) {
|
|
|
12010
12289
|
function localRuntimeStates(config) {
|
|
12011
12290
|
const map = new Map;
|
|
12012
12291
|
for (const runtime of config.local.runtimes) {
|
|
12013
|
-
map.set(runtime.
|
|
12292
|
+
map.set(runtime.defaultModel.providerID, { enabled: runtime.enabled });
|
|
12014
12293
|
}
|
|
12015
12294
|
return map;
|
|
12016
12295
|
}
|
|
@@ -12018,7 +12297,7 @@ function disabledLocalProviderIDs(config) {
|
|
|
12018
12297
|
const ids = new Set;
|
|
12019
12298
|
for (const runtime of config.local.runtimes) {
|
|
12020
12299
|
if (!runtime.enabled) {
|
|
12021
|
-
ids.add(runtime.
|
|
12300
|
+
ids.add(runtime.defaultModel.providerID);
|
|
12022
12301
|
}
|
|
12023
12302
|
}
|
|
12024
12303
|
return ids;
|
|
@@ -12034,7 +12313,11 @@ function computeLive(model, isLocalProvider, liveModels) {
|
|
|
12034
12313
|
if (!snapshot.reachable) {
|
|
12035
12314
|
return "unreachable";
|
|
12036
12315
|
}
|
|
12037
|
-
|
|
12316
|
+
if (snapshot.modelIDs.has(model.modelID))
|
|
12317
|
+
return "confirmed";
|
|
12318
|
+
if (snapshot.residency?.has(model.modelID))
|
|
12319
|
+
return snapshot.residency.get(model.modelID) === false ? "not-loaded" : "residency-unknown";
|
|
12320
|
+
return "not-advertised";
|
|
12038
12321
|
}
|
|
12039
12322
|
function resolveAgentModel(model, context) {
|
|
12040
12323
|
const isLocalProvider = KNOWN_LOCAL_PROVIDER_IDS.has(model.providerID) || context.localRuntimes.has(model.providerID);
|
|
@@ -14365,12 +14648,19 @@ function defaultModelFromOpencode(opencodeConfig) {
|
|
|
14365
14648
|
}
|
|
14366
14649
|
return;
|
|
14367
14650
|
}
|
|
14368
|
-
function liveModelsFromSnapshots(snapshots) {
|
|
14651
|
+
function liveModelsFromSnapshots(snapshots, config) {
|
|
14369
14652
|
const map = new Map;
|
|
14370
14653
|
for (const snapshot of snapshots) {
|
|
14371
|
-
|
|
14654
|
+
const runtime = config.local.runtimes.find((runtime2) => runtime2.id === snapshot.id);
|
|
14655
|
+
if (runtime === undefined || !runtime.enabled)
|
|
14656
|
+
continue;
|
|
14657
|
+
const kind = localRuntimeKind(runtime);
|
|
14658
|
+
map.set(runtime.defaultModel.providerID, {
|
|
14372
14659
|
reachable: snapshot.reachable,
|
|
14373
|
-
modelIDs: new Set(snapshot.models.map((model) => model.modelID))
|
|
14660
|
+
modelIDs: new Set(snapshot.models.filter((model) => hasRequiredModelResidency(kind, model)).map((model) => model.modelID)),
|
|
14661
|
+
...kind === "lemonade" ? {
|
|
14662
|
+
residency: new Map(snapshot.models.map((model) => [model.modelID, model.loaded]))
|
|
14663
|
+
} : {}
|
|
14374
14664
|
});
|
|
14375
14665
|
}
|
|
14376
14666
|
return map;
|
|
@@ -14656,7 +14946,7 @@ async function runCli(argv, deps) {
|
|
|
14656
14946
|
const agentModels = diagnoseAgentModels(agentFiles, {
|
|
14657
14947
|
opencodeProviders: parseOpencodeProviders(opencodeConfig),
|
|
14658
14948
|
localRuntimes: localRuntimeStates(config),
|
|
14659
|
-
liveModels: liveModelsFromSnapshots(snapshots),
|
|
14949
|
+
liveModels: liveModelsFromSnapshots(snapshots, config),
|
|
14660
14950
|
sourceDir: deps.agentDir,
|
|
14661
14951
|
...defaultModel !== undefined ? { defaultModel } : {}
|
|
14662
14952
|
});
|
|
@@ -14695,29 +14985,53 @@ async function runCli(argv, deps) {
|
|
|
14695
14985
|
const rosterMissing = deps.loadRosterForDoctor !== undefined && roster === undefined && rosterLoadError === undefined;
|
|
14696
14986
|
const orchestratorAgentName = ORCHESTRATOR_AGENT_PATH.slice(ORCHESTRATOR_AGENT_PATH.lastIndexOf("/") + 1).replace(/\.md$/, "");
|
|
14697
14987
|
const orchestratorAgentMissing = !agentFiles.some((file) => file.name === orchestratorAgentName);
|
|
14988
|
+
const inventoryNotes = [];
|
|
14989
|
+
const readySnapshots = snapshots.map((snapshot) => {
|
|
14990
|
+
const runtime = config.local.runtimes.find((runtime2) => runtime2.id === snapshot.id);
|
|
14991
|
+
if (runtime === undefined || localRuntimeKind(runtime) !== "lemonade")
|
|
14992
|
+
return snapshot;
|
|
14993
|
+
inventoryNotes.push(executionSetupMessages.lemonadeInventory(runtime.id, runtime.defaultModel.providerID, snapshot.models));
|
|
14994
|
+
return {
|
|
14995
|
+
...snapshot,
|
|
14996
|
+
models: snapshot.models.filter((model) => hasRequiredModelResidency(localRuntimeKind(runtime), model))
|
|
14997
|
+
};
|
|
14998
|
+
});
|
|
14999
|
+
const residencyNotes = agentModels.flatMap((agent) => {
|
|
15000
|
+
const live = agent.resolution?.live;
|
|
15001
|
+
if (agent.model === undefined || live !== "not-loaded" && live !== "residency-unknown")
|
|
15002
|
+
return [];
|
|
15003
|
+
return [
|
|
15004
|
+
executionSetupMessages.lemonadeAgentResidency(agent.name, `${agent.model.providerID}/${agent.model.modelID}`, live)
|
|
15005
|
+
];
|
|
15006
|
+
});
|
|
14698
15007
|
return {
|
|
14699
15008
|
exitCode: 0,
|
|
14700
|
-
stdout:
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
15009
|
+
stdout: [
|
|
15010
|
+
renderDoctor({
|
|
15011
|
+
config,
|
|
15012
|
+
snapshots: readySnapshots,
|
|
15013
|
+
telemetryPath,
|
|
15014
|
+
telemetryRecords: records.length,
|
|
15015
|
+
agentModels,
|
|
15016
|
+
opencodeConfigPaths,
|
|
15017
|
+
...opencodeConfig !== undefined ? { opencodeConfig } : {},
|
|
15018
|
+
...queueWait !== undefined ? { queueWait } : {},
|
|
15019
|
+
...rosterAudit !== undefined ? { rosterAudit } : {},
|
|
15020
|
+
...rosterRoleCount !== undefined ? { rosterRoleCount } : {},
|
|
15021
|
+
...rosterLoadError !== undefined ? { rosterLoadError } : {},
|
|
15022
|
+
...rosterMissing ? { rosterMissing } : {},
|
|
15023
|
+
...orchestratorAgentMissing ? { orchestratorAgentMissing } : {},
|
|
15024
|
+
...diagnostics !== undefined && diagnostics.length > 0 ? { diagnostics } : {},
|
|
15025
|
+
...opencodeConfigError !== undefined ? { opencodeConfigError } : {},
|
|
15026
|
+
...cacheEntries !== undefined ? { cacheEntries, cliVersion: deps.version } : {},
|
|
15027
|
+
...legacyLayout !== undefined && legacyLayout.length > 0 ? { legacyLayout } : {},
|
|
15028
|
+
...otelBackend !== undefined ? { otelBackend } : {},
|
|
15029
|
+
...gitignoreCoverage !== undefined ? { gitignore: gitignoreCoverage } : {}
|
|
15030
|
+
}),
|
|
15031
|
+
...inventoryNotes,
|
|
15032
|
+
...residencyNotes
|
|
15033
|
+
].join(`
|
|
15034
|
+
`)
|
|
14721
15035
|
};
|
|
14722
15036
|
}
|
|
14723
15037
|
if (command === "migrate") {
|
|
@@ -14901,29 +15215,29 @@ import {
|
|
|
14901
15215
|
writeFile as writeFile2
|
|
14902
15216
|
} from "node:fs/promises";
|
|
14903
15217
|
import { dirname as dirname5, join as join12, resolve as resolve7 } from "node:path";
|
|
14904
|
-
import { z as
|
|
15218
|
+
import { z as z22 } from "zod";
|
|
14905
15219
|
var CONSOLE_RUNTIME_SCHEMA_VERSION = 1;
|
|
14906
15220
|
var CONSOLE_RUNTIME_DIRECTORY = ".opencode/openteam-local/console";
|
|
14907
15221
|
var CONSOLE_RUNTIME_FILE = "runtime.json";
|
|
14908
15222
|
var CONSOLE_LAUNCH_LOCK_FILE = "launch.lock";
|
|
14909
15223
|
var CONSOLE_LOG_FILE = "console.log";
|
|
14910
|
-
var ConsoleRuntimeStateSchema =
|
|
14911
|
-
schemaVersion:
|
|
14912
|
-
pid:
|
|
14913
|
-
workspaceRoot:
|
|
14914
|
-
host:
|
|
14915
|
-
port:
|
|
14916
|
-
url:
|
|
14917
|
-
startedAt:
|
|
14918
|
-
launchId:
|
|
14919
|
-
logPath:
|
|
15224
|
+
var ConsoleRuntimeStateSchema = z22.object({
|
|
15225
|
+
schemaVersion: z22.literal(CONSOLE_RUNTIME_SCHEMA_VERSION),
|
|
15226
|
+
pid: z22.number().int().positive(),
|
|
15227
|
+
workspaceRoot: z22.string().min(1),
|
|
15228
|
+
host: z22.string().min(1),
|
|
15229
|
+
port: z22.number().int().min(1).max(65535),
|
|
15230
|
+
url: z22.url(),
|
|
15231
|
+
startedAt: z22.iso.datetime({ offset: true }),
|
|
15232
|
+
launchId: z22.uuid(),
|
|
15233
|
+
logPath: z22.string().min(1)
|
|
14920
15234
|
}).strict();
|
|
14921
|
-
var ConsoleLaunchLockSchema =
|
|
14922
|
-
schemaVersion:
|
|
14923
|
-
workspaceRoot:
|
|
14924
|
-
launchId:
|
|
14925
|
-
ownerPid:
|
|
14926
|
-
createdAt:
|
|
15235
|
+
var ConsoleLaunchLockSchema = z22.object({
|
|
15236
|
+
schemaVersion: z22.literal(CONSOLE_RUNTIME_SCHEMA_VERSION),
|
|
15237
|
+
workspaceRoot: z22.string().min(1),
|
|
15238
|
+
launchId: z22.uuid(),
|
|
15239
|
+
ownerPid: z22.number().int().positive(),
|
|
15240
|
+
createdAt: z22.iso.datetime({ offset: true })
|
|
14927
15241
|
}).strict();
|
|
14928
15242
|
|
|
14929
15243
|
class ConsoleRuntimeStateFileError extends Error {
|
|
@@ -15622,36 +15936,36 @@ function formatResponse(response) {
|
|
|
15622
15936
|
}
|
|
15623
15937
|
|
|
15624
15938
|
// src/plugin/reportRunSchema.ts
|
|
15625
|
-
import { z as
|
|
15939
|
+
import { z as z24 } from "zod";
|
|
15626
15940
|
|
|
15627
15941
|
// src/plugin/graphShadowIngress.ts
|
|
15628
|
-
import { z as
|
|
15942
|
+
import { z as z23 } from "zod";
|
|
15629
15943
|
var LEGACY_EXECUTION_TRACE_VERSION = 1;
|
|
15630
|
-
var LegacyExecutionStatusSchema =
|
|
15944
|
+
var LegacyExecutionStatusSchema = z23.enum([
|
|
15631
15945
|
"completed",
|
|
15632
15946
|
"failed",
|
|
15633
15947
|
"cancelled"
|
|
15634
15948
|
]);
|
|
15635
|
-
var LegacyReviewOutcomeSchema =
|
|
15949
|
+
var LegacyReviewOutcomeSchema = z23.enum([
|
|
15636
15950
|
"approved",
|
|
15637
15951
|
"rejected",
|
|
15638
15952
|
"inconclusive"
|
|
15639
15953
|
]);
|
|
15640
|
-
var LegacyTraceNodeV1Schema =
|
|
15954
|
+
var LegacyTraceNodeV1Schema = z23.object({
|
|
15641
15955
|
id: NodeIDSchema,
|
|
15642
15956
|
role: NodeRoleSchema,
|
|
15643
|
-
model:
|
|
15644
|
-
sessionRef:
|
|
15957
|
+
model: z23.string().min(1),
|
|
15958
|
+
sessionRef: z23.string().min(1).optional(),
|
|
15645
15959
|
errorClass: ErrorClassSchema.optional()
|
|
15646
15960
|
}).strict();
|
|
15647
|
-
var LegacyExecutionTraceV1Schema =
|
|
15648
|
-
version:
|
|
15961
|
+
var LegacyExecutionTraceV1Schema = z23.object({
|
|
15962
|
+
version: z23.literal(LEGACY_EXECUTION_TRACE_VERSION),
|
|
15649
15963
|
runID: NodeIDSchema,
|
|
15650
15964
|
status: LegacyExecutionStatusSchema,
|
|
15651
15965
|
outcome: LegacyReviewOutcomeSchema,
|
|
15652
|
-
fixes:
|
|
15653
|
-
nodes:
|
|
15654
|
-
parentSessionRef:
|
|
15966
|
+
fixes: z23.number().int().nonnegative(),
|
|
15967
|
+
nodes: z23.array(LegacyTraceNodeV1Schema).min(1),
|
|
15968
|
+
parentSessionRef: z23.string().min(1).optional()
|
|
15655
15969
|
}).strict();
|
|
15656
15970
|
function gateReason2(gate) {
|
|
15657
15971
|
if (gate === undefined || gate.mode === "off") {
|
|
@@ -15722,20 +16036,20 @@ function parseLegacyExecutionTrace(input) {
|
|
|
15722
16036
|
}
|
|
15723
16037
|
|
|
15724
16038
|
// src/plugin/reportRunSchema.ts
|
|
15725
|
-
var ReportRunNodeSchema =
|
|
16039
|
+
var ReportRunNodeSchema = z24.object({
|
|
15726
16040
|
id: NodeIDSchema,
|
|
15727
16041
|
role: NodeRoleSchema,
|
|
15728
|
-
model:
|
|
15729
|
-
ok:
|
|
15730
|
-
sessionRef:
|
|
16042
|
+
model: z24.string().min(1),
|
|
16043
|
+
ok: z24.boolean(),
|
|
16044
|
+
sessionRef: z24.string().min(1).optional(),
|
|
15731
16045
|
errorClass: ErrorClassSchema.optional()
|
|
15732
16046
|
}).strict();
|
|
15733
|
-
var ReportRunPayloadSchema =
|
|
16047
|
+
var ReportRunPayloadSchema = z24.object({
|
|
15734
16048
|
runID: NodeIDSchema,
|
|
15735
16049
|
status: LegacyExecutionStatusSchema,
|
|
15736
|
-
fixes:
|
|
15737
|
-
nodes:
|
|
15738
|
-
parentSessionRef:
|
|
16050
|
+
fixes: z24.number().int().nonnegative(),
|
|
16051
|
+
nodes: z24.array(ReportRunNodeSchema).min(1),
|
|
16052
|
+
parentSessionRef: z24.string().min(1).optional()
|
|
15739
16053
|
}).strict();
|
|
15740
16054
|
|
|
15741
16055
|
// src/orchestrator/graphShadow.ts
|
|
@@ -16839,6 +17153,309 @@ function hashPrompt(prompt) {
|
|
|
16839
17153
|
return `fnv1a32:${(hash >>> 0).toString(16).padStart(8, "0")}`;
|
|
16840
17154
|
}
|
|
16841
17155
|
|
|
17156
|
+
// src/plugin/modelResidency.ts
|
|
17157
|
+
import { z as z25 } from "zod";
|
|
17158
|
+
|
|
17159
|
+
// src/local/lemonadeRequestGuard.ts
|
|
17160
|
+
var inferencePaths = new Set([
|
|
17161
|
+
"/chat/completions",
|
|
17162
|
+
"/completions",
|
|
17163
|
+
"/embeddings",
|
|
17164
|
+
"/responses"
|
|
17165
|
+
]);
|
|
17166
|
+
function modelID(payload) {
|
|
17167
|
+
if (typeof payload !== "object" || payload === null || !("model" in payload) || typeof payload.model !== "string" || payload.model.length === 0 || payload.model !== payload.model.trim()) {
|
|
17168
|
+
throw new ModelResidencyError("request");
|
|
17169
|
+
}
|
|
17170
|
+
if (payload.model.endsWith(":latest"))
|
|
17171
|
+
throw new ModelResidencyError("identity");
|
|
17172
|
+
return payload.model;
|
|
17173
|
+
}
|
|
17174
|
+
function createLemonadeGuardedFetch(options) {
|
|
17175
|
+
const base = lemonadeBaseURL(options.baseURL);
|
|
17176
|
+
const upstream = options.fetch;
|
|
17177
|
+
const healthFetch = options.healthFetch ?? upstream;
|
|
17178
|
+
return Object.assign(async (input, init) => {
|
|
17179
|
+
const request = new Request(input, init);
|
|
17180
|
+
const url = new URL(request.url);
|
|
17181
|
+
if (url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "" || !request.url.startsWith(`${base}/`)) {
|
|
17182
|
+
throw new ModelResidencyError("destination");
|
|
17183
|
+
}
|
|
17184
|
+
const path4 = request.url.slice(base.length);
|
|
17185
|
+
const metadataOnly = request.method === "GET" && (path4 === "/health" || /^\/models(?:\/[^/]+)?$/.test(path4));
|
|
17186
|
+
if (!metadataOnly && (request.method !== "POST" || !inferencePaths.has(path4))) {
|
|
17187
|
+
throw new ModelResidencyError("request");
|
|
17188
|
+
}
|
|
17189
|
+
if (!metadataOnly) {
|
|
17190
|
+
await withResidencyDeadline(async (signal) => {
|
|
17191
|
+
signal.throwIfAborted();
|
|
17192
|
+
let payload;
|
|
17193
|
+
try {
|
|
17194
|
+
payload = await request.clone().json();
|
|
17195
|
+
} catch {
|
|
17196
|
+
signal.throwIfAborted();
|
|
17197
|
+
throw new ModelResidencyError("request");
|
|
17198
|
+
}
|
|
17199
|
+
signal.throwIfAborted();
|
|
17200
|
+
const model = modelID(payload);
|
|
17201
|
+
const modelIDs = typeof options.modelIDs === "function" ? await options.modelIDs() : options.modelIDs;
|
|
17202
|
+
signal.throwIfAborted();
|
|
17203
|
+
if (modelIDs !== undefined && !modelIDs.has(model)) {
|
|
17204
|
+
throw new ModelResidencyError("identity");
|
|
17205
|
+
}
|
|
17206
|
+
const residency = await readLemonadeResidency(base, healthFetch, {
|
|
17207
|
+
...options,
|
|
17208
|
+
signal,
|
|
17209
|
+
headers: request.headers
|
|
17210
|
+
});
|
|
17211
|
+
signal.throwIfAborted();
|
|
17212
|
+
const entry = residency.get(model);
|
|
17213
|
+
if (entry?.loaded !== true) {
|
|
17214
|
+
throw new ModelResidencyError(entry?.loaded === undefined && entry !== undefined ? "unknown" : "inactive");
|
|
17215
|
+
}
|
|
17216
|
+
}, { ...options, signal: request.signal });
|
|
17217
|
+
}
|
|
17218
|
+
if (request.signal.aborted)
|
|
17219
|
+
throw new ModelResidencyError("cancelled");
|
|
17220
|
+
const {
|
|
17221
|
+
body: _body,
|
|
17222
|
+
headers: _headers,
|
|
17223
|
+
method: _method,
|
|
17224
|
+
signal: _signal,
|
|
17225
|
+
redirect: _redirect,
|
|
17226
|
+
...transportOptions
|
|
17227
|
+
} = init ?? {};
|
|
17228
|
+
return upstream(request, { ...transportOptions, redirect: "error" });
|
|
17229
|
+
}, {
|
|
17230
|
+
preconnect: (...args) => upstream.preconnect?.(...args)
|
|
17231
|
+
});
|
|
17232
|
+
}
|
|
17233
|
+
|
|
17234
|
+
// src/plugin/modelResidency.ts
|
|
17235
|
+
function isFetch(value) {
|
|
17236
|
+
return typeof value === "function";
|
|
17237
|
+
}
|
|
17238
|
+
function origin(value) {
|
|
17239
|
+
return typeof value === "string" && URL.canParse(value) ? new URL(value).origin : undefined;
|
|
17240
|
+
}
|
|
17241
|
+
var TEMPLATE_REFERENCE = /\$\{[^}]+\}/;
|
|
17242
|
+
function resolveTemplateReferences(value, readEnv) {
|
|
17243
|
+
let unresolved = false;
|
|
17244
|
+
const resolved = value.replace(/\$\{([^}]+)\}/g, (match, key) => {
|
|
17245
|
+
const resolvedValue = readEnv(key);
|
|
17246
|
+
if (resolvedValue === undefined) {
|
|
17247
|
+
unresolved = true;
|
|
17248
|
+
return match;
|
|
17249
|
+
}
|
|
17250
|
+
return resolvedValue;
|
|
17251
|
+
});
|
|
17252
|
+
return unresolved ? undefined : resolved;
|
|
17253
|
+
}
|
|
17254
|
+
function endpointBinding(value, readEnv) {
|
|
17255
|
+
if (!TEMPLATE_REFERENCE.test(value))
|
|
17256
|
+
return { ambiguous: false, origin: origin(value) };
|
|
17257
|
+
const resolved = resolveTemplateReferences(value, readEnv);
|
|
17258
|
+
return resolved === undefined ? { ambiguous: true } : { ambiguous: false, origin: origin(resolved) };
|
|
17259
|
+
}
|
|
17260
|
+
function optionBaseURL(value) {
|
|
17261
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
17262
|
+
}
|
|
17263
|
+
function providerBase(provider, model) {
|
|
17264
|
+
return optionBaseURL(provider.options?.baseURL) ?? model?.provider?.api ?? provider.api;
|
|
17265
|
+
}
|
|
17266
|
+
function providerRoutes(provider) {
|
|
17267
|
+
const models = Object.values(provider.models ?? {});
|
|
17268
|
+
return (models.length === 0 ? [undefined] : models).map((model) => ({
|
|
17269
|
+
baseURL: providerBase(provider, model),
|
|
17270
|
+
npm: model?.provider?.npm ?? provider.npm
|
|
17271
|
+
}));
|
|
17272
|
+
}
|
|
17273
|
+
function wireID(key, model) {
|
|
17274
|
+
const id = model?.id ?? key;
|
|
17275
|
+
if (id.length === 0 || id !== id.trim())
|
|
17276
|
+
throw new ModelResidencyError("identity");
|
|
17277
|
+
return id;
|
|
17278
|
+
}
|
|
17279
|
+
function nativeEligibleID(id) {
|
|
17280
|
+
return id === "openai" || id === "anthropic" || id.startsWith("opencode");
|
|
17281
|
+
}
|
|
17282
|
+
function configuredRuntime(config, providerID) {
|
|
17283
|
+
const runtimes = config.local.runtimes.filter((runtime2) => runtime2.defaultModel.providerID === providerID);
|
|
17284
|
+
const runtime = runtimes[0];
|
|
17285
|
+
if (runtimes.length !== 1 || runtime === undefined || !runtime.enabled) {
|
|
17286
|
+
throw new ModelResidencyError("destination");
|
|
17287
|
+
}
|
|
17288
|
+
return runtime;
|
|
17289
|
+
}
|
|
17290
|
+
function createModelResidencyGuard(config, options) {
|
|
17291
|
+
const guarded = new Map;
|
|
17292
|
+
const blocked = new Set;
|
|
17293
|
+
let hostConfig;
|
|
17294
|
+
const readEnv = options.readEnv ?? ((name) => process.env[name]);
|
|
17295
|
+
const lemonadeRuntimes = () => config.local.runtimes.filter((runtime) => localRuntimeKind(runtime) === "lemonade");
|
|
17296
|
+
const protects = (providerID, baseURL) => lemonadeRuntimes().some((runtime) => {
|
|
17297
|
+
if (runtime.defaultModel.providerID === providerID)
|
|
17298
|
+
return true;
|
|
17299
|
+
if (baseURL === undefined)
|
|
17300
|
+
return false;
|
|
17301
|
+
const binding = endpointBinding(baseURL, readEnv);
|
|
17302
|
+
if (binding.ambiguous)
|
|
17303
|
+
return true;
|
|
17304
|
+
return binding.origin !== undefined && binding.origin === origin(runtime.baseURL ?? LEMONADE_DEFAULT_BASE_URL);
|
|
17305
|
+
});
|
|
17306
|
+
const resolvedWireID = (model, declaredID) => {
|
|
17307
|
+
const id = options.resolveApiModelID === undefined ? declaredID : options.resolveApiModelID(model);
|
|
17308
|
+
if (id === undefined)
|
|
17309
|
+
throw new ModelResidencyError("identity");
|
|
17310
|
+
return wireID(id, undefined);
|
|
17311
|
+
};
|
|
17312
|
+
const configHook = async (host) => {
|
|
17313
|
+
hostConfig = host;
|
|
17314
|
+
const previousGuards = new Map(guarded);
|
|
17315
|
+
guarded.clear();
|
|
17316
|
+
blocked.clear();
|
|
17317
|
+
for (const [providerID, provider] of Object.entries(host.provider ?? {})) {
|
|
17318
|
+
const routes = providerRoutes(provider);
|
|
17319
|
+
if (!routes.some((route) => protects(providerID, route.baseURL)))
|
|
17320
|
+
continue;
|
|
17321
|
+
const previous = previousGuards.get(providerID);
|
|
17322
|
+
const configuredFetch = provider.options?.fetch;
|
|
17323
|
+
const originalFetch = previous !== undefined && configuredFetch === previous.fetch ? previous.originalFetch : configuredFetch ?? options.fetch;
|
|
17324
|
+
blocked.add(providerID);
|
|
17325
|
+
const wasDisabled = host.disabled_providers?.includes(providerID) ?? false;
|
|
17326
|
+
host.disabled_providers = [
|
|
17327
|
+
...new Set([...host.disabled_providers ?? [], providerID])
|
|
17328
|
+
];
|
|
17329
|
+
const reject = Object.assign(async () => {
|
|
17330
|
+
throw new ModelResidencyError("transport");
|
|
17331
|
+
}, { preconnect: () => {} });
|
|
17332
|
+
provider.options = { ...provider.options, fetch: reject };
|
|
17333
|
+
try {
|
|
17334
|
+
const runtime = configuredRuntime(config, providerID);
|
|
17335
|
+
const baseURL = lemonadeBaseURL(runtime.baseURL ?? LEMONADE_DEFAULT_BASE_URL);
|
|
17336
|
+
if (localRuntimeKind(runtime) !== "lemonade" || routes.some((route) => route.baseURL === undefined || lemonadeBaseURL(route.baseURL) !== baseURL))
|
|
17337
|
+
throw new ModelResidencyError("destination");
|
|
17338
|
+
if (routes.some((route) => route.npm !== "@ai-sdk/openai-compatible") || nativeEligibleID(providerID) || !isFetch(originalFetch))
|
|
17339
|
+
throw new ModelResidencyError("transport");
|
|
17340
|
+
const modelKeys = new Map;
|
|
17341
|
+
for (const [key, model] of Object.entries(provider.models ?? {})) {
|
|
17342
|
+
if (model.options?.fetch !== undefined || model.options?.baseURL !== undefined && (typeof model.options.baseURL !== "string" || lemonadeBaseURL(model.options.baseURL) !== baseURL))
|
|
17343
|
+
throw new ModelResidencyError("transport");
|
|
17344
|
+
modelKeys.set(key, wireID(key, model));
|
|
17345
|
+
}
|
|
17346
|
+
if (!modelKeys.has(runtime.defaultModel.modelID))
|
|
17347
|
+
modelKeys.set(runtime.defaultModel.modelID, undefined);
|
|
17348
|
+
const modelIDs = () => {
|
|
17349
|
+
const ids = new Set;
|
|
17350
|
+
for (const [modelID2, declaredID] of modelKeys) {
|
|
17351
|
+
const id = options.resolveApiModelID === undefined ? declaredID : options.resolveApiModelID({ providerID, modelID: modelID2 });
|
|
17352
|
+
if (id !== undefined)
|
|
17353
|
+
ids.add(wireID(id, undefined));
|
|
17354
|
+
}
|
|
17355
|
+
return ids;
|
|
17356
|
+
};
|
|
17357
|
+
const fetch = createLemonadeGuardedFetch({
|
|
17358
|
+
...options,
|
|
17359
|
+
baseURL,
|
|
17360
|
+
modelIDs: async () => {
|
|
17361
|
+
await options.modelInventoryReady?.();
|
|
17362
|
+
return modelIDs();
|
|
17363
|
+
},
|
|
17364
|
+
fetch: originalFetch,
|
|
17365
|
+
healthFetch: options.fetch
|
|
17366
|
+
});
|
|
17367
|
+
provider.options.fetch = fetch;
|
|
17368
|
+
guarded.set(providerID, {
|
|
17369
|
+
baseURL,
|
|
17370
|
+
fetch,
|
|
17371
|
+
originalFetch,
|
|
17372
|
+
modelIDs,
|
|
17373
|
+
modelKeys
|
|
17374
|
+
});
|
|
17375
|
+
blocked.delete(providerID);
|
|
17376
|
+
if (!wasDisabled) {
|
|
17377
|
+
host.disabled_providers = host.disabled_providers.filter((id) => id !== providerID);
|
|
17378
|
+
}
|
|
17379
|
+
} catch (error) {
|
|
17380
|
+
if (!(error instanceof ModelResidencyError))
|
|
17381
|
+
throw error;
|
|
17382
|
+
(options.warn ?? console.warn)(modelResidencyMessages.providerDisabled(providerID));
|
|
17383
|
+
}
|
|
17384
|
+
}
|
|
17385
|
+
};
|
|
17386
|
+
const beforeInference = async (input) => {
|
|
17387
|
+
const base = optionBaseURL(input.provider.options.baseURL) ?? input.model.api.url;
|
|
17388
|
+
if (!protects(input.model.providerID, base))
|
|
17389
|
+
return;
|
|
17390
|
+
const provider = guarded.get(input.model.providerID);
|
|
17391
|
+
if (provider === undefined || blocked.has(input.model.providerID) || input.provider.options.fetch !== provider.fetch || input.model.api.npm !== "@ai-sdk/openai-compatible" || nativeEligibleID(input.model.providerID))
|
|
17392
|
+
throw new ModelResidencyError("transport");
|
|
17393
|
+
if (lemonadeBaseURL(base) !== provider.baseURL) {
|
|
17394
|
+
throw new ModelResidencyError("destination");
|
|
17395
|
+
}
|
|
17396
|
+
const id = resolvedWireID({ providerID: input.model.providerID, modelID: input.model.id }, provider.modelKeys.get(input.model.id));
|
|
17397
|
+
if (id !== input.model.api.id)
|
|
17398
|
+
throw new ModelResidencyError("identity");
|
|
17399
|
+
if (!provider.modelKeys.has(input.model.id))
|
|
17400
|
+
provider.modelKeys.set(input.model.id, undefined);
|
|
17401
|
+
};
|
|
17402
|
+
const localTarget = (model) => {
|
|
17403
|
+
const runtime = configuredRuntime(config, model.providerID);
|
|
17404
|
+
if (hostConfig?.disabled_providers?.includes(model.providerID)) {
|
|
17405
|
+
throw new ModelResidencyError("transport");
|
|
17406
|
+
}
|
|
17407
|
+
if (runtime.baseURL === undefined)
|
|
17408
|
+
throw new ModelResidencyError("destination");
|
|
17409
|
+
const provider = hostConfig?.provider?.[model.providerID];
|
|
17410
|
+
const entry = Object.hasOwn(provider?.models ?? {}, model.modelID) ? provider?.models?.[model.modelID] : undefined;
|
|
17411
|
+
const configuredURL = provider === undefined ? undefined : providerBase(provider, entry);
|
|
17412
|
+
if (configuredURL !== undefined && new URL(configuredURL).href.replace(/\/$/, "") !== new URL(runtime.baseURL).href.replace(/\/$/, "")) {
|
|
17413
|
+
throw new ModelResidencyError("destination");
|
|
17414
|
+
}
|
|
17415
|
+
const modelID2 = resolvedWireID(model, entry === undefined && localRuntimeKind(runtime) === "lemonade" ? undefined : wireID(model.modelID, entry));
|
|
17416
|
+
let fetch = options.fetch;
|
|
17417
|
+
if (localRuntimeKind(runtime) === "lemonade") {
|
|
17418
|
+
const installed = guarded.get(model.providerID);
|
|
17419
|
+
if (installed === undefined || blocked.has(model.providerID)) {
|
|
17420
|
+
throw new ModelResidencyError("transport");
|
|
17421
|
+
}
|
|
17422
|
+
if (installed.baseURL !== lemonadeBaseURL(runtime.baseURL)) {
|
|
17423
|
+
throw new ModelResidencyError("destination");
|
|
17424
|
+
}
|
|
17425
|
+
if (!installed.modelKeys.has(model.modelID))
|
|
17426
|
+
installed.modelKeys.set(model.modelID, undefined);
|
|
17427
|
+
if (!installed.modelIDs().has(modelID2))
|
|
17428
|
+
throw new ModelResidencyError("identity");
|
|
17429
|
+
fetch = installed.fetch;
|
|
17430
|
+
}
|
|
17431
|
+
const configuredHeaders = z25.record(z25.string(), z25.string()).safeParse(provider?.options?.headers ?? {});
|
|
17432
|
+
if (!configuredHeaders.success)
|
|
17433
|
+
throw new ModelResidencyError("configuration");
|
|
17434
|
+
const headers = new Headers(configuredHeaders.data);
|
|
17435
|
+
if (typeof provider?.options?.apiKey === "string" && !headers.has("authorization")) {
|
|
17436
|
+
headers.set("authorization", `Bearer ${provider.options.apiKey}`);
|
|
17437
|
+
}
|
|
17438
|
+
for (const [name, value] of Object.entries(entry?.headers ?? {}))
|
|
17439
|
+
headers.set(name, value);
|
|
17440
|
+
const upstream = fetch;
|
|
17441
|
+
return {
|
|
17442
|
+
baseURL: runtime.baseURL,
|
|
17443
|
+
modelID: modelID2,
|
|
17444
|
+
fetch: [...headers].length === 0 ? fetch : Object.assign(async (input, init) => {
|
|
17445
|
+
const request = new Request(input, init);
|
|
17446
|
+
for (const [name, value] of headers) {
|
|
17447
|
+
if (!request.headers.has(name))
|
|
17448
|
+
request.headers.set(name, value);
|
|
17449
|
+
}
|
|
17450
|
+
return upstream(request);
|
|
17451
|
+
}, {
|
|
17452
|
+
preconnect: (...args) => upstream.preconnect?.(...args)
|
|
17453
|
+
})
|
|
17454
|
+
};
|
|
17455
|
+
};
|
|
17456
|
+
return { config: configHook, beforeInference, localTarget };
|
|
17457
|
+
}
|
|
17458
|
+
|
|
16842
17459
|
// src/plugin/hooks.ts
|
|
16843
17460
|
var codeSignals = [
|
|
16844
17461
|
"```",
|
|
@@ -16982,7 +17599,10 @@ function createChatMessageHook(config, getAvailable, options = {}) {
|
|
|
16982
17599
|
};
|
|
16983
17600
|
}
|
|
16984
17601
|
function createHooks(config, getAvailable, options = {}) {
|
|
17602
|
+
const residency = options.modelResidency ?? createModelResidencyGuard(config, { fetch: globalThis.fetch });
|
|
16985
17603
|
return {
|
|
17604
|
+
config: residency.config,
|
|
17605
|
+
"chat.params": residency.beforeInference,
|
|
16986
17606
|
"chat.message": createChatMessageHook(config, getAvailable, options)
|
|
16987
17607
|
};
|
|
16988
17608
|
}
|
|
@@ -17036,62 +17656,62 @@ ${lines.join(`
|
|
|
17036
17656
|
}
|
|
17037
17657
|
|
|
17038
17658
|
// src/memory/types.ts
|
|
17039
|
-
import { z as
|
|
17659
|
+
import { z as z26 } from "zod";
|
|
17040
17660
|
var SHARED_OWNER_KEY = "*";
|
|
17041
|
-
var OwnerKeySchema =
|
|
17042
|
-
var MemoryKindSchema =
|
|
17043
|
-
var MemoryBaseSchema =
|
|
17044
|
-
id:
|
|
17661
|
+
var OwnerKeySchema = z26.string().min(1);
|
|
17662
|
+
var MemoryKindSchema = z26.enum(["fact", "preference", "entity"]);
|
|
17663
|
+
var MemoryBaseSchema = z26.object({
|
|
17664
|
+
id: z26.string().min(1),
|
|
17045
17665
|
ownerKey: OwnerKeySchema,
|
|
17046
|
-
confidence:
|
|
17047
|
-
validFrom:
|
|
17048
|
-
validUntil:
|
|
17049
|
-
createdAt:
|
|
17050
|
-
invalidatedAt:
|
|
17051
|
-
sourceHash:
|
|
17052
|
-
supersededBy:
|
|
17666
|
+
confidence: z26.number().min(0).max(1),
|
|
17667
|
+
validFrom: z26.number().finite(),
|
|
17668
|
+
validUntil: z26.number().finite().nullable().default(null),
|
|
17669
|
+
createdAt: z26.number().finite(),
|
|
17670
|
+
invalidatedAt: z26.number().finite().nullable().default(null),
|
|
17671
|
+
sourceHash: z26.string().min(1),
|
|
17672
|
+
supersededBy: z26.string().min(1).nullable().default(null)
|
|
17053
17673
|
}).strict();
|
|
17054
17674
|
var FactSchema = MemoryBaseSchema.extend({
|
|
17055
|
-
kind:
|
|
17056
|
-
subject:
|
|
17057
|
-
predicate:
|
|
17058
|
-
object:
|
|
17059
|
-
category:
|
|
17675
|
+
kind: z26.literal("fact"),
|
|
17676
|
+
subject: z26.string().min(1),
|
|
17677
|
+
predicate: z26.string().min(1),
|
|
17678
|
+
object: z26.string().min(1),
|
|
17679
|
+
category: z26.string().min(1).nullable().default(null)
|
|
17060
17680
|
});
|
|
17061
17681
|
var PreferenceSchema = MemoryBaseSchema.extend({
|
|
17062
|
-
kind:
|
|
17063
|
-
category:
|
|
17064
|
-
preference:
|
|
17065
|
-
context:
|
|
17066
|
-
lastAccessedAt:
|
|
17067
|
-
accessCount:
|
|
17682
|
+
kind: z26.literal("preference"),
|
|
17683
|
+
category: z26.string().min(1),
|
|
17684
|
+
preference: z26.string().min(1),
|
|
17685
|
+
context: z26.string().min(1).nullable().default(null),
|
|
17686
|
+
lastAccessedAt: z26.number().finite().nullable().default(null),
|
|
17687
|
+
accessCount: z26.number().int().min(0).default(0)
|
|
17068
17688
|
});
|
|
17069
17689
|
var EntitySchema = MemoryBaseSchema.extend({
|
|
17070
|
-
kind:
|
|
17071
|
-
canonicalName:
|
|
17072
|
-
type:
|
|
17073
|
-
aliases:
|
|
17690
|
+
kind: z26.literal("entity"),
|
|
17691
|
+
canonicalName: z26.string().min(1),
|
|
17692
|
+
type: z26.string().min(1),
|
|
17693
|
+
aliases: z26.array(z26.string().min(1)).default([])
|
|
17074
17694
|
});
|
|
17075
17695
|
var RelationSchema = MemoryBaseSchema.extend({
|
|
17076
|
-
kind:
|
|
17077
|
-
from:
|
|
17078
|
-
to:
|
|
17079
|
-
predicate:
|
|
17080
|
-
annotation:
|
|
17696
|
+
kind: z26.literal("relation"),
|
|
17697
|
+
from: z26.string().min(1),
|
|
17698
|
+
to: z26.string().min(1),
|
|
17699
|
+
predicate: z26.string().min(1),
|
|
17700
|
+
annotation: z26.string().min(1).nullable().default(null)
|
|
17081
17701
|
});
|
|
17082
|
-
var MemoryRecordSchema =
|
|
17702
|
+
var MemoryRecordSchema = z26.discriminatedUnion("kind", [
|
|
17083
17703
|
FactSchema,
|
|
17084
17704
|
PreferenceSchema,
|
|
17085
17705
|
EntitySchema,
|
|
17086
17706
|
RelationSchema
|
|
17087
17707
|
]);
|
|
17088
|
-
var RecallQuerySchema =
|
|
17708
|
+
var RecallQuerySchema = z26.object({
|
|
17089
17709
|
ownerKey: OwnerKeySchema,
|
|
17090
|
-
kinds:
|
|
17091
|
-
asOf:
|
|
17092
|
-
limit:
|
|
17093
|
-
minSimilarity:
|
|
17094
|
-
includeShared:
|
|
17710
|
+
kinds: z26.array(MemoryKindSchema).default(["fact", "preference", "entity"]),
|
|
17711
|
+
asOf: z26.number().finite().nullable().default(null),
|
|
17712
|
+
limit: z26.number().int().positive().default(8),
|
|
17713
|
+
minSimilarity: z26.number().min(0).max(1).default(0.2),
|
|
17714
|
+
includeShared: z26.boolean().default(true)
|
|
17095
17715
|
}).strict();
|
|
17096
17716
|
|
|
17097
17717
|
// src/memory/rank.ts
|
|
@@ -17662,42 +18282,42 @@ function buildMemoryInjector(deps, policy) {
|
|
|
17662
18282
|
|
|
17663
18283
|
// src/plugin/memoryTool.ts
|
|
17664
18284
|
import { tool as tool4 } from "@opencode-ai/plugin";
|
|
17665
|
-
import { z as
|
|
18285
|
+
import { z as z28 } from "zod";
|
|
17666
18286
|
|
|
17667
18287
|
// src/memory/extract.ts
|
|
17668
|
-
import { z as
|
|
18288
|
+
import { z as z27 } from "zod";
|
|
17669
18289
|
var REDACTED = "[redacted]";
|
|
17670
|
-
var RawFactSchema =
|
|
17671
|
-
subject:
|
|
17672
|
-
predicate:
|
|
17673
|
-
object:
|
|
17674
|
-
category:
|
|
17675
|
-
confidence:
|
|
18290
|
+
var RawFactSchema = z27.object({
|
|
18291
|
+
subject: z27.string().min(1),
|
|
18292
|
+
predicate: z27.string().min(1),
|
|
18293
|
+
object: z27.string().min(1),
|
|
18294
|
+
category: z27.string().min(1).nullable().optional(),
|
|
18295
|
+
confidence: z27.number().min(0).max(1).optional()
|
|
17676
18296
|
});
|
|
17677
|
-
var RawPreferenceSchema =
|
|
17678
|
-
category:
|
|
17679
|
-
preference:
|
|
17680
|
-
context:
|
|
17681
|
-
confidence:
|
|
18297
|
+
var RawPreferenceSchema = z27.object({
|
|
18298
|
+
category: z27.string().min(1),
|
|
18299
|
+
preference: z27.string().min(1),
|
|
18300
|
+
context: z27.string().min(1).nullable().optional(),
|
|
18301
|
+
confidence: z27.number().min(0).max(1).optional()
|
|
17682
18302
|
});
|
|
17683
|
-
var RawEntitySchema =
|
|
17684
|
-
canonicalName:
|
|
17685
|
-
type:
|
|
17686
|
-
aliases:
|
|
17687
|
-
confidence:
|
|
18303
|
+
var RawEntitySchema = z27.object({
|
|
18304
|
+
canonicalName: z27.string().min(1),
|
|
18305
|
+
type: z27.string().min(1),
|
|
18306
|
+
aliases: z27.array(z27.string().min(1)).optional(),
|
|
18307
|
+
confidence: z27.number().min(0).max(1).optional()
|
|
17688
18308
|
});
|
|
17689
|
-
var RawRelationSchema =
|
|
17690
|
-
from:
|
|
17691
|
-
to:
|
|
17692
|
-
predicate:
|
|
17693
|
-
annotation:
|
|
17694
|
-
confidence:
|
|
18309
|
+
var RawRelationSchema = z27.object({
|
|
18310
|
+
from: z27.string().min(1),
|
|
18311
|
+
to: z27.string().min(1),
|
|
18312
|
+
predicate: z27.string().min(1),
|
|
18313
|
+
annotation: z27.string().min(1).nullable().optional(),
|
|
18314
|
+
confidence: z27.number().min(0).max(1).optional()
|
|
17695
18315
|
}).strict();
|
|
17696
|
-
var RawExtractionSchema =
|
|
17697
|
-
facts:
|
|
17698
|
-
preferences:
|
|
17699
|
-
entities:
|
|
17700
|
-
relations:
|
|
18316
|
+
var RawExtractionSchema = z27.object({
|
|
18317
|
+
facts: z27.array(RawFactSchema).default([]),
|
|
18318
|
+
preferences: z27.array(RawPreferenceSchema).default([]),
|
|
18319
|
+
entities: z27.array(RawEntitySchema).default([]),
|
|
18320
|
+
relations: z27.array(RawRelationSchema).default([])
|
|
17701
18321
|
});
|
|
17702
18322
|
var DEFAULT_CONFIDENCE = 0.6;
|
|
17703
18323
|
var SYSTEM_PROMPT = [
|
|
@@ -17951,13 +18571,13 @@ var memoryToolMessages = {
|
|
|
17951
18571
|
|
|
17952
18572
|
// src/plugin/memoryTool.ts
|
|
17953
18573
|
var SCRIBE_ROLE_ID = "scribe";
|
|
17954
|
-
var MemoryMessageSchema =
|
|
17955
|
-
role:
|
|
17956
|
-
content:
|
|
18574
|
+
var MemoryMessageSchema = z28.object({
|
|
18575
|
+
role: z28.enum(["system", "user", "assistant"]).describe(memoryToolMessages.messageRoleDescription),
|
|
18576
|
+
content: z28.string().min(1).describe(memoryToolMessages.messageContentDescription)
|
|
17957
18577
|
}).strict();
|
|
17958
|
-
var MemoryWritePayloadSchema =
|
|
17959
|
-
messages:
|
|
17960
|
-
roleID:
|
|
18578
|
+
var MemoryWritePayloadSchema = z28.object({
|
|
18579
|
+
messages: z28.array(MemoryMessageSchema).min(1).describe(memoryToolMessages.messagesDescription),
|
|
18580
|
+
roleID: z28.string().min(1).default(SCRIBE_ROLE_ID).describe(memoryToolMessages.roleIDDescription)
|
|
17961
18581
|
}).strict();
|
|
17962
18582
|
function createMemoryTool(deps) {
|
|
17963
18583
|
return tool4({
|
|
@@ -17969,7 +18589,7 @@ function createMemoryTool(deps) {
|
|
|
17969
18589
|
})).describe(memoryToolMessages.messagesDescription),
|
|
17970
18590
|
roleID: tool4.schema.string().optional().describe(memoryToolMessages.roleIDDescription)
|
|
17971
18591
|
},
|
|
17972
|
-
async execute(args) {
|
|
18592
|
+
async execute(args, toolContext) {
|
|
17973
18593
|
const parsed = MemoryWritePayloadSchema.safeParse(args);
|
|
17974
18594
|
if (!parsed.success) {
|
|
17975
18595
|
return memoryToolMessages.validationError(parsed.error.message);
|
|
@@ -17990,33 +18610,83 @@ function createMemoryTool(deps) {
|
|
|
17990
18610
|
if (executionMode2 === "frontier") {
|
|
17991
18611
|
return memoryToolMessages.frontierDomainRefusal;
|
|
17992
18612
|
}
|
|
17993
|
-
if (!await deps.localRuntimeReachable()) {
|
|
17994
|
-
return memoryToolMessages.localRuntimeUnavailable;
|
|
17995
|
-
}
|
|
17996
|
-
const runtime = deps.config.local.runtimes.find((rt) => rt.enabled && typeof rt.baseURL === "string" && rt.baseURL.length > 0);
|
|
17997
|
-
if (runtime?.baseURL === undefined) {
|
|
17998
|
-
return memoryToolMessages.localRuntimeBaseURLMissing;
|
|
17999
|
-
}
|
|
18000
|
-
const modelID = semantic.extraction.model?.modelID ?? runtime.defaultModel.modelID;
|
|
18001
|
-
const transcript = messages.map((m) => `${m.role}: ${m.content}`).join(`
|
|
18002
|
-
`);
|
|
18003
|
-
const sourceHash = sha256Hex(transcript);
|
|
18004
|
-
const now = deps.now();
|
|
18005
|
-
const context = {
|
|
18006
|
-
ownerKey: semantic.scope === "user" ? "user" : "project",
|
|
18007
|
-
now,
|
|
18008
|
-
sourceHash,
|
|
18009
|
-
storeContent: semantic.storeContent,
|
|
18010
|
-
idPrefix: `${sourceHash.slice(0, 12)}:${now}`
|
|
18011
|
-
};
|
|
18012
18613
|
let records;
|
|
18013
18614
|
try {
|
|
18615
|
+
const signal = toolContext.abort;
|
|
18616
|
+
const throwIfAborted = () => {
|
|
18617
|
+
if (signal?.aborted)
|
|
18618
|
+
throw new ModelResidencyError("cancelled");
|
|
18619
|
+
};
|
|
18620
|
+
throwIfAborted();
|
|
18621
|
+
const configuredModel = semantic.extraction.model;
|
|
18622
|
+
let runtime;
|
|
18623
|
+
if (configuredModel != null) {
|
|
18624
|
+
const matches = deps.config.local.runtimes.filter((candidate) => candidate.defaultModel.providerID === configuredModel.providerID);
|
|
18625
|
+
runtime = matches[0];
|
|
18626
|
+
if (matches.length !== 1 || runtime === undefined || !runtime.enabled) {
|
|
18627
|
+
return modelResidencyMessages.extractionRuntimeUnavailable;
|
|
18628
|
+
}
|
|
18629
|
+
} else {
|
|
18630
|
+
runtime = deps.config.local.runtimes.find((candidate) => candidate.enabled && typeof candidate.baseURL === "string" && candidate.baseURL.length > 0);
|
|
18631
|
+
}
|
|
18632
|
+
if (runtime?.baseURL === undefined || runtime.baseURL.length === 0) {
|
|
18633
|
+
return memoryToolMessages.localRuntimeBaseURLMissing;
|
|
18634
|
+
}
|
|
18635
|
+
const baseURL = runtime.baseURL;
|
|
18636
|
+
const model = configuredModel ?? runtime.defaultModel;
|
|
18637
|
+
const selectedRuntime = runtime;
|
|
18638
|
+
const deadline = {
|
|
18639
|
+
...deps.residencyOptions,
|
|
18640
|
+
...signal === undefined ? {} : { signal }
|
|
18641
|
+
};
|
|
18642
|
+
const reachable = localRuntimeKind(runtime) === "lemonade" ? await withResidencyDeadline((signal2) => deps.localRuntimeReachable(selectedRuntime, signal2), deadline) : await deps.localRuntimeReachable(runtime);
|
|
18643
|
+
throwIfAborted();
|
|
18644
|
+
if (!reachable)
|
|
18645
|
+
return memoryToolMessages.localRuntimeUnavailable;
|
|
18646
|
+
const resolveTarget = deps.resolveExtractionTarget;
|
|
18647
|
+
const target = resolveTarget ? await withResidencyDeadline(async () => resolveTarget(model), deadline) : {
|
|
18648
|
+
baseURL,
|
|
18649
|
+
modelID: model.modelID,
|
|
18650
|
+
fetch: localRuntimeKind(runtime) === "lemonade" ? createLemonadeGuardedFetch({
|
|
18651
|
+
baseURL,
|
|
18652
|
+
fetch: deps.fetch,
|
|
18653
|
+
modelIDs: new Set([model.modelID]),
|
|
18654
|
+
...deps.residencyOptions
|
|
18655
|
+
}) : deps.fetch
|
|
18656
|
+
};
|
|
18657
|
+
throwIfAborted();
|
|
18658
|
+
if (target === undefined || target.baseURL !== baseURL) {
|
|
18659
|
+
throw new ModelResidencyError("destination");
|
|
18660
|
+
}
|
|
18661
|
+
const fetch = signal === undefined ? target.fetch : Object.assign(async (input, init) => {
|
|
18662
|
+
throwIfAborted();
|
|
18663
|
+
const response = await target.fetch(input, {
|
|
18664
|
+
...init,
|
|
18665
|
+
signal
|
|
18666
|
+
});
|
|
18667
|
+
throwIfAborted();
|
|
18668
|
+
return response;
|
|
18669
|
+
}, {
|
|
18670
|
+
preconnect: (...args2) => target.fetch.preconnect?.(...args2)
|
|
18671
|
+
});
|
|
18672
|
+
const transcript = messages.map((m) => `${m.role}: ${m.content}`).join(`
|
|
18673
|
+
`);
|
|
18674
|
+
const sourceHash = sha256Hex(transcript);
|
|
18675
|
+
const now = deps.now();
|
|
18676
|
+
const context = {
|
|
18677
|
+
ownerKey: semantic.scope === "user" ? "user" : "project",
|
|
18678
|
+
now,
|
|
18679
|
+
sourceHash,
|
|
18680
|
+
storeContent: semantic.storeContent,
|
|
18681
|
+
idPrefix: `${sourceHash.slice(0, 12)}:${now}`
|
|
18682
|
+
};
|
|
18014
18683
|
records = await extractMemory({
|
|
18015
|
-
baseURL:
|
|
18016
|
-
modelID,
|
|
18684
|
+
baseURL: target.baseURL,
|
|
18685
|
+
modelID: target.modelID,
|
|
18017
18686
|
messages,
|
|
18018
18687
|
context
|
|
18019
|
-
}, { fetch
|
|
18688
|
+
}, { fetch, ...deps.warn ? { warn: deps.warn } : {} });
|
|
18689
|
+
throwIfAborted();
|
|
18020
18690
|
} catch (error) {
|
|
18021
18691
|
const reason = error instanceof Error ? error.message : String(error);
|
|
18022
18692
|
return memoryToolMessages.extractionFailure(reason);
|
|
@@ -18082,10 +18752,10 @@ function createOrchestratedModelOwnership() {
|
|
|
18082
18752
|
|
|
18083
18753
|
// src/plugin/orchestrateTool.ts
|
|
18084
18754
|
import { tool as tool5 } from "@opencode-ai/plugin";
|
|
18085
|
-
import { z as
|
|
18755
|
+
import { z as z30 } from "zod";
|
|
18086
18756
|
|
|
18087
18757
|
// src/orchestrator/coordinator.ts
|
|
18088
|
-
import { z as
|
|
18758
|
+
import { z as z29 } from "zod";
|
|
18089
18759
|
|
|
18090
18760
|
// src/orchestrator/nodeIteration.ts
|
|
18091
18761
|
var DEFAULT_MAX_RETRIES = 2;
|
|
@@ -18295,12 +18965,15 @@ async function applyReportDurabilityGate(results, probe) {
|
|
|
18295
18965
|
}
|
|
18296
18966
|
|
|
18297
18967
|
// src/orchestrator/runtimeSelection.ts
|
|
18298
|
-
function
|
|
18968
|
+
function configuredRuntime2(runtimeId, config) {
|
|
18299
18969
|
return config.local.runtimes.find((runtime) => runtime.id === runtimeId);
|
|
18300
18970
|
}
|
|
18301
18971
|
function runtimeIdOfModel(model, config) {
|
|
18302
18972
|
return config.local.runtimes.find((runtime) => sameModel(runtime.defaultModel, model))?.id;
|
|
18303
18973
|
}
|
|
18974
|
+
function enabledRuntimeForProvider(providerID, config) {
|
|
18975
|
+
return config.local.runtimes.find((runtime) => runtime.enabled && runtime.defaultModel.providerID === providerID)?.id;
|
|
18976
|
+
}
|
|
18304
18977
|
function roleLocalModel(role, runtimeId, fallback, runtime) {
|
|
18305
18978
|
const pinned = role.localModels?.[runtimeId];
|
|
18306
18979
|
if (pinned !== undefined) {
|
|
@@ -18315,7 +18988,7 @@ function runtimeClassModel(modelClass, runtime) {
|
|
|
18315
18988
|
}
|
|
18316
18989
|
return modelClass === "thinking" ? runtime.thinkingModel : runtime.coderModel;
|
|
18317
18990
|
}
|
|
18318
|
-
function selectDispatchRuntime(role, decision2, reachable, config) {
|
|
18991
|
+
function selectDispatchRuntime(role, decision2, reachable, config, availableModels2) {
|
|
18319
18992
|
if (decision2.routeKind !== "local") {
|
|
18320
18993
|
return { runtimeId: undefined, decision: decision2 };
|
|
18321
18994
|
}
|
|
@@ -18326,7 +18999,7 @@ function selectDispatchRuntime(role, decision2, reachable, config) {
|
|
|
18326
18999
|
if (!reachable.has(runtimeId)) {
|
|
18327
19000
|
continue;
|
|
18328
19001
|
}
|
|
18329
|
-
const runtime =
|
|
19002
|
+
const runtime = configuredRuntime2(runtimeId, config);
|
|
18330
19003
|
if (runtime?.defaultModel.providerID === decision2.selected.providerID) {
|
|
18331
19004
|
return { runtimeId, decision: decision2 };
|
|
18332
19005
|
}
|
|
@@ -18336,15 +19009,17 @@ function selectDispatchRuntime(role, decision2, reachable, config) {
|
|
|
18336
19009
|
if (exactRuntimeId !== undefined) {
|
|
18337
19010
|
return { runtimeId: exactRuntimeId, decision: decision2 };
|
|
18338
19011
|
}
|
|
18339
|
-
|
|
18340
|
-
|
|
19012
|
+
return {
|
|
19013
|
+
runtimeId: enabledRuntimeForProvider(decision2.selected.providerID, config),
|
|
19014
|
+
decision: decision2
|
|
19015
|
+
};
|
|
18341
19016
|
}
|
|
18342
19017
|
if (listed !== undefined && listed.length > 0 && reachable !== undefined) {
|
|
18343
19018
|
for (const runtimeId of listed) {
|
|
18344
19019
|
if (!reachable.has(runtimeId)) {
|
|
18345
19020
|
continue;
|
|
18346
19021
|
}
|
|
18347
|
-
const runtime =
|
|
19022
|
+
const runtime = configuredRuntime2(runtimeId, config);
|
|
18348
19023
|
if (runtime === undefined) {
|
|
18349
19024
|
continue;
|
|
18350
19025
|
}
|
|
@@ -18357,7 +19032,7 @@ function selectDispatchRuntime(role, decision2, reachable, config) {
|
|
|
18357
19032
|
}
|
|
18358
19033
|
const resolvedRuntimeId = runtimeIdOfModel(decision2.selected, config);
|
|
18359
19034
|
if (resolvedRuntimeId !== undefined) {
|
|
18360
|
-
const pinned = roleLocalModel(role, resolvedRuntimeId, decision2.selected,
|
|
19035
|
+
const pinned = roleLocalModel(role, resolvedRuntimeId, decision2.selected, configuredRuntime2(resolvedRuntimeId, config));
|
|
18361
19036
|
if (pinned !== decision2.selected) {
|
|
18362
19037
|
return {
|
|
18363
19038
|
runtimeId: resolvedRuntimeId,
|
|
@@ -18365,8 +19040,9 @@ function selectDispatchRuntime(role, decision2, reachable, config) {
|
|
|
18365
19040
|
};
|
|
18366
19041
|
}
|
|
18367
19042
|
}
|
|
19043
|
+
const knownAlias = localModelAliases(decision2.selected.providerID, availableModels2).has(decision2.selected.modelID);
|
|
18368
19044
|
return {
|
|
18369
|
-
runtimeId: resolvedRuntimeId,
|
|
19045
|
+
runtimeId: resolvedRuntimeId ?? (knownAlias ? enabledRuntimeForProvider(decision2.selected.providerID, config) : undefined),
|
|
18370
19046
|
decision: decision2
|
|
18371
19047
|
};
|
|
18372
19048
|
}
|
|
@@ -18553,7 +19229,7 @@ function buildRecord(input, decision2, subsession, deps, decisionID, batchID) {
|
|
|
18553
19229
|
}
|
|
18554
19230
|
return record;
|
|
18555
19231
|
}
|
|
18556
|
-
var TelemetryFailureClassSchema =
|
|
19232
|
+
var TelemetryFailureClassSchema = z29.enum([
|
|
18557
19233
|
"create-rejected",
|
|
18558
19234
|
"create-no-id",
|
|
18559
19235
|
"prompt-rejected",
|
|
@@ -18812,7 +19488,7 @@ async function runRoleTaskWithCorrelation(input, deps, correlation, batch, route
|
|
|
18812
19488
|
if (routed.routeKind === "blocked") {
|
|
18813
19489
|
throw new Error(coordinatorRoutingBlocked(input.roleID, routed.blockReason));
|
|
18814
19490
|
}
|
|
18815
|
-
const selection = selectDispatchRuntime(role, routed, batch.set, input.config);
|
|
19491
|
+
const selection = selectDispatchRuntime(role, routed, batch.set, input.config, input.availableModels);
|
|
18816
19492
|
const decision2 = selection.decision;
|
|
18817
19493
|
const composed = composeSubsessionPrompt({
|
|
18818
19494
|
prompt: input.prompt,
|
|
@@ -18894,8 +19570,9 @@ async function runRoleTaskWithCorrelation(input, deps, correlation, batch, route
|
|
|
18894
19570
|
if (runtimeId !== undefined && deps.runtimeLimiter !== undefined) {
|
|
18895
19571
|
const limiter = deps.runtimeLimiter;
|
|
18896
19572
|
const priority = priorityForRole(role);
|
|
18897
|
-
const dispatchRuntime =
|
|
18898
|
-
const
|
|
19573
|
+
const dispatchRuntime = configuredRuntime2(runtimeId, input.config) ?? { id: runtimeId };
|
|
19574
|
+
const aliases = localModelAliases(decision2.selected.providerID, input.availableModels);
|
|
19575
|
+
const poolKey = slotPoolKey(withReportedModelSlots(dispatchRuntime, deps.reportedModelSlots?.(runtimeId), aliases), aliases.get(decision2.selected.modelID) ?? decision2.selected.modelID);
|
|
18899
19576
|
release = limiter.tryAcquire(poolKey, priority);
|
|
18900
19577
|
let waitedMs = 0;
|
|
18901
19578
|
if (release === undefined) {
|
|
@@ -19369,7 +20046,7 @@ async function runRoleTasks(inputs, deps, options = {}) {
|
|
|
19369
20046
|
var _pluginWarnedRoles = new Set;
|
|
19370
20047
|
var EMPTY_ROLE_ID_SET = new Set;
|
|
19371
20048
|
var SAFE_ROLE_ID = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
19372
|
-
var RoleIDSchema =
|
|
20049
|
+
var RoleIDSchema = z30.string().min(1).superRefine((roleID, ctx) => {
|
|
19373
20050
|
if (!SAFE_ROLE_ID.test(roleID)) {
|
|
19374
20051
|
ctx.addIssue({
|
|
19375
20052
|
code: "custom",
|
|
@@ -19377,16 +20054,16 @@ var RoleIDSchema = z28.string().min(1).superRefine((roleID, ctx) => {
|
|
|
19377
20054
|
});
|
|
19378
20055
|
}
|
|
19379
20056
|
});
|
|
19380
|
-
var RoleAssignmentSchema =
|
|
20057
|
+
var RoleAssignmentSchema = z30.object({
|
|
19381
20058
|
roleID: RoleIDSchema.describe("Role identifier from the roster"),
|
|
19382
|
-
prompt:
|
|
19383
|
-
title:
|
|
19384
|
-
dependsOn:
|
|
20059
|
+
prompt: z30.string().min(1).describe("Work prompt for this role"),
|
|
20060
|
+
title: z30.string().min(1).optional().describe("Human-readable title"),
|
|
20061
|
+
dependsOn: z30.array(RoleIDSchema).optional().describe("Role IDs this assignment depends on (DAG edges)")
|
|
19385
20062
|
}).strict();
|
|
19386
|
-
var OrchestratePayloadSchema =
|
|
19387
|
-
assignments:
|
|
19388
|
-
parentSessionID:
|
|
19389
|
-
directory:
|
|
20063
|
+
var OrchestratePayloadSchema = z30.object({
|
|
20064
|
+
assignments: z30.array(RoleAssignmentSchema).min(1).describe("Role assignments to distribute"),
|
|
20065
|
+
parentSessionID: z30.string().min(1).optional().describe(PARENT_SESSION_DESCRIPTION),
|
|
20066
|
+
directory: z30.string().min(1).optional().describe("Working directory override")
|
|
19390
20067
|
}).strict();
|
|
19391
20068
|
function validateAssignmentDependencies(assignments) {
|
|
19392
20069
|
const ids = new Set;
|
|
@@ -20122,7 +20799,7 @@ ${advisory}`;
|
|
|
20122
20799
|
|
|
20123
20800
|
// src/plugin/registerCastTool.ts
|
|
20124
20801
|
import { tool as tool6 } from "@opencode-ai/plugin";
|
|
20125
|
-
import { z as
|
|
20802
|
+
import { z as z31 } from "zod";
|
|
20126
20803
|
|
|
20127
20804
|
// src/messages/rosterSummary.ts
|
|
20128
20805
|
var ROSTER_SUMMARY_HEADING = "Registered team model policies";
|
|
@@ -20351,13 +21028,13 @@ async function persistPreparedTeam(storage, files) {
|
|
|
20351
21028
|
}
|
|
20352
21029
|
|
|
20353
21030
|
// src/plugin/registerCastTool.ts
|
|
20354
|
-
var CastEntrySchema =
|
|
20355
|
-
roleID:
|
|
20356
|
-
agentName:
|
|
21031
|
+
var CastEntrySchema = z31.object({
|
|
21032
|
+
roleID: z31.string().min(1).describe("Stable role identifier, e.g. scribe or guardian"),
|
|
21033
|
+
agentName: z31.string().min(1).describe("Themed character name assigned to the role")
|
|
20357
21034
|
}).strict();
|
|
20358
|
-
var RegisterCastPayloadSchema =
|
|
20359
|
-
universe:
|
|
20360
|
-
entries:
|
|
21035
|
+
var RegisterCastPayloadSchema = z31.object({
|
|
21036
|
+
universe: z31.string().min(1).describe("Casting universe for this roster"),
|
|
21037
|
+
entries: z31.array(CastEntrySchema).min(1).describe("Role-to-name mappings")
|
|
20361
21038
|
}).strict();
|
|
20362
21039
|
function offendingFields(error) {
|
|
20363
21040
|
const fields = error.issues.flatMap((issue) => {
|
|
@@ -20976,7 +21653,7 @@ async function buildMemoryRuntimeFromConfig(config, deps, options = {}) {
|
|
|
20976
21653
|
if (runtime?.baseURL === undefined) {
|
|
20977
21654
|
return;
|
|
20978
21655
|
}
|
|
20979
|
-
const
|
|
21656
|
+
const modelID2 = semantic.embeddings.model?.modelID ?? runtime.defaultModel.modelID;
|
|
20980
21657
|
const openDatabase = deps.openDatabase ?? createBunSqliteDatabase;
|
|
20981
21658
|
const makeEmbedder = deps.createEmbedder ?? createLocalEmbedder;
|
|
20982
21659
|
const fetchImpl = deps.fetch ?? globalThis.fetch;
|
|
@@ -20989,8 +21666,8 @@ async function buildMemoryRuntimeFromConfig(config, deps, options = {}) {
|
|
|
20989
21666
|
if (rebuildResult.rejectedLines > 0) {
|
|
20990
21667
|
warn(`[openteam] memory log rejected ${rebuildResult.rejectedLines} line(s); semantic memory may be incomplete.`);
|
|
20991
21668
|
}
|
|
20992
|
-
const embedder = makeEmbedder({ baseURL: runtime.baseURL, modelID }, { fetch: fetchImpl });
|
|
20993
|
-
await ensureMemoryEmbeddings({ index, embedder, model:
|
|
21669
|
+
const embedder = makeEmbedder({ baseURL: runtime.baseURL, modelID: modelID2 }, { fetch: fetchImpl });
|
|
21670
|
+
await ensureMemoryEmbeddings({ index, embedder, model: modelID2, warn });
|
|
20994
21671
|
return {
|
|
20995
21672
|
index,
|
|
20996
21673
|
embedder,
|
|
@@ -21018,18 +21695,18 @@ import { join as join15, resolve as resolve11 } from "node:path";
|
|
|
21018
21695
|
import { ZodError } from "zod";
|
|
21019
21696
|
|
|
21020
21697
|
// src/storage/lifecycle/codec.ts
|
|
21021
|
-
import { z as
|
|
21698
|
+
import { z as z32 } from "zod";
|
|
21022
21699
|
var LIFECYCLE_CODEC_VERSION = 1;
|
|
21023
21700
|
var LIFECYCLE_GENESIS_DIGEST = sha256Hex("openteam/lifecycle-journal/genesis/v1");
|
|
21024
21701
|
var NUL5 = "\x00";
|
|
21025
21702
|
var NEWLINE2 = `
|
|
21026
21703
|
`;
|
|
21027
|
-
var frameSchema =
|
|
21028
|
-
v:
|
|
21029
|
-
seq:
|
|
21030
|
-
prev:
|
|
21031
|
-
sum:
|
|
21032
|
-
event:
|
|
21704
|
+
var frameSchema = z32.object({
|
|
21705
|
+
v: z32.literal(LIFECYCLE_CODEC_VERSION),
|
|
21706
|
+
seq: z32.number().int().nonnegative(),
|
|
21707
|
+
prev: z32.string().min(1),
|
|
21708
|
+
sum: z32.string().min(1),
|
|
21709
|
+
event: z32.unknown()
|
|
21033
21710
|
}).strict();
|
|
21034
21711
|
function canonical2(value) {
|
|
21035
21712
|
if (Array.isArray(value)) {
|
|
@@ -21369,8 +22046,8 @@ function readRun(runDir, runID) {
|
|
|
21369
22046
|
if (metadataText === undefined || eventsText === undefined) {
|
|
21370
22047
|
throw new LifecycleFsError("corrupt");
|
|
21371
22048
|
}
|
|
21372
|
-
const
|
|
21373
|
-
if (
|
|
22049
|
+
const metadata2 = parseJson(metadataText, parseLifecycleRunMetadata);
|
|
22050
|
+
if (metadata2.runID !== runID) {
|
|
21374
22051
|
throw new LifecycleFsError("corrupt");
|
|
21375
22052
|
}
|
|
21376
22053
|
let decoded;
|
|
@@ -21385,10 +22062,10 @@ function readRun(runDir, runID) {
|
|
|
21385
22062
|
}
|
|
21386
22063
|
}
|
|
21387
22064
|
const first = decoded.events[0];
|
|
21388
|
-
if (first === undefined || first.type !== "run.started" || first.source !==
|
|
22065
|
+
if (first === undefined || first.type !== "run.started" || first.source !== metadata2.source || first.executionAuthority !== metadata2.executionAuthority || first.root.operationID !== metadata2.root.operationID || first.root.taskID !== metadata2.root.taskID) {
|
|
21389
22066
|
throw new LifecycleFsError("corrupt");
|
|
21390
22067
|
}
|
|
21391
|
-
return { metadata, decoded };
|
|
22068
|
+
return { metadata: metadata2, decoded };
|
|
21392
22069
|
}
|
|
21393
22070
|
function terminalOutcome(events) {
|
|
21394
22071
|
const last = events.at(-1);
|
|
@@ -21466,7 +22143,7 @@ var createFsLifecycleJournal = (options) => {
|
|
|
21466
22143
|
mkdirSync3(stagingPath);
|
|
21467
22144
|
const writerToken = issueWriterToken();
|
|
21468
22145
|
const eventAt = now();
|
|
21469
|
-
const
|
|
22146
|
+
const metadata2 = parseLifecycleRunMetadata({
|
|
21470
22147
|
...parsedInput,
|
|
21471
22148
|
version: 1,
|
|
21472
22149
|
createdAt: eventAt
|
|
@@ -21482,7 +22159,7 @@ var createFsLifecycleJournal = (options) => {
|
|
|
21482
22159
|
executionAuthority: parsedInput.executionAuthority,
|
|
21483
22160
|
root: parsedInput.root
|
|
21484
22161
|
});
|
|
21485
|
-
writeDurable2(join15(stagingPath, METADATA_FILE), `${JSON.stringify(
|
|
22162
|
+
writeDurable2(join15(stagingPath, METADATA_FILE), `${JSON.stringify(metadata2)}
|
|
21486
22163
|
`);
|
|
21487
22164
|
writeDurable2(join15(stagingPath, EVENTS_FILE), encodeLifecycleJournal([event]));
|
|
21488
22165
|
writeDurable2(join15(stagingPath, OWNER_FILE2), `${JSON.stringify(lease)}
|
|
@@ -21498,7 +22175,7 @@ var createFsLifecycleJournal = (options) => {
|
|
|
21498
22175
|
stagingPath = undefined;
|
|
21499
22176
|
return ok({
|
|
21500
22177
|
handle: { runID, writerToken },
|
|
21501
|
-
metadata,
|
|
22178
|
+
metadata: metadata2,
|
|
21502
22179
|
event,
|
|
21503
22180
|
lease,
|
|
21504
22181
|
head: 1
|
|
@@ -22359,6 +23036,9 @@ async function listConfiguredOpencodeInventory(ctx) {
|
|
|
22359
23036
|
providerID: model.providerID,
|
|
22360
23037
|
modelID: model.id
|
|
22361
23038
|
};
|
|
23039
|
+
if (typeof model.api?.id === "string" && model.api.id.length > 0 && model.api.id === model.api.id.trim() && model.api.id !== model.id) {
|
|
23040
|
+
configuredModel.apiModelID = model.api.id;
|
|
23041
|
+
}
|
|
22362
23042
|
if (typeof model.capabilities?.toolcall === "boolean") {
|
|
22363
23043
|
configuredModel.supportsTools = model.capabilities.toolcall;
|
|
22364
23044
|
}
|
|
@@ -22428,12 +23108,20 @@ var server = async (ctx, rawOptions) => {
|
|
|
22428
23108
|
const injectMemory = await buildMemoryInjectorFromConfig(config, storage, diagnostics.warn("memory-runtime-warning", { toast: false }));
|
|
22429
23109
|
const sessionTracker = createSessionTracker();
|
|
22430
23110
|
const orchestratedModelOwnership = createOrchestratedModelOwnership();
|
|
23111
|
+
const modelResidency = createModelResidencyGuard(config, {
|
|
23112
|
+
fetch: globalThis.fetch,
|
|
23113
|
+
...ctx.client.config?.providers === undefined ? {} : {
|
|
23114
|
+
resolveApiModelID: cache.resolveApiModelID,
|
|
23115
|
+
modelInventoryReady: ensureAvailability
|
|
23116
|
+
}
|
|
23117
|
+
});
|
|
22431
23118
|
const resolveAgentRole = async (agentName) => {
|
|
22432
23119
|
const entry = (await readRoutingRosterEntries(storage)).find((candidate) => candidate.agentName === agentName);
|
|
22433
23120
|
return entry?.roleID;
|
|
22434
23121
|
};
|
|
22435
23122
|
const hooks = createHooks(config, cache.get, injectMemory === undefined ? {
|
|
22436
23123
|
sink,
|
|
23124
|
+
modelResidency,
|
|
22437
23125
|
beforeRoute: ensureAvailability,
|
|
22438
23126
|
capabilityProfiles,
|
|
22439
23127
|
orchestratedModelOwnership,
|
|
@@ -22441,6 +23129,7 @@ var server = async (ctx, rawOptions) => {
|
|
|
22441
23129
|
onRoute: (sid, model) => sessionTracker.trackRoutedModel(sid, model)
|
|
22442
23130
|
} : {
|
|
22443
23131
|
sink,
|
|
23132
|
+
modelResidency,
|
|
22444
23133
|
beforeRoute: ensureAvailability,
|
|
22445
23134
|
capabilityProfiles,
|
|
22446
23135
|
injectMemory,
|
|
@@ -22561,7 +23250,7 @@ var server = async (ctx, rawOptions) => {
|
|
|
22561
23250
|
if (runtime === undefined) {
|
|
22562
23251
|
return;
|
|
22563
23252
|
}
|
|
22564
|
-
return withReportedModelSlots(runtime, reportedSlotsByRuntime.get(runtimeId));
|
|
23253
|
+
return withReportedModelSlots(runtime, reportedSlotsByRuntime.get(runtimeId), localModelAliases(runtime.defaultModel.providerID, cache.get()));
|
|
22565
23254
|
};
|
|
22566
23255
|
const runtimeLimiter = createRuntimeConcurrencyLimiter({
|
|
22567
23256
|
capacityFor: (key2) => {
|
|
@@ -22606,7 +23295,27 @@ var server = async (ctx, rawOptions) => {
|
|
|
22606
23295
|
config,
|
|
22607
23296
|
storage,
|
|
22608
23297
|
now,
|
|
22609
|
-
localRuntimeReachable,
|
|
23298
|
+
localRuntimeReachable: async (runtime, signal) => {
|
|
23299
|
+
if (localRuntimeKind(runtime) === "lemonade") {
|
|
23300
|
+
if (ctx.client.config?.providers !== undefined)
|
|
23301
|
+
await ensureAvailability();
|
|
23302
|
+
signal?.throwIfAborted();
|
|
23303
|
+
const target = modelResidency.localTarget(resolveMemorySemantic(config).extraction.model ?? runtime.defaultModel);
|
|
23304
|
+
const response = await target.fetch(`${target.baseURL}/health`, {
|
|
23305
|
+
method: "GET",
|
|
23306
|
+
...signal === undefined ? {} : { signal }
|
|
23307
|
+
});
|
|
23308
|
+
return response.ok;
|
|
23309
|
+
}
|
|
23310
|
+
const snapshots = await registry.probe([runtime]);
|
|
23311
|
+
rememberReportedSlots(snapshots);
|
|
23312
|
+
return anyRuntimeReachable(snapshots);
|
|
23313
|
+
},
|
|
23314
|
+
resolveExtractionTarget: async (model) => {
|
|
23315
|
+
if (ctx.client.config?.providers !== undefined)
|
|
23316
|
+
await ensureAvailability();
|
|
23317
|
+
return modelResidency.localTarget(model);
|
|
23318
|
+
},
|
|
22610
23319
|
fetch: globalThis.fetch,
|
|
22611
23320
|
warn: diagnostics.warn("memory-extraction-warning", { toast: false })
|
|
22612
23321
|
});
|