@codexhost/cli-win32-arm64 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/THIRD_PARTY_NOTICES.txt +8 -0
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +232 -21
- package/app/console-web.js +5434 -1092
- package/app/desktop-controller.mjs +252 -41
- package/app/host-runtime.mjs +5318 -1448
- package/app/plugins/antigravity/manifest.json +18 -1
- package/app/plugins/antigravity/plugin.mjs +276 -42
- package/app/plugins/claude-code/manifest.json +28 -0
- package/app/plugins/claude-code/plugin.mjs +1049 -359
- package/app/plugins/codebuddy/manifest.json +17 -0
- package/app/plugins/codebuddy/plugin.mjs +5931 -5358
- package/app/plugins/codex-usage/manifest.json +9 -0
- package/app/plugins/codex-usage/plugin.mjs +16703 -0
- package/app/plugins/cursor-cli/manifest.json +17 -0
- package/app/plugins/cursor-cli/plugin.mjs +351 -77
- package/app/plugins/deepseek-harness/assets/icon.svg +1 -0
- package/app/plugins/deepseek-harness/manifest.json +35 -2
- package/app/plugins/deepseek-harness/plugin.mjs +798 -242
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/manifest.json +21 -1
- package/app/plugins/grok/plugin.mjs +884 -259
- package/app/plugins/hermes/assets/icon.png +0 -0
- package/app/plugins/hermes/manifest.json +30 -2
- package/app/plugins/hermes/plugin.mjs +278 -33
- package/app/plugins/kimi-code/assets/icon.svg +5 -0
- package/app/plugins/kimi-code/manifest.json +25 -2
- package/app/plugins/kimi-code/plugin.mjs +555 -36
- package/app/plugins/kiro-cli/assets/kiro-agent.svg +11 -0
- package/app/plugins/kiro-cli/manifest.json +18 -1
- package/app/plugins/kiro-cli/plugin.mjs +284 -22
- package/app/plugins/omp/manifest.json +21 -1
- package/app/plugins/omp/plugin.mjs +2737 -1956
- package/app/plugins/opencode/manifest.json +18 -1
- package/app/plugins/opencode/plugin.mjs +694 -147
- package/app/plugins/pi/manifest.json +32 -0
- package/app/plugins/pi/plugin.mjs +2809 -2254
- package/app/plugins/qoder/manifest.json +18 -1
- package/app/plugins/qoder/plugin.mjs +585 -81
- package/app/plugins/qoder-cn/manifest.json +18 -1
- package/app/plugins/qoder-cn/plugin.mjs +585 -81
- package/app/plugins/workbuddy/manifest.json +18 -0
- package/app/plugins/workbuddy/plugin.mjs +6317 -5746
- package/app/plugins/zcode/manifest.json +19 -1
- package/app/plugins/zcode/plugin.mjs +1066 -260
- package/app/renderer-extension.js +1999 -1686
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/licenses/Cordis-LICENSE.txt +21 -0
- package/licenses/Cosmokit-LICENSE.txt +21 -0
- package/package.json +1 -1
- package/app/plugins/kiro-cli/assets/icon.svg +0 -5
|
@@ -396,7 +396,7 @@ async function npmInstallation(command, packages, environment) {
|
|
|
396
396
|
const npm = resolveHarnessExecutable({ id: "npm", command: "npm", installRoots: { posix: [], windows: [] } }, { environment: env });
|
|
397
397
|
let globalInstall = modules === globalRoot;
|
|
398
398
|
if (process.platform === "win32") {
|
|
399
|
-
const
|
|
399
|
+
const project2 = (await Promise.all(["package.json", "package-lock.json", "npm-shrinkwrap.json"].map((file2) => readFile(path4.join(prefix, file2), "utf8").then(() => true, (error51) => error51.code !== "ENOENT")))).some(Boolean);
|
|
400
400
|
const bins = typeof metadata.bin === "string" ? { [name.split("/").at(-1) ?? name]: metadata.bin } : metadata.bin ?? {};
|
|
401
401
|
const launchers = await Promise.all(Object.entries(bins).map(async ([bin, entry]) => {
|
|
402
402
|
if (path4.basename(bin) !== bin || entry.includes(".."))
|
|
@@ -407,7 +407,7 @@ async function npmInstallation(command, packages, environment) {
|
|
|
407
407
|
const shim = await readFile(path4.join(prefix, `${bin}.cmd`), "utf8").catch(() => "");
|
|
408
408
|
return referencesNpmBin(shim, name, entry);
|
|
409
409
|
}));
|
|
410
|
-
globalInstall = globalInstall && !
|
|
410
|
+
globalInstall = globalInstall && !project2 && launchers.some(Boolean);
|
|
411
411
|
}
|
|
412
412
|
const canUpdate = globalInstall && !!npm;
|
|
413
413
|
return {
|
|
@@ -487,10 +487,50 @@ function createHarnessInstaller(environment, source) {
|
|
|
487
487
|
};
|
|
488
488
|
}
|
|
489
489
|
|
|
490
|
-
// dist/
|
|
491
|
-
import
|
|
492
|
-
import
|
|
493
|
-
import
|
|
490
|
+
// dist/usage-statistics.js
|
|
491
|
+
import os2 from "node:os";
|
|
492
|
+
import path5 from "node:path";
|
|
493
|
+
import { lstat } from "node:fs/promises";
|
|
494
|
+
|
|
495
|
+
// ../../harness-adapter/dist/usage-statistics.js
|
|
496
|
+
var MAX_SESSION_ID_LENGTH = 512;
|
|
497
|
+
var MAX_CWD_LENGTH = 4096;
|
|
498
|
+
function sessionIdOk(value) {
|
|
499
|
+
return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
|
|
500
|
+
}
|
|
501
|
+
function cwdOk(value) {
|
|
502
|
+
return typeof value === "string" && value.length > 0 && value.length <= MAX_CWD_LENGTH && !value.includes("\0") && (value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value) || value.startsWith("\\\\"));
|
|
503
|
+
}
|
|
504
|
+
function withUsageSession(entry, session) {
|
|
505
|
+
const sessionId = sessionIdOk(session.sessionId) ? session.sessionId : void 0;
|
|
506
|
+
const cwd = cwdOk(session.cwd) ? session.cwd : void 0;
|
|
507
|
+
if (sessionId === void 0 && cwd === void 0)
|
|
508
|
+
return entry;
|
|
509
|
+
return {
|
|
510
|
+
...entry,
|
|
511
|
+
...sessionId !== void 0 ? { sessionId } : {},
|
|
512
|
+
...cwd !== void 0 ? { cwd } : {}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
function usageEntryFromRequest(request, occurredAtMs) {
|
|
516
|
+
if (!Number.isSafeInteger(occurredAtMs) || occurredAtMs <= 0)
|
|
517
|
+
return null;
|
|
518
|
+
return {
|
|
519
|
+
id: request.requestId,
|
|
520
|
+
occurredAtMs,
|
|
521
|
+
...request.model !== void 0 ? { model: request.model } : {},
|
|
522
|
+
inputTokens: request.inputTokens,
|
|
523
|
+
...request.cachedInputTokens !== void 0 ? { cachedInputTokens: request.cachedInputTokens } : {},
|
|
524
|
+
...request.cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens: request.cacheWriteInputTokens } : {},
|
|
525
|
+
...request.cacheWrite1hInputTokens !== void 0 ? { cacheWrite1hInputTokens: request.cacheWrite1hInputTokens } : {},
|
|
526
|
+
outputTokens: request.outputTokens,
|
|
527
|
+
...request.reasoningOutputTokens !== void 0 ? { reasoningOutputTokens: request.reasoningOutputTokens } : {}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
function nativeTimeMs(value) {
|
|
531
|
+
const time3 = typeof value === "number" ? value : typeof value === "string" ? Date.parse(value) : Number.NaN;
|
|
532
|
+
return Number.isFinite(time3) && time3 > 0 ? Math.floor(time3) : null;
|
|
533
|
+
}
|
|
494
534
|
|
|
495
535
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
496
536
|
var external_exports = {};
|
|
@@ -1258,10 +1298,10 @@ function mergeDefs(...defs) {
|
|
|
1258
1298
|
function cloneDef(schema) {
|
|
1259
1299
|
return mergeDefs(schema._zod.def);
|
|
1260
1300
|
}
|
|
1261
|
-
function getElementAtPath(obj,
|
|
1262
|
-
if (!
|
|
1301
|
+
function getElementAtPath(obj, path14) {
|
|
1302
|
+
if (!path14)
|
|
1263
1303
|
return obj;
|
|
1264
|
-
return
|
|
1304
|
+
return path14.reduce((acc, key) => acc?.[key], obj);
|
|
1265
1305
|
}
|
|
1266
1306
|
function promiseAllObject(promisesObj) {
|
|
1267
1307
|
const keys = Object.keys(promisesObj);
|
|
@@ -1670,11 +1710,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1670
1710
|
}
|
|
1671
1711
|
return false;
|
|
1672
1712
|
}
|
|
1673
|
-
function prefixIssues(
|
|
1713
|
+
function prefixIssues(path14, issues) {
|
|
1674
1714
|
return issues.map((iss) => {
|
|
1675
1715
|
var _a3;
|
|
1676
1716
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1677
|
-
iss.path.unshift(
|
|
1717
|
+
iss.path.unshift(path14);
|
|
1678
1718
|
return iss;
|
|
1679
1719
|
});
|
|
1680
1720
|
}
|
|
@@ -1821,16 +1861,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1821
1861
|
}
|
|
1822
1862
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1823
1863
|
const fieldErrors = { _errors: [] };
|
|
1824
|
-
const processError = (error52,
|
|
1864
|
+
const processError = (error52, path14 = []) => {
|
|
1825
1865
|
for (const issue2 of error52.issues) {
|
|
1826
1866
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1827
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1867
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1828
1868
|
} else if (issue2.code === "invalid_key") {
|
|
1829
|
-
processError({ issues: issue2.issues }, [...
|
|
1869
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1830
1870
|
} else if (issue2.code === "invalid_element") {
|
|
1831
|
-
processError({ issues: issue2.issues }, [...
|
|
1871
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1832
1872
|
} else {
|
|
1833
|
-
const fullpath = [...
|
|
1873
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1834
1874
|
if (fullpath.length === 0) {
|
|
1835
1875
|
fieldErrors._errors.push(mapper(issue2));
|
|
1836
1876
|
} else {
|
|
@@ -1857,17 +1897,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1857
1897
|
}
|
|
1858
1898
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1859
1899
|
const result = { errors: [] };
|
|
1860
|
-
const processError = (error52,
|
|
1900
|
+
const processError = (error52, path14 = []) => {
|
|
1861
1901
|
var _a3, _b;
|
|
1862
1902
|
for (const issue2 of error52.issues) {
|
|
1863
1903
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1864
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1904
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1865
1905
|
} else if (issue2.code === "invalid_key") {
|
|
1866
|
-
processError({ issues: issue2.issues }, [...
|
|
1906
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1867
1907
|
} else if (issue2.code === "invalid_element") {
|
|
1868
|
-
processError({ issues: issue2.issues }, [...
|
|
1908
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1869
1909
|
} else {
|
|
1870
|
-
const fullpath = [...
|
|
1910
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1871
1911
|
if (fullpath.length === 0) {
|
|
1872
1912
|
result.errors.push(mapper(issue2));
|
|
1873
1913
|
continue;
|
|
@@ -1899,8 +1939,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1899
1939
|
}
|
|
1900
1940
|
function toDotPath(_path) {
|
|
1901
1941
|
const segs = [];
|
|
1902
|
-
const
|
|
1903
|
-
for (const seg of
|
|
1942
|
+
const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1943
|
+
for (const seg of path14) {
|
|
1904
1944
|
if (typeof seg === "number")
|
|
1905
1945
|
segs.push(`[${seg}]`);
|
|
1906
1946
|
else if (typeof seg === "symbol")
|
|
@@ -5128,8 +5168,8 @@ function az_default() {
|
|
|
5128
5168
|
}
|
|
5129
5169
|
|
|
5130
5170
|
// ../../../node_modules/zod/v4/locales/be.js
|
|
5131
|
-
function getBelarusianPlural(
|
|
5132
|
-
const absCount = Math.abs(
|
|
5171
|
+
function getBelarusianPlural(count2, one, few, many) {
|
|
5172
|
+
const absCount = Math.abs(count2);
|
|
5133
5173
|
const lastDigit = absCount % 10;
|
|
5134
5174
|
const lastTwoDigits = absCount % 100;
|
|
5135
5175
|
if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
|
|
@@ -7207,8 +7247,8 @@ function hu_default() {
|
|
|
7207
7247
|
}
|
|
7208
7248
|
|
|
7209
7249
|
// ../../../node_modules/zod/v4/locales/hy.js
|
|
7210
|
-
function getArmenianPlural(
|
|
7211
|
-
return Math.abs(
|
|
7250
|
+
function getArmenianPlural(count2, one, many) {
|
|
7251
|
+
return Math.abs(count2) === 1 ? one : many;
|
|
7212
7252
|
}
|
|
7213
7253
|
function withDefiniteArticle(word) {
|
|
7214
7254
|
if (!word)
|
|
@@ -9336,8 +9376,8 @@ function ro_default() {
|
|
|
9336
9376
|
}
|
|
9337
9377
|
|
|
9338
9378
|
// ../../../node_modules/zod/v4/locales/ru.js
|
|
9339
|
-
function getRussianPlural(
|
|
9340
|
-
const absCount = Math.abs(
|
|
9379
|
+
function getRussianPlural(count2, one, few, many) {
|
|
9380
|
+
const absCount = Math.abs(count2);
|
|
9341
9381
|
const lastDigit = absCount % 10;
|
|
9342
9382
|
const lastTwoDigits = absCount % 100;
|
|
9343
9383
|
if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
|
|
@@ -14592,13 +14632,13 @@ function resolveRef(ref, ctx) {
|
|
|
14592
14632
|
if (!ref.startsWith("#")) {
|
|
14593
14633
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14594
14634
|
}
|
|
14595
|
-
const
|
|
14596
|
-
if (
|
|
14635
|
+
const path14 = ref.slice(1).split("/").filter(Boolean);
|
|
14636
|
+
if (path14.length === 0) {
|
|
14597
14637
|
return ctx.rootSchema;
|
|
14598
14638
|
}
|
|
14599
14639
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14600
|
-
if (
|
|
14601
|
-
const key =
|
|
14640
|
+
if (path14[0] === defsKey) {
|
|
14641
|
+
const key = path14[1];
|
|
14602
14642
|
if (!key || !ctx.defs[key]) {
|
|
14603
14643
|
throw new Error(`Reference not found: ${ref}`);
|
|
14604
14644
|
}
|
|
@@ -15006,6 +15046,15 @@ function date4(params) {
|
|
|
15006
15046
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15007
15047
|
config(en_default());
|
|
15008
15048
|
|
|
15049
|
+
// ../../shared-contracts/dist/delegation-read.js
|
|
15050
|
+
var REMOTE_THREAD_REPLY_MAX_BYTES = 16 * 1024 * 1024;
|
|
15051
|
+
var delegationReadParamsSchema = external_exports.strictObject({
|
|
15052
|
+
threadId: external_exports.string().min(1).max(1024),
|
|
15053
|
+
view: external_exports.enum(["result", "messages"]),
|
|
15054
|
+
cursor: external_exports.string().min(1).max(8192).optional(),
|
|
15055
|
+
limit: external_exports.number().int().min(1).max(100).optional()
|
|
15056
|
+
});
|
|
15057
|
+
|
|
15009
15058
|
// ../../shared-contracts/dist/credential-imports.js
|
|
15010
15059
|
var credentialSourceSchema = external_exports.object({
|
|
15011
15060
|
id: external_exports.string().min(1).max(256),
|
|
@@ -15076,6 +15125,153 @@ var harnessDisplaySetSchema = external_exports.strictObject({
|
|
|
15076
15125
|
initializeOnly: external_exports.boolean().optional()
|
|
15077
15126
|
});
|
|
15078
15127
|
|
|
15128
|
+
// ../../shared-contracts/dist/model-price-overrides.js
|
|
15129
|
+
var usdPerMillionTokens = external_exports.number().finite().nonnegative();
|
|
15130
|
+
var modelPriceOverrideSchema = external_exports.strictObject({
|
|
15131
|
+
input: usdPerMillionTokens,
|
|
15132
|
+
output: usdPerMillionTokens,
|
|
15133
|
+
cacheRead: usdPerMillionTokens.optional(),
|
|
15134
|
+
cacheWrite: usdPerMillionTokens.optional(),
|
|
15135
|
+
cacheWrite1h: usdPerMillionTokens.optional()
|
|
15136
|
+
});
|
|
15137
|
+
var modelPriceKeySchema = external_exports.string().max(512).refine((key) => key.trim() === key && key.length > 0, "Model ID is required");
|
|
15138
|
+
var modelPriceOverridesSchema = external_exports.strictObject({
|
|
15139
|
+
/** Absolute path of the Host's `pricing.json`. */
|
|
15140
|
+
path: external_exports.string(),
|
|
15141
|
+
entries: external_exports.array(external_exports.strictObject({ key: external_exports.string(), price: modelPriceOverrideSchema })),
|
|
15142
|
+
/** Why the existing file is unusable; the Host then ignores it and refuses to overwrite it. */
|
|
15143
|
+
error: external_exports.string().nullable()
|
|
15144
|
+
});
|
|
15145
|
+
var modelPriceOverridesGetSchema = external_exports.strictObject({});
|
|
15146
|
+
var modelPriceOverridesSetSchema = external_exports.strictObject({
|
|
15147
|
+
key: modelPriceKeySchema,
|
|
15148
|
+
price: modelPriceOverrideSchema.nullable(),
|
|
15149
|
+
previousKey: modelPriceKeySchema.optional()
|
|
15150
|
+
});
|
|
15151
|
+
var modelPriceDefaultParamsSchema = external_exports.strictObject({
|
|
15152
|
+
model: modelPriceKeySchema
|
|
15153
|
+
});
|
|
15154
|
+
var modelPriceSuggestionSchema = external_exports.strictObject({
|
|
15155
|
+
/** Verified from catalog canonical links, not inferred from names or equal prices. */
|
|
15156
|
+
official: external_exports.boolean().optional(),
|
|
15157
|
+
canonicalModelId: external_exports.string().min(1).optional(),
|
|
15158
|
+
provider: external_exports.string().min(1).max(512),
|
|
15159
|
+
model: external_exports.string().min(1).max(512),
|
|
15160
|
+
price: modelPriceOverrideSchema
|
|
15161
|
+
});
|
|
15162
|
+
var modelPriceDefaultResultSchema = external_exports.strictObject({
|
|
15163
|
+
price: modelPriceOverrideSchema.nullable(),
|
|
15164
|
+
/** Local catalog suggestions only; never used automatically for pricing. */
|
|
15165
|
+
suggestions: external_exports.array(modelPriceSuggestionSchema).max(6).optional()
|
|
15166
|
+
});
|
|
15167
|
+
|
|
15168
|
+
// ../../shared-contracts/dist/usage-statistics.js
|
|
15169
|
+
var USAGE_STATISTICS_RANGES = ["today", "7d", "30d", "90d", "all"];
|
|
15170
|
+
var count = external_exports.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
|
|
15171
|
+
var localDate = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/u);
|
|
15172
|
+
var harness = external_exports.string().min(1).max(128);
|
|
15173
|
+
var model = external_exports.string().min(1).max(512);
|
|
15174
|
+
var project = external_exports.string().min(1).max(4096);
|
|
15175
|
+
var usageStatisticsParamsSchema = external_exports.strictObject({
|
|
15176
|
+
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
15177
|
+
harness: harness.optional(),
|
|
15178
|
+
model: model.nullable().optional(),
|
|
15179
|
+
project: project.nullable().optional(),
|
|
15180
|
+
/** One local date inside the range. */
|
|
15181
|
+
date: localDate.optional()
|
|
15182
|
+
});
|
|
15183
|
+
var usageStatisticsTotalsSchema = external_exports.strictObject({
|
|
15184
|
+
requests: count,
|
|
15185
|
+
inputTokens: count,
|
|
15186
|
+
cachedInputTokens: count,
|
|
15187
|
+
cacheWriteInputTokens: count,
|
|
15188
|
+
cacheKnownInputTokens: count,
|
|
15189
|
+
outputTokens: count,
|
|
15190
|
+
reasoningOutputTokens: count,
|
|
15191
|
+
/** USD at the public price, summed over the priced requests only. */
|
|
15192
|
+
costUsd: external_exports.number().finite().min(0),
|
|
15193
|
+
/** Requests without a price (or the cache data the price needs); not in `costUsd`. */
|
|
15194
|
+
unpricedRequests: count,
|
|
15195
|
+
/**
|
|
15196
|
+
* Requests whose storage gave no token counts: counted as requests, with neither tokens nor
|
|
15197
|
+
* cost, and not as unpriced.
|
|
15198
|
+
*/
|
|
15199
|
+
unmeteredRequests: count
|
|
15200
|
+
});
|
|
15201
|
+
var totals = usageStatisticsTotalsSchema.shape;
|
|
15202
|
+
var usageStatisticsSessionSchema = external_exports.strictObject({
|
|
15203
|
+
harness,
|
|
15204
|
+
sessionId: external_exports.string().min(1).max(512),
|
|
15205
|
+
project: project.nullable(),
|
|
15206
|
+
/** Models the session used, most requests first. */
|
|
15207
|
+
models: external_exports.array(model).max(16),
|
|
15208
|
+
firstAtMs: count,
|
|
15209
|
+
lastAtMs: count,
|
|
15210
|
+
...totals
|
|
15211
|
+
});
|
|
15212
|
+
var usageStatisticsResultSchema = external_exports.strictObject({
|
|
15213
|
+
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
15214
|
+
/** First local date of the range; null for all time. */
|
|
15215
|
+
from: localDate.nullable(),
|
|
15216
|
+
to: localDate,
|
|
15217
|
+
/** The filters these figures apply, echoed so a late answer to older filters is recognised. */
|
|
15218
|
+
filters: external_exports.strictObject({
|
|
15219
|
+
harness: harness.nullable(),
|
|
15220
|
+
model: model.nullable(),
|
|
15221
|
+
unknownModel: external_exports.boolean(),
|
|
15222
|
+
project: project.nullable(),
|
|
15223
|
+
unknownProject: external_exports.boolean(),
|
|
15224
|
+
date: localDate.nullable()
|
|
15225
|
+
}),
|
|
15226
|
+
/** Reading of native storage: incomplete while the first read, or a refresh, is under way. */
|
|
15227
|
+
reading: external_exports.strictObject({ complete: external_exports.boolean(), sources: count, read: count }),
|
|
15228
|
+
/** Harnesses whose storage could not be read; their part is missing, the rest is complete. */
|
|
15229
|
+
failures: external_exports.array(external_exports.strictObject({ harness, message: external_exports.string().max(2048) })).max(256),
|
|
15230
|
+
/** Every value seen in the range, ignoring the filters, to choose filters from. */
|
|
15231
|
+
options: external_exports.strictObject({
|
|
15232
|
+
harnesses: external_exports.array(harness).max(256),
|
|
15233
|
+
models: external_exports.array(model.nullable()).max(4096),
|
|
15234
|
+
projects: external_exports.array(project.nullable()).max(4096)
|
|
15235
|
+
}),
|
|
15236
|
+
/** Current display metadata, scoped by Harness. Never a pricing or filter identity.
|
|
15237
|
+
* Optional for older Hosts; missing/conflicting labels fall back to the native model ID.
|
|
15238
|
+
*/
|
|
15239
|
+
modelLabels: external_exports.array(external_exports.strictObject({ harness, model, label: model })).max(4096).optional(),
|
|
15240
|
+
/** Native credits, all filters applied, never combined across Harnesses or treated as USD.
|
|
15241
|
+
* Only groups with at least one reported value appear; reportedRequests exposes partial data.
|
|
15242
|
+
*/
|
|
15243
|
+
credits: external_exports.array(external_exports.strictObject({
|
|
15244
|
+
harness,
|
|
15245
|
+
model: model.nullable(),
|
|
15246
|
+
credits: external_exports.number().finite().min(0),
|
|
15247
|
+
reportedRequests: count,
|
|
15248
|
+
requests: count
|
|
15249
|
+
})).max(4096).optional(),
|
|
15250
|
+
/** All filters applied. */
|
|
15251
|
+
totals: usageStatisticsTotalsSchema,
|
|
15252
|
+
/** Each date and Harness of the range: every filter except the day. */
|
|
15253
|
+
daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
|
|
15254
|
+
/** Local weekday (0 = Sunday) and hour, all filters applied. */
|
|
15255
|
+
hourly: external_exports.array(external_exports.strictObject({
|
|
15256
|
+
weekday: external_exports.number().int().min(0).max(6),
|
|
15257
|
+
hour: external_exports.number().int().min(0).max(23),
|
|
15258
|
+
...totals
|
|
15259
|
+
})).max(168),
|
|
15260
|
+
byHarness: external_exports.array(external_exports.strictObject({ harness, ...totals })).max(256),
|
|
15261
|
+
byModel: external_exports.array(external_exports.strictObject({
|
|
15262
|
+
model: model.nullable(),
|
|
15263
|
+
...totals,
|
|
15264
|
+
/** Requests priced by what the Harness recorded they cost, not by a price list. */
|
|
15265
|
+
harnessPricedRequests: count
|
|
15266
|
+
})).max(4096),
|
|
15267
|
+
byProject: external_exports.array(external_exports.strictObject({ project: project.nullable(), ...totals })).max(4096),
|
|
15268
|
+
/**
|
|
15269
|
+
* The sessions that spent the most, by cost and by tokens without cache, all filters applied;
|
|
15270
|
+
* requests without a native session are not listed here but count everywhere else.
|
|
15271
|
+
*/
|
|
15272
|
+
sessions: external_exports.array(usageStatisticsSessionSchema).max(100)
|
|
15273
|
+
});
|
|
15274
|
+
|
|
15079
15275
|
// ../../shared-contracts/dist/ids.js
|
|
15080
15276
|
var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
|
|
15081
15277
|
message: "Identifier must not be empty or whitespace"
|
|
@@ -15123,6 +15319,10 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
15123
15319
|
"codexhost/account/list",
|
|
15124
15320
|
"codexhost/account/refresh",
|
|
15125
15321
|
"codexhost/account/usage/inspect",
|
|
15322
|
+
"codexhost/usage/model-prices/get",
|
|
15323
|
+
"codexhost/usage/model-prices/set",
|
|
15324
|
+
"codexhost/usage/model-prices/default",
|
|
15325
|
+
"codexhost/usage/statistics/get",
|
|
15126
15326
|
"codexhost/update/check",
|
|
15127
15327
|
"codexhost/update/start",
|
|
15128
15328
|
"codexhost/update/status"
|
|
@@ -15187,6 +15387,7 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
15187
15387
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15188
15388
|
outputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15189
15389
|
outputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
|
|
15390
|
+
apiOutputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
|
|
15190
15391
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15191
15392
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15192
15393
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
@@ -15198,7 +15399,11 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
15198
15399
|
planFiveHourUsedPercent: cacheHitRatePercentSchema.optional(),
|
|
15199
15400
|
planFiveHourResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
|
|
15200
15401
|
planSevenDayUsedPercent: cacheHitRatePercentSchema.optional(),
|
|
15201
|
-
planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional()
|
|
15402
|
+
planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
|
|
15403
|
+
sessionCacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
15404
|
+
timeToFirstOutputMs: nonNegativeSafeIntegerSchema.optional(),
|
|
15405
|
+
costSource: external_exports.enum(["publicPrice", "native"]).optional(),
|
|
15406
|
+
unpricedModels: external_exports.array(external_exports.string().min(1)).min(1).optional()
|
|
15202
15407
|
}).strict().superRefine((usage, context) => {
|
|
15203
15408
|
if (Object.keys(usage).length === 0) {
|
|
15204
15409
|
context.addIssue({ code: "custom", message: "Thread Usage must contain a reliable field" });
|
|
@@ -15219,6 +15424,20 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
15219
15424
|
path: ["contextWindowTokens"]
|
|
15220
15425
|
});
|
|
15221
15426
|
}
|
|
15427
|
+
if (usage.costSource !== void 0 && usage.totalCostUsd === void 0) {
|
|
15428
|
+
context.addIssue({
|
|
15429
|
+
code: "custom",
|
|
15430
|
+
message: "Thread Usage costSource must be provided with totalCostUsd",
|
|
15431
|
+
path: ["costSource"]
|
|
15432
|
+
});
|
|
15433
|
+
}
|
|
15434
|
+
if (usage.unpricedModels !== void 0 && usage.costSource !== "publicPrice") {
|
|
15435
|
+
context.addIssue({
|
|
15436
|
+
code: "custom",
|
|
15437
|
+
message: "Thread Usage unpricedModels must be provided with a publicPrice cost",
|
|
15438
|
+
path: ["unpricedModels"]
|
|
15439
|
+
});
|
|
15440
|
+
}
|
|
15222
15441
|
if (usage.planFiveHourResetsAtUnix !== void 0 && usage.planFiveHourUsedPercent === void 0) {
|
|
15223
15442
|
context.addIssue({
|
|
15224
15443
|
code: "custom",
|
|
@@ -15473,27 +15692,27 @@ var harnessModelCatalogSchema = external_exports.object({
|
|
|
15473
15692
|
}).strict().superRefine((catalog, context) => {
|
|
15474
15693
|
const refs = /* @__PURE__ */ new Set();
|
|
15475
15694
|
const thinkingIds = new Set(catalog.thinkingOptions.map(({ id }) => id));
|
|
15476
|
-
for (const [index,
|
|
15477
|
-
if (refs.has(
|
|
15695
|
+
for (const [index, model2] of catalog.models.entries()) {
|
|
15696
|
+
if (refs.has(model2.ref.id)) {
|
|
15478
15697
|
context.addIssue({
|
|
15479
15698
|
code: "custom",
|
|
15480
15699
|
message: "Model Catalog refs must be unique",
|
|
15481
15700
|
path: ["models", index, "ref", "id"]
|
|
15482
15701
|
});
|
|
15483
15702
|
}
|
|
15484
|
-
refs.add(
|
|
15485
|
-
if (
|
|
15486
|
-
if (refs.has(
|
|
15703
|
+
refs.add(model2.ref.id);
|
|
15704
|
+
if (model2.fastModel) {
|
|
15705
|
+
if (refs.has(model2.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model2.fastModel?.id)) {
|
|
15487
15706
|
context.addIssue({
|
|
15488
15707
|
code: "custom",
|
|
15489
15708
|
message: "Fast Model refs must be distinct and unique",
|
|
15490
15709
|
path: ["models", index, "fastModel"]
|
|
15491
15710
|
});
|
|
15492
15711
|
}
|
|
15493
|
-
refs.add(
|
|
15712
|
+
refs.add(model2.fastModel.id);
|
|
15494
15713
|
}
|
|
15495
15714
|
const supportedThinkingIds = /* @__PURE__ */ new Set();
|
|
15496
|
-
for (const [optionIndex, optionId] of (
|
|
15715
|
+
for (const [optionIndex, optionId] of (model2.supportedThinkingOptionIds ?? []).entries()) {
|
|
15497
15716
|
if (supportedThinkingIds.has(optionId)) {
|
|
15498
15717
|
context.addIssue({
|
|
15499
15718
|
code: "custom",
|
|
@@ -15687,13 +15906,40 @@ var HARNESS_PLUGIN_LIMIT = 128;
|
|
|
15687
15906
|
var harnessPluginIdSchema = external_exports.string().min(1).max(128).regex(/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/u).refine((id) => id !== "codex", "The official Codex identity is reserved").pipe(harnessIdSchema);
|
|
15688
15907
|
var relativeResourceSchema = external_exports.string().min(1).max(512).refine((value) => !/[\\\u0000:#?]/u.test(value) && !value.startsWith("/") && !value.split("/").some((part) => part === ".." || part === ""), "Plugin resources must be relative paths inside the plugin");
|
|
15689
15908
|
var documentationUrlSchema = external_exports.url().refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Plugin documentation links must be credential-free HTTPS URLs");
|
|
15909
|
+
var localizedTextSchema = external_exports.object({ en: external_exports.string().max(4096), "zh-CN": external_exports.string().max(4096).optional() }).strict();
|
|
15910
|
+
var harnessInstallationGuideSchema = external_exports.object({
|
|
15911
|
+
commands: external_exports.array(external_exports.object({ terminal: external_exports.string().max(256), command: external_exports.string().max(4096) }).strict()).max(8),
|
|
15912
|
+
before: localizedTextSchema.optional(),
|
|
15913
|
+
after: localizedTextSchema.optional(),
|
|
15914
|
+
downloads: external_exports.array(external_exports.object({ label: external_exports.string().max(128), url: documentationUrlSchema }).strict()).max(8).optional()
|
|
15915
|
+
}).strict();
|
|
15690
15916
|
var pluginPresentationShape = {
|
|
15691
15917
|
id: harnessPluginIdSchema,
|
|
15692
15918
|
name: external_exports.string().trim().min(1).max(128),
|
|
15693
15919
|
version: external_exports.string().min(1).max(128),
|
|
15920
|
+
/** Capability-only plugin; omitted for existing session-capable plugins. */
|
|
15921
|
+
kind: external_exports.literal("usage").optional(),
|
|
15922
|
+
/** Original image styling or bounded vector paths; never arbitrary CSS/SVG markup. */
|
|
15923
|
+
iconStyle: external_exports.object({
|
|
15924
|
+
vector: external_exports.object({
|
|
15925
|
+
viewBox: external_exports.string().max(128).regex(/^-?\d+(?:\.\d+)?(?: +-?\d+(?:\.\d+)?){3}$/u),
|
|
15926
|
+
color: external_exports.string().regex(/^(?:currentColor|#[a-f0-9]{6})$/iu),
|
|
15927
|
+
paths: external_exports.array(external_exports.object({
|
|
15928
|
+
d: external_exports.string().min(1).max(32768).regex(/^[MmLlHhVvCcSsQqTtAaZz\d.,+eE\s-]+$/u),
|
|
15929
|
+
fillRule: external_exports.enum(["evenodd", "nonzero"]).optional(),
|
|
15930
|
+
fill: external_exports.string().regex(/^(?:currentColor|#[a-f0-9]{6})$/iu).optional()
|
|
15931
|
+
}).strict()).min(1).max(32)
|
|
15932
|
+
}).strict().optional(),
|
|
15933
|
+
background: external_exports.string().regex(/^#[a-f0-9]{6}$/iu).optional(),
|
|
15934
|
+
borderRadius: external_exports.number().min(0).max(50).optional(),
|
|
15935
|
+
paddingRatio: external_exports.number().min(0).max(0.25).optional()
|
|
15936
|
+
}).strict().optional(),
|
|
15937
|
+
installation: harnessInstallationGuideSchema.optional(),
|
|
15938
|
+
notice: localizedTextSchema.optional(),
|
|
15694
15939
|
/** The factory accepts a persisted local entrypoint through its construction context. */
|
|
15695
15940
|
launchCommand: external_exports.literal(true).optional(),
|
|
15696
15941
|
links: external_exports.object({
|
|
15942
|
+
website: documentationUrlSchema.optional(),
|
|
15697
15943
|
documentation: documentationUrlSchema.optional(),
|
|
15698
15944
|
installation: documentationUrlSchema.optional()
|
|
15699
15945
|
}).strict().optional()
|
|
@@ -16112,6 +16358,11 @@ var codexSshDraftSchema = external_exports.strictObject({
|
|
|
16112
16358
|
});
|
|
16113
16359
|
var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
|
|
16114
16360
|
external_exports.strictObject({ action: external_exports.literal("list") }),
|
|
16361
|
+
external_exports.strictObject({
|
|
16362
|
+
action: external_exports.literal("read-thread"),
|
|
16363
|
+
hostId: hostId.refine((id) => id !== "local"),
|
|
16364
|
+
input: delegationReadParamsSchema
|
|
16365
|
+
}),
|
|
16115
16366
|
external_exports.strictObject({
|
|
16116
16367
|
action: external_exports.literal("save"),
|
|
16117
16368
|
draft: codexSshDraftSchema,
|
|
@@ -16243,7 +16494,6 @@ var tokenFields = [
|
|
|
16243
16494
|
"cachedInputTokens",
|
|
16244
16495
|
"cacheWriteInputTokens",
|
|
16245
16496
|
"outputTokens",
|
|
16246
|
-
"outputTokensPerSecond",
|
|
16247
16497
|
"reasoningOutputTokens",
|
|
16248
16498
|
"totalTokens",
|
|
16249
16499
|
"contextWindowTokens",
|
|
@@ -16251,10 +16501,12 @@ var tokenFields = [
|
|
|
16251
16501
|
];
|
|
16252
16502
|
var safeIntegerFields = [
|
|
16253
16503
|
"planFiveHourResetsAtUnix",
|
|
16254
|
-
"planSevenDayResetsAtUnix"
|
|
16504
|
+
"planSevenDayResetsAtUnix",
|
|
16505
|
+
"timeToFirstOutputMs"
|
|
16255
16506
|
];
|
|
16256
16507
|
var percentFields = [
|
|
16257
16508
|
"cacheHitRatePercent",
|
|
16509
|
+
"sessionCacheHitRatePercent",
|
|
16258
16510
|
"planFiveHourUsedPercent",
|
|
16259
16511
|
"planSevenDayUsedPercent"
|
|
16260
16512
|
];
|
|
@@ -16262,9 +16514,14 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
16262
16514
|
...tokenFields,
|
|
16263
16515
|
...safeIntegerFields,
|
|
16264
16516
|
...percentFields,
|
|
16517
|
+
"sessionCacheUsage",
|
|
16265
16518
|
"totalCostUsd",
|
|
16266
16519
|
"totalCredits",
|
|
16267
|
-
"contextUsagePercent"
|
|
16520
|
+
"contextUsagePercent",
|
|
16521
|
+
"outputTokensPerSecond",
|
|
16522
|
+
"apiOutputTokensPerSecond",
|
|
16523
|
+
"costSource",
|
|
16524
|
+
"unpricedModels"
|
|
16268
16525
|
]);
|
|
16269
16526
|
function isRecord(value) {
|
|
16270
16527
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -16280,7 +16537,11 @@ function parseHostUsage(value) {
|
|
|
16280
16537
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
16281
16538
|
}
|
|
16282
16539
|
}
|
|
16283
|
-
for (const field of [
|
|
16540
|
+
for (const field of [
|
|
16541
|
+
"totalCredits",
|
|
16542
|
+
"contextUsagePercent",
|
|
16543
|
+
"apiOutputTokensPerSecond"
|
|
16544
|
+
]) {
|
|
16284
16545
|
const candidate2 = value[field];
|
|
16285
16546
|
if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isFinite(candidate2) || candidate2 < 0)) {
|
|
16286
16547
|
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
@@ -16310,6 +16571,12 @@ function parseHostUsage(value) {
|
|
|
16310
16571
|
throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
|
|
16311
16572
|
}
|
|
16312
16573
|
}
|
|
16574
|
+
if (value.sessionCacheUsage !== void 0) {
|
|
16575
|
+
const totals2 = value.sessionCacheUsage;
|
|
16576
|
+
if (!isRecord(totals2) || Object.keys(totals2).some((key) => key !== "inputTokens" && key !== "cachedInputTokens") || typeof totals2.inputTokens !== "number" || !Number.isSafeInteger(totals2.inputTokens) || totals2.inputTokens < 0 || typeof totals2.cachedInputTokens !== "number" || !Number.isSafeInteger(totals2.cachedInputTokens) || totals2.cachedInputTokens < 0 || totals2.cachedInputTokens > totals2.inputTokens) {
|
|
16577
|
+
throw new Error("Harness Usage 'sessionCacheUsage' must contain complete bounded token totals");
|
|
16578
|
+
}
|
|
16579
|
+
}
|
|
16313
16580
|
const hasContextUsed = value.contextUsedTokens !== void 0;
|
|
16314
16581
|
const hasContextWindow = value.contextWindowTokens !== void 0;
|
|
16315
16582
|
if (hasContextUsed !== hasContextWindow) {
|
|
@@ -16324,8 +16591,217 @@ function parseHostUsage(value) {
|
|
|
16324
16591
|
if (value.planSevenDayResetsAtUnix !== void 0 && value.planSevenDayUsedPercent === void 0) {
|
|
16325
16592
|
throw new Error("Harness Usage 'planSevenDayResetsAtUnix' must be provided with 'planSevenDayUsedPercent'");
|
|
16326
16593
|
}
|
|
16594
|
+
if (value.costSource !== void 0) {
|
|
16595
|
+
if (value.costSource !== "publicPrice" && value.costSource !== "native") {
|
|
16596
|
+
throw new Error("Harness Usage 'costSource' must be 'publicPrice' or 'native'");
|
|
16597
|
+
}
|
|
16598
|
+
if (value.totalCostUsd === void 0) {
|
|
16599
|
+
throw new Error("Harness Usage 'costSource' must be provided with 'totalCostUsd'");
|
|
16600
|
+
}
|
|
16601
|
+
}
|
|
16602
|
+
if (value.unpricedModels !== void 0) {
|
|
16603
|
+
const models = value.unpricedModels;
|
|
16604
|
+
if (!Array.isArray(models) || models.length === 0 || !models.every((model2) => typeof model2 === "string" && model2.length > 0)) {
|
|
16605
|
+
throw new Error("Harness Usage 'unpricedModels' must be a non-empty list of Model IDs");
|
|
16606
|
+
}
|
|
16607
|
+
if (value.costSource !== "publicPrice") {
|
|
16608
|
+
throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
|
|
16609
|
+
}
|
|
16610
|
+
return { ...value, unpricedModels: [...models] };
|
|
16611
|
+
}
|
|
16327
16612
|
return { ...value };
|
|
16328
16613
|
}
|
|
16614
|
+
var requestTokenFields = [
|
|
16615
|
+
"inputTokens",
|
|
16616
|
+
"cachedInputTokens",
|
|
16617
|
+
"cacheWriteInputTokens",
|
|
16618
|
+
"cacheWrite1hInputTokens",
|
|
16619
|
+
"outputTokens",
|
|
16620
|
+
"reasoningOutputTokens",
|
|
16621
|
+
"startedAtMs",
|
|
16622
|
+
"completedAtMs"
|
|
16623
|
+
];
|
|
16624
|
+
var requestFields = /* @__PURE__ */ new Set([
|
|
16625
|
+
...requestTokenFields,
|
|
16626
|
+
"requestId",
|
|
16627
|
+
"historical",
|
|
16628
|
+
"model",
|
|
16629
|
+
"provider"
|
|
16630
|
+
]);
|
|
16631
|
+
function parseHostUsageRequest(value) {
|
|
16632
|
+
if (!isRecord(value))
|
|
16633
|
+
throw new Error("Harness Usage request must be an object");
|
|
16634
|
+
for (const key of Object.keys(value)) {
|
|
16635
|
+
if (!requestFields.has(key)) {
|
|
16636
|
+
throw new Error(`Harness Usage request contains unknown field '${key}'`);
|
|
16637
|
+
}
|
|
16638
|
+
}
|
|
16639
|
+
if (typeof value.requestId !== "string" || value.requestId.length === 0) {
|
|
16640
|
+
throw new Error("Harness Usage request 'requestId' must be a non-empty string");
|
|
16641
|
+
}
|
|
16642
|
+
for (const field of ["model", "provider"]) {
|
|
16643
|
+
const candidate2 = value[field];
|
|
16644
|
+
if (candidate2 !== void 0 && (typeof candidate2 !== "string" || candidate2.length === 0)) {
|
|
16645
|
+
throw new Error(`Harness Usage request '${field}' must be a non-empty string`);
|
|
16646
|
+
}
|
|
16647
|
+
}
|
|
16648
|
+
if (value.historical !== void 0 && typeof value.historical !== "boolean") {
|
|
16649
|
+
throw new Error("Harness Usage request 'historical' must be a boolean");
|
|
16650
|
+
}
|
|
16651
|
+
for (const field of requestTokenFields) {
|
|
16652
|
+
const candidate2 = value[field];
|
|
16653
|
+
if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isSafeInteger(candidate2) || candidate2 < 0)) {
|
|
16654
|
+
throw new Error(`Harness Usage request '${field}' must be a non-negative safe integer`);
|
|
16655
|
+
}
|
|
16656
|
+
}
|
|
16657
|
+
if (value.inputTokens === void 0 || value.outputTokens === void 0) {
|
|
16658
|
+
throw new Error("Harness Usage request must contain 'inputTokens' and 'outputTokens'");
|
|
16659
|
+
}
|
|
16660
|
+
const request = value;
|
|
16661
|
+
if ((request.cachedInputTokens ?? 0) + (request.cacheWriteInputTokens ?? 0) > request.inputTokens) {
|
|
16662
|
+
throw new Error("Harness Usage request cache Tokens must not exceed 'inputTokens'");
|
|
16663
|
+
}
|
|
16664
|
+
if ((request.reasoningOutputTokens ?? 0) > request.outputTokens) {
|
|
16665
|
+
throw new Error("Harness Usage request 'reasoningOutputTokens' must not exceed 'outputTokens'");
|
|
16666
|
+
}
|
|
16667
|
+
if (request.cacheWrite1hInputTokens !== void 0 && request.cacheWrite1hInputTokens > (request.cacheWriteInputTokens ?? -1)) {
|
|
16668
|
+
throw new Error("Harness Usage request 'cacheWrite1hInputTokens' must not exceed 'cacheWriteInputTokens'");
|
|
16669
|
+
}
|
|
16670
|
+
if (request.startedAtMs === void 0 !== (request.completedAtMs === void 0)) {
|
|
16671
|
+
throw new Error("Harness Usage request timing fields must be provided together");
|
|
16672
|
+
}
|
|
16673
|
+
if (request.startedAtMs !== void 0 && request.completedAtMs !== void 0 && request.completedAtMs < request.startedAtMs) {
|
|
16674
|
+
throw new Error("Harness Usage request 'completedAtMs' must not precede 'startedAtMs'");
|
|
16675
|
+
}
|
|
16676
|
+
return { ...request };
|
|
16677
|
+
}
|
|
16678
|
+
|
|
16679
|
+
// dist/v2/usage.js
|
|
16680
|
+
function v2UsageRequest(message, historical, firstOutputAtMs) {
|
|
16681
|
+
if (message.type !== "assistant" || !message.tokens)
|
|
16682
|
+
return null;
|
|
16683
|
+
const { input, output, reasoning, cache } = message.tokens;
|
|
16684
|
+
const { streamed } = message.time;
|
|
16685
|
+
return parseHostUsageRequest({
|
|
16686
|
+
requestId: message.id,
|
|
16687
|
+
...historical ? { historical: true } : {},
|
|
16688
|
+
model: message.model.id,
|
|
16689
|
+
// Built-in OpenCode providers use models.dev IDs. A custom provider ID matches no price
|
|
16690
|
+
// entry, so Host falls back to the exact model ID.
|
|
16691
|
+
provider: message.model.providerID,
|
|
16692
|
+
inputTokens: input + cache.read + cache.write,
|
|
16693
|
+
cachedInputTokens: cache.read,
|
|
16694
|
+
cacheWriteInputTokens: cache.write,
|
|
16695
|
+
outputTokens: output + reasoning,
|
|
16696
|
+
reasoningOutputTokens: reasoning,
|
|
16697
|
+
// End at stream completion, not step completion, which can include tool execution.
|
|
16698
|
+
// Without a native stream end, keep the usage but do not guess its generation duration.
|
|
16699
|
+
...!historical && firstOutputAtMs !== void 0 && streamed !== void 0 && streamed >= firstOutputAtMs ? { startedAtMs: firstOutputAtMs, completedAtMs: streamed } : {}
|
|
16700
|
+
});
|
|
16701
|
+
}
|
|
16702
|
+
|
|
16703
|
+
// dist/usage-statistics.js
|
|
16704
|
+
function parseRowData(data) {
|
|
16705
|
+
try {
|
|
16706
|
+
return JSON.parse(String(data));
|
|
16707
|
+
} catch {
|
|
16708
|
+
return null;
|
|
16709
|
+
}
|
|
16710
|
+
}
|
|
16711
|
+
function isRecord2(value) {
|
|
16712
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16713
|
+
}
|
|
16714
|
+
function openCodeDatabasePath(environment) {
|
|
16715
|
+
const home = environment.HOME || environment.USERPROFILE || os2.homedir();
|
|
16716
|
+
const directory = path5.join(environment.XDG_DATA_HOME || path5.join(home, ".local", "share"), "opencode");
|
|
16717
|
+
const configured = environment.OPENCODE_DB;
|
|
16718
|
+
if (configured === ":memory:")
|
|
16719
|
+
return null;
|
|
16720
|
+
return configured ? path5.resolve(directory, configured) : path5.join(directory, "opencode.db");
|
|
16721
|
+
}
|
|
16722
|
+
async function fingerprint(file2) {
|
|
16723
|
+
const info = await lstat(file2).catch(() => null);
|
|
16724
|
+
if (!info?.isFile())
|
|
16725
|
+
return null;
|
|
16726
|
+
const wal = await lstat(`${file2}-wal`).catch(() => null);
|
|
16727
|
+
return `${info.ino}:${info.size}:${info.mtimeMs}:${wal ? `${wal.size}:${wal.mtimeMs}` : "-"}`;
|
|
16728
|
+
}
|
|
16729
|
+
async function readOpenCodeUsage(file2) {
|
|
16730
|
+
const { DatabaseSync } = await import("node:sqlite");
|
|
16731
|
+
const database = new DatabaseSync(file2, { readOnly: true });
|
|
16732
|
+
try {
|
|
16733
|
+
const tables = new Set(database.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map((row) => String(row.name)));
|
|
16734
|
+
const directories = /* @__PURE__ */ new Map();
|
|
16735
|
+
for (const table of ["session", "session_v2"]) {
|
|
16736
|
+
if (!tables.has(table))
|
|
16737
|
+
continue;
|
|
16738
|
+
for (const row of database.prepare(`SELECT id, directory FROM ${table}`).iterate()) {
|
|
16739
|
+
if (typeof row.directory === "string")
|
|
16740
|
+
directories.set(String(row.id), row.directory);
|
|
16741
|
+
}
|
|
16742
|
+
}
|
|
16743
|
+
const entries = /* @__PURE__ */ new Map();
|
|
16744
|
+
const add = (message, createdAtMs, session) => {
|
|
16745
|
+
let request;
|
|
16746
|
+
try {
|
|
16747
|
+
request = v2UsageRequest(message, true);
|
|
16748
|
+
} catch {
|
|
16749
|
+
return;
|
|
16750
|
+
}
|
|
16751
|
+
const at = nativeTimeMs(createdAtMs);
|
|
16752
|
+
const entry = request && at !== null && usageEntryFromRequest(request, at);
|
|
16753
|
+
if (entry && !entries.has(entry.id)) {
|
|
16754
|
+
const sessionId = typeof session === "string" ? session : void 0;
|
|
16755
|
+
entries.set(entry.id, withUsageSession(entry, {
|
|
16756
|
+
sessionId,
|
|
16757
|
+
cwd: sessionId === void 0 ? void 0 : directories.get(sessionId)
|
|
16758
|
+
}));
|
|
16759
|
+
}
|
|
16760
|
+
};
|
|
16761
|
+
if (tables.has("session_message")) {
|
|
16762
|
+
for (const row of database.prepare("SELECT id, session_id, data FROM session_message WHERE type = 'assistant'").iterate()) {
|
|
16763
|
+
const data = parseRowData(row.data);
|
|
16764
|
+
if (!isRecord2(data))
|
|
16765
|
+
continue;
|
|
16766
|
+
add({ ...data, id: String(row.id), type: "assistant" }, isRecord2(data.time) ? data.time.created : void 0, row.session_id);
|
|
16767
|
+
}
|
|
16768
|
+
}
|
|
16769
|
+
const migrated = tables.has("kv") && /"phase"\s*:\s*"completed"/u.test(String(database.prepare("SELECT value FROM kv WHERE key = 'migration.v1-v2'").get()?.value ?? ""));
|
|
16770
|
+
if (tables.has("message") && !migrated) {
|
|
16771
|
+
for (const row of database.prepare("SELECT id, session_id, data FROM message").iterate()) {
|
|
16772
|
+
const data = parseRowData(row.data);
|
|
16773
|
+
if (!isRecord2(data) || data.role !== "assistant" || typeof data.modelID !== "string") {
|
|
16774
|
+
continue;
|
|
16775
|
+
}
|
|
16776
|
+
add({
|
|
16777
|
+
id: String(row.id),
|
|
16778
|
+
type: "assistant",
|
|
16779
|
+
model: { id: data.modelID, providerID: data.providerID },
|
|
16780
|
+
tokens: data.tokens,
|
|
16781
|
+
time: data.time
|
|
16782
|
+
}, isRecord2(data.time) ? data.time.created : void 0, row.session_id);
|
|
16783
|
+
}
|
|
16784
|
+
}
|
|
16785
|
+
return [...entries.values()];
|
|
16786
|
+
} finally {
|
|
16787
|
+
database.close();
|
|
16788
|
+
}
|
|
16789
|
+
}
|
|
16790
|
+
function createOpenCodeUsageStatistics(environment) {
|
|
16791
|
+
return Object.freeze({
|
|
16792
|
+
async listSources() {
|
|
16793
|
+
const file2 = openCodeDatabasePath(environment);
|
|
16794
|
+
const stamp = file2 ? await fingerprint(file2) : null;
|
|
16795
|
+
return file2 && stamp ? [{ id: file2, fingerprint: stamp }] : [];
|
|
16796
|
+
},
|
|
16797
|
+
readSource: (id) => readOpenCodeUsage(id)
|
|
16798
|
+
});
|
|
16799
|
+
}
|
|
16800
|
+
|
|
16801
|
+
// dist/opencode-adapter.js
|
|
16802
|
+
import { randomUUID } from "node:crypto";
|
|
16803
|
+
import fs4 from "node:fs";
|
|
16804
|
+
import path9 from "node:path";
|
|
16329
16805
|
|
|
16330
16806
|
// dist/model-catalog.js
|
|
16331
16807
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
@@ -16336,10 +16812,10 @@ function assertNonBlank(value, label) {
|
|
|
16336
16812
|
if (!value.trim())
|
|
16337
16813
|
throw new Error(`OpenCode ${label} must not be empty`);
|
|
16338
16814
|
}
|
|
16339
|
-
function encodeOpenCodeModelRef(
|
|
16340
|
-
assertNonBlank(
|
|
16341
|
-
assertNonBlank(
|
|
16342
|
-
const encoded = Buffer2.from(JSON.stringify([
|
|
16815
|
+
function encodeOpenCodeModelRef(model2) {
|
|
16816
|
+
assertNonBlank(model2.providerID, "Provider ID");
|
|
16817
|
+
assertNonBlank(model2.modelID, "Model ID");
|
|
16818
|
+
const encoded = Buffer2.from(JSON.stringify([model2.providerID, model2.modelID]), "utf8").toString("base64url");
|
|
16343
16819
|
const id = `${MODEL_REF_PREFIX}${encoded}`;
|
|
16344
16820
|
if (id.length > HARNESS_MODEL_REF_MAX_LENGTH) {
|
|
16345
16821
|
throw new Error("OpenCode Model identity is too long for a Model Ref");
|
|
@@ -16397,26 +16873,26 @@ function compareText(left, right) {
|
|
|
16397
16873
|
}
|
|
16398
16874
|
function modelsForConnectedProviders(catalog) {
|
|
16399
16875
|
const connected = new Set(catalog.connected);
|
|
16400
|
-
return catalog.all.flatMap((provider) => connected.has(provider.id) ? Object.values(provider.models).map((
|
|
16876
|
+
return catalog.all.flatMap((provider) => connected.has(provider.id) ? Object.values(provider.models).map((model2) => ({ provider, model: model2 })) : []);
|
|
16401
16877
|
}
|
|
16402
16878
|
function normalizeOpenCodeModelCatalog(catalog) {
|
|
16403
16879
|
const nativeModels = modelsForConnectedProviders(catalog);
|
|
16404
16880
|
const variants = /* @__PURE__ */ new Set();
|
|
16405
|
-
for (const { model } of nativeModels) {
|
|
16406
|
-
for (const variant of Object.keys(
|
|
16881
|
+
for (const { model: model2 } of nativeModels) {
|
|
16882
|
+
for (const variant of Object.keys(model2.variants ?? {}))
|
|
16407
16883
|
variants.add(variant);
|
|
16408
16884
|
}
|
|
16409
16885
|
const thinkingOptions = [
|
|
16410
16886
|
variantOption(void 0),
|
|
16411
16887
|
...[...variants].sort(compareText).map((variant) => variantOption(variant))
|
|
16412
16888
|
];
|
|
16413
|
-
const models = nativeModels.map(({ provider, model }) => ({
|
|
16414
|
-
ref: encodeOpenCodeModelRef({ providerID: provider.id, modelID:
|
|
16415
|
-
label: `${provider.name} / ${
|
|
16416
|
-
resolvedModelLabel: `${provider.id}/${
|
|
16889
|
+
const models = nativeModels.map(({ provider, model: model2 }) => ({
|
|
16890
|
+
ref: encodeOpenCodeModelRef({ providerID: provider.id, modelID: model2.id }),
|
|
16891
|
+
label: `${provider.name} / ${model2.name}`,
|
|
16892
|
+
resolvedModelLabel: `${provider.id}/${model2.id}`,
|
|
16417
16893
|
supportedThinkingOptionIds: [
|
|
16418
16894
|
DEFAULT_VARIANT_ID,
|
|
16419
|
-
...Object.keys(
|
|
16895
|
+
...Object.keys(model2.variants ?? {}).sort(compareText).map(encodeOpenCodeVariant)
|
|
16420
16896
|
]
|
|
16421
16897
|
})).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
|
|
16422
16898
|
const defaultNative = catalog.connected.map((providerID) => ({ providerID, modelID: catalog.default[providerID] })).find((candidate2) => typeof candidate2.modelID === "string" && candidate2.modelID.length > 0);
|
|
@@ -16428,9 +16904,9 @@ function normalizeOpenCodeModelCatalog(catalog) {
|
|
|
16428
16904
|
defaultThinkingOptionId: DEFAULT_VARIANT_ID
|
|
16429
16905
|
});
|
|
16430
16906
|
}
|
|
16431
|
-
function openCodeContextWindow(catalog,
|
|
16432
|
-
const provider = catalog.all.find(({ id }) => id ===
|
|
16433
|
-
const context = provider?.models[
|
|
16907
|
+
function openCodeContextWindow(catalog, model2) {
|
|
16908
|
+
const provider = catalog.all.find(({ id }) => id === model2.providerID);
|
|
16909
|
+
const context = provider?.models[model2.modelID]?.limit.context;
|
|
16434
16910
|
return typeof context === "number" && Number.isSafeInteger(context) && context > 0 ? context : void 0;
|
|
16435
16911
|
}
|
|
16436
16912
|
|
|
@@ -16753,7 +17229,7 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
16753
17229
|
import fs2 from "node:fs";
|
|
16754
17230
|
import { createServer } from "node:net";
|
|
16755
17231
|
import { homedir as homedir2, tmpdir as tmpdir2 } from "node:os";
|
|
16756
|
-
import
|
|
17232
|
+
import path7 from "node:path";
|
|
16757
17233
|
|
|
16758
17234
|
// ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
|
|
16759
17235
|
var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url2, ...options }) => {
|
|
@@ -16979,7 +17455,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
|
|
|
16979
17455
|
|
|
16980
17456
|
// ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
|
|
16981
17457
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
16982
|
-
var defaultPathSerializer = ({ path:
|
|
17458
|
+
var defaultPathSerializer = ({ path: path14, url: _url2 }) => {
|
|
16983
17459
|
let url2 = _url2;
|
|
16984
17460
|
const matches = _url2.match(PATH_PARAM_RE);
|
|
16985
17461
|
if (matches) {
|
|
@@ -16998,7 +17474,7 @@ var defaultPathSerializer = ({ path: path13, url: _url2 }) => {
|
|
|
16998
17474
|
name = name.substring(1);
|
|
16999
17475
|
style = "matrix";
|
|
17000
17476
|
}
|
|
17001
|
-
const value =
|
|
17477
|
+
const value = path14[name];
|
|
17002
17478
|
if (value === void 0 || value === null) {
|
|
17003
17479
|
continue;
|
|
17004
17480
|
}
|
|
@@ -17029,11 +17505,11 @@ var defaultPathSerializer = ({ path: path13, url: _url2 }) => {
|
|
|
17029
17505
|
}
|
|
17030
17506
|
return url2;
|
|
17031
17507
|
};
|
|
17032
|
-
var getUrl = ({ baseUrl, path:
|
|
17508
|
+
var getUrl = ({ baseUrl, path: path14, query, querySerializer, url: _url2 }) => {
|
|
17033
17509
|
const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
|
|
17034
17510
|
let url2 = (baseUrl ?? "") + pathUrl;
|
|
17035
|
-
if (
|
|
17036
|
-
url2 = defaultPathSerializer({ path:
|
|
17511
|
+
if (path14) {
|
|
17512
|
+
url2 = defaultPathSerializer({ path: path14, url: url2 });
|
|
17037
17513
|
}
|
|
17038
17514
|
let search = query ? querySerializer(query) : "";
|
|
17039
17515
|
if (search.startsWith("?")) {
|
|
@@ -22156,7 +22632,7 @@ function createOpencodeClient(config2) {
|
|
|
22156
22632
|
}
|
|
22157
22633
|
|
|
22158
22634
|
// dist/command.js
|
|
22159
|
-
import
|
|
22635
|
+
import path6 from "node:path";
|
|
22160
22636
|
var OpenCodeExecutableError = class extends Error {
|
|
22161
22637
|
code = "OPENCODE_NOT_FOUND";
|
|
22162
22638
|
constructor(message = "OpenCode CLI is not installed") {
|
|
@@ -22190,7 +22666,7 @@ function resolveOpenCodeExecutable(input = {}, dependencies = {}) {
|
|
|
22190
22666
|
}, dependencies);
|
|
22191
22667
|
if (!resolution)
|
|
22192
22668
|
throw new OpenCodeExecutableError();
|
|
22193
|
-
return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable :
|
|
22669
|
+
return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path6.resolve(resolution.executable);
|
|
22194
22670
|
}
|
|
22195
22671
|
function openCodeServerInvocation(executable, environment, platform = process.platform, port = 0) {
|
|
22196
22672
|
return commandInvocation(executable, ["serve", "--hostname=127.0.0.1", `--port=${port}`], environment, platform);
|
|
@@ -22218,14 +22694,14 @@ function freeLoopbackPort() {
|
|
|
22218
22694
|
});
|
|
22219
22695
|
});
|
|
22220
22696
|
}
|
|
22221
|
-
function
|
|
22697
|
+
function isRecord3(value) {
|
|
22222
22698
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22223
22699
|
}
|
|
22224
22700
|
function errorText(error51) {
|
|
22225
22701
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
22226
22702
|
}
|
|
22227
22703
|
function isMissingExecutable(error51) {
|
|
22228
|
-
return
|
|
22704
|
+
return isRecord3(error51) && error51.code === "ENOENT";
|
|
22229
22705
|
}
|
|
22230
22706
|
function classifySdkError(error51, operation) {
|
|
22231
22707
|
if (error51 instanceof OpenCodeTransportError)
|
|
@@ -22280,14 +22756,14 @@ function signalProcessTree(child, signal) {
|
|
|
22280
22756
|
try {
|
|
22281
22757
|
process.kill(-child.pid, signal);
|
|
22282
22758
|
} catch (error51) {
|
|
22283
|
-
if (!
|
|
22759
|
+
if (!isRecord3(error51) || error51.code !== "ESRCH")
|
|
22284
22760
|
throw error51;
|
|
22285
22761
|
}
|
|
22286
22762
|
}
|
|
22287
22763
|
function safeOpenCodeServerCwd(environment) {
|
|
22288
22764
|
const candidates = [environment.USERPROFILE, environment.HOME, homedir2(), tmpdir2()];
|
|
22289
22765
|
for (const candidate2 of candidates) {
|
|
22290
|
-
if (!candidate2 || !
|
|
22766
|
+
if (!candidate2 || !path7.isAbsolute(candidate2))
|
|
22291
22767
|
continue;
|
|
22292
22768
|
try {
|
|
22293
22769
|
if (!fs2.statSync(candidate2).isDirectory())
|
|
@@ -22311,7 +22787,7 @@ function managedOpenCodeEnvironment(environment, executionPolicy = "default") {
|
|
|
22311
22787
|
if (existing !== void 0) {
|
|
22312
22788
|
try {
|
|
22313
22789
|
const parsed = JSON.parse(existing);
|
|
22314
|
-
if (!
|
|
22790
|
+
if (!isRecord3(parsed))
|
|
22315
22791
|
throw new Error("OpenCode config content must be an object");
|
|
22316
22792
|
config2 = { ...parsed };
|
|
22317
22793
|
} catch (error51) {
|
|
@@ -22634,11 +23110,11 @@ var SdkOpenCodeTransport = class {
|
|
|
22634
23110
|
parts: [{ type: "text", text: input.text }]
|
|
22635
23111
|
}), this.#commandTimeoutMs, "OpenCode prompt admission"), "prompt admission");
|
|
22636
23112
|
}
|
|
22637
|
-
async summarize(sessionID,
|
|
23113
|
+
async summarize(sessionID, model2) {
|
|
22638
23114
|
const client2 = await this.#getClient();
|
|
22639
23115
|
responseData2(await withTimeout2(client2.session.summarize({
|
|
22640
23116
|
sessionID,
|
|
22641
|
-
...
|
|
23117
|
+
...model2 ? { providerID: model2.providerID, modelID: model2.modelID } : {}
|
|
22642
23118
|
}), this.#commandTimeoutMs, "OpenCode context compaction"), "context compaction");
|
|
22643
23119
|
}
|
|
22644
23120
|
async abort(sessionID) {
|
|
@@ -22736,7 +23212,7 @@ var SdkOpenCodeTransport = class {
|
|
|
22736
23212
|
|
|
22737
23213
|
// dist/file-change-verification.js
|
|
22738
23214
|
import fs3 from "node:fs";
|
|
22739
|
-
import
|
|
23215
|
+
import path8 from "node:path";
|
|
22740
23216
|
function missingPath(error51) {
|
|
22741
23217
|
if (!error51 || typeof error51 !== "object")
|
|
22742
23218
|
return false;
|
|
@@ -22748,33 +23224,33 @@ function hasDotPathSegment(value) {
|
|
|
22748
23224
|
return segments.some((segment) => segment === "." || segment === "..");
|
|
22749
23225
|
}
|
|
22750
23226
|
function canonicalDirectoryPath(value) {
|
|
22751
|
-
let candidate2 =
|
|
23227
|
+
let candidate2 = path8.resolve(value);
|
|
22752
23228
|
const missingSegments = [];
|
|
22753
23229
|
for (; ; ) {
|
|
22754
23230
|
try {
|
|
22755
|
-
return
|
|
23231
|
+
return path8.join(fs3.realpathSync.native(candidate2), ...missingSegments);
|
|
22756
23232
|
} catch (error51) {
|
|
22757
23233
|
if (!missingPath(error51))
|
|
22758
23234
|
return void 0;
|
|
22759
|
-
const parent =
|
|
23235
|
+
const parent = path8.dirname(candidate2);
|
|
22760
23236
|
if (parent === candidate2)
|
|
22761
23237
|
return void 0;
|
|
22762
|
-
missingSegments.unshift(
|
|
23238
|
+
missingSegments.unshift(path8.basename(candidate2));
|
|
22763
23239
|
candidate2 = parent;
|
|
22764
23240
|
}
|
|
22765
23241
|
}
|
|
22766
23242
|
}
|
|
22767
23243
|
function canonicalFilePath(value) {
|
|
22768
|
-
const absolute =
|
|
22769
|
-
const parent = canonicalDirectoryPath(
|
|
22770
|
-
return parent ?
|
|
23244
|
+
const absolute = path8.resolve(value);
|
|
23245
|
+
const parent = canonicalDirectoryPath(path8.dirname(absolute));
|
|
23246
|
+
return parent ? path8.join(parent, path8.basename(absolute)) : void 0;
|
|
22771
23247
|
}
|
|
22772
23248
|
function pathIsWithin(root, candidate2, allowRoot) {
|
|
22773
|
-
const relative =
|
|
22774
|
-
return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${
|
|
23249
|
+
const relative = path8.relative(root, candidate2);
|
|
23250
|
+
return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${path8.sep}`) && !path8.isAbsolute(relative);
|
|
22775
23251
|
}
|
|
22776
23252
|
function verifiedOpenCodeWorktree(sessionDirectory, paths) {
|
|
22777
|
-
if (!paths || typeof paths !== "object" || typeof sessionDirectory !== "string" || typeof paths.directory !== "string" || typeof paths.worktree !== "string" || hasDotPathSegment(sessionDirectory) || hasDotPathSegment(paths.directory) || hasDotPathSegment(paths.worktree) || !
|
|
23253
|
+
if (!paths || typeof paths !== "object" || typeof sessionDirectory !== "string" || typeof paths.directory !== "string" || typeof paths.worktree !== "string" || hasDotPathSegment(sessionDirectory) || hasDotPathSegment(paths.directory) || hasDotPathSegment(paths.worktree) || !path8.isAbsolute(sessionDirectory) || !path8.isAbsolute(paths.directory) || !path8.isAbsolute(paths.worktree)) {
|
|
22778
23254
|
return void 0;
|
|
22779
23255
|
}
|
|
22780
23256
|
const session = canonicalDirectoryPath(sessionDirectory);
|
|
@@ -22786,10 +23262,10 @@ function verifiedOpenCodeWorktree(sessionDirectory, paths) {
|
|
|
22786
23262
|
return worktree;
|
|
22787
23263
|
}
|
|
22788
23264
|
function openCodeFileIdentity(file2, worktree) {
|
|
22789
|
-
if (typeof file2 !== "string" || typeof worktree !== "string" || hasDotPathSegment(file2) || hasDotPathSegment(worktree) || !
|
|
23265
|
+
if (typeof file2 !== "string" || typeof worktree !== "string" || hasDotPathSegment(file2) || hasDotPathSegment(worktree) || !path8.isAbsolute(worktree) || !file2 || file2.includes("\0") || file2.includes("\n") || file2.includes("\r")) {
|
|
22790
23266
|
return void 0;
|
|
22791
23267
|
}
|
|
22792
|
-
const candidate2 = canonicalFilePath(
|
|
23268
|
+
const candidate2 = canonicalFilePath(path8.isAbsolute(file2) ? file2 : path8.resolve(worktree, file2));
|
|
22793
23269
|
return candidate2 && pathIsWithin(worktree, candidate2, false) ? candidate2 : void 0;
|
|
22794
23270
|
}
|
|
22795
23271
|
|
|
@@ -22847,12 +23323,12 @@ function storedSelection(session) {
|
|
|
22847
23323
|
}
|
|
22848
23324
|
return { providerID, modelID, ...typeof variant === "string" ? { variant } : {} };
|
|
22849
23325
|
}
|
|
22850
|
-
function selectionMetadata(session,
|
|
23326
|
+
function selectionMetadata(session, model2, variant) {
|
|
22851
23327
|
return {
|
|
22852
23328
|
...session.metadata,
|
|
22853
23329
|
[SELECTION_METADATA_KEY]: {
|
|
22854
|
-
providerID:
|
|
22855
|
-
modelID:
|
|
23330
|
+
providerID: model2.providerID,
|
|
23331
|
+
modelID: model2.modelID,
|
|
22856
23332
|
...variant ? { variant } : {}
|
|
22857
23333
|
}
|
|
22858
23334
|
};
|
|
@@ -22948,17 +23424,17 @@ async function readProjection(transport, sessionID, providerCatalog, toolOutputL
|
|
|
22948
23424
|
diffsByUserMessageId: new Map(diffEntries),
|
|
22949
23425
|
toolOutputLimit
|
|
22950
23426
|
});
|
|
22951
|
-
const
|
|
23427
|
+
const model2 = nativeModelFromSession(session, messages);
|
|
22952
23428
|
const nativeVariant = nativeVariantFromSession(session, messages);
|
|
22953
|
-
const nativeModel =
|
|
23429
|
+
const nativeModel = model2 ? providerCatalog.all.find(({ id }) => id === model2.providerID)?.models[model2.modelID] : void 0;
|
|
22954
23430
|
const variant = nativeVariant === "default" && nativeModel && !Object.hasOwn(nativeModel.variants ?? {}, "default") ? void 0 : nativeVariant;
|
|
22955
|
-
const usage = projectOpenCodeUsage(openCodeAssistantMessages(session, messages),
|
|
23431
|
+
const usage = projectOpenCodeUsage(openCodeAssistantMessages(session, messages), model2 ? openCodeContextWindow(providerCatalog, model2) : void 0);
|
|
22956
23432
|
return {
|
|
22957
23433
|
session,
|
|
22958
23434
|
messages,
|
|
22959
23435
|
snapshot,
|
|
22960
23436
|
usage,
|
|
22961
|
-
...
|
|
23437
|
+
...model2 ? { model: model2 } : {},
|
|
22962
23438
|
...variant ? { variant } : {}
|
|
22963
23439
|
};
|
|
22964
23440
|
}
|
|
@@ -23084,13 +23560,13 @@ function sameCwd(left, right) {
|
|
|
23084
23560
|
try {
|
|
23085
23561
|
return fs4.realpathSync.native(value);
|
|
23086
23562
|
} catch {
|
|
23087
|
-
return
|
|
23563
|
+
return path9.resolve(value);
|
|
23088
23564
|
}
|
|
23089
23565
|
};
|
|
23090
23566
|
return canonical(left) === canonical(right);
|
|
23091
23567
|
}
|
|
23092
|
-
function sessionState(session, modelCatalog,
|
|
23093
|
-
const effectiveModel =
|
|
23568
|
+
function sessionState(session, modelCatalog, model2, variant, executionPolicy = "default", permissionModeId = OPENCODE_DEFAULT_PERMISSION_MODE_ID) {
|
|
23569
|
+
const effectiveModel = model2 ? encodeOpenCodeModelRef(model2) : void 0;
|
|
23094
23570
|
const modelEntry = effectiveModel ? modelCatalog.models.find(({ ref }) => ref.id === effectiveModel.id) : void 0;
|
|
23095
23571
|
const availableThinkingOptions = modelEntry?.supportedThinkingOptionIds?.map((id) => modelCatalog.thinkingOptions.find((option) => option.id === id)).filter((option) => Boolean(option));
|
|
23096
23572
|
const effectiveThinkingOptionId = encodeOpenCodeVariant(variant);
|
|
@@ -23492,8 +23968,8 @@ var OpenCodeHarnessSession = class {
|
|
|
23492
23968
|
};
|
|
23493
23969
|
}
|
|
23494
23970
|
const modelRef = this.#model ? encodeOpenCodeModelRef(this.#model) : void 0;
|
|
23495
|
-
const
|
|
23496
|
-
if (!
|
|
23971
|
+
const model2 = modelRef ? this.#modelCatalog.models.find(({ ref }) => ref.id === modelRef.id) : void 0;
|
|
23972
|
+
if (!model2?.supportedThinkingOptionIds?.includes(command.thinkingOptionId)) {
|
|
23497
23973
|
return {
|
|
23498
23974
|
ok: false,
|
|
23499
23975
|
error: {
|
|
@@ -24343,14 +24819,14 @@ var OpenCodeAdapter = class {
|
|
|
24343
24819
|
const modelCatalog = normalizeOpenCodeModelCatalog(providers);
|
|
24344
24820
|
let session;
|
|
24345
24821
|
if (input.kind === "create") {
|
|
24346
|
-
const
|
|
24822
|
+
const model2 = input.model ? decodeOpenCodeModelRef(input.model) : void 0;
|
|
24347
24823
|
const variant = input.thinkingOptionId ? decodeOpenCodeVariant(input.thinkingOptionId) : void 0;
|
|
24348
24824
|
if (input.model && !modelCatalog.models.some(({ ref }) => ref.id === input.model?.id)) {
|
|
24349
24825
|
throw new OpenCodeTransportError("protocolError", "Requested OpenCode Model is absent from the connected Provider catalog");
|
|
24350
24826
|
}
|
|
24351
24827
|
const permission = requestedPermissionMode && requestedPermissionMode !== "default" ? requestedPermissionRules(void 0, requestedPermissionMode) : void 0;
|
|
24352
24828
|
session = await transport.createSession({
|
|
24353
|
-
...
|
|
24829
|
+
...model2 ? { model: model2 } : {},
|
|
24354
24830
|
...variant ? { variant } : {},
|
|
24355
24831
|
...permission ? { permission } : {}
|
|
24356
24832
|
});
|
|
@@ -24465,7 +24941,7 @@ import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
|
24465
24941
|
|
|
24466
24942
|
// dist/v2/state.js
|
|
24467
24943
|
import fs5 from "node:fs";
|
|
24468
|
-
import
|
|
24944
|
+
import path10 from "node:path";
|
|
24469
24945
|
var harnessId = harnessIdSchema.parse("opencode");
|
|
24470
24946
|
function failure(message, code = "nativeFailure") {
|
|
24471
24947
|
return {
|
|
@@ -24485,7 +24961,7 @@ function sameDirectory(left, right) {
|
|
|
24485
24961
|
try {
|
|
24486
24962
|
return fs5.realpathSync(value);
|
|
24487
24963
|
} catch {
|
|
24488
|
-
return
|
|
24964
|
+
return path10.resolve(value);
|
|
24489
24965
|
}
|
|
24490
24966
|
};
|
|
24491
24967
|
return canonical(left) === canonical(right);
|
|
@@ -24507,17 +24983,17 @@ function v2Locator(ref) {
|
|
|
24507
24983
|
return { directory: locator.directory, executionPolicy: locator.executionPolicy };
|
|
24508
24984
|
}
|
|
24509
24985
|
function v2Catalog(models, defaultModel) {
|
|
24510
|
-
const enabled = models.filter((
|
|
24511
|
-
const variants = [...new Set(enabled.flatMap((
|
|
24512
|
-
const ref = (
|
|
24986
|
+
const enabled = models.filter((model2) => model2.enabled);
|
|
24987
|
+
const variants = [...new Set(enabled.flatMap((model2) => model2.variants.map((v) => v.id)))].sort();
|
|
24988
|
+
const ref = (model2) => encodeOpenCodeModelRef({ providerID: model2.providerID, modelID: model2.id });
|
|
24513
24989
|
return harnessModelCatalogSchema.parse({
|
|
24514
|
-
models: enabled.map((
|
|
24515
|
-
ref: ref(
|
|
24516
|
-
label: `${
|
|
24517
|
-
resolvedModelLabel: `${
|
|
24990
|
+
models: enabled.map((model2) => ({
|
|
24991
|
+
ref: ref(model2),
|
|
24992
|
+
label: `${model2.providerID} / ${model2.name}`,
|
|
24993
|
+
resolvedModelLabel: `${model2.providerID}/${model2.id}`,
|
|
24518
24994
|
supportedThinkingOptionIds: [
|
|
24519
24995
|
encodeOpenCodeVariant(void 0),
|
|
24520
|
-
...
|
|
24996
|
+
...model2.variants.map((v) => encodeOpenCodeVariant(v.id))
|
|
24521
24997
|
]
|
|
24522
24998
|
})),
|
|
24523
24999
|
...defaultModel && enabled.some((m) => ref(m).id === ref(defaultModel).id) ? { defaultModel: ref(defaultModel) } : {},
|
|
@@ -24534,12 +25010,12 @@ function v2Permissions(current = [], mode) {
|
|
|
24534
25010
|
return selected === "default" ? rules : [...rules, { action: "*", resource: "*", effect: selected }];
|
|
24535
25011
|
}
|
|
24536
25012
|
function v2State(session, catalog, policy) {
|
|
24537
|
-
const
|
|
24538
|
-
const entry = catalog.models.find((candidate2) => candidate2.ref.id ===
|
|
25013
|
+
const model2 = session.model ? encodeOpenCodeModelRef({ providerID: session.model.providerID, modelID: session.model.id }) : void 0;
|
|
25014
|
+
const entry = catalog.models.find((candidate2) => candidate2.ref.id === model2?.id);
|
|
24539
25015
|
const mode = session.permissions?.findLast((rule) => rule.action === "*" && rule.resource === "*");
|
|
24540
25016
|
return {
|
|
24541
25017
|
nativeRef: v2Ref(session, policy),
|
|
24542
|
-
...
|
|
25018
|
+
...model2 ? { effectiveModel: model2 } : {},
|
|
24543
25019
|
...entry ? {
|
|
24544
25020
|
resolvedModelLabel: entry.resolvedModelLabel ?? entry.label,
|
|
24545
25021
|
availableThinkingOptions: catalog.thinkingOptions.filter((v) => entry.supportedThinkingOptionIds?.includes(v.id)),
|
|
@@ -26400,7 +26876,7 @@ var V2Connection = class {
|
|
|
26400
26876
|
};
|
|
26401
26877
|
|
|
26402
26878
|
// dist/v2/history.js
|
|
26403
|
-
import
|
|
26879
|
+
import path11 from "node:path";
|
|
26404
26880
|
async function readMessages(client2, sessionID) {
|
|
26405
26881
|
const messages = [];
|
|
26406
26882
|
let cursor;
|
|
@@ -26419,11 +26895,12 @@ async function readMessages(client2, sessionID) {
|
|
|
26419
26895
|
} while (cursor);
|
|
26420
26896
|
return messages;
|
|
26421
26897
|
}
|
|
26422
|
-
var contentId = (messageID,
|
|
26898
|
+
var contentId = (messageID, type, ordinal) => hostItemIdSchema.parse(`${messageID}:${type}:${ordinal}`);
|
|
26423
26899
|
function assistantItems2(message, limit) {
|
|
26424
|
-
|
|
26425
|
-
|
|
26900
|
+
const ordinals = { text: 0, reasoning: 0 };
|
|
26901
|
+
return message.content.map((part) => {
|
|
26426
26902
|
if (part.type === "text" || part.type === "reasoning") {
|
|
26903
|
+
const itemId2 = contentId(message.id, part.type, ordinals[part.type]++);
|
|
26427
26904
|
return {
|
|
26428
26905
|
item: {
|
|
26429
26906
|
type: part.type === "text" ? "agentMessage" : "reasoning",
|
|
@@ -26438,7 +26915,7 @@ function assistantItems2(message, limit) {
|
|
|
26438
26915
|
return {
|
|
26439
26916
|
item: {
|
|
26440
26917
|
type: "toolExecution",
|
|
26441
|
-
itemId:
|
|
26918
|
+
itemId: hostItemIdSchema.parse(`${message.id}:tool:${part.id}`),
|
|
26442
26919
|
toolName: part.name,
|
|
26443
26920
|
namespace: "opencode",
|
|
26444
26921
|
arguments: typeof state.input === "string" ? state.input : state.input,
|
|
@@ -26525,9 +27002,9 @@ function fileChanges(session, turn, diffs) {
|
|
|
26525
27002
|
if (!diffs.length)
|
|
26526
27003
|
return void 0;
|
|
26527
27004
|
const changes = diffs.map((diff) => {
|
|
26528
|
-
const absolute =
|
|
26529
|
-
const relative =
|
|
26530
|
-
if (relative.startsWith(`..${
|
|
27005
|
+
const absolute = path11.resolve(session.location.directory, diff.file);
|
|
27006
|
+
const relative = path11.relative(session.location.directory, absolute);
|
|
27007
|
+
if (relative.startsWith(`..${path11.sep}`) || relative === ".." || path11.isAbsolute(relative))
|
|
26531
27008
|
throw new Error("OpenCode v2 diff escaped the Session directory");
|
|
26532
27009
|
return {
|
|
26533
27010
|
path: absolute,
|
|
@@ -26570,7 +27047,7 @@ function terminalItemOutcome(outcome) {
|
|
|
26570
27047
|
|
|
26571
27048
|
// dist/v2/session-import.js
|
|
26572
27049
|
import fs6 from "node:fs";
|
|
26573
|
-
import
|
|
27050
|
+
import path12 from "node:path";
|
|
26574
27051
|
|
|
26575
27052
|
// ../../harness-adapter/dist/session-import.js
|
|
26576
27053
|
function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
|
|
@@ -26603,7 +27080,7 @@ function sessionImportCandidate(input) {
|
|
|
26603
27080
|
var PAGE_SIZE = 200;
|
|
26604
27081
|
var MAX_PAGES = 1e4;
|
|
26605
27082
|
function existingDirectory(directory) {
|
|
26606
|
-
if (typeof directory !== "string" || !
|
|
27083
|
+
if (typeof directory !== "string" || !path12.isAbsolute(directory))
|
|
26607
27084
|
return null;
|
|
26608
27085
|
try {
|
|
26609
27086
|
return fs6.statSync(directory).isDirectory() ? directory : null;
|
|
@@ -26803,6 +27280,14 @@ function v2Capabilities(catalog) {
|
|
|
26803
27280
|
history: { fork: true, forkAcrossCwd: false, rollbackLastTurn: true }
|
|
26804
27281
|
};
|
|
26805
27282
|
}
|
|
27283
|
+
var FIRST_OUTPUT_EVENTS = /* @__PURE__ */ new Set([
|
|
27284
|
+
"session.reasoning.started",
|
|
27285
|
+
"session.reasoning.delta",
|
|
27286
|
+
"session.text.started",
|
|
27287
|
+
"session.text.delta",
|
|
27288
|
+
"session.tool.input.started",
|
|
27289
|
+
"session.tool.input.delta"
|
|
27290
|
+
]);
|
|
26806
27291
|
var V2Session = class {
|
|
26807
27292
|
client;
|
|
26808
27293
|
connection;
|
|
@@ -26826,6 +27311,11 @@ var V2Session = class {
|
|
|
26826
27311
|
#reconciling;
|
|
26827
27312
|
#timer;
|
|
26828
27313
|
#configuring = false;
|
|
27314
|
+
#cacheHitRatePercent;
|
|
27315
|
+
/** Assistant messages already published as usage requests. */
|
|
27316
|
+
#meteredMessages = /* @__PURE__ */ new Set();
|
|
27317
|
+
/** Adapter receive time of each assistant message's first reasoning, text or tool input. */
|
|
27318
|
+
#firstOutputAt = /* @__PURE__ */ new Map();
|
|
26829
27319
|
constructor(client2, connection, info, catalog, policy, limit, onClosed) {
|
|
26830
27320
|
this.client = client2;
|
|
26831
27321
|
this.connection = connection;
|
|
@@ -26870,6 +27360,7 @@ var V2Session = class {
|
|
|
26870
27360
|
}
|
|
26871
27361
|
})();
|
|
26872
27362
|
});
|
|
27363
|
+
await this.#replayUsage();
|
|
26873
27364
|
this.#timer = setInterval(() => {
|
|
26874
27365
|
void this.#refresh();
|
|
26875
27366
|
}, 400);
|
|
@@ -26938,22 +27429,22 @@ var V2Session = class {
|
|
|
26938
27429
|
permissions: v2Permissions(this.info.permissions, command.permissionModeId)
|
|
26939
27430
|
});
|
|
26940
27431
|
} else {
|
|
26941
|
-
let
|
|
27432
|
+
let model2 = this.info.model;
|
|
26942
27433
|
if (command.type === "model.select") {
|
|
26943
27434
|
if (!this.catalog.models.some((m) => m.ref.id === command.model.id))
|
|
26944
27435
|
throw new Error("OpenCode Model is not available");
|
|
26945
27436
|
const decoded = decodeOpenCodeModelRef(command.model);
|
|
26946
|
-
|
|
27437
|
+
model2 = { providerID: decoded.providerID, id: decoded.modelID };
|
|
26947
27438
|
} else {
|
|
26948
|
-
if (!
|
|
27439
|
+
if (!model2)
|
|
26949
27440
|
throw new Error("Select a Model before a Thinking option");
|
|
26950
27441
|
const state = v2State(this.info, this.catalog, this.policy);
|
|
26951
27442
|
if (!state.availableThinkingOptions?.some((v) => v.id === command.thinkingOptionId))
|
|
26952
27443
|
throw new Error("Thinking option is unavailable for this Model");
|
|
26953
27444
|
const variant = decodeOpenCodeVariant(command.thinkingOptionId);
|
|
26954
|
-
|
|
27445
|
+
model2 = { providerID: model2.providerID, id: model2.id, ...variant ? { variant } : {} };
|
|
26955
27446
|
}
|
|
26956
|
-
await this.client.session.switchModel({ sessionID: this.info.id, model });
|
|
27447
|
+
await this.client.session.switchModel({ sessionID: this.info.id, model: model2 });
|
|
26957
27448
|
}
|
|
26958
27449
|
this.info = await this.client.session.get({ sessionID: this.info.id });
|
|
26959
27450
|
this.#emit({
|
|
@@ -27036,11 +27527,14 @@ var V2Session = class {
|
|
|
27036
27527
|
const active = this.#active;
|
|
27037
27528
|
if (!active || !("data" in event) || !("sessionID" in event.data) || event.data.sessionID !== this.info.id)
|
|
27038
27529
|
return;
|
|
27530
|
+
if (FIRST_OUTPUT_EVENTS.has(event.type) && "assistantMessageID" in event.data && typeof event.data.assistantMessageID === "string" && !this.#firstOutputAt.has(event.data.assistantMessageID))
|
|
27531
|
+
this.#firstOutputAt.set(event.data.assistantMessageID, Date.now());
|
|
27039
27532
|
if (event.type === "session.step.started")
|
|
27040
27533
|
active.assistants.add(event.data.assistantMessageID);
|
|
27041
27534
|
if ((event.type === "session.text.delta" || event.type === "session.reasoning.delta") && active.assistants.has(event.data.assistantMessageID)) {
|
|
27042
|
-
const
|
|
27043
|
-
const
|
|
27535
|
+
const contentType = event.type === "session.text.delta" ? "text" : "reasoning";
|
|
27536
|
+
const itemId2 = contentId(event.data.assistantMessageID, contentType, event.data.ordinal);
|
|
27537
|
+
const type = contentType === "text" ? "agentMessage" : "reasoning";
|
|
27044
27538
|
const previous = active.transient.get(itemId2);
|
|
27045
27539
|
const item = {
|
|
27046
27540
|
type,
|
|
@@ -27054,6 +27548,56 @@ var V2Session = class {
|
|
|
27054
27548
|
if (!event.type.endsWith(".delta"))
|
|
27055
27549
|
void this.#refresh();
|
|
27056
27550
|
}
|
|
27551
|
+
/** Publishes assistant messages not yet metered; returns false when one is unusable. */
|
|
27552
|
+
#meterUsage(messages, historical) {
|
|
27553
|
+
let usable = true;
|
|
27554
|
+
const previousCacheHitRate = this.#cacheHitRatePercent;
|
|
27555
|
+
for (const message of messages) {
|
|
27556
|
+
let request;
|
|
27557
|
+
try {
|
|
27558
|
+
request = v2UsageRequest(message, historical, this.#firstOutputAt.get(message.id));
|
|
27559
|
+
} catch {
|
|
27560
|
+
this.#cacheHitRatePercent = void 0;
|
|
27561
|
+
if (this.#meteredMessages.has(message.id))
|
|
27562
|
+
continue;
|
|
27563
|
+
this.#meteredMessages.add(message.id);
|
|
27564
|
+
if (!historical)
|
|
27565
|
+
this.#emit({ type: "usage.history", complete: false });
|
|
27566
|
+
usable = false;
|
|
27567
|
+
continue;
|
|
27568
|
+
}
|
|
27569
|
+
if (!request)
|
|
27570
|
+
continue;
|
|
27571
|
+
this.#cacheHitRatePercent = request.inputTokens > 0 && request.cachedInputTokens !== void 0 ? request.cachedInputTokens / request.inputTokens * 100 : void 0;
|
|
27572
|
+
if (this.#meteredMessages.has(message.id))
|
|
27573
|
+
continue;
|
|
27574
|
+
this.#meteredMessages.add(message.id);
|
|
27575
|
+
this.#firstOutputAt.delete(message.id);
|
|
27576
|
+
this.#emit({ type: "usage.request", request });
|
|
27577
|
+
}
|
|
27578
|
+
if (this.#cacheHitRatePercent !== previousCacheHitRate)
|
|
27579
|
+
this.#emit({
|
|
27580
|
+
type: "session.usage.changed",
|
|
27581
|
+
usage: this.#usage()
|
|
27582
|
+
});
|
|
27583
|
+
return usable;
|
|
27584
|
+
}
|
|
27585
|
+
#usage() {
|
|
27586
|
+
const usage = v2Usage(this.info);
|
|
27587
|
+
if (this.#cacheHitRatePercent !== void 0)
|
|
27588
|
+
usage.cacheHitRatePercent = this.#cacheHitRatePercent;
|
|
27589
|
+
return usage;
|
|
27590
|
+
}
|
|
27591
|
+
/** Replays every metered request of the native history, then declares it complete. */
|
|
27592
|
+
async #replayUsage() {
|
|
27593
|
+
let complete = false;
|
|
27594
|
+
try {
|
|
27595
|
+
complete = this.#meterUsage(await readMessages(this.client, this.info.id), true);
|
|
27596
|
+
} catch {
|
|
27597
|
+
complete = false;
|
|
27598
|
+
}
|
|
27599
|
+
this.#emit({ type: "usage.history", complete });
|
|
27600
|
+
}
|
|
27057
27601
|
#refresh() {
|
|
27058
27602
|
if (this.#closed || !this.#active?.admitted)
|
|
27059
27603
|
return Promise.resolve();
|
|
@@ -27072,6 +27616,7 @@ var V2Session = class {
|
|
|
27072
27616
|
if (this.#active !== active || this.#closed)
|
|
27073
27617
|
return;
|
|
27074
27618
|
this.info = info;
|
|
27619
|
+
this.#meterUsage(messages, false);
|
|
27075
27620
|
const turns = snapshot.turns.filter((t) => !active.baseline.has(t.nativeTurnRef.nativeTurnKey));
|
|
27076
27621
|
if (turns.length > 1)
|
|
27077
27622
|
throw new Error("Concurrent native prompts cannot be assigned to one Host Turn");
|
|
@@ -27168,7 +27713,7 @@ var V2Session = class {
|
|
|
27168
27713
|
});
|
|
27169
27714
|
this.#emit({
|
|
27170
27715
|
type: "session.usage.changed",
|
|
27171
|
-
usage:
|
|
27716
|
+
usage: this.#usage(),
|
|
27172
27717
|
observedForTurnId: active.turnId
|
|
27173
27718
|
});
|
|
27174
27719
|
this.#active = void 0;
|
|
@@ -27364,10 +27909,10 @@ var V2Adapter = class {
|
|
|
27364
27909
|
const catalog = await this.#catalog(client2, input.cwd);
|
|
27365
27910
|
let info;
|
|
27366
27911
|
if (input.kind === "create") {
|
|
27367
|
-
const
|
|
27912
|
+
const model2 = selectedModel(input, catalog);
|
|
27368
27913
|
info = await client2.session.create({
|
|
27369
27914
|
location: { directory: input.cwd },
|
|
27370
|
-
...
|
|
27915
|
+
...model2 ? { model: model2 } : {},
|
|
27371
27916
|
permissions: v2Permissions([], input.permissionModeId ?? harnessPermissionModeIdSchema.parse(policy === "unattended-full-access" ? "allow" : "default"))
|
|
27372
27917
|
});
|
|
27373
27918
|
created = info.id;
|
|
@@ -27384,19 +27929,19 @@ var V2Adapter = class {
|
|
|
27384
27929
|
if (input.kind !== "resume") {
|
|
27385
27930
|
const parent = info;
|
|
27386
27931
|
const turns = source.snapshot.turns;
|
|
27387
|
-
let
|
|
27932
|
+
let count2;
|
|
27388
27933
|
if (input.kind === "rollbackLastTurn") {
|
|
27389
27934
|
if (!turns.length)
|
|
27390
27935
|
throw new Error("OpenCode history is empty");
|
|
27391
|
-
|
|
27936
|
+
count2 = turns.length - 1;
|
|
27392
27937
|
} else {
|
|
27393
27938
|
if (input.checkpoint.harnessId !== harnessId || input.checkpoint.nativeSessionId !== info.id)
|
|
27394
27939
|
throw new Error("Checkpoint belongs to another Session");
|
|
27395
|
-
|
|
27396
|
-
if (!
|
|
27940
|
+
count2 = turns.findIndex((turn) => turn.checkpoint?.checkpointId === input.checkpoint.checkpointId) + 1;
|
|
27941
|
+
if (!count2 || JSON.stringify(turns[count2 - 1]?.checkpoint) !== JSON.stringify(input.checkpoint))
|
|
27397
27942
|
throw new Error("OpenCode checkpoint does not match native history");
|
|
27398
27943
|
}
|
|
27399
|
-
const before = turns[
|
|
27944
|
+
const before = turns[count2]?.nativeTurnRef.nativeTurnKey;
|
|
27400
27945
|
info = await client2.session.fork({ sessionID: parent.id, ...before ? { before } : {} });
|
|
27401
27946
|
if (info.id === parent.id)
|
|
27402
27947
|
throw new Error("OpenCode fork returned its source Session");
|
|
@@ -27411,7 +27956,7 @@ var V2Adapter = class {
|
|
|
27411
27956
|
await client2.session.switchModel({ sessionID: info.id, model: parent.model });
|
|
27412
27957
|
info = await client2.session.get({ sessionID: info.id });
|
|
27413
27958
|
const derived = await readHistory(client2, info, this.options.toolOutputLimit ?? 64e3);
|
|
27414
|
-
if (historyContent(derived.snapshot, false) !== historyContent({ turns: turns.slice(0,
|
|
27959
|
+
if (historyContent(derived.snapshot, false) !== historyContent({ turns: turns.slice(0, count2) }, false))
|
|
27415
27960
|
throw new Error("OpenCode fork did not preserve the exact history prefix");
|
|
27416
27961
|
if (!isDeepStrictEqual2(info.permissions ?? [], parent.permissions ?? []) || !isDeepStrictEqual2(info.model, parent.model))
|
|
27417
27962
|
throw new Error("OpenCode fork did not preserve the current configuration");
|
|
@@ -27460,14 +28005,14 @@ function selectedModel(input, catalog) {
|
|
|
27460
28005
|
throw new Error("Thinking selection requires a Model");
|
|
27461
28006
|
return void 0;
|
|
27462
28007
|
}
|
|
27463
|
-
const entry = catalog.models.find((
|
|
28008
|
+
const entry = catalog.models.find((model3) => model3.ref.id === selected.id);
|
|
27464
28009
|
if (!entry)
|
|
27465
28010
|
throw new Error("OpenCode Model is not available");
|
|
27466
28011
|
if (input.thinkingOptionId && !entry.supportedThinkingOptionIds?.includes(input.thinkingOptionId))
|
|
27467
28012
|
throw new Error("OpenCode Thinking option is not available for this Model");
|
|
27468
|
-
const
|
|
28013
|
+
const model2 = decodeOpenCodeModelRef(selected);
|
|
27469
28014
|
const variant = input.thinkingOptionId ? decodeOpenCodeVariant(input.thinkingOptionId) : void 0;
|
|
27470
|
-
return { providerID:
|
|
28015
|
+
return { providerID: model2.providerID, id: model2.modelID, ...variant ? { variant } : {} };
|
|
27471
28016
|
}
|
|
27472
28017
|
function historyContent(snapshot, identities = true) {
|
|
27473
28018
|
return JSON.stringify(snapshot.turns.map((turn) => ({
|
|
@@ -27491,9 +28036,11 @@ var OpenCodeAdapter2 = class {
|
|
|
27491
28036
|
commandCatalog = openCodeCommandCatalog;
|
|
27492
28037
|
#adapters = /* @__PURE__ */ new Set();
|
|
27493
28038
|
#closed = false;
|
|
28039
|
+
usageStatistics;
|
|
27494
28040
|
constructor(options = {}, dependencies) {
|
|
27495
28041
|
this.options = options;
|
|
27496
28042
|
this.dependencies = dependencies;
|
|
28043
|
+
this.usageStatistics = createOpenCodeUsageStatistics(options.environment ?? process.env);
|
|
27497
28044
|
}
|
|
27498
28045
|
async #select(environment, input) {
|
|
27499
28046
|
if (this.#closed)
|
|
@@ -27603,7 +28150,7 @@ function normalize(error51) {
|
|
|
27603
28150
|
// dist/installation.js
|
|
27604
28151
|
import { realpath as realpath2 } from "node:fs/promises";
|
|
27605
28152
|
import { homedir as homedir3 } from "node:os";
|
|
27606
|
-
import
|
|
28153
|
+
import path13 from "node:path";
|
|
27607
28154
|
function createOpenCodeInstallation(environment, command) {
|
|
27608
28155
|
let update;
|
|
27609
28156
|
return createInstallationManager({
|
|
@@ -27624,8 +28171,8 @@ function createOpenCodeInstallation(environment, command) {
|
|
|
27624
28171
|
const release = JSON.parse(await fetchInstallationText("https://api.github.com/repos/anomalyco/opencode/releases/latest"));
|
|
27625
28172
|
latestVersion = installationVersion(release.tag_name);
|
|
27626
28173
|
const home = environment.HOME ?? environment.USERPROFILE ?? homedir3();
|
|
27627
|
-
const standard =
|
|
27628
|
-
canUpdate = process.platform !== "win32" &&
|
|
28174
|
+
const standard = path13.join(home, ".opencode", "bin", process.platform === "win32" ? "opencode.exe" : "opencode");
|
|
28175
|
+
canUpdate = process.platform !== "win32" && path13.resolve(executable) === standard && await realpath2(executable) === standard;
|
|
27629
28176
|
update = async (version2) => {
|
|
27630
28177
|
await runInstallationCommand(executable, ["upgrade", version2, "--method", "curl"], environment, 3e5);
|
|
27631
28178
|
};
|