@evident-ai/cli 3.4.1-dev.1549524 → 3.4.1-dev.1856549
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +63 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1524,7 +1524,7 @@ function drainSessionDbRecoveryReport({
|
|
|
1524
1524
|
skippedLines++;
|
|
1525
1525
|
return [];
|
|
1526
1526
|
}
|
|
1527
|
-
return [value];
|
|
1527
|
+
return [{ ...value, replication_suspended: value.replication_suspended ?? false }];
|
|
1528
1528
|
} catch (error2) {
|
|
1529
1529
|
skippedLines++;
|
|
1530
1530
|
console.error(
|
|
@@ -1549,12 +1549,39 @@ function buildSessionDbRecoveryActivity(record) {
|
|
|
1549
1549
|
const level = record.severity === "warning" ? "warn" : record.severity === "error" ? "error" : null;
|
|
1550
1550
|
if (!level) return null;
|
|
1551
1551
|
const noVerifiedPoint = record.verified_restore_point ? ` The verified restore point is ${record.verified_restore_point}.` : " No verified restore point is known.";
|
|
1552
|
+
const replication = record.replication_suspended ? " This start is not backing up its new session history; restart after fixing the cause." : "";
|
|
1553
|
+
const giveupMessage = (() => {
|
|
1554
|
+
switch (record.reason) {
|
|
1555
|
+
case "restore_deadline_exceeded":
|
|
1556
|
+
return "The restore did not finish before this startup deadline. Earlier sessions are unavailable for this start; collect the SESSION-DB-RESTORE-TRUNCATED boot log before retrying.";
|
|
1557
|
+
case "restore_tool_unusable":
|
|
1558
|
+
case "classification_unrecognised":
|
|
1559
|
+
return "The restore or classification tool produced an unsupported result. Inspect the named boot marker or log and repair the runner image or bundle before restarting.";
|
|
1560
|
+
case "synchroniser_config_unevaluable":
|
|
1561
|
+
case "synchroniser_config_incomplete":
|
|
1562
|
+
return "The installed hook and synchroniser bundle could not agree on configuration. Inspect the named boot marker or log and repair the runner image or bundle before restarting.";
|
|
1563
|
+
case "synchroniser_config_unresolved":
|
|
1564
|
+
return "The synchroniser configuration could not be resolved. Inspect the preceding boot error and repair the identified runner image, bundle, or local environment before restarting.";
|
|
1565
|
+
case "litestream_config_unavailable":
|
|
1566
|
+
return "The local Litestream configuration could not be generated or written. Inspect the preceding boot error and repair the runner image, bundle, local environment, or write permissions before restarting.";
|
|
1567
|
+
case "classification_fatal":
|
|
1568
|
+
return "Session history could not be restored because backup setup could not be established. Inspect the named boot marker or log and repair the identified backup configuration or permissions.";
|
|
1569
|
+
default:
|
|
1570
|
+
return null;
|
|
1571
|
+
}
|
|
1572
|
+
})();
|
|
1573
|
+
if (giveupMessage)
|
|
1574
|
+
return {
|
|
1575
|
+
level,
|
|
1576
|
+
metadata: withoutContractFields(record),
|
|
1577
|
+
message: `${giveupMessage}${replication}`
|
|
1578
|
+
};
|
|
1552
1579
|
switch (record.outcome) {
|
|
1553
1580
|
case "fresh_session_db":
|
|
1554
1581
|
return {
|
|
1555
1582
|
level,
|
|
1556
1583
|
metadata: withoutContractFields(record),
|
|
1557
|
-
message: `This runner started with a fresh session database. Earlier sessions are unavailable, and queued conversation or session references from before this start may no longer resolve.${noVerifiedPoint} Review the runner's backup configuration before relying on restored session history
|
|
1584
|
+
message: `This runner started with a fresh session database. Earlier sessions are unavailable, and queued conversation or session references from before this start may no longer resolve.${noVerifiedPoint} Review the runner's backup configuration before relying on restored session history.${replication}`
|
|
1558
1585
|
};
|
|
1559
1586
|
case "restore_retried":
|
|
1560
1587
|
return {
|
|
@@ -1592,7 +1619,7 @@ function buildSessionDbRecoveryActivity(record) {
|
|
|
1592
1619
|
return {
|
|
1593
1620
|
level,
|
|
1594
1621
|
metadata: withoutContractFields(record),
|
|
1595
|
-
message:
|
|
1622
|
+
message: `This runner started without restoring session history because it could not verify where its session history is backed up. Nothing in the backup was changed; check the runner backup configuration and permissions.${replication}`
|
|
1596
1623
|
};
|
|
1597
1624
|
case "session_db_boot_refused":
|
|
1598
1625
|
return {
|
|
@@ -1632,7 +1659,7 @@ var STRING_OR_NULL_FIELDS = ["quarantine_destination", "verified_restore_point"]
|
|
|
1632
1659
|
function isSessionDbRecoveryRecord(value) {
|
|
1633
1660
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1634
1661
|
const record = value;
|
|
1635
|
-
return record.v === 1 && record.event === "session_db_recovery" && typeof record.at === "string" && STAGES.has(record.stage) && OUTCOMES.has(record.outcome) && SEVERITIES.has(record.severity) && typeof record.reason === "string" && NUMBER_FIELDS.every((field) => record[field] === null || Number.isInteger(record[field])) && STRING_OR_NULL_FIELDS.every(
|
|
1662
|
+
return record.v === 1 && record.event === "session_db_recovery" && typeof record.at === "string" && STAGES.has(record.stage) && OUTCOMES.has(record.outcome) && SEVERITIES.has(record.severity) && typeof record.reason === "string" && (record.replication_suspended === void 0 || typeof record.replication_suspended === "boolean") && NUMBER_FIELDS.every((field) => record[field] === null || Number.isInteger(record[field])) && STRING_OR_NULL_FIELDS.every(
|
|
1636
1663
|
(field) => record[field] === null || typeof record[field] === "string"
|
|
1637
1664
|
);
|
|
1638
1665
|
}
|
|
@@ -2208,6 +2235,7 @@ async function createOpenCodeSession(port, directory) {
|
|
|
2208
2235
|
return data.id;
|
|
2209
2236
|
}
|
|
2210
2237
|
async function getModelAttachmentCapability(port, model) {
|
|
2238
|
+
const { model: baseModel } = splitModelVariant(model);
|
|
2211
2239
|
try {
|
|
2212
2240
|
const res = await timedFetch(`${opencodeBase(port)}/config/providers`);
|
|
2213
2241
|
if (!res.ok) {
|
|
@@ -2224,9 +2252,9 @@ async function getModelAttachmentCapability(port, model) {
|
|
|
2224
2252
|
);
|
|
2225
2253
|
return null;
|
|
2226
2254
|
}
|
|
2227
|
-
const slash =
|
|
2228
|
-
const providerId = slash > 0 ?
|
|
2229
|
-
let modelId = slash > 0 ?
|
|
2255
|
+
const slash = baseModel ? baseModel.indexOf("/") : -1;
|
|
2256
|
+
const providerId = slash > 0 ? baseModel.slice(0, slash) : void 0;
|
|
2257
|
+
let modelId = slash > 0 ? baseModel.slice(slash + 1) : void 0;
|
|
2230
2258
|
const defaults2 = body?.default && typeof body.default === "object" ? body.default : void 0;
|
|
2231
2259
|
let provider = providerId ? providers.find((p) => p?.id === providerId) : void 0;
|
|
2232
2260
|
if (!provider && !providerId) {
|
|
@@ -2306,6 +2334,29 @@ async function buildFileParts(attachments, capable) {
|
|
|
2306
2334
|
}
|
|
2307
2335
|
return { parts, outcomes, capabilityUnknown };
|
|
2308
2336
|
}
|
|
2337
|
+
function splitModelVariant(raw) {
|
|
2338
|
+
const value = raw?.trim();
|
|
2339
|
+
if (!value) return {};
|
|
2340
|
+
const hashIndex = value.indexOf("#");
|
|
2341
|
+
if (hashIndex === -1) return { model: value };
|
|
2342
|
+
const model = value.slice(0, hashIndex).trim() || void 0;
|
|
2343
|
+
const variant = value.slice(hashIndex + 1).trim() || void 0;
|
|
2344
|
+
return { model, variant };
|
|
2345
|
+
}
|
|
2346
|
+
function applyModelOptions(body, options) {
|
|
2347
|
+
if (options?.agent) body.agent = options.agent;
|
|
2348
|
+
const { model, variant } = splitModelVariant(options?.model);
|
|
2349
|
+
if (model) {
|
|
2350
|
+
const slashIndex = model.indexOf("/");
|
|
2351
|
+
if (slashIndex !== -1) {
|
|
2352
|
+
body.model = {
|
|
2353
|
+
providerID: model.substring(0, slashIndex),
|
|
2354
|
+
modelID: model.substring(slashIndex + 1)
|
|
2355
|
+
};
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
if (variant) body.variant = variant;
|
|
2359
|
+
}
|
|
2309
2360
|
function messageText(m) {
|
|
2310
2361
|
if (!m || !Array.isArray(m.parts)) return "";
|
|
2311
2362
|
return m.parts.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
|
|
@@ -2330,18 +2381,7 @@ async function sendPromptAsync(port, sessionId, content, options, attachments) {
|
|
|
2330
2381
|
const body = {
|
|
2331
2382
|
parts
|
|
2332
2383
|
};
|
|
2333
|
-
|
|
2334
|
-
body.agent = options.agent;
|
|
2335
|
-
}
|
|
2336
|
-
if (options?.model) {
|
|
2337
|
-
const slashIndex = options.model.indexOf("/");
|
|
2338
|
-
if (slashIndex !== -1) {
|
|
2339
|
-
body.model = {
|
|
2340
|
-
providerID: options.model.substring(0, slashIndex),
|
|
2341
|
-
modelID: options.model.substring(slashIndex + 1)
|
|
2342
|
-
};
|
|
2343
|
-
}
|
|
2344
|
-
}
|
|
2384
|
+
applyModelOptions(body, options);
|
|
2345
2385
|
const res = await timedFetch(`${opencodeBase(port)}/session/${sessionId}/prompt_async`, {
|
|
2346
2386
|
method: "POST",
|
|
2347
2387
|
headers: { "Content-Type": "application/json" },
|
|
@@ -2349,7 +2389,10 @@ async function sendPromptAsync(port, sessionId, content, options, attachments) {
|
|
|
2349
2389
|
});
|
|
2350
2390
|
if (res.status < 200 || res.status >= 300) {
|
|
2351
2391
|
const text = await res.text().catch(() => "");
|
|
2352
|
-
|
|
2392
|
+
const { variant } = splitModelVariant(options?.model);
|
|
2393
|
+
throw new Error(
|
|
2394
|
+
`OpenCode prompt_async failed: HTTP ${res.status}${text ? `: ${text}` : ""}${variant ? ` (variant: ${variant})` : ""}`
|
|
2395
|
+
);
|
|
2353
2396
|
}
|
|
2354
2397
|
const READ_BACK_ATTEMPTS = 5;
|
|
2355
2398
|
const READ_BACK_DELAY_MS = 150;
|