@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/cli.js
CHANGED
|
@@ -3356,6 +3356,25 @@ var executionSetupMessages = {
|
|
|
3356
3356
|
`),
|
|
3357
3357
|
localOnlyTitle: "Local execution",
|
|
3358
3358
|
localRequiredError: "local execution requires an enabled local runtime",
|
|
3359
|
+
lemonadeDetectedHint: (loaded, advertised) => `detected - ${loaded} confirmed loaded of ${advertised} advertised text model(s)`,
|
|
3360
|
+
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.",
|
|
3361
|
+
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.`,
|
|
3362
|
+
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.",
|
|
3363
|
+
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.",
|
|
3364
|
+
lemonadeEndpointMismatch: "Lemonade endpoint/provider mapping differs from the selected runtime. Reconcile the configured base URL and provider before rerunning setup; no model was substituted.",
|
|
3365
|
+
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.`,
|
|
3366
|
+
lemonadeEffectiveConfigLabel: "effective setup configuration",
|
|
3367
|
+
lemonadeEffectiveConfigAmbiguous: "Cannot establish one effective openteam configuration from the configured plugin loaders. Reconcile their options before rerunning setup; no provider identity was guessed.",
|
|
3368
|
+
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.`,
|
|
3369
|
+
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.`,
|
|
3370
|
+
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.",
|
|
3371
|
+
lemonadeV2Title: "Lemonade transport compatibility",
|
|
3372
|
+
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.`,
|
|
3373
|
+
lemonadeInventory: (instanceID, providerID, models) => {
|
|
3374
|
+
const inventory = models.map((model) => `${model.modelID} (${model.loaded === true ? "loaded" : model.loaded === false ? "inactive" : "residency unknown"})`).join(", ");
|
|
3375
|
+
return `Lemonade inventory ${instanceID} (provider ${providerID}): ${inventory || "no advertised text models"}. Only confirmed loaded text models count as ready.`;
|
|
3376
|
+
},
|
|
3377
|
+
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.`,
|
|
3359
3378
|
mixedPrimaryQuestion: "Primary coordinator model",
|
|
3360
3379
|
mixedPrimaryLocal: (model) => `Use local thinking model ${model}`,
|
|
3361
3380
|
mixedPrimaryFrontier: "Choose a frontier model",
|
|
@@ -9248,7 +9267,7 @@ function parseOpencodeProviders(opencodeConfig) {
|
|
|
9248
9267
|
function localRuntimeStates(config) {
|
|
9249
9268
|
const map = new Map;
|
|
9250
9269
|
for (const runtime of config.local.runtimes) {
|
|
9251
|
-
map.set(runtime.
|
|
9270
|
+
map.set(runtime.defaultModel.providerID, { enabled: runtime.enabled });
|
|
9252
9271
|
}
|
|
9253
9272
|
return map;
|
|
9254
9273
|
}
|
|
@@ -9256,7 +9275,7 @@ function disabledLocalProviderIDs(config) {
|
|
|
9256
9275
|
const ids = new Set;
|
|
9257
9276
|
for (const runtime of config.local.runtimes) {
|
|
9258
9277
|
if (!runtime.enabled) {
|
|
9259
|
-
ids.add(runtime.
|
|
9278
|
+
ids.add(runtime.defaultModel.providerID);
|
|
9260
9279
|
}
|
|
9261
9280
|
}
|
|
9262
9281
|
return ids;
|
|
@@ -9272,7 +9291,11 @@ function computeLive(model, isLocalProvider, liveModels) {
|
|
|
9272
9291
|
if (!snapshot.reachable) {
|
|
9273
9292
|
return "unreachable";
|
|
9274
9293
|
}
|
|
9275
|
-
|
|
9294
|
+
if (snapshot.modelIDs.has(model.modelID))
|
|
9295
|
+
return "confirmed";
|
|
9296
|
+
if (snapshot.residency?.has(model.modelID))
|
|
9297
|
+
return snapshot.residency.get(model.modelID) === false ? "not-loaded" : "residency-unknown";
|
|
9298
|
+
return "not-advertised";
|
|
9276
9299
|
}
|
|
9277
9300
|
function resolveAgentModel(model, context) {
|
|
9278
9301
|
const isLocalProvider = KNOWN_LOCAL_PROVIDER_IDS.has(model.providerID) || context.localRuntimes.has(model.providerID);
|
|
@@ -16012,6 +16035,243 @@ function ensureFoundryV1BaseURL(endpoint) {
|
|
|
16012
16035
|
}
|
|
16013
16036
|
}
|
|
16014
16037
|
|
|
16038
|
+
// src/local/lemonadeResidency.ts
|
|
16039
|
+
import { z as z22 } from "zod";
|
|
16040
|
+
|
|
16041
|
+
// src/messages/modelResidency.ts
|
|
16042
|
+
var reasons = {
|
|
16043
|
+
unknown: "fresh residency metadata is unavailable, malformed, or ambiguous",
|
|
16044
|
+
inactive: "the requested model is not verified as resident and serving",
|
|
16045
|
+
identity: "the requested model identity can be rewritten or is ambiguous",
|
|
16046
|
+
destination: "the request destination does not match its configured runtime",
|
|
16047
|
+
transport: "this provider execution path cannot enforce the residency guard",
|
|
16048
|
+
request: "this is not a supported, explicit model inference request",
|
|
16049
|
+
cancelled: "the request was cancelled before residency could be verified",
|
|
16050
|
+
timeout: "the residency metadata deadline expired",
|
|
16051
|
+
configuration: "the residency guard configuration is invalid"
|
|
16052
|
+
};
|
|
16053
|
+
var modelResidencyMessages = {
|
|
16054
|
+
blocked: (reason) => `[openteam] Lemonade model request blocked: ${reasons[reason]}.`,
|
|
16055
|
+
providerDisabled: (providerID) => `[openteam] Lemonade provider "${providerID}" is disabled because its configured transport or runtime mapping cannot enforce loaded-only requests.`,
|
|
16056
|
+
extractionRuntimeUnavailable: "[openteam] Memory extraction requires one enabled local runtime matching the configured extraction provider."
|
|
16057
|
+
};
|
|
16058
|
+
|
|
16059
|
+
// src/local/lemonadeResidency.ts
|
|
16060
|
+
class ModelResidencyError extends Error {
|
|
16061
|
+
code;
|
|
16062
|
+
statusCode = 400;
|
|
16063
|
+
isRetryable = false;
|
|
16064
|
+
constructor(code) {
|
|
16065
|
+
super(modelResidencyMessages.blocked(code));
|
|
16066
|
+
this.code = code;
|
|
16067
|
+
this.name = "ModelResidencyError";
|
|
16068
|
+
}
|
|
16069
|
+
}
|
|
16070
|
+
var modelName = z22.string().min(1).refine((name) => name === name.trim());
|
|
16071
|
+
var LoadedModelSchema = z22.object({
|
|
16072
|
+
model_name: modelName,
|
|
16073
|
+
loaded: z22.boolean().optional(),
|
|
16074
|
+
status: z22.string().optional(),
|
|
16075
|
+
backend_alive: z22.boolean().optional(),
|
|
16076
|
+
backend_health: z22.string().optional(),
|
|
16077
|
+
watchdog_reset: z22.boolean().optional(),
|
|
16078
|
+
watchdog_reset_reason: z22.string().optional(),
|
|
16079
|
+
residency_class: z22.string().optional(),
|
|
16080
|
+
slot_pool: z22.string().optional(),
|
|
16081
|
+
checkpoint: z22.string().optional(),
|
|
16082
|
+
type: z22.string().optional(),
|
|
16083
|
+
device: z22.string().optional(),
|
|
16084
|
+
backend_url: z22.string().optional(),
|
|
16085
|
+
pid: z22.number().int().optional(),
|
|
16086
|
+
launch_command: z22.unknown().optional(),
|
|
16087
|
+
pinned: z22.boolean().optional(),
|
|
16088
|
+
recipe: z22.string().optional(),
|
|
16089
|
+
recipe_options: z22.unknown().optional(),
|
|
16090
|
+
is_busy: z22.boolean().optional(),
|
|
16091
|
+
is_streaming: z22.boolean().optional(),
|
|
16092
|
+
max_context_window: z22.number().optional(),
|
|
16093
|
+
cost_input_per_million: z22.number().optional(),
|
|
16094
|
+
cost_output_per_million: z22.number().optional(),
|
|
16095
|
+
last_use: z22.number().optional()
|
|
16096
|
+
}).strict();
|
|
16097
|
+
var TelemetrySchema = z22.object({
|
|
16098
|
+
enabled: z22.boolean(),
|
|
16099
|
+
captures: z22.array(z22.string()).optional()
|
|
16100
|
+
}).strict();
|
|
16101
|
+
var HealthSchema = z22.object({
|
|
16102
|
+
status: z22.literal("ok"),
|
|
16103
|
+
all_models_loaded: z22.array(LoadedModelSchema),
|
|
16104
|
+
version: z22.string().optional(),
|
|
16105
|
+
model_loaded: z22.string().nullable().optional(),
|
|
16106
|
+
telemetry: TelemetrySchema.optional(),
|
|
16107
|
+
max_models: z22.record(z22.string(), z22.number().int()).optional(),
|
|
16108
|
+
pinned_models: z22.record(z22.string(), z22.number().int()).optional(),
|
|
16109
|
+
pinned_helper_models: z22.record(z22.string(), z22.number().int()).optional(),
|
|
16110
|
+
websocket_port: z22.number().int().optional(),
|
|
16111
|
+
update_check_done: z22.boolean().optional()
|
|
16112
|
+
}).strict();
|
|
16113
|
+
var AliasSchema = z22.object({
|
|
16114
|
+
alias: modelName,
|
|
16115
|
+
target: modelName,
|
|
16116
|
+
downloaded: z22.boolean().optional(),
|
|
16117
|
+
recipe: z22.string().optional()
|
|
16118
|
+
}).strict();
|
|
16119
|
+
var AliasesSchema = z22.object({
|
|
16120
|
+
aliases: z22.array(AliasSchema)
|
|
16121
|
+
}).strict();
|
|
16122
|
+
var MetadataRecordSchema = z22.record(z22.string(), z22.unknown());
|
|
16123
|
+
var inactiveStates = new Set([
|
|
16124
|
+
"loading",
|
|
16125
|
+
"downsizing",
|
|
16126
|
+
"downsized",
|
|
16127
|
+
"evicting",
|
|
16128
|
+
"unloaded"
|
|
16129
|
+
]);
|
|
16130
|
+
var inactiveHealth = new Set(["stopped", "exited", "watchdog_reset"]);
|
|
16131
|
+
var standardPools = new Set([
|
|
16132
|
+
"standard/llm",
|
|
16133
|
+
"standard/embedding",
|
|
16134
|
+
"standard/reranking",
|
|
16135
|
+
"standard/transcription",
|
|
16136
|
+
"standard/image",
|
|
16137
|
+
"standard/tts",
|
|
16138
|
+
"standard/audio-generation",
|
|
16139
|
+
"standard/classification",
|
|
16140
|
+
"standard/mesh"
|
|
16141
|
+
]);
|
|
16142
|
+
function usableState(entry) {
|
|
16143
|
+
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/")) {
|
|
16144
|
+
return false;
|
|
16145
|
+
}
|
|
16146
|
+
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))) {
|
|
16147
|
+
return;
|
|
16148
|
+
}
|
|
16149
|
+
return true;
|
|
16150
|
+
}
|
|
16151
|
+
function projectMetadataObject(payload, keys) {
|
|
16152
|
+
const record2 = MetadataRecordSchema.safeParse(payload);
|
|
16153
|
+
if (!record2.success)
|
|
16154
|
+
throw new ModelResidencyError("unknown");
|
|
16155
|
+
return Object.fromEntries(keys.filter((key) => Object.hasOwn(record2.data, key)).map((key) => [key, record2.data[key]]));
|
|
16156
|
+
}
|
|
16157
|
+
function parseResidency(healthPayload, aliasPayload) {
|
|
16158
|
+
const healthFields = projectMetadataObject(healthPayload, Object.keys(HealthSchema.shape));
|
|
16159
|
+
if (Array.isArray(healthFields.all_models_loaded)) {
|
|
16160
|
+
healthFields.all_models_loaded = healthFields.all_models_loaded.map((entry) => projectMetadataObject(entry, Object.keys(LoadedModelSchema.shape)));
|
|
16161
|
+
}
|
|
16162
|
+
if (healthFields.telemetry !== undefined) {
|
|
16163
|
+
healthFields.telemetry = projectMetadataObject(healthFields.telemetry, Object.keys(TelemetrySchema.shape));
|
|
16164
|
+
}
|
|
16165
|
+
const aliasFields = projectMetadataObject(aliasPayload, Object.keys(AliasesSchema.shape));
|
|
16166
|
+
if (Array.isArray(aliasFields.aliases)) {
|
|
16167
|
+
aliasFields.aliases = aliasFields.aliases.map((entry) => projectMetadataObject(entry, Object.keys(AliasSchema.shape)));
|
|
16168
|
+
}
|
|
16169
|
+
const health = HealthSchema.safeParse(healthFields);
|
|
16170
|
+
const aliases = AliasesSchema.safeParse(aliasFields);
|
|
16171
|
+
if (!health.success || !aliases.success)
|
|
16172
|
+
throw new ModelResidencyError("unknown");
|
|
16173
|
+
const result = new Map;
|
|
16174
|
+
for (const entry of health.data.all_models_loaded) {
|
|
16175
|
+
if (result.has(entry.model_name))
|
|
16176
|
+
throw new ModelResidencyError("unknown");
|
|
16177
|
+
result.set(entry.model_name, {
|
|
16178
|
+
loaded: entry.model_name.endsWith(":latest") ? undefined : usableState(entry),
|
|
16179
|
+
metadata: entry
|
|
16180
|
+
});
|
|
16181
|
+
}
|
|
16182
|
+
const seenAliases = new Set;
|
|
16183
|
+
for (const entry of aliases.data.aliases) {
|
|
16184
|
+
if (seenAliases.has(entry.alias))
|
|
16185
|
+
throw new ModelResidencyError("unknown");
|
|
16186
|
+
seenAliases.add(entry.alias);
|
|
16187
|
+
result.set(entry.alias, {
|
|
16188
|
+
loaded: undefined,
|
|
16189
|
+
metadata: result.get(entry.alias)?.metadata ?? {}
|
|
16190
|
+
});
|
|
16191
|
+
}
|
|
16192
|
+
return result;
|
|
16193
|
+
}
|
|
16194
|
+
function lemonadeBaseURL(value) {
|
|
16195
|
+
let url;
|
|
16196
|
+
try {
|
|
16197
|
+
url = new URL(value);
|
|
16198
|
+
} catch {
|
|
16199
|
+
throw new ModelResidencyError("destination");
|
|
16200
|
+
}
|
|
16201
|
+
if (url.protocol !== "http:" && url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "" || !/^\/(?:api\/)?v[01]\/?$/.test(url.pathname)) {
|
|
16202
|
+
throw new ModelResidencyError("destination");
|
|
16203
|
+
}
|
|
16204
|
+
return `${url.origin}${url.pathname.replace(/\/$/, "")}`;
|
|
16205
|
+
}
|
|
16206
|
+
async function withResidencyDeadline(operation, options) {
|
|
16207
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
16208
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
16209
|
+
throw new ModelResidencyError("configuration");
|
|
16210
|
+
}
|
|
16211
|
+
const controller = new AbortController;
|
|
16212
|
+
const cancel = () => controller.abort(new ModelResidencyError("cancelled"));
|
|
16213
|
+
if (options.signal?.aborted)
|
|
16214
|
+
throw new ModelResidencyError("cancelled");
|
|
16215
|
+
options.signal?.addEventListener("abort", cancel, { once: true });
|
|
16216
|
+
const schedule = options.scheduleTimeout ?? ((callback, ms2) => {
|
|
16217
|
+
const timer = setTimeout(callback, ms2);
|
|
16218
|
+
return () => clearTimeout(timer);
|
|
16219
|
+
});
|
|
16220
|
+
let onAbort = () => {};
|
|
16221
|
+
const aborted = new Promise((_, reject) => {
|
|
16222
|
+
onAbort = () => reject(controller.signal.reason);
|
|
16223
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
16224
|
+
});
|
|
16225
|
+
const clearTimer = schedule(() => controller.abort(new ModelResidencyError("timeout")), timeoutMs);
|
|
16226
|
+
try {
|
|
16227
|
+
controller.signal.throwIfAborted();
|
|
16228
|
+
return await Promise.race([operation(controller.signal), aborted]);
|
|
16229
|
+
} finally {
|
|
16230
|
+
clearTimer();
|
|
16231
|
+
options.signal?.removeEventListener("abort", cancel);
|
|
16232
|
+
controller.signal.removeEventListener("abort", onAbort);
|
|
16233
|
+
controller.abort();
|
|
16234
|
+
}
|
|
16235
|
+
}
|
|
16236
|
+
async function metadata(url, fetch2, signal, headers) {
|
|
16237
|
+
signal.throwIfAborted();
|
|
16238
|
+
let payload;
|
|
16239
|
+
try {
|
|
16240
|
+
const response = await fetch2(url, {
|
|
16241
|
+
method: "GET",
|
|
16242
|
+
headers,
|
|
16243
|
+
signal,
|
|
16244
|
+
redirect: "error",
|
|
16245
|
+
cache: "no-store"
|
|
16246
|
+
});
|
|
16247
|
+
signal.throwIfAborted();
|
|
16248
|
+
if (!response.ok || response.redirected || response.url !== "" && response.url !== url) {
|
|
16249
|
+
throw new ModelResidencyError("unknown");
|
|
16250
|
+
}
|
|
16251
|
+
payload = await response.json();
|
|
16252
|
+
} catch {
|
|
16253
|
+
signal.throwIfAborted();
|
|
16254
|
+
throw new ModelResidencyError("unknown");
|
|
16255
|
+
}
|
|
16256
|
+
signal.throwIfAborted();
|
|
16257
|
+
return payload;
|
|
16258
|
+
}
|
|
16259
|
+
async function readLemonadeResidency(baseURL, fetch2, options = {}) {
|
|
16260
|
+
const base = lemonadeBaseURL(baseURL);
|
|
16261
|
+
const headers = new Headers(options.headers);
|
|
16262
|
+
headers.delete("content-type");
|
|
16263
|
+
headers.delete("content-length");
|
|
16264
|
+
headers.set("accept", "application/json");
|
|
16265
|
+
headers.set("cache-control", "no-cache, no-store");
|
|
16266
|
+
headers.delete("if-none-match");
|
|
16267
|
+
headers.delete("if-modified-since");
|
|
16268
|
+
return withResidencyDeadline(async (signal) => {
|
|
16269
|
+
const aliases = await metadata(`${new URL(base).origin}/internal/aliases`, fetch2, signal, headers);
|
|
16270
|
+
const health = await metadata(`${base}/health`, fetch2, signal, headers);
|
|
16271
|
+
return parseResidency(health, aliases);
|
|
16272
|
+
}, options);
|
|
16273
|
+
}
|
|
16274
|
+
|
|
16015
16275
|
// src/local/lemonade.ts
|
|
16016
16276
|
var LEMONADE_DEFAULT_BASE_URL = "http://localhost:13305/api/v1";
|
|
16017
16277
|
var NON_TEXT_LABELS = new Set([
|
|
@@ -16098,36 +16358,19 @@ function isNonTextModel(entry) {
|
|
|
16098
16358
|
return entry.labels.some((label) => typeof label === "string" && NON_TEXT_LABELS.has(label));
|
|
16099
16359
|
}
|
|
16100
16360
|
async function readLoadedModels(baseURL, fetch2) {
|
|
16101
|
-
let payload;
|
|
16102
16361
|
try {
|
|
16103
|
-
const
|
|
16104
|
-
|
|
16105
|
-
|
|
16106
|
-
|
|
16107
|
-
|
|
16108
|
-
|
|
16109
|
-
|
|
16110
|
-
|
|
16362
|
+
const residency = await readLemonadeResidency(baseURL, fetch2);
|
|
16363
|
+
return new Map([...residency].map(([name, entry]) => [
|
|
16364
|
+
name,
|
|
16365
|
+
{
|
|
16366
|
+
loaded: entry.loaded,
|
|
16367
|
+
slots: entry.loaded === true ? readSlotCount(entry.metadata) : undefined,
|
|
16368
|
+
totalContextWindow: entry.loaded === true ? readLoadedContextWindow(entry.metadata) : undefined
|
|
16369
|
+
}
|
|
16370
|
+
]));
|
|
16111
16371
|
} catch {
|
|
16112
16372
|
return;
|
|
16113
16373
|
}
|
|
16114
|
-
if (!isObject2(payload) || !Array.isArray(payload.all_models_loaded)) {
|
|
16115
|
-
return;
|
|
16116
|
-
}
|
|
16117
|
-
const loaded = new Map;
|
|
16118
|
-
for (const entry of payload.all_models_loaded) {
|
|
16119
|
-
if (!isObject2(entry) || typeof entry.model_name !== "string") {
|
|
16120
|
-
continue;
|
|
16121
|
-
}
|
|
16122
|
-
if (entry.loaded === false) {
|
|
16123
|
-
continue;
|
|
16124
|
-
}
|
|
16125
|
-
loaded.set(entry.model_name, {
|
|
16126
|
-
slots: readSlotCount(entry),
|
|
16127
|
-
totalContextWindow: readLoadedContextWindow(entry)
|
|
16128
|
-
});
|
|
16129
|
-
}
|
|
16130
|
-
return loaded;
|
|
16131
16374
|
}
|
|
16132
16375
|
function readSlotCount(entry) {
|
|
16133
16376
|
return slotsFromLlamacppArgs(entry) ?? slotsFromLaunchCommand(entry);
|
|
@@ -16274,6 +16517,9 @@ function enrichWithLoadState(models, loaded) {
|
|
|
16274
16517
|
if (hit === undefined) {
|
|
16275
16518
|
return { ...base, loaded: false };
|
|
16276
16519
|
}
|
|
16520
|
+
if (hit.loaded !== true) {
|
|
16521
|
+
return hit.loaded === false ? { ...base, loaded: false } : base;
|
|
16522
|
+
}
|
|
16277
16523
|
const contextWindow = derivedConservativeContextWindow(model.contextWindow, hit);
|
|
16278
16524
|
return {
|
|
16279
16525
|
...base,
|
|
@@ -16290,6 +16536,11 @@ function isObject2(value) {
|
|
|
16290
16536
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16291
16537
|
}
|
|
16292
16538
|
|
|
16539
|
+
// src/local/modelResidency.ts
|
|
16540
|
+
function hasRequiredModelResidency(kind, model) {
|
|
16541
|
+
return kind !== "lemonade" || model?.loaded === true;
|
|
16542
|
+
}
|
|
16543
|
+
|
|
16293
16544
|
// src/local/lmstudio.ts
|
|
16294
16545
|
var LMSTUDIO_DEFAULT_BASE_URL = "http://localhost:1234/v1";
|
|
16295
16546
|
function createLMStudioAdapter() {
|
|
@@ -16507,50 +16758,36 @@ function createDetect(exec) {
|
|
|
16507
16758
|
foundryDiscovery: foundryDiscoveryFromExec(exec)
|
|
16508
16759
|
});
|
|
16509
16760
|
const snapshots = await registry.probe(DETECTION_RUNTIMES);
|
|
16510
|
-
return
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16522
|
-
}
|
|
16523
|
-
return detected;
|
|
16524
|
-
});
|
|
16761
|
+
return DETECTION_RUNTIMES.map((runtime) => detectedRuntime(runtime, snapshots.find((snapshot) => snapshot.id === runtime.id)));
|
|
16762
|
+
};
|
|
16763
|
+
}
|
|
16764
|
+
function detectedRuntime(runtime, snapshot) {
|
|
16765
|
+
const modelInfo = snapshot?.models ?? [];
|
|
16766
|
+
return {
|
|
16767
|
+
id: runtime.id,
|
|
16768
|
+
baseURL: snapshot?.baseURL ?? runtime.baseURL ?? "",
|
|
16769
|
+
reachable: snapshot?.reachable ?? false,
|
|
16770
|
+
models: modelInfo.filter((model) => hasRequiredModelResidency(localRuntimeKind(runtime), model)).map((model) => model.modelID),
|
|
16771
|
+
modelInfo,
|
|
16772
|
+
...snapshot?.error === undefined ? {} : { error: snapshot.error }
|
|
16525
16773
|
};
|
|
16526
16774
|
}
|
|
16527
16775
|
function createProbeRuntime(exec) {
|
|
16528
|
-
return async (
|
|
16776
|
+
return async (kind, baseURL) => {
|
|
16529
16777
|
const registry = new RuntimeRegistry({
|
|
16530
16778
|
fetch: globalThis.fetch,
|
|
16531
16779
|
clock: () => new Date().toISOString(),
|
|
16532
16780
|
foundryDiscovery: foundryDiscoveryFromExec(exec)
|
|
16533
16781
|
});
|
|
16534
16782
|
const runtime = {
|
|
16535
|
-
id,
|
|
16783
|
+
id: kind,
|
|
16784
|
+
kind,
|
|
16536
16785
|
enabled: true,
|
|
16537
16786
|
baseURL,
|
|
16538
|
-
defaultModel: { providerID:
|
|
16787
|
+
defaultModel: { providerID: kind, modelID: "probe" }
|
|
16539
16788
|
};
|
|
16540
16789
|
const [snapshot] = await registry.probe([runtime]);
|
|
16541
|
-
|
|
16542
|
-
id,
|
|
16543
|
-
baseURL: snapshot?.baseURL ?? baseURL,
|
|
16544
|
-
reachable: snapshot?.reachable ?? false,
|
|
16545
|
-
models: snapshot?.models.map((model) => model.modelID) ?? []
|
|
16546
|
-
};
|
|
16547
|
-
if (snapshot?.models.some((model) => model.loaded !== undefined) === true) {
|
|
16548
|
-
detected.modelInfo = snapshot.models;
|
|
16549
|
-
}
|
|
16550
|
-
if (snapshot?.error !== undefined) {
|
|
16551
|
-
detected.error = snapshot.error;
|
|
16552
|
-
}
|
|
16553
|
-
return detected;
|
|
16790
|
+
return detectedRuntime(runtime, snapshot);
|
|
16554
16791
|
};
|
|
16555
16792
|
}
|
|
16556
16793
|
|
|
@@ -16663,11 +16900,11 @@ function planWorktreeReconciliation(input) {
|
|
|
16663
16900
|
}
|
|
16664
16901
|
|
|
16665
16902
|
// src/telemetry/otelConfig.ts
|
|
16666
|
-
import { z as
|
|
16667
|
-
var OtelBackendConfigSchema =
|
|
16668
|
-
backend:
|
|
16669
|
-
connectionEnv:
|
|
16670
|
-
serviceName:
|
|
16903
|
+
import { z as z23 } from "zod";
|
|
16904
|
+
var OtelBackendConfigSchema = z23.object({
|
|
16905
|
+
backend: z23.literal("opentelemetry"),
|
|
16906
|
+
connectionEnv: z23.string().min(1),
|
|
16907
|
+
serviceName: z23.string().min(1).optional()
|
|
16671
16908
|
}).strict();
|
|
16672
16909
|
function parseConnectionString(raw) {
|
|
16673
16910
|
const pairs = new Map;
|
|
@@ -17809,7 +18046,7 @@ import { posix as pathPosix, win32 as pathWin32 } from "node:path";
|
|
|
17809
18046
|
// package.json
|
|
17810
18047
|
var package_default = {
|
|
17811
18048
|
name: "@jmanuelcorral/openteam",
|
|
17812
|
-
version: "0.24.
|
|
18049
|
+
version: "0.24.1",
|
|
17813
18050
|
packageManager: "bun@1.3.14",
|
|
17814
18051
|
description: "Cost-aware, local-first routing plugin for opencode with cheapest-capable frontier fallback and multi-agent orchestration.",
|
|
17815
18052
|
license: "MIT",
|
|
@@ -17953,31 +18190,31 @@ function compareSemver(a, b) {
|
|
|
17953
18190
|
}
|
|
17954
18191
|
|
|
17955
18192
|
// src/graph/soakLedger.ts
|
|
17956
|
-
import { z as
|
|
17957
|
-
var Sha256Schema2 =
|
|
17958
|
-
var SoakPlatformSchema =
|
|
17959
|
-
var PrivacyPairSchema =
|
|
17960
|
-
surfacesScanned:
|
|
17961
|
-
rawFindings:
|
|
18193
|
+
import { z as z24 } from "zod";
|
|
18194
|
+
var Sha256Schema2 = z24.string().regex(/^[0-9a-f]{64}$/);
|
|
18195
|
+
var SoakPlatformSchema = z24.enum(["linux", "win32", "darwin"]);
|
|
18196
|
+
var PrivacyPairSchema = z24.object({
|
|
18197
|
+
surfacesScanned: z24.number().int().nonnegative(),
|
|
18198
|
+
rawFindings: z24.number().int().nonnegative()
|
|
17962
18199
|
}).strict();
|
|
17963
|
-
var DuplicateEffectPairSchema =
|
|
17964
|
-
effectsExamined:
|
|
17965
|
-
duplicatesFound:
|
|
18200
|
+
var DuplicateEffectPairSchema = z24.object({
|
|
18201
|
+
effectsExamined: z24.number().int().nonnegative(),
|
|
18202
|
+
duplicatesFound: z24.number().int().nonnegative()
|
|
17966
18203
|
}).strict();
|
|
17967
|
-
var ModelVerificationPairSchema =
|
|
17968
|
-
nodesChecked:
|
|
17969
|
-
unverified:
|
|
17970
|
-
mismatched:
|
|
18204
|
+
var ModelVerificationPairSchema = z24.object({
|
|
18205
|
+
nodesChecked: z24.number().int().nonnegative(),
|
|
18206
|
+
unverified: z24.number().int().nonnegative(),
|
|
18207
|
+
mismatched: z24.number().int().nonnegative()
|
|
17971
18208
|
}).strict();
|
|
17972
|
-
var SoakObservationSchema =
|
|
17973
|
-
version:
|
|
17974
|
-
seq:
|
|
17975
|
-
timestamp:
|
|
18209
|
+
var SoakObservationSchema = z24.object({
|
|
18210
|
+
version: z24.literal(1),
|
|
18211
|
+
seq: z24.number().int().nonnegative(),
|
|
18212
|
+
timestamp: z24.string().datetime(),
|
|
17976
18213
|
platform: SoakPlatformSchema,
|
|
17977
|
-
opencodeVersion:
|
|
17978
|
-
provenance:
|
|
18214
|
+
opencodeVersion: z24.string().min(1),
|
|
18215
|
+
provenance: z24.enum(["genuine-usage", "ci-synthetic"]),
|
|
17979
18216
|
traceDigest: Sha256Schema2,
|
|
17980
|
-
criticalDivergences:
|
|
18217
|
+
criticalDivergences: z24.number().int().nonnegative().nullable(),
|
|
17981
18218
|
privacy: PrivacyPairSchema.nullable(),
|
|
17982
18219
|
duplicateEffects: DuplicateEffectPairSchema.nullable(),
|
|
17983
18220
|
modelVerification: ModelVerificationPairSchema.nullable(),
|
|
@@ -18259,6 +18496,12 @@ var KNOWN_RUNTIMES = [
|
|
|
18259
18496
|
dynamicPort: true
|
|
18260
18497
|
}
|
|
18261
18498
|
];
|
|
18499
|
+
var LEMONADE_PROJECT_CONFIG_CANDIDATES = [
|
|
18500
|
+
".opencode/opencode.jsonc",
|
|
18501
|
+
".opencode/opencode.json",
|
|
18502
|
+
"opencode.jsonc",
|
|
18503
|
+
"opencode.json"
|
|
18504
|
+
];
|
|
18262
18505
|
function knownRuntime(id) {
|
|
18263
18506
|
const found = KNOWN_RUNTIMES.find((runtime) => runtime.id === id);
|
|
18264
18507
|
if (found === undefined) {
|
|
@@ -18275,7 +18518,44 @@ function choiceKind(choice) {
|
|
|
18275
18518
|
function choiceProviderID(choice) {
|
|
18276
18519
|
return choice.providerID ?? choice.id;
|
|
18277
18520
|
}
|
|
18521
|
+
function selectableModelIDs(models, modelInfo, kind) {
|
|
18522
|
+
const byID = new Map(modelInfo?.map((model) => [model.modelID, model]));
|
|
18523
|
+
return models.filter((id) => hasRequiredModelResidency(kind, byID.get(id)));
|
|
18524
|
+
}
|
|
18525
|
+
function assertRuntimeResidency(choice, primary) {
|
|
18526
|
+
const kind = localRuntimeKind(choice);
|
|
18527
|
+
const references2 = [
|
|
18528
|
+
choice.defaultModelID,
|
|
18529
|
+
choice.thinkingModelID,
|
|
18530
|
+
choice.coderModelID,
|
|
18531
|
+
...primary.providerID === choiceProviderID(choice) ? [primary.modelID] : []
|
|
18532
|
+
];
|
|
18533
|
+
for (const id of references2) {
|
|
18534
|
+
if (id === undefined)
|
|
18535
|
+
continue;
|
|
18536
|
+
const info = choice.models.includes(id) ? choice.modelInfo?.find((model) => model.modelID === id) : undefined;
|
|
18537
|
+
if (!hasRequiredModelResidency(kind, info))
|
|
18538
|
+
throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${choiceProviderID(choice)}/${id}`));
|
|
18539
|
+
}
|
|
18540
|
+
}
|
|
18541
|
+
function assertSetupResidency(answers) {
|
|
18542
|
+
for (const choice of answers.runtimes) {
|
|
18543
|
+
if (choice.enabled) {
|
|
18544
|
+
assertRuntimeResidency(choice, answers.primaryModel);
|
|
18545
|
+
} else if (choiceProviderID(choice) === answers.primaryModel.providerID && !hasRequiredModelResidency(localRuntimeKind(choice), undefined)) {
|
|
18546
|
+
throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${answers.primaryModel.providerID}/${answers.primaryModel.modelID}`));
|
|
18547
|
+
}
|
|
18548
|
+
}
|
|
18549
|
+
}
|
|
18550
|
+
function lemonadeV2Policies(providers) {
|
|
18551
|
+
return [...new Set(providers)].sort().map((providerID) => {
|
|
18552
|
+
if (providerID.length === 0 || /[*?\\/\s]/.test(providerID))
|
|
18553
|
+
throw new Error(executionSetupMessages.lemonadeV2InvalidProvider(providerID));
|
|
18554
|
+
return { action: "provider.use", resource: providerID, effect: "deny" };
|
|
18555
|
+
});
|
|
18556
|
+
}
|
|
18278
18557
|
function buildOpenTeamConfig(answers) {
|
|
18558
|
+
assertSetupResidency(answers);
|
|
18279
18559
|
const runtimes = answers.runtimes.filter((choice) => choice.enabled).map((choice) => {
|
|
18280
18560
|
const runtime = {
|
|
18281
18561
|
id: choice.id,
|
|
@@ -18344,6 +18624,8 @@ function orchestratorAgentModel(answers) {
|
|
|
18344
18624
|
return { ...answers.primaryModel };
|
|
18345
18625
|
}
|
|
18346
18626
|
function buildOpencodeConfig(answers) {
|
|
18627
|
+
assertSetupResidency(answers);
|
|
18628
|
+
const policies = lemonadeV2Policies(answers.runtimes.filter((choice) => choice.enabled && choiceKind(choice) === "lemonade").map(choiceProviderID));
|
|
18347
18629
|
const provider = {};
|
|
18348
18630
|
const providerOwner = new Map;
|
|
18349
18631
|
for (const choice of answers.runtimes) {
|
|
@@ -18356,7 +18638,7 @@ function buildOpencodeConfig(answers) {
|
|
|
18356
18638
|
continue;
|
|
18357
18639
|
}
|
|
18358
18640
|
const providerID = choiceProviderID(choice);
|
|
18359
|
-
const modelIDs = new Set(choice.models);
|
|
18641
|
+
const modelIDs = new Set(selectableModelIDs(choice.models, choice.modelInfo, meta.id));
|
|
18360
18642
|
modelIDs.add(choice.defaultModelID);
|
|
18361
18643
|
if (choice.thinkingModelID !== undefined) {
|
|
18362
18644
|
modelIDs.add(choice.thinkingModelID);
|
|
@@ -18412,6 +18694,8 @@ function buildOpencodeConfig(answers) {
|
|
|
18412
18694
|
if (answers.yolo) {
|
|
18413
18695
|
config.permission = { "*": "allow" };
|
|
18414
18696
|
}
|
|
18697
|
+
if (policies.length > 0)
|
|
18698
|
+
config.experimental = { policies };
|
|
18415
18699
|
return config;
|
|
18416
18700
|
}
|
|
18417
18701
|
function serializeOpencodeConfig(config) {
|
|
@@ -18511,10 +18795,11 @@ async function chooseFrontier(prompt, profiles) {
|
|
|
18511
18795
|
}
|
|
18512
18796
|
return parseFrontierRef(selected);
|
|
18513
18797
|
}
|
|
18514
|
-
function orderModelChoices(models, modelInfo) {
|
|
18798
|
+
function orderModelChoices(models, modelInfo, kind) {
|
|
18515
18799
|
const byID = new Map((modelInfo ?? []).map((model) => [model.modelID, model]));
|
|
18516
18800
|
const anyLoadState = (modelInfo ?? []).some((model) => model.loaded !== undefined);
|
|
18517
|
-
const
|
|
18801
|
+
const offered = kind === undefined ? models : selectableModelIDs(models, modelInfo, kind);
|
|
18802
|
+
const decorated = offered.map((modelID, index) => {
|
|
18518
18803
|
const info = byID.get(modelID);
|
|
18519
18804
|
return {
|
|
18520
18805
|
modelID,
|
|
@@ -18540,27 +18825,34 @@ function modelStateSuffix(loaded, slots) {
|
|
|
18540
18825
|
}
|
|
18541
18826
|
return slots === undefined ? "(loaded)" : `(loaded · ${slots} slot${slots === 1 ? "" : "s"})`;
|
|
18542
18827
|
}
|
|
18543
|
-
function preferredModelID(models, modelInfo) {
|
|
18544
|
-
const
|
|
18545
|
-
|
|
18828
|
+
function preferredModelID(models, modelInfo, kind) {
|
|
18829
|
+
const offered = kind === undefined ? models : selectableModelIDs(models, modelInfo, kind);
|
|
18830
|
+
const loaded = (modelInfo ?? []).find((model) => model.loaded === true && offered.includes(model.modelID));
|
|
18831
|
+
return loaded?.modelID ?? offered[0];
|
|
18546
18832
|
}
|
|
18547
18833
|
async function chooseRuntimeModel(prompt, models, meta, modelInfo) {
|
|
18548
|
-
|
|
18834
|
+
const offered = selectableModelIDs(models, modelInfo, meta.id);
|
|
18835
|
+
if (offered.length === 0) {
|
|
18836
|
+
if (meta.id === "lemonade")
|
|
18837
|
+
throw new Error(executionSetupMessages.lemonadeNoLoadedModels);
|
|
18549
18838
|
return prompt.text({
|
|
18550
18839
|
message: `Default model for ${meta.label} (no models detected)`,
|
|
18551
18840
|
placeholder: meta.fallbackModelID,
|
|
18552
18841
|
initial: meta.fallbackModelID
|
|
18553
18842
|
});
|
|
18554
18843
|
}
|
|
18555
|
-
const first = preferredModelID(
|
|
18844
|
+
const first = preferredModelID(offered, modelInfo, meta.id);
|
|
18556
18845
|
const opts = {
|
|
18557
18846
|
message: `Default local model for ${meta.label}`,
|
|
18558
|
-
choices: orderModelChoices(
|
|
18847
|
+
choices: orderModelChoices(offered, modelInfo, meta.id)
|
|
18559
18848
|
};
|
|
18560
18849
|
if (first !== undefined) {
|
|
18561
18850
|
opts.initial = first;
|
|
18562
18851
|
}
|
|
18563
|
-
|
|
18852
|
+
const selected = await prompt.select(opts);
|
|
18853
|
+
if (meta.id === "lemonade" && !offered.includes(selected))
|
|
18854
|
+
throw new Error(executionSetupMessages.lemonadeModelNotLoaded(selected));
|
|
18855
|
+
return selected;
|
|
18564
18856
|
}
|
|
18565
18857
|
function remoteBaseURLExample(meta) {
|
|
18566
18858
|
const base = meta.defaultBaseURL ?? "http://localhost:11434/v1";
|
|
@@ -18615,6 +18907,8 @@ async function resolveRuntimeConnection(deps, meta, info) {
|
|
|
18615
18907
|
initial: RUNTIME_LOCATION_LOCAL
|
|
18616
18908
|
});
|
|
18617
18909
|
if (location === RUNTIME_LOCATION_LOCAL) {
|
|
18910
|
+
if (meta.id === "lemonade" && info?.reachable !== true)
|
|
18911
|
+
throw new Error(executionSetupMessages.lemonadeProbeFailed);
|
|
18618
18912
|
const baseURL2 = info?.baseURL !== undefined && info.baseURL.length > 0 ? info.baseURL : meta.defaultBaseURL;
|
|
18619
18913
|
return { baseURL: baseURL2, ...connectionOf(info) };
|
|
18620
18914
|
}
|
|
@@ -18624,16 +18918,26 @@ async function resolveRuntimeConnection(deps, meta, info) {
|
|
|
18624
18918
|
});
|
|
18625
18919
|
const baseURL = normalizeRemoteBaseURL(entered, meta.defaultBaseURL);
|
|
18626
18920
|
let probedRuntime;
|
|
18921
|
+
if (meta.id === "lemonade" && deps.probeRuntime === undefined)
|
|
18922
|
+
throw new Error(executionSetupMessages.lemonadeProbeRequired);
|
|
18627
18923
|
if (deps.probeRuntime !== undefined) {
|
|
18628
18924
|
try {
|
|
18629
18925
|
probedRuntime = await deps.probeRuntime(meta.id, baseURL);
|
|
18630
|
-
} catch {
|
|
18926
|
+
} catch (cause) {
|
|
18927
|
+
if (meta.id === "lemonade")
|
|
18928
|
+
throw new Error(executionSetupMessages.lemonadeProbeFailed, { cause });
|
|
18929
|
+
}
|
|
18930
|
+
if (meta.id === "lemonade" && probedRuntime?.reachable !== true)
|
|
18931
|
+
throw new Error(executionSetupMessages.lemonadeProbeFailed);
|
|
18631
18932
|
}
|
|
18632
18933
|
return { baseURL, ...connectionOf(probedRuntime) };
|
|
18633
18934
|
}
|
|
18634
18935
|
async function chooseClassModel(prompt, models, meta, defaultModelID, modelClass, modelInfo) {
|
|
18635
18936
|
const label = modelClass === "thinking" ? `Thinking model for ${meta.label} (design, analysis, review reasoning)` : `Coder model for ${meta.label} (writing and editing code)`;
|
|
18636
|
-
|
|
18937
|
+
const offered = selectableModelIDs(models, modelInfo, meta.id);
|
|
18938
|
+
if (offered.length === 0) {
|
|
18939
|
+
if (meta.id === "lemonade")
|
|
18940
|
+
throw new Error(executionSetupMessages.lemonadeNoLoadedModels);
|
|
18637
18941
|
const raw = await prompt.text({
|
|
18638
18942
|
message: `${label} — enter to reuse the default`,
|
|
18639
18943
|
placeholder: defaultModelID,
|
|
@@ -18641,14 +18945,17 @@ async function chooseClassModel(prompt, models, meta, defaultModelID, modelClass
|
|
|
18641
18945
|
});
|
|
18642
18946
|
return raw.trim().length > 0 ? raw.trim() : defaultModelID;
|
|
18643
18947
|
}
|
|
18644
|
-
|
|
18948
|
+
const selected = await prompt.select({
|
|
18645
18949
|
message: label,
|
|
18646
|
-
choices: orderModelChoices(
|
|
18950
|
+
choices: orderModelChoices(offered, modelInfo, meta.id).map((choice) => ({
|
|
18647
18951
|
value: choice.value,
|
|
18648
18952
|
label: choice.value === defaultModelID ? `${choice.label} — default` : choice.label
|
|
18649
18953
|
})),
|
|
18650
18954
|
initial: defaultModelID
|
|
18651
18955
|
});
|
|
18956
|
+
if (meta.id === "lemonade" && !offered.includes(selected))
|
|
18957
|
+
throw new Error(executionSetupMessages.lemonadeModelNotLoaded(selected));
|
|
18958
|
+
return selected;
|
|
18652
18959
|
}
|
|
18653
18960
|
async function resolveEnabledRuntime(deps, meta, info) {
|
|
18654
18961
|
const connection = await resolveRuntimeConnection(deps, meta, info);
|
|
@@ -18661,7 +18968,8 @@ async function resolveEnabledRuntime(deps, meta, info) {
|
|
|
18661
18968
|
defaultModelID,
|
|
18662
18969
|
thinkingModelID,
|
|
18663
18970
|
coderModelID,
|
|
18664
|
-
models: connection.models
|
|
18971
|
+
models: selectableModelIDs(connection.models, connection.modelInfo, meta.id),
|
|
18972
|
+
...connection.modelInfo === undefined ? {} : { modelInfo: connection.modelInfo }
|
|
18665
18973
|
};
|
|
18666
18974
|
if (connection.baseURL !== undefined) {
|
|
18667
18975
|
choice.baseURL = connection.baseURL;
|
|
@@ -19161,17 +19469,52 @@ async function readExistingOpencodeConfigFiles(paths, deps) {
|
|
|
19161
19469
|
function opencodeFileAt(files, path2) {
|
|
19162
19470
|
return files.find((file) => file.path === path2);
|
|
19163
19471
|
}
|
|
19164
|
-
function mergeExistingOpencodeConfigFiles(files) {
|
|
19472
|
+
function mergeExistingOpencodeConfigFiles(files, paths, planned = new Map) {
|
|
19165
19473
|
let merged;
|
|
19166
|
-
for (const path2 of [...
|
|
19167
|
-
const
|
|
19168
|
-
if (
|
|
19474
|
+
for (const path2 of [...paths].reverse()) {
|
|
19475
|
+
const raw = planned.get(path2) ?? opencodeFileAt(files, path2)?.raw;
|
|
19476
|
+
if (raw === undefined) {
|
|
19169
19477
|
continue;
|
|
19170
19478
|
}
|
|
19171
|
-
merged = merged === undefined ?
|
|
19479
|
+
merged = merged === undefined ? raw : mergeOpencodeConfigs(merged, raw);
|
|
19172
19480
|
}
|
|
19173
19481
|
return merged;
|
|
19174
19482
|
}
|
|
19483
|
+
async function effectiveSetupConfig(portable, files, deps) {
|
|
19484
|
+
const optionsByLoader = new Map;
|
|
19485
|
+
for (const file of files) {
|
|
19486
|
+
if (!Array.isArray(file.raw.plugin))
|
|
19487
|
+
continue;
|
|
19488
|
+
for (const entry of [...file.raw.plugin].reverse()) {
|
|
19489
|
+
const spec = extractPluginSpec(entry);
|
|
19490
|
+
if (spec === undefined)
|
|
19491
|
+
continue;
|
|
19492
|
+
let identity;
|
|
19493
|
+
if (isOpenteamNpmSpec(spec)) {
|
|
19494
|
+
identity = OPENTEAM_PACKAGE_NAME;
|
|
19495
|
+
} else if (isLocalFileSpec(spec) && await classifyLocalPluginSpecForSetup(spec, file.path, deps.classifyLocalPluginSpec) === "ours") {
|
|
19496
|
+
const resolved = resolvePluginSpecPath(spec, file.path);
|
|
19497
|
+
if (resolved === undefined)
|
|
19498
|
+
throw new Error(executionSetupMessages.lemonadeEffectiveConfigAmbiguous);
|
|
19499
|
+
identity = resolved;
|
|
19500
|
+
} else {
|
|
19501
|
+
continue;
|
|
19502
|
+
}
|
|
19503
|
+
if (!optionsByLoader.has(identity)) {
|
|
19504
|
+
optionsByLoader.set(identity, Array.isArray(entry) ? entry[1] : undefined);
|
|
19505
|
+
}
|
|
19506
|
+
}
|
|
19507
|
+
}
|
|
19508
|
+
const overlayText = await deps.readFile(DEFAULT_LOCAL_OVERLAY_PATH);
|
|
19509
|
+
const overlay = overlayText === undefined ? undefined : parseConfigFileJson(DEFAULT_LOCAL_OVERLAY_PATH, overlayText);
|
|
19510
|
+
const resolutions = [
|
|
19511
|
+
...optionsByLoader.size > 0 ? optionsByLoader.values() : [undefined]
|
|
19512
|
+
].map((options) => validateConfigInput(executionSetupMessages.lemonadeEffectiveConfigLabel, mergeConfigInputs(mergeConfigInputs(portable, configOptionsFromPluginOptions(options)), overlay)));
|
|
19513
|
+
const effective = resolutions[0];
|
|
19514
|
+
if (effective === undefined || resolutions.some((config) => JSON.stringify(config) !== JSON.stringify(effective)))
|
|
19515
|
+
throw new Error(executionSetupMessages.lemonadeEffectiveConfigAmbiguous);
|
|
19516
|
+
return effective;
|
|
19517
|
+
}
|
|
19175
19518
|
function relevantLocalProviderIDs(generated, existingOpenTeamConfig) {
|
|
19176
19519
|
const ids = new Set(Object.keys(generated.provider ?? {}));
|
|
19177
19520
|
for (const runtime of existingOpenTeamConfig?.local.runtimes ?? []) {
|
|
@@ -19348,15 +19691,42 @@ function highestExistingPinVersion(files) {
|
|
|
19348
19691
|
}
|
|
19349
19692
|
return highest;
|
|
19350
19693
|
}
|
|
19694
|
+
function reconcileLemonadeV2Policies(raw, denials) {
|
|
19695
|
+
if (denials.length === 0)
|
|
19696
|
+
return raw;
|
|
19697
|
+
const experimental = raw.experimental;
|
|
19698
|
+
if (experimental !== undefined && !isRecord6(experimental))
|
|
19699
|
+
throw new Error(executionSetupMessages.lemonadeV2InvalidPolicies);
|
|
19700
|
+
const policies = experimental?.policies;
|
|
19701
|
+
if (policies !== undefined && !Array.isArray(policies))
|
|
19702
|
+
throw new Error(executionSetupMessages.lemonadeV2InvalidPolicies);
|
|
19703
|
+
const existing = policies ?? [];
|
|
19704
|
+
for (const policy of existing) {
|
|
19705
|
+
if (!isRecord6(policy) || policy.action !== "provider.use" || typeof policy.resource !== "string" || policy.effect !== "allow" && policy.effect !== "deny")
|
|
19706
|
+
throw new Error(executionSetupMessages.lemonadeV2InvalidPolicies);
|
|
19707
|
+
}
|
|
19708
|
+
const terminal = denials.every((denial, index) => {
|
|
19709
|
+
const policy = existing[existing.length - denials.length + index];
|
|
19710
|
+
return isRecord6(policy) && Object.keys(policy).length === 3 && policy.action === denial.action && policy.resource === denial.resource && policy.effect === denial.effect;
|
|
19711
|
+
});
|
|
19712
|
+
if (terminal)
|
|
19713
|
+
return raw;
|
|
19714
|
+
return {
|
|
19715
|
+
...raw,
|
|
19716
|
+
experimental: { ...experimental, policies: [...existing, ...denials] }
|
|
19717
|
+
};
|
|
19718
|
+
}
|
|
19351
19719
|
function mergeOpencodeConfigForRerun(generated, targetRaw, options) {
|
|
19352
19720
|
const effectiveRaw = options.effectiveRaw ?? targetRaw;
|
|
19353
19721
|
const includePlugin = options.includePlugin ?? true;
|
|
19722
|
+
const managesV2Policies = (generated.experimental?.policies.length ?? 0) > 0;
|
|
19354
19723
|
const managedKeys = new Set([
|
|
19355
19724
|
"$schema",
|
|
19356
19725
|
"provider",
|
|
19357
19726
|
"model",
|
|
19358
19727
|
"small_model",
|
|
19359
19728
|
"permission",
|
|
19729
|
+
...managesV2Policies ? ["experimental"] : [],
|
|
19360
19730
|
...includePlugin ? ["plugin"] : []
|
|
19361
19731
|
]);
|
|
19362
19732
|
const unknownFields = {};
|
|
@@ -19419,7 +19789,10 @@ function mergeOpencodeConfigForRerun(generated, targetRaw, options) {
|
|
|
19419
19789
|
if (permission !== undefined) {
|
|
19420
19790
|
result.permission = permission;
|
|
19421
19791
|
}
|
|
19422
|
-
|
|
19792
|
+
if (managesV2Policies && hasOwn2(targetRaw, "experimental")) {
|
|
19793
|
+
result.experimental = targetRaw.experimental;
|
|
19794
|
+
}
|
|
19795
|
+
return reconcileLemonadeV2Policies(result, generated.experimental?.policies ?? []);
|
|
19423
19796
|
}
|
|
19424
19797
|
function mergeOpenTeamConfigForRerun(generated, existing) {
|
|
19425
19798
|
const existingOrch = existing.orchestrator;
|
|
@@ -19469,6 +19842,21 @@ function mergeOpenTeamConfigForRerun(generated, existing) {
|
|
|
19469
19842
|
assertEffectiveConfigModelDomains(merged);
|
|
19470
19843
|
return merged;
|
|
19471
19844
|
}
|
|
19845
|
+
function preserveRetainedLemonadeRuntimes(generated, previous, opencode) {
|
|
19846
|
+
const providers = recordAt2(opencode, "provider") ?? {};
|
|
19847
|
+
const retained = (previous?.local.runtimes ?? []).filter((runtime) => localRuntimeKind(runtime) === "lemonade" && hasOwn2(providers, runtime.defaultModel.providerID));
|
|
19848
|
+
const deselected = retained.filter((runtime) => !generated.local.runtimes.some((selected) => selected.defaultModel.providerID === runtime.defaultModel.providerID)).map((runtime) => ({ ...runtime, enabled: false }));
|
|
19849
|
+
return {
|
|
19850
|
+
config: deselected.length === 0 ? generated : OpenTeamConfigSchema.parse({
|
|
19851
|
+
...generated,
|
|
19852
|
+
local: {
|
|
19853
|
+
...generated.local,
|
|
19854
|
+
runtimes: [...generated.local.runtimes, ...deselected]
|
|
19855
|
+
}
|
|
19856
|
+
}),
|
|
19857
|
+
providerIDs: retained.map((runtime) => runtime.defaultModel.providerID)
|
|
19858
|
+
};
|
|
19859
|
+
}
|
|
19472
19860
|
async function existingPluginOwnerPath(files, classifyLocalPluginSpec) {
|
|
19473
19861
|
let unknownLocalPlugin;
|
|
19474
19862
|
for (const file of files) {
|
|
@@ -19496,6 +19884,86 @@ async function confirmJsonNormalization(prompt, path2, format) {
|
|
|
19496
19884
|
initial: false
|
|
19497
19885
|
});
|
|
19498
19886
|
}
|
|
19887
|
+
function assertPreviousLemonadePrimary(answers, previousConfig) {
|
|
19888
|
+
const priorLemonadePrimary = previousConfig?.local.runtimes.some((runtime) => runtime.defaultModel.providerID === answers.primaryModel.providerID && localRuntimeKind(runtime) === "lemonade");
|
|
19889
|
+
if (priorLemonadePrimary && !answers.runtimes.some((choice) => choice.enabled && choiceProviderID(choice) === answers.primaryModel.providerID)) {
|
|
19890
|
+
throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${answers.primaryModel.providerID}/${answers.primaryModel.modelID}`));
|
|
19891
|
+
}
|
|
19892
|
+
}
|
|
19893
|
+
async function verifyLemonadeBeforeWrite(deps, answers, config, opencode) {
|
|
19894
|
+
for (const choice of answers.runtimes) {
|
|
19895
|
+
if (choice.enabled && localRuntimeKind(choice) === "lemonade" && !config.local.runtimes.some((runtime) => runtime.enabled && runtime.defaultModel.providerID === choiceProviderID(choice) && localRuntimeKind(runtime) === "lemonade"))
|
|
19896
|
+
throw new Error(executionSetupMessages.lemonadeEndpointMismatch);
|
|
19897
|
+
}
|
|
19898
|
+
for (const runtime of config.local.runtimes) {
|
|
19899
|
+
if (localRuntimeKind(runtime) !== "lemonade")
|
|
19900
|
+
continue;
|
|
19901
|
+
const providerID = runtime.defaultModel.providerID;
|
|
19902
|
+
const provider = isRecord6(opencode.provider) ? opencode.provider[providerID] : undefined;
|
|
19903
|
+
if (!runtime.enabled && provider === undefined)
|
|
19904
|
+
continue;
|
|
19905
|
+
const endpoint = isRecord6(provider) ? (isRecord6(provider.options) ? provider.options.baseURL : undefined) ?? provider.api : undefined;
|
|
19906
|
+
if (typeof endpoint !== "string" || lemonadeBaseURL(endpoint) !== lemonadeBaseURL(runtime.baseURL ?? LEMONADE_DEFAULT_BASE_URL) || config.local.runtimes.filter((candidate) => candidate.defaultModel.providerID === providerID).length !== 1)
|
|
19907
|
+
throw new Error(executionSetupMessages.lemonadeEndpointMismatch);
|
|
19908
|
+
if (!runtime.enabled)
|
|
19909
|
+
continue;
|
|
19910
|
+
if (deps.probeRuntime === undefined)
|
|
19911
|
+
throw new Error(executionSetupMessages.lemonadeProbeRequired);
|
|
19912
|
+
const references2 = new Set([
|
|
19913
|
+
runtime.defaultModel.modelID,
|
|
19914
|
+
runtime.thinkingModel,
|
|
19915
|
+
runtime.coderModel
|
|
19916
|
+
]);
|
|
19917
|
+
for (const choice of answers.runtimes) {
|
|
19918
|
+
if (choice.enabled && choiceProviderID(choice) === providerID) {
|
|
19919
|
+
for (const id of [
|
|
19920
|
+
...choice.models,
|
|
19921
|
+
choice.defaultModelID,
|
|
19922
|
+
choice.thinkingModelID,
|
|
19923
|
+
choice.coderModelID
|
|
19924
|
+
])
|
|
19925
|
+
references2.add(id);
|
|
19926
|
+
}
|
|
19927
|
+
}
|
|
19928
|
+
for (const ref of [
|
|
19929
|
+
answers.primaryModel,
|
|
19930
|
+
config.orchestrator?.primary?.model,
|
|
19931
|
+
config.router.localDefault
|
|
19932
|
+
]) {
|
|
19933
|
+
if (ref !== null && typeof ref === "object" && ref.providerID === providerID)
|
|
19934
|
+
references2.add(ref.modelID);
|
|
19935
|
+
}
|
|
19936
|
+
for (const key of ["model", "small_model"]) {
|
|
19937
|
+
const ref = opencode[key];
|
|
19938
|
+
if (typeof ref === "string" && ref.startsWith(`${providerID}/`))
|
|
19939
|
+
references2.add(ref.slice(providerID.length + 1));
|
|
19940
|
+
}
|
|
19941
|
+
const models = isRecord6(provider) ? recordAt2(provider, "models") : undefined;
|
|
19942
|
+
const wireIDs = new Set;
|
|
19943
|
+
for (const alias of references2) {
|
|
19944
|
+
if (alias === undefined)
|
|
19945
|
+
continue;
|
|
19946
|
+
const declaration = recordAt2(models, alias);
|
|
19947
|
+
const wireID = declaration !== undefined && hasOwn2(declaration, "id") ? declaration.id : alias;
|
|
19948
|
+
if (declaration === undefined || typeof wireID !== "string" || wireID.length === 0 || wireID !== wireID.trim())
|
|
19949
|
+
throw new Error(executionSetupMessages.lemonadeModelIdentityUnknown(`${providerID}/${alias}`));
|
|
19950
|
+
wireIDs.add(wireID);
|
|
19951
|
+
}
|
|
19952
|
+
let fresh;
|
|
19953
|
+
try {
|
|
19954
|
+
fresh = await deps.probeRuntime(localRuntimeKind(runtime), endpoint);
|
|
19955
|
+
} catch (cause) {
|
|
19956
|
+
throw new Error(executionSetupMessages.lemonadeProbeFailed, { cause });
|
|
19957
|
+
}
|
|
19958
|
+
if (!fresh.reachable || fresh.id !== localRuntimeKind(runtime) || fresh.baseURL.replace(/\/+$/, "") !== endpoint.replace(/\/+$/, ""))
|
|
19959
|
+
throw new Error(executionSetupMessages.lemonadeProbeFailed);
|
|
19960
|
+
for (const wireID of wireIDs) {
|
|
19961
|
+
const info = fresh.models.includes(wireID) ? fresh.modelInfo?.find((model) => model.modelID === wireID) : undefined;
|
|
19962
|
+
if (!hasRequiredModelResidency("lemonade", info))
|
|
19963
|
+
throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${providerID}/${wireID}`));
|
|
19964
|
+
}
|
|
19965
|
+
}
|
|
19966
|
+
}
|
|
19499
19967
|
async function runSetup(deps) {
|
|
19500
19968
|
const { prompt } = deps;
|
|
19501
19969
|
try {
|
|
@@ -19507,7 +19975,7 @@ async function runSetup(deps) {
|
|
|
19507
19975
|
return {
|
|
19508
19976
|
value: meta.id,
|
|
19509
19977
|
label: meta.label,
|
|
19510
|
-
hint: info?.reachable ? `detected · ${info.models.length} model(s)` : "not detected (you can point it to another machine)",
|
|
19978
|
+
hint: info?.reachable ? meta.id === "lemonade" ? executionSetupMessages.lemonadeDetectedHint(selectableModelIDs(info.models, info.modelInfo, meta.id).length, info.modelInfo?.length ?? info.models.length) : `detected · ${info.models.length} model(s)` : "not detected (you can point it to another machine)",
|
|
19511
19979
|
selected: info?.reachable ?? false
|
|
19512
19980
|
};
|
|
19513
19981
|
});
|
|
@@ -19624,17 +20092,18 @@ async function runSetup(deps) {
|
|
|
19624
20092
|
};
|
|
19625
20093
|
const openTeamConfig = buildOpenTeamConfig(answers);
|
|
19626
20094
|
const opencodeConfig = buildOpencodeConfig(answers);
|
|
20095
|
+
const opencodeConfigPaths = LEMONADE_PROJECT_CONFIG_CANDIDATES;
|
|
19627
20096
|
const orchestratorAgent = buildOrchestratorAgent(orchestratorAgentModel(answers), { yolo });
|
|
19628
20097
|
const slashCommands = buildOpenteamCommands();
|
|
19629
20098
|
const openTeamPath = DEFAULT_CONFIG_PATH;
|
|
19630
|
-
const existingOpencodePath = await deps.resolveOpencodeWriteTarget(
|
|
20099
|
+
const existingOpencodePath = await deps.resolveOpencodeWriteTarget(opencodeConfigPaths);
|
|
19631
20100
|
const opencodeDataPath = existingOpencodePath ?? OPENCODE_CONFIG_CANDIDATES[0];
|
|
19632
20101
|
const agentPath = ORCHESTRATOR_AGENT_PATH;
|
|
19633
20102
|
let existingOpenTeamConfig;
|
|
19634
20103
|
let existingOpencodeFiles;
|
|
19635
20104
|
try {
|
|
19636
20105
|
existingOpenTeamConfig = await readExistingOpenTeamConfig(openTeamPath, deps);
|
|
19637
|
-
existingOpencodeFiles = await readExistingOpencodeConfigFiles(
|
|
20106
|
+
existingOpencodeFiles = await readExistingOpencodeConfigFiles(opencodeConfigPaths, deps);
|
|
19638
20107
|
} catch (error) {
|
|
19639
20108
|
if (error instanceof ConfigParseError) {
|
|
19640
20109
|
return {
|
|
@@ -19644,7 +20113,29 @@ async function runSetup(deps) {
|
|
|
19644
20113
|
}
|
|
19645
20114
|
throw error;
|
|
19646
20115
|
}
|
|
19647
|
-
|
|
20116
|
+
assertPreviousLemonadePrimary(answers, existingOpenTeamConfig);
|
|
20117
|
+
const effectiveExistingOpencode = mergeExistingOpencodeConfigFiles(existingOpencodeFiles, opencodeConfigPaths);
|
|
20118
|
+
const {
|
|
20119
|
+
config: finalOpenTeamConfig,
|
|
20120
|
+
providerIDs: retainedLemonadeProviderIDs
|
|
20121
|
+
} = preserveRetainedLemonadeRuntimes(existingOpenTeamConfig !== undefined ? mergeOpenTeamConfigForRerun(openTeamConfig, existingOpenTeamConfig) : openTeamConfig, existingOpenTeamConfig, effectiveExistingOpencode);
|
|
20122
|
+
assertEffectiveConfigModelDomains(finalOpenTeamConfig);
|
|
20123
|
+
const effectiveOpenTeamConfig = await effectiveSetupConfig(finalOpenTeamConfig, existingOpencodeFiles, deps);
|
|
20124
|
+
assertEffectiveConfigModelDomains(effectiveOpenTeamConfig);
|
|
20125
|
+
for (const providerID of retainedLemonadeProviderIDs) {
|
|
20126
|
+
const matches = effectiveOpenTeamConfig.local.runtimes.filter((runtime) => runtime.defaultModel.providerID === providerID);
|
|
20127
|
+
if (matches.length !== 1 || matches[0] === undefined || localRuntimeKind(matches[0]) !== "lemonade")
|
|
20128
|
+
throw new Error(executionSetupMessages.lemonadeRetainedProviderUnprotected(providerID));
|
|
20129
|
+
}
|
|
20130
|
+
const v2Denials = lemonadeV2Policies([
|
|
20131
|
+
...opencodeConfig.experimental?.policies.map((policy) => policy.resource) ?? [],
|
|
20132
|
+
...effectiveOpenTeamConfig.local.runtimes.filter((runtime) => localRuntimeKind(runtime) === "lemonade").map((runtime) => runtime.defaultModel.providerID)
|
|
20133
|
+
]);
|
|
20134
|
+
if (v2Denials.length > 0)
|
|
20135
|
+
opencodeConfig.experimental = { policies: v2Denials };
|
|
20136
|
+
const v2Notice = v2Denials.length > 0 ? executionSetupMessages.lemonadeV2Restriction(v2Denials.map((policy) => policy.resource)) : undefined;
|
|
20137
|
+
if (v2Notice !== undefined)
|
|
20138
|
+
prompt.note(v2Notice, executionSetupMessages.lemonadeV2Title);
|
|
19648
20139
|
const relevantProviderIDs = relevantLocalProviderIDs(opencodeConfig, existingOpenTeamConfig);
|
|
19649
20140
|
for (const file of existingOpencodeFiles) {
|
|
19650
20141
|
assertRelevantLimitNumbers(file, relevantProviderIDs);
|
|
@@ -19673,8 +20164,6 @@ async function runSetup(deps) {
|
|
|
19673
20164
|
const pluginOwnerFile = opencodeFileAt(existingOpencodeFiles, pluginOwnerPath);
|
|
19674
20165
|
const pluginPlan = await mergePluginEntriesForRerun(Array.isArray(pluginOwnerFile?.raw.plugin) ? pluginOwnerFile.raw.plugin : [], pluginOwnerPath, preservePlugin, deps.classifyLocalPluginSpec);
|
|
19675
20166
|
const includePluginInDataFile = pluginOwnerPath === opencodeDataPath;
|
|
19676
|
-
const finalOpenTeamConfig = existingOpenTeamConfig !== undefined ? mergeOpenTeamConfigForRerun(openTeamConfig, existingOpenTeamConfig) : openTeamConfig;
|
|
19677
|
-
assertEffectiveConfigModelDomains(finalOpenTeamConfig);
|
|
19678
20167
|
const dataTargetRaw = opencodeFileAt(existingOpencodeFiles, opencodeDataPath)?.raw ?? {};
|
|
19679
20168
|
const mergedOpencodeRaw = mergeOpencodeConfigForRerun(opencodeConfig, dataTargetRaw, {
|
|
19680
20169
|
...effectiveExistingOpencode !== undefined ? { effectiveRaw: effectiveExistingOpencode } : {},
|
|
@@ -19689,7 +20178,7 @@ async function runSetup(deps) {
|
|
|
19689
20178
|
providerIDs: relevantProviderIDs
|
|
19690
20179
|
});
|
|
19691
20180
|
const opencodeWritePlan = new Map([
|
|
19692
|
-
[opencodeDataPath,
|
|
20181
|
+
[opencodeDataPath, repairedDataTarget.raw]
|
|
19693
20182
|
]);
|
|
19694
20183
|
for (const file of existingOpencodeFiles) {
|
|
19695
20184
|
if (file.path === opencodeDataPath) {
|
|
@@ -19701,14 +20190,14 @@ async function runSetup(deps) {
|
|
|
19701
20190
|
generated: opencodeConfig,
|
|
19702
20191
|
providerIDs: relevantProviderIDs
|
|
19703
20192
|
});
|
|
19704
|
-
let plannedRaw = repaired.raw;
|
|
19705
|
-
let changed = repaired.changed;
|
|
20193
|
+
let plannedRaw = reconcileLemonadeV2Policies(repaired.raw, v2Denials);
|
|
20194
|
+
let changed = repaired.changed || plannedRaw !== repaired.raw;
|
|
19706
20195
|
if (file.path === pluginOwnerPath && !includePluginInDataFile && pluginPlan.changed) {
|
|
19707
20196
|
plannedRaw = { ...plannedRaw, plugin: [...pluginPlan.plugins] };
|
|
19708
20197
|
changed = true;
|
|
19709
20198
|
}
|
|
19710
20199
|
if (changed) {
|
|
19711
|
-
opencodeWritePlan.set(file.path,
|
|
20200
|
+
opencodeWritePlan.set(file.path, plannedRaw);
|
|
19712
20201
|
}
|
|
19713
20202
|
}
|
|
19714
20203
|
const opencodeGitignorePath = OPENCODE_GITIGNORE_PATH;
|
|
@@ -19772,9 +20261,13 @@ async function runSetup(deps) {
|
|
|
19772
20261
|
stdout: shouldWriteOpencodeGitignore ? `setup cancelled by user; ${OPENCODE_GITIGNORE_PATH} ensured` : "setup cancelled by user"
|
|
19773
20262
|
};
|
|
19774
20263
|
}
|
|
20264
|
+
const effectivePlannedOpencode = mergeExistingOpencodeConfigFiles(existingOpencodeFiles, opencodeConfigPaths, opencodeWritePlan);
|
|
20265
|
+
if (effectivePlannedOpencode === undefined)
|
|
20266
|
+
throw new Error(executionSetupMessages.lemonadeEndpointMismatch);
|
|
20267
|
+
await verifyLemonadeBeforeWrite(deps, answers, effectiveOpenTeamConfig, effectivePlannedOpencode);
|
|
19775
20268
|
await deps.writeFile(openTeamPath, serializeOpenTeamConfig(finalOpenTeamConfig));
|
|
19776
20269
|
for (const [path2, contents] of opencodeWritePlan) {
|
|
19777
|
-
await deps.writeFile(path2, contents);
|
|
20270
|
+
await deps.writeFile(path2, serializeOpencodeConfig(contents));
|
|
19778
20271
|
}
|
|
19779
20272
|
await deps.writeFile(agentPath, orchestratorAgent);
|
|
19780
20273
|
for (const command of slashCommands) {
|
|
@@ -19805,7 +20298,11 @@ async function runSetup(deps) {
|
|
|
19805
20298
|
prompt.outro(executionSetupMessages.done);
|
|
19806
20299
|
return {
|
|
19807
20300
|
exitCode: 0,
|
|
19808
|
-
stdout:
|
|
20301
|
+
stdout: [
|
|
20302
|
+
executionSetupMessages.complete(`${writtenOpencodePaths}, ${DEFAULT_CONFIG_PATH}, ${ORCHESTRATOR_AGENT_PATH}, ${OPENTEAM_COMMAND_DIR}/*.md, ${OPENCODE_GITIGNORE_PATH}`),
|
|
20303
|
+
...v2Notice === undefined ? [] : [v2Notice]
|
|
20304
|
+
].join(`
|
|
20305
|
+
`)
|
|
19809
20306
|
};
|
|
19810
20307
|
} catch (error) {
|
|
19811
20308
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -20460,7 +20957,7 @@ import {
|
|
|
20460
20957
|
import { basename as basename3, dirname as dirname8, join as join19, relative as relative2, resolve as resolve11, win32 } from "node:path";
|
|
20461
20958
|
import { fileURLToPath } from "node:url";
|
|
20462
20959
|
import { promisify as promisify2 } from "node:util";
|
|
20463
|
-
import { z as
|
|
20960
|
+
import { z as z25 } from "zod";
|
|
20464
20961
|
var NPM_ORIGIN = "https://registry.npmjs.org";
|
|
20465
20962
|
var NPM_PACKAGE_PATH = "/@jmanuelcorral%2Fopenteam";
|
|
20466
20963
|
var NPM_LATEST_URL = `${NPM_ORIGIN}${NPM_PACKAGE_PATH}/latest`;
|
|
@@ -20479,9 +20976,9 @@ var UPGRADE_BACKUP_DIRECTORY = ".opencode/openteam-local/upgrade-backups";
|
|
|
20479
20976
|
function npmVersionUrl(version) {
|
|
20480
20977
|
return `${NPM_ORIGIN}${NPM_PACKAGE_PATH}/${version}`;
|
|
20481
20978
|
}
|
|
20482
|
-
var RegistryPackageIdentitySchema =
|
|
20483
|
-
name:
|
|
20484
|
-
version:
|
|
20979
|
+
var RegistryPackageIdentitySchema = z25.object({
|
|
20980
|
+
name: z25.string(),
|
|
20981
|
+
version: z25.string()
|
|
20485
20982
|
}).strict();
|
|
20486
20983
|
|
|
20487
20984
|
class TransientFetchError extends Error {
|
|
@@ -22140,12 +22637,19 @@ function defaultModelFromOpencode(opencodeConfig) {
|
|
|
22140
22637
|
}
|
|
22141
22638
|
return;
|
|
22142
22639
|
}
|
|
22143
|
-
function liveModelsFromSnapshots(snapshots) {
|
|
22640
|
+
function liveModelsFromSnapshots(snapshots, config) {
|
|
22144
22641
|
const map = new Map;
|
|
22145
22642
|
for (const snapshot of snapshots) {
|
|
22146
|
-
|
|
22643
|
+
const runtime = config.local.runtimes.find((runtime2) => runtime2.id === snapshot.id);
|
|
22644
|
+
if (runtime === undefined || !runtime.enabled)
|
|
22645
|
+
continue;
|
|
22646
|
+
const kind = localRuntimeKind(runtime);
|
|
22647
|
+
map.set(runtime.defaultModel.providerID, {
|
|
22147
22648
|
reachable: snapshot.reachable,
|
|
22148
|
-
modelIDs: new Set(snapshot.models.map((model) => model.modelID))
|
|
22649
|
+
modelIDs: new Set(snapshot.models.filter((model) => hasRequiredModelResidency(kind, model)).map((model) => model.modelID)),
|
|
22650
|
+
...kind === "lemonade" ? {
|
|
22651
|
+
residency: new Map(snapshot.models.map((model) => [model.modelID, model.loaded]))
|
|
22652
|
+
} : {}
|
|
22149
22653
|
});
|
|
22150
22654
|
}
|
|
22151
22655
|
return map;
|
|
@@ -22431,7 +22935,7 @@ async function runCli(argv, deps) {
|
|
|
22431
22935
|
const agentModels = diagnoseAgentModels(agentFiles, {
|
|
22432
22936
|
opencodeProviders: parseOpencodeProviders(opencodeConfig),
|
|
22433
22937
|
localRuntimes: localRuntimeStates(config),
|
|
22434
|
-
liveModels: liveModelsFromSnapshots(snapshots),
|
|
22938
|
+
liveModels: liveModelsFromSnapshots(snapshots, config),
|
|
22435
22939
|
sourceDir: deps.agentDir,
|
|
22436
22940
|
...defaultModel !== undefined ? { defaultModel } : {}
|
|
22437
22941
|
});
|
|
@@ -22470,29 +22974,53 @@ async function runCli(argv, deps) {
|
|
|
22470
22974
|
const rosterMissing = deps.loadRosterForDoctor !== undefined && roster === undefined && rosterLoadError === undefined;
|
|
22471
22975
|
const orchestratorAgentName = ORCHESTRATOR_AGENT_PATH.slice(ORCHESTRATOR_AGENT_PATH.lastIndexOf("/") + 1).replace(/\.md$/, "");
|
|
22472
22976
|
const orchestratorAgentMissing = !agentFiles.some((file) => file.name === orchestratorAgentName);
|
|
22977
|
+
const inventoryNotes = [];
|
|
22978
|
+
const readySnapshots = snapshots.map((snapshot) => {
|
|
22979
|
+
const runtime = config.local.runtimes.find((runtime2) => runtime2.id === snapshot.id);
|
|
22980
|
+
if (runtime === undefined || localRuntimeKind(runtime) !== "lemonade")
|
|
22981
|
+
return snapshot;
|
|
22982
|
+
inventoryNotes.push(executionSetupMessages.lemonadeInventory(runtime.id, runtime.defaultModel.providerID, snapshot.models));
|
|
22983
|
+
return {
|
|
22984
|
+
...snapshot,
|
|
22985
|
+
models: snapshot.models.filter((model) => hasRequiredModelResidency(localRuntimeKind(runtime), model))
|
|
22986
|
+
};
|
|
22987
|
+
});
|
|
22988
|
+
const residencyNotes = agentModels.flatMap((agent) => {
|
|
22989
|
+
const live = agent.resolution?.live;
|
|
22990
|
+
if (agent.model === undefined || live !== "not-loaded" && live !== "residency-unknown")
|
|
22991
|
+
return [];
|
|
22992
|
+
return [
|
|
22993
|
+
executionSetupMessages.lemonadeAgentResidency(agent.name, `${agent.model.providerID}/${agent.model.modelID}`, live)
|
|
22994
|
+
];
|
|
22995
|
+
});
|
|
22473
22996
|
return {
|
|
22474
22997
|
exitCode: 0,
|
|
22475
|
-
stdout:
|
|
22476
|
-
|
|
22477
|
-
|
|
22478
|
-
|
|
22479
|
-
|
|
22480
|
-
|
|
22481
|
-
|
|
22482
|
-
|
|
22483
|
-
|
|
22484
|
-
|
|
22485
|
-
|
|
22486
|
-
|
|
22487
|
-
|
|
22488
|
-
|
|
22489
|
-
|
|
22490
|
-
|
|
22491
|
-
|
|
22492
|
-
|
|
22493
|
-
|
|
22494
|
-
|
|
22495
|
-
|
|
22998
|
+
stdout: [
|
|
22999
|
+
renderDoctor({
|
|
23000
|
+
config,
|
|
23001
|
+
snapshots: readySnapshots,
|
|
23002
|
+
telemetryPath,
|
|
23003
|
+
telemetryRecords: records.length,
|
|
23004
|
+
agentModels,
|
|
23005
|
+
opencodeConfigPaths,
|
|
23006
|
+
...opencodeConfig !== undefined ? { opencodeConfig } : {},
|
|
23007
|
+
...queueWait !== undefined ? { queueWait } : {},
|
|
23008
|
+
...rosterAudit !== undefined ? { rosterAudit } : {},
|
|
23009
|
+
...rosterRoleCount !== undefined ? { rosterRoleCount } : {},
|
|
23010
|
+
...rosterLoadError !== undefined ? { rosterLoadError } : {},
|
|
23011
|
+
...rosterMissing ? { rosterMissing } : {},
|
|
23012
|
+
...orchestratorAgentMissing ? { orchestratorAgentMissing } : {},
|
|
23013
|
+
...diagnostics !== undefined && diagnostics.length > 0 ? { diagnostics } : {},
|
|
23014
|
+
...opencodeConfigError !== undefined ? { opencodeConfigError } : {},
|
|
23015
|
+
...cacheEntries !== undefined ? { cacheEntries, cliVersion: deps.version } : {},
|
|
23016
|
+
...legacyLayout !== undefined && legacyLayout.length > 0 ? { legacyLayout } : {},
|
|
23017
|
+
...otelBackend !== undefined ? { otelBackend } : {},
|
|
23018
|
+
...gitignoreCoverage !== undefined ? { gitignore: gitignoreCoverage } : {}
|
|
23019
|
+
}),
|
|
23020
|
+
...inventoryNotes,
|
|
23021
|
+
...residencyNotes
|
|
23022
|
+
].join(`
|
|
23023
|
+
`)
|
|
22496
23024
|
};
|
|
22497
23025
|
}
|
|
22498
23026
|
if (command === "migrate") {
|
|
@@ -22609,14 +23137,14 @@ ${HELP}`
|
|
|
22609
23137
|
}
|
|
22610
23138
|
|
|
22611
23139
|
// src/orchestrator/roster.ts
|
|
22612
|
-
import { z as
|
|
22613
|
-
var RosterEntrySchema =
|
|
22614
|
-
roleID:
|
|
22615
|
-
agentName:
|
|
23140
|
+
import { z as z26 } from "zod";
|
|
23141
|
+
var RosterEntrySchema = z26.object({
|
|
23142
|
+
roleID: z26.string().min(1),
|
|
23143
|
+
agentName: z26.string().min(1)
|
|
22616
23144
|
}).strict();
|
|
22617
|
-
var RosterSchema =
|
|
22618
|
-
universe:
|
|
22619
|
-
entries:
|
|
23145
|
+
var RosterSchema = z26.object({
|
|
23146
|
+
universe: z26.string().min(1),
|
|
23147
|
+
entries: z26.array(RosterEntrySchema)
|
|
22620
23148
|
}).strict();
|
|
22621
23149
|
var ROSTER_JSON_FENCE = /```json\s*([\s\S]*?)```/;
|
|
22622
23150
|
|
|
@@ -23170,7 +23698,7 @@ import { readFile as readFile4 } from "node:fs/promises";
|
|
|
23170
23698
|
import { basename as basename4, dirname as dirname9 } from "node:path";
|
|
23171
23699
|
|
|
23172
23700
|
// src/graph/certificate.ts
|
|
23173
|
-
import { z as
|
|
23701
|
+
import { z as z27 } from "zod";
|
|
23174
23702
|
|
|
23175
23703
|
// src/contract/opencode.ts
|
|
23176
23704
|
var SUPPORTED_OPENCODE_VERSIONS = [
|
|
@@ -23211,7 +23739,7 @@ function isCertificateVersionCompatible(certifiedVersion, liveVersion) {
|
|
|
23211
23739
|
|
|
23212
23740
|
// src/graph/certificate.ts
|
|
23213
23741
|
var SHADOW_CERTIFICATE_MIN_RUNS = 1000;
|
|
23214
|
-
var DivergenceCodeSchema =
|
|
23742
|
+
var DivergenceCodeSchema = z27.enum([
|
|
23215
23743
|
"status",
|
|
23216
23744
|
"order",
|
|
23217
23745
|
"roles",
|
|
@@ -23219,50 +23747,50 @@ var DivergenceCodeSchema = z26.enum([
|
|
|
23219
23747
|
"fixes",
|
|
23220
23748
|
"outcome"
|
|
23221
23749
|
]);
|
|
23222
|
-
var ProvenanceSchema =
|
|
23750
|
+
var ProvenanceSchema = z27.enum([
|
|
23223
23751
|
"recomputed",
|
|
23224
23752
|
"compiled",
|
|
23225
23753
|
"validated",
|
|
23226
23754
|
"carried"
|
|
23227
23755
|
]);
|
|
23228
|
-
var EvidenceSchema =
|
|
23229
|
-
opencodeVersion:
|
|
23230
|
-
parity:
|
|
23231
|
-
runs:
|
|
23232
|
-
match:
|
|
23233
|
-
divergent:
|
|
23234
|
-
inconclusive:
|
|
23235
|
-
divergences:
|
|
23756
|
+
var EvidenceSchema = z27.object({
|
|
23757
|
+
opencodeVersion: z27.string().min(1),
|
|
23758
|
+
parity: z27.object({
|
|
23759
|
+
runs: z27.number().int().nonnegative(),
|
|
23760
|
+
match: z27.number().int().nonnegative(),
|
|
23761
|
+
divergent: z27.number().int().nonnegative(),
|
|
23762
|
+
inconclusive: z27.number().int().nonnegative(),
|
|
23763
|
+
divergences: z27.array(DivergenceCodeSchema)
|
|
23236
23764
|
}).strict(),
|
|
23237
|
-
legacy:
|
|
23238
|
-
observed:
|
|
23239
|
-
duplicated:
|
|
23765
|
+
legacy: z27.object({
|
|
23766
|
+
observed: z27.number().int().nonnegative(),
|
|
23767
|
+
duplicated: z27.number().int().nonnegative()
|
|
23240
23768
|
}).strict(),
|
|
23241
|
-
privacy:
|
|
23242
|
-
surfacesScanned:
|
|
23243
|
-
rawFindings:
|
|
23769
|
+
privacy: z27.object({
|
|
23770
|
+
surfacesScanned: z27.number().int().nonnegative(),
|
|
23771
|
+
rawFindings: z27.number().int().nonnegative()
|
|
23244
23772
|
}).strict(),
|
|
23245
|
-
overhead:
|
|
23246
|
-
p95Millis:
|
|
23247
|
-
budgetMillis:
|
|
23248
|
-
samples:
|
|
23773
|
+
overhead: z27.object({
|
|
23774
|
+
p95Millis: z27.number().nonnegative(),
|
|
23775
|
+
budgetMillis: z27.number().positive(),
|
|
23776
|
+
samples: z27.number().int().nonnegative()
|
|
23249
23777
|
}).strict(),
|
|
23250
|
-
provenance:
|
|
23778
|
+
provenance: z27.record(DivergenceCodeSchema, ProvenanceSchema)
|
|
23251
23779
|
}).strict();
|
|
23252
|
-
var CertificateSchema =
|
|
23253
|
-
version:
|
|
23254
|
-
certificate:
|
|
23255
|
-
opencodeVersion:
|
|
23780
|
+
var CertificateSchema = z27.object({
|
|
23781
|
+
version: z27.literal(1),
|
|
23782
|
+
certificate: z27.literal("graph-shadow"),
|
|
23783
|
+
opencodeVersion: z27.string().min(1),
|
|
23256
23784
|
evidence: EvidenceSchema,
|
|
23257
|
-
verdict:
|
|
23258
|
-
failedGates:
|
|
23785
|
+
verdict: z27.enum(["pass", "fail"]),
|
|
23786
|
+
failedGates: z27.array(z27.enum([
|
|
23259
23787
|
"sample",
|
|
23260
23788
|
"parity",
|
|
23261
23789
|
"one-legacy-execution",
|
|
23262
23790
|
"privacy",
|
|
23263
23791
|
"overhead"
|
|
23264
23792
|
])),
|
|
23265
|
-
digest:
|
|
23793
|
+
digest: z27.string().regex(/^[0-9a-f]{64}$/)
|
|
23266
23794
|
}).strict();
|
|
23267
23795
|
|
|
23268
23796
|
class ShadowCertificateError extends Error {
|
|
@@ -23377,37 +23905,37 @@ function parseShadowCertificate(value, opencodeVersion) {
|
|
|
23377
23905
|
}
|
|
23378
23906
|
return certificate;
|
|
23379
23907
|
}
|
|
23380
|
-
var ReleaseDeterminismSchema =
|
|
23381
|
-
var ReleaseCrashRecoverySchema =
|
|
23382
|
-
scenarios:
|
|
23383
|
-
allConverge:
|
|
23908
|
+
var ReleaseDeterminismSchema = z27.object({ runs: z27.number().int().nonnegative(), allMatch: z27.boolean() }).strict();
|
|
23909
|
+
var ReleaseCrashRecoverySchema = z27.object({
|
|
23910
|
+
scenarios: z27.number().int().nonnegative(),
|
|
23911
|
+
allConverge: z27.boolean()
|
|
23384
23912
|
}).strict();
|
|
23385
|
-
var ReleaseReplayEquivalenceSchema =
|
|
23386
|
-
checks:
|
|
23387
|
-
allEquivalent:
|
|
23913
|
+
var ReleaseReplayEquivalenceSchema = z27.object({
|
|
23914
|
+
checks: z27.number().int().nonnegative(),
|
|
23915
|
+
allEquivalent: z27.boolean()
|
|
23388
23916
|
}).strict();
|
|
23389
|
-
var ReleasePrivacySchema =
|
|
23390
|
-
surfacesScanned:
|
|
23391
|
-
rawFindings:
|
|
23917
|
+
var ReleasePrivacySchema = z27.object({
|
|
23918
|
+
surfacesScanned: z27.number().int().nonnegative(),
|
|
23919
|
+
rawFindings: z27.number().int().nonnegative()
|
|
23392
23920
|
}).strict();
|
|
23393
|
-
var ReleaseContractSchema =
|
|
23394
|
-
roundTrips:
|
|
23395
|
-
allSettled:
|
|
23921
|
+
var ReleaseContractSchema = z27.object({
|
|
23922
|
+
roundTrips: z27.number().int().nonnegative(),
|
|
23923
|
+
allSettled: z27.boolean()
|
|
23396
23924
|
}).strict();
|
|
23397
|
-
var ReleaseHealthSchema =
|
|
23398
|
-
samples:
|
|
23399
|
-
bounded:
|
|
23400
|
-
idempotent:
|
|
23925
|
+
var ReleaseHealthSchema = z27.object({
|
|
23926
|
+
samples: z27.number().int().nonnegative(),
|
|
23927
|
+
bounded: z27.boolean(),
|
|
23928
|
+
idempotent: z27.boolean()
|
|
23401
23929
|
}).strict();
|
|
23402
|
-
var ReleasePerformanceSchema =
|
|
23403
|
-
p95Millis:
|
|
23404
|
-
budgetMillis:
|
|
23405
|
-
samples:
|
|
23930
|
+
var ReleasePerformanceSchema = z27.object({
|
|
23931
|
+
p95Millis: z27.number().nonnegative(),
|
|
23932
|
+
budgetMillis: z27.number().positive(),
|
|
23933
|
+
samples: z27.number().int().nonnegative()
|
|
23406
23934
|
}).strict();
|
|
23407
|
-
var ReleaseEvidenceSchema =
|
|
23408
|
-
opencodeVersion:
|
|
23409
|
-
platform:
|
|
23410
|
-
shadowCertificateDigest:
|
|
23935
|
+
var ReleaseEvidenceSchema = z27.object({
|
|
23936
|
+
opencodeVersion: z27.string().min(1),
|
|
23937
|
+
platform: z27.enum(["linux", "win32"]),
|
|
23938
|
+
shadowCertificateDigest: z27.string().regex(/^[0-9a-f]{64}$/),
|
|
23411
23939
|
determinism: ReleaseDeterminismSchema,
|
|
23412
23940
|
crashRecovery: ReleaseCrashRecoverySchema,
|
|
23413
23941
|
replayEquivalence: ReleaseReplayEquivalenceSchema,
|
|
@@ -23416,15 +23944,15 @@ var ReleaseEvidenceSchema = z26.object({
|
|
|
23416
23944
|
health: ReleaseHealthSchema,
|
|
23417
23945
|
performance: ReleasePerformanceSchema
|
|
23418
23946
|
}).strict();
|
|
23419
|
-
var ReleaseCertificateSchema =
|
|
23420
|
-
version:
|
|
23421
|
-
certificate:
|
|
23422
|
-
platform:
|
|
23423
|
-
opencodeVersion:
|
|
23424
|
-
shadowCertificateDigest:
|
|
23947
|
+
var ReleaseCertificateSchema = z27.object({
|
|
23948
|
+
version: z27.literal(2),
|
|
23949
|
+
certificate: z27.literal("graph-release"),
|
|
23950
|
+
platform: z27.enum(["linux", "win32"]),
|
|
23951
|
+
opencodeVersion: z27.string().min(1),
|
|
23952
|
+
shadowCertificateDigest: z27.string().regex(/^[0-9a-f]{64}$/),
|
|
23425
23953
|
evidence: ReleaseEvidenceSchema,
|
|
23426
|
-
verdict:
|
|
23427
|
-
failedGates:
|
|
23954
|
+
verdict: z27.enum(["pass", "fail"]),
|
|
23955
|
+
failedGates: z27.array(z27.enum([
|
|
23428
23956
|
"shadow-valid",
|
|
23429
23957
|
"determinism",
|
|
23430
23958
|
"crash-recovery",
|
|
@@ -23434,7 +23962,7 @@ var ReleaseCertificateSchema = z26.object({
|
|
|
23434
23962
|
"health",
|
|
23435
23963
|
"performance"
|
|
23436
23964
|
])),
|
|
23437
|
-
digest:
|
|
23965
|
+
digest: z27.string().regex(/^[0-9a-f]{64}$/)
|
|
23438
23966
|
}).strict();
|
|
23439
23967
|
|
|
23440
23968
|
class ReleaseCertificateError extends Error {
|
|
@@ -23562,7 +24090,7 @@ function parseReleaseCertificate(value, opencodeVersion, expectedShadowDigest) {
|
|
|
23562
24090
|
}
|
|
23563
24091
|
return certificate;
|
|
23564
24092
|
}
|
|
23565
|
-
var ShadowDivergenceCodeSchema =
|
|
24093
|
+
var ShadowDivergenceCodeSchema = z27.enum([
|
|
23566
24094
|
"status",
|
|
23567
24095
|
"order",
|
|
23568
24096
|
"roles",
|
|
@@ -23571,13 +24099,13 @@ var ShadowDivergenceCodeSchema = z26.enum([
|
|
|
23571
24099
|
"outcome"
|
|
23572
24100
|
]);
|
|
23573
24101
|
var RECOMPUTED_DIVERGENCE_CODES = ["fixes"];
|
|
23574
|
-
var RecomputedDivergenceCodeSchema =
|
|
23575
|
-
var SoakPolicySchema =
|
|
23576
|
-
minimumGenuineObservations:
|
|
23577
|
-
minimumDistinctDays:
|
|
23578
|
-
requireGenuineUsageOnAllPlatforms:
|
|
23579
|
-
supportedOpencodeVersions:
|
|
23580
|
-
criticalDivergenceCodes:
|
|
24102
|
+
var RecomputedDivergenceCodeSchema = z27.enum(RECOMPUTED_DIVERGENCE_CODES);
|
|
24103
|
+
var SoakPolicySchema = z27.object({
|
|
24104
|
+
minimumGenuineObservations: z27.number().int().positive(),
|
|
24105
|
+
minimumDistinctDays: z27.number().int().positive(),
|
|
24106
|
+
requireGenuineUsageOnAllPlatforms: z27.boolean(),
|
|
24107
|
+
supportedOpencodeVersions: z27.array(z27.string().min(1)).min(1),
|
|
24108
|
+
criticalDivergenceCodes: z27.array(RecomputedDivergenceCodeSchema).min(1)
|
|
23581
24109
|
}).strict();
|
|
23582
24110
|
var DEFAULT_SOAK_POLICY = {
|
|
23583
24111
|
minimumGenuineObservations: 100,
|
|
@@ -23586,46 +24114,46 @@ var DEFAULT_SOAK_POLICY = {
|
|
|
23586
24114
|
supportedOpencodeVersions: [...SUPPORTED_OPENCODE_VERSIONS],
|
|
23587
24115
|
criticalDivergenceCodes: ["fixes"]
|
|
23588
24116
|
};
|
|
23589
|
-
var SoakPlatformEnumSchema =
|
|
23590
|
-
var SoakPrivacyPairEvidenceSchema =
|
|
23591
|
-
surfacesScanned:
|
|
23592
|
-
rawFindings:
|
|
24117
|
+
var SoakPlatformEnumSchema = z27.enum(["linux", "win32", "darwin"]);
|
|
24118
|
+
var SoakPrivacyPairEvidenceSchema = z27.object({
|
|
24119
|
+
surfacesScanned: z27.number().int().nonnegative(),
|
|
24120
|
+
rawFindings: z27.number().int().nonnegative()
|
|
23593
24121
|
}).strict();
|
|
23594
|
-
var SoakDuplicateEffectPairEvidenceSchema =
|
|
23595
|
-
effectsExamined:
|
|
23596
|
-
duplicatesFound:
|
|
24122
|
+
var SoakDuplicateEffectPairEvidenceSchema = z27.object({
|
|
24123
|
+
effectsExamined: z27.number().int().nonnegative(),
|
|
24124
|
+
duplicatesFound: z27.number().int().nonnegative()
|
|
23597
24125
|
}).strict();
|
|
23598
|
-
var SoakModelVerificationPairEvidenceSchema =
|
|
23599
|
-
nodesChecked:
|
|
23600
|
-
unverified:
|
|
23601
|
-
mismatched:
|
|
24126
|
+
var SoakModelVerificationPairEvidenceSchema = z27.object({
|
|
24127
|
+
nodesChecked: z27.number().int().nonnegative(),
|
|
24128
|
+
unverified: z27.number().int().nonnegative(),
|
|
24129
|
+
mismatched: z27.number().int().nonnegative()
|
|
23602
24130
|
}).strict();
|
|
23603
|
-
var SoakEvidenceSchema =
|
|
23604
|
-
totalObservations:
|
|
23605
|
-
genuineUsageObservations:
|
|
23606
|
-
ciSyntheticObservations:
|
|
23607
|
-
recorderCount:
|
|
23608
|
-
ineligibleObservations:
|
|
23609
|
-
firstTimestamp:
|
|
23610
|
-
lastTimestamp:
|
|
23611
|
-
distinctDays:
|
|
23612
|
-
criticalDivergences:
|
|
24131
|
+
var SoakEvidenceSchema = z27.object({
|
|
24132
|
+
totalObservations: z27.number().int().nonnegative(),
|
|
24133
|
+
genuineUsageObservations: z27.number().int().nonnegative(),
|
|
24134
|
+
ciSyntheticObservations: z27.number().int().nonnegative(),
|
|
24135
|
+
recorderCount: z27.number().int().nonnegative(),
|
|
24136
|
+
ineligibleObservations: z27.number().int().nonnegative(),
|
|
24137
|
+
firstTimestamp: z27.string().datetime().nullable(),
|
|
24138
|
+
lastTimestamp: z27.string().datetime().nullable(),
|
|
24139
|
+
distinctDays: z27.number().int().nonnegative(),
|
|
24140
|
+
criticalDivergences: z27.number().int().nonnegative().nullable(),
|
|
23613
24141
|
privacy: SoakPrivacyPairEvidenceSchema.nullable(),
|
|
23614
24142
|
duplicateEffects: SoakDuplicateEffectPairEvidenceSchema.nullable(),
|
|
23615
24143
|
modelVerification: SoakModelVerificationPairEvidenceSchema.nullable(),
|
|
23616
|
-
platformsGenuine:
|
|
23617
|
-
platformsSynthetic:
|
|
23618
|
-
opencodeVersionsObserved:
|
|
23619
|
-
invalidChains:
|
|
24144
|
+
platformsGenuine: z27.array(SoakPlatformEnumSchema),
|
|
24145
|
+
platformsSynthetic: z27.array(SoakPlatformEnumSchema),
|
|
24146
|
+
opencodeVersionsObserved: z27.array(z27.string().min(1)),
|
|
24147
|
+
invalidChains: z27.number().int().nonnegative()
|
|
23620
24148
|
}).strict();
|
|
23621
|
-
var SoakCertificateSchema =
|
|
23622
|
-
version:
|
|
23623
|
-
certificate:
|
|
23624
|
-
trustBoundary:
|
|
24149
|
+
var SoakCertificateSchema = z27.object({
|
|
24150
|
+
version: z27.literal(1),
|
|
24151
|
+
certificate: z27.literal("graph-soak"),
|
|
24152
|
+
trustBoundary: z27.literal("contributors"),
|
|
23625
24153
|
policy: SoakPolicySchema,
|
|
23626
24154
|
evidence: SoakEvidenceSchema,
|
|
23627
|
-
verdict:
|
|
23628
|
-
failedGates:
|
|
24155
|
+
verdict: z27.enum(["pass", "fail"]),
|
|
24156
|
+
failedGates: z27.array(z27.enum([
|
|
23629
24157
|
"minimum-observations",
|
|
23630
24158
|
"minimum-duration",
|
|
23631
24159
|
"chain-integrity",
|
|
@@ -23636,8 +24164,8 @@ var SoakCertificateSchema = z26.object({
|
|
|
23636
24164
|
"os-diversity",
|
|
23637
24165
|
"opencode-pin"
|
|
23638
24166
|
])),
|
|
23639
|
-
ledgerDigest:
|
|
23640
|
-
digest:
|
|
24167
|
+
ledgerDigest: z27.string().regex(/^[0-9a-f]{64}$/),
|
|
24168
|
+
digest: z27.string().regex(/^[0-9a-f]{64}$/)
|
|
23641
24169
|
}).strict();
|
|
23642
24170
|
|
|
23643
24171
|
class SoakCertificateError extends Error {
|
|
@@ -24285,62 +24813,62 @@ var realCacheAdapter = {
|
|
|
24285
24813
|
};
|
|
24286
24814
|
|
|
24287
24815
|
// src/memory/types.ts
|
|
24288
|
-
import { z as
|
|
24816
|
+
import { z as z28 } from "zod";
|
|
24289
24817
|
var SHARED_OWNER_KEY = "*";
|
|
24290
|
-
var OwnerKeySchema =
|
|
24291
|
-
var MemoryKindSchema =
|
|
24292
|
-
var MemoryBaseSchema =
|
|
24293
|
-
id:
|
|
24818
|
+
var OwnerKeySchema = z28.string().min(1);
|
|
24819
|
+
var MemoryKindSchema = z28.enum(["fact", "preference", "entity"]);
|
|
24820
|
+
var MemoryBaseSchema = z28.object({
|
|
24821
|
+
id: z28.string().min(1),
|
|
24294
24822
|
ownerKey: OwnerKeySchema,
|
|
24295
|
-
confidence:
|
|
24296
|
-
validFrom:
|
|
24297
|
-
validUntil:
|
|
24298
|
-
createdAt:
|
|
24299
|
-
invalidatedAt:
|
|
24300
|
-
sourceHash:
|
|
24301
|
-
supersededBy:
|
|
24823
|
+
confidence: z28.number().min(0).max(1),
|
|
24824
|
+
validFrom: z28.number().finite(),
|
|
24825
|
+
validUntil: z28.number().finite().nullable().default(null),
|
|
24826
|
+
createdAt: z28.number().finite(),
|
|
24827
|
+
invalidatedAt: z28.number().finite().nullable().default(null),
|
|
24828
|
+
sourceHash: z28.string().min(1),
|
|
24829
|
+
supersededBy: z28.string().min(1).nullable().default(null)
|
|
24302
24830
|
}).strict();
|
|
24303
24831
|
var FactSchema = MemoryBaseSchema.extend({
|
|
24304
|
-
kind:
|
|
24305
|
-
subject:
|
|
24306
|
-
predicate:
|
|
24307
|
-
object:
|
|
24308
|
-
category:
|
|
24832
|
+
kind: z28.literal("fact"),
|
|
24833
|
+
subject: z28.string().min(1),
|
|
24834
|
+
predicate: z28.string().min(1),
|
|
24835
|
+
object: z28.string().min(1),
|
|
24836
|
+
category: z28.string().min(1).nullable().default(null)
|
|
24309
24837
|
});
|
|
24310
24838
|
var PreferenceSchema = MemoryBaseSchema.extend({
|
|
24311
|
-
kind:
|
|
24312
|
-
category:
|
|
24313
|
-
preference:
|
|
24314
|
-
context:
|
|
24315
|
-
lastAccessedAt:
|
|
24316
|
-
accessCount:
|
|
24839
|
+
kind: z28.literal("preference"),
|
|
24840
|
+
category: z28.string().min(1),
|
|
24841
|
+
preference: z28.string().min(1),
|
|
24842
|
+
context: z28.string().min(1).nullable().default(null),
|
|
24843
|
+
lastAccessedAt: z28.number().finite().nullable().default(null),
|
|
24844
|
+
accessCount: z28.number().int().min(0).default(0)
|
|
24317
24845
|
});
|
|
24318
24846
|
var EntitySchema = MemoryBaseSchema.extend({
|
|
24319
|
-
kind:
|
|
24320
|
-
canonicalName:
|
|
24321
|
-
type:
|
|
24322
|
-
aliases:
|
|
24847
|
+
kind: z28.literal("entity"),
|
|
24848
|
+
canonicalName: z28.string().min(1),
|
|
24849
|
+
type: z28.string().min(1),
|
|
24850
|
+
aliases: z28.array(z28.string().min(1)).default([])
|
|
24323
24851
|
});
|
|
24324
24852
|
var RelationSchema = MemoryBaseSchema.extend({
|
|
24325
|
-
kind:
|
|
24326
|
-
from:
|
|
24327
|
-
to:
|
|
24328
|
-
predicate:
|
|
24329
|
-
annotation:
|
|
24853
|
+
kind: z28.literal("relation"),
|
|
24854
|
+
from: z28.string().min(1),
|
|
24855
|
+
to: z28.string().min(1),
|
|
24856
|
+
predicate: z28.string().min(1),
|
|
24857
|
+
annotation: z28.string().min(1).nullable().default(null)
|
|
24330
24858
|
});
|
|
24331
|
-
var MemoryRecordSchema =
|
|
24859
|
+
var MemoryRecordSchema = z28.discriminatedUnion("kind", [
|
|
24332
24860
|
FactSchema,
|
|
24333
24861
|
PreferenceSchema,
|
|
24334
24862
|
EntitySchema,
|
|
24335
24863
|
RelationSchema
|
|
24336
24864
|
]);
|
|
24337
|
-
var RecallQuerySchema =
|
|
24865
|
+
var RecallQuerySchema = z28.object({
|
|
24338
24866
|
ownerKey: OwnerKeySchema,
|
|
24339
|
-
kinds:
|
|
24340
|
-
asOf:
|
|
24341
|
-
limit:
|
|
24342
|
-
minSimilarity:
|
|
24343
|
-
includeShared:
|
|
24867
|
+
kinds: z28.array(MemoryKindSchema).default(["fact", "preference", "entity"]),
|
|
24868
|
+
asOf: z28.number().finite().nullable().default(null),
|
|
24869
|
+
limit: z28.number().int().positive().default(8),
|
|
24870
|
+
minSimilarity: z28.number().min(0).max(1).default(0.2),
|
|
24871
|
+
includeShared: z28.boolean().default(true)
|
|
24344
24872
|
}).strict();
|
|
24345
24873
|
|
|
24346
24874
|
// src/memory/rank.ts
|