@codexhost/cli-linux-arm64 0.12.2 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/THIRD_PARTY_NOTICES.txt +9 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +319 -64
- package/app/console-web.js +5089 -1367
- package/app/desktop-controller.mjs +259 -41
- package/app/host-runtime.mjs +5735 -1564
- package/app/plugins/antigravity/manifest.json +18 -1
- package/app/plugins/antigravity/plugin.mjs +282 -41
- package/app/plugins/claude-code/manifest.json +28 -0
- package/app/plugins/claude-code/plugin.mjs +35300 -23918
- package/app/plugins/codebuddy/manifest.json +17 -0
- package/app/plugins/codebuddy/plugin.mjs +5971 -5355
- package/app/plugins/codex-usage/manifest.json +9 -0
- package/app/plugins/codex-usage/plugin.mjs +17324 -0
- package/app/plugins/cursor-cli/manifest.json +17 -0
- package/app/plugins/cursor-cli/plugin.mjs +357 -76
- 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 +822 -241
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/manifest.json +21 -1
- package/app/plugins/grok/plugin.mjs +918 -258
- package/app/plugins/hermes/assets/icon.png +0 -0
- package/app/plugins/hermes/manifest.json +30 -2
- package/app/plugins/hermes/plugin.mjs +284 -32
- 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 +561 -35
- 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 +290 -21
- package/app/plugins/omp/manifest.json +21 -1
- package/app/plugins/omp/plugin.mjs +2765 -1960
- package/app/plugins/opencode/manifest.json +18 -1
- package/app/plugins/opencode/plugin.mjs +723 -146
- package/app/plugins/pi/manifest.json +32 -0
- package/app/plugins/pi/plugin.mjs +2908 -2312
- package/app/plugins/qoder/manifest.json +18 -1
- package/app/plugins/qoder/plugin.mjs +634 -80
- package/app/plugins/qoder-cn/manifest.json +18 -1
- package/app/plugins/qoder-cn/plugin.mjs +634 -80
- package/app/plugins/workbuddy/manifest.json +18 -0
- package/app/plugins/workbuddy/plugin.mjs +6361 -5747
- package/app/plugins/zcode/manifest.json +19 -1
- package/app/plugins/zcode/plugin.mjs +1098 -259
- package/app/renderer-extension.js +13080 -8884
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +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,66 @@ 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
|
+
var MAX_SESSION_TITLE_LENGTH = 200;
|
|
499
|
+
function usageSessionTitle(value) {
|
|
500
|
+
if (typeof value !== "string")
|
|
501
|
+
return void 0;
|
|
502
|
+
const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
|
|
503
|
+
if (!normalized)
|
|
504
|
+
return void 0;
|
|
505
|
+
if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
|
|
506
|
+
return normalized;
|
|
507
|
+
const characters = [...normalized];
|
|
508
|
+
if (characters.length <= MAX_SESSION_TITLE_LENGTH)
|
|
509
|
+
return normalized;
|
|
510
|
+
return `${characters.slice(0, MAX_SESSION_TITLE_LENGTH - 1).join("").trimEnd()}…`;
|
|
511
|
+
}
|
|
512
|
+
function sessionIdOk(value) {
|
|
513
|
+
return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
|
|
514
|
+
}
|
|
515
|
+
function cwdOk(value) {
|
|
516
|
+
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("\\\\"));
|
|
517
|
+
}
|
|
518
|
+
function withUsageSession(entry, session) {
|
|
519
|
+
const sessionId = sessionIdOk(session.sessionId) ? session.sessionId : void 0;
|
|
520
|
+
const cwd = cwdOk(session.cwd) ? session.cwd : void 0;
|
|
521
|
+
const sessionTitle = sessionId !== void 0 ? usageSessionTitle(session.title) : void 0;
|
|
522
|
+
if (sessionId === void 0 && cwd === void 0)
|
|
523
|
+
return entry;
|
|
524
|
+
return {
|
|
525
|
+
...entry,
|
|
526
|
+
...sessionId !== void 0 ? { sessionId } : {},
|
|
527
|
+
...cwd !== void 0 ? { cwd } : {},
|
|
528
|
+
...sessionTitle !== void 0 ? { sessionTitle } : {}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
function usageEntryFromRequest(request, occurredAtMs) {
|
|
532
|
+
if (!Number.isSafeInteger(occurredAtMs) || occurredAtMs <= 0)
|
|
533
|
+
return null;
|
|
534
|
+
return {
|
|
535
|
+
id: request.requestId,
|
|
536
|
+
occurredAtMs,
|
|
537
|
+
...request.model !== void 0 ? { model: request.model } : {},
|
|
538
|
+
inputTokens: request.inputTokens,
|
|
539
|
+
...request.cachedInputTokens !== void 0 ? { cachedInputTokens: request.cachedInputTokens } : {},
|
|
540
|
+
...request.cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens: request.cacheWriteInputTokens } : {},
|
|
541
|
+
...request.cacheWrite1hInputTokens !== void 0 ? { cacheWrite1hInputTokens: request.cacheWrite1hInputTokens } : {},
|
|
542
|
+
outputTokens: request.outputTokens,
|
|
543
|
+
...request.reasoningOutputTokens !== void 0 ? { reasoningOutputTokens: request.reasoningOutputTokens } : {}
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
function nativeTimeMs(value) {
|
|
547
|
+
const time3 = typeof value === "number" ? value : typeof value === "string" ? Date.parse(value) : Number.NaN;
|
|
548
|
+
return Number.isFinite(time3) && time3 > 0 ? Math.floor(time3) : null;
|
|
549
|
+
}
|
|
494
550
|
|
|
495
551
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
496
552
|
var external_exports = {};
|
|
@@ -1258,10 +1314,10 @@ function mergeDefs(...defs) {
|
|
|
1258
1314
|
function cloneDef(schema) {
|
|
1259
1315
|
return mergeDefs(schema._zod.def);
|
|
1260
1316
|
}
|
|
1261
|
-
function getElementAtPath(obj,
|
|
1262
|
-
if (!
|
|
1317
|
+
function getElementAtPath(obj, path14) {
|
|
1318
|
+
if (!path14)
|
|
1263
1319
|
return obj;
|
|
1264
|
-
return
|
|
1320
|
+
return path14.reduce((acc, key) => acc?.[key], obj);
|
|
1265
1321
|
}
|
|
1266
1322
|
function promiseAllObject(promisesObj) {
|
|
1267
1323
|
const keys = Object.keys(promisesObj);
|
|
@@ -1670,11 +1726,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1670
1726
|
}
|
|
1671
1727
|
return false;
|
|
1672
1728
|
}
|
|
1673
|
-
function prefixIssues(
|
|
1729
|
+
function prefixIssues(path14, issues) {
|
|
1674
1730
|
return issues.map((iss) => {
|
|
1675
1731
|
var _a3;
|
|
1676
1732
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1677
|
-
iss.path.unshift(
|
|
1733
|
+
iss.path.unshift(path14);
|
|
1678
1734
|
return iss;
|
|
1679
1735
|
});
|
|
1680
1736
|
}
|
|
@@ -1821,16 +1877,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1821
1877
|
}
|
|
1822
1878
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1823
1879
|
const fieldErrors = { _errors: [] };
|
|
1824
|
-
const processError = (error52,
|
|
1880
|
+
const processError = (error52, path14 = []) => {
|
|
1825
1881
|
for (const issue2 of error52.issues) {
|
|
1826
1882
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1827
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1883
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1828
1884
|
} else if (issue2.code === "invalid_key") {
|
|
1829
|
-
processError({ issues: issue2.issues }, [...
|
|
1885
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1830
1886
|
} else if (issue2.code === "invalid_element") {
|
|
1831
|
-
processError({ issues: issue2.issues }, [...
|
|
1887
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1832
1888
|
} else {
|
|
1833
|
-
const fullpath = [...
|
|
1889
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1834
1890
|
if (fullpath.length === 0) {
|
|
1835
1891
|
fieldErrors._errors.push(mapper(issue2));
|
|
1836
1892
|
} else {
|
|
@@ -1857,17 +1913,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1857
1913
|
}
|
|
1858
1914
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1859
1915
|
const result = { errors: [] };
|
|
1860
|
-
const processError = (error52,
|
|
1916
|
+
const processError = (error52, path14 = []) => {
|
|
1861
1917
|
var _a3, _b;
|
|
1862
1918
|
for (const issue2 of error52.issues) {
|
|
1863
1919
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1864
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1920
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1865
1921
|
} else if (issue2.code === "invalid_key") {
|
|
1866
|
-
processError({ issues: issue2.issues }, [...
|
|
1922
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1867
1923
|
} else if (issue2.code === "invalid_element") {
|
|
1868
|
-
processError({ issues: issue2.issues }, [...
|
|
1924
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1869
1925
|
} else {
|
|
1870
|
-
const fullpath = [...
|
|
1926
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1871
1927
|
if (fullpath.length === 0) {
|
|
1872
1928
|
result.errors.push(mapper(issue2));
|
|
1873
1929
|
continue;
|
|
@@ -1899,8 +1955,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1899
1955
|
}
|
|
1900
1956
|
function toDotPath(_path) {
|
|
1901
1957
|
const segs = [];
|
|
1902
|
-
const
|
|
1903
|
-
for (const seg of
|
|
1958
|
+
const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1959
|
+
for (const seg of path14) {
|
|
1904
1960
|
if (typeof seg === "number")
|
|
1905
1961
|
segs.push(`[${seg}]`);
|
|
1906
1962
|
else if (typeof seg === "symbol")
|
|
@@ -5128,8 +5184,8 @@ function az_default() {
|
|
|
5128
5184
|
}
|
|
5129
5185
|
|
|
5130
5186
|
// ../../../node_modules/zod/v4/locales/be.js
|
|
5131
|
-
function getBelarusianPlural(
|
|
5132
|
-
const absCount = Math.abs(
|
|
5187
|
+
function getBelarusianPlural(count2, one, few, many) {
|
|
5188
|
+
const absCount = Math.abs(count2);
|
|
5133
5189
|
const lastDigit = absCount % 10;
|
|
5134
5190
|
const lastTwoDigits = absCount % 100;
|
|
5135
5191
|
if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
|
|
@@ -7207,8 +7263,8 @@ function hu_default() {
|
|
|
7207
7263
|
}
|
|
7208
7264
|
|
|
7209
7265
|
// ../../../node_modules/zod/v4/locales/hy.js
|
|
7210
|
-
function getArmenianPlural(
|
|
7211
|
-
return Math.abs(
|
|
7266
|
+
function getArmenianPlural(count2, one, many) {
|
|
7267
|
+
return Math.abs(count2) === 1 ? one : many;
|
|
7212
7268
|
}
|
|
7213
7269
|
function withDefiniteArticle(word) {
|
|
7214
7270
|
if (!word)
|
|
@@ -9336,8 +9392,8 @@ function ro_default() {
|
|
|
9336
9392
|
}
|
|
9337
9393
|
|
|
9338
9394
|
// ../../../node_modules/zod/v4/locales/ru.js
|
|
9339
|
-
function getRussianPlural(
|
|
9340
|
-
const absCount = Math.abs(
|
|
9395
|
+
function getRussianPlural(count2, one, few, many) {
|
|
9396
|
+
const absCount = Math.abs(count2);
|
|
9341
9397
|
const lastDigit = absCount % 10;
|
|
9342
9398
|
const lastTwoDigits = absCount % 100;
|
|
9343
9399
|
if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
|
|
@@ -14592,13 +14648,13 @@ function resolveRef(ref, ctx) {
|
|
|
14592
14648
|
if (!ref.startsWith("#")) {
|
|
14593
14649
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14594
14650
|
}
|
|
14595
|
-
const
|
|
14596
|
-
if (
|
|
14651
|
+
const path14 = ref.slice(1).split("/").filter(Boolean);
|
|
14652
|
+
if (path14.length === 0) {
|
|
14597
14653
|
return ctx.rootSchema;
|
|
14598
14654
|
}
|
|
14599
14655
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14600
|
-
if (
|
|
14601
|
-
const key =
|
|
14656
|
+
if (path14[0] === defsKey) {
|
|
14657
|
+
const key = path14[1];
|
|
14602
14658
|
if (!key || !ctx.defs[key]) {
|
|
14603
14659
|
throw new Error(`Reference not found: ${ref}`);
|
|
14604
14660
|
}
|
|
@@ -15006,6 +15062,15 @@ function date4(params) {
|
|
|
15006
15062
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15007
15063
|
config(en_default());
|
|
15008
15064
|
|
|
15065
|
+
// ../../shared-contracts/dist/delegation-read.js
|
|
15066
|
+
var REMOTE_THREAD_REPLY_MAX_BYTES = 16 * 1024 * 1024;
|
|
15067
|
+
var delegationReadParamsSchema = external_exports.strictObject({
|
|
15068
|
+
threadId: external_exports.string().min(1).max(1024),
|
|
15069
|
+
view: external_exports.enum(["result", "messages"]),
|
|
15070
|
+
cursor: external_exports.string().min(1).max(8192).optional(),
|
|
15071
|
+
limit: external_exports.number().int().min(1).max(100).optional()
|
|
15072
|
+
});
|
|
15073
|
+
|
|
15009
15074
|
// ../../shared-contracts/dist/credential-imports.js
|
|
15010
15075
|
var credentialSourceSchema = external_exports.object({
|
|
15011
15076
|
id: external_exports.string().min(1).max(256),
|
|
@@ -15076,6 +15141,160 @@ var harnessDisplaySetSchema = external_exports.strictObject({
|
|
|
15076
15141
|
initializeOnly: external_exports.boolean().optional()
|
|
15077
15142
|
});
|
|
15078
15143
|
|
|
15144
|
+
// ../../shared-contracts/dist/model-price-overrides.js
|
|
15145
|
+
var usdPerMillionTokens = external_exports.number().finite().nonnegative();
|
|
15146
|
+
var modelPriceOverrideSchema = external_exports.strictObject({
|
|
15147
|
+
input: usdPerMillionTokens,
|
|
15148
|
+
output: usdPerMillionTokens,
|
|
15149
|
+
cacheRead: usdPerMillionTokens.optional(),
|
|
15150
|
+
cacheWrite: usdPerMillionTokens.optional(),
|
|
15151
|
+
cacheWrite1h: usdPerMillionTokens.optional()
|
|
15152
|
+
});
|
|
15153
|
+
var modelPriceKeySchema = external_exports.string().max(512).refine((key) => key.trim() === key && key.length > 0, "Model ID is required");
|
|
15154
|
+
var modelPriceOverridesSchema = external_exports.strictObject({
|
|
15155
|
+
/** Absolute path of the Host's `pricing.json`. */
|
|
15156
|
+
path: external_exports.string(),
|
|
15157
|
+
entries: external_exports.array(external_exports.strictObject({ key: external_exports.string(), price: modelPriceOverrideSchema })),
|
|
15158
|
+
/** Why the existing file is unusable; the Host then ignores it and refuses to overwrite it. */
|
|
15159
|
+
error: external_exports.string().nullable()
|
|
15160
|
+
});
|
|
15161
|
+
var modelPriceOverridesGetSchema = external_exports.strictObject({});
|
|
15162
|
+
var modelPriceOverridesSetSchema = external_exports.strictObject({
|
|
15163
|
+
key: modelPriceKeySchema,
|
|
15164
|
+
price: modelPriceOverrideSchema.nullable(),
|
|
15165
|
+
previousKey: modelPriceKeySchema.optional()
|
|
15166
|
+
});
|
|
15167
|
+
var modelPriceDefaultParamsSchema = external_exports.strictObject({
|
|
15168
|
+
model: modelPriceKeySchema
|
|
15169
|
+
});
|
|
15170
|
+
var modelPriceSuggestionSchema = external_exports.strictObject({
|
|
15171
|
+
/** Verified from catalog canonical links, not inferred from names or equal prices. */
|
|
15172
|
+
official: external_exports.boolean().optional(),
|
|
15173
|
+
canonicalModelId: external_exports.string().min(1).optional(),
|
|
15174
|
+
provider: external_exports.string().min(1).max(512),
|
|
15175
|
+
model: external_exports.string().min(1).max(512),
|
|
15176
|
+
price: modelPriceOverrideSchema
|
|
15177
|
+
});
|
|
15178
|
+
var modelPriceDefaultResultSchema = external_exports.strictObject({
|
|
15179
|
+
price: modelPriceOverrideSchema.nullable(),
|
|
15180
|
+
/** Local catalog suggestions only; never used automatically for pricing. */
|
|
15181
|
+
suggestions: external_exports.array(modelPriceSuggestionSchema).max(6).optional()
|
|
15182
|
+
});
|
|
15183
|
+
|
|
15184
|
+
// ../../shared-contracts/dist/usage-statistics.js
|
|
15185
|
+
var USAGE_STATISTICS_RANGES = ["today", "7d", "30d", "90d", "all"];
|
|
15186
|
+
var count = external_exports.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
|
|
15187
|
+
var localDate = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/u);
|
|
15188
|
+
var harness = external_exports.string().min(1).max(128);
|
|
15189
|
+
var model = external_exports.string().min(1).max(512);
|
|
15190
|
+
var project = external_exports.string().min(1).max(4096);
|
|
15191
|
+
var usageStatisticsParamsSchema = external_exports.strictObject({
|
|
15192
|
+
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
15193
|
+
harness: harness.optional(),
|
|
15194
|
+
model: model.nullable().optional(),
|
|
15195
|
+
project: project.nullable().optional(),
|
|
15196
|
+
/** One local date inside the range. */
|
|
15197
|
+
date: localDate.optional()
|
|
15198
|
+
});
|
|
15199
|
+
var usageStatisticsTotalsSchema = external_exports.strictObject({
|
|
15200
|
+
requests: count,
|
|
15201
|
+
inputTokens: count,
|
|
15202
|
+
cachedInputTokens: count,
|
|
15203
|
+
cacheWriteInputTokens: count,
|
|
15204
|
+
cacheKnownInputTokens: count,
|
|
15205
|
+
outputTokens: count,
|
|
15206
|
+
reasoningOutputTokens: count,
|
|
15207
|
+
/** USD at the public price, summed over the priced requests only. */
|
|
15208
|
+
costUsd: external_exports.number().finite().min(0),
|
|
15209
|
+
/** Requests without a price (or the cache data the price needs); not in `costUsd`. */
|
|
15210
|
+
unpricedRequests: count,
|
|
15211
|
+
/**
|
|
15212
|
+
* Requests whose storage gave no token counts: counted as requests, with neither tokens nor
|
|
15213
|
+
* cost, and not as unpriced.
|
|
15214
|
+
*/
|
|
15215
|
+
unmeteredRequests: count
|
|
15216
|
+
});
|
|
15217
|
+
var totals = usageStatisticsTotalsSchema.shape;
|
|
15218
|
+
var usageStatisticsSessionSchema = external_exports.strictObject({
|
|
15219
|
+
harness,
|
|
15220
|
+
sessionId: external_exports.string().min(1).max(512),
|
|
15221
|
+
project: project.nullable(),
|
|
15222
|
+
/** Persisted Desktop title for a mapped Session, otherwise its native name; may be absent. */
|
|
15223
|
+
title: external_exports.string().min(1).max(200).optional(),
|
|
15224
|
+
/** Models the session used, most requests first. */
|
|
15225
|
+
models: external_exports.array(model).max(16),
|
|
15226
|
+
firstAtMs: count,
|
|
15227
|
+
lastAtMs: count,
|
|
15228
|
+
...totals
|
|
15229
|
+
});
|
|
15230
|
+
var usageStatisticsResultSchema = external_exports.strictObject({
|
|
15231
|
+
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
15232
|
+
/** First local date of the range; null for all time. */
|
|
15233
|
+
from: localDate.nullable(),
|
|
15234
|
+
to: localDate,
|
|
15235
|
+
/** The filters these figures apply, echoed so a late answer to older filters is recognised. */
|
|
15236
|
+
filters: external_exports.strictObject({
|
|
15237
|
+
harness: harness.nullable(),
|
|
15238
|
+
model: model.nullable(),
|
|
15239
|
+
unknownModel: external_exports.boolean(),
|
|
15240
|
+
project: project.nullable(),
|
|
15241
|
+
unknownProject: external_exports.boolean(),
|
|
15242
|
+
date: localDate.nullable()
|
|
15243
|
+
}),
|
|
15244
|
+
/** Reading of native storage: incomplete while the first read, or a refresh, is under way. */
|
|
15245
|
+
reading: external_exports.strictObject({ complete: external_exports.boolean(), sources: count, read: count }),
|
|
15246
|
+
/** Harnesses whose storage could not be read; their part is missing, the rest is complete. */
|
|
15247
|
+
failures: external_exports.array(external_exports.strictObject({ harness, message: external_exports.string().max(2048) })).max(256),
|
|
15248
|
+
/** Every value seen in the range, ignoring the filters, to choose filters from. */
|
|
15249
|
+
options: external_exports.strictObject({
|
|
15250
|
+
harnesses: external_exports.array(harness).max(256),
|
|
15251
|
+
models: external_exports.array(model.nullable()).max(4096),
|
|
15252
|
+
projects: external_exports.array(project.nullable()).max(4096)
|
|
15253
|
+
}),
|
|
15254
|
+
/** Current display metadata, scoped by Harness. Never a pricing or filter identity.
|
|
15255
|
+
* Optional for older Hosts; missing/conflicting labels fall back to the native model ID.
|
|
15256
|
+
*/
|
|
15257
|
+
modelLabels: external_exports.array(external_exports.strictObject({ harness, model, label: model })).max(4096).optional(),
|
|
15258
|
+
/** Native credits, all filters applied, never combined across Harnesses or treated as USD.
|
|
15259
|
+
* Only groups with at least one reported value appear; reportedRequests exposes partial data.
|
|
15260
|
+
*/
|
|
15261
|
+
credits: external_exports.array(external_exports.strictObject({
|
|
15262
|
+
harness,
|
|
15263
|
+
model: model.nullable(),
|
|
15264
|
+
credits: external_exports.number().finite().min(0),
|
|
15265
|
+
reportedRequests: count,
|
|
15266
|
+
requests: count
|
|
15267
|
+
})).max(4096).optional(),
|
|
15268
|
+
/** All filters applied. */
|
|
15269
|
+
totals: usageStatisticsTotalsSchema,
|
|
15270
|
+
/** Each date and Harness of the range: every filter except the day. */
|
|
15271
|
+
daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
|
|
15272
|
+
/** Local weekday (0 = Sunday) and hour, all filters applied. */
|
|
15273
|
+
hourly: external_exports.array(external_exports.strictObject({
|
|
15274
|
+
weekday: external_exports.number().int().min(0).max(6),
|
|
15275
|
+
hour: external_exports.number().int().min(0).max(23),
|
|
15276
|
+
...totals
|
|
15277
|
+
})).max(168),
|
|
15278
|
+
byHarness: external_exports.array(external_exports.strictObject({ harness, ...totals })).max(256),
|
|
15279
|
+
byModel: external_exports.array(external_exports.strictObject({
|
|
15280
|
+
model: model.nullable(),
|
|
15281
|
+
...totals,
|
|
15282
|
+
/** Requests priced by what the Harness recorded they cost, not by a price list. */
|
|
15283
|
+
harnessPricedRequests: count
|
|
15284
|
+
})).max(4096),
|
|
15285
|
+
byProject: external_exports.array(external_exports.strictObject({ project: project.nullable(), ...totals })).max(4096),
|
|
15286
|
+
/**
|
|
15287
|
+
* The sessions that spent the most, by cost and by tokens without cache, all filters applied;
|
|
15288
|
+
* requests without a native session are not listed here but count everywhere else.
|
|
15289
|
+
*/
|
|
15290
|
+
sessions: external_exports.array(usageStatisticsSessionSchema).max(100),
|
|
15291
|
+
/**
|
|
15292
|
+
* The sessions last active in the range, newest first, all filters applied. Optional for older
|
|
15293
|
+
* Hosts; missing is treated as no list rather than no sessions.
|
|
15294
|
+
*/
|
|
15295
|
+
recentSessions: external_exports.array(usageStatisticsSessionSchema).max(100).optional()
|
|
15296
|
+
});
|
|
15297
|
+
|
|
15079
15298
|
// ../../shared-contracts/dist/ids.js
|
|
15080
15299
|
var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
|
|
15081
15300
|
message: "Identifier must not be empty or whitespace"
|
|
@@ -15123,6 +15342,10 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
15123
15342
|
"codexhost/account/list",
|
|
15124
15343
|
"codexhost/account/refresh",
|
|
15125
15344
|
"codexhost/account/usage/inspect",
|
|
15345
|
+
"codexhost/usage/model-prices/get",
|
|
15346
|
+
"codexhost/usage/model-prices/set",
|
|
15347
|
+
"codexhost/usage/model-prices/default",
|
|
15348
|
+
"codexhost/usage/statistics/get",
|
|
15126
15349
|
"codexhost/update/check",
|
|
15127
15350
|
"codexhost/update/start",
|
|
15128
15351
|
"codexhost/update/status"
|
|
@@ -15187,6 +15410,7 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
15187
15410
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15188
15411
|
outputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15189
15412
|
outputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
|
|
15413
|
+
apiOutputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
|
|
15190
15414
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15191
15415
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15192
15416
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
@@ -15198,7 +15422,11 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
15198
15422
|
planFiveHourUsedPercent: cacheHitRatePercentSchema.optional(),
|
|
15199
15423
|
planFiveHourResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
|
|
15200
15424
|
planSevenDayUsedPercent: cacheHitRatePercentSchema.optional(),
|
|
15201
|
-
planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional()
|
|
15425
|
+
planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
|
|
15426
|
+
sessionCacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
15427
|
+
timeToFirstOutputMs: nonNegativeSafeIntegerSchema.optional(),
|
|
15428
|
+
costSource: external_exports.enum(["publicPrice", "native"]).optional(),
|
|
15429
|
+
unpricedModels: external_exports.array(external_exports.string().min(1)).min(1).optional()
|
|
15202
15430
|
}).strict().superRefine((usage, context) => {
|
|
15203
15431
|
if (Object.keys(usage).length === 0) {
|
|
15204
15432
|
context.addIssue({ code: "custom", message: "Thread Usage must contain a reliable field" });
|
|
@@ -15219,6 +15447,20 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
15219
15447
|
path: ["contextWindowTokens"]
|
|
15220
15448
|
});
|
|
15221
15449
|
}
|
|
15450
|
+
if (usage.costSource !== void 0 && usage.totalCostUsd === void 0) {
|
|
15451
|
+
context.addIssue({
|
|
15452
|
+
code: "custom",
|
|
15453
|
+
message: "Thread Usage costSource must be provided with totalCostUsd",
|
|
15454
|
+
path: ["costSource"]
|
|
15455
|
+
});
|
|
15456
|
+
}
|
|
15457
|
+
if (usage.unpricedModels !== void 0 && usage.costSource !== "publicPrice") {
|
|
15458
|
+
context.addIssue({
|
|
15459
|
+
code: "custom",
|
|
15460
|
+
message: "Thread Usage unpricedModels must be provided with a publicPrice cost",
|
|
15461
|
+
path: ["unpricedModels"]
|
|
15462
|
+
});
|
|
15463
|
+
}
|
|
15222
15464
|
if (usage.planFiveHourResetsAtUnix !== void 0 && usage.planFiveHourUsedPercent === void 0) {
|
|
15223
15465
|
context.addIssue({
|
|
15224
15466
|
code: "custom",
|
|
@@ -15473,27 +15715,27 @@ var harnessModelCatalogSchema = external_exports.object({
|
|
|
15473
15715
|
}).strict().superRefine((catalog, context) => {
|
|
15474
15716
|
const refs = /* @__PURE__ */ new Set();
|
|
15475
15717
|
const thinkingIds = new Set(catalog.thinkingOptions.map(({ id }) => id));
|
|
15476
|
-
for (const [index,
|
|
15477
|
-
if (refs.has(
|
|
15718
|
+
for (const [index, model2] of catalog.models.entries()) {
|
|
15719
|
+
if (refs.has(model2.ref.id)) {
|
|
15478
15720
|
context.addIssue({
|
|
15479
15721
|
code: "custom",
|
|
15480
15722
|
message: "Model Catalog refs must be unique",
|
|
15481
15723
|
path: ["models", index, "ref", "id"]
|
|
15482
15724
|
});
|
|
15483
15725
|
}
|
|
15484
|
-
refs.add(
|
|
15485
|
-
if (
|
|
15486
|
-
if (refs.has(
|
|
15726
|
+
refs.add(model2.ref.id);
|
|
15727
|
+
if (model2.fastModel) {
|
|
15728
|
+
if (refs.has(model2.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model2.fastModel?.id)) {
|
|
15487
15729
|
context.addIssue({
|
|
15488
15730
|
code: "custom",
|
|
15489
15731
|
message: "Fast Model refs must be distinct and unique",
|
|
15490
15732
|
path: ["models", index, "fastModel"]
|
|
15491
15733
|
});
|
|
15492
15734
|
}
|
|
15493
|
-
refs.add(
|
|
15735
|
+
refs.add(model2.fastModel.id);
|
|
15494
15736
|
}
|
|
15495
15737
|
const supportedThinkingIds = /* @__PURE__ */ new Set();
|
|
15496
|
-
for (const [optionIndex, optionId] of (
|
|
15738
|
+
for (const [optionIndex, optionId] of (model2.supportedThinkingOptionIds ?? []).entries()) {
|
|
15497
15739
|
if (supportedThinkingIds.has(optionId)) {
|
|
15498
15740
|
context.addIssue({
|
|
15499
15741
|
code: "custom",
|
|
@@ -15687,13 +15929,40 @@ var HARNESS_PLUGIN_LIMIT = 128;
|
|
|
15687
15929
|
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
15930
|
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
15931
|
var documentationUrlSchema = external_exports.url().refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Plugin documentation links must be credential-free HTTPS URLs");
|
|
15932
|
+
var localizedTextSchema = external_exports.object({ en: external_exports.string().max(4096), "zh-CN": external_exports.string().max(4096).optional() }).strict();
|
|
15933
|
+
var harnessInstallationGuideSchema = external_exports.object({
|
|
15934
|
+
commands: external_exports.array(external_exports.object({ terminal: external_exports.string().max(256), command: external_exports.string().max(4096) }).strict()).max(8),
|
|
15935
|
+
before: localizedTextSchema.optional(),
|
|
15936
|
+
after: localizedTextSchema.optional(),
|
|
15937
|
+
downloads: external_exports.array(external_exports.object({ label: external_exports.string().max(128), url: documentationUrlSchema }).strict()).max(8).optional()
|
|
15938
|
+
}).strict();
|
|
15690
15939
|
var pluginPresentationShape = {
|
|
15691
15940
|
id: harnessPluginIdSchema,
|
|
15692
15941
|
name: external_exports.string().trim().min(1).max(128),
|
|
15693
15942
|
version: external_exports.string().min(1).max(128),
|
|
15943
|
+
/** Capability-only plugin; omitted for existing session-capable plugins. */
|
|
15944
|
+
kind: external_exports.literal("usage").optional(),
|
|
15945
|
+
/** Original image styling or bounded vector paths; never arbitrary CSS/SVG markup. */
|
|
15946
|
+
iconStyle: external_exports.object({
|
|
15947
|
+
vector: external_exports.object({
|
|
15948
|
+
viewBox: external_exports.string().max(128).regex(/^-?\d+(?:\.\d+)?(?: +-?\d+(?:\.\d+)?){3}$/u),
|
|
15949
|
+
color: external_exports.string().regex(/^(?:currentColor|#[a-f0-9]{6})$/iu),
|
|
15950
|
+
paths: external_exports.array(external_exports.object({
|
|
15951
|
+
d: external_exports.string().min(1).max(32768).regex(/^[MmLlHhVvCcSsQqTtAaZz\d.,+eE\s-]+$/u),
|
|
15952
|
+
fillRule: external_exports.enum(["evenodd", "nonzero"]).optional(),
|
|
15953
|
+
fill: external_exports.string().regex(/^(?:currentColor|#[a-f0-9]{6})$/iu).optional()
|
|
15954
|
+
}).strict()).min(1).max(32)
|
|
15955
|
+
}).strict().optional(),
|
|
15956
|
+
background: external_exports.string().regex(/^#[a-f0-9]{6}$/iu).optional(),
|
|
15957
|
+
borderRadius: external_exports.number().min(0).max(50).optional(),
|
|
15958
|
+
paddingRatio: external_exports.number().min(0).max(0.25).optional()
|
|
15959
|
+
}).strict().optional(),
|
|
15960
|
+
installation: harnessInstallationGuideSchema.optional(),
|
|
15961
|
+
notice: localizedTextSchema.optional(),
|
|
15694
15962
|
/** The factory accepts a persisted local entrypoint through its construction context. */
|
|
15695
15963
|
launchCommand: external_exports.literal(true).optional(),
|
|
15696
15964
|
links: external_exports.object({
|
|
15965
|
+
website: documentationUrlSchema.optional(),
|
|
15697
15966
|
documentation: documentationUrlSchema.optional(),
|
|
15698
15967
|
installation: documentationUrlSchema.optional()
|
|
15699
15968
|
}).strict().optional()
|
|
@@ -16112,6 +16381,11 @@ var codexSshDraftSchema = external_exports.strictObject({
|
|
|
16112
16381
|
});
|
|
16113
16382
|
var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
|
|
16114
16383
|
external_exports.strictObject({ action: external_exports.literal("list") }),
|
|
16384
|
+
external_exports.strictObject({
|
|
16385
|
+
action: external_exports.literal("read-thread"),
|
|
16386
|
+
hostId: hostId.refine((id) => id !== "local"),
|
|
16387
|
+
input: delegationReadParamsSchema
|
|
16388
|
+
}),
|
|
16115
16389
|
external_exports.strictObject({
|
|
16116
16390
|
action: external_exports.literal("save"),
|
|
16117
16391
|
draft: codexSshDraftSchema,
|
|
@@ -16250,10 +16524,12 @@ var tokenFields = [
|
|
|
16250
16524
|
];
|
|
16251
16525
|
var safeIntegerFields = [
|
|
16252
16526
|
"planFiveHourResetsAtUnix",
|
|
16253
|
-
"planSevenDayResetsAtUnix"
|
|
16527
|
+
"planSevenDayResetsAtUnix",
|
|
16528
|
+
"timeToFirstOutputMs"
|
|
16254
16529
|
];
|
|
16255
16530
|
var percentFields = [
|
|
16256
16531
|
"cacheHitRatePercent",
|
|
16532
|
+
"sessionCacheHitRatePercent",
|
|
16257
16533
|
"planFiveHourUsedPercent",
|
|
16258
16534
|
"planSevenDayUsedPercent"
|
|
16259
16535
|
];
|
|
@@ -16261,10 +16537,14 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
16261
16537
|
...tokenFields,
|
|
16262
16538
|
...safeIntegerFields,
|
|
16263
16539
|
...percentFields,
|
|
16540
|
+
"sessionCacheUsage",
|
|
16264
16541
|
"totalCostUsd",
|
|
16265
16542
|
"totalCredits",
|
|
16266
16543
|
"contextUsagePercent",
|
|
16267
|
-
"outputTokensPerSecond"
|
|
16544
|
+
"outputTokensPerSecond",
|
|
16545
|
+
"apiOutputTokensPerSecond",
|
|
16546
|
+
"costSource",
|
|
16547
|
+
"unpricedModels"
|
|
16268
16548
|
]);
|
|
16269
16549
|
function isRecord(value) {
|
|
16270
16550
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -16280,7 +16560,11 @@ function parseHostUsage(value) {
|
|
|
16280
16560
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
16281
16561
|
}
|
|
16282
16562
|
}
|
|
16283
|
-
for (const field of [
|
|
16563
|
+
for (const field of [
|
|
16564
|
+
"totalCredits",
|
|
16565
|
+
"contextUsagePercent",
|
|
16566
|
+
"apiOutputTokensPerSecond"
|
|
16567
|
+
]) {
|
|
16284
16568
|
const candidate2 = value[field];
|
|
16285
16569
|
if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isFinite(candidate2) || candidate2 < 0)) {
|
|
16286
16570
|
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
@@ -16310,6 +16594,12 @@ function parseHostUsage(value) {
|
|
|
16310
16594
|
throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
|
|
16311
16595
|
}
|
|
16312
16596
|
}
|
|
16597
|
+
if (value.sessionCacheUsage !== void 0) {
|
|
16598
|
+
const totals2 = value.sessionCacheUsage;
|
|
16599
|
+
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) {
|
|
16600
|
+
throw new Error("Harness Usage 'sessionCacheUsage' must contain complete bounded token totals");
|
|
16601
|
+
}
|
|
16602
|
+
}
|
|
16313
16603
|
const hasContextUsed = value.contextUsedTokens !== void 0;
|
|
16314
16604
|
const hasContextWindow = value.contextWindowTokens !== void 0;
|
|
16315
16605
|
if (hasContextUsed !== hasContextWindow) {
|
|
@@ -16324,8 +16614,224 @@ function parseHostUsage(value) {
|
|
|
16324
16614
|
if (value.planSevenDayResetsAtUnix !== void 0 && value.planSevenDayUsedPercent === void 0) {
|
|
16325
16615
|
throw new Error("Harness Usage 'planSevenDayResetsAtUnix' must be provided with 'planSevenDayUsedPercent'");
|
|
16326
16616
|
}
|
|
16617
|
+
if (value.costSource !== void 0) {
|
|
16618
|
+
if (value.costSource !== "publicPrice" && value.costSource !== "native") {
|
|
16619
|
+
throw new Error("Harness Usage 'costSource' must be 'publicPrice' or 'native'");
|
|
16620
|
+
}
|
|
16621
|
+
if (value.totalCostUsd === void 0) {
|
|
16622
|
+
throw new Error("Harness Usage 'costSource' must be provided with 'totalCostUsd'");
|
|
16623
|
+
}
|
|
16624
|
+
}
|
|
16625
|
+
if (value.unpricedModels !== void 0) {
|
|
16626
|
+
const models = value.unpricedModels;
|
|
16627
|
+
if (!Array.isArray(models) || models.length === 0 || !models.every((model2) => typeof model2 === "string" && model2.length > 0)) {
|
|
16628
|
+
throw new Error("Harness Usage 'unpricedModels' must be a non-empty list of Model IDs");
|
|
16629
|
+
}
|
|
16630
|
+
if (value.costSource !== "publicPrice") {
|
|
16631
|
+
throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
|
|
16632
|
+
}
|
|
16633
|
+
return { ...value, unpricedModels: [...models] };
|
|
16634
|
+
}
|
|
16327
16635
|
return { ...value };
|
|
16328
16636
|
}
|
|
16637
|
+
var requestTokenFields = [
|
|
16638
|
+
"inputTokens",
|
|
16639
|
+
"cachedInputTokens",
|
|
16640
|
+
"cacheWriteInputTokens",
|
|
16641
|
+
"cacheWrite1hInputTokens",
|
|
16642
|
+
"outputTokens",
|
|
16643
|
+
"reasoningOutputTokens",
|
|
16644
|
+
"startedAtMs",
|
|
16645
|
+
"completedAtMs"
|
|
16646
|
+
];
|
|
16647
|
+
var requestFields = /* @__PURE__ */ new Set([
|
|
16648
|
+
...requestTokenFields,
|
|
16649
|
+
"requestId",
|
|
16650
|
+
"historical",
|
|
16651
|
+
"model",
|
|
16652
|
+
"provider"
|
|
16653
|
+
]);
|
|
16654
|
+
function parseHostUsageRequest(value) {
|
|
16655
|
+
if (!isRecord(value))
|
|
16656
|
+
throw new Error("Harness Usage request must be an object");
|
|
16657
|
+
for (const key of Object.keys(value)) {
|
|
16658
|
+
if (!requestFields.has(key)) {
|
|
16659
|
+
throw new Error(`Harness Usage request contains unknown field '${key}'`);
|
|
16660
|
+
}
|
|
16661
|
+
}
|
|
16662
|
+
if (typeof value.requestId !== "string" || value.requestId.length === 0) {
|
|
16663
|
+
throw new Error("Harness Usage request 'requestId' must be a non-empty string");
|
|
16664
|
+
}
|
|
16665
|
+
for (const field of ["model", "provider"]) {
|
|
16666
|
+
const candidate2 = value[field];
|
|
16667
|
+
if (candidate2 !== void 0 && (typeof candidate2 !== "string" || candidate2.length === 0)) {
|
|
16668
|
+
throw new Error(`Harness Usage request '${field}' must be a non-empty string`);
|
|
16669
|
+
}
|
|
16670
|
+
}
|
|
16671
|
+
if (value.historical !== void 0 && typeof value.historical !== "boolean") {
|
|
16672
|
+
throw new Error("Harness Usage request 'historical' must be a boolean");
|
|
16673
|
+
}
|
|
16674
|
+
for (const field of requestTokenFields) {
|
|
16675
|
+
const candidate2 = value[field];
|
|
16676
|
+
if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isSafeInteger(candidate2) || candidate2 < 0)) {
|
|
16677
|
+
throw new Error(`Harness Usage request '${field}' must be a non-negative safe integer`);
|
|
16678
|
+
}
|
|
16679
|
+
}
|
|
16680
|
+
if (value.inputTokens === void 0 || value.outputTokens === void 0) {
|
|
16681
|
+
throw new Error("Harness Usage request must contain 'inputTokens' and 'outputTokens'");
|
|
16682
|
+
}
|
|
16683
|
+
const request = value;
|
|
16684
|
+
if ((request.cachedInputTokens ?? 0) + (request.cacheWriteInputTokens ?? 0) > request.inputTokens) {
|
|
16685
|
+
throw new Error("Harness Usage request cache Tokens must not exceed 'inputTokens'");
|
|
16686
|
+
}
|
|
16687
|
+
if ((request.reasoningOutputTokens ?? 0) > request.outputTokens) {
|
|
16688
|
+
throw new Error("Harness Usage request 'reasoningOutputTokens' must not exceed 'outputTokens'");
|
|
16689
|
+
}
|
|
16690
|
+
if (request.cacheWrite1hInputTokens !== void 0 && request.cacheWrite1hInputTokens > (request.cacheWriteInputTokens ?? -1)) {
|
|
16691
|
+
throw new Error("Harness Usage request 'cacheWrite1hInputTokens' must not exceed 'cacheWriteInputTokens'");
|
|
16692
|
+
}
|
|
16693
|
+
if (request.startedAtMs === void 0 !== (request.completedAtMs === void 0)) {
|
|
16694
|
+
throw new Error("Harness Usage request timing fields must be provided together");
|
|
16695
|
+
}
|
|
16696
|
+
if (request.startedAtMs !== void 0 && request.completedAtMs !== void 0 && request.completedAtMs < request.startedAtMs) {
|
|
16697
|
+
throw new Error("Harness Usage request 'completedAtMs' must not precede 'startedAtMs'");
|
|
16698
|
+
}
|
|
16699
|
+
return { ...request };
|
|
16700
|
+
}
|
|
16701
|
+
|
|
16702
|
+
// dist/v2/usage.js
|
|
16703
|
+
function v2UsageRequest(message, historical, firstOutputAtMs) {
|
|
16704
|
+
if (message.type !== "assistant" || !message.tokens)
|
|
16705
|
+
return null;
|
|
16706
|
+
const { input, output, reasoning, cache } = message.tokens;
|
|
16707
|
+
const { streamed } = message.time;
|
|
16708
|
+
return parseHostUsageRequest({
|
|
16709
|
+
requestId: message.id,
|
|
16710
|
+
...historical ? { historical: true } : {},
|
|
16711
|
+
model: message.model.id,
|
|
16712
|
+
// Built-in OpenCode providers use models.dev IDs. A custom provider ID matches no price
|
|
16713
|
+
// entry, so Host falls back to the exact model ID.
|
|
16714
|
+
provider: message.model.providerID,
|
|
16715
|
+
inputTokens: input + cache.read + cache.write,
|
|
16716
|
+
cachedInputTokens: cache.read,
|
|
16717
|
+
cacheWriteInputTokens: cache.write,
|
|
16718
|
+
outputTokens: output + reasoning,
|
|
16719
|
+
reasoningOutputTokens: reasoning,
|
|
16720
|
+
// End at stream completion, not step completion, which can include tool execution.
|
|
16721
|
+
// Without a native stream end, keep the usage but do not guess its generation duration.
|
|
16722
|
+
...!historical && firstOutputAtMs !== void 0 && streamed !== void 0 && streamed >= firstOutputAtMs ? { startedAtMs: firstOutputAtMs, completedAtMs: streamed } : {}
|
|
16723
|
+
});
|
|
16724
|
+
}
|
|
16725
|
+
|
|
16726
|
+
// dist/usage-statistics.js
|
|
16727
|
+
function parseRowData(data) {
|
|
16728
|
+
try {
|
|
16729
|
+
return JSON.parse(String(data));
|
|
16730
|
+
} catch {
|
|
16731
|
+
return null;
|
|
16732
|
+
}
|
|
16733
|
+
}
|
|
16734
|
+
function isRecord2(value) {
|
|
16735
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16736
|
+
}
|
|
16737
|
+
function openCodeDatabasePath(environment) {
|
|
16738
|
+
const home = environment.HOME || environment.USERPROFILE || os2.homedir();
|
|
16739
|
+
const directory = path5.join(environment.XDG_DATA_HOME || path5.join(home, ".local", "share"), "opencode");
|
|
16740
|
+
const configured = environment.OPENCODE_DB;
|
|
16741
|
+
if (configured === ":memory:")
|
|
16742
|
+
return null;
|
|
16743
|
+
return configured ? path5.resolve(directory, configured) : path5.join(directory, "opencode.db");
|
|
16744
|
+
}
|
|
16745
|
+
async function fingerprint(file2) {
|
|
16746
|
+
const info = await lstat(file2).catch(() => null);
|
|
16747
|
+
if (!info?.isFile())
|
|
16748
|
+
return null;
|
|
16749
|
+
const wal = await lstat(`${file2}-wal`).catch(() => null);
|
|
16750
|
+
return `${info.ino}:${info.size}:${info.mtimeMs}:${wal ? `${wal.size}:${wal.mtimeMs}` : "-"}`;
|
|
16751
|
+
}
|
|
16752
|
+
async function readOpenCodeUsage(file2) {
|
|
16753
|
+
const { DatabaseSync } = await import("node:sqlite");
|
|
16754
|
+
const database = new DatabaseSync(file2, { readOnly: true });
|
|
16755
|
+
try {
|
|
16756
|
+
const tables = new Set(database.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map((row) => String(row.name)));
|
|
16757
|
+
const directories = /* @__PURE__ */ new Map();
|
|
16758
|
+
const titles = /* @__PURE__ */ new Map();
|
|
16759
|
+
for (const table of ["session", "session_v2"]) {
|
|
16760
|
+
if (!tables.has(table))
|
|
16761
|
+
continue;
|
|
16762
|
+
const columns = new Set(database.prepare(`PRAGMA table_info(${table})`).all().map((row) => String(row.name)));
|
|
16763
|
+
const titleColumn = columns.has("title") ? ", title" : "";
|
|
16764
|
+
for (const row of database.prepare(`SELECT id, directory${titleColumn} FROM ${table}`).iterate()) {
|
|
16765
|
+
if (typeof row.directory === "string")
|
|
16766
|
+
directories.set(String(row.id), row.directory);
|
|
16767
|
+
const title = usageSessionTitle(row.title);
|
|
16768
|
+
if (title)
|
|
16769
|
+
titles.set(String(row.id), title);
|
|
16770
|
+
}
|
|
16771
|
+
}
|
|
16772
|
+
const entries = /* @__PURE__ */ new Map();
|
|
16773
|
+
const add = (message, createdAtMs, session) => {
|
|
16774
|
+
let request;
|
|
16775
|
+
try {
|
|
16776
|
+
request = v2UsageRequest(message, true);
|
|
16777
|
+
} catch {
|
|
16778
|
+
return;
|
|
16779
|
+
}
|
|
16780
|
+
const at = nativeTimeMs(createdAtMs);
|
|
16781
|
+
const entry = request && at !== null && usageEntryFromRequest(request, at);
|
|
16782
|
+
if (entry && !entries.has(entry.id)) {
|
|
16783
|
+
const sessionId = typeof session === "string" ? session : void 0;
|
|
16784
|
+
entries.set(entry.id, withUsageSession(entry, {
|
|
16785
|
+
sessionId,
|
|
16786
|
+
cwd: sessionId === void 0 ? void 0 : directories.get(sessionId),
|
|
16787
|
+
title: sessionId === void 0 ? void 0 : titles.get(sessionId)
|
|
16788
|
+
}));
|
|
16789
|
+
}
|
|
16790
|
+
};
|
|
16791
|
+
if (tables.has("session_message")) {
|
|
16792
|
+
for (const row of database.prepare("SELECT id, session_id, data FROM session_message WHERE type = 'assistant'").iterate()) {
|
|
16793
|
+
const data = parseRowData(row.data);
|
|
16794
|
+
if (!isRecord2(data))
|
|
16795
|
+
continue;
|
|
16796
|
+
add({ ...data, id: String(row.id), type: "assistant" }, isRecord2(data.time) ? data.time.created : void 0, row.session_id);
|
|
16797
|
+
}
|
|
16798
|
+
}
|
|
16799
|
+
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 ?? ""));
|
|
16800
|
+
if (tables.has("message") && !migrated) {
|
|
16801
|
+
for (const row of database.prepare("SELECT id, session_id, data FROM message").iterate()) {
|
|
16802
|
+
const data = parseRowData(row.data);
|
|
16803
|
+
if (!isRecord2(data) || data.role !== "assistant" || typeof data.modelID !== "string") {
|
|
16804
|
+
continue;
|
|
16805
|
+
}
|
|
16806
|
+
add({
|
|
16807
|
+
id: String(row.id),
|
|
16808
|
+
type: "assistant",
|
|
16809
|
+
model: { id: data.modelID, providerID: data.providerID },
|
|
16810
|
+
tokens: data.tokens,
|
|
16811
|
+
time: data.time
|
|
16812
|
+
}, isRecord2(data.time) ? data.time.created : void 0, row.session_id);
|
|
16813
|
+
}
|
|
16814
|
+
}
|
|
16815
|
+
return [...entries.values()];
|
|
16816
|
+
} finally {
|
|
16817
|
+
database.close();
|
|
16818
|
+
}
|
|
16819
|
+
}
|
|
16820
|
+
function createOpenCodeUsageStatistics(environment) {
|
|
16821
|
+
return Object.freeze({
|
|
16822
|
+
async listSources() {
|
|
16823
|
+
const file2 = openCodeDatabasePath(environment);
|
|
16824
|
+
const stamp = file2 ? await fingerprint(file2) : null;
|
|
16825
|
+
return file2 && stamp ? [{ id: file2, fingerprint: stamp }] : [];
|
|
16826
|
+
},
|
|
16827
|
+
readSource: (id) => readOpenCodeUsage(id)
|
|
16828
|
+
});
|
|
16829
|
+
}
|
|
16830
|
+
|
|
16831
|
+
// dist/opencode-adapter.js
|
|
16832
|
+
import { randomUUID } from "node:crypto";
|
|
16833
|
+
import fs4 from "node:fs";
|
|
16834
|
+
import path9 from "node:path";
|
|
16329
16835
|
|
|
16330
16836
|
// dist/model-catalog.js
|
|
16331
16837
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
@@ -16336,10 +16842,10 @@ function assertNonBlank(value, label) {
|
|
|
16336
16842
|
if (!value.trim())
|
|
16337
16843
|
throw new Error(`OpenCode ${label} must not be empty`);
|
|
16338
16844
|
}
|
|
16339
|
-
function encodeOpenCodeModelRef(
|
|
16340
|
-
assertNonBlank(
|
|
16341
|
-
assertNonBlank(
|
|
16342
|
-
const encoded = Buffer2.from(JSON.stringify([
|
|
16845
|
+
function encodeOpenCodeModelRef(model2) {
|
|
16846
|
+
assertNonBlank(model2.providerID, "Provider ID");
|
|
16847
|
+
assertNonBlank(model2.modelID, "Model ID");
|
|
16848
|
+
const encoded = Buffer2.from(JSON.stringify([model2.providerID, model2.modelID]), "utf8").toString("base64url");
|
|
16343
16849
|
const id = `${MODEL_REF_PREFIX}${encoded}`;
|
|
16344
16850
|
if (id.length > HARNESS_MODEL_REF_MAX_LENGTH) {
|
|
16345
16851
|
throw new Error("OpenCode Model identity is too long for a Model Ref");
|
|
@@ -16397,26 +16903,26 @@ function compareText(left, right) {
|
|
|
16397
16903
|
}
|
|
16398
16904
|
function modelsForConnectedProviders(catalog) {
|
|
16399
16905
|
const connected = new Set(catalog.connected);
|
|
16400
|
-
return catalog.all.flatMap((provider) => connected.has(provider.id) ? Object.values(provider.models).map((
|
|
16906
|
+
return catalog.all.flatMap((provider) => connected.has(provider.id) ? Object.values(provider.models).map((model2) => ({ provider, model: model2 })) : []);
|
|
16401
16907
|
}
|
|
16402
16908
|
function normalizeOpenCodeModelCatalog(catalog) {
|
|
16403
16909
|
const nativeModels = modelsForConnectedProviders(catalog);
|
|
16404
16910
|
const variants = /* @__PURE__ */ new Set();
|
|
16405
|
-
for (const { model } of nativeModels) {
|
|
16406
|
-
for (const variant of Object.keys(
|
|
16911
|
+
for (const { model: model2 } of nativeModels) {
|
|
16912
|
+
for (const variant of Object.keys(model2.variants ?? {}))
|
|
16407
16913
|
variants.add(variant);
|
|
16408
16914
|
}
|
|
16409
16915
|
const thinkingOptions = [
|
|
16410
16916
|
variantOption(void 0),
|
|
16411
16917
|
...[...variants].sort(compareText).map((variant) => variantOption(variant))
|
|
16412
16918
|
];
|
|
16413
|
-
const models = nativeModels.map(({ provider, model }) => ({
|
|
16414
|
-
ref: encodeOpenCodeModelRef({ providerID: provider.id, modelID:
|
|
16415
|
-
label: `${provider.name} / ${
|
|
16416
|
-
resolvedModelLabel: `${provider.id}/${
|
|
16919
|
+
const models = nativeModels.map(({ provider, model: model2 }) => ({
|
|
16920
|
+
ref: encodeOpenCodeModelRef({ providerID: provider.id, modelID: model2.id }),
|
|
16921
|
+
label: `${provider.name} / ${model2.name}`,
|
|
16922
|
+
resolvedModelLabel: `${provider.id}/${model2.id}`,
|
|
16417
16923
|
supportedThinkingOptionIds: [
|
|
16418
16924
|
DEFAULT_VARIANT_ID,
|
|
16419
|
-
...Object.keys(
|
|
16925
|
+
...Object.keys(model2.variants ?? {}).sort(compareText).map(encodeOpenCodeVariant)
|
|
16420
16926
|
]
|
|
16421
16927
|
})).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
|
|
16422
16928
|
const defaultNative = catalog.connected.map((providerID) => ({ providerID, modelID: catalog.default[providerID] })).find((candidate2) => typeof candidate2.modelID === "string" && candidate2.modelID.length > 0);
|
|
@@ -16428,9 +16934,9 @@ function normalizeOpenCodeModelCatalog(catalog) {
|
|
|
16428
16934
|
defaultThinkingOptionId: DEFAULT_VARIANT_ID
|
|
16429
16935
|
});
|
|
16430
16936
|
}
|
|
16431
|
-
function openCodeContextWindow(catalog,
|
|
16432
|
-
const provider = catalog.all.find(({ id }) => id ===
|
|
16433
|
-
const context = provider?.models[
|
|
16937
|
+
function openCodeContextWindow(catalog, model2) {
|
|
16938
|
+
const provider = catalog.all.find(({ id }) => id === model2.providerID);
|
|
16939
|
+
const context = provider?.models[model2.modelID]?.limit.context;
|
|
16434
16940
|
return typeof context === "number" && Number.isSafeInteger(context) && context > 0 ? context : void 0;
|
|
16435
16941
|
}
|
|
16436
16942
|
|
|
@@ -16753,7 +17259,7 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
16753
17259
|
import fs2 from "node:fs";
|
|
16754
17260
|
import { createServer } from "node:net";
|
|
16755
17261
|
import { homedir as homedir2, tmpdir as tmpdir2 } from "node:os";
|
|
16756
|
-
import
|
|
17262
|
+
import path7 from "node:path";
|
|
16757
17263
|
|
|
16758
17264
|
// ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
|
|
16759
17265
|
var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url2, ...options }) => {
|
|
@@ -16979,7 +17485,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
|
|
|
16979
17485
|
|
|
16980
17486
|
// ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
|
|
16981
17487
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
16982
|
-
var defaultPathSerializer = ({ path:
|
|
17488
|
+
var defaultPathSerializer = ({ path: path14, url: _url2 }) => {
|
|
16983
17489
|
let url2 = _url2;
|
|
16984
17490
|
const matches = _url2.match(PATH_PARAM_RE);
|
|
16985
17491
|
if (matches) {
|
|
@@ -16998,7 +17504,7 @@ var defaultPathSerializer = ({ path: path13, url: _url2 }) => {
|
|
|
16998
17504
|
name = name.substring(1);
|
|
16999
17505
|
style = "matrix";
|
|
17000
17506
|
}
|
|
17001
|
-
const value =
|
|
17507
|
+
const value = path14[name];
|
|
17002
17508
|
if (value === void 0 || value === null) {
|
|
17003
17509
|
continue;
|
|
17004
17510
|
}
|
|
@@ -17029,11 +17535,11 @@ var defaultPathSerializer = ({ path: path13, url: _url2 }) => {
|
|
|
17029
17535
|
}
|
|
17030
17536
|
return url2;
|
|
17031
17537
|
};
|
|
17032
|
-
var getUrl = ({ baseUrl, path:
|
|
17538
|
+
var getUrl = ({ baseUrl, path: path14, query, querySerializer, url: _url2 }) => {
|
|
17033
17539
|
const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
|
|
17034
17540
|
let url2 = (baseUrl ?? "") + pathUrl;
|
|
17035
|
-
if (
|
|
17036
|
-
url2 = defaultPathSerializer({ path:
|
|
17541
|
+
if (path14) {
|
|
17542
|
+
url2 = defaultPathSerializer({ path: path14, url: url2 });
|
|
17037
17543
|
}
|
|
17038
17544
|
let search = query ? querySerializer(query) : "";
|
|
17039
17545
|
if (search.startsWith("?")) {
|
|
@@ -22156,7 +22662,7 @@ function createOpencodeClient(config2) {
|
|
|
22156
22662
|
}
|
|
22157
22663
|
|
|
22158
22664
|
// dist/command.js
|
|
22159
|
-
import
|
|
22665
|
+
import path6 from "node:path";
|
|
22160
22666
|
var OpenCodeExecutableError = class extends Error {
|
|
22161
22667
|
code = "OPENCODE_NOT_FOUND";
|
|
22162
22668
|
constructor(message = "OpenCode CLI is not installed") {
|
|
@@ -22190,7 +22696,7 @@ function resolveOpenCodeExecutable(input = {}, dependencies = {}) {
|
|
|
22190
22696
|
}, dependencies);
|
|
22191
22697
|
if (!resolution)
|
|
22192
22698
|
throw new OpenCodeExecutableError();
|
|
22193
|
-
return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable :
|
|
22699
|
+
return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path6.resolve(resolution.executable);
|
|
22194
22700
|
}
|
|
22195
22701
|
function openCodeServerInvocation(executable, environment, platform = process.platform, port = 0) {
|
|
22196
22702
|
return commandInvocation(executable, ["serve", "--hostname=127.0.0.1", `--port=${port}`], environment, platform);
|
|
@@ -22218,14 +22724,14 @@ function freeLoopbackPort() {
|
|
|
22218
22724
|
});
|
|
22219
22725
|
});
|
|
22220
22726
|
}
|
|
22221
|
-
function
|
|
22727
|
+
function isRecord3(value) {
|
|
22222
22728
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22223
22729
|
}
|
|
22224
22730
|
function errorText(error51) {
|
|
22225
22731
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
22226
22732
|
}
|
|
22227
22733
|
function isMissingExecutable(error51) {
|
|
22228
|
-
return
|
|
22734
|
+
return isRecord3(error51) && error51.code === "ENOENT";
|
|
22229
22735
|
}
|
|
22230
22736
|
function classifySdkError(error51, operation) {
|
|
22231
22737
|
if (error51 instanceof OpenCodeTransportError)
|
|
@@ -22280,14 +22786,14 @@ function signalProcessTree(child, signal) {
|
|
|
22280
22786
|
try {
|
|
22281
22787
|
process.kill(-child.pid, signal);
|
|
22282
22788
|
} catch (error51) {
|
|
22283
|
-
if (!
|
|
22789
|
+
if (!isRecord3(error51) || error51.code !== "ESRCH")
|
|
22284
22790
|
throw error51;
|
|
22285
22791
|
}
|
|
22286
22792
|
}
|
|
22287
22793
|
function safeOpenCodeServerCwd(environment) {
|
|
22288
22794
|
const candidates = [environment.USERPROFILE, environment.HOME, homedir2(), tmpdir2()];
|
|
22289
22795
|
for (const candidate2 of candidates) {
|
|
22290
|
-
if (!candidate2 || !
|
|
22796
|
+
if (!candidate2 || !path7.isAbsolute(candidate2))
|
|
22291
22797
|
continue;
|
|
22292
22798
|
try {
|
|
22293
22799
|
if (!fs2.statSync(candidate2).isDirectory())
|
|
@@ -22311,7 +22817,7 @@ function managedOpenCodeEnvironment(environment, executionPolicy = "default") {
|
|
|
22311
22817
|
if (existing !== void 0) {
|
|
22312
22818
|
try {
|
|
22313
22819
|
const parsed = JSON.parse(existing);
|
|
22314
|
-
if (!
|
|
22820
|
+
if (!isRecord3(parsed))
|
|
22315
22821
|
throw new Error("OpenCode config content must be an object");
|
|
22316
22822
|
config2 = { ...parsed };
|
|
22317
22823
|
} catch (error51) {
|
|
@@ -22634,11 +23140,11 @@ var SdkOpenCodeTransport = class {
|
|
|
22634
23140
|
parts: [{ type: "text", text: input.text }]
|
|
22635
23141
|
}), this.#commandTimeoutMs, "OpenCode prompt admission"), "prompt admission");
|
|
22636
23142
|
}
|
|
22637
|
-
async summarize(sessionID,
|
|
23143
|
+
async summarize(sessionID, model2) {
|
|
22638
23144
|
const client2 = await this.#getClient();
|
|
22639
23145
|
responseData2(await withTimeout2(client2.session.summarize({
|
|
22640
23146
|
sessionID,
|
|
22641
|
-
...
|
|
23147
|
+
...model2 ? { providerID: model2.providerID, modelID: model2.modelID } : {}
|
|
22642
23148
|
}), this.#commandTimeoutMs, "OpenCode context compaction"), "context compaction");
|
|
22643
23149
|
}
|
|
22644
23150
|
async abort(sessionID) {
|
|
@@ -22736,7 +23242,7 @@ var SdkOpenCodeTransport = class {
|
|
|
22736
23242
|
|
|
22737
23243
|
// dist/file-change-verification.js
|
|
22738
23244
|
import fs3 from "node:fs";
|
|
22739
|
-
import
|
|
23245
|
+
import path8 from "node:path";
|
|
22740
23246
|
function missingPath(error51) {
|
|
22741
23247
|
if (!error51 || typeof error51 !== "object")
|
|
22742
23248
|
return false;
|
|
@@ -22748,33 +23254,33 @@ function hasDotPathSegment(value) {
|
|
|
22748
23254
|
return segments.some((segment) => segment === "." || segment === "..");
|
|
22749
23255
|
}
|
|
22750
23256
|
function canonicalDirectoryPath(value) {
|
|
22751
|
-
let candidate2 =
|
|
23257
|
+
let candidate2 = path8.resolve(value);
|
|
22752
23258
|
const missingSegments = [];
|
|
22753
23259
|
for (; ; ) {
|
|
22754
23260
|
try {
|
|
22755
|
-
return
|
|
23261
|
+
return path8.join(fs3.realpathSync.native(candidate2), ...missingSegments);
|
|
22756
23262
|
} catch (error51) {
|
|
22757
23263
|
if (!missingPath(error51))
|
|
22758
23264
|
return void 0;
|
|
22759
|
-
const parent =
|
|
23265
|
+
const parent = path8.dirname(candidate2);
|
|
22760
23266
|
if (parent === candidate2)
|
|
22761
23267
|
return void 0;
|
|
22762
|
-
missingSegments.unshift(
|
|
23268
|
+
missingSegments.unshift(path8.basename(candidate2));
|
|
22763
23269
|
candidate2 = parent;
|
|
22764
23270
|
}
|
|
22765
23271
|
}
|
|
22766
23272
|
}
|
|
22767
23273
|
function canonicalFilePath(value) {
|
|
22768
|
-
const absolute =
|
|
22769
|
-
const parent = canonicalDirectoryPath(
|
|
22770
|
-
return parent ?
|
|
23274
|
+
const absolute = path8.resolve(value);
|
|
23275
|
+
const parent = canonicalDirectoryPath(path8.dirname(absolute));
|
|
23276
|
+
return parent ? path8.join(parent, path8.basename(absolute)) : void 0;
|
|
22771
23277
|
}
|
|
22772
23278
|
function pathIsWithin(root, candidate2, allowRoot) {
|
|
22773
|
-
const relative =
|
|
22774
|
-
return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${
|
|
23279
|
+
const relative = path8.relative(root, candidate2);
|
|
23280
|
+
return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${path8.sep}`) && !path8.isAbsolute(relative);
|
|
22775
23281
|
}
|
|
22776
23282
|
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) || !
|
|
23283
|
+
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
23284
|
return void 0;
|
|
22779
23285
|
}
|
|
22780
23286
|
const session = canonicalDirectoryPath(sessionDirectory);
|
|
@@ -22786,10 +23292,10 @@ function verifiedOpenCodeWorktree(sessionDirectory, paths) {
|
|
|
22786
23292
|
return worktree;
|
|
22787
23293
|
}
|
|
22788
23294
|
function openCodeFileIdentity(file2, worktree) {
|
|
22789
|
-
if (typeof file2 !== "string" || typeof worktree !== "string" || hasDotPathSegment(file2) || hasDotPathSegment(worktree) || !
|
|
23295
|
+
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
23296
|
return void 0;
|
|
22791
23297
|
}
|
|
22792
|
-
const candidate2 = canonicalFilePath(
|
|
23298
|
+
const candidate2 = canonicalFilePath(path8.isAbsolute(file2) ? file2 : path8.resolve(worktree, file2));
|
|
22793
23299
|
return candidate2 && pathIsWithin(worktree, candidate2, false) ? candidate2 : void 0;
|
|
22794
23300
|
}
|
|
22795
23301
|
|
|
@@ -22847,12 +23353,12 @@ function storedSelection(session) {
|
|
|
22847
23353
|
}
|
|
22848
23354
|
return { providerID, modelID, ...typeof variant === "string" ? { variant } : {} };
|
|
22849
23355
|
}
|
|
22850
|
-
function selectionMetadata(session,
|
|
23356
|
+
function selectionMetadata(session, model2, variant) {
|
|
22851
23357
|
return {
|
|
22852
23358
|
...session.metadata,
|
|
22853
23359
|
[SELECTION_METADATA_KEY]: {
|
|
22854
|
-
providerID:
|
|
22855
|
-
modelID:
|
|
23360
|
+
providerID: model2.providerID,
|
|
23361
|
+
modelID: model2.modelID,
|
|
22856
23362
|
...variant ? { variant } : {}
|
|
22857
23363
|
}
|
|
22858
23364
|
};
|
|
@@ -22948,17 +23454,17 @@ async function readProjection(transport, sessionID, providerCatalog, toolOutputL
|
|
|
22948
23454
|
diffsByUserMessageId: new Map(diffEntries),
|
|
22949
23455
|
toolOutputLimit
|
|
22950
23456
|
});
|
|
22951
|
-
const
|
|
23457
|
+
const model2 = nativeModelFromSession(session, messages);
|
|
22952
23458
|
const nativeVariant = nativeVariantFromSession(session, messages);
|
|
22953
|
-
const nativeModel =
|
|
23459
|
+
const nativeModel = model2 ? providerCatalog.all.find(({ id }) => id === model2.providerID)?.models[model2.modelID] : void 0;
|
|
22954
23460
|
const variant = nativeVariant === "default" && nativeModel && !Object.hasOwn(nativeModel.variants ?? {}, "default") ? void 0 : nativeVariant;
|
|
22955
|
-
const usage = projectOpenCodeUsage(openCodeAssistantMessages(session, messages),
|
|
23461
|
+
const usage = projectOpenCodeUsage(openCodeAssistantMessages(session, messages), model2 ? openCodeContextWindow(providerCatalog, model2) : void 0);
|
|
22956
23462
|
return {
|
|
22957
23463
|
session,
|
|
22958
23464
|
messages,
|
|
22959
23465
|
snapshot,
|
|
22960
23466
|
usage,
|
|
22961
|
-
...
|
|
23467
|
+
...model2 ? { model: model2 } : {},
|
|
22962
23468
|
...variant ? { variant } : {}
|
|
22963
23469
|
};
|
|
22964
23470
|
}
|
|
@@ -23084,13 +23590,13 @@ function sameCwd(left, right) {
|
|
|
23084
23590
|
try {
|
|
23085
23591
|
return fs4.realpathSync.native(value);
|
|
23086
23592
|
} catch {
|
|
23087
|
-
return
|
|
23593
|
+
return path9.resolve(value);
|
|
23088
23594
|
}
|
|
23089
23595
|
};
|
|
23090
23596
|
return canonical(left) === canonical(right);
|
|
23091
23597
|
}
|
|
23092
|
-
function sessionState(session, modelCatalog,
|
|
23093
|
-
const effectiveModel =
|
|
23598
|
+
function sessionState(session, modelCatalog, model2, variant, executionPolicy = "default", permissionModeId = OPENCODE_DEFAULT_PERMISSION_MODE_ID) {
|
|
23599
|
+
const effectiveModel = model2 ? encodeOpenCodeModelRef(model2) : void 0;
|
|
23094
23600
|
const modelEntry = effectiveModel ? modelCatalog.models.find(({ ref }) => ref.id === effectiveModel.id) : void 0;
|
|
23095
23601
|
const availableThinkingOptions = modelEntry?.supportedThinkingOptionIds?.map((id) => modelCatalog.thinkingOptions.find((option) => option.id === id)).filter((option) => Boolean(option));
|
|
23096
23602
|
const effectiveThinkingOptionId = encodeOpenCodeVariant(variant);
|
|
@@ -23492,8 +23998,8 @@ var OpenCodeHarnessSession = class {
|
|
|
23492
23998
|
};
|
|
23493
23999
|
}
|
|
23494
24000
|
const modelRef = this.#model ? encodeOpenCodeModelRef(this.#model) : void 0;
|
|
23495
|
-
const
|
|
23496
|
-
if (!
|
|
24001
|
+
const model2 = modelRef ? this.#modelCatalog.models.find(({ ref }) => ref.id === modelRef.id) : void 0;
|
|
24002
|
+
if (!model2?.supportedThinkingOptionIds?.includes(command.thinkingOptionId)) {
|
|
23497
24003
|
return {
|
|
23498
24004
|
ok: false,
|
|
23499
24005
|
error: {
|
|
@@ -24343,14 +24849,14 @@ var OpenCodeAdapter = class {
|
|
|
24343
24849
|
const modelCatalog = normalizeOpenCodeModelCatalog(providers);
|
|
24344
24850
|
let session;
|
|
24345
24851
|
if (input.kind === "create") {
|
|
24346
|
-
const
|
|
24852
|
+
const model2 = input.model ? decodeOpenCodeModelRef(input.model) : void 0;
|
|
24347
24853
|
const variant = input.thinkingOptionId ? decodeOpenCodeVariant(input.thinkingOptionId) : void 0;
|
|
24348
24854
|
if (input.model && !modelCatalog.models.some(({ ref }) => ref.id === input.model?.id)) {
|
|
24349
24855
|
throw new OpenCodeTransportError("protocolError", "Requested OpenCode Model is absent from the connected Provider catalog");
|
|
24350
24856
|
}
|
|
24351
24857
|
const permission = requestedPermissionMode && requestedPermissionMode !== "default" ? requestedPermissionRules(void 0, requestedPermissionMode) : void 0;
|
|
24352
24858
|
session = await transport.createSession({
|
|
24353
|
-
...
|
|
24859
|
+
...model2 ? { model: model2 } : {},
|
|
24354
24860
|
...variant ? { variant } : {},
|
|
24355
24861
|
...permission ? { permission } : {}
|
|
24356
24862
|
});
|
|
@@ -24465,7 +24971,7 @@ import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
|
24465
24971
|
|
|
24466
24972
|
// dist/v2/state.js
|
|
24467
24973
|
import fs5 from "node:fs";
|
|
24468
|
-
import
|
|
24974
|
+
import path10 from "node:path";
|
|
24469
24975
|
var harnessId = harnessIdSchema.parse("opencode");
|
|
24470
24976
|
function failure(message, code = "nativeFailure") {
|
|
24471
24977
|
return {
|
|
@@ -24485,7 +24991,7 @@ function sameDirectory(left, right) {
|
|
|
24485
24991
|
try {
|
|
24486
24992
|
return fs5.realpathSync(value);
|
|
24487
24993
|
} catch {
|
|
24488
|
-
return
|
|
24994
|
+
return path10.resolve(value);
|
|
24489
24995
|
}
|
|
24490
24996
|
};
|
|
24491
24997
|
return canonical(left) === canonical(right);
|
|
@@ -24507,17 +25013,17 @@ function v2Locator(ref) {
|
|
|
24507
25013
|
return { directory: locator.directory, executionPolicy: locator.executionPolicy };
|
|
24508
25014
|
}
|
|
24509
25015
|
function v2Catalog(models, defaultModel) {
|
|
24510
|
-
const enabled = models.filter((
|
|
24511
|
-
const variants = [...new Set(enabled.flatMap((
|
|
24512
|
-
const ref = (
|
|
25016
|
+
const enabled = models.filter((model2) => model2.enabled);
|
|
25017
|
+
const variants = [...new Set(enabled.flatMap((model2) => model2.variants.map((v) => v.id)))].sort();
|
|
25018
|
+
const ref = (model2) => encodeOpenCodeModelRef({ providerID: model2.providerID, modelID: model2.id });
|
|
24513
25019
|
return harnessModelCatalogSchema.parse({
|
|
24514
|
-
models: enabled.map((
|
|
24515
|
-
ref: ref(
|
|
24516
|
-
label: `${
|
|
24517
|
-
resolvedModelLabel: `${
|
|
25020
|
+
models: enabled.map((model2) => ({
|
|
25021
|
+
ref: ref(model2),
|
|
25022
|
+
label: `${model2.providerID} / ${model2.name}`,
|
|
25023
|
+
resolvedModelLabel: `${model2.providerID}/${model2.id}`,
|
|
24518
25024
|
supportedThinkingOptionIds: [
|
|
24519
25025
|
encodeOpenCodeVariant(void 0),
|
|
24520
|
-
...
|
|
25026
|
+
...model2.variants.map((v) => encodeOpenCodeVariant(v.id))
|
|
24521
25027
|
]
|
|
24522
25028
|
})),
|
|
24523
25029
|
...defaultModel && enabled.some((m) => ref(m).id === ref(defaultModel).id) ? { defaultModel: ref(defaultModel) } : {},
|
|
@@ -24534,12 +25040,12 @@ function v2Permissions(current = [], mode) {
|
|
|
24534
25040
|
return selected === "default" ? rules : [...rules, { action: "*", resource: "*", effect: selected }];
|
|
24535
25041
|
}
|
|
24536
25042
|
function v2State(session, catalog, policy) {
|
|
24537
|
-
const
|
|
24538
|
-
const entry = catalog.models.find((candidate2) => candidate2.ref.id ===
|
|
25043
|
+
const model2 = session.model ? encodeOpenCodeModelRef({ providerID: session.model.providerID, modelID: session.model.id }) : void 0;
|
|
25044
|
+
const entry = catalog.models.find((candidate2) => candidate2.ref.id === model2?.id);
|
|
24539
25045
|
const mode = session.permissions?.findLast((rule) => rule.action === "*" && rule.resource === "*");
|
|
24540
25046
|
return {
|
|
24541
25047
|
nativeRef: v2Ref(session, policy),
|
|
24542
|
-
...
|
|
25048
|
+
...model2 ? { effectiveModel: model2 } : {},
|
|
24543
25049
|
...entry ? {
|
|
24544
25050
|
resolvedModelLabel: entry.resolvedModelLabel ?? entry.label,
|
|
24545
25051
|
availableThinkingOptions: catalog.thinkingOptions.filter((v) => entry.supportedThinkingOptionIds?.includes(v.id)),
|
|
@@ -26400,7 +26906,7 @@ var V2Connection = class {
|
|
|
26400
26906
|
};
|
|
26401
26907
|
|
|
26402
26908
|
// dist/v2/history.js
|
|
26403
|
-
import
|
|
26909
|
+
import path11 from "node:path";
|
|
26404
26910
|
async function readMessages(client2, sessionID) {
|
|
26405
26911
|
const messages = [];
|
|
26406
26912
|
let cursor;
|
|
@@ -26419,11 +26925,12 @@ async function readMessages(client2, sessionID) {
|
|
|
26419
26925
|
} while (cursor);
|
|
26420
26926
|
return messages;
|
|
26421
26927
|
}
|
|
26422
|
-
var contentId = (messageID,
|
|
26928
|
+
var contentId = (messageID, type, ordinal) => hostItemIdSchema.parse(`${messageID}:${type}:${ordinal}`);
|
|
26423
26929
|
function assistantItems2(message, limit) {
|
|
26424
|
-
|
|
26425
|
-
|
|
26930
|
+
const ordinals = { text: 0, reasoning: 0 };
|
|
26931
|
+
return message.content.map((part) => {
|
|
26426
26932
|
if (part.type === "text" || part.type === "reasoning") {
|
|
26933
|
+
const itemId2 = contentId(message.id, part.type, ordinals[part.type]++);
|
|
26427
26934
|
return {
|
|
26428
26935
|
item: {
|
|
26429
26936
|
type: part.type === "text" ? "agentMessage" : "reasoning",
|
|
@@ -26438,7 +26945,7 @@ function assistantItems2(message, limit) {
|
|
|
26438
26945
|
return {
|
|
26439
26946
|
item: {
|
|
26440
26947
|
type: "toolExecution",
|
|
26441
|
-
itemId:
|
|
26948
|
+
itemId: hostItemIdSchema.parse(`${message.id}:tool:${part.id}`),
|
|
26442
26949
|
toolName: part.name,
|
|
26443
26950
|
namespace: "opencode",
|
|
26444
26951
|
arguments: typeof state.input === "string" ? state.input : state.input,
|
|
@@ -26525,9 +27032,9 @@ function fileChanges(session, turn, diffs) {
|
|
|
26525
27032
|
if (!diffs.length)
|
|
26526
27033
|
return void 0;
|
|
26527
27034
|
const changes = diffs.map((diff) => {
|
|
26528
|
-
const absolute =
|
|
26529
|
-
const relative =
|
|
26530
|
-
if (relative.startsWith(`..${
|
|
27035
|
+
const absolute = path11.resolve(session.location.directory, diff.file);
|
|
27036
|
+
const relative = path11.relative(session.location.directory, absolute);
|
|
27037
|
+
if (relative.startsWith(`..${path11.sep}`) || relative === ".." || path11.isAbsolute(relative))
|
|
26531
27038
|
throw new Error("OpenCode v2 diff escaped the Session directory");
|
|
26532
27039
|
return {
|
|
26533
27040
|
path: absolute,
|
|
@@ -26570,7 +27077,7 @@ function terminalItemOutcome(outcome) {
|
|
|
26570
27077
|
|
|
26571
27078
|
// dist/v2/session-import.js
|
|
26572
27079
|
import fs6 from "node:fs";
|
|
26573
|
-
import
|
|
27080
|
+
import path12 from "node:path";
|
|
26574
27081
|
|
|
26575
27082
|
// ../../harness-adapter/dist/session-import.js
|
|
26576
27083
|
function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
|
|
@@ -26603,7 +27110,7 @@ function sessionImportCandidate(input) {
|
|
|
26603
27110
|
var PAGE_SIZE = 200;
|
|
26604
27111
|
var MAX_PAGES = 1e4;
|
|
26605
27112
|
function existingDirectory(directory) {
|
|
26606
|
-
if (typeof directory !== "string" || !
|
|
27113
|
+
if (typeof directory !== "string" || !path12.isAbsolute(directory))
|
|
26607
27114
|
return null;
|
|
26608
27115
|
try {
|
|
26609
27116
|
return fs6.statSync(directory).isDirectory() ? directory : null;
|
|
@@ -26803,6 +27310,14 @@ function v2Capabilities(catalog) {
|
|
|
26803
27310
|
history: { fork: true, forkAcrossCwd: false, rollbackLastTurn: true }
|
|
26804
27311
|
};
|
|
26805
27312
|
}
|
|
27313
|
+
var FIRST_OUTPUT_EVENTS = /* @__PURE__ */ new Set([
|
|
27314
|
+
"session.reasoning.started",
|
|
27315
|
+
"session.reasoning.delta",
|
|
27316
|
+
"session.text.started",
|
|
27317
|
+
"session.text.delta",
|
|
27318
|
+
"session.tool.input.started",
|
|
27319
|
+
"session.tool.input.delta"
|
|
27320
|
+
]);
|
|
26806
27321
|
var V2Session = class {
|
|
26807
27322
|
client;
|
|
26808
27323
|
connection;
|
|
@@ -26826,6 +27341,11 @@ var V2Session = class {
|
|
|
26826
27341
|
#reconciling;
|
|
26827
27342
|
#timer;
|
|
26828
27343
|
#configuring = false;
|
|
27344
|
+
#cacheHitRatePercent;
|
|
27345
|
+
/** Assistant messages already published as usage requests. */
|
|
27346
|
+
#meteredMessages = /* @__PURE__ */ new Set();
|
|
27347
|
+
/** Adapter receive time of each assistant message's first reasoning, text or tool input. */
|
|
27348
|
+
#firstOutputAt = /* @__PURE__ */ new Map();
|
|
26829
27349
|
constructor(client2, connection, info, catalog, policy, limit, onClosed) {
|
|
26830
27350
|
this.client = client2;
|
|
26831
27351
|
this.connection = connection;
|
|
@@ -26870,6 +27390,7 @@ var V2Session = class {
|
|
|
26870
27390
|
}
|
|
26871
27391
|
})();
|
|
26872
27392
|
});
|
|
27393
|
+
await this.#replayUsage();
|
|
26873
27394
|
this.#timer = setInterval(() => {
|
|
26874
27395
|
void this.#refresh();
|
|
26875
27396
|
}, 400);
|
|
@@ -26938,22 +27459,22 @@ var V2Session = class {
|
|
|
26938
27459
|
permissions: v2Permissions(this.info.permissions, command.permissionModeId)
|
|
26939
27460
|
});
|
|
26940
27461
|
} else {
|
|
26941
|
-
let
|
|
27462
|
+
let model2 = this.info.model;
|
|
26942
27463
|
if (command.type === "model.select") {
|
|
26943
27464
|
if (!this.catalog.models.some((m) => m.ref.id === command.model.id))
|
|
26944
27465
|
throw new Error("OpenCode Model is not available");
|
|
26945
27466
|
const decoded = decodeOpenCodeModelRef(command.model);
|
|
26946
|
-
|
|
27467
|
+
model2 = { providerID: decoded.providerID, id: decoded.modelID };
|
|
26947
27468
|
} else {
|
|
26948
|
-
if (!
|
|
27469
|
+
if (!model2)
|
|
26949
27470
|
throw new Error("Select a Model before a Thinking option");
|
|
26950
27471
|
const state = v2State(this.info, this.catalog, this.policy);
|
|
26951
27472
|
if (!state.availableThinkingOptions?.some((v) => v.id === command.thinkingOptionId))
|
|
26952
27473
|
throw new Error("Thinking option is unavailable for this Model");
|
|
26953
27474
|
const variant = decodeOpenCodeVariant(command.thinkingOptionId);
|
|
26954
|
-
|
|
27475
|
+
model2 = { providerID: model2.providerID, id: model2.id, ...variant ? { variant } : {} };
|
|
26955
27476
|
}
|
|
26956
|
-
await this.client.session.switchModel({ sessionID: this.info.id, model });
|
|
27477
|
+
await this.client.session.switchModel({ sessionID: this.info.id, model: model2 });
|
|
26957
27478
|
}
|
|
26958
27479
|
this.info = await this.client.session.get({ sessionID: this.info.id });
|
|
26959
27480
|
this.#emit({
|
|
@@ -27036,11 +27557,14 @@ var V2Session = class {
|
|
|
27036
27557
|
const active = this.#active;
|
|
27037
27558
|
if (!active || !("data" in event) || !("sessionID" in event.data) || event.data.sessionID !== this.info.id)
|
|
27038
27559
|
return;
|
|
27560
|
+
if (FIRST_OUTPUT_EVENTS.has(event.type) && "assistantMessageID" in event.data && typeof event.data.assistantMessageID === "string" && !this.#firstOutputAt.has(event.data.assistantMessageID))
|
|
27561
|
+
this.#firstOutputAt.set(event.data.assistantMessageID, Date.now());
|
|
27039
27562
|
if (event.type === "session.step.started")
|
|
27040
27563
|
active.assistants.add(event.data.assistantMessageID);
|
|
27041
27564
|
if ((event.type === "session.text.delta" || event.type === "session.reasoning.delta") && active.assistants.has(event.data.assistantMessageID)) {
|
|
27042
|
-
const
|
|
27043
|
-
const
|
|
27565
|
+
const contentType = event.type === "session.text.delta" ? "text" : "reasoning";
|
|
27566
|
+
const itemId2 = contentId(event.data.assistantMessageID, contentType, event.data.ordinal);
|
|
27567
|
+
const type = contentType === "text" ? "agentMessage" : "reasoning";
|
|
27044
27568
|
const previous = active.transient.get(itemId2);
|
|
27045
27569
|
const item = {
|
|
27046
27570
|
type,
|
|
@@ -27054,6 +27578,56 @@ var V2Session = class {
|
|
|
27054
27578
|
if (!event.type.endsWith(".delta"))
|
|
27055
27579
|
void this.#refresh();
|
|
27056
27580
|
}
|
|
27581
|
+
/** Publishes assistant messages not yet metered; returns false when one is unusable. */
|
|
27582
|
+
#meterUsage(messages, historical) {
|
|
27583
|
+
let usable = true;
|
|
27584
|
+
const previousCacheHitRate = this.#cacheHitRatePercent;
|
|
27585
|
+
for (const message of messages) {
|
|
27586
|
+
let request;
|
|
27587
|
+
try {
|
|
27588
|
+
request = v2UsageRequest(message, historical, this.#firstOutputAt.get(message.id));
|
|
27589
|
+
} catch {
|
|
27590
|
+
this.#cacheHitRatePercent = void 0;
|
|
27591
|
+
if (this.#meteredMessages.has(message.id))
|
|
27592
|
+
continue;
|
|
27593
|
+
this.#meteredMessages.add(message.id);
|
|
27594
|
+
if (!historical)
|
|
27595
|
+
this.#emit({ type: "usage.history", complete: false });
|
|
27596
|
+
usable = false;
|
|
27597
|
+
continue;
|
|
27598
|
+
}
|
|
27599
|
+
if (!request)
|
|
27600
|
+
continue;
|
|
27601
|
+
this.#cacheHitRatePercent = request.inputTokens > 0 && request.cachedInputTokens !== void 0 ? request.cachedInputTokens / request.inputTokens * 100 : void 0;
|
|
27602
|
+
if (this.#meteredMessages.has(message.id))
|
|
27603
|
+
continue;
|
|
27604
|
+
this.#meteredMessages.add(message.id);
|
|
27605
|
+
this.#firstOutputAt.delete(message.id);
|
|
27606
|
+
this.#emit({ type: "usage.request", request });
|
|
27607
|
+
}
|
|
27608
|
+
if (this.#cacheHitRatePercent !== previousCacheHitRate)
|
|
27609
|
+
this.#emit({
|
|
27610
|
+
type: "session.usage.changed",
|
|
27611
|
+
usage: this.#usage()
|
|
27612
|
+
});
|
|
27613
|
+
return usable;
|
|
27614
|
+
}
|
|
27615
|
+
#usage() {
|
|
27616
|
+
const usage = v2Usage(this.info);
|
|
27617
|
+
if (this.#cacheHitRatePercent !== void 0)
|
|
27618
|
+
usage.cacheHitRatePercent = this.#cacheHitRatePercent;
|
|
27619
|
+
return usage;
|
|
27620
|
+
}
|
|
27621
|
+
/** Replays every metered request of the native history, then declares it complete. */
|
|
27622
|
+
async #replayUsage() {
|
|
27623
|
+
let complete = false;
|
|
27624
|
+
try {
|
|
27625
|
+
complete = this.#meterUsage(await readMessages(this.client, this.info.id), true);
|
|
27626
|
+
} catch {
|
|
27627
|
+
complete = false;
|
|
27628
|
+
}
|
|
27629
|
+
this.#emit({ type: "usage.history", complete });
|
|
27630
|
+
}
|
|
27057
27631
|
#refresh() {
|
|
27058
27632
|
if (this.#closed || !this.#active?.admitted)
|
|
27059
27633
|
return Promise.resolve();
|
|
@@ -27072,6 +27646,7 @@ var V2Session = class {
|
|
|
27072
27646
|
if (this.#active !== active || this.#closed)
|
|
27073
27647
|
return;
|
|
27074
27648
|
this.info = info;
|
|
27649
|
+
this.#meterUsage(messages, false);
|
|
27075
27650
|
const turns = snapshot.turns.filter((t) => !active.baseline.has(t.nativeTurnRef.nativeTurnKey));
|
|
27076
27651
|
if (turns.length > 1)
|
|
27077
27652
|
throw new Error("Concurrent native prompts cannot be assigned to one Host Turn");
|
|
@@ -27168,7 +27743,7 @@ var V2Session = class {
|
|
|
27168
27743
|
});
|
|
27169
27744
|
this.#emit({
|
|
27170
27745
|
type: "session.usage.changed",
|
|
27171
|
-
usage:
|
|
27746
|
+
usage: this.#usage(),
|
|
27172
27747
|
observedForTurnId: active.turnId
|
|
27173
27748
|
});
|
|
27174
27749
|
this.#active = void 0;
|
|
@@ -27364,10 +27939,10 @@ var V2Adapter = class {
|
|
|
27364
27939
|
const catalog = await this.#catalog(client2, input.cwd);
|
|
27365
27940
|
let info;
|
|
27366
27941
|
if (input.kind === "create") {
|
|
27367
|
-
const
|
|
27942
|
+
const model2 = selectedModel(input, catalog);
|
|
27368
27943
|
info = await client2.session.create({
|
|
27369
27944
|
location: { directory: input.cwd },
|
|
27370
|
-
...
|
|
27945
|
+
...model2 ? { model: model2 } : {},
|
|
27371
27946
|
permissions: v2Permissions([], input.permissionModeId ?? harnessPermissionModeIdSchema.parse(policy === "unattended-full-access" ? "allow" : "default"))
|
|
27372
27947
|
});
|
|
27373
27948
|
created = info.id;
|
|
@@ -27384,19 +27959,19 @@ var V2Adapter = class {
|
|
|
27384
27959
|
if (input.kind !== "resume") {
|
|
27385
27960
|
const parent = info;
|
|
27386
27961
|
const turns = source.snapshot.turns;
|
|
27387
|
-
let
|
|
27962
|
+
let count2;
|
|
27388
27963
|
if (input.kind === "rollbackLastTurn") {
|
|
27389
27964
|
if (!turns.length)
|
|
27390
27965
|
throw new Error("OpenCode history is empty");
|
|
27391
|
-
|
|
27966
|
+
count2 = turns.length - 1;
|
|
27392
27967
|
} else {
|
|
27393
27968
|
if (input.checkpoint.harnessId !== harnessId || input.checkpoint.nativeSessionId !== info.id)
|
|
27394
27969
|
throw new Error("Checkpoint belongs to another Session");
|
|
27395
|
-
|
|
27396
|
-
if (!
|
|
27970
|
+
count2 = turns.findIndex((turn) => turn.checkpoint?.checkpointId === input.checkpoint.checkpointId) + 1;
|
|
27971
|
+
if (!count2 || JSON.stringify(turns[count2 - 1]?.checkpoint) !== JSON.stringify(input.checkpoint))
|
|
27397
27972
|
throw new Error("OpenCode checkpoint does not match native history");
|
|
27398
27973
|
}
|
|
27399
|
-
const before = turns[
|
|
27974
|
+
const before = turns[count2]?.nativeTurnRef.nativeTurnKey;
|
|
27400
27975
|
info = await client2.session.fork({ sessionID: parent.id, ...before ? { before } : {} });
|
|
27401
27976
|
if (info.id === parent.id)
|
|
27402
27977
|
throw new Error("OpenCode fork returned its source Session");
|
|
@@ -27411,7 +27986,7 @@ var V2Adapter = class {
|
|
|
27411
27986
|
await client2.session.switchModel({ sessionID: info.id, model: parent.model });
|
|
27412
27987
|
info = await client2.session.get({ sessionID: info.id });
|
|
27413
27988
|
const derived = await readHistory(client2, info, this.options.toolOutputLimit ?? 64e3);
|
|
27414
|
-
if (historyContent(derived.snapshot, false) !== historyContent({ turns: turns.slice(0,
|
|
27989
|
+
if (historyContent(derived.snapshot, false) !== historyContent({ turns: turns.slice(0, count2) }, false))
|
|
27415
27990
|
throw new Error("OpenCode fork did not preserve the exact history prefix");
|
|
27416
27991
|
if (!isDeepStrictEqual2(info.permissions ?? [], parent.permissions ?? []) || !isDeepStrictEqual2(info.model, parent.model))
|
|
27417
27992
|
throw new Error("OpenCode fork did not preserve the current configuration");
|
|
@@ -27460,14 +28035,14 @@ function selectedModel(input, catalog) {
|
|
|
27460
28035
|
throw new Error("Thinking selection requires a Model");
|
|
27461
28036
|
return void 0;
|
|
27462
28037
|
}
|
|
27463
|
-
const entry = catalog.models.find((
|
|
28038
|
+
const entry = catalog.models.find((model3) => model3.ref.id === selected.id);
|
|
27464
28039
|
if (!entry)
|
|
27465
28040
|
throw new Error("OpenCode Model is not available");
|
|
27466
28041
|
if (input.thinkingOptionId && !entry.supportedThinkingOptionIds?.includes(input.thinkingOptionId))
|
|
27467
28042
|
throw new Error("OpenCode Thinking option is not available for this Model");
|
|
27468
|
-
const
|
|
28043
|
+
const model2 = decodeOpenCodeModelRef(selected);
|
|
27469
28044
|
const variant = input.thinkingOptionId ? decodeOpenCodeVariant(input.thinkingOptionId) : void 0;
|
|
27470
|
-
return { providerID:
|
|
28045
|
+
return { providerID: model2.providerID, id: model2.modelID, ...variant ? { variant } : {} };
|
|
27471
28046
|
}
|
|
27472
28047
|
function historyContent(snapshot, identities = true) {
|
|
27473
28048
|
return JSON.stringify(snapshot.turns.map((turn) => ({
|
|
@@ -27491,9 +28066,11 @@ var OpenCodeAdapter2 = class {
|
|
|
27491
28066
|
commandCatalog = openCodeCommandCatalog;
|
|
27492
28067
|
#adapters = /* @__PURE__ */ new Set();
|
|
27493
28068
|
#closed = false;
|
|
28069
|
+
usageStatistics;
|
|
27494
28070
|
constructor(options = {}, dependencies) {
|
|
27495
28071
|
this.options = options;
|
|
27496
28072
|
this.dependencies = dependencies;
|
|
28073
|
+
this.usageStatistics = createOpenCodeUsageStatistics(options.environment ?? process.env);
|
|
27497
28074
|
}
|
|
27498
28075
|
async #select(environment, input) {
|
|
27499
28076
|
if (this.#closed)
|
|
@@ -27603,7 +28180,7 @@ function normalize(error51) {
|
|
|
27603
28180
|
// dist/installation.js
|
|
27604
28181
|
import { realpath as realpath2 } from "node:fs/promises";
|
|
27605
28182
|
import { homedir as homedir3 } from "node:os";
|
|
27606
|
-
import
|
|
28183
|
+
import path13 from "node:path";
|
|
27607
28184
|
function createOpenCodeInstallation(environment, command) {
|
|
27608
28185
|
let update;
|
|
27609
28186
|
return createInstallationManager({
|
|
@@ -27624,8 +28201,8 @@ function createOpenCodeInstallation(environment, command) {
|
|
|
27624
28201
|
const release = JSON.parse(await fetchInstallationText("https://api.github.com/repos/anomalyco/opencode/releases/latest"));
|
|
27625
28202
|
latestVersion = installationVersion(release.tag_name);
|
|
27626
28203
|
const home = environment.HOME ?? environment.USERPROFILE ?? homedir3();
|
|
27627
|
-
const standard =
|
|
27628
|
-
canUpdate = process.platform !== "win32" &&
|
|
28204
|
+
const standard = path13.join(home, ".opencode", "bin", process.platform === "win32" ? "opencode.exe" : "opencode");
|
|
28205
|
+
canUpdate = process.platform !== "win32" && path13.resolve(executable) === standard && await realpath2(executable) === standard;
|
|
27629
28206
|
update = async (version2) => {
|
|
27630
28207
|
await runInstallationCommand(executable, ["upgrade", version2, "--method", "curl"], environment, 3e5);
|
|
27631
28208
|
};
|