@codexhost/cli-darwin-x64 0.10.2 → 0.11.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 +4 -0
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +17959 -0
- package/app/console-web.js +25950 -0
- package/app/desktop-controller.mjs +154 -14
- package/app/host-runtime.mjs +3176 -1070
- package/app/plugins/antigravity/plugin.mjs +345 -72
- package/app/plugins/claude-code/plugin.mjs +2153 -1465
- package/app/plugins/codebuddy/plugin.mjs +426 -93
- package/app/plugins/cursor-cli/manifest.json +1 -1
- package/app/plugins/cursor-cli/plugin.mjs +1134 -495
- package/app/plugins/deepseek-harness/plugin.mjs +604 -36
- package/app/plugins/grok/plugin.mjs +290 -78
- package/app/plugins/hermes/plugin.mjs +311 -85
- package/app/plugins/kimi-code/plugin.mjs +659 -74
- package/app/plugins/kiro-cli/plugin.mjs +227 -55
- package/app/plugins/omp/plugin.mjs +300 -45
- package/app/plugins/opencode/plugin.mjs +3600 -206
- package/app/plugins/pi/plugin.mjs +897 -275
- package/app/plugins/qoder/plugin.mjs +397 -46
- package/app/plugins/qoder-cn/plugin.mjs +404 -47
- package/app/plugins/workbuddy/plugin.mjs +116 -6
- package/app/renderer-extension.js +2303 -1200
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
- package/package.json +1 -1
|
@@ -5,15 +5,10 @@ var __export = (target, all) => {
|
|
|
5
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
// dist/
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync, lstatSync, renameSync, rmdirSync } from "node:fs";
|
|
13
|
-
import { realpath } from "node:fs/promises";
|
|
14
|
-
import os2 from "node:os";
|
|
15
|
-
import path3 from "node:path";
|
|
16
|
-
import { pathToFileURL } from "node:url";
|
|
8
|
+
// dist/account-balance.js
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
17
12
|
|
|
18
13
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
19
14
|
var external_exports = {};
|
|
@@ -781,10 +776,10 @@ function mergeDefs(...defs) {
|
|
|
781
776
|
function cloneDef(schema) {
|
|
782
777
|
return mergeDefs(schema._zod.def);
|
|
783
778
|
}
|
|
784
|
-
function getElementAtPath(obj,
|
|
785
|
-
if (!
|
|
779
|
+
function getElementAtPath(obj, path13) {
|
|
780
|
+
if (!path13)
|
|
786
781
|
return obj;
|
|
787
|
-
return
|
|
782
|
+
return path13.reduce((acc, key) => acc?.[key], obj);
|
|
788
783
|
}
|
|
789
784
|
function promiseAllObject(promisesObj) {
|
|
790
785
|
const keys = Object.keys(promisesObj);
|
|
@@ -1193,11 +1188,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1193
1188
|
}
|
|
1194
1189
|
return false;
|
|
1195
1190
|
}
|
|
1196
|
-
function prefixIssues(
|
|
1191
|
+
function prefixIssues(path13, issues) {
|
|
1197
1192
|
return issues.map((iss) => {
|
|
1198
1193
|
var _a3;
|
|
1199
1194
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1200
|
-
iss.path.unshift(
|
|
1195
|
+
iss.path.unshift(path13);
|
|
1201
1196
|
return iss;
|
|
1202
1197
|
});
|
|
1203
1198
|
}
|
|
@@ -1344,16 +1339,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1344
1339
|
}
|
|
1345
1340
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1346
1341
|
const fieldErrors = { _errors: [] };
|
|
1347
|
-
const processError = (error52,
|
|
1342
|
+
const processError = (error52, path13 = []) => {
|
|
1348
1343
|
for (const issue2 of error52.issues) {
|
|
1349
1344
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1350
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1345
|
+
issue2.errors.map((issues) => processError({ issues }, [...path13, ...issue2.path]));
|
|
1351
1346
|
} else if (issue2.code === "invalid_key") {
|
|
1352
|
-
processError({ issues: issue2.issues }, [...
|
|
1347
|
+
processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
|
|
1353
1348
|
} else if (issue2.code === "invalid_element") {
|
|
1354
|
-
processError({ issues: issue2.issues }, [...
|
|
1349
|
+
processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
|
|
1355
1350
|
} else {
|
|
1356
|
-
const fullpath = [...
|
|
1351
|
+
const fullpath = [...path13, ...issue2.path];
|
|
1357
1352
|
if (fullpath.length === 0) {
|
|
1358
1353
|
fieldErrors._errors.push(mapper(issue2));
|
|
1359
1354
|
} else {
|
|
@@ -1380,17 +1375,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1380
1375
|
}
|
|
1381
1376
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1382
1377
|
const result = { errors: [] };
|
|
1383
|
-
const processError = (error52,
|
|
1378
|
+
const processError = (error52, path13 = []) => {
|
|
1384
1379
|
var _a3, _b;
|
|
1385
1380
|
for (const issue2 of error52.issues) {
|
|
1386
1381
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1387
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1382
|
+
issue2.errors.map((issues) => processError({ issues }, [...path13, ...issue2.path]));
|
|
1388
1383
|
} else if (issue2.code === "invalid_key") {
|
|
1389
|
-
processError({ issues: issue2.issues }, [...
|
|
1384
|
+
processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
|
|
1390
1385
|
} else if (issue2.code === "invalid_element") {
|
|
1391
|
-
processError({ issues: issue2.issues }, [...
|
|
1386
|
+
processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
|
|
1392
1387
|
} else {
|
|
1393
|
-
const fullpath = [...
|
|
1388
|
+
const fullpath = [...path13, ...issue2.path];
|
|
1394
1389
|
if (fullpath.length === 0) {
|
|
1395
1390
|
result.errors.push(mapper(issue2));
|
|
1396
1391
|
continue;
|
|
@@ -1422,8 +1417,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1422
1417
|
}
|
|
1423
1418
|
function toDotPath(_path) {
|
|
1424
1419
|
const segs = [];
|
|
1425
|
-
const
|
|
1426
|
-
for (const seg of
|
|
1420
|
+
const path13 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1421
|
+
for (const seg of path13) {
|
|
1427
1422
|
if (typeof seg === "number")
|
|
1428
1423
|
segs.push(`[${seg}]`);
|
|
1429
1424
|
else if (typeof seg === "symbol")
|
|
@@ -14115,13 +14110,13 @@ function resolveRef(ref, ctx) {
|
|
|
14115
14110
|
if (!ref.startsWith("#")) {
|
|
14116
14111
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14117
14112
|
}
|
|
14118
|
-
const
|
|
14119
|
-
if (
|
|
14113
|
+
const path13 = ref.slice(1).split("/").filter(Boolean);
|
|
14114
|
+
if (path13.length === 0) {
|
|
14120
14115
|
return ctx.rootSchema;
|
|
14121
14116
|
}
|
|
14122
14117
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14123
|
-
if (
|
|
14124
|
-
const key =
|
|
14118
|
+
if (path13[0] === defsKey) {
|
|
14119
|
+
const key = path13[1];
|
|
14125
14120
|
if (!key || !ctx.defs[key]) {
|
|
14126
14121
|
throw new Error(`Reference not found: ${ref}`);
|
|
14127
14122
|
}
|
|
@@ -14584,6 +14579,55 @@ var credentialImportsParamsSchema = external_exports.object({
|
|
|
14584
14579
|
request: credentialImportsRequestSchema
|
|
14585
14580
|
}).strict();
|
|
14586
14581
|
|
|
14582
|
+
// ../../shared-contracts/dist/harness-display-settings.js
|
|
14583
|
+
var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
|
|
14584
|
+
agent: external_exports.string().min(1).max(128),
|
|
14585
|
+
section: external_exports.enum(["main", "more", "auto"])
|
|
14586
|
+
})).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
|
|
14587
|
+
var harnessDisplaySettingsSchema = external_exports.strictObject({
|
|
14588
|
+
entries: harnessDisplayEntriesSchema.nullable()
|
|
14589
|
+
});
|
|
14590
|
+
var harnessDisplayGetSchema = external_exports.strictObject({});
|
|
14591
|
+
var harnessDisplaySetSchema = external_exports.strictObject({
|
|
14592
|
+
entries: harnessDisplayEntriesSchema,
|
|
14593
|
+
/** Import legacy Desktop preferences only if no shared settings exist yet. */
|
|
14594
|
+
initializeOnly: external_exports.boolean().optional()
|
|
14595
|
+
});
|
|
14596
|
+
|
|
14597
|
+
// ../../shared-contracts/dist/console.js
|
|
14598
|
+
var consoleAnnouncementSchema = external_exports.strictObject({
|
|
14599
|
+
title: external_exports.string().trim().min(1).max(200),
|
|
14600
|
+
type: external_exports.enum(["info", "warning", "danger"]),
|
|
14601
|
+
body: external_exports.string().trim().min(1).max(16 * 1024)
|
|
14602
|
+
});
|
|
14603
|
+
var consoleOpenParamsSchema = external_exports.strictObject({});
|
|
14604
|
+
var consoleOpenResultSchema = external_exports.strictObject({
|
|
14605
|
+
/** The console address. */
|
|
14606
|
+
url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
|
|
14607
|
+
});
|
|
14608
|
+
var CONSOLE_HOST_METHODS = Object.freeze([
|
|
14609
|
+
"codexhost/harness/plugins/list",
|
|
14610
|
+
"codexhost/harness/display-settings/get",
|
|
14611
|
+
"codexhost/harness/display-settings/set",
|
|
14612
|
+
"codexhost/harness/inspect",
|
|
14613
|
+
"codexhost/harness/launch-settings/get",
|
|
14614
|
+
"codexhost/harness/launch-settings/set",
|
|
14615
|
+
"codexhost/harness/web-ui/open",
|
|
14616
|
+
"codexhost/harness/accounts/sources",
|
|
14617
|
+
"codexhost/harness/accounts/list",
|
|
14618
|
+
"codexhost/harness/accounts/inspect",
|
|
14619
|
+
"codexhost/harness/credential-imports",
|
|
14620
|
+
"codexhost/harness/session-import/sources",
|
|
14621
|
+
"codexhost/harness/session-import/list",
|
|
14622
|
+
"codexhost/harness/session-import/import",
|
|
14623
|
+
"codexhost/account/list",
|
|
14624
|
+
"codexhost/account/refresh",
|
|
14625
|
+
"codexhost/account/usage/inspect",
|
|
14626
|
+
"codexhost/update/check",
|
|
14627
|
+
"codexhost/update/start",
|
|
14628
|
+
"codexhost/update/status"
|
|
14629
|
+
]);
|
|
14630
|
+
|
|
14587
14631
|
// ../../shared-contracts/dist/version.js
|
|
14588
14632
|
var WORKSPACE_CONTRACT_VERSION = 1;
|
|
14589
14633
|
|
|
@@ -14637,6 +14681,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
|
|
|
14637
14681
|
var hostItemIdSchema = opaqueIdSchema.brand();
|
|
14638
14682
|
var hostInteractionIdSchema = opaqueIdSchema.brand();
|
|
14639
14683
|
|
|
14684
|
+
// ../../shared-contracts/dist/manual-compaction.js
|
|
14685
|
+
var threadManualCompactionStartedSchema = external_exports.strictObject({
|
|
14686
|
+
threadId: hostThreadIdSchema,
|
|
14687
|
+
turnId: hostTurnIdSchema
|
|
14688
|
+
});
|
|
14689
|
+
|
|
14640
14690
|
// ../../shared-contracts/dist/thread-usage.js
|
|
14641
14691
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
14642
14692
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
@@ -14697,6 +14747,10 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
14697
14747
|
var usagePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
14698
14748
|
var accountCreditsProductUsageSchema = external_exports.object({
|
|
14699
14749
|
product: external_exports.string().min(1),
|
|
14750
|
+
used: external_exports.number().finite().nonnegative().optional(),
|
|
14751
|
+
// Zero is a real empty cap, not an absent field.
|
|
14752
|
+
limit: external_exports.number().finite().nonnegative().optional(),
|
|
14753
|
+
unit: external_exports.string().min(1).max(32).optional(),
|
|
14700
14754
|
usagePercent: usagePercentSchema,
|
|
14701
14755
|
resetsAt: external_exports.string().min(1).optional()
|
|
14702
14756
|
}).strict();
|
|
@@ -14706,6 +14760,10 @@ var accountResetCreditsSchema = external_exports.object({
|
|
|
14706
14760
|
expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
|
|
14707
14761
|
}).strict();
|
|
14708
14762
|
var accountCreditsSnapshotSchema = external_exports.object({
|
|
14763
|
+
used: external_exports.number().finite().nonnegative().optional(),
|
|
14764
|
+
// Zero is a real empty cap, not an absent field.
|
|
14765
|
+
limit: external_exports.number().finite().nonnegative().optional(),
|
|
14766
|
+
unit: external_exports.string().min(1).max(32).optional(),
|
|
14709
14767
|
/** Native label when the primary limit is scoped to a model or product group. */
|
|
14710
14768
|
label: external_exports.string().min(1).optional(),
|
|
14711
14769
|
usedPercent: usagePercentSchema,
|
|
@@ -14725,12 +14783,27 @@ var threadUsageInspectionSchema = external_exports.object({
|
|
|
14725
14783
|
}).strict();
|
|
14726
14784
|
|
|
14727
14785
|
// ../../shared-contracts/dist/harness-accounts.js
|
|
14728
|
-
var
|
|
14786
|
+
var accountBalanceSnapshotSchema = external_exports.object({
|
|
14787
|
+
amount: external_exports.number().finite().nonnegative(),
|
|
14788
|
+
/** ISO 4217 code as reported by the Provider, for example `CNY`. */
|
|
14789
|
+
currency: external_exports.string().trim().min(1).max(8),
|
|
14790
|
+
/** Native label when the Harness exposes several Billing Sources. */
|
|
14791
|
+
label: external_exports.string().trim().min(1).max(128).optional()
|
|
14792
|
+
}).strict();
|
|
14793
|
+
var harnessAccountSnapshotObject = external_exports.object({
|
|
14729
14794
|
email: external_exports.string().trim().min(1).max(320).optional(),
|
|
14730
14795
|
label: external_exports.string().trim().min(1).max(256).optional(),
|
|
14731
14796
|
plan: external_exports.string().trim().min(1).max(128).optional(),
|
|
14732
|
-
credits: accountCreditsSnapshotSchema
|
|
14797
|
+
credits: accountCreditsSnapshotSchema.optional(),
|
|
14798
|
+
balance: accountBalanceSnapshotSchema.optional()
|
|
14733
14799
|
}).strict();
|
|
14800
|
+
function requireReportedQuota(schema) {
|
|
14801
|
+
return schema.refine((value) => {
|
|
14802
|
+
const reported = value;
|
|
14803
|
+
return reported.credits !== void 0 || reported.balance !== void 0;
|
|
14804
|
+
}, { message: "Account must report either credits or a balance" });
|
|
14805
|
+
}
|
|
14806
|
+
var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
|
|
14734
14807
|
var harnessAccountIdentityShape = {
|
|
14735
14808
|
harnessId: harnessIdSchema,
|
|
14736
14809
|
harnessName: external_exports.string().trim().min(1).max(128)
|
|
@@ -14741,11 +14814,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
|
|
|
14741
14814
|
var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
|
|
14742
14815
|
var harnessAccountInspectResultSchema = external_exports.object({
|
|
14743
14816
|
...harnessAccountIdentityShape,
|
|
14744
|
-
account: harnessAccountSnapshotSchema.nullable()
|
|
14817
|
+
account: harnessAccountSnapshotSchema.nullable(),
|
|
14818
|
+
/** Every Billing Source from one Harness; `account` remains the first for older clients. */
|
|
14819
|
+
accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
|
|
14745
14820
|
}).strict();
|
|
14746
14821
|
var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
|
|
14747
14822
|
var harnessAccountListResultSchema = external_exports.object({
|
|
14748
|
-
accounts: external_exports.array(
|
|
14823
|
+
accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
|
|
14749
14824
|
}).strict();
|
|
14750
14825
|
|
|
14751
14826
|
// ../../shared-contracts/dist/json-value.js
|
|
@@ -14883,6 +14958,8 @@ var harnessModelSchema = external_exports.object({
|
|
|
14883
14958
|
ref: harnessModelRefSchema,
|
|
14884
14959
|
label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
|
|
14885
14960
|
resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
|
|
14961
|
+
/** Optional opaque selection for this same Model with priority processing enabled. */
|
|
14962
|
+
fastModel: harnessModelRefSchema.optional(),
|
|
14886
14963
|
supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
|
|
14887
14964
|
}).strict();
|
|
14888
14965
|
var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
|
|
@@ -14915,6 +14992,16 @@ var harnessModelCatalogSchema = external_exports.object({
|
|
|
14915
14992
|
});
|
|
14916
14993
|
}
|
|
14917
14994
|
refs.add(model.ref.id);
|
|
14995
|
+
if (model.fastModel) {
|
|
14996
|
+
if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
|
|
14997
|
+
context.addIssue({
|
|
14998
|
+
code: "custom",
|
|
14999
|
+
message: "Fast Model refs must be distinct and unique",
|
|
15000
|
+
path: ["models", index, "fastModel"]
|
|
15001
|
+
});
|
|
15002
|
+
}
|
|
15003
|
+
refs.add(model.fastModel.id);
|
|
15004
|
+
}
|
|
14918
15005
|
const supportedThinkingIds = /* @__PURE__ */ new Set();
|
|
14919
15006
|
for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
|
|
14920
15007
|
if (supportedThinkingIds.has(optionId)) {
|
|
@@ -15034,11 +15121,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
|
|
|
15034
15121
|
thinkingOptionId: harnessThinkingOptionIdSchema
|
|
15035
15122
|
}).strict();
|
|
15036
15123
|
var threadInspectionParamsSchema = external_exports.object({
|
|
15037
|
-
threadId: hostThreadIdSchema
|
|
15124
|
+
threadId: hostThreadIdSchema,
|
|
15125
|
+
includeReferenceCapability: external_exports.boolean().optional()
|
|
15038
15126
|
}).strict();
|
|
15039
15127
|
var codexThreadInspectionSchema = external_exports.object({
|
|
15040
15128
|
owner: external_exports.literal("codex"),
|
|
15041
|
-
locked: external_exports.literal(true)
|
|
15129
|
+
locked: external_exports.literal(true),
|
|
15130
|
+
supportsThreadReferences: external_exports.literal(true).optional()
|
|
15042
15131
|
}).strict();
|
|
15043
15132
|
var externalThreadInspectionSchema = external_exports.object({
|
|
15044
15133
|
owner: external_exports.literal("external"),
|
|
@@ -15164,6 +15253,19 @@ var harnessLaunchSettingsSchema = external_exports.object({
|
|
|
15164
15253
|
restartRequired: external_exports.boolean()
|
|
15165
15254
|
}).strict();
|
|
15166
15255
|
|
|
15256
|
+
// ../../shared-contracts/dist/harness-installation.js
|
|
15257
|
+
var harnessInstallationParamsSchema = external_exports.object({
|
|
15258
|
+
harnessId: harnessIdSchema,
|
|
15259
|
+
action: external_exports.enum(["check", "update"])
|
|
15260
|
+
}).strict();
|
|
15261
|
+
var harnessInstallationStateSchema = external_exports.object({
|
|
15262
|
+
currentVersion: external_exports.string().min(1).max(128),
|
|
15263
|
+
latestVersion: external_exports.string().min(1).max(128),
|
|
15264
|
+
updateAvailable: external_exports.boolean(),
|
|
15265
|
+
canUpdate: external_exports.boolean(),
|
|
15266
|
+
message: external_exports.string().max(2048).optional()
|
|
15267
|
+
}).strict();
|
|
15268
|
+
|
|
15167
15269
|
// ../../shared-contracts/dist/codex-accounts.js
|
|
15168
15270
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
15169
15271
|
var nonBlankTextSchema3 = external_exports.string().trim().min(1);
|
|
@@ -15466,11 +15568,164 @@ var updateStatusResultSchema = external_exports.strictObject({
|
|
|
15466
15568
|
// ../../shared-contracts/dist/index.js
|
|
15467
15569
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
15468
15570
|
|
|
15571
|
+
// dist/account-balance.js
|
|
15572
|
+
var DEEPSEEK_BALANCE_ENDPOINT = "https://api.deepseek.com/user/balance";
|
|
15573
|
+
var SUB2API_USAGE_PATH = "/v1/usage";
|
|
15574
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
15575
|
+
var MAX_PI_ACCOUNTS = 8;
|
|
15576
|
+
function agentDirectory(environment) {
|
|
15577
|
+
const configured = environment.PI_CODING_AGENT_DIR?.trim();
|
|
15578
|
+
if (configured)
|
|
15579
|
+
return configured;
|
|
15580
|
+
return path.join(environment.HOME ?? environment.USERPROFILE ?? homedir(), ".pi", "agent");
|
|
15581
|
+
}
|
|
15582
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
15583
|
+
async function deepSeekApiKey(environment) {
|
|
15584
|
+
const auth = record2(JSON.parse(await readFile(path.join(agentDirectory(environment), "auth.json"), "utf8")));
|
|
15585
|
+
const deepseek = record2(auth.deepseek);
|
|
15586
|
+
if (deepseek.type !== "api_key")
|
|
15587
|
+
return void 0;
|
|
15588
|
+
return typeof deepseek.key === "string" && deepseek.key.trim() ? deepseek.key : void 0;
|
|
15589
|
+
}
|
|
15590
|
+
function projectSub2ApiUsage(payload, providerId) {
|
|
15591
|
+
const data = record2(payload);
|
|
15592
|
+
if (data.isValid === false)
|
|
15593
|
+
return null;
|
|
15594
|
+
if (data.mode !== "unrestricted" && data.mode !== "quota_limited")
|
|
15595
|
+
return null;
|
|
15596
|
+
const currency = typeof data.unit === "string" ? data.unit.trim() : "";
|
|
15597
|
+
if (!/^[A-Z]{3}$/u.test(currency))
|
|
15598
|
+
return null;
|
|
15599
|
+
const wallet = finiteAmount(data.balance);
|
|
15600
|
+
const remaining = finiteAmount(data.remaining);
|
|
15601
|
+
const quotaRemaining = finiteAmount(record2(data.quota).remaining);
|
|
15602
|
+
const amount = wallet ?? remaining ?? quotaRemaining;
|
|
15603
|
+
if (amount === null)
|
|
15604
|
+
return null;
|
|
15605
|
+
const planName = typeof data.planName === "string" ? data.planName.trim() : "";
|
|
15606
|
+
const label = providerId.trim();
|
|
15607
|
+
if (!label || label.length > 128)
|
|
15608
|
+
return null;
|
|
15609
|
+
const parsed = harnessAccountSnapshotSchema.safeParse({
|
|
15610
|
+
label,
|
|
15611
|
+
...planName ? { plan: planName.slice(0, 128) } : {},
|
|
15612
|
+
balance: { amount, currency, label: planName || label }
|
|
15613
|
+
});
|
|
15614
|
+
return parsed.success ? parsed.data : null;
|
|
15615
|
+
}
|
|
15616
|
+
function finiteAmount(value) {
|
|
15617
|
+
const amount = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : Number.NaN;
|
|
15618
|
+
return Number.isFinite(amount) && amount >= 0 ? amount : null;
|
|
15619
|
+
}
|
|
15620
|
+
function projectDeepSeekBalance(payload) {
|
|
15621
|
+
const data = record2(payload);
|
|
15622
|
+
if (!Array.isArray(data.balance_infos))
|
|
15623
|
+
return null;
|
|
15624
|
+
const first = record2(data.balance_infos[0]);
|
|
15625
|
+
const amount = finiteAmount(first.total_balance);
|
|
15626
|
+
const currency = typeof first.currency === "string" ? first.currency.trim() : "";
|
|
15627
|
+
if (amount === null || !currency)
|
|
15628
|
+
return null;
|
|
15629
|
+
const parsed = harnessAccountSnapshotSchema.safeParse({
|
|
15630
|
+
label: "DeepSeek",
|
|
15631
|
+
balance: { amount, currency, label: "DeepSeek API" }
|
|
15632
|
+
});
|
|
15633
|
+
return parsed.success ? parsed.data : null;
|
|
15634
|
+
}
|
|
15635
|
+
function usageEndpoint(baseUrl) {
|
|
15636
|
+
let url2;
|
|
15637
|
+
try {
|
|
15638
|
+
url2 = new URL(baseUrl);
|
|
15639
|
+
} catch {
|
|
15640
|
+
return null;
|
|
15641
|
+
}
|
|
15642
|
+
if (url2.protocol !== "https:" && url2.protocol !== "http:" || !url2.hostname)
|
|
15643
|
+
return null;
|
|
15644
|
+
url2.username = "";
|
|
15645
|
+
url2.password = "";
|
|
15646
|
+
url2.pathname = SUB2API_USAGE_PATH;
|
|
15647
|
+
url2.search = "";
|
|
15648
|
+
url2.hash = "";
|
|
15649
|
+
return url2.toString();
|
|
15650
|
+
}
|
|
15651
|
+
async function configuredSub2ApiProviders(environment) {
|
|
15652
|
+
try {
|
|
15653
|
+
const models = record2(JSON.parse(await readFile(path.join(agentDirectory(environment), "models.json"), "utf8")));
|
|
15654
|
+
const providers = record2(models.providers);
|
|
15655
|
+
const found = [];
|
|
15656
|
+
for (const [id, definition] of Object.entries(providers)) {
|
|
15657
|
+
const provider = record2(definition);
|
|
15658
|
+
const apiKey = typeof provider.apiKey === "string" ? provider.apiKey.trim() : "";
|
|
15659
|
+
const baseUrl = typeof provider.baseUrl === "string" ? provider.baseUrl.trim() : "";
|
|
15660
|
+
if (!id.trim() || id.length > 128 || !apiKey || !usageEndpoint(baseUrl))
|
|
15661
|
+
continue;
|
|
15662
|
+
found.push({ id, apiKey, baseUrl });
|
|
15663
|
+
}
|
|
15664
|
+
return found.sort((left, right) => left.id.localeCompare(right.id));
|
|
15665
|
+
} catch {
|
|
15666
|
+
return [];
|
|
15667
|
+
}
|
|
15668
|
+
}
|
|
15669
|
+
async function fetchSub2ApiBalance(provider, fetchImpl, signal) {
|
|
15670
|
+
const endpoint = usageEndpoint(provider.baseUrl);
|
|
15671
|
+
if (!endpoint)
|
|
15672
|
+
return null;
|
|
15673
|
+
const response = await fetchImpl(endpoint, {
|
|
15674
|
+
headers: { Authorization: `Bearer ${provider.apiKey}`, Accept: "application/json" },
|
|
15675
|
+
redirect: "error",
|
|
15676
|
+
signal
|
|
15677
|
+
});
|
|
15678
|
+
if (!response.ok)
|
|
15679
|
+
return null;
|
|
15680
|
+
return projectSub2ApiUsage(await response.json(), provider.id);
|
|
15681
|
+
}
|
|
15682
|
+
async function fetchPiAccounts(input = {}) {
|
|
15683
|
+
try {
|
|
15684
|
+
const environment = input.environment ?? process.env;
|
|
15685
|
+
const fetchImpl = input.fetch ?? fetch;
|
|
15686
|
+
const signal = input.signal ? AbortSignal.any([input.signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]) : AbortSignal.timeout(REQUEST_TIMEOUT_MS);
|
|
15687
|
+
const [providers, deepseek] = await Promise.all([
|
|
15688
|
+
input.readProviders ? input.readProviders() : configuredSub2ApiProviders(environment),
|
|
15689
|
+
fetchPiAccountBalance({ ...input, environment, fetch: fetchImpl, signal })
|
|
15690
|
+
]);
|
|
15691
|
+
const wallets = await Promise.all(providers.filter((provider) => provider.apiKey.trim() && usageEndpoint(provider.baseUrl)).map((provider) => fetchSub2ApiBalance(provider, fetchImpl, signal).catch(() => null)));
|
|
15692
|
+
return [...wallets, deepseek].filter((account) => account !== null).slice(0, MAX_PI_ACCOUNTS);
|
|
15693
|
+
} catch {
|
|
15694
|
+
return [];
|
|
15695
|
+
}
|
|
15696
|
+
}
|
|
15697
|
+
async function fetchPiAccountBalance(input) {
|
|
15698
|
+
try {
|
|
15699
|
+
const key = await (input.readApiKey ? input.readApiKey() : deepSeekApiKey(input.environment));
|
|
15700
|
+
if (!key)
|
|
15701
|
+
return null;
|
|
15702
|
+
const response = await input.fetch(DEEPSEEK_BALANCE_ENDPOINT, {
|
|
15703
|
+
headers: { Authorization: `Bearer ${key}`, Accept: "application/json" },
|
|
15704
|
+
signal: input.signal
|
|
15705
|
+
});
|
|
15706
|
+
if (!response.ok)
|
|
15707
|
+
return null;
|
|
15708
|
+
return projectDeepSeekBalance(await response.json());
|
|
15709
|
+
} catch {
|
|
15710
|
+
return null;
|
|
15711
|
+
}
|
|
15712
|
+
}
|
|
15713
|
+
|
|
15714
|
+
// dist/pi-credential-imports.js
|
|
15715
|
+
import { randomUUID } from "node:crypto";
|
|
15716
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
15717
|
+
import { promisify } from "node:util";
|
|
15718
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync, lstatSync, renameSync, rmdirSync } from "node:fs";
|
|
15719
|
+
import { realpath } from "node:fs/promises";
|
|
15720
|
+
import os2 from "node:os";
|
|
15721
|
+
import path5 from "node:path";
|
|
15722
|
+
import { pathToFileURL } from "node:url";
|
|
15723
|
+
|
|
15469
15724
|
// ../../harness-discovery/dist/environment.js
|
|
15470
15725
|
import fs from "node:fs";
|
|
15471
|
-
import
|
|
15726
|
+
import path2 from "node:path";
|
|
15472
15727
|
function targetPath(platform) {
|
|
15473
|
-
return platform === "win32" ?
|
|
15728
|
+
return platform === "win32" ? path2.win32 : path2.posix;
|
|
15474
15729
|
}
|
|
15475
15730
|
function environmentValue(environment, name) {
|
|
15476
15731
|
const lowered = name.toLowerCase();
|
|
@@ -15512,12 +15767,28 @@ function newestFirst(names) {
|
|
|
15512
15767
|
return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
|
|
15513
15768
|
}
|
|
15514
15769
|
|
|
15770
|
+
// ../../harness-discovery/dist/invocation.js
|
|
15771
|
+
import path3 from "node:path";
|
|
15772
|
+
function commandInvocation(command, arguments_, environment, platform = process.platform) {
|
|
15773
|
+
const extension = path3.win32.extname(command).toLowerCase();
|
|
15774
|
+
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
15775
|
+
return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
|
|
15776
|
+
}
|
|
15777
|
+
const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
|
|
15778
|
+
const commandLine = [command, ...arguments_].map(quote).join(" ");
|
|
15779
|
+
return {
|
|
15780
|
+
command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
|
|
15781
|
+
arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
|
|
15782
|
+
windowsVerbatimArguments: true
|
|
15783
|
+
};
|
|
15784
|
+
}
|
|
15785
|
+
|
|
15515
15786
|
// ../../harness-discovery/dist/node-runtime.js
|
|
15516
|
-
import
|
|
15787
|
+
import path4 from "node:path";
|
|
15517
15788
|
function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
|
|
15518
15789
|
const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
|
|
15519
15790
|
const delimiter = platform === "win32" ? ";" : ":";
|
|
15520
|
-
const runtimeDirectory =
|
|
15791
|
+
const runtimeDirectory = path4.dirname(runtimeExecutable);
|
|
15521
15792
|
const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
|
|
15522
15793
|
const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
|
|
15523
15794
|
if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
|
|
@@ -15689,6 +15960,116 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
|
|
|
15689
15960
|
return void 0;
|
|
15690
15961
|
}
|
|
15691
15962
|
|
|
15963
|
+
// ../../harness-discovery/dist/installation.js
|
|
15964
|
+
import { execFile } from "node:child_process";
|
|
15965
|
+
import { homedir as homedir2 } from "node:os";
|
|
15966
|
+
function runInstallationCommand(command, args, environment, timeout = 3e4) {
|
|
15967
|
+
const env = withNodeRuntimeOnPath(environment);
|
|
15968
|
+
const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
|
|
15969
|
+
return new Promise((resolve, reject) => {
|
|
15970
|
+
const child = execFile(invocation.command, invocation.arguments, {
|
|
15971
|
+
env,
|
|
15972
|
+
cwd: env.HOME ?? env.USERPROFILE ?? homedir2(),
|
|
15973
|
+
encoding: "utf8",
|
|
15974
|
+
timeout,
|
|
15975
|
+
killSignal: "SIGKILL",
|
|
15976
|
+
maxBuffer: 1024 * 1024,
|
|
15977
|
+
windowsHide: true,
|
|
15978
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
15979
|
+
}, (error51, stdout, stderr) => {
|
|
15980
|
+
if (error51)
|
|
15981
|
+
reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
|
|
15982
|
+
else
|
|
15983
|
+
resolve((stdout || stderr).trim());
|
|
15984
|
+
});
|
|
15985
|
+
child.stdin?.end();
|
|
15986
|
+
});
|
|
15987
|
+
}
|
|
15988
|
+
function installationVersion(value) {
|
|
15989
|
+
if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
|
|
15990
|
+
throw new Error("Harness returned an invalid version");
|
|
15991
|
+
return value.trim().replace(/^v/, "");
|
|
15992
|
+
}
|
|
15993
|
+
function versionFromOutput(output) {
|
|
15994
|
+
return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
|
|
15995
|
+
}
|
|
15996
|
+
function newerInstallationVersion(current, latest) {
|
|
15997
|
+
const a = installationVersion(current).replace(/\+.*/, "");
|
|
15998
|
+
const b = installationVersion(latest).replace(/\+.*/, "");
|
|
15999
|
+
const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
|
|
16000
|
+
const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
|
|
16001
|
+
for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
|
|
16002
|
+
if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
|
|
16003
|
+
return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
|
|
16004
|
+
}
|
|
16005
|
+
const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
|
|
16006
|
+
const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
|
|
16007
|
+
if (!preA.length || !preB.length)
|
|
16008
|
+
return !!preA.length && !preB.length;
|
|
16009
|
+
for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
|
|
16010
|
+
const x = preA[i];
|
|
16011
|
+
const y = preB[i];
|
|
16012
|
+
if (x === y)
|
|
16013
|
+
continue;
|
|
16014
|
+
if (x === void 0 || y === void 0)
|
|
16015
|
+
return x === void 0;
|
|
16016
|
+
const numericX = /^\d+$/.test(x);
|
|
16017
|
+
const numericY = /^\d+$/.test(y);
|
|
16018
|
+
if (numericX && numericY) {
|
|
16019
|
+
if (BigInt(x) === BigInt(y))
|
|
16020
|
+
continue;
|
|
16021
|
+
return BigInt(y) > BigInt(x);
|
|
16022
|
+
}
|
|
16023
|
+
if (numericX !== numericY)
|
|
16024
|
+
return numericX;
|
|
16025
|
+
return y > x;
|
|
16026
|
+
}
|
|
16027
|
+
return false;
|
|
16028
|
+
}
|
|
16029
|
+
function createInstallationManager(options) {
|
|
16030
|
+
let checking;
|
|
16031
|
+
let updating;
|
|
16032
|
+
const check2 = () => checking ??= options.check().finally(() => {
|
|
16033
|
+
checking = void 0;
|
|
16034
|
+
});
|
|
16035
|
+
return (action) => {
|
|
16036
|
+
if (updating)
|
|
16037
|
+
return updating;
|
|
16038
|
+
if (action === "check")
|
|
16039
|
+
return check2();
|
|
16040
|
+
updating = (async () => {
|
|
16041
|
+
const before = await check2();
|
|
16042
|
+
if (!before.updateAvailable)
|
|
16043
|
+
return before;
|
|
16044
|
+
if (!before.canUpdate)
|
|
16045
|
+
throw new Error(before.message ?? "This installation cannot be updated automatically");
|
|
16046
|
+
await options.update(before);
|
|
16047
|
+
const after = await check2();
|
|
16048
|
+
if (after.currentVersion === before.currentVersion)
|
|
16049
|
+
throw new Error("The Harness version did not change; check the native updater and retry");
|
|
16050
|
+
return after;
|
|
16051
|
+
})().finally(() => {
|
|
16052
|
+
updating = void 0;
|
|
16053
|
+
});
|
|
16054
|
+
return updating;
|
|
16055
|
+
};
|
|
16056
|
+
}
|
|
16057
|
+
async function fetchInstallationText(url2) {
|
|
16058
|
+
const request = async () => {
|
|
16059
|
+
const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
|
|
16060
|
+
if (!response.ok)
|
|
16061
|
+
throw new Error("Could not check the latest Harness version");
|
|
16062
|
+
return response.text();
|
|
16063
|
+
};
|
|
16064
|
+
try {
|
|
16065
|
+
return await request();
|
|
16066
|
+
} catch (error51) {
|
|
16067
|
+
if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
|
|
16068
|
+
throw error51;
|
|
16069
|
+
return request();
|
|
16070
|
+
}
|
|
16071
|
+
}
|
|
16072
|
+
|
|
15692
16073
|
// dist/command.js
|
|
15693
16074
|
var piDiscoverySpec = {
|
|
15694
16075
|
id: "pi",
|
|
@@ -15756,6 +16137,15 @@ function describeOauth(credential) {
|
|
|
15756
16137
|
...match ? { vendor: match.vendor } : {}
|
|
15757
16138
|
};
|
|
15758
16139
|
}
|
|
16140
|
+
function readPiCodexProviderNames(environment) {
|
|
16141
|
+
const agentDir = environment.PI_CODING_AGENT_DIR ?? path5.join(environment.HOME ?? environment.USERPROFILE ?? os2.homedir(), ".pi/agent");
|
|
16142
|
+
try {
|
|
16143
|
+
const auth = parseAuth(readFileSync(path5.join(agentDir, "auth.json"), "utf8"));
|
|
16144
|
+
return Object.entries(auth).filter(([, credential]) => describeOauth(credential).vendor === "openai-codex").map(([provider]) => provider);
|
|
16145
|
+
} catch {
|
|
16146
|
+
return [];
|
|
16147
|
+
}
|
|
16148
|
+
}
|
|
15759
16149
|
function writeAuth(filename, content) {
|
|
15760
16150
|
const temporary = `${filename}.${randomUUID()}.tmp`;
|
|
15761
16151
|
try {
|
|
@@ -15766,8 +16156,8 @@ function writeAuth(filename, content) {
|
|
|
15766
16156
|
}
|
|
15767
16157
|
}
|
|
15768
16158
|
function removeOwnedFiles(dir) {
|
|
15769
|
-
rmSync(
|
|
15770
|
-
rmSync(
|
|
16159
|
+
rmSync(path5.join(dir, "index.ts"), { force: true });
|
|
16160
|
+
rmSync(path5.join(dir, "import.json"), { force: true });
|
|
15771
16161
|
try {
|
|
15772
16162
|
rmdirSync(dir);
|
|
15773
16163
|
} catch {
|
|
@@ -15775,26 +16165,26 @@ function removeOwnedFiles(dir) {
|
|
|
15775
16165
|
}
|
|
15776
16166
|
async function installation(command, environment, authPath) {
|
|
15777
16167
|
const executable = await realpath(resolvePiExecutable({ ...command ? { command } : {}, environment }));
|
|
15778
|
-
let directory =
|
|
16168
|
+
let directory = path5.dirname(executable);
|
|
15779
16169
|
while (true) {
|
|
15780
|
-
const manifest =
|
|
16170
|
+
const manifest = path5.join(directory, "package.json");
|
|
15781
16171
|
if (existsSync(manifest)) {
|
|
15782
16172
|
const pkg = JSON.parse(readFileSync(manifest, "utf8"));
|
|
15783
16173
|
if (pkg.name === "@earendil-works/pi-coding-agent")
|
|
15784
16174
|
break;
|
|
15785
16175
|
}
|
|
15786
|
-
const parent =
|
|
16176
|
+
const parent = path5.dirname(directory);
|
|
15787
16177
|
if (parent === directory)
|
|
15788
16178
|
throw new Error("Pi credential import requires a supported npm Pi installation");
|
|
15789
16179
|
directory = parent;
|
|
15790
16180
|
}
|
|
15791
|
-
const storage = await import(pathToFileURL(
|
|
15792
|
-
const ai =
|
|
15793
|
-
const all = await import(pathToFileURL(
|
|
16181
|
+
const storage = await import(pathToFileURL(path5.join(directory, "dist/core/auth-storage.js")).href);
|
|
16182
|
+
const ai = path5.join(directory, "node_modules/@earendil-works/pi-ai/dist");
|
|
16183
|
+
const all = await import(pathToFileURL(path5.join(ai, "providers/all.js")).href);
|
|
15794
16184
|
const providers = all.getBuiltinProviders();
|
|
15795
16185
|
const providerModules = {
|
|
15796
|
-
"openai-codex": pathToFileURL(
|
|
15797
|
-
xai: pathToFileURL(
|
|
16186
|
+
"openai-codex": pathToFileURL(path5.join(ai, "providers/openai-codex.js")).href,
|
|
16187
|
+
xai: pathToFileURL(path5.join(ai, "providers/xai.js")).href
|
|
15798
16188
|
};
|
|
15799
16189
|
for (const [id, url2] of Object.entries(providerModules)) {
|
|
15800
16190
|
const module = await import(url2);
|
|
@@ -15807,9 +16197,9 @@ async function installation(command, environment, authPath) {
|
|
|
15807
16197
|
providerModules,
|
|
15808
16198
|
reservedNames: providers.map((p) => typeof p === "string" ? p : p.id),
|
|
15809
16199
|
async configuredProviderNames() {
|
|
15810
|
-
const { stdout } = await promisify(
|
|
15811
|
-
cwd: existsSync(
|
|
15812
|
-
env: { ...environment, PI_CODING_AGENT_DIR:
|
|
16200
|
+
const { stdout } = await promisify(execFile2)(process.execPath, [executable, "--offline", "--no-approve", "--list-models"], {
|
|
16201
|
+
cwd: existsSync(path5.dirname(authPath)) ? path5.dirname(authPath) : os2.homedir(),
|
|
16202
|
+
env: { ...environment, PI_CODING_AGENT_DIR: path5.dirname(authPath), PI_OFFLINE: "1" },
|
|
15813
16203
|
timeout: 15e3,
|
|
15814
16204
|
maxBuffer: 4 * 1024 * 1024
|
|
15815
16205
|
});
|
|
@@ -15839,26 +16229,26 @@ export default async function (pi) {
|
|
|
15839
16229
|
}
|
|
15840
16230
|
function createPiCredentialImports(options = {}) {
|
|
15841
16231
|
const env = { ...process.env, ...options.environment };
|
|
15842
|
-
const agentDir = env.PI_CODING_AGENT_DIR ??
|
|
15843
|
-
const authPath =
|
|
15844
|
-
const extensionsDir =
|
|
16232
|
+
const agentDir = env.PI_CODING_AGENT_DIR ?? path5.join(env.HOME ?? os2.homedir(), ".pi/agent");
|
|
16233
|
+
const authPath = path5.join(agentDir, "auth.json");
|
|
16234
|
+
const extensionsDir = path5.join(agentDir, "extensions");
|
|
15845
16235
|
const saveAuth = (auth) => (options.writeAuth ?? writeAuth)(authPath, JSON.stringify(auth, null, 2) + "\n");
|
|
15846
16236
|
const resolve = () => options.resolveInstallation?.(authPath) ?? installation(options.command, env, authPath);
|
|
15847
|
-
const location = (name) =>
|
|
16237
|
+
const location = (name) => path5.join(extensionsDir, `${PREFIX}${credentialImportNameSchema.parse(name)}`);
|
|
15848
16238
|
const readRecord = (name) => {
|
|
15849
16239
|
const dir = location(name);
|
|
15850
16240
|
if (lstatSync(dir).isSymbolicLink())
|
|
15851
16241
|
throw new Error("Imported configuration was changed; manage it in Pi");
|
|
15852
|
-
const value = JSON.parse(readFileSync(
|
|
16242
|
+
const value = JSON.parse(readFileSync(path5.join(dir, "import.json"), "utf8"));
|
|
15853
16243
|
if (value.version !== 1 || typeof value.owner !== "string" || typeof value.extension !== "string")
|
|
15854
16244
|
throw new Error("Invalid import metadata");
|
|
15855
|
-
const
|
|
15856
|
-
if (!object2(
|
|
16245
|
+
const record7 = value.record;
|
|
16246
|
+
if (!object2(record7))
|
|
15857
16247
|
throw new Error("Invalid import metadata");
|
|
15858
16248
|
value.record = credentialImportRecordSchema.parse({
|
|
15859
|
-
name:
|
|
15860
|
-
source:
|
|
15861
|
-
importedAt:
|
|
16249
|
+
name: record7.name,
|
|
16250
|
+
source: record7.source,
|
|
16251
|
+
importedAt: record7.importedAt
|
|
15862
16252
|
});
|
|
15863
16253
|
if (value.record.name !== name)
|
|
15864
16254
|
throw new Error("Import identity mismatch");
|
|
@@ -15866,7 +16256,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15866
16256
|
};
|
|
15867
16257
|
const owned = (meta3, auth) => {
|
|
15868
16258
|
const credential = auth[meta3.record.name];
|
|
15869
|
-
const file2 =
|
|
16259
|
+
const file2 = path5.join(location(meta3.record.name), "index.ts");
|
|
15870
16260
|
return existsSync(file2) && !lstatSync(file2).isSymbolicLink() && readFileSync(file2, "utf8") === meta3.extension && object2(credential) && credential.type === "oauth" && credential.codexhostImportId === meta3.owner;
|
|
15871
16261
|
};
|
|
15872
16262
|
const readAuth = () => existsSync(authPath) ? parseAuth(readFileSync(authPath, "utf8")) : {};
|
|
@@ -15880,7 +16270,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15880
16270
|
const name = entry.slice(PREFIX.length);
|
|
15881
16271
|
if (!credentialImportNameSchema.safeParse(name).success)
|
|
15882
16272
|
continue;
|
|
15883
|
-
if (!existsSync(
|
|
16273
|
+
if (!existsSync(path5.join(location(name), "import.json")))
|
|
15884
16274
|
continue;
|
|
15885
16275
|
try {
|
|
15886
16276
|
const meta3 = readRecord(name);
|
|
@@ -15901,7 +16291,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15901
16291
|
},
|
|
15902
16292
|
async listOthers() {
|
|
15903
16293
|
const auth = readAuth();
|
|
15904
|
-
const ours = new Set(ownedRecords(auth).map((
|
|
16294
|
+
const ours = new Set(ownedRecords(auth).map((record7) => record7.name));
|
|
15905
16295
|
const result = /* @__PURE__ */ new Map();
|
|
15906
16296
|
const usable = (provider) => Boolean(provider) && provider.length <= 128 && !ours.has(provider) && !result.has(provider);
|
|
15907
16297
|
for (const [provider, credential] of Object.entries(auth)) {
|
|
@@ -15914,7 +16304,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15914
16304
|
...describeOauth(credential)
|
|
15915
16305
|
});
|
|
15916
16306
|
}
|
|
15917
|
-
const modelsPath =
|
|
16307
|
+
const modelsPath = path5.join(agentDir, "models.json");
|
|
15918
16308
|
if (existsSync(modelsPath)) {
|
|
15919
16309
|
const models = JSON.parse(readFileSync(modelsPath, "utf8"));
|
|
15920
16310
|
const providers = object2(models) && object2(models.providers) ? models.providers : {};
|
|
@@ -15936,7 +16326,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15936
16326
|
if (sdk.reservedNames.includes(name) || (await sdk.configuredProviderNames?.())?.includes(name))
|
|
15937
16327
|
throw new Error("Provider name already exists; choose another name");
|
|
15938
16328
|
const owner = randomUUID();
|
|
15939
|
-
const
|
|
16329
|
+
const record7 = credentialImportRecordSchema.parse({
|
|
15940
16330
|
name,
|
|
15941
16331
|
source: transfer.source,
|
|
15942
16332
|
importedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -15948,15 +16338,15 @@ function createPiCredentialImports(options = {}) {
|
|
|
15948
16338
|
try {
|
|
15949
16339
|
sdk.backend.withLock((current) => {
|
|
15950
16340
|
const auth = parseAuth(current);
|
|
15951
|
-
const modelsPath =
|
|
16341
|
+
const modelsPath = path5.join(agentDir, "models.json");
|
|
15952
16342
|
const models = existsSync(modelsPath) ? JSON.parse(readFileSync(modelsPath, "utf8")) : {};
|
|
15953
|
-
if (Object.hasOwn(auth, name) || Object.hasOwn(models.providers ?? {}, name) || existsSync(dir) || existsSync(
|
|
16343
|
+
if (Object.hasOwn(auth, name) || Object.hasOwn(models.providers ?? {}, name) || existsSync(dir) || existsSync(path5.join(extensionsDir, `${name}-provider.ts`)))
|
|
15954
16344
|
throw new Error("Provider name already exists; choose another name");
|
|
15955
16345
|
mkdirSync(extensionsDir, { recursive: true, mode: 448 });
|
|
15956
16346
|
mkdirSync(dir, { mode: 448 });
|
|
15957
16347
|
created = true;
|
|
15958
|
-
writeFileSync(
|
|
15959
|
-
writeFileSync(
|
|
16348
|
+
writeFileSync(path5.join(dir, "import.json"), JSON.stringify({ version: 1, owner, record: record7, extension }), { flag: "wx", mode: 384 });
|
|
16349
|
+
writeFileSync(path5.join(dir, "index.ts"), extension, { flag: "wx", mode: 384 });
|
|
15960
16350
|
auth[name] = { type: "oauth", ...transfer.oauth, codexhostImportId: owner };
|
|
15961
16351
|
saveAuth(auth);
|
|
15962
16352
|
committed = true;
|
|
@@ -15975,7 +16365,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15975
16365
|
const auth = parseAuth(current);
|
|
15976
16366
|
if (!owned(meta3, auth) || meta3.record.source.id !== transfer.source.id || meta3.record.source.provider !== transfer.source.provider)
|
|
15977
16367
|
throw new Error("Import ownership or source account changed; refusing replacement");
|
|
15978
|
-
const metadataPath =
|
|
16368
|
+
const metadataPath = path5.join(location(name), "import.json");
|
|
15979
16369
|
const previous = readFileSync(metadataPath, "utf8");
|
|
15980
16370
|
const updated = {
|
|
15981
16371
|
...meta3,
|
|
@@ -16009,15 +16399,229 @@ function createPiCredentialImports(options = {}) {
|
|
|
16009
16399
|
};
|
|
16010
16400
|
}
|
|
16011
16401
|
|
|
16402
|
+
// dist/pi-fast-mode.js
|
|
16403
|
+
import { createHash, randomUUID as randomUUID2 } from "node:crypto";
|
|
16404
|
+
import { mkdir, readFile as readFile2, rename, rm, writeFile } from "node:fs/promises";
|
|
16405
|
+
import { homedir as homedir3 } from "node:os";
|
|
16406
|
+
import path6 from "node:path";
|
|
16407
|
+
|
|
16408
|
+
// dist/pi-model-catalog.js
|
|
16409
|
+
var PI_MODEL_REF_PREFIX = "pi-model-v1.";
|
|
16410
|
+
var PI_DRAFT_THINKING_OPTION_IDS = [
|
|
16411
|
+
"off",
|
|
16412
|
+
"minimal",
|
|
16413
|
+
"low",
|
|
16414
|
+
"medium",
|
|
16415
|
+
"high",
|
|
16416
|
+
"xhigh",
|
|
16417
|
+
"max"
|
|
16418
|
+
].map((id) => harnessThinkingOptionIdSchema.parse(id));
|
|
16419
|
+
var PI_THINKING_LABELS = {
|
|
16420
|
+
off: "Off",
|
|
16421
|
+
minimal: "Minimal",
|
|
16422
|
+
low: "Low",
|
|
16423
|
+
medium: "Medium",
|
|
16424
|
+
high: "High",
|
|
16425
|
+
xhigh: "Extra High",
|
|
16426
|
+
max: "Max"
|
|
16427
|
+
};
|
|
16428
|
+
function compareText(left, right) {
|
|
16429
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
16430
|
+
}
|
|
16431
|
+
function assertNativePart(value, name) {
|
|
16432
|
+
if (value.trim().length === 0)
|
|
16433
|
+
throw new Error(`Pi ${name} must not be empty`);
|
|
16434
|
+
}
|
|
16435
|
+
function encodePiModelRef(model) {
|
|
16436
|
+
assertNativePart(model.provider, "Model provider");
|
|
16437
|
+
assertNativePart(model.id, "Model id");
|
|
16438
|
+
const encoded = Buffer.from(JSON.stringify(model.fast ? [model.provider, model.id, true] : [model.provider, model.id]), "utf8").toString("base64url");
|
|
16439
|
+
return harnessModelRefSchema.parse({ id: `${PI_MODEL_REF_PREFIX}${encoded}` });
|
|
16440
|
+
}
|
|
16441
|
+
function decodePiModelRef(ref) {
|
|
16442
|
+
const parsedRef = harnessModelRefSchema.parse(ref);
|
|
16443
|
+
if (!parsedRef.id.startsWith(PI_MODEL_REF_PREFIX)) {
|
|
16444
|
+
throw new Error("Model Ref does not belong to PiAdapter");
|
|
16445
|
+
}
|
|
16446
|
+
const encoded = parsedRef.id.slice(PI_MODEL_REF_PREFIX.length);
|
|
16447
|
+
let decoded;
|
|
16448
|
+
try {
|
|
16449
|
+
decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
16450
|
+
} catch {
|
|
16451
|
+
throw new Error("Pi Model Ref is malformed");
|
|
16452
|
+
}
|
|
16453
|
+
if (!Array.isArray(decoded) || decoded.length !== 2 && !(decoded.length === 3 && decoded[2] === true) || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") {
|
|
16454
|
+
throw new Error("Pi Model Ref has an invalid native identity");
|
|
16455
|
+
}
|
|
16456
|
+
const native = {
|
|
16457
|
+
provider: decoded[0],
|
|
16458
|
+
id: decoded[1],
|
|
16459
|
+
...decoded[2] === true ? { fast: true } : {}
|
|
16460
|
+
};
|
|
16461
|
+
assertNativePart(native.provider, "Model provider");
|
|
16462
|
+
assertNativePart(native.id, "Model id");
|
|
16463
|
+
if (encodePiModelRef(native).id !== parsedRef.id) {
|
|
16464
|
+
throw new Error("Pi Model Ref is not canonical");
|
|
16465
|
+
}
|
|
16466
|
+
return native;
|
|
16467
|
+
}
|
|
16468
|
+
function samePiModel(left, right) {
|
|
16469
|
+
return left === null ? right === null : right !== null && left.provider === right.provider && left.id === right.id;
|
|
16470
|
+
}
|
|
16471
|
+
function fallbackThinkingLabel(id) {
|
|
16472
|
+
const label = id.split(/[._~-]+/u).filter((part) => part.length > 0).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
16473
|
+
return label || id;
|
|
16474
|
+
}
|
|
16475
|
+
function normalizePiThinkingOptions(levels) {
|
|
16476
|
+
return levels.map((id) => harnessThinkingOptionSchema.parse({
|
|
16477
|
+
id,
|
|
16478
|
+
label: PI_THINKING_LABELS[id] ?? fallbackThinkingLabel(id)
|
|
16479
|
+
}));
|
|
16480
|
+
}
|
|
16481
|
+
function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, effectiveThinkingOptionId) {
|
|
16482
|
+
const byRef = /* @__PURE__ */ new Map();
|
|
16483
|
+
for (const native of nativeModels) {
|
|
16484
|
+
const ref = encodePiModelRef(native);
|
|
16485
|
+
const existing = byRef.get(ref.id);
|
|
16486
|
+
if (existing) {
|
|
16487
|
+
if (existing.reasoning !== native.reasoning) {
|
|
16488
|
+
throw new Error("Pi duplicate Model entries disagree on reasoning capability");
|
|
16489
|
+
}
|
|
16490
|
+
continue;
|
|
16491
|
+
}
|
|
16492
|
+
byRef.set(ref.id, {
|
|
16493
|
+
model: {
|
|
16494
|
+
ref,
|
|
16495
|
+
label: `${native.provider} / ${native.id}`
|
|
16496
|
+
},
|
|
16497
|
+
reasoning: native.reasoning
|
|
16498
|
+
});
|
|
16499
|
+
}
|
|
16500
|
+
const defaultModel = effectiveModel ? encodePiModelRef(effectiveModel) : void 0;
|
|
16501
|
+
if (defaultModel && !byRef.has(defaultModel.id)) {
|
|
16502
|
+
throw new Error("Pi effective Model is absent from the available Model catalog");
|
|
16503
|
+
}
|
|
16504
|
+
if (thinkingLevels && effectiveThinkingOptionId && !thinkingLevels.includes(effectiveThinkingOptionId)) {
|
|
16505
|
+
throw new Error("Pi effective Thinking option is absent from the available option catalog");
|
|
16506
|
+
}
|
|
16507
|
+
if (thinkingLevels && !effectiveThinkingOptionId) {
|
|
16508
|
+
throw new Error("Pi did not report an effective Thinking option");
|
|
16509
|
+
}
|
|
16510
|
+
const thinkingOptions = thinkingLevels ? normalizePiThinkingOptions(PI_DRAFT_THINKING_OPTION_IDS) : [];
|
|
16511
|
+
const allThinkingOptionIds = thinkingOptions.map(({ id }) => id);
|
|
16512
|
+
const offThinkingOptionId = thinkingOptions.find(({ id }) => id === "off")?.id;
|
|
16513
|
+
const models = [...byRef.values()].map(({ model, reasoning }) => ({
|
|
16514
|
+
...model,
|
|
16515
|
+
supportedThinkingOptionIds: reasoning ? allThinkingOptionIds : offThinkingOptionId ? [offThinkingOptionId] : []
|
|
16516
|
+
})).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
|
|
16517
|
+
const defaultThinkingOptionId = thinkingOptions.find(({ id }) => id === effectiveThinkingOptionId)?.id;
|
|
16518
|
+
return harnessModelCatalogSchema.parse({
|
|
16519
|
+
models,
|
|
16520
|
+
...defaultModel ? { defaultModel } : {},
|
|
16521
|
+
thinkingOptions,
|
|
16522
|
+
...defaultThinkingOptionId ? { defaultThinkingOptionId } : {}
|
|
16523
|
+
});
|
|
16524
|
+
}
|
|
16525
|
+
|
|
16526
|
+
// dist/pi-fast-mode.js
|
|
16527
|
+
var PI_FAST_COMMAND = "codexhost-fast-mode";
|
|
16528
|
+
var PI_FAST_ACK = "codexhost-fast-mode:";
|
|
16529
|
+
var PI_FAST_EXTENSION = `export default function(pi) {
|
|
16530
|
+
let target;
|
|
16531
|
+
const wrapped = new Set();
|
|
16532
|
+
pi.on("model_select", (_event, ctx) => {
|
|
16533
|
+
if (target && (target.provider !== ctx.model?.provider || target.id !== ctx.model?.id || ctx.model?.api !== "openai-codex-responses")) target = undefined;
|
|
16534
|
+
});
|
|
16535
|
+
pi.on("session_start", (_event, ctx) => {
|
|
16536
|
+
if (typeof ctx.modelRegistry.getProvider !== "function") return;
|
|
16537
|
+
pi.registerCommand("${PI_FAST_COMMAND}", {
|
|
16538
|
+
description: "Codex Host Fast mode",
|
|
16539
|
+
handler: async (args, ctx) => {
|
|
16540
|
+
const [mode, nonce] = args.split(" ");
|
|
16541
|
+
if (!nonce || (mode !== "on" && mode !== "off")) throw new Error("Invalid Fast selection");
|
|
16542
|
+
if (mode === "on") {
|
|
16543
|
+
const model = ctx.model;
|
|
16544
|
+
if (!model || model.api !== "openai-codex-responses") throw new Error("Fast requires the Codex API");
|
|
16545
|
+
const original = ctx.modelRegistry.getProvider(model.provider);
|
|
16546
|
+
if (!original) throw new Error("Codex Provider is unavailable");
|
|
16547
|
+
if (!wrapped.has(model.provider)) {
|
|
16548
|
+
const options = (model, value) => target && model.api === "openai-codex-responses" && target.provider === model.provider && target.id === model.id
|
|
16549
|
+
? {
|
|
16550
|
+
...value,
|
|
16551
|
+
serviceTier: "priority",
|
|
16552
|
+
// Pi streamSimple drops serviceTier but preserves onPayload.
|
|
16553
|
+
onPayload: async (payload, requestModel) => {
|
|
16554
|
+
const request = { ...payload, service_tier: "priority" };
|
|
16555
|
+
const replacement = await value?.onPayload?.(request, requestModel);
|
|
16556
|
+
return { ...(replacement === undefined ? request : replacement), service_tier: "priority" };
|
|
16557
|
+
},
|
|
16558
|
+
} : value;
|
|
16559
|
+
pi.registerProvider({
|
|
16560
|
+
...original,
|
|
16561
|
+
stream: (model, context, value) => original.stream(model, context, options(model, value)),
|
|
16562
|
+
streamSimple: (model, context, value) => original.streamSimple(model, context, options(model, value)),
|
|
16563
|
+
});
|
|
16564
|
+
wrapped.add(model.provider);
|
|
16565
|
+
}
|
|
16566
|
+
target = { provider: model.provider, id: model.id };
|
|
16567
|
+
} else target = undefined;
|
|
16568
|
+
ctx.ui.notify("${PI_FAST_ACK}" + nonce + ":" + mode, "info");
|
|
16569
|
+
},
|
|
16570
|
+
});
|
|
16571
|
+
});
|
|
16572
|
+
}
|
|
16573
|
+
`;
|
|
16574
|
+
async function ensurePiFastExtension(environment) {
|
|
16575
|
+
const digest = createHash("sha256").update(PI_FAST_EXTENSION).digest("hex").slice(0, 16);
|
|
16576
|
+
const dataDirectory = environment.CODEXHOST_DATA_DIR ?? path6.join(environment.HOME ?? environment.USERPROFILE ?? homedir3(), ".codexhost");
|
|
16577
|
+
const directory = path6.resolve(dataDirectory, "extensions", "pi-codex-fast");
|
|
16578
|
+
const file2 = path6.join(directory, `${digest}.mjs`);
|
|
16579
|
+
if (await readFile2(file2, "utf8").catch(() => "") === PI_FAST_EXTENSION)
|
|
16580
|
+
return file2;
|
|
16581
|
+
await mkdir(directory, { recursive: true });
|
|
16582
|
+
const temporary = `${file2}.${randomUUID2()}.tmp`;
|
|
16583
|
+
try {
|
|
16584
|
+
await writeFile(temporary, PI_FAST_EXTENSION, { mode: 384 });
|
|
16585
|
+
try {
|
|
16586
|
+
await rename(temporary, file2);
|
|
16587
|
+
} catch (error51) {
|
|
16588
|
+
if (await readFile2(file2, "utf8").catch(() => "") !== PI_FAST_EXTENSION)
|
|
16589
|
+
throw error51;
|
|
16590
|
+
}
|
|
16591
|
+
} finally {
|
|
16592
|
+
await rm(temporary, { force: true });
|
|
16593
|
+
}
|
|
16594
|
+
return file2;
|
|
16595
|
+
}
|
|
16596
|
+
async function piFastModelKeys(models, environment) {
|
|
16597
|
+
try {
|
|
16598
|
+
const codexHome = environment.CODEX_HOME ?? path6.join(environment.HOME ?? environment.USERPROFILE ?? homedir3(), ".codex");
|
|
16599
|
+
const cache = JSON.parse(await readFile2(path6.join(codexHome, "models_cache.json"), "utf8"));
|
|
16600
|
+
if (!cache || typeof cache !== "object" || !("models" in cache) || !Array.isArray(cache.models))
|
|
16601
|
+
return /* @__PURE__ */ new Set();
|
|
16602
|
+
const priority = new Set(cache.models.filter((model) => typeof model?.slug === "string" && Array.isArray(model.service_tiers) && model.service_tiers.some((tier) => tier?.id === "priority")).map((model) => model.slug));
|
|
16603
|
+
const codexProviders = new Set(readPiCodexProviderNames(environment));
|
|
16604
|
+
return new Set(models.filter((model) => model.api === "openai-codex-responses" && codexProviders.has(model.provider) && priority.has(model.id)).map((model) => encodePiModelRef(model).id));
|
|
16605
|
+
} catch {
|
|
16606
|
+
return /* @__PURE__ */ new Set();
|
|
16607
|
+
}
|
|
16608
|
+
}
|
|
16609
|
+
function withPiFast(catalog, supported) {
|
|
16610
|
+
return {
|
|
16611
|
+
...catalog,
|
|
16612
|
+
models: catalog.models.map((model) => supported.has(model.ref.id) ? { ...model, fastModel: encodePiModelRef({ ...decodePiModelRef(model.ref), fast: true }) } : model)
|
|
16613
|
+
};
|
|
16614
|
+
}
|
|
16615
|
+
|
|
16012
16616
|
// dist/pi-empty-session.js
|
|
16013
16617
|
import { createReadStream } from "node:fs";
|
|
16014
16618
|
import { createInterface } from "node:readline";
|
|
16015
|
-
import { randomUUID as
|
|
16016
|
-
import { link, open as open2, rm } from "node:fs/promises";
|
|
16017
|
-
import
|
|
16619
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
16620
|
+
import { link, open as open2, rm as rm2 } from "node:fs/promises";
|
|
16621
|
+
import path7 from "node:path";
|
|
16018
16622
|
|
|
16019
16623
|
// dist/pi-subagents.js
|
|
16020
|
-
import { createHash } from "node:crypto";
|
|
16624
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
16021
16625
|
|
|
16022
16626
|
// dist/pi-subagent-workflow.js
|
|
16023
16627
|
var PREFIX2 = "pi-subagents-workflow-v1:";
|
|
@@ -16031,23 +16635,23 @@ var STATES = {
|
|
|
16031
16635
|
rejected: "failed",
|
|
16032
16636
|
detached: "running"
|
|
16033
16637
|
};
|
|
16034
|
-
function
|
|
16638
|
+
function record3(value) {
|
|
16035
16639
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16036
16640
|
}
|
|
16037
16641
|
function text(value, limit = 256) {
|
|
16038
16642
|
return typeof value === "string" && value.length > 0 && value.length <= limit;
|
|
16039
16643
|
}
|
|
16040
16644
|
function piWorkflowSummary(result) {
|
|
16041
|
-
if (!
|
|
16645
|
+
if (!record3(result) || !record3(result.details) || result.details.mode !== "workflow" || result.details.asyncId !== void 0)
|
|
16042
16646
|
return null;
|
|
16043
16647
|
const details = result.details;
|
|
16044
16648
|
const summary = details.workflowChildren;
|
|
16045
|
-
if (!
|
|
16649
|
+
if (!record3(summary) || summary.version !== 1 || !text(summary.workflowRunId) || summary.workflowRunId !== details.runId || !text(summary.parentToolCallId) || typeof summary.inventoryComplete !== "boolean" || !Array.isArray(summary.children) || summary.children.length > 256)
|
|
16046
16650
|
return null;
|
|
16047
16651
|
const children = [];
|
|
16048
16652
|
const seen = /* @__PURE__ */ new Set();
|
|
16049
16653
|
for (const child of summary.children) {
|
|
16050
|
-
if (!
|
|
16654
|
+
if (!record3(child) || !text(child.childId) || seen.has(child.childId) || typeof child.state !== "string" || !Object.hasOwn(STATES, child.state))
|
|
16051
16655
|
return null;
|
|
16052
16656
|
for (const key of ["agent", "sessionName", "model", "thinking"]) {
|
|
16053
16657
|
if (child[key] !== void 0 && !text(child[key], 2048))
|
|
@@ -16120,7 +16724,7 @@ var STATUS_PREFIX = "PI_SUBAGENT_ASYNC_JSON:";
|
|
|
16120
16724
|
var INSPECT_PREFIX = "PI_SUBAGENT_INSPECT_JSON:";
|
|
16121
16725
|
var ID_PREFIX = "pi-subagents-v1:";
|
|
16122
16726
|
var MAX_BYTES = 64 * 1024;
|
|
16123
|
-
function
|
|
16727
|
+
function record4(value) {
|
|
16124
16728
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16125
16729
|
}
|
|
16126
16730
|
function token(value) {
|
|
@@ -16137,7 +16741,7 @@ var statuses = {
|
|
|
16137
16741
|
rejected: "failed"
|
|
16138
16742
|
};
|
|
16139
16743
|
function node(value, depth, budget) {
|
|
16140
|
-
if (!
|
|
16744
|
+
if (!record4(value) || depth > 8 || ++budget.count > 256 || !token(value.id) || !["subagent", "workflow", "step", "host-step"].includes(String(value.kind)) || typeof value.label !== "string" || value.label.length > 2048 || typeof value.state !== "string" || !Object.hasOwn(statuses, value.state))
|
|
16141
16745
|
return null;
|
|
16142
16746
|
const children = [];
|
|
16143
16747
|
if (value.children !== void 0) {
|
|
@@ -16159,14 +16763,14 @@ function node(value, depth, budget) {
|
|
|
16159
16763
|
};
|
|
16160
16764
|
}
|
|
16161
16765
|
function widget(value, key, prefix) {
|
|
16162
|
-
if (!
|
|
16766
|
+
if (!record4(value) || value.type !== "extension_ui_request" || value.method !== "setWidget" || value.widgetKey !== key || !Array.isArray(value.widgetLines))
|
|
16163
16767
|
return null;
|
|
16164
16768
|
const line = value.widgetLines.find((part) => typeof part === "string" && part.startsWith(prefix));
|
|
16165
16769
|
if (!line || Buffer.byteLength(line) > MAX_BYTES + prefix.length)
|
|
16166
16770
|
return null;
|
|
16167
16771
|
try {
|
|
16168
16772
|
const parsed = JSON.parse(line.slice(prefix.length));
|
|
16169
|
-
return
|
|
16773
|
+
return record4(parsed) && parsed.version === 1 ? parsed : null;
|
|
16170
16774
|
} catch {
|
|
16171
16775
|
return null;
|
|
16172
16776
|
}
|
|
@@ -16230,7 +16834,7 @@ function states(run) {
|
|
|
16230
16834
|
return result;
|
|
16231
16835
|
}
|
|
16232
16836
|
function asyncRunId(toolName, result) {
|
|
16233
|
-
if (toolName !== "subagent" || !
|
|
16837
|
+
if (toolName !== "subagent" || !record4(result) || !record4(result.details))
|
|
16234
16838
|
return null;
|
|
16235
16839
|
const details = result.details;
|
|
16236
16840
|
return ["single", "parallel", "chain", "workflow"].includes(String(details.mode)) && token(details.asyncId) && typeof details.asyncDir === "string" ? details.asyncId : null;
|
|
@@ -16370,15 +16974,15 @@ function parsePiSubagentInspection(value) {
|
|
|
16370
16974
|
const parsed = widget(value, "subagent-inspect", INSPECT_PREFIX);
|
|
16371
16975
|
if (!parsed || parsed.kind !== "pi-subagents.inspect-reply" || !token(parsed.requestId))
|
|
16372
16976
|
return null;
|
|
16373
|
-
if (parsed.error !== void 0 && (!
|
|
16977
|
+
if (parsed.error !== void 0 && (!record4(parsed.error) || typeof parsed.error.code !== "string" || typeof parsed.error.message !== "string"))
|
|
16374
16978
|
return null;
|
|
16375
16979
|
for (const field of ["asyncId", "childId", "status", "task", "finalOutput"]) {
|
|
16376
16980
|
if (parsed[field] !== void 0 && typeof parsed[field] !== "string")
|
|
16377
16981
|
return null;
|
|
16378
16982
|
}
|
|
16379
|
-
if (parsed.messages !== void 0 && (!Array.isArray(parsed.messages) || parsed.messages.length > 200 || parsed.messages.some((entry) => !
|
|
16983
|
+
if (parsed.messages !== void 0 && (!Array.isArray(parsed.messages) || parsed.messages.length > 200 || parsed.messages.some((entry) => !record4(entry) || typeof entry.role !== "string" || typeof entry.text !== "string" || !["text", "toolCall", "toolResult"].includes(String(entry.kind)) || entry.name !== void 0 && typeof entry.name !== "string")))
|
|
16380
16984
|
return null;
|
|
16381
|
-
if (parsed.truncated !== void 0 && (!
|
|
16985
|
+
if (parsed.truncated !== void 0 && (!record4(parsed.truncated) || typeof parsed.truncated.task !== "boolean" || typeof parsed.truncated.finalOutput !== "boolean" || !Number.isSafeInteger(parsed.truncated.messages) || Number(parsed.truncated.messages) < 0))
|
|
16382
16986
|
return null;
|
|
16383
16987
|
return parsed;
|
|
16384
16988
|
}
|
|
@@ -16397,7 +17001,7 @@ ${entry.text}`);
|
|
|
16397
17001
|
nativeTurnRef: nativeTurnRefSchema.parse({
|
|
16398
17002
|
harnessId: "pi",
|
|
16399
17003
|
nativeSessionId: parentSessionId,
|
|
16400
|
-
nativeTurnKey: `pi-subagent-${
|
|
17004
|
+
nativeTurnKey: `pi-subagent-${createHash2("sha256").update(id).digest("hex")}`,
|
|
16401
17005
|
formatVersion: 1
|
|
16402
17006
|
}),
|
|
16403
17007
|
input: reply.task ? [{ type: "text", text: reply.task }] : [],
|
|
@@ -16405,7 +17009,7 @@ ${entry.text}`);
|
|
|
16405
17009
|
item: {
|
|
16406
17010
|
type: "agentMessage",
|
|
16407
17011
|
text: text2,
|
|
16408
|
-
itemId: hostItemIdSchema.parse(`pi-subagent-${
|
|
17012
|
+
itemId: hostItemIdSchema.parse(`pi-subagent-${createHash2("sha256").update(`${id}:${index}:${text2}`).digest("hex")}`)
|
|
16409
17013
|
},
|
|
16410
17014
|
outcome: { status: "succeeded" }
|
|
16411
17015
|
})),
|
|
@@ -16425,120 +17029,6 @@ ${entry.text}`);
|
|
|
16425
17029
|
};
|
|
16426
17030
|
}
|
|
16427
17031
|
|
|
16428
|
-
// dist/pi-model-catalog.js
|
|
16429
|
-
var PI_MODEL_REF_PREFIX = "pi-model-v1.";
|
|
16430
|
-
var PI_DRAFT_THINKING_OPTION_IDS = [
|
|
16431
|
-
"off",
|
|
16432
|
-
"minimal",
|
|
16433
|
-
"low",
|
|
16434
|
-
"medium",
|
|
16435
|
-
"high",
|
|
16436
|
-
"xhigh",
|
|
16437
|
-
"max"
|
|
16438
|
-
].map((id) => harnessThinkingOptionIdSchema.parse(id));
|
|
16439
|
-
var PI_THINKING_LABELS = {
|
|
16440
|
-
off: "Off",
|
|
16441
|
-
minimal: "Minimal",
|
|
16442
|
-
low: "Low",
|
|
16443
|
-
medium: "Medium",
|
|
16444
|
-
high: "High",
|
|
16445
|
-
xhigh: "Extra High",
|
|
16446
|
-
max: "Max"
|
|
16447
|
-
};
|
|
16448
|
-
function compareText(left, right) {
|
|
16449
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
16450
|
-
}
|
|
16451
|
-
function assertNativePart(value, name) {
|
|
16452
|
-
if (value.trim().length === 0)
|
|
16453
|
-
throw new Error(`Pi ${name} must not be empty`);
|
|
16454
|
-
}
|
|
16455
|
-
function encodePiModelRef(model) {
|
|
16456
|
-
assertNativePart(model.provider, "Model provider");
|
|
16457
|
-
assertNativePart(model.id, "Model id");
|
|
16458
|
-
const encoded = Buffer.from(JSON.stringify([model.provider, model.id]), "utf8").toString("base64url");
|
|
16459
|
-
return harnessModelRefSchema.parse({ id: `${PI_MODEL_REF_PREFIX}${encoded}` });
|
|
16460
|
-
}
|
|
16461
|
-
function decodePiModelRef(ref) {
|
|
16462
|
-
const parsedRef = harnessModelRefSchema.parse(ref);
|
|
16463
|
-
if (!parsedRef.id.startsWith(PI_MODEL_REF_PREFIX)) {
|
|
16464
|
-
throw new Error("Model Ref does not belong to PiAdapter");
|
|
16465
|
-
}
|
|
16466
|
-
const encoded = parsedRef.id.slice(PI_MODEL_REF_PREFIX.length);
|
|
16467
|
-
let decoded;
|
|
16468
|
-
try {
|
|
16469
|
-
decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
16470
|
-
} catch {
|
|
16471
|
-
throw new Error("Pi Model Ref is malformed");
|
|
16472
|
-
}
|
|
16473
|
-
if (!Array.isArray(decoded) || decoded.length !== 2 || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") {
|
|
16474
|
-
throw new Error("Pi Model Ref has an invalid native identity");
|
|
16475
|
-
}
|
|
16476
|
-
const native = { provider: decoded[0], id: decoded[1] };
|
|
16477
|
-
assertNativePart(native.provider, "Model provider");
|
|
16478
|
-
assertNativePart(native.id, "Model id");
|
|
16479
|
-
if (encodePiModelRef(native).id !== parsedRef.id) {
|
|
16480
|
-
throw new Error("Pi Model Ref is not canonical");
|
|
16481
|
-
}
|
|
16482
|
-
return native;
|
|
16483
|
-
}
|
|
16484
|
-
function samePiModel(left, right) {
|
|
16485
|
-
return left === null ? right === null : right !== null && left.provider === right.provider && left.id === right.id;
|
|
16486
|
-
}
|
|
16487
|
-
function fallbackThinkingLabel(id) {
|
|
16488
|
-
const label = id.split(/[._~-]+/u).filter((part) => part.length > 0).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
16489
|
-
return label || id;
|
|
16490
|
-
}
|
|
16491
|
-
function normalizePiThinkingOptions(levels) {
|
|
16492
|
-
return levels.map((id) => harnessThinkingOptionSchema.parse({
|
|
16493
|
-
id,
|
|
16494
|
-
label: PI_THINKING_LABELS[id] ?? fallbackThinkingLabel(id)
|
|
16495
|
-
}));
|
|
16496
|
-
}
|
|
16497
|
-
function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, effectiveThinkingOptionId) {
|
|
16498
|
-
const byRef = /* @__PURE__ */ new Map();
|
|
16499
|
-
for (const native of nativeModels) {
|
|
16500
|
-
const ref = encodePiModelRef(native);
|
|
16501
|
-
const existing = byRef.get(ref.id);
|
|
16502
|
-
if (existing) {
|
|
16503
|
-
if (existing.reasoning !== native.reasoning) {
|
|
16504
|
-
throw new Error("Pi duplicate Model entries disagree on reasoning capability");
|
|
16505
|
-
}
|
|
16506
|
-
continue;
|
|
16507
|
-
}
|
|
16508
|
-
byRef.set(ref.id, {
|
|
16509
|
-
model: {
|
|
16510
|
-
ref,
|
|
16511
|
-
label: `${native.provider} / ${native.id}`
|
|
16512
|
-
},
|
|
16513
|
-
reasoning: native.reasoning
|
|
16514
|
-
});
|
|
16515
|
-
}
|
|
16516
|
-
const defaultModel = effectiveModel ? encodePiModelRef(effectiveModel) : void 0;
|
|
16517
|
-
if (defaultModel && !byRef.has(defaultModel.id)) {
|
|
16518
|
-
throw new Error("Pi effective Model is absent from the available Model catalog");
|
|
16519
|
-
}
|
|
16520
|
-
if (thinkingLevels && effectiveThinkingOptionId && !thinkingLevels.includes(effectiveThinkingOptionId)) {
|
|
16521
|
-
throw new Error("Pi effective Thinking option is absent from the available option catalog");
|
|
16522
|
-
}
|
|
16523
|
-
if (thinkingLevels && !effectiveThinkingOptionId) {
|
|
16524
|
-
throw new Error("Pi did not report an effective Thinking option");
|
|
16525
|
-
}
|
|
16526
|
-
const thinkingOptions = thinkingLevels ? normalizePiThinkingOptions(PI_DRAFT_THINKING_OPTION_IDS) : [];
|
|
16527
|
-
const allThinkingOptionIds = thinkingOptions.map(({ id }) => id);
|
|
16528
|
-
const offThinkingOptionId = thinkingOptions.find(({ id }) => id === "off")?.id;
|
|
16529
|
-
const models = [...byRef.values()].map(({ model, reasoning }) => ({
|
|
16530
|
-
...model,
|
|
16531
|
-
supportedThinkingOptionIds: reasoning ? allThinkingOptionIds : offThinkingOptionId ? [offThinkingOptionId] : []
|
|
16532
|
-
})).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
|
|
16533
|
-
const defaultThinkingOptionId = thinkingOptions.find(({ id }) => id === effectiveThinkingOptionId)?.id;
|
|
16534
|
-
return harnessModelCatalogSchema.parse({
|
|
16535
|
-
models,
|
|
16536
|
-
...defaultModel ? { defaultModel } : {},
|
|
16537
|
-
thinkingOptions,
|
|
16538
|
-
...defaultThinkingOptionId ? { defaultThinkingOptionId } : {}
|
|
16539
|
-
});
|
|
16540
|
-
}
|
|
16541
|
-
|
|
16542
17032
|
// dist/pi-history.js
|
|
16543
17033
|
var piHarnessId = harnessIdSchema.parse("pi");
|
|
16544
17034
|
function isRecord(value) {
|
|
@@ -16844,7 +17334,7 @@ async function verifyPiSessionCwd(input) {
|
|
|
16844
17334
|
async function persistEmptyPiSession(input) {
|
|
16845
17335
|
const { state: state2, history, sourceSessionFile, sourceSessionId, cwd } = input;
|
|
16846
17336
|
const destination = state2.sessionFile;
|
|
16847
|
-
if (!destination || !
|
|
17337
|
+
if (!destination || !path7.isAbsolute(destination) || path7.resolve(destination) === path7.resolve(sourceSessionFile) || state2.sessionId === sourceSessionId || mapPiSnapshot(history, { sessionId: state2.sessionId, model: null }).turns.length !== 0)
|
|
16848
17338
|
throw new Error("Pi empty Session is not an independent empty native fork");
|
|
16849
17339
|
await verifyPiSessionCwd({
|
|
16850
17340
|
sessionFile: sourceSessionFile,
|
|
@@ -16868,7 +17358,7 @@ async function persistEmptyPiSession(input) {
|
|
|
16868
17358
|
cwd,
|
|
16869
17359
|
parentSession: sourceSessionFile
|
|
16870
17360
|
};
|
|
16871
|
-
const temporary =
|
|
17361
|
+
const temporary = path7.join(path7.dirname(destination), `.codexhost-${randomUUID3()}.tmp`);
|
|
16872
17362
|
try {
|
|
16873
17363
|
const file2 = await open2(temporary, "wx", 384);
|
|
16874
17364
|
try {
|
|
@@ -16879,7 +17369,7 @@ async function persistEmptyPiSession(input) {
|
|
|
16879
17369
|
}
|
|
16880
17370
|
await link(temporary, destination);
|
|
16881
17371
|
if (process.platform !== "win32") {
|
|
16882
|
-
const directory = await open2(
|
|
17372
|
+
const directory = await open2(path7.dirname(destination), "r");
|
|
16883
17373
|
try {
|
|
16884
17374
|
await directory.sync();
|
|
16885
17375
|
} finally {
|
|
@@ -16887,7 +17377,7 @@ async function persistEmptyPiSession(input) {
|
|
|
16887
17377
|
}
|
|
16888
17378
|
}
|
|
16889
17379
|
} finally {
|
|
16890
|
-
await
|
|
17380
|
+
await rm2(temporary, { force: true });
|
|
16891
17381
|
}
|
|
16892
17382
|
}
|
|
16893
17383
|
async function readPiEmptySessionConfiguration(sessionFile) {
|
|
@@ -17042,16 +17532,16 @@ var Diff = class {
|
|
|
17042
17532
|
}
|
|
17043
17533
|
}
|
|
17044
17534
|
}
|
|
17045
|
-
addToPath(
|
|
17046
|
-
const last =
|
|
17535
|
+
addToPath(path13, added, removed, oldPosInc, options) {
|
|
17536
|
+
const last = path13.lastComponent;
|
|
17047
17537
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
17048
17538
|
return {
|
|
17049
|
-
oldPos:
|
|
17539
|
+
oldPos: path13.oldPos + oldPosInc,
|
|
17050
17540
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
17051
17541
|
};
|
|
17052
17542
|
} else {
|
|
17053
17543
|
return {
|
|
17054
|
-
oldPos:
|
|
17544
|
+
oldPos: path13.oldPos + oldPosInc,
|
|
17055
17545
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
17056
17546
|
};
|
|
17057
17547
|
}
|
|
@@ -17463,8 +17953,8 @@ function splitLines(text2) {
|
|
|
17463
17953
|
}
|
|
17464
17954
|
|
|
17465
17955
|
// dist/pi-adapter.js
|
|
17466
|
-
import { randomUUID as
|
|
17467
|
-
import
|
|
17956
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17957
|
+
import path12 from "node:path";
|
|
17468
17958
|
|
|
17469
17959
|
// ../../harness-adapter/dist/question.js
|
|
17470
17960
|
function invalidRequest(message3) {
|
|
@@ -17769,16 +18259,16 @@ function mergeLiveHarnessCommands(builtIns, idPrefix, live, exclusions = {}) {
|
|
|
17769
18259
|
}
|
|
17770
18260
|
|
|
17771
18261
|
// dist/pi-workflow-child-history.js
|
|
17772
|
-
import { createHash as
|
|
18262
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
17773
18263
|
import { constants } from "node:fs";
|
|
17774
18264
|
import { open as open3 } from "node:fs/promises";
|
|
17775
|
-
import
|
|
17776
|
-
function
|
|
18265
|
+
import path8 from "node:path";
|
|
18266
|
+
function record5(value) {
|
|
17777
18267
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17778
18268
|
}
|
|
17779
18269
|
var MAX_SESSION_BYTES = 8 * 1024 * 1024;
|
|
17780
18270
|
async function childHistory(file2, parentSessionId, identity) {
|
|
17781
|
-
if (!
|
|
18271
|
+
if (!path8.isAbsolute(file2))
|
|
17782
18272
|
throw new Error("Pi child Session path is not absolute");
|
|
17783
18273
|
const handle = await open3(file2, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
17784
18274
|
try {
|
|
@@ -17791,18 +18281,18 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
17791
18281
|
throw new Error("Pi child Session exceeds read bounds");
|
|
17792
18282
|
const values = buffer.subarray(0, bytesRead).toString("utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
17793
18283
|
const header = values[0];
|
|
17794
|
-
if (!
|
|
18284
|
+
if (!record5(header) || header.type !== "session" || typeof header.id !== "string" || header.version !== 3)
|
|
17795
18285
|
throw new Error("Unsupported Pi child Session header");
|
|
17796
18286
|
const entries = [];
|
|
17797
18287
|
for (const entry of values.slice(1)) {
|
|
17798
18288
|
const parsed = jsonValueSchema.safeParse(entry);
|
|
17799
|
-
if (!parsed.success || !
|
|
18289
|
+
if (!parsed.success || !record5(parsed.data) || typeof parsed.data.id !== "string")
|
|
17800
18290
|
throw new Error("Malformed Pi child Session entry");
|
|
17801
18291
|
entries.push(parsed.data);
|
|
17802
18292
|
}
|
|
17803
18293
|
const history = { entries, leafId: String(entries.at(-1)?.id ?? "") || null };
|
|
17804
18294
|
const snapshot = mapPiSnapshot(history, { sessionId: parentSessionId, model: null });
|
|
17805
|
-
const prefix =
|
|
18295
|
+
const prefix = createHash3("sha256").update(identity).digest("hex");
|
|
17806
18296
|
return {
|
|
17807
18297
|
turns: snapshot.turns.map((turn) => {
|
|
17808
18298
|
const readonlyTurn = {
|
|
@@ -17823,7 +18313,7 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
17823
18313
|
async function readPiWorkflowChild(history, parentSessionId, address) {
|
|
17824
18314
|
for (const entry of activePiEntries(history).reverse()) {
|
|
17825
18315
|
const message3 = entry.message;
|
|
17826
|
-
if (!
|
|
18316
|
+
if (!record5(message3) || message3.role !== "toolResult" || message3.toolName !== "subagent")
|
|
17827
18317
|
continue;
|
|
17828
18318
|
const summary = piWorkflowSummary(message3);
|
|
17829
18319
|
if (!summary || summary.workflowRunId !== address.workflowRunId || summary.parentToolCallId !== message3.toolCallId)
|
|
@@ -17832,10 +18322,10 @@ async function readPiWorkflowChild(history, parentSessionId, address) {
|
|
|
17832
18322
|
if (!child)
|
|
17833
18323
|
break;
|
|
17834
18324
|
const details = message3.details;
|
|
17835
|
-
if (!
|
|
18325
|
+
if (!record5(details) || !Array.isArray(details.results))
|
|
17836
18326
|
break;
|
|
17837
|
-
const result = details.results.findLast((candidate) =>
|
|
17838
|
-
if (!
|
|
18327
|
+
const result = details.results.findLast((candidate) => record5(candidate) && candidate.workflowKey === address.childId);
|
|
18328
|
+
if (!record5(result))
|
|
17839
18329
|
break;
|
|
17840
18330
|
const id = piWorkflowSubagentId(address);
|
|
17841
18331
|
if (typeof result.sessionFile === "string") {
|
|
@@ -17881,22 +18371,22 @@ ${output}`,
|
|
|
17881
18371
|
// dist/pi-subagent-history.js
|
|
17882
18372
|
import { constants as constants2 } from "node:fs";
|
|
17883
18373
|
import { open as open4 } from "node:fs/promises";
|
|
17884
|
-
import
|
|
17885
|
-
function
|
|
18374
|
+
import path9 from "node:path";
|
|
18375
|
+
function record6(value) {
|
|
17886
18376
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17887
18377
|
}
|
|
17888
18378
|
function state(value) {
|
|
17889
18379
|
return value === "pending" ? "queued" : value === "completed" ? "complete" : value;
|
|
17890
18380
|
}
|
|
17891
18381
|
function piSubagentArtifact(value, runId, parentSessionId) {
|
|
17892
|
-
if (!
|
|
18382
|
+
if (!record6(value) || value.lifecycleArtifactVersion !== 3 || value.runId !== runId || value.sessionId !== parentSessionId || !["single", "parallel", "chain", "workflow"].includes(String(value.mode)))
|
|
17893
18383
|
return null;
|
|
17894
18384
|
if (value.steps !== void 0 && (!Array.isArray(value.steps) || value.steps.length > 128))
|
|
17895
18385
|
return null;
|
|
17896
18386
|
const steps = Array.isArray(value.steps) ? value.steps : [];
|
|
17897
18387
|
const children = [];
|
|
17898
18388
|
for (const [index, step] of steps.entries()) {
|
|
17899
|
-
if (!
|
|
18389
|
+
if (!record6(step) || typeof step.agent !== "string")
|
|
17900
18390
|
return null;
|
|
17901
18391
|
children.push({
|
|
17902
18392
|
id: step.workflowKey ?? step.runId ?? `step:${index}`,
|
|
@@ -17929,17 +18419,17 @@ function piSubagentArtifact(value, runId, parentSessionId) {
|
|
|
17929
18419
|
async function restorePiSubagents(history, parentSessionId, observer) {
|
|
17930
18420
|
const receipts = /* @__PURE__ */ new Map();
|
|
17931
18421
|
for (const entry of activePiEntries(history)) {
|
|
17932
|
-
if (!
|
|
18422
|
+
if (!record6(entry.message) || entry.message.role !== "toolResult" || entry.message.toolName !== "subagent" || entry.message.isError !== false || !record6(entry.message.details))
|
|
17933
18423
|
continue;
|
|
17934
18424
|
const details = entry.message.details;
|
|
17935
|
-
if (!["single", "parallel", "chain", "workflow"].includes(String(details.mode)) || typeof details.asyncId !== "string" || typeof details.asyncDir !== "string" || !
|
|
18425
|
+
if (!["single", "parallel", "chain", "workflow"].includes(String(details.mode)) || typeof details.asyncId !== "string" || typeof details.asyncDir !== "string" || !path9.isAbsolute(details.asyncDir) || path9.basename(details.asyncDir) !== details.asyncId)
|
|
17936
18426
|
continue;
|
|
17937
18427
|
receipts.set(details.asyncId, details.asyncDir);
|
|
17938
18428
|
}
|
|
17939
18429
|
for (const [id, directory] of [...receipts].slice(-128)) {
|
|
17940
18430
|
let file2;
|
|
17941
18431
|
try {
|
|
17942
|
-
file2 = await open4(
|
|
18432
|
+
file2 = await open4(path9.join(directory, "status.json"), constants2.O_RDONLY | (constants2.O_NOFOLLOW ?? 0));
|
|
17943
18433
|
const stat2 = await file2.stat();
|
|
17944
18434
|
if (!stat2.isFile() || stat2.size > 1024 * 1024)
|
|
17945
18435
|
continue;
|
|
@@ -18021,7 +18511,7 @@ async function rollbackPiLastTurn(transport, sourceSessionId, cwd) {
|
|
|
18021
18511
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
18022
18512
|
import { opendir, realpath as realpath3, stat } from "node:fs/promises";
|
|
18023
18513
|
import os3 from "node:os";
|
|
18024
|
-
import
|
|
18514
|
+
import path10 from "node:path";
|
|
18025
18515
|
import { createInterface as createInterface2 } from "node:readline";
|
|
18026
18516
|
var PiSessionChangedError = class extends Error {
|
|
18027
18517
|
constructor() {
|
|
@@ -18038,7 +18528,7 @@ function missing(error51) {
|
|
|
18038
18528
|
return isRecord4(error51) && error51.code === "ENOENT";
|
|
18039
18529
|
}
|
|
18040
18530
|
function expandDirectory(value, home) {
|
|
18041
|
-
return
|
|
18531
|
+
return path10.resolve(value === "~" ? home : value.startsWith(`~${path10.sep}`) || value.startsWith("~/") ? path10.join(home, value.slice(2)) : value);
|
|
18042
18532
|
}
|
|
18043
18533
|
function piSessionImportDirectory(environment) {
|
|
18044
18534
|
const home = (process.platform === "win32" ? environment.USERPROFILE : environment.HOME) || os3.homedir();
|
|
@@ -18047,7 +18537,7 @@ function piSessionImportDirectory(environment) {
|
|
|
18047
18537
|
return { directory: expandDirectory(custom2, home), flat: true };
|
|
18048
18538
|
const agent = environment.PI_CODING_AGENT_DIR;
|
|
18049
18539
|
return {
|
|
18050
|
-
directory:
|
|
18540
|
+
directory: path10.join(agent ? expandDirectory(agent, home) : path10.join(home, ".pi", "agent"), "sessions"),
|
|
18051
18541
|
flat: false
|
|
18052
18542
|
};
|
|
18053
18543
|
}
|
|
@@ -18065,9 +18555,9 @@ async function sessionFiles(directory, flat, signal) {
|
|
|
18065
18555
|
for await (const entry of entries) {
|
|
18066
18556
|
signal.throwIfAborted();
|
|
18067
18557
|
if (projectLevel && entry.isDirectory())
|
|
18068
|
-
await visit(
|
|
18558
|
+
await visit(path10.join(dir, entry.name), false);
|
|
18069
18559
|
else if (!projectLevel && entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
18070
|
-
files.push(
|
|
18560
|
+
files.push(path10.join(dir, entry.name));
|
|
18071
18561
|
}
|
|
18072
18562
|
}
|
|
18073
18563
|
};
|
|
@@ -18100,7 +18590,7 @@ async function readCandidate(file2, signal) {
|
|
|
18100
18590
|
if (!isRecord4(entry))
|
|
18101
18591
|
return null;
|
|
18102
18592
|
if (!header) {
|
|
18103
|
-
if (entry.type !== "session" || entry.version !== 3 || typeof entry.id !== "string" || typeof entry.cwd !== "string" || !
|
|
18593
|
+
if (entry.type !== "session" || entry.version !== 3 || typeof entry.id !== "string" || typeof entry.cwd !== "string" || !path10.isAbsolute(entry.cwd))
|
|
18104
18594
|
return null;
|
|
18105
18595
|
header = entry;
|
|
18106
18596
|
continue;
|
|
@@ -18250,8 +18740,8 @@ var PiSessionImportIndex = class {
|
|
|
18250
18740
|
|
|
18251
18741
|
// dist/pi-rpc-session.js
|
|
18252
18742
|
import { spawn, spawnSync } from "node:child_process";
|
|
18253
|
-
import { randomUUID as
|
|
18254
|
-
import
|
|
18743
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
18744
|
+
import path11 from "node:path";
|
|
18255
18745
|
|
|
18256
18746
|
// dist/pi-slash-commands.js
|
|
18257
18747
|
var DYNAMIC_ID_PREFIX = "pi.slash.";
|
|
@@ -18273,15 +18763,15 @@ function parsePiNativeCommands(response) {
|
|
|
18273
18763
|
return data.commands.flatMap((entry) => {
|
|
18274
18764
|
if (typeof entry !== "object" || entry === null)
|
|
18275
18765
|
return [];
|
|
18276
|
-
const
|
|
18277
|
-
const name = typeof
|
|
18766
|
+
const record7 = entry;
|
|
18767
|
+
const name = typeof record7.name === "string" ? record7.name.trim().replace(/^\//u, "") : "";
|
|
18278
18768
|
if (!name)
|
|
18279
18769
|
return [];
|
|
18280
18770
|
return [
|
|
18281
18771
|
{
|
|
18282
18772
|
name,
|
|
18283
|
-
...typeof
|
|
18284
|
-
...typeof
|
|
18773
|
+
...typeof record7.description === "string" ? { description: record7.description } : {},
|
|
18774
|
+
...typeof record7.source === "string" ? { source: record7.source } : {}
|
|
18285
18775
|
}
|
|
18286
18776
|
];
|
|
18287
18777
|
});
|
|
@@ -18369,7 +18859,7 @@ function optionalPiStateContextUsage(value) {
|
|
|
18369
18859
|
}
|
|
18370
18860
|
|
|
18371
18861
|
// dist/pi-subagent-rpc.js
|
|
18372
|
-
import { randomUUID as
|
|
18862
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
18373
18863
|
var PiSubagentRpc = class {
|
|
18374
18864
|
send;
|
|
18375
18865
|
timeoutMs;
|
|
@@ -18411,7 +18901,7 @@ var PiSubagentRpc = class {
|
|
|
18411
18901
|
if (!Array.isArray(data?.commands) || !data.commands.some((command) => command?.name === "subagents-inspect-rpc" && command.source === "extension")) {
|
|
18412
18902
|
throw new Error("Installed Pi has no pi-subagents Host inspection command");
|
|
18413
18903
|
}
|
|
18414
|
-
const requestId =
|
|
18904
|
+
const requestId = randomUUID4();
|
|
18415
18905
|
const reply = new Promise((resolve, reject) => {
|
|
18416
18906
|
const timer = setTimeout(() => {
|
|
18417
18907
|
this.#pending.delete(requestId);
|
|
@@ -18557,7 +19047,11 @@ function parseAvailableModels(response) {
|
|
|
18557
19047
|
if (!parsed || !isRecord6(model) || typeof model.reasoning !== "boolean") {
|
|
18558
19048
|
throw new PiRpcFaultError("protocolError", "Pi RPC catalog contains a Model without reasoning capability");
|
|
18559
19049
|
}
|
|
18560
|
-
return {
|
|
19050
|
+
return {
|
|
19051
|
+
...parsed,
|
|
19052
|
+
reasoning: model.reasoning,
|
|
19053
|
+
...typeof model.api === "string" ? { api: model.api } : {}
|
|
19054
|
+
};
|
|
18561
19055
|
});
|
|
18562
19056
|
}
|
|
18563
19057
|
function assistantText(value) {
|
|
@@ -18642,13 +19136,14 @@ function piRpcProcessCommand(options, dependencies = {}) {
|
|
|
18642
19136
|
const modelArguments = startupModel ? ["--provider", startupModel.provider, "--model", startupModel.id] : [];
|
|
18643
19137
|
const thinkingArguments = options.emptySessionConfiguration ? ["--thinking", options.emptySessionConfiguration.thinkingLevel] : [];
|
|
18644
19138
|
const arguments_ = [
|
|
19139
|
+
...options.fastExtension ? ["--extension", options.fastExtension] : [],
|
|
18645
19140
|
"--mode",
|
|
18646
19141
|
"rpc",
|
|
18647
19142
|
...modelArguments,
|
|
18648
19143
|
...thinkingArguments,
|
|
18649
19144
|
...sessionArguments
|
|
18650
19145
|
];
|
|
18651
|
-
const extension =
|
|
19146
|
+
const extension = path11.win32.extname(command).toLowerCase();
|
|
18652
19147
|
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
18653
19148
|
return { command, arguments: arguments_, windowsVerbatimArguments: false };
|
|
18654
19149
|
}
|
|
@@ -18687,6 +19182,8 @@ var PiRpcSession = class {
|
|
|
18687
19182
|
#failed = false;
|
|
18688
19183
|
#pending = /* @__PURE__ */ new Map();
|
|
18689
19184
|
#state = null;
|
|
19185
|
+
#fast = null;
|
|
19186
|
+
#fastAcknowledgement = null;
|
|
18690
19187
|
#latestCacheHitRatePercent;
|
|
18691
19188
|
#manualCompaction = null;
|
|
18692
19189
|
#stderrTail = "";
|
|
@@ -18713,7 +19210,9 @@ var PiRpcSession = class {
|
|
|
18713
19210
|
get state() {
|
|
18714
19211
|
if (!this.#state)
|
|
18715
19212
|
throw new Error("Pi RPC Session has not started");
|
|
18716
|
-
|
|
19213
|
+
if (this.#fast && (this.#fast.provider !== this.#state.provider || this.#fast.id !== this.#state.modelId))
|
|
19214
|
+
this.#fast = null;
|
|
19215
|
+
return this.#fast ? { ...this.#state, fast: true } : this.#state;
|
|
18717
19216
|
}
|
|
18718
19217
|
get stderrTail() {
|
|
18719
19218
|
return this.#stderrTail;
|
|
@@ -18730,8 +19229,10 @@ var PiRpcSession = class {
|
|
|
18730
19229
|
async start() {
|
|
18731
19230
|
if (this.#child || this.#closed)
|
|
18732
19231
|
throw new Error("Pi RPC Session cannot be started twice");
|
|
19232
|
+
const fastExtension = this.#processAdapter === nodeProcessAdapter ? await ensurePiFastExtension({ ...process.env, ...this.#options.environment }) : void 0;
|
|
18733
19233
|
const child = this.#processAdapter.spawn({
|
|
18734
19234
|
cwd: this.#options.cwd,
|
|
19235
|
+
...fastExtension ? { fastExtension } : {},
|
|
18735
19236
|
...this.#options.command ? { command: this.#options.command } : {},
|
|
18736
19237
|
environment: withNodeRuntimeOnPath({
|
|
18737
19238
|
...process.env,
|
|
@@ -18878,7 +19379,36 @@ var PiRpcSession = class {
|
|
|
18878
19379
|
throw error51;
|
|
18879
19380
|
}
|
|
18880
19381
|
}
|
|
19382
|
+
async supportsFastMode() {
|
|
19383
|
+
return (await this.getCommands()).some((command) => command.name === PI_FAST_COMMAND && command.source === "extension");
|
|
19384
|
+
}
|
|
19385
|
+
async selectFastMode(enabled) {
|
|
19386
|
+
if (!enabled && !this.#fast)
|
|
19387
|
+
return this.state;
|
|
19388
|
+
if (!await this.supportsFastMode())
|
|
19389
|
+
throw new Error("Installed Pi does not support the Host Fast extension");
|
|
19390
|
+
const nonce = randomUUID5();
|
|
19391
|
+
const mode = enabled ? "on" : "off";
|
|
19392
|
+
const acknowledgement = { message: `${PI_FAST_ACK}${nonce}:${mode}`, received: false };
|
|
19393
|
+
this.#fastAcknowledgement = acknowledgement;
|
|
19394
|
+
try {
|
|
19395
|
+
await this.#send("prompt", { message: `/${PI_FAST_COMMAND} ${mode} ${nonce}` });
|
|
19396
|
+
if (!acknowledgement.received)
|
|
19397
|
+
throw new Error("Pi did not confirm the Fast selection");
|
|
19398
|
+
this.#fast = enabled ? { provider: this.state.provider ?? "", id: this.state.modelId ?? "" } : null;
|
|
19399
|
+
return this.state;
|
|
19400
|
+
} catch (error51) {
|
|
19401
|
+
const fault = error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("protocolError", `Pi Fast selection could not be confirmed: ${message2(error51)}`);
|
|
19402
|
+
this.#fail(fault);
|
|
19403
|
+
await this.close().catch(() => void 0);
|
|
19404
|
+
throw fault;
|
|
19405
|
+
} finally {
|
|
19406
|
+
this.#fastAcknowledgement = null;
|
|
19407
|
+
}
|
|
19408
|
+
}
|
|
18881
19409
|
async selectModel(model) {
|
|
19410
|
+
if (this.#fast)
|
|
19411
|
+
await this.selectFastMode(false);
|
|
18882
19412
|
await this.#send("set_model", { provider: model.provider, modelId: model.id });
|
|
18883
19413
|
return this.#refreshState("Model");
|
|
18884
19414
|
}
|
|
@@ -18890,7 +19420,7 @@ var PiRpcSession = class {
|
|
|
18890
19420
|
async #refreshState(operation) {
|
|
18891
19421
|
try {
|
|
18892
19422
|
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18893
|
-
return this
|
|
19423
|
+
return this.state;
|
|
18894
19424
|
} catch (error51) {
|
|
18895
19425
|
const fault = error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("protocolError", `Pi RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
18896
19426
|
this.#fail(fault);
|
|
@@ -19046,6 +19576,11 @@ var PiRpcSession = class {
|
|
|
19046
19576
|
}
|
|
19047
19577
|
}
|
|
19048
19578
|
#handle(value) {
|
|
19579
|
+
if (value.type === "extension_ui_request" && value.method === "notify" && typeof value.message === "string" && value.message.startsWith(PI_FAST_ACK)) {
|
|
19580
|
+
if (this.#fastAcknowledgement?.message === value.message)
|
|
19581
|
+
this.#fastAcknowledgement.received = true;
|
|
19582
|
+
return;
|
|
19583
|
+
}
|
|
19049
19584
|
if (this.#closed || this.#failed)
|
|
19050
19585
|
return;
|
|
19051
19586
|
if (value.type === "response") {
|
|
@@ -19168,7 +19703,7 @@ var PiRpcSession = class {
|
|
|
19168
19703
|
const active = {
|
|
19169
19704
|
origin: "autonomous",
|
|
19170
19705
|
autonomousEvents: events,
|
|
19171
|
-
nativeTurnKey: assistantMessageId(value) ??
|
|
19706
|
+
nativeTurnKey: assistantMessageId(value) ?? randomUUID5(),
|
|
19172
19707
|
nativeCancellationObserved: false,
|
|
19173
19708
|
text: "",
|
|
19174
19709
|
assistantMessageId: null,
|
|
@@ -19411,7 +19946,7 @@ var PiRpcSession = class {
|
|
|
19411
19946
|
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19412
19947
|
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19413
19948
|
}
|
|
19414
|
-
const messageId = assistantMessageId(value) ??
|
|
19949
|
+
const messageId = assistantMessageId(value) ?? randomUUID5();
|
|
19415
19950
|
active.assistantMessageId = messageId;
|
|
19416
19951
|
active.sawStreamedMessageText = false;
|
|
19417
19952
|
active.sawStreamedMessageReasoning = false;
|
|
@@ -19472,7 +20007,7 @@ var PiRpcSession = class {
|
|
|
19472
20007
|
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19473
20008
|
return Promise.reject(new Error("Pi RPC stdin is unavailable"));
|
|
19474
20009
|
}
|
|
19475
|
-
const id = `codexhost-${
|
|
20010
|
+
const id = `codexhost-${randomUUID5()}`;
|
|
19476
20011
|
return new Promise((resolve, reject) => {
|
|
19477
20012
|
const pending = {
|
|
19478
20013
|
command: type,
|
|
@@ -19647,7 +20182,7 @@ function nativeModelFromState(state2) {
|
|
|
19647
20182
|
}
|
|
19648
20183
|
function effectiveModelFromState(state2) {
|
|
19649
20184
|
const model = nativeModelFromState(state2);
|
|
19650
|
-
return model ? encodePiModelRef(model) : void 0;
|
|
20185
|
+
return model ? encodePiModelRef({ ...model, ...state2.fast ? { fast: true } : {} }) : void 0;
|
|
19651
20186
|
}
|
|
19652
20187
|
function harnessStateFromPi(state2, thinkingLevels) {
|
|
19653
20188
|
const effectiveModel = effectiveModelFromState(state2);
|
|
@@ -19733,10 +20268,10 @@ function stripDiffPrefix(pathString) {
|
|
|
19733
20268
|
return pathString.startsWith("a/") || pathString.startsWith("b/") ? pathString.slice(2) : pathString;
|
|
19734
20269
|
}
|
|
19735
20270
|
function displayPath(nativePath, cwd) {
|
|
19736
|
-
const resolvedCwd =
|
|
19737
|
-
const resolvedPath =
|
|
19738
|
-
const relative =
|
|
19739
|
-
const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${
|
|
20271
|
+
const resolvedCwd = path12.resolve(cwd);
|
|
20272
|
+
const resolvedPath = path12.isAbsolute(nativePath) ? path12.resolve(nativePath) : path12.resolve(cwd, nativePath);
|
|
20273
|
+
const relative = path12.relative(resolvedCwd, resolvedPath);
|
|
20274
|
+
const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path12.sep}`);
|
|
19740
20275
|
const selected = inside ? relative : resolvedPath;
|
|
19741
20276
|
const normalized = selected.replaceAll("\\", "/");
|
|
19742
20277
|
if (normalized.length === 0 || normalized === ".")
|
|
@@ -19935,6 +20470,7 @@ var PiHarnessSession = class {
|
|
|
19935
20470
|
#requestedModel;
|
|
19936
20471
|
#requestedThinkingOptionId;
|
|
19937
20472
|
#toolOutputLimit;
|
|
20473
|
+
#isFastSupported;
|
|
19938
20474
|
#acceptingTurn = false;
|
|
19939
20475
|
#active = null;
|
|
19940
20476
|
#closePromise = null;
|
|
@@ -19956,6 +20492,7 @@ var PiHarnessSession = class {
|
|
|
19956
20492
|
this.#requestedModel = options.model;
|
|
19957
20493
|
this.#requestedThinkingOptionId = options.thinkingOptionId;
|
|
19958
20494
|
this.#toolOutputLimit = options.toolOutputLimit;
|
|
20495
|
+
this.#isFastSupported = options.isFastSupported;
|
|
19959
20496
|
this.capabilities = {
|
|
19960
20497
|
configuration: {
|
|
19961
20498
|
selectModel: true,
|
|
@@ -19984,13 +20521,13 @@ var PiHarnessSession = class {
|
|
|
19984
20521
|
return this.#transport?.state.sessionId === id;
|
|
19985
20522
|
}
|
|
19986
20523
|
async readSubagentHistory(cwd) {
|
|
19987
|
-
if (this.#phase !== "open" ||
|
|
20524
|
+
if (this.#phase !== "open" || path12.resolve(cwd) !== path12.resolve(this.#cwd)) {
|
|
19988
20525
|
throw new Error("Pi Subagent parent workspace or Session is unavailable");
|
|
19989
20526
|
}
|
|
19990
20527
|
return (await this.#ensureTransport()).getEntries();
|
|
19991
20528
|
}
|
|
19992
20529
|
async inspectSubagent(id, cwd) {
|
|
19993
|
-
if (this.#phase !== "open" ||
|
|
20530
|
+
if (this.#phase !== "open" || path12.resolve(cwd) !== path12.resolve(this.#cwd)) {
|
|
19994
20531
|
throw new Error("Pi Subagent parent workspace or Session is unavailable");
|
|
19995
20532
|
}
|
|
19996
20533
|
const transport = await this.#ensureTransport();
|
|
@@ -20233,20 +20770,27 @@ var PiHarnessSession = class {
|
|
|
20233
20770
|
error: invalidState("Pi Model selection requires a started Native Session")
|
|
20234
20771
|
};
|
|
20235
20772
|
}
|
|
20236
|
-
let requested;
|
|
20237
|
-
try {
|
|
20238
|
-
requested = decodePiModelRef(command.model);
|
|
20239
|
-
} catch (error51) {
|
|
20240
|
-
return { ok: false, error: normalizedError(error51, "invalidRequest") };
|
|
20241
|
-
}
|
|
20242
20773
|
const previousModel = this.#state.effectiveModel;
|
|
20243
20774
|
this.#configuring = true;
|
|
20244
20775
|
try {
|
|
20776
|
+
let requested;
|
|
20777
|
+
try {
|
|
20778
|
+
requested = decodePiModelRef(command.model);
|
|
20779
|
+
if (requested.fast && !await this.#isFastSupported(command.model, transport))
|
|
20780
|
+
throw new Error("Fast is unavailable for this Pi Model");
|
|
20781
|
+
} catch (error51) {
|
|
20782
|
+
return { ok: false, error: normalizedError(error51, "invalidRequest") };
|
|
20783
|
+
}
|
|
20245
20784
|
let state2;
|
|
20246
20785
|
let thinkingLevels;
|
|
20247
20786
|
try {
|
|
20248
|
-
state2 = await transport.selectModel(requested);
|
|
20787
|
+
state2 = samePiModel(nativeModelFromState(transport.state), requested) ? transport.state : await transport.selectModel(requested);
|
|
20249
20788
|
thinkingLevels = await transport.getAvailableThinkingLevels();
|
|
20789
|
+
if (requested.fast || state2.fast) {
|
|
20790
|
+
if (!transport.selectFastMode)
|
|
20791
|
+
throw new Error("Pi Fast extension is unavailable");
|
|
20792
|
+
state2 = await transport.selectFastMode(requested.fast === true);
|
|
20793
|
+
}
|
|
20250
20794
|
this.#publishTransportState(state2, thinkingLevels);
|
|
20251
20795
|
} catch (error51) {
|
|
20252
20796
|
if (error51 instanceof PiRpcFaultError)
|
|
@@ -20383,7 +20927,7 @@ var PiHarnessSession = class {
|
|
|
20383
20927
|
const transport = this.#transport;
|
|
20384
20928
|
if (this.#phase === "open" && transport?.getCommands) {
|
|
20385
20929
|
try {
|
|
20386
|
-
this.#liveCommands = piLiveCommandCatalog(piCommandCatalog, await transport.getCommands());
|
|
20930
|
+
this.#liveCommands = piLiveCommandCatalog(piCommandCatalog, (await transport.getCommands()).filter((command) => command.name !== PI_FAST_COMMAND));
|
|
20387
20931
|
} catch {
|
|
20388
20932
|
}
|
|
20389
20933
|
}
|
|
@@ -20530,6 +21074,11 @@ var PiHarnessSession = class {
|
|
|
20530
21074
|
this.#publishTransportState(state2, thinkingLevels);
|
|
20531
21075
|
throw new Error("Pi did not activate the requested create Model");
|
|
20532
21076
|
}
|
|
21077
|
+
if (requested.fast) {
|
|
21078
|
+
if (!await this.#isFastSupported(this.#requestedModel, transport) || !transport.selectFastMode)
|
|
21079
|
+
throw new Error("Fast is unavailable for this Pi Model");
|
|
21080
|
+
state2 = await transport.selectFastMode(true);
|
|
21081
|
+
}
|
|
20533
21082
|
}
|
|
20534
21083
|
if (this.#requestedThinkingOptionId) {
|
|
20535
21084
|
if (!thinkingLevels) {
|
|
@@ -20610,7 +21159,7 @@ var PiHarnessSession = class {
|
|
|
20610
21159
|
}));
|
|
20611
21160
|
return;
|
|
20612
21161
|
}
|
|
20613
|
-
const turnId = hostTurnIdSchema.parse(
|
|
21162
|
+
const turnId = hostTurnIdSchema.parse(randomUUID6());
|
|
20614
21163
|
let resolveCompletion = () => void 0;
|
|
20615
21164
|
const completion = new Promise((resolve) => {
|
|
20616
21165
|
resolveCompletion = resolve;
|
|
@@ -20772,7 +21321,7 @@ var PiHarnessSession = class {
|
|
|
20772
21321
|
if (active.interactionByNativeId.has(request.requestId)) {
|
|
20773
21322
|
throw new Error("Pi Interaction started more than once");
|
|
20774
21323
|
}
|
|
20775
|
-
const interactionId = hostInteractionIdSchema.parse(
|
|
21324
|
+
const interactionId = hostInteractionIdSchema.parse(randomUUID6());
|
|
20776
21325
|
const question = request.method === "select" ? {
|
|
20777
21326
|
id: "answer",
|
|
20778
21327
|
type: "choice",
|
|
@@ -21119,7 +21668,7 @@ var PiHarnessSession = class {
|
|
|
21119
21668
|
this.#channel.emit({ kind: "event", event });
|
|
21120
21669
|
}
|
|
21121
21670
|
#newItemId() {
|
|
21122
|
-
return hostItemIdSchema.parse(
|
|
21671
|
+
return hostItemIdSchema.parse(randomUUID6());
|
|
21123
21672
|
}
|
|
21124
21673
|
};
|
|
21125
21674
|
var PiAdapter = class {
|
|
@@ -21210,6 +21759,7 @@ var PiAdapter = class {
|
|
|
21210
21759
|
#inspections = /* @__PURE__ */ new Set();
|
|
21211
21760
|
#sessions = /* @__PURE__ */ new Set();
|
|
21212
21761
|
#toolOutputLimit;
|
|
21762
|
+
#environment;
|
|
21213
21763
|
#closePromise = null;
|
|
21214
21764
|
#thinkingSelectionSupported = null;
|
|
21215
21765
|
constructor(options = {}, dependencies = {
|
|
@@ -21229,10 +21779,21 @@ var PiAdapter = class {
|
|
|
21229
21779
|
remove: (name) => updateCatalog(imports.remove(name))
|
|
21230
21780
|
};
|
|
21231
21781
|
this.#createTransport = dependencies.createTransport;
|
|
21782
|
+
this.#environment = options.environment ?? process.env;
|
|
21232
21783
|
this.#importIndex = new PiSessionImportIndex({ ...process.env, ...options.environment });
|
|
21233
21784
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? 2e3;
|
|
21234
21785
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT;
|
|
21235
21786
|
}
|
|
21787
|
+
/** Pi itself holds no Account; this reports configured Provider balances. */
|
|
21788
|
+
async inspectAccounts() {
|
|
21789
|
+
if (this.#closePromise)
|
|
21790
|
+
return [];
|
|
21791
|
+
return fetchPiAccounts({ environment: this.#environment });
|
|
21792
|
+
}
|
|
21793
|
+
async inspectAccount() {
|
|
21794
|
+
const accounts = await this.inspectAccounts();
|
|
21795
|
+
return accounts[0] ?? null;
|
|
21796
|
+
}
|
|
21236
21797
|
#readImport(operation) {
|
|
21237
21798
|
if (this.#importAbort.signal.aborted)
|
|
21238
21799
|
return Promise.resolve({ ok: false, error: invalidState("Pi Adapter is closed") });
|
|
@@ -21292,7 +21853,9 @@ var PiAdapter = class {
|
|
|
21292
21853
|
stage = "capabilities";
|
|
21293
21854
|
const thinkingLevels = await transport.getAvailableThinkingLevels();
|
|
21294
21855
|
this.#thinkingSelectionSupported = thinkingLevels !== null;
|
|
21295
|
-
const
|
|
21856
|
+
const normalized = normalizePiModelCatalog(models, nativeModelFromState(transport.state), thinkingLevels, transport.state.thinkingLevel);
|
|
21857
|
+
const fastModels = await transport.supportsFastMode?.() ? await piFastModelKeys(models, this.#environment) : /* @__PURE__ */ new Set();
|
|
21858
|
+
const catalog = withPiFast(normalized, fastModels);
|
|
21296
21859
|
await transport.close();
|
|
21297
21860
|
return {
|
|
21298
21861
|
status: "ready",
|
|
@@ -21329,6 +21892,27 @@ var PiAdapter = class {
|
|
|
21329
21892
|
if (this.#closePromise) {
|
|
21330
21893
|
return { ok: false, error: invalidState("Pi Adapter is closed") };
|
|
21331
21894
|
}
|
|
21895
|
+
if ("model" in input && input.model) {
|
|
21896
|
+
let model;
|
|
21897
|
+
try {
|
|
21898
|
+
model = decodePiModelRef(input.model);
|
|
21899
|
+
} catch (error51) {
|
|
21900
|
+
return { ok: false, error: normalizedError(error51, "invalidRequest") };
|
|
21901
|
+
}
|
|
21902
|
+
if (model.fast) {
|
|
21903
|
+
if (!this.#isFastSupported(input.model, input.cwd))
|
|
21904
|
+
await this.inspect({ cwd: input.cwd });
|
|
21905
|
+
if (!this.#isFastSupported(input.model, input.cwd) && input.kind !== "resume")
|
|
21906
|
+
return {
|
|
21907
|
+
ok: false,
|
|
21908
|
+
error: {
|
|
21909
|
+
code: "unsupported",
|
|
21910
|
+
message: "Fast is unavailable for this Pi Model",
|
|
21911
|
+
retryable: false
|
|
21912
|
+
}
|
|
21913
|
+
};
|
|
21914
|
+
}
|
|
21915
|
+
}
|
|
21332
21916
|
if (input.cwd.length === 0) {
|
|
21333
21917
|
return {
|
|
21334
21918
|
ok: false,
|
|
@@ -21499,6 +22083,11 @@ var PiAdapter = class {
|
|
|
21499
22083
|
await transport.verifySessionCwd(input.cwd);
|
|
21500
22084
|
}
|
|
21501
22085
|
}
|
|
22086
|
+
if (input.kind === "resume" && input.model && this.#isFastSupported(input.model, input.cwd) && decodePiModelRef(input.model).fast && samePiModel(nativeModelFromState(transport.state), decodePiModelRef(input.model))) {
|
|
22087
|
+
if (!transport.selectFastMode)
|
|
22088
|
+
throw new Error("Pi Fast extension is unavailable");
|
|
22089
|
+
await transport.selectFastMode(true);
|
|
22090
|
+
}
|
|
21502
22091
|
const startedThinkingLevels = await transport.getAvailableThinkingLevels();
|
|
21503
22092
|
this.#thinkingSelectionSupported = startedThinkingLevels !== null;
|
|
21504
22093
|
const initialUsage = await transport.getSessionUsage().catch(() => null);
|
|
@@ -21515,6 +22104,9 @@ var PiAdapter = class {
|
|
|
21515
22104
|
return { ok: false, error: normalizedError(error51, "nativeFailure") };
|
|
21516
22105
|
}
|
|
21517
22106
|
}
|
|
22107
|
+
#isFastSupported(ref, cwd) {
|
|
22108
|
+
return this.#inspectionCache.get(cwd)?.catalog.models.some((model) => model.fastModel?.id === ref.id) ?? false;
|
|
22109
|
+
}
|
|
21518
22110
|
#trackSession(cwd, options) {
|
|
21519
22111
|
const environment = options.environment;
|
|
21520
22112
|
const createTransport = environment ? (input) => this.#createTransport({ ...input, environment }) : this.#createTransport;
|
|
@@ -21526,6 +22118,14 @@ var PiAdapter = class {
|
|
|
21526
22118
|
...options.thinkingOptionId ? { thinkingOptionId: options.thinkingOptionId } : {},
|
|
21527
22119
|
toolOutputLimit: this.#toolOutputLimit,
|
|
21528
22120
|
supportsThinkingSelection: options.supportsThinkingSelection,
|
|
22121
|
+
isFastSupported: async (ref, transport) => {
|
|
22122
|
+
if (this.#inspectionCache.has(cwd))
|
|
22123
|
+
return this.#isFastSupported(ref, cwd);
|
|
22124
|
+
if (!await transport.supportsFastMode?.())
|
|
22125
|
+
return false;
|
|
22126
|
+
const fastModels = await piFastModelKeys(await transport.getAvailableModels(), environment ?? this.#environment);
|
|
22127
|
+
return fastModels.has(encodePiModelRef({ ...decodePiModelRef(ref), fast: false }).id);
|
|
22128
|
+
},
|
|
21529
22129
|
...options.startedTransport ? { startedTransport: options.startedTransport } : {},
|
|
21530
22130
|
...options.startedThinkingLevels !== void 0 ? { startedThinkingLevels: options.startedThinkingLevels } : {},
|
|
21531
22131
|
...options.initialUsage !== void 0 ? { initialUsage: options.initialUsage } : {}
|
|
@@ -21546,14 +22146,36 @@ var PiAdapter = class {
|
|
|
21546
22146
|
}
|
|
21547
22147
|
};
|
|
21548
22148
|
|
|
22149
|
+
// dist/installation.js
|
|
22150
|
+
var PI_LATEST_VERSION_URL = "https://pi.dev/api/latest-version";
|
|
22151
|
+
function createPiInstallation(environment, command) {
|
|
22152
|
+
const run = (args, timeout) => runInstallationCommand(resolvePiExecutable({ environment, ...command ? { command } : {} }), args, environment, timeout);
|
|
22153
|
+
return createInstallationManager({
|
|
22154
|
+
async check() {
|
|
22155
|
+
const currentVersion = versionFromOutput(await run(["--version"]));
|
|
22156
|
+
const payload = JSON.parse(await fetchInstallationText(PI_LATEST_VERSION_URL));
|
|
22157
|
+
const latestVersion = installationVersion(payload.version);
|
|
22158
|
+
return {
|
|
22159
|
+
currentVersion,
|
|
22160
|
+
latestVersion,
|
|
22161
|
+
updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
|
|
22162
|
+
canUpdate: true
|
|
22163
|
+
};
|
|
22164
|
+
},
|
|
22165
|
+
async update() {
|
|
22166
|
+
await run(["update"], 3e5);
|
|
22167
|
+
}
|
|
22168
|
+
});
|
|
22169
|
+
}
|
|
22170
|
+
|
|
21549
22171
|
// dist/plugin.js
|
|
21550
22172
|
var PI_COMMAND_ENV = "CODEXHOST_PI_COMMAND";
|
|
21551
22173
|
function createHarnessAdapter(context) {
|
|
21552
22174
|
const environment = { ...context.environment };
|
|
21553
|
-
return new PiAdapter({
|
|
22175
|
+
return Object.assign(new PiAdapter({
|
|
21554
22176
|
...environment[PI_COMMAND_ENV] ? { command: environment[PI_COMMAND_ENV] } : {},
|
|
21555
22177
|
environment
|
|
21556
|
-
});
|
|
22178
|
+
}), { installation: createPiInstallation(environment, environment[PI_COMMAND_ENV]) });
|
|
21557
22179
|
}
|
|
21558
22180
|
export {
|
|
21559
22181
|
PI_COMMAND_ENV,
|