@codexhost/cli-darwin-x64 0.16.1 → 0.17.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 +2 -2
- package/THIRD_PARTY_NOTICES.txt +6 -2
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +55 -20
- package/app/console-web.js +45 -17
- package/app/desktop-controller.mjs +76 -31
- package/app/host-runtime.mjs +2671 -1869
- package/app/plugins/antigravity/plugin.mjs +35 -2
- package/app/plugins/claude-code/plugin.mjs +12 -6
- package/app/plugins/codebuddy/plugin.mjs +10 -0
- package/app/plugins/cursor-cli/plugin.mjs +9 -5
- package/app/plugins/deepseek-harness/plugin.mjs +459 -46
- package/app/plugins/devin/assets/icon.svg +1 -0
- package/app/plugins/devin/manifest.json +30 -0
- package/app/plugins/devin/plugin.mjs +23363 -0
- package/app/plugins/enabled.json +2 -0
- package/app/plugins/grok/plugin.mjs +472 -391
- package/app/plugins/hermes/plugin.mjs +453 -196
- package/app/plugins/pi/plugin.mjs +1460 -411
- package/app/plugins/qoder/plugin.mjs +9524 -8654
- package/app/plugins/qoder-cn/plugin.mjs +9524 -8654
- package/app/plugins/qwen-code/assets/icon.svg +1 -0
- package/app/plugins/qwen-code/manifest.json +29 -0
- package/app/plugins/qwen-code/plugin.mjs +29298 -0
- package/app/plugins/workbuddy/plugin.mjs +10 -0
- package/app/renderer-extension.js +162 -54
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/licenses/Qwen-Code-SDK-LICENSE.txt +203 -0
- package/package.json +2 -2
|
@@ -528,9 +528,9 @@ async function jsonlHeader(file2, match, signal, maxLines = 4) {
|
|
|
528
528
|
continue;
|
|
529
529
|
}
|
|
530
530
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
531
|
-
const
|
|
532
|
-
if (match(
|
|
533
|
-
return
|
|
531
|
+
const record9 = value;
|
|
532
|
+
if (match(record9))
|
|
533
|
+
return record9;
|
|
534
534
|
}
|
|
535
535
|
}
|
|
536
536
|
return null;
|
|
@@ -1317,10 +1317,10 @@ function mergeDefs(...defs) {
|
|
|
1317
1317
|
function cloneDef(schema) {
|
|
1318
1318
|
return mergeDefs(schema._zod.def);
|
|
1319
1319
|
}
|
|
1320
|
-
function getElementAtPath(obj,
|
|
1321
|
-
if (!
|
|
1320
|
+
function getElementAtPath(obj, path17) {
|
|
1321
|
+
if (!path17)
|
|
1322
1322
|
return obj;
|
|
1323
|
-
return
|
|
1323
|
+
return path17.reduce((acc, key) => acc?.[key], obj);
|
|
1324
1324
|
}
|
|
1325
1325
|
function promiseAllObject(promisesObj) {
|
|
1326
1326
|
const keys = Object.keys(promisesObj);
|
|
@@ -1729,11 +1729,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1729
1729
|
}
|
|
1730
1730
|
return false;
|
|
1731
1731
|
}
|
|
1732
|
-
function prefixIssues(
|
|
1732
|
+
function prefixIssues(path17, issues) {
|
|
1733
1733
|
return issues.map((iss) => {
|
|
1734
1734
|
var _a3;
|
|
1735
1735
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1736
|
-
iss.path.unshift(
|
|
1736
|
+
iss.path.unshift(path17);
|
|
1737
1737
|
return iss;
|
|
1738
1738
|
});
|
|
1739
1739
|
}
|
|
@@ -1880,16 +1880,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1880
1880
|
}
|
|
1881
1881
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1882
1882
|
const fieldErrors = { _errors: [] };
|
|
1883
|
-
const processError = (error52,
|
|
1883
|
+
const processError = (error52, path17 = []) => {
|
|
1884
1884
|
for (const issue2 of error52.issues) {
|
|
1885
1885
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1886
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1886
|
+
issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
|
|
1887
1887
|
} else if (issue2.code === "invalid_key") {
|
|
1888
|
-
processError({ issues: issue2.issues }, [...
|
|
1888
|
+
processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
|
|
1889
1889
|
} else if (issue2.code === "invalid_element") {
|
|
1890
|
-
processError({ issues: issue2.issues }, [...
|
|
1890
|
+
processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
|
|
1891
1891
|
} else {
|
|
1892
|
-
const fullpath = [...
|
|
1892
|
+
const fullpath = [...path17, ...issue2.path];
|
|
1893
1893
|
if (fullpath.length === 0) {
|
|
1894
1894
|
fieldErrors._errors.push(mapper(issue2));
|
|
1895
1895
|
} else {
|
|
@@ -1916,17 +1916,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1916
1916
|
}
|
|
1917
1917
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1918
1918
|
const result = { errors: [] };
|
|
1919
|
-
const processError = (error52,
|
|
1919
|
+
const processError = (error52, path17 = []) => {
|
|
1920
1920
|
var _a3, _b;
|
|
1921
1921
|
for (const issue2 of error52.issues) {
|
|
1922
1922
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1923
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1923
|
+
issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
|
|
1924
1924
|
} else if (issue2.code === "invalid_key") {
|
|
1925
|
-
processError({ issues: issue2.issues }, [...
|
|
1925
|
+
processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
|
|
1926
1926
|
} else if (issue2.code === "invalid_element") {
|
|
1927
|
-
processError({ issues: issue2.issues }, [...
|
|
1927
|
+
processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
|
|
1928
1928
|
} else {
|
|
1929
|
-
const fullpath = [...
|
|
1929
|
+
const fullpath = [...path17, ...issue2.path];
|
|
1930
1930
|
if (fullpath.length === 0) {
|
|
1931
1931
|
result.errors.push(mapper(issue2));
|
|
1932
1932
|
continue;
|
|
@@ -1958,8 +1958,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1958
1958
|
}
|
|
1959
1959
|
function toDotPath(_path) {
|
|
1960
1960
|
const segs = [];
|
|
1961
|
-
const
|
|
1962
|
-
for (const seg of
|
|
1961
|
+
const path17 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1962
|
+
for (const seg of path17) {
|
|
1963
1963
|
if (typeof seg === "number")
|
|
1964
1964
|
segs.push(`[${seg}]`);
|
|
1965
1965
|
else if (typeof seg === "symbol")
|
|
@@ -8189,8 +8189,8 @@ function ko_default() {
|
|
|
8189
8189
|
}
|
|
8190
8190
|
|
|
8191
8191
|
// ../../../node_modules/zod/v4/locales/lt.js
|
|
8192
|
-
var capitalizeFirstCharacter = (
|
|
8193
|
-
return
|
|
8192
|
+
var capitalizeFirstCharacter = (text3) => {
|
|
8193
|
+
return text3.charAt(0).toUpperCase() + text3.slice(1);
|
|
8194
8194
|
};
|
|
8195
8195
|
function getUnitTypeFromNumber(number4) {
|
|
8196
8196
|
const abs = Math.abs(number4);
|
|
@@ -14651,13 +14651,13 @@ function resolveRef(ref, ctx) {
|
|
|
14651
14651
|
if (!ref.startsWith("#")) {
|
|
14652
14652
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14653
14653
|
}
|
|
14654
|
-
const
|
|
14655
|
-
if (
|
|
14654
|
+
const path17 = ref.slice(1).split("/").filter(Boolean);
|
|
14655
|
+
if (path17.length === 0) {
|
|
14656
14656
|
return ctx.rootSchema;
|
|
14657
14657
|
}
|
|
14658
14658
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14659
|
-
if (
|
|
14660
|
-
const key =
|
|
14659
|
+
if (path17[0] === defsKey) {
|
|
14660
|
+
const key = path17[1];
|
|
14661
14661
|
if (!key || !ctx.defs[key]) {
|
|
14662
14662
|
throw new Error(`Reference not found: ${ref}`);
|
|
14663
14663
|
}
|
|
@@ -15146,7 +15146,7 @@ var harnessDisplaySetSchema = external_exports.strictObject({
|
|
|
15146
15146
|
|
|
15147
15147
|
// ../../shared-contracts/dist/harness-presentation.js
|
|
15148
15148
|
var localeSchema = external_exports.string().max(64).regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u);
|
|
15149
|
-
var displayText = (maximum) => external_exports.string().min(1).max(maximum).refine((
|
|
15149
|
+
var displayText = (maximum) => external_exports.string().min(1).max(maximum).refine((text3) => text3.trim().length > 0);
|
|
15150
15150
|
var harnessLocalizationsSchema = external_exports.record(localeSchema, external_exports.object({
|
|
15151
15151
|
label: displayText(256).optional(),
|
|
15152
15152
|
description: displayText(1024).optional()
|
|
@@ -15474,7 +15474,7 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
|
|
|
15474
15474
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
15475
15475
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
15476
15476
|
var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
15477
|
-
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((
|
|
15477
|
+
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text3) => text3.length <= maximum));
|
|
15478
15478
|
var composerIndicatorsSchema = external_exports.array(external_exports.object({
|
|
15479
15479
|
kind: external_exports.literal("countdown"),
|
|
15480
15480
|
id: external_exports.string().min(1).max(64),
|
|
@@ -16719,8 +16719,8 @@ async function readCandidate(file2, signal) {
|
|
|
16719
16719
|
const message3 = isRecord(entry.message) ? entry.message : null;
|
|
16720
16720
|
if (!firstMessage && entry.type === "message" && message3?.role === "user") {
|
|
16721
16721
|
const content = message3.content;
|
|
16722
|
-
const
|
|
16723
|
-
firstMessage = sessionImportTitle(
|
|
16722
|
+
const text3 = typeof content === "string" ? content : Array.isArray(content) ? content.filter((block) => isRecord(block) && block.type === "text" && typeof block.text === "string").map((block) => block.text).join(" ") : "";
|
|
16723
|
+
firstMessage = sessionImportTitle(text3);
|
|
16724
16724
|
}
|
|
16725
16725
|
hasUser = entry.type === "message" && message3?.role === "user" || typeof entry.parentId === "string" && entries.get(entry.parentId) === true;
|
|
16726
16726
|
entries.set(entry.id, hasUser);
|
|
@@ -17233,8 +17233,8 @@ function liveHarnessCommandPrompt(catalog, idPrefix, commandId, argumentText) {
|
|
|
17233
17233
|
const descriptor = catalog.commands.find(({ id }) => id === commandId);
|
|
17234
17234
|
if (!descriptor)
|
|
17235
17235
|
return null;
|
|
17236
|
-
const
|
|
17237
|
-
return
|
|
17236
|
+
const text3 = typeof argumentText === "string" ? argumentText.trim() : "";
|
|
17237
|
+
return text3 ? `${descriptor.invocation} ${text3}` : descriptor.invocation;
|
|
17238
17238
|
}
|
|
17239
17239
|
function mergeLiveHarnessCommands(builtIns, idPrefix, live, exclusions = {}) {
|
|
17240
17240
|
if (!live)
|
|
@@ -17370,16 +17370,16 @@ var Diff = class {
|
|
|
17370
17370
|
}
|
|
17371
17371
|
}
|
|
17372
17372
|
}
|
|
17373
|
-
addToPath(
|
|
17374
|
-
const last =
|
|
17373
|
+
addToPath(path17, added, removed, oldPosInc, options) {
|
|
17374
|
+
const last = path17.lastComponent;
|
|
17375
17375
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
17376
17376
|
return {
|
|
17377
|
-
oldPos:
|
|
17377
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
17378
17378
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
17379
17379
|
};
|
|
17380
17380
|
} else {
|
|
17381
17381
|
return {
|
|
17382
|
-
oldPos:
|
|
17382
|
+
oldPos: path17.oldPos + oldPosInc,
|
|
17383
17383
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
17384
17384
|
};
|
|
17385
17385
|
}
|
|
@@ -17779,9 +17779,9 @@ function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader
|
|
|
17779
17779
|
} }));
|
|
17780
17780
|
}
|
|
17781
17781
|
}
|
|
17782
|
-
function splitLines(
|
|
17783
|
-
const hasTrailingNl =
|
|
17784
|
-
const result =
|
|
17782
|
+
function splitLines(text3) {
|
|
17783
|
+
const hasTrailingNl = text3.endsWith("\n");
|
|
17784
|
+
const result = text3.split("\n").map((line) => line + "\n");
|
|
17785
17785
|
if (hasTrailingNl) {
|
|
17786
17786
|
result.pop();
|
|
17787
17787
|
} else {
|
|
@@ -18015,11 +18015,344 @@ function piNestedCallFileChanges(nestedCalls, cwd) {
|
|
|
18015
18015
|
return projected;
|
|
18016
18016
|
}
|
|
18017
18017
|
|
|
18018
|
-
// dist/pi-
|
|
18018
|
+
// dist/pi-message-item-id.js
|
|
18019
18019
|
import { createHash } from "node:crypto";
|
|
18020
|
+
function piMessageIdentity(sessionId, message3, timestampCounts) {
|
|
18021
|
+
if (typeof message3 !== "object" || message3 === null || !("role" in message3) || message3.role !== "assistant")
|
|
18022
|
+
return void 0;
|
|
18023
|
+
if ("timestamp" in message3 && typeof message3.timestamp === "number" && Number.isSafeInteger(message3.timestamp) && message3.timestamp >= 0) {
|
|
18024
|
+
const occurrence = timestampCounts.get(message3.timestamp) ?? 0;
|
|
18025
|
+
timestampCounts.set(message3.timestamp, occurrence + 1);
|
|
18026
|
+
return { sessionId, timestamp: message3.timestamp, occurrence };
|
|
18027
|
+
}
|
|
18028
|
+
if ("responseId" in message3 && typeof message3.responseId === "string" && message3.responseId.trim().length > 0)
|
|
18029
|
+
return { responseId: message3.responseId };
|
|
18030
|
+
return void 0;
|
|
18031
|
+
}
|
|
18032
|
+
function piHistoryMessageIdentities(sessionId, entries) {
|
|
18033
|
+
const timestampCounts = /* @__PURE__ */ new Map();
|
|
18034
|
+
const identities = /* @__PURE__ */ new Map();
|
|
18035
|
+
for (const entry of entries) {
|
|
18036
|
+
const identity = piMessageIdentity(sessionId, entry.message, timestampCounts);
|
|
18037
|
+
if (identity)
|
|
18038
|
+
identities.set(entry.id, identity);
|
|
18039
|
+
}
|
|
18040
|
+
return { identities, timestampCounts };
|
|
18041
|
+
}
|
|
18042
|
+
function piMessageItemId(identity, kind) {
|
|
18043
|
+
if (!identity)
|
|
18044
|
+
return null;
|
|
18045
|
+
const timestampIdentity = "timestamp" in identity;
|
|
18046
|
+
const value = timestampIdentity ? JSON.stringify([identity.sessionId, identity.timestamp, identity.occurrence]) : identity.responseId;
|
|
18047
|
+
const digest = createHash("sha256").update(value).digest("hex");
|
|
18048
|
+
return hostItemIdSchema.parse(`pi-${timestampIdentity ? "message" : "response"}-v1-${digest}-${kind}`);
|
|
18049
|
+
}
|
|
18050
|
+
|
|
18051
|
+
// dist/pi-assistant-outcome.js
|
|
18052
|
+
function piAssistantWasAborted(value) {
|
|
18053
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
18054
|
+
return false;
|
|
18055
|
+
const message3 = value;
|
|
18056
|
+
return message3.role === "assistant" && (message3.stopReason === "aborted" || message3.stopReason === "error" && message3.errorMessage === "This operation was aborted");
|
|
18057
|
+
}
|
|
18058
|
+
function piAssistantPhase(value) {
|
|
18059
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
18060
|
+
return void 0;
|
|
18061
|
+
const message3 = value;
|
|
18062
|
+
if (message3.role !== "assistant")
|
|
18063
|
+
return void 0;
|
|
18064
|
+
const lastText = Array.isArray(message3.content) ? message3.content.findLast((part) => typeof part === "object" && part !== null && !Array.isArray(part) && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string" && part.text.trim().length > 0) : void 0;
|
|
18065
|
+
if (!lastText && !(typeof message3.content === "string" && message3.content.trim()))
|
|
18066
|
+
return void 0;
|
|
18067
|
+
if (typeof lastText?.textSignature === "string") {
|
|
18068
|
+
try {
|
|
18069
|
+
const signature = JSON.parse(lastText.textSignature);
|
|
18070
|
+
if (typeof signature === "object" && signature !== null && !Array.isArray(signature) && "v" in signature && signature.v === 1 && "id" in signature && typeof signature.id === "string" && "phase" in signature && (signature.phase === "commentary" || signature.phase === "final_answer"))
|
|
18071
|
+
return signature.phase;
|
|
18072
|
+
} catch {
|
|
18073
|
+
}
|
|
18074
|
+
}
|
|
18075
|
+
if (message3.stopReason === "toolUse")
|
|
18076
|
+
return "commentary";
|
|
18077
|
+
if (message3.stopReason === "stop")
|
|
18078
|
+
return "final_answer";
|
|
18079
|
+
return void 0;
|
|
18080
|
+
}
|
|
18081
|
+
|
|
18082
|
+
// dist/pi-subagents.js
|
|
18083
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
18084
|
+
|
|
18085
|
+
// dist/pi-gotgenes-extension.js
|
|
18086
|
+
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
18087
|
+
import { mkdir, readFile, rename, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
18088
|
+
import { homedir as homedir2 } from "node:os";
|
|
18089
|
+
import path7 from "node:path";
|
|
18090
|
+
var GOTGENES_WIDGET = "codexhost-gotgenes-subagents";
|
|
18091
|
+
var GOTGENES_PREFIX = "CODEXHOST_GOTGENES_SUBAGENTS_V1:";
|
|
18092
|
+
var GOTGENES_EXTENSION = `export default function(pi) {
|
|
18093
|
+
let ctx, timer, service, previous = "";
|
|
18094
|
+
const publish = () => {
|
|
18095
|
+
if (!ctx) return;
|
|
18096
|
+
// Child SDK sessions can publish their own process-global service. Bind this parent once.
|
|
18097
|
+
if (!service) {
|
|
18098
|
+
const candidate = globalThis[Symbol.for("@gotgenes/pi-subagents:service")];
|
|
18099
|
+
if (typeof candidate?.listAgents !== "function") return;
|
|
18100
|
+
service = candidate;
|
|
18101
|
+
}
|
|
18102
|
+
const agents = service.listAgents().slice(0, 128).map((r) => ({
|
|
18103
|
+
id: r.id, type: r.type, description: r.description?.slice(0, 2048),
|
|
18104
|
+
status: r.status, isBackground: r.isBackground, outputFile: r.outputFile,
|
|
18105
|
+
toolUses: r.toolUses, startedAt: r.startedAt, completedAt: r.completedAt,
|
|
18106
|
+
result: r.result?.slice(0, 2048), error: r.error?.slice(0, 2048),
|
|
18107
|
+
turnBudget: r.turnBudget, lifetimeUsage: r.lifetimeUsage,
|
|
18108
|
+
}));
|
|
18109
|
+
const payload = JSON.stringify({version: 1, agents});
|
|
18110
|
+
if (payload === previous) return;
|
|
18111
|
+
previous = payload;
|
|
18112
|
+
ctx.ui.setWidget("${GOTGENES_WIDGET}", ["${GOTGENES_PREFIX}" + payload]);
|
|
18113
|
+
};
|
|
18114
|
+
const schedule = () => queueMicrotask(publish);
|
|
18115
|
+
for (const name of ["created", "started", "completed", "failed", "resuming", "resumed", "compacted", "steered", "update"]) {
|
|
18116
|
+
pi.events.on("subagents:" + name, schedule);
|
|
18117
|
+
}
|
|
18118
|
+
pi.on("session_start", (_event, context) => {
|
|
18119
|
+
// A session switch keeps this extension's manager/service; only reload creates a new instance.
|
|
18120
|
+
ctx = context; previous = ""; clearInterval(timer);
|
|
18121
|
+
schedule();
|
|
18122
|
+
// The public service publishes outputFile only after queued session creation and has no progress event.
|
|
18123
|
+
timer = setInterval(publish, 1000);
|
|
18124
|
+
timer.unref?.();
|
|
18125
|
+
});
|
|
18126
|
+
pi.on("session_shutdown", () => { clearInterval(timer); timer = undefined; ctx = undefined; service = undefined; });
|
|
18127
|
+
}
|
|
18128
|
+
`;
|
|
18129
|
+
async function ensureGotgenesExtension(environment) {
|
|
18130
|
+
const digest = createHash2("sha256").update(GOTGENES_EXTENSION).digest("hex").slice(0, 16);
|
|
18131
|
+
const root = environment.CODEXHOST_DATA_DIR ?? path7.join(environment.HOME ?? environment.USERPROFILE ?? homedir2(), ".codexhost");
|
|
18132
|
+
const directory = path7.resolve(root, "extensions", "pi-subagent-observer");
|
|
18133
|
+
const file2 = path7.join(directory, `${digest}.mjs`);
|
|
18134
|
+
if (await readFile(file2, "utf8").catch(() => "") === GOTGENES_EXTENSION)
|
|
18135
|
+
return file2;
|
|
18136
|
+
await mkdir(directory, { recursive: true });
|
|
18137
|
+
const temporary = `${file2}.${randomUUID()}.tmp`;
|
|
18138
|
+
try {
|
|
18139
|
+
await writeFile2(temporary, GOTGENES_EXTENSION, { mode: 384 });
|
|
18140
|
+
try {
|
|
18141
|
+
await rename(temporary, file2);
|
|
18142
|
+
} catch (error51) {
|
|
18143
|
+
if (await readFile(file2, "utf8").catch(() => "") !== GOTGENES_EXTENSION)
|
|
18144
|
+
throw error51;
|
|
18145
|
+
}
|
|
18146
|
+
} finally {
|
|
18147
|
+
await rm2(temporary, { force: true });
|
|
18148
|
+
}
|
|
18149
|
+
return file2;
|
|
18150
|
+
}
|
|
18151
|
+
|
|
18152
|
+
// dist/pi-gotgenes-subagents.js
|
|
18153
|
+
var PREFIX = "pi-gotgenes-v1:";
|
|
18154
|
+
var STATUSES = {
|
|
18155
|
+
queued: "pending",
|
|
18156
|
+
running: "running",
|
|
18157
|
+
background: "pending",
|
|
18158
|
+
completed: "completed",
|
|
18159
|
+
aborted: "interrupted",
|
|
18160
|
+
stopped: "interrupted",
|
|
18161
|
+
error: "failed"
|
|
18162
|
+
};
|
|
18163
|
+
function isRecord4(value) {
|
|
18164
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18165
|
+
}
|
|
18166
|
+
function text(value, limit = 2048) {
|
|
18167
|
+
return typeof value === "string" && value.length > 0 && value.length <= limit;
|
|
18168
|
+
}
|
|
18169
|
+
function gotgenesId(id) {
|
|
18170
|
+
return PREFIX + Buffer.from(id).toString("base64url");
|
|
18171
|
+
}
|
|
18172
|
+
function parseGotgenesId(value) {
|
|
18173
|
+
if (!value.startsWith(PREFIX))
|
|
18174
|
+
return null;
|
|
18175
|
+
const id = Buffer.from(value.slice(PREFIX.length), "base64url").toString("utf8");
|
|
18176
|
+
if (!text(id, 256) || /[\s/\\]/u.test(id) || gotgenesId(id) !== value)
|
|
18177
|
+
throw new Error("Invalid gotgenes subagent identity");
|
|
18178
|
+
return id;
|
|
18179
|
+
}
|
|
18180
|
+
function gotgenesRecord(value) {
|
|
18181
|
+
if (!isRecord4(value) || !text(value.id, 256) || /[\s/\\]/u.test(value.id) || !text(value.type) || !text(value.description) || typeof value.status !== "string" || !Object.hasOwn(STATUSES, value.status))
|
|
18182
|
+
return null;
|
|
18183
|
+
const status = STATUSES[value.status];
|
|
18184
|
+
if (!status)
|
|
18185
|
+
return null;
|
|
18186
|
+
const id = gotgenesId(value.id);
|
|
18187
|
+
const progress = typeof value.toolUses === "number" ? `${value.toolUses} tool uses` : void 0;
|
|
18188
|
+
const result = typeof value.error === "string" ? value.error : typeof value.result === "string" ? value.result : progress;
|
|
18189
|
+
return {
|
|
18190
|
+
id: value.id,
|
|
18191
|
+
roleKnown: value.roleKnown !== false,
|
|
18192
|
+
backgroundKnown: typeof value.isBackground === "boolean",
|
|
18193
|
+
child: {
|
|
18194
|
+
subagentId: id,
|
|
18195
|
+
nativeSubagentId: id,
|
|
18196
|
+
description: value.description,
|
|
18197
|
+
role: value.type,
|
|
18198
|
+
status,
|
|
18199
|
+
background: value.isBackground === true,
|
|
18200
|
+
...text(value.modelName) ? { model: value.modelName } : {},
|
|
18201
|
+
...result ? { resultSummary: result.slice(0, 2048) } : {}
|
|
18202
|
+
},
|
|
18203
|
+
...text(value.outputFile, 8192) ? { outputFile: value.outputFile } : {},
|
|
18204
|
+
revision: JSON.stringify([
|
|
18205
|
+
value.toolUses,
|
|
18206
|
+
value.turnBudget,
|
|
18207
|
+
value.lifetimeUsage,
|
|
18208
|
+
value.outputFile
|
|
18209
|
+
])
|
|
18210
|
+
};
|
|
18211
|
+
}
|
|
18212
|
+
function gotgenesToolRecord(toolName, result) {
|
|
18213
|
+
if (!["subagent", "get_subagent_result"].includes(toolName) || !isRecord4(result) || !isRecord4(result.details))
|
|
18214
|
+
return null;
|
|
18215
|
+
const d = result.details;
|
|
18216
|
+
if (!text(d.agentId, 256) || !text(d.displayName) || !text(d.description))
|
|
18217
|
+
return null;
|
|
18218
|
+
return gotgenesRecord({
|
|
18219
|
+
...d,
|
|
18220
|
+
id: d.agentId,
|
|
18221
|
+
type: d.subagentType ?? d.displayName,
|
|
18222
|
+
roleKnown: text(d.subagentType),
|
|
18223
|
+
isBackground: toolName === "subagent" ? d.status === "background" || Array.isArray(d.tags) && d.tags.includes("background") : void 0,
|
|
18224
|
+
outputFile: d.transcriptPath,
|
|
18225
|
+
result: d.preview
|
|
18226
|
+
});
|
|
18227
|
+
}
|
|
18228
|
+
function parseGotgenesWidget(value) {
|
|
18229
|
+
if (!isRecord4(value) || value.type !== "extension_ui_request" || value.method !== "setWidget" || value.widgetKey !== GOTGENES_WIDGET || !Array.isArray(value.widgetLines))
|
|
18230
|
+
return null;
|
|
18231
|
+
const line = value.widgetLines.find((x) => typeof x === "string" && x.startsWith(GOTGENES_PREFIX));
|
|
18232
|
+
if (!line || Buffer.byteLength(line) > 1024 * 1024)
|
|
18233
|
+
return null;
|
|
18234
|
+
try {
|
|
18235
|
+
const payload = JSON.parse(line.slice(GOTGENES_PREFIX.length));
|
|
18236
|
+
if (!isRecord4(payload) || payload.version !== 1 || !Array.isArray(payload.agents) || payload.agents.length > 128)
|
|
18237
|
+
return null;
|
|
18238
|
+
const records = payload.agents.map(gotgenesRecord);
|
|
18239
|
+
return records.every((r) => r !== null) ? records : null;
|
|
18240
|
+
} catch {
|
|
18241
|
+
return null;
|
|
18242
|
+
}
|
|
18243
|
+
}
|
|
18244
|
+
function mergeGotgenesRecord(previous, record9) {
|
|
18245
|
+
const model2 = record9.child.model ?? previous?.child.model;
|
|
18246
|
+
const role = record9.roleKnown ? record9.child.role : previous?.child.role ?? record9.child.role;
|
|
18247
|
+
return {
|
|
18248
|
+
...previous,
|
|
18249
|
+
...record9,
|
|
18250
|
+
roleKnown: record9.roleKnown || previous?.roleKnown === true,
|
|
18251
|
+
backgroundKnown: record9.backgroundKnown || previous?.backgroundKnown === true,
|
|
18252
|
+
outputFile: record9.outputFile ?? previous?.outputFile,
|
|
18253
|
+
child: {
|
|
18254
|
+
...previous?.child,
|
|
18255
|
+
...record9.child,
|
|
18256
|
+
...model2 ? { model: model2 } : {},
|
|
18257
|
+
...role ? { role } : {},
|
|
18258
|
+
background: record9.backgroundKnown ? record9.child.background : previous?.child.background ?? record9.child.background
|
|
18259
|
+
}
|
|
18260
|
+
};
|
|
18261
|
+
}
|
|
18262
|
+
var GotgenesSubagents = class {
|
|
18263
|
+
emit;
|
|
18264
|
+
records = /* @__PURE__ */ new Map();
|
|
18265
|
+
#nativeObserved = /* @__PURE__ */ new Set();
|
|
18266
|
+
#active = /* @__PURE__ */ new Map();
|
|
18267
|
+
constructor(emit) {
|
|
18268
|
+
this.emit = emit;
|
|
18269
|
+
}
|
|
18270
|
+
observe(records, publish = true, activeTurn, nativeObservation = false) {
|
|
18271
|
+
for (const record9 of records) {
|
|
18272
|
+
if (!publish && this.#nativeObserved.has(record9.id))
|
|
18273
|
+
continue;
|
|
18274
|
+
if (nativeObservation)
|
|
18275
|
+
this.#nativeObserved.add(record9.id);
|
|
18276
|
+
const previous = this.records.get(record9.id);
|
|
18277
|
+
const merged = mergeGotgenesRecord(previous, record9);
|
|
18278
|
+
this.records.set(record9.id, merged);
|
|
18279
|
+
if (publish && !previous && activeTurn && !this.#active.has(record9.id)) {
|
|
18280
|
+
const item = {
|
|
18281
|
+
type: "subagentDelegation",
|
|
18282
|
+
itemId: activeTurn.nextItemId(),
|
|
18283
|
+
operation: "spawn",
|
|
18284
|
+
subagents: [merged.child]
|
|
18285
|
+
};
|
|
18286
|
+
this.#active.set(record9.id, { turnId: activeTurn.turnId, item });
|
|
18287
|
+
this.emit({ type: "item.started", turnId: activeTurn.turnId, item });
|
|
18288
|
+
}
|
|
18289
|
+
if (!publish || JSON.stringify(previous) === JSON.stringify(merged))
|
|
18290
|
+
continue;
|
|
18291
|
+
const active = this.#active.get(record9.id);
|
|
18292
|
+
if (active) {
|
|
18293
|
+
active.item = { ...active.item, subagents: [merged.child] };
|
|
18294
|
+
this.emit({
|
|
18295
|
+
type: "item.updated",
|
|
18296
|
+
turnId: active.turnId,
|
|
18297
|
+
itemId: active.item.itemId,
|
|
18298
|
+
update: { type: "subagents.replace", subagents: [merged.child] }
|
|
18299
|
+
});
|
|
18300
|
+
}
|
|
18301
|
+
this.emit({
|
|
18302
|
+
type: "subagent.state.changed",
|
|
18303
|
+
nativeSubagentId: merged.child.subagentId,
|
|
18304
|
+
status: merged.child.status
|
|
18305
|
+
});
|
|
18306
|
+
this.emit({ type: "subagent.transcript.changed", nativeSubagentId: merged.child.subagentId });
|
|
18307
|
+
}
|
|
18308
|
+
}
|
|
18309
|
+
project(toolName, result, itemId2) {
|
|
18310
|
+
const parsed = gotgenesToolRecord(toolName, result);
|
|
18311
|
+
if (!parsed || toolName !== "subagent")
|
|
18312
|
+
return null;
|
|
18313
|
+
const child = this.records.get(parsed.id)?.child ?? parsed.child;
|
|
18314
|
+
return { type: "subagentDelegation", itemId: itemId2, operation: "spawn", subagents: [child] };
|
|
18315
|
+
}
|
|
18316
|
+
start(turnId, toolName, result, itemId2) {
|
|
18317
|
+
const parsed = gotgenesToolRecord(toolName, result);
|
|
18318
|
+
if (!parsed)
|
|
18319
|
+
return false;
|
|
18320
|
+
const prior = this.records.get(parsed.id);
|
|
18321
|
+
if (!prior || !this.#nativeObserved.has(parsed.id))
|
|
18322
|
+
this.observe([parsed]);
|
|
18323
|
+
else {
|
|
18324
|
+
this.observe([
|
|
18325
|
+
{
|
|
18326
|
+
...prior,
|
|
18327
|
+
child: { ...prior.child, ...parsed.child.model ? { model: parsed.child.model } : {} }
|
|
18328
|
+
}
|
|
18329
|
+
]);
|
|
18330
|
+
}
|
|
18331
|
+
if (toolName === "subagent" && !this.#active.has(parsed.id)) {
|
|
18332
|
+
const item = this.project(toolName, result, itemId2);
|
|
18333
|
+
if (!item)
|
|
18334
|
+
return false;
|
|
18335
|
+
this.#active.set(parsed.id, { turnId, item });
|
|
18336
|
+
this.emit({ type: "item.started", turnId, item });
|
|
18337
|
+
}
|
|
18338
|
+
return true;
|
|
18339
|
+
}
|
|
18340
|
+
finish(turnId) {
|
|
18341
|
+
for (const [id, active] of this.#active) {
|
|
18342
|
+
if (active.turnId !== turnId)
|
|
18343
|
+
continue;
|
|
18344
|
+
this.#active.delete(id);
|
|
18345
|
+
this.emit({
|
|
18346
|
+
type: "item.completed",
|
|
18347
|
+
turnId,
|
|
18348
|
+
snapshot: { item: active.item, outcome: { status: "succeeded" } }
|
|
18349
|
+
});
|
|
18350
|
+
}
|
|
18351
|
+
}
|
|
18352
|
+
};
|
|
18020
18353
|
|
|
18021
18354
|
// dist/pi-subagent-workflow.js
|
|
18022
|
-
var
|
|
18355
|
+
var PREFIX2 = "pi-subagents-workflow-v1:";
|
|
18023
18356
|
var STATES = {
|
|
18024
18357
|
pending: "pending",
|
|
18025
18358
|
running: "running",
|
|
@@ -18033,7 +18366,7 @@ var STATES = {
|
|
|
18033
18366
|
function record2(value) {
|
|
18034
18367
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18035
18368
|
}
|
|
18036
|
-
function
|
|
18369
|
+
function text2(value, limit = 256) {
|
|
18037
18370
|
return typeof value === "string" && value.length > 0 && value.length <= limit;
|
|
18038
18371
|
}
|
|
18039
18372
|
function piWorkflowSummary(result) {
|
|
@@ -18041,15 +18374,15 @@ function piWorkflowSummary(result) {
|
|
|
18041
18374
|
return null;
|
|
18042
18375
|
const details = result.details;
|
|
18043
18376
|
const summary = details.workflowChildren;
|
|
18044
|
-
if (!record2(summary) || summary.version !== 1 || !
|
|
18377
|
+
if (!record2(summary) || summary.version !== 1 || !text2(summary.workflowRunId) || summary.workflowRunId !== details.runId || !text2(summary.parentToolCallId) || typeof summary.inventoryComplete !== "boolean" || !Array.isArray(summary.children) || summary.children.length > 256)
|
|
18045
18378
|
return null;
|
|
18046
18379
|
const children = [];
|
|
18047
18380
|
const seen = /* @__PURE__ */ new Set();
|
|
18048
18381
|
for (const child of summary.children) {
|
|
18049
|
-
if (!record2(child) || !
|
|
18382
|
+
if (!record2(child) || !text2(child.childId) || seen.has(child.childId) || typeof child.state !== "string" || !Object.hasOwn(STATES, child.state))
|
|
18050
18383
|
return null;
|
|
18051
18384
|
for (const key of ["agent", "sessionName", "model", "thinking"]) {
|
|
18052
|
-
if (child[key] !== void 0 && !
|
|
18385
|
+
if (child[key] !== void 0 && !text2(child[key], 2048))
|
|
18053
18386
|
return null;
|
|
18054
18387
|
}
|
|
18055
18388
|
const mappedState = STATES[child.state];
|
|
@@ -18073,15 +18406,15 @@ function piWorkflowSummary(result) {
|
|
|
18073
18406
|
};
|
|
18074
18407
|
}
|
|
18075
18408
|
function piWorkflowSubagentId(address) {
|
|
18076
|
-
return
|
|
18409
|
+
return PREFIX2 + Buffer.from(JSON.stringify([address.workflowRunId, address.childId])).toString("base64url");
|
|
18077
18410
|
}
|
|
18078
18411
|
function parsePiWorkflowSubagentId(id) {
|
|
18079
|
-
if (!id.startsWith(
|
|
18412
|
+
if (!id.startsWith(PREFIX2))
|
|
18080
18413
|
return null;
|
|
18081
18414
|
if (id.length > 3e3)
|
|
18082
18415
|
throw new Error("Invalid Pi workflow child identity");
|
|
18083
|
-
const value = JSON.parse(Buffer.from(id.slice(
|
|
18084
|
-
if (!Array.isArray(value) || value.length !== 2 || !
|
|
18416
|
+
const value = JSON.parse(Buffer.from(id.slice(PREFIX2.length), "base64url").toString("utf8"));
|
|
18417
|
+
if (!Array.isArray(value) || value.length !== 2 || !text2(value[0]) || !text2(value[1]))
|
|
18085
18418
|
throw new Error("Invalid Pi workflow child identity");
|
|
18086
18419
|
const address = { workflowRunId: value[0], childId: value[1] };
|
|
18087
18420
|
if (piWorkflowSubagentId(address) !== id)
|
|
@@ -18239,8 +18572,13 @@ var PiSubagents = class {
|
|
|
18239
18572
|
#children = /* @__PURE__ */ new Map();
|
|
18240
18573
|
#active = /* @__PURE__ */ new Map();
|
|
18241
18574
|
#waiting = /* @__PURE__ */ new Map();
|
|
18575
|
+
gotgenes;
|
|
18242
18576
|
constructor(emit) {
|
|
18243
18577
|
this.emit = emit;
|
|
18578
|
+
this.gotgenes = new GotgenesSubagents(emit);
|
|
18579
|
+
}
|
|
18580
|
+
observeGotgenes(records, activeTurn) {
|
|
18581
|
+
this.gotgenes.observe(records, true, activeTurn, true);
|
|
18244
18582
|
}
|
|
18245
18583
|
observe(runs) {
|
|
18246
18584
|
this.#apply(runs, true);
|
|
@@ -18294,6 +18632,9 @@ var PiSubagents = class {
|
|
|
18294
18632
|
}
|
|
18295
18633
|
}
|
|
18296
18634
|
project(toolName, result, itemId2, callId) {
|
|
18635
|
+
const gotgenes = this.gotgenes.project(toolName, result, itemId2);
|
|
18636
|
+
if (gotgenes)
|
|
18637
|
+
return gotgenes;
|
|
18297
18638
|
const workflow = toolName === "subagent" ? piWorkflowSummary(result) : null;
|
|
18298
18639
|
if (workflow && (!callId || workflow.parentToolCallId === callId))
|
|
18299
18640
|
return projectPiWorkflow(workflow, itemId2);
|
|
@@ -18304,6 +18645,8 @@ var PiSubagents = class {
|
|
|
18304
18645
|
return children.length ? { type: "subagentDelegation", itemId: itemId2, operation: "spawn", subagents: children } : null;
|
|
18305
18646
|
}
|
|
18306
18647
|
start(turnId, toolName, result, itemId2, callId) {
|
|
18648
|
+
if (this.gotgenes.start(turnId, toolName, result, itemId2))
|
|
18649
|
+
return;
|
|
18307
18650
|
const workflow = toolName === "subagent" ? piWorkflowSummary(result) : null;
|
|
18308
18651
|
if (workflow && (!callId || workflow.parentToolCallId === callId)) {
|
|
18309
18652
|
const key = `workflow:${workflow.workflowRunId}`;
|
|
@@ -18349,6 +18692,7 @@ var PiSubagents = class {
|
|
|
18349
18692
|
this.emit({ type: "item.started", turnId, item });
|
|
18350
18693
|
}
|
|
18351
18694
|
finish(turnId) {
|
|
18695
|
+
this.gotgenes.finish(turnId);
|
|
18352
18696
|
for (const [runId, waiting] of this.#waiting) {
|
|
18353
18697
|
if (waiting.turnId === turnId)
|
|
18354
18698
|
this.#waiting.delete(runId);
|
|
@@ -18396,15 +18740,15 @@ ${entry.text}`);
|
|
|
18396
18740
|
nativeTurnRef: nativeTurnRefSchema.parse({
|
|
18397
18741
|
harnessId: "pi",
|
|
18398
18742
|
nativeSessionId: parentSessionId,
|
|
18399
|
-
nativeTurnKey: `pi-subagent-${
|
|
18743
|
+
nativeTurnKey: `pi-subagent-${createHash3("sha256").update(id).digest("hex")}`,
|
|
18400
18744
|
formatVersion: 1
|
|
18401
18745
|
}),
|
|
18402
18746
|
input: reply.task ? [{ type: "text", text: reply.task }] : [],
|
|
18403
|
-
items: texts.map((
|
|
18747
|
+
items: texts.map((text3, index) => ({
|
|
18404
18748
|
item: {
|
|
18405
18749
|
type: "agentMessage",
|
|
18406
|
-
text:
|
|
18407
|
-
itemId: hostItemIdSchema.parse(`pi-subagent-${
|
|
18750
|
+
text: text3,
|
|
18751
|
+
itemId: hostItemIdSchema.parse(`pi-subagent-${createHash3("sha256").update(`${id}:${index}:${text3}`).digest("hex")}`)
|
|
18408
18752
|
},
|
|
18409
18753
|
outcome: { status: "succeeded" }
|
|
18410
18754
|
})),
|
|
@@ -18552,22 +18896,149 @@ function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, e
|
|
|
18552
18896
|
});
|
|
18553
18897
|
}
|
|
18554
18898
|
|
|
18899
|
+
// dist/pi-progress.js
|
|
18900
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
18901
|
+
function record4(value) {
|
|
18902
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18903
|
+
}
|
|
18904
|
+
function textContent(content) {
|
|
18905
|
+
if (typeof content === "string")
|
|
18906
|
+
return content;
|
|
18907
|
+
if (!Array.isArray(content))
|
|
18908
|
+
return "";
|
|
18909
|
+
return content.filter((part) => record4(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
|
|
18910
|
+
}
|
|
18911
|
+
function boundedPiProgress(text3) {
|
|
18912
|
+
const limit = 64e3;
|
|
18913
|
+
return text3.length <= limit ? text3 : `${text3.slice(0, limit)}
|
|
18914
|
+
[Pi notification truncated]`;
|
|
18915
|
+
}
|
|
18916
|
+
function visibleText(text3) {
|
|
18917
|
+
return text3.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
18918
|
+
}
|
|
18919
|
+
function noticeDisplay(value, fallback) {
|
|
18920
|
+
if (!record4(value) || !record4(value.details) || typeof value.details.summary !== "string")
|
|
18921
|
+
return visibleText(fallback);
|
|
18922
|
+
const details = value.details;
|
|
18923
|
+
const parts = [visibleText(details.summary)];
|
|
18924
|
+
if (typeof details.exitCode === "number")
|
|
18925
|
+
parts.push(`Exit code: ${details.exitCode}`);
|
|
18926
|
+
for (const key of ["signal", "error", "errorMessage"])
|
|
18927
|
+
if (typeof details[key] === "string" && details[key])
|
|
18928
|
+
parts.push(`${key}: ${visibleText(details[key])}`);
|
|
18929
|
+
if (record4(details.logMatch) && typeof details.logMatch.line === "string")
|
|
18930
|
+
parts.push(`Log: ${visibleText(details.logMatch.line)}`);
|
|
18931
|
+
if (typeof details.command === "string" && details.command)
|
|
18932
|
+
parts.push(`Command: ${visibleText(details.command)}`);
|
|
18933
|
+
return parts.join("\n\n");
|
|
18934
|
+
}
|
|
18935
|
+
function piCustomNoticeKey(value) {
|
|
18936
|
+
if (!record4(value) || value.type !== "custom_message" && value.role !== "custom" || value.display !== true || typeof value.customType !== "string")
|
|
18937
|
+
return null;
|
|
18938
|
+
const text3 = textContent(value.content);
|
|
18939
|
+
if (text3.trim().length === 0)
|
|
18940
|
+
return null;
|
|
18941
|
+
return JSON.stringify([value.customType, text3]);
|
|
18942
|
+
}
|
|
18943
|
+
function piCustomNotice(value, sessionId, occurrences) {
|
|
18944
|
+
const key = piCustomNoticeKey(value);
|
|
18945
|
+
if (!key)
|
|
18946
|
+
return null;
|
|
18947
|
+
const occurrence = occurrences.get(key) ?? 0;
|
|
18948
|
+
occurrences.set(key, occurrence + 1);
|
|
18949
|
+
const digest = createHash4("sha256").update(JSON.stringify([sessionId, key, occurrence])).digest("hex");
|
|
18950
|
+
const [customType, text3] = JSON.parse(key);
|
|
18951
|
+
return {
|
|
18952
|
+
type: "progress.message",
|
|
18953
|
+
itemId: hostItemIdSchema.parse(`pi-notice-v1-${digest}`),
|
|
18954
|
+
text: boundedPiProgress(`Pi notification (${visibleText(customType)})
|
|
18955
|
+
|
|
18956
|
+
${noticeDisplay(value, text3)}`)
|
|
18957
|
+
};
|
|
18958
|
+
}
|
|
18959
|
+
function piHistoryNotices(sessionId, entries) {
|
|
18960
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
18961
|
+
const notices = /* @__PURE__ */ new Map();
|
|
18962
|
+
for (const entry of entries) {
|
|
18963
|
+
const notice = piCustomNotice(entry.message ?? entry, sessionId, occurrences);
|
|
18964
|
+
if (notice)
|
|
18965
|
+
notices.set(entry.id, notice);
|
|
18966
|
+
}
|
|
18967
|
+
return { notices, occurrences };
|
|
18968
|
+
}
|
|
18969
|
+
function piStatusText(value) {
|
|
18970
|
+
if (value.type === "auto_retry_start") {
|
|
18971
|
+
const attempt = typeof value.attempt === "number" ? ` ${value.attempt}` : "";
|
|
18972
|
+
const maximum = typeof value.maxAttempts === "number" ? `/${value.maxAttempts}` : "";
|
|
18973
|
+
const delay2 = typeof value.delayMs === "number" && value.delayMs >= 0 ? ` Waiting ${value.delayMs / 1e3} s before retrying.` : "";
|
|
18974
|
+
const reason = typeof value.errorMessage === "string" ? `
|
|
18975
|
+
|
|
18976
|
+
${visibleText(value.errorMessage)}` : "";
|
|
18977
|
+
return boundedPiProgress(`Pi retry${attempt}${maximum}.${delay2}${reason}`);
|
|
18978
|
+
}
|
|
18979
|
+
if (value.type === "auto_retry_end") {
|
|
18980
|
+
if (typeof value.success !== "boolean")
|
|
18981
|
+
return null;
|
|
18982
|
+
const reason = typeof value.finalError === "string" ? `
|
|
18983
|
+
|
|
18984
|
+
${visibleText(value.finalError)}` : "";
|
|
18985
|
+
return boundedPiProgress(`Pi retry ${value.success ? "succeeded" : "ended without success"}.${reason}`);
|
|
18986
|
+
}
|
|
18987
|
+
if (value.type !== "extension_ui_request")
|
|
18988
|
+
return null;
|
|
18989
|
+
if (value.method === "notify" && typeof value.message === "string" && value.message.trim()) {
|
|
18990
|
+
const level = typeof value.notifyType === "string" ? ` (${value.notifyType})` : "";
|
|
18991
|
+
return boundedPiProgress(`Pi notification${level}
|
|
18992
|
+
|
|
18993
|
+
${visibleText(value.message)}`);
|
|
18994
|
+
}
|
|
18995
|
+
if (value.method === "setStatus" && typeof value.statusKey === "string") {
|
|
18996
|
+
return typeof value.statusText === "string" && value.statusText.trim() ? boundedPiProgress(`Pi status (${visibleText(value.statusKey)})
|
|
18997
|
+
|
|
18998
|
+
${visibleText(value.statusText)}`) : `Pi status (${visibleText(value.statusKey)}) cleared.`;
|
|
18999
|
+
}
|
|
19000
|
+
return null;
|
|
19001
|
+
}
|
|
19002
|
+
|
|
19003
|
+
// dist/pi-tool-command.js
|
|
19004
|
+
function record5(value) {
|
|
19005
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19006
|
+
}
|
|
19007
|
+
function stringField(value, key) {
|
|
19008
|
+
if (!record5(value))
|
|
19009
|
+
return void 0;
|
|
19010
|
+
for (const source of [value, value.input, value.arguments]) {
|
|
19011
|
+
if (record5(source) && typeof source[key] === "string" && source[key].length > 0)
|
|
19012
|
+
return source[key];
|
|
19013
|
+
}
|
|
19014
|
+
return void 0;
|
|
19015
|
+
}
|
|
19016
|
+
function piToolCommand(name, arguments_) {
|
|
19017
|
+
if (!["bash", "exec", "terminal", "run"].includes(name.toLowerCase()))
|
|
19018
|
+
return null;
|
|
19019
|
+
const command = ["command", "cmd", "script", "commandLine", "command_line"].map((key) => stringField(arguments_, key)).find((value) => value !== void 0);
|
|
19020
|
+
if (!command)
|
|
19021
|
+
return null;
|
|
19022
|
+
const cwd = stringField(arguments_, "cwd");
|
|
19023
|
+
return { command, ...cwd ? { cwd } : {} };
|
|
19024
|
+
}
|
|
19025
|
+
|
|
18555
19026
|
// dist/pi-history.js
|
|
18556
19027
|
var piHarnessId = harnessIdSchema.parse("pi");
|
|
18557
|
-
function
|
|
19028
|
+
function isRecord5(value) {
|
|
18558
19029
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18559
19030
|
}
|
|
18560
|
-
function
|
|
19031
|
+
function textContent2(value) {
|
|
18561
19032
|
if (typeof value === "string")
|
|
18562
19033
|
return value;
|
|
18563
19034
|
if (!Array.isArray(value))
|
|
18564
19035
|
return "";
|
|
18565
|
-
return value.filter((part) =>
|
|
19036
|
+
return value.filter((part) => isRecord5(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
|
|
18566
19037
|
}
|
|
18567
19038
|
function thinkingContent(value) {
|
|
18568
19039
|
if (!Array.isArray(value))
|
|
18569
19040
|
return "";
|
|
18570
|
-
return value.filter((part) =>
|
|
19041
|
+
return value.filter((part) => isRecord5(part) && part.type === "thinking" && typeof part.thinking === "string").map((part) => part.thinking).join("");
|
|
18571
19042
|
}
|
|
18572
19043
|
function validatedEntry(value) {
|
|
18573
19044
|
if (typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
|
|
@@ -18598,7 +19069,7 @@ function activePiEntries(history) {
|
|
|
18598
19069
|
return reversed.reverse();
|
|
18599
19070
|
}
|
|
18600
19071
|
function message(entry) {
|
|
18601
|
-
return entry.type === "message" &&
|
|
19072
|
+
return entry.type === "message" && isRecord5(entry.message) ? entry.message : null;
|
|
18602
19073
|
}
|
|
18603
19074
|
function messageRole(entry) {
|
|
18604
19075
|
const value = message(entry)?.role;
|
|
@@ -18613,7 +19084,7 @@ function assistantOutcome(entries) {
|
|
|
18613
19084
|
if (!final)
|
|
18614
19085
|
return { status: "unknown", reason: "Pi history has no Assistant terminal" };
|
|
18615
19086
|
const stopReason = final.stopReason;
|
|
18616
|
-
if (
|
|
19087
|
+
if (piAssistantWasAborted(final)) {
|
|
18617
19088
|
return { status: "cancelled", reason: "Pi Assistant was aborted" };
|
|
18618
19089
|
}
|
|
18619
19090
|
if (stopReason === "error") {
|
|
@@ -18626,7 +19097,7 @@ function assistantOutcome(entries) {
|
|
|
18626
19097
|
}
|
|
18627
19098
|
};
|
|
18628
19099
|
}
|
|
18629
|
-
if (typeof stopReason === "string" ||
|
|
19100
|
+
if (typeof stopReason === "string" || textContent2(final.content).length > 0) {
|
|
18630
19101
|
return { status: "succeeded" };
|
|
18631
19102
|
}
|
|
18632
19103
|
return { status: "unknown", reason: "Pi Assistant terminal is not classifiable" };
|
|
@@ -18643,8 +19114,8 @@ function itemOutcome(outcome) {
|
|
|
18643
19114
|
return { status: "succeeded" };
|
|
18644
19115
|
}
|
|
18645
19116
|
function toolOutput(value) {
|
|
18646
|
-
const
|
|
18647
|
-
return
|
|
19117
|
+
const text3 = textContent2(value);
|
|
19118
|
+
return text3.length > 0 ? { content: [{ type: "text", text: text3 }] } : void 0;
|
|
18648
19119
|
}
|
|
18649
19120
|
function historicalFileChanges(call, nativeMessage, toolItemId, cwd) {
|
|
18650
19121
|
const items = [];
|
|
@@ -18667,37 +19138,52 @@ function historicalFileChanges(call, nativeMessage, toolItemId, cwd) {
|
|
|
18667
19138
|
}
|
|
18668
19139
|
return items;
|
|
18669
19140
|
}
|
|
18670
|
-
function snapshotItems(entries, outcome, subagents, cwd) {
|
|
19141
|
+
function snapshotItems(entries, messageIdentities, notices, outcome, subagents, cwd) {
|
|
18671
19142
|
const snapshots = [];
|
|
18672
19143
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
18673
19144
|
for (const entry of entries) {
|
|
19145
|
+
const notice = notices.get(entry.id);
|
|
19146
|
+
if (notice) {
|
|
19147
|
+
snapshots.push({
|
|
19148
|
+
item: {
|
|
19149
|
+
type: "agentMessage",
|
|
19150
|
+
itemId: notice.itemId,
|
|
19151
|
+
text: notice.text,
|
|
19152
|
+
phase: "commentary"
|
|
19153
|
+
},
|
|
19154
|
+
outcome: { status: "succeeded" }
|
|
19155
|
+
});
|
|
19156
|
+
continue;
|
|
19157
|
+
}
|
|
18674
19158
|
const nativeMessage = message(entry);
|
|
18675
19159
|
if (!nativeMessage)
|
|
18676
19160
|
continue;
|
|
18677
19161
|
const content = Array.isArray(nativeMessage.content) ? nativeMessage.content : [];
|
|
18678
19162
|
if (nativeMessage.role === "assistant") {
|
|
18679
|
-
const
|
|
19163
|
+
const text3 = textContent2(content);
|
|
18680
19164
|
const reasoning = thinkingContent(content);
|
|
18681
19165
|
let projectedText = false;
|
|
18682
19166
|
let projectedReasoning = false;
|
|
18683
19167
|
for (const [ordinal, part] of content.entries()) {
|
|
18684
|
-
if (!
|
|
19168
|
+
if (!isRecord5(part))
|
|
18685
19169
|
continue;
|
|
18686
19170
|
if (part.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
|
|
18687
19171
|
const item2 = {
|
|
18688
19172
|
type: "reasoning",
|
|
18689
|
-
itemId: itemId(entry.id, "reasoning", 0),
|
|
19173
|
+
itemId: piMessageItemId(messageIdentities.get(entry.id), "reasoning") ?? itemId(entry.id, "reasoning", 0),
|
|
18690
19174
|
text: reasoning
|
|
18691
19175
|
};
|
|
18692
19176
|
snapshots.push({ item: item2, outcome: itemOutcome(outcome) });
|
|
18693
19177
|
projectedReasoning = true;
|
|
18694
19178
|
continue;
|
|
18695
19179
|
}
|
|
18696
|
-
if (part.type === "text" && !projectedText &&
|
|
19180
|
+
if (part.type === "text" && !projectedText && text3.length > 0) {
|
|
19181
|
+
const phase = piAssistantPhase(nativeMessage);
|
|
18697
19182
|
const item2 = {
|
|
18698
19183
|
type: "agentMessage",
|
|
18699
|
-
itemId: itemId(entry.id, "assistant", 0),
|
|
18700
|
-
text:
|
|
19184
|
+
itemId: piMessageItemId(messageIdentities.get(entry.id), "assistant") ?? itemId(entry.id, "assistant", 0),
|
|
19185
|
+
text: text3,
|
|
19186
|
+
...phase ? { phase } : {}
|
|
18701
19187
|
};
|
|
18702
19188
|
snapshots.push({ item: item2, outcome: itemOutcome(outcome) });
|
|
18703
19189
|
projectedText = true;
|
|
@@ -18725,9 +19211,24 @@ function snapshotItems(entries, outcome, subagents, cwd) {
|
|
|
18725
19211
|
if (!call || call.name !== nativeMessage.toolName)
|
|
18726
19212
|
continue;
|
|
18727
19213
|
const output = toolOutput(nativeMessage.content);
|
|
18728
|
-
const
|
|
18729
|
-
|
|
19214
|
+
const shell = piToolCommand(call.name, call.arguments);
|
|
19215
|
+
const commandCwd = shell?.cwd ?? cwd;
|
|
19216
|
+
const durationMs = typeof nativeMessage.durationMs === "number" && Number.isFinite(nativeMessage.durationMs) && nativeMessage.durationMs >= 0 ? nativeMessage.durationMs : void 0;
|
|
19217
|
+
const base = {
|
|
18730
19218
|
itemId: itemId(call.entryId, "tool", call.ordinal),
|
|
19219
|
+
...durationMs !== void 0 ? { durationMs } : {}
|
|
19220
|
+
};
|
|
19221
|
+
const exitCode = typeof nativeMessage.exitCode === "number" && Number.isInteger(nativeMessage.exitCode) ? nativeMessage.exitCode : void 0;
|
|
19222
|
+
const item = shell ? {
|
|
19223
|
+
...base,
|
|
19224
|
+
type: "commandExecution",
|
|
19225
|
+
command: shell.command,
|
|
19226
|
+
...commandCwd ? { cwd: commandCwd } : {},
|
|
19227
|
+
...output ? { output: textContent2(nativeMessage.content) } : {},
|
|
19228
|
+
...exitCode !== void 0 ? { exitCode } : {}
|
|
19229
|
+
} : {
|
|
19230
|
+
...base,
|
|
19231
|
+
type: "toolExecution",
|
|
18731
19232
|
toolName: call.name,
|
|
18732
19233
|
arguments: call.arguments,
|
|
18733
19234
|
...output ? { output } : {}
|
|
@@ -18758,6 +19259,10 @@ function snapshotItems(entries, outcome, subagents, cwd) {
|
|
|
18758
19259
|
function modelChange(entry) {
|
|
18759
19260
|
return entry.type === "model_change" && typeof entry.provider === "string" && typeof entry.modelId === "string" ? { provider: entry.provider, id: entry.modelId } : null;
|
|
18760
19261
|
}
|
|
19262
|
+
function isEmptyWakeup(entry) {
|
|
19263
|
+
const content = message(entry)?.content;
|
|
19264
|
+
return content === "" || Array.isArray(content) && content.every((part) => isRecord5(part) && part.type === "text" && part.text === "");
|
|
19265
|
+
}
|
|
18761
19266
|
function turnStarts(active) {
|
|
18762
19267
|
const starts = [];
|
|
18763
19268
|
let terminal = true;
|
|
@@ -18765,6 +19270,8 @@ function turnStarts(active) {
|
|
|
18765
19270
|
for (const [index, entry] of active.entries()) {
|
|
18766
19271
|
const role = messageRole(entry);
|
|
18767
19272
|
if (role === "user") {
|
|
19273
|
+
if (pending && isEmptyWakeup(entry))
|
|
19274
|
+
continue;
|
|
18768
19275
|
starts.push({ entry, index });
|
|
18769
19276
|
pending = null;
|
|
18770
19277
|
terminal = false;
|
|
@@ -18781,6 +19288,8 @@ function turnStarts(active) {
|
|
|
18781
19288
|
}
|
|
18782
19289
|
function mapPiSnapshot(history, state2, subagents = new PiSubagents(() => void 0)) {
|
|
18783
19290
|
const active = activePiEntries(history);
|
|
19291
|
+
const { identities } = piHistoryMessageIdentities(state2.sessionId, active);
|
|
19292
|
+
const { notices } = piHistoryNotices(state2.sessionId, active);
|
|
18784
19293
|
const turns = [];
|
|
18785
19294
|
const starts = turnStarts(active);
|
|
18786
19295
|
const byIndex = new Map(starts.map((start, ordinal) => [start.index, ordinal]));
|
|
@@ -18802,7 +19311,7 @@ function mapPiSnapshot(history, state2, subagents = new PiSubagents(() => void 0
|
|
|
18802
19311
|
const end = next?.index ?? active.length;
|
|
18803
19312
|
const entries = active.slice(index, end);
|
|
18804
19313
|
const outcome = assistantOutcome(entries);
|
|
18805
|
-
const userText =
|
|
19314
|
+
const userText = textContent2(message(user)?.content);
|
|
18806
19315
|
const nativeTurnRef = nativeTurnRefSchema.parse({
|
|
18807
19316
|
harnessId: piHarnessId,
|
|
18808
19317
|
nativeSessionId: state2.sessionId,
|
|
@@ -18819,7 +19328,7 @@ function mapPiSnapshot(history, state2, subagents = new PiSubagents(() => void 0
|
|
|
18819
19328
|
nativeTurnRef,
|
|
18820
19329
|
...!next || messageRole(next.entry) === "user" ? { checkpoint } : {},
|
|
18821
19330
|
input: messageRole(user) === "user" ? [{ type: "text", text: userText }] : [],
|
|
18822
|
-
items: snapshotItems(entries, outcome, subagents, state2.cwd),
|
|
19331
|
+
items: snapshotItems(entries, identities, notices, outcome, subagents, state2.cwd),
|
|
18823
19332
|
outcome,
|
|
18824
19333
|
...effectiveModel ? { model: encodePiModelRef(effectiveModel) } : {}
|
|
18825
19334
|
});
|
|
@@ -18854,14 +19363,14 @@ function resolvePiForkBoundary(history, checkpointId) {
|
|
|
18854
19363
|
}
|
|
18855
19364
|
|
|
18856
19365
|
// dist/pi-usage.js
|
|
18857
|
-
function
|
|
19366
|
+
function isRecord6(value) {
|
|
18858
19367
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18859
19368
|
}
|
|
18860
19369
|
function nonNegativeSafeInteger(value) {
|
|
18861
19370
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
18862
19371
|
}
|
|
18863
19372
|
function optionalPiCacheHitRatePercent(value) {
|
|
18864
|
-
if (!
|
|
19373
|
+
if (!isRecord6(value) || value.role !== "assistant" || !isRecord6(value.usage))
|
|
18865
19374
|
return null;
|
|
18866
19375
|
const input = nonNegativeSafeInteger(value.usage.input);
|
|
18867
19376
|
const cacheRead = nonNegativeSafeInteger(value.usage.cacheRead);
|
|
@@ -18874,20 +19383,20 @@ function optionalPiCacheHitRatePercent(value) {
|
|
|
18874
19383
|
function latestPiCacheHitRatePercent(history) {
|
|
18875
19384
|
let latest = null;
|
|
18876
19385
|
for (const entry of activePiEntries(history)) {
|
|
18877
|
-
if (entry.type === "message" &&
|
|
19386
|
+
if (entry.type === "message" && isRecord6(entry.message) && entry.message.role === "assistant") {
|
|
18878
19387
|
latest = optionalPiCacheHitRatePercent(entry.message);
|
|
18879
19388
|
}
|
|
18880
19389
|
}
|
|
18881
19390
|
return latest;
|
|
18882
19391
|
}
|
|
18883
19392
|
function responseData(response, operation) {
|
|
18884
|
-
if (!
|
|
19393
|
+
if (!isRecord6(response.data)) {
|
|
18885
19394
|
throw new Error(`Pi RPC ${operation} response has no data`);
|
|
18886
19395
|
}
|
|
18887
19396
|
return response.data;
|
|
18888
19397
|
}
|
|
18889
19398
|
function contextUsage(value) {
|
|
18890
|
-
if (!
|
|
19399
|
+
if (!isRecord6(value))
|
|
18891
19400
|
throw new Error("Pi RPC context Usage is invalid");
|
|
18892
19401
|
return parseHostUsage({
|
|
18893
19402
|
contextUsedTokens: value.tokens,
|
|
@@ -18897,15 +19406,15 @@ function contextUsage(value) {
|
|
|
18897
19406
|
function parsePiSessionUsage(response) {
|
|
18898
19407
|
const data = responseData(response, "Session stats");
|
|
18899
19408
|
const tokens = data.tokens;
|
|
18900
|
-
if (tokens !== void 0 && !
|
|
19409
|
+
if (tokens !== void 0 && !isRecord6(tokens)) {
|
|
18901
19410
|
throw new Error("Pi RPC Session stats tokens are invalid");
|
|
18902
19411
|
}
|
|
18903
19412
|
return parseHostUsage({
|
|
18904
|
-
...
|
|
18905
|
-
...
|
|
18906
|
-
...
|
|
18907
|
-
...
|
|
18908
|
-
...
|
|
19413
|
+
...isRecord6(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
|
|
19414
|
+
...isRecord6(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
|
|
19415
|
+
...isRecord6(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
|
|
19416
|
+
...isRecord6(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
|
|
19417
|
+
...isRecord6(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
|
|
18909
19418
|
...data.cost !== void 0 ? { totalCostUsd: data.cost } : {},
|
|
18910
19419
|
...data.contextUsage !== void 0 ? contextUsage(data.contextUsage) : {}
|
|
18911
19420
|
});
|
|
@@ -18924,9 +19433,9 @@ function optionalPiStateContextUsage(value) {
|
|
|
18924
19433
|
}
|
|
18925
19434
|
}
|
|
18926
19435
|
function piUsageRecord(message3, extra = {}) {
|
|
18927
|
-
if (!
|
|
19436
|
+
if (!isRecord6(message3) || message3.role !== "assistant")
|
|
18928
19437
|
return null;
|
|
18929
|
-
const usage =
|
|
19438
|
+
const usage = isRecord6(message3.usage) ? message3.usage : null;
|
|
18930
19439
|
const input = nonNegativeSafeInteger(usage?.input);
|
|
18931
19440
|
const output = nonNegativeSafeInteger(usage?.output);
|
|
18932
19441
|
const requestId = typeof message3.responseId === "string" && message3.responseId.length > 0 ? message3.responseId : typeof message3.timestamp === "number" && Number.isSafeInteger(message3.timestamp) ? `t${message3.timestamp}` : null;
|
|
@@ -18963,17 +19472,17 @@ function piUsageHistory(history) {
|
|
|
18963
19472
|
for (const entry of history.entries) {
|
|
18964
19473
|
if (entry.type !== "message")
|
|
18965
19474
|
continue;
|
|
18966
|
-
const
|
|
18967
|
-
if (
|
|
18968
|
-
requests.push(
|
|
18969
|
-
else if (
|
|
19475
|
+
const record9 = piUsageRecord(entry.message, { historical: true });
|
|
19476
|
+
if (record9?.kind === "request")
|
|
19477
|
+
requests.push(record9.request);
|
|
19478
|
+
else if (record9?.kind === "missing")
|
|
18970
19479
|
complete = false;
|
|
18971
19480
|
}
|
|
18972
19481
|
return { requests, complete };
|
|
18973
19482
|
}
|
|
18974
19483
|
|
|
18975
19484
|
// dist/pi-usage-statistics.js
|
|
18976
|
-
function
|
|
19485
|
+
function isRecord7(value) {
|
|
18977
19486
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18978
19487
|
}
|
|
18979
19488
|
function piUserText(content) {
|
|
@@ -18981,11 +19490,11 @@ function piUserText(content) {
|
|
|
18981
19490
|
return content;
|
|
18982
19491
|
if (!Array.isArray(content))
|
|
18983
19492
|
return void 0;
|
|
18984
|
-
return content.filter((block) =>
|
|
19493
|
+
return content.filter((block) => isRecord7(block) && block.type === "text" && typeof block.text === "string").map((block) => String(block.text)).join(" ");
|
|
18985
19494
|
}
|
|
18986
19495
|
async function readPiUsage(file2, signal) {
|
|
18987
19496
|
const entries = [];
|
|
18988
|
-
const header = await jsonlHeader(file2, (
|
|
19497
|
+
const header = await jsonlHeader(file2, (record9) => record9.type === "session", signal);
|
|
18989
19498
|
let name;
|
|
18990
19499
|
const session = {
|
|
18991
19500
|
sessionId: typeof header?.id === "string" ? header.id : void 0,
|
|
@@ -19002,11 +19511,11 @@ async function readPiUsage(file2, signal) {
|
|
|
19002
19511
|
if (!name && message3?.role === "user") {
|
|
19003
19512
|
name = usageSessionTitle(piUserText(message3.content));
|
|
19004
19513
|
}
|
|
19005
|
-
const
|
|
19006
|
-
if (
|
|
19514
|
+
const record9 = piUsageRecord(line.message);
|
|
19515
|
+
if (record9?.kind !== "request")
|
|
19007
19516
|
continue;
|
|
19008
19517
|
const at = nativeTimeMs(message3.timestamp) ?? nativeTimeMs(line.timestamp);
|
|
19009
|
-
const entry = at !== null && usageEntryFromRequest(
|
|
19518
|
+
const entry = at !== null && usageEntryFromRequest(record9.request, at);
|
|
19010
19519
|
if (!entry)
|
|
19011
19520
|
continue;
|
|
19012
19521
|
if (!(typeof message3.responseId === "string" && message3.responseId.length > 0)) {
|
|
@@ -19027,9 +19536,9 @@ function createPiUsageStatistics(environment) {
|
|
|
19027
19536
|
}
|
|
19028
19537
|
|
|
19029
19538
|
// dist/account-balance.js
|
|
19030
|
-
import { readFile } from "node:fs/promises";
|
|
19031
|
-
import { homedir as
|
|
19032
|
-
import
|
|
19539
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
19540
|
+
import { homedir as homedir3 } from "node:os";
|
|
19541
|
+
import path8 from "node:path";
|
|
19033
19542
|
var DEEPSEEK_BALANCE_ENDPOINT = "https://api.deepseek.com/user/balance";
|
|
19034
19543
|
var SUB2API_USAGE_PATH = "/v1/usage";
|
|
19035
19544
|
var REQUEST_TIMEOUT_MS = 1e4;
|
|
@@ -19038,18 +19547,18 @@ function agentDirectory(environment) {
|
|
|
19038
19547
|
const configured = environment.PI_CODING_AGENT_DIR?.trim();
|
|
19039
19548
|
if (configured)
|
|
19040
19549
|
return configured;
|
|
19041
|
-
return
|
|
19550
|
+
return path8.join(environment.HOME ?? environment.USERPROFILE ?? homedir3(), ".pi", "agent");
|
|
19042
19551
|
}
|
|
19043
|
-
var
|
|
19552
|
+
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
19044
19553
|
async function deepSeekApiKey(environment) {
|
|
19045
|
-
const auth =
|
|
19046
|
-
const deepseek =
|
|
19554
|
+
const auth = record6(JSON.parse(await readFile2(path8.join(agentDirectory(environment), "auth.json"), "utf8")));
|
|
19555
|
+
const deepseek = record6(auth.deepseek);
|
|
19047
19556
|
if (deepseek.type !== "api_key")
|
|
19048
19557
|
return void 0;
|
|
19049
19558
|
return typeof deepseek.key === "string" && deepseek.key.trim() ? deepseek.key : void 0;
|
|
19050
19559
|
}
|
|
19051
19560
|
function projectSub2ApiUsage(payload, providerId) {
|
|
19052
|
-
const data =
|
|
19561
|
+
const data = record6(payload);
|
|
19053
19562
|
if (data.isValid === false)
|
|
19054
19563
|
return null;
|
|
19055
19564
|
if (data.mode !== "unrestricted" && data.mode !== "quota_limited")
|
|
@@ -19059,7 +19568,7 @@ function projectSub2ApiUsage(payload, providerId) {
|
|
|
19059
19568
|
return null;
|
|
19060
19569
|
const wallet = finiteAmount(data.balance);
|
|
19061
19570
|
const remaining = finiteAmount(data.remaining);
|
|
19062
|
-
const quotaRemaining = finiteAmount(
|
|
19571
|
+
const quotaRemaining = finiteAmount(record6(data.quota).remaining);
|
|
19063
19572
|
const amount = wallet ?? remaining ?? quotaRemaining;
|
|
19064
19573
|
if (amount === null)
|
|
19065
19574
|
return null;
|
|
@@ -19079,10 +19588,10 @@ function finiteAmount(value) {
|
|
|
19079
19588
|
return Number.isFinite(amount) && amount >= 0 ? amount : null;
|
|
19080
19589
|
}
|
|
19081
19590
|
function projectDeepSeekBalance(payload) {
|
|
19082
|
-
const data =
|
|
19591
|
+
const data = record6(payload);
|
|
19083
19592
|
if (!Array.isArray(data.balance_infos))
|
|
19084
19593
|
return null;
|
|
19085
|
-
const first =
|
|
19594
|
+
const first = record6(data.balance_infos[0]);
|
|
19086
19595
|
const amount = finiteAmount(first.total_balance);
|
|
19087
19596
|
const currency = typeof first.currency === "string" ? first.currency.trim() : "";
|
|
19088
19597
|
if (amount === null || !currency)
|
|
@@ -19111,11 +19620,11 @@ function usageEndpoint(baseUrl) {
|
|
|
19111
19620
|
}
|
|
19112
19621
|
async function configuredSub2ApiProviders(environment) {
|
|
19113
19622
|
try {
|
|
19114
|
-
const models =
|
|
19115
|
-
const providers =
|
|
19623
|
+
const models = record6(JSON.parse(await readFile2(path8.join(agentDirectory(environment), "models.json"), "utf8")));
|
|
19624
|
+
const providers = record6(models.providers);
|
|
19116
19625
|
const found = [];
|
|
19117
19626
|
for (const [id, definition] of Object.entries(providers)) {
|
|
19118
|
-
const provider =
|
|
19627
|
+
const provider = record6(definition);
|
|
19119
19628
|
const apiKey = typeof provider.apiKey === "string" ? provider.apiKey.trim() : "";
|
|
19120
19629
|
const baseUrl = typeof provider.baseUrl === "string" ? provider.baseUrl.trim() : "";
|
|
19121
19630
|
if (!id.trim() || id.length > 128 || !apiKey || !usageEndpoint(baseUrl))
|
|
@@ -19173,21 +19682,21 @@ async function fetchPiAccountBalance(input) {
|
|
|
19173
19682
|
}
|
|
19174
19683
|
|
|
19175
19684
|
// dist/pi-credential-imports.js
|
|
19176
|
-
import { randomUUID } from "node:crypto";
|
|
19685
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
19177
19686
|
import { execFile as execFile2 } from "node:child_process";
|
|
19178
19687
|
import { promisify } from "node:util";
|
|
19179
19688
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync, lstatSync, renameSync, rmdirSync } from "node:fs";
|
|
19180
19689
|
import { realpath as realpath2 } from "node:fs/promises";
|
|
19181
19690
|
import os4 from "node:os";
|
|
19182
|
-
import
|
|
19691
|
+
import path10 from "node:path";
|
|
19183
19692
|
import { pathToFileURL } from "node:url";
|
|
19184
19693
|
|
|
19185
19694
|
// dist/command.js
|
|
19186
19695
|
import fs2 from "node:fs";
|
|
19187
|
-
import { homedir as
|
|
19188
|
-
import
|
|
19696
|
+
import { homedir as homedir4, tmpdir as tmpdir2 } from "node:os";
|
|
19697
|
+
import path9 from "node:path";
|
|
19189
19698
|
var PI_PACKAGE_NAME = "@earendil-works/pi-coding-agent";
|
|
19190
|
-
var PI_PACKAGE_PATH =
|
|
19699
|
+
var PI_PACKAGE_PATH = path9.join("node_modules", "@earendil-works", "pi-coding-agent");
|
|
19191
19700
|
var piDiscoverySpec = {
|
|
19192
19701
|
id: "pi",
|
|
19193
19702
|
command: "pi",
|
|
@@ -19213,18 +19722,18 @@ function resolvePiExecutable(input, dependencies = {}) {
|
|
|
19213
19722
|
return resolution?.executable ?? input.command ?? input.environment.PI_COMMAND ?? "pi";
|
|
19214
19723
|
}
|
|
19215
19724
|
function findPiPackageDirectory(executable) {
|
|
19216
|
-
let directory =
|
|
19725
|
+
let directory = path9.dirname(executable);
|
|
19217
19726
|
while (true) {
|
|
19218
|
-
for (const candidate of [directory,
|
|
19727
|
+
for (const candidate of [directory, path9.join(directory, PI_PACKAGE_PATH)]) {
|
|
19219
19728
|
try {
|
|
19220
|
-
const manifest = JSON.parse(fs2.readFileSync(
|
|
19729
|
+
const manifest = JSON.parse(fs2.readFileSync(path9.join(candidate, "package.json"), "utf8"));
|
|
19221
19730
|
if (typeof manifest === "object" && manifest !== null && "name" in manifest && manifest.name === PI_PACKAGE_NAME) {
|
|
19222
19731
|
return candidate;
|
|
19223
19732
|
}
|
|
19224
19733
|
} catch {
|
|
19225
19734
|
}
|
|
19226
19735
|
}
|
|
19227
|
-
const parent =
|
|
19736
|
+
const parent = path9.dirname(directory);
|
|
19228
19737
|
if (parent === directory)
|
|
19229
19738
|
return void 0;
|
|
19230
19739
|
directory = parent;
|
|
@@ -19232,16 +19741,16 @@ function findPiPackageDirectory(executable) {
|
|
|
19232
19741
|
}
|
|
19233
19742
|
function findPiCliEntry(packageDirectory) {
|
|
19234
19743
|
try {
|
|
19235
|
-
const manifest = JSON.parse(fs2.readFileSync(
|
|
19744
|
+
const manifest = JSON.parse(fs2.readFileSync(path9.join(packageDirectory, "package.json"), "utf8"));
|
|
19236
19745
|
if (typeof manifest !== "object" || manifest === null || !("bin" in manifest))
|
|
19237
19746
|
return void 0;
|
|
19238
19747
|
const bin = manifest.bin;
|
|
19239
19748
|
const entry = typeof bin === "string" ? bin : typeof bin === "object" && bin !== null && "pi" in bin ? bin.pi : void 0;
|
|
19240
19749
|
if (typeof entry !== "string" || !entry.trim())
|
|
19241
19750
|
return void 0;
|
|
19242
|
-
const resolved =
|
|
19243
|
-
const relative =
|
|
19244
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
19751
|
+
const resolved = path9.resolve(packageDirectory, entry);
|
|
19752
|
+
const relative = path9.relative(packageDirectory, resolved);
|
|
19753
|
+
if (relative === ".." || relative.startsWith(`..${path9.sep}`) || path9.isAbsolute(relative) || !fs2.statSync(resolved).isFile()) {
|
|
19245
19754
|
return void 0;
|
|
19246
19755
|
}
|
|
19247
19756
|
return resolved;
|
|
@@ -19250,11 +19759,11 @@ function findPiCliEntry(packageDirectory) {
|
|
|
19250
19759
|
}
|
|
19251
19760
|
}
|
|
19252
19761
|
function isFilesystemRoot(cwd) {
|
|
19253
|
-
const resolved =
|
|
19254
|
-
return resolved ===
|
|
19762
|
+
const resolved = path9.resolve(cwd);
|
|
19763
|
+
return resolved === path9.parse(resolved).root;
|
|
19255
19764
|
}
|
|
19256
19765
|
function writableDirectory(candidate) {
|
|
19257
|
-
if (!candidate || !
|
|
19766
|
+
if (!candidate || !path9.isAbsolute(candidate) || isFilesystemRoot(candidate))
|
|
19258
19767
|
return void 0;
|
|
19259
19768
|
try {
|
|
19260
19769
|
if (!fs2.statSync(candidate).isDirectory())
|
|
@@ -19267,19 +19776,19 @@ function writableDirectory(candidate) {
|
|
|
19267
19776
|
}
|
|
19268
19777
|
function resolvePiInspectCwd(inputCwd, environment = process.env) {
|
|
19269
19778
|
if (typeof inputCwd === "string" && inputCwd.length > 0 && !isFilesystemRoot(inputCwd)) {
|
|
19270
|
-
return
|
|
19779
|
+
return path9.resolve(inputCwd);
|
|
19271
19780
|
}
|
|
19272
|
-
const candidates = [environment.USERPROFILE, environment.HOME,
|
|
19781
|
+
const candidates = [environment.USERPROFILE, environment.HOME, homedir4(), tmpdir2()];
|
|
19273
19782
|
for (const candidate of candidates) {
|
|
19274
19783
|
const usable = writableDirectory(candidate);
|
|
19275
19784
|
if (usable)
|
|
19276
19785
|
return usable;
|
|
19277
19786
|
}
|
|
19278
|
-
return inputCwd && inputCwd.length > 0 ?
|
|
19787
|
+
return inputCwd && inputCwd.length > 0 ? path9.resolve(inputCwd) : process.cwd();
|
|
19279
19788
|
}
|
|
19280
19789
|
|
|
19281
19790
|
// dist/pi-credential-imports.js
|
|
19282
|
-
var
|
|
19791
|
+
var PREFIX3 = "codexhost-account-";
|
|
19283
19792
|
function object2(value) {
|
|
19284
19793
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19285
19794
|
}
|
|
@@ -19320,7 +19829,7 @@ function describeOauth(credential) {
|
|
|
19320
19829
|
};
|
|
19321
19830
|
}
|
|
19322
19831
|
function writeAuth(filename, content) {
|
|
19323
|
-
const temporary = `${filename}.${
|
|
19832
|
+
const temporary = `${filename}.${randomUUID2()}.tmp`;
|
|
19324
19833
|
try {
|
|
19325
19834
|
writeFileSync(temporary, content, { flag: "wx", mode: 384 });
|
|
19326
19835
|
renameSync(temporary, filename);
|
|
@@ -19329,8 +19838,8 @@ function writeAuth(filename, content) {
|
|
|
19329
19838
|
}
|
|
19330
19839
|
}
|
|
19331
19840
|
function removeOwnedFiles(dir) {
|
|
19332
|
-
rmSync(
|
|
19333
|
-
rmSync(
|
|
19841
|
+
rmSync(path10.join(dir, "index.ts"), { force: true });
|
|
19842
|
+
rmSync(path10.join(dir, "import.json"), { force: true });
|
|
19334
19843
|
try {
|
|
19335
19844
|
rmdirSync(dir);
|
|
19336
19845
|
} catch {
|
|
@@ -19342,13 +19851,13 @@ async function installation(command, environment, authPath) {
|
|
|
19342
19851
|
const cliEntry = directory ? findPiCliEntry(directory) : void 0;
|
|
19343
19852
|
if (!directory || !cliEntry)
|
|
19344
19853
|
throw new Error("Pi credential import requires a supported npm Pi installation");
|
|
19345
|
-
const storage = await import(pathToFileURL(
|
|
19346
|
-
const ai =
|
|
19347
|
-
const all = await import(pathToFileURL(
|
|
19854
|
+
const storage = await import(pathToFileURL(path10.join(directory, "dist/core/auth-storage.js")).href);
|
|
19855
|
+
const ai = path10.join(directory, "node_modules/@earendil-works/pi-ai/dist");
|
|
19856
|
+
const all = await import(pathToFileURL(path10.join(ai, "providers/all.js")).href);
|
|
19348
19857
|
const providers = all.getBuiltinProviders();
|
|
19349
19858
|
const providerModules = {
|
|
19350
|
-
"openai-codex": pathToFileURL(
|
|
19351
|
-
xai: pathToFileURL(
|
|
19859
|
+
"openai-codex": pathToFileURL(path10.join(ai, "providers/openai-codex.js")).href,
|
|
19860
|
+
xai: pathToFileURL(path10.join(ai, "providers/xai.js")).href
|
|
19352
19861
|
};
|
|
19353
19862
|
for (const [id, url2] of Object.entries(providerModules)) {
|
|
19354
19863
|
const module = await import(url2);
|
|
@@ -19362,8 +19871,8 @@ async function installation(command, environment, authPath) {
|
|
|
19362
19871
|
reservedNames: providers.map((p) => typeof p === "string" ? p : p.id),
|
|
19363
19872
|
async configuredProviderNames() {
|
|
19364
19873
|
const { stdout } = await promisify(execFile2)(process.execPath, [cliEntry, "--offline", "--no-approve", "--list-models"], {
|
|
19365
|
-
cwd: existsSync(
|
|
19366
|
-
env: { ...environment, PI_CODING_AGENT_DIR:
|
|
19874
|
+
cwd: existsSync(path10.dirname(authPath)) ? path10.dirname(authPath) : os4.homedir(),
|
|
19875
|
+
env: { ...environment, PI_CODING_AGENT_DIR: path10.dirname(authPath), PI_OFFLINE: "1" },
|
|
19367
19876
|
timeout: 15e3,
|
|
19368
19877
|
maxBuffer: 4 * 1024 * 1024
|
|
19369
19878
|
});
|
|
@@ -19393,26 +19902,26 @@ export default async function (pi) {
|
|
|
19393
19902
|
}
|
|
19394
19903
|
function createPiCredentialImports(options = {}) {
|
|
19395
19904
|
const env = { ...process.env, ...options.environment };
|
|
19396
|
-
const agentDir = env.PI_CODING_AGENT_DIR ??
|
|
19397
|
-
const authPath =
|
|
19398
|
-
const extensionsDir =
|
|
19905
|
+
const agentDir = env.PI_CODING_AGENT_DIR ?? path10.join(env.HOME ?? os4.homedir(), ".pi/agent");
|
|
19906
|
+
const authPath = path10.join(agentDir, "auth.json");
|
|
19907
|
+
const extensionsDir = path10.join(agentDir, "extensions");
|
|
19399
19908
|
const saveAuth = (auth) => (options.writeAuth ?? writeAuth)(authPath, JSON.stringify(auth, null, 2) + "\n");
|
|
19400
19909
|
const resolve = () => options.resolveInstallation?.(authPath) ?? installation(options.command, env, authPath);
|
|
19401
|
-
const location = (name) =>
|
|
19910
|
+
const location = (name) => path10.join(extensionsDir, `${PREFIX3}${credentialImportNameSchema.parse(name)}`);
|
|
19402
19911
|
const readRecord = (name) => {
|
|
19403
19912
|
const dir = location(name);
|
|
19404
19913
|
if (lstatSync(dir).isSymbolicLink())
|
|
19405
19914
|
throw new Error("Imported configuration was changed; manage it in Pi");
|
|
19406
|
-
const value = JSON.parse(readFileSync(
|
|
19915
|
+
const value = JSON.parse(readFileSync(path10.join(dir, "import.json"), "utf8"));
|
|
19407
19916
|
if (value.version !== 1 || typeof value.owner !== "string" || typeof value.extension !== "string")
|
|
19408
19917
|
throw new Error("Invalid import metadata");
|
|
19409
|
-
const
|
|
19410
|
-
if (!object2(
|
|
19918
|
+
const record9 = value.record;
|
|
19919
|
+
if (!object2(record9))
|
|
19411
19920
|
throw new Error("Invalid import metadata");
|
|
19412
19921
|
value.record = credentialImportRecordSchema.parse({
|
|
19413
|
-
name:
|
|
19414
|
-
source:
|
|
19415
|
-
importedAt:
|
|
19922
|
+
name: record9.name,
|
|
19923
|
+
source: record9.source,
|
|
19924
|
+
importedAt: record9.importedAt
|
|
19416
19925
|
});
|
|
19417
19926
|
if (value.record.name !== name)
|
|
19418
19927
|
throw new Error("Import identity mismatch");
|
|
@@ -19420,7 +19929,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
19420
19929
|
};
|
|
19421
19930
|
const owned = (meta3, auth) => {
|
|
19422
19931
|
const credential = auth[meta3.record.name];
|
|
19423
|
-
const file2 =
|
|
19932
|
+
const file2 = path10.join(location(meta3.record.name), "index.ts");
|
|
19424
19933
|
return existsSync(file2) && !lstatSync(file2).isSymbolicLink() && readFileSync(file2, "utf8") === meta3.extension && object2(credential) && credential.type === "oauth" && credential.codexhostImportId === meta3.owner;
|
|
19425
19934
|
};
|
|
19426
19935
|
const readAuth = () => existsSync(authPath) ? parseAuth(readFileSync(authPath, "utf8")) : {};
|
|
@@ -19429,12 +19938,12 @@ function createPiCredentialImports(options = {}) {
|
|
|
19429
19938
|
return [];
|
|
19430
19939
|
const result = [];
|
|
19431
19940
|
for (const entry of readdirSync(extensionsDir)) {
|
|
19432
|
-
if (!entry.startsWith(
|
|
19941
|
+
if (!entry.startsWith(PREFIX3))
|
|
19433
19942
|
continue;
|
|
19434
|
-
const name = entry.slice(
|
|
19943
|
+
const name = entry.slice(PREFIX3.length);
|
|
19435
19944
|
if (!credentialImportNameSchema.safeParse(name).success)
|
|
19436
19945
|
continue;
|
|
19437
|
-
if (!existsSync(
|
|
19946
|
+
if (!existsSync(path10.join(location(name), "import.json")))
|
|
19438
19947
|
continue;
|
|
19439
19948
|
try {
|
|
19440
19949
|
const meta3 = readRecord(name);
|
|
@@ -19455,7 +19964,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
19455
19964
|
},
|
|
19456
19965
|
async listOthers() {
|
|
19457
19966
|
const auth = readAuth();
|
|
19458
|
-
const ours = new Set(ownedRecords(auth).map((
|
|
19967
|
+
const ours = new Set(ownedRecords(auth).map((record9) => record9.name));
|
|
19459
19968
|
const result = /* @__PURE__ */ new Map();
|
|
19460
19969
|
const usable = (provider) => Boolean(provider) && provider.length <= 128 && !ours.has(provider) && !result.has(provider);
|
|
19461
19970
|
for (const [provider, credential] of Object.entries(auth)) {
|
|
@@ -19468,7 +19977,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
19468
19977
|
...describeOauth(credential)
|
|
19469
19978
|
});
|
|
19470
19979
|
}
|
|
19471
|
-
const modelsPath =
|
|
19980
|
+
const modelsPath = path10.join(agentDir, "models.json");
|
|
19472
19981
|
if (existsSync(modelsPath)) {
|
|
19473
19982
|
const models = JSON.parse(readFileSync(modelsPath, "utf8"));
|
|
19474
19983
|
const providers = object2(models) && object2(models.providers) ? models.providers : {};
|
|
@@ -19489,8 +19998,8 @@ function createPiCredentialImports(options = {}) {
|
|
|
19489
19998
|
throw new Error("Unsupported credential source");
|
|
19490
19999
|
if (sdk.reservedNames.includes(name) || (await sdk.configuredProviderNames?.())?.includes(name))
|
|
19491
20000
|
throw new Error("Provider name already exists; choose another name");
|
|
19492
|
-
const owner =
|
|
19493
|
-
const
|
|
20001
|
+
const owner = randomUUID2();
|
|
20002
|
+
const record9 = credentialImportRecordSchema.parse({
|
|
19494
20003
|
name,
|
|
19495
20004
|
source: transfer.source,
|
|
19496
20005
|
importedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -19502,15 +20011,15 @@ function createPiCredentialImports(options = {}) {
|
|
|
19502
20011
|
try {
|
|
19503
20012
|
sdk.backend.withLock((current) => {
|
|
19504
20013
|
const auth = parseAuth(current);
|
|
19505
|
-
const modelsPath =
|
|
20014
|
+
const modelsPath = path10.join(agentDir, "models.json");
|
|
19506
20015
|
const models = existsSync(modelsPath) ? JSON.parse(readFileSync(modelsPath, "utf8")) : {};
|
|
19507
|
-
if (Object.hasOwn(auth, name) || Object.hasOwn(models.providers ?? {}, name) || existsSync(dir) || existsSync(
|
|
20016
|
+
if (Object.hasOwn(auth, name) || Object.hasOwn(models.providers ?? {}, name) || existsSync(dir) || existsSync(path10.join(extensionsDir, `${name}-provider.ts`)))
|
|
19508
20017
|
throw new Error("Provider name already exists; choose another name");
|
|
19509
20018
|
mkdirSync(extensionsDir, { recursive: true, mode: 448 });
|
|
19510
20019
|
mkdirSync(dir, { mode: 448 });
|
|
19511
20020
|
created = true;
|
|
19512
|
-
writeFileSync(
|
|
19513
|
-
writeFileSync(
|
|
20021
|
+
writeFileSync(path10.join(dir, "import.json"), JSON.stringify({ version: 1, owner, record: record9, extension }), { flag: "wx", mode: 384 });
|
|
20022
|
+
writeFileSync(path10.join(dir, "index.ts"), extension, { flag: "wx", mode: 384 });
|
|
19514
20023
|
auth[name] = { type: "oauth", ...transfer.oauth, codexhostImportId: owner };
|
|
19515
20024
|
saveAuth(auth);
|
|
19516
20025
|
committed = true;
|
|
@@ -19529,7 +20038,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
19529
20038
|
const auth = parseAuth(current);
|
|
19530
20039
|
if (!owned(meta3, auth) || meta3.record.source.id !== transfer.source.id || meta3.record.source.provider !== transfer.source.provider)
|
|
19531
20040
|
throw new Error("Import ownership or source account changed; refusing replacement");
|
|
19532
|
-
const metadataPath =
|
|
20041
|
+
const metadataPath = path10.join(location(name), "import.json");
|
|
19533
20042
|
const previous = readFileSync(metadataPath, "utf8");
|
|
19534
20043
|
const updated = {
|
|
19535
20044
|
...meta3,
|
|
@@ -19564,10 +20073,10 @@ function createPiCredentialImports(options = {}) {
|
|
|
19564
20073
|
}
|
|
19565
20074
|
|
|
19566
20075
|
// dist/pi-fast-mode.js
|
|
19567
|
-
import { createHash as
|
|
19568
|
-
import { mkdir, readFile as
|
|
19569
|
-
import { homedir as
|
|
19570
|
-
import
|
|
20076
|
+
import { createHash as createHash5, randomUUID as randomUUID3 } from "node:crypto";
|
|
20077
|
+
import { mkdir as mkdir2, readFile as readFile3, rename as rename2, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
|
|
20078
|
+
import { homedir as homedir5 } from "node:os";
|
|
20079
|
+
import path11 from "node:path";
|
|
19571
20080
|
var PI_FAST_COMMAND = "codexhost-fast-mode";
|
|
19572
20081
|
var PI_FAST_ACK = "codexhost-fast-mode:";
|
|
19573
20082
|
var PI_FAST_EXTENSION = `export default function(pi) {
|
|
@@ -19617,24 +20126,24 @@ var PI_FAST_EXTENSION = `export default function(pi) {
|
|
|
19617
20126
|
}
|
|
19618
20127
|
`;
|
|
19619
20128
|
async function ensurePiFastExtension(environment) {
|
|
19620
|
-
const digest =
|
|
19621
|
-
const dataDirectory = environment.CODEXHOST_DATA_DIR ??
|
|
19622
|
-
const directory =
|
|
19623
|
-
const file2 =
|
|
19624
|
-
if (await
|
|
20129
|
+
const digest = createHash5("sha256").update(PI_FAST_EXTENSION).digest("hex").slice(0, 16);
|
|
20130
|
+
const dataDirectory = environment.CODEXHOST_DATA_DIR ?? path11.join(environment.HOME ?? environment.USERPROFILE ?? homedir5(), ".codexhost");
|
|
20131
|
+
const directory = path11.resolve(dataDirectory, "extensions", "pi-codex-fast");
|
|
20132
|
+
const file2 = path11.join(directory, `${digest}.mjs`);
|
|
20133
|
+
if (await readFile3(file2, "utf8").catch(() => "") === PI_FAST_EXTENSION)
|
|
19625
20134
|
return file2;
|
|
19626
|
-
await
|
|
19627
|
-
const temporary = `${file2}.${
|
|
20135
|
+
await mkdir2(directory, { recursive: true });
|
|
20136
|
+
const temporary = `${file2}.${randomUUID3()}.tmp`;
|
|
19628
20137
|
try {
|
|
19629
|
-
await
|
|
20138
|
+
await writeFile3(temporary, PI_FAST_EXTENSION, { mode: 384 });
|
|
19630
20139
|
try {
|
|
19631
|
-
await
|
|
20140
|
+
await rename2(temporary, file2);
|
|
19632
20141
|
} catch (error51) {
|
|
19633
|
-
if (await
|
|
20142
|
+
if (await readFile3(file2, "utf8").catch(() => "") !== PI_FAST_EXTENSION)
|
|
19634
20143
|
throw error51;
|
|
19635
20144
|
}
|
|
19636
20145
|
} finally {
|
|
19637
|
-
await
|
|
20146
|
+
await rm3(temporary, { force: true });
|
|
19638
20147
|
}
|
|
19639
20148
|
return file2;
|
|
19640
20149
|
}
|
|
@@ -19651,15 +20160,15 @@ function withPiFast(catalog, supported) {
|
|
|
19651
20160
|
// dist/pi-empty-session.js
|
|
19652
20161
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
19653
20162
|
import { createInterface as createInterface3 } from "node:readline";
|
|
19654
|
-
import { randomUUID as
|
|
19655
|
-
import { link, open as open2, rm as
|
|
19656
|
-
import
|
|
20163
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
20164
|
+
import { link, open as open2, rm as rm4 } from "node:fs/promises";
|
|
20165
|
+
import path12 from "node:path";
|
|
19657
20166
|
|
|
19658
20167
|
// dist/pi-session-file.js
|
|
19659
20168
|
import { open, realpath as realpath3 } from "node:fs/promises";
|
|
19660
20169
|
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
19661
20170
|
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
19662
|
-
function
|
|
20171
|
+
function isRecord8(value) {
|
|
19663
20172
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19664
20173
|
}
|
|
19665
20174
|
async function readPiSessionHeader(sessionFile) {
|
|
@@ -19679,7 +20188,7 @@ async function readPiSessionHeader(sessionFile) {
|
|
|
19679
20188
|
} catch {
|
|
19680
20189
|
throw new Error("Pi Session header is not valid JSON");
|
|
19681
20190
|
}
|
|
19682
|
-
if (!
|
|
20191
|
+
if (!isRecord8(parsed) || parsed.type !== "session" || typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
19683
20192
|
throw new Error("Pi Session header is invalid");
|
|
19684
20193
|
}
|
|
19685
20194
|
return {
|
|
@@ -19712,7 +20221,7 @@ async function verifyPiSessionCwd(input) {
|
|
|
19712
20221
|
async function persistEmptyPiSession(input) {
|
|
19713
20222
|
const { state: state2, history, sourceSessionFile, sourceSessionId, cwd } = input;
|
|
19714
20223
|
const destination = state2.sessionFile;
|
|
19715
|
-
if (!destination || !
|
|
20224
|
+
if (!destination || !path12.isAbsolute(destination) || path12.resolve(destination) === path12.resolve(sourceSessionFile) || state2.sessionId === sourceSessionId || mapPiSnapshot(history, { sessionId: state2.sessionId, model: null }).turns.length !== 0)
|
|
19716
20225
|
throw new Error("Pi empty Session is not an independent empty native fork");
|
|
19717
20226
|
await verifyPiSessionCwd({
|
|
19718
20227
|
sessionFile: sourceSessionFile,
|
|
@@ -19736,7 +20245,7 @@ async function persistEmptyPiSession(input) {
|
|
|
19736
20245
|
cwd,
|
|
19737
20246
|
parentSession: sourceSessionFile
|
|
19738
20247
|
};
|
|
19739
|
-
const temporary =
|
|
20248
|
+
const temporary = path12.join(path12.dirname(destination), `.codexhost-${randomUUID4()}.tmp`);
|
|
19740
20249
|
try {
|
|
19741
20250
|
const file2 = await open2(temporary, "wx", 384);
|
|
19742
20251
|
try {
|
|
@@ -19747,7 +20256,7 @@ async function persistEmptyPiSession(input) {
|
|
|
19747
20256
|
}
|
|
19748
20257
|
await link(temporary, destination);
|
|
19749
20258
|
if (process.platform !== "win32") {
|
|
19750
|
-
const directory = await open2(
|
|
20259
|
+
const directory = await open2(path12.dirname(destination), "r");
|
|
19751
20260
|
try {
|
|
19752
20261
|
await directory.sync();
|
|
19753
20262
|
} finally {
|
|
@@ -19755,7 +20264,7 @@ async function persistEmptyPiSession(input) {
|
|
|
19755
20264
|
}
|
|
19756
20265
|
}
|
|
19757
20266
|
} finally {
|
|
19758
|
-
await
|
|
20267
|
+
await rm4(temporary, { force: true });
|
|
19759
20268
|
}
|
|
19760
20269
|
}
|
|
19761
20270
|
async function readPiEmptySessionConfiguration(sessionFile) {
|
|
@@ -19811,20 +20320,20 @@ async function readPiEmptySessionConfiguration(sessionFile) {
|
|
|
19811
20320
|
}
|
|
19812
20321
|
|
|
19813
20322
|
// dist/pi-adapter.js
|
|
19814
|
-
import { randomUUID as
|
|
19815
|
-
import
|
|
20323
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
20324
|
+
import path16 from "node:path";
|
|
19816
20325
|
|
|
19817
20326
|
// dist/pi-workflow-child-history.js
|
|
19818
|
-
import { createHash as
|
|
20327
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
19819
20328
|
import { constants } from "node:fs";
|
|
19820
20329
|
import { open as open3 } from "node:fs/promises";
|
|
19821
|
-
import
|
|
19822
|
-
function
|
|
20330
|
+
import path13 from "node:path";
|
|
20331
|
+
function record7(value) {
|
|
19823
20332
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19824
20333
|
}
|
|
19825
20334
|
var MAX_SESSION_BYTES = 8 * 1024 * 1024;
|
|
19826
|
-
async function childHistory(file2, parentSessionId, identity) {
|
|
19827
|
-
if (!
|
|
20335
|
+
async function childHistory(file2, parentSessionId, identity, validateParent = false) {
|
|
20336
|
+
if (!path13.isAbsolute(file2))
|
|
19828
20337
|
throw new Error("Pi child Session path is not absolute");
|
|
19829
20338
|
const handle = await open3(file2, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
19830
20339
|
try {
|
|
@@ -19837,12 +20346,14 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
19837
20346
|
throw new Error("Pi child Session exceeds read bounds");
|
|
19838
20347
|
const values = buffer.subarray(0, bytesRead).toString("utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
19839
20348
|
const header = values[0];
|
|
19840
|
-
if (!
|
|
20349
|
+
if (!record7(header) || header.type !== "session" || typeof header.id !== "string" || header.version !== 3)
|
|
19841
20350
|
throw new Error("Unsupported Pi child Session header");
|
|
20351
|
+
if (validateParent && header.parentSession !== parentSessionId)
|
|
20352
|
+
throw new Error("Pi child Session parent identity mismatch");
|
|
19842
20353
|
const entries = [];
|
|
19843
20354
|
for (const entry of values.slice(1)) {
|
|
19844
20355
|
const parsed = jsonValueSchema.safeParse(entry);
|
|
19845
|
-
if (!parsed.success || !
|
|
20356
|
+
if (!parsed.success || !record7(parsed.data) || typeof parsed.data.id !== "string")
|
|
19846
20357
|
throw new Error("Malformed Pi child Session entry");
|
|
19847
20358
|
entries.push(parsed.data);
|
|
19848
20359
|
}
|
|
@@ -19852,7 +20363,7 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
19852
20363
|
model: null,
|
|
19853
20364
|
...typeof header.cwd === "string" ? { cwd: header.cwd } : {}
|
|
19854
20365
|
});
|
|
19855
|
-
const prefix =
|
|
20366
|
+
const prefix = createHash6("sha256").update(identity).digest("hex");
|
|
19856
20367
|
return {
|
|
19857
20368
|
turns: snapshot.turns.map((turn) => {
|
|
19858
20369
|
const readonlyTurn = {
|
|
@@ -19873,7 +20384,7 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
19873
20384
|
async function readPiWorkflowChild(history, parentSessionId, address) {
|
|
19874
20385
|
for (const entry of activePiEntries(history).reverse()) {
|
|
19875
20386
|
const message3 = entry.message;
|
|
19876
|
-
if (!
|
|
20387
|
+
if (!record7(message3) || message3.role !== "toolResult" || message3.toolName !== "subagent")
|
|
19877
20388
|
continue;
|
|
19878
20389
|
const summary = piWorkflowSummary(message3);
|
|
19879
20390
|
if (!summary || summary.workflowRunId !== address.workflowRunId || summary.parentToolCallId !== message3.toolCallId)
|
|
@@ -19882,10 +20393,10 @@ async function readPiWorkflowChild(history, parentSessionId, address) {
|
|
|
19882
20393
|
if (!child)
|
|
19883
20394
|
break;
|
|
19884
20395
|
const details = message3.details;
|
|
19885
|
-
if (!
|
|
20396
|
+
if (!record7(details) || !Array.isArray(details.results))
|
|
19886
20397
|
break;
|
|
19887
|
-
const result = details.results.findLast((candidate) =>
|
|
19888
|
-
if (!
|
|
20398
|
+
const result = details.results.findLast((candidate) => record7(candidate) && candidate.workflowKey === address.childId);
|
|
20399
|
+
if (!record7(result))
|
|
19889
20400
|
break;
|
|
19890
20401
|
const id = piWorkflowSubagentId(address);
|
|
19891
20402
|
if (typeof result.sessionFile === "string") {
|
|
@@ -19928,25 +20439,69 @@ ${output}`,
|
|
|
19928
20439
|
};
|
|
19929
20440
|
}
|
|
19930
20441
|
|
|
20442
|
+
// dist/pi-gotgenes-history.js
|
|
20443
|
+
function gotgenesHistory(history) {
|
|
20444
|
+
const records = /* @__PURE__ */ new Map();
|
|
20445
|
+
for (const entry of activePiEntries(history)) {
|
|
20446
|
+
const message3 = entry.message;
|
|
20447
|
+
const parsed = entry.type === "custom" && entry.customType === "subagents:record" ? gotgenesRecord(entry.data) : isRecord4(message3) && message3.role === "toolResult" && typeof message3.toolName === "string" ? gotgenesToolRecord(message3.toolName, message3) : null;
|
|
20448
|
+
if (!parsed)
|
|
20449
|
+
continue;
|
|
20450
|
+
records.set(parsed.id, mergeGotgenesRecord(records.get(parsed.id), parsed));
|
|
20451
|
+
}
|
|
20452
|
+
return [...records.values()];
|
|
20453
|
+
}
|
|
20454
|
+
function restoreGotgenes(history, observer) {
|
|
20455
|
+
observer.observe(gotgenesHistory(history), false);
|
|
20456
|
+
}
|
|
20457
|
+
async function readGotgenesChild(history, parentSessionId, id, live) {
|
|
20458
|
+
const saved = gotgenesHistory(history).find((entry) => entry.id === id);
|
|
20459
|
+
const record9 = live?.outputFile ? live : saved;
|
|
20460
|
+
if (!record9?.outputFile)
|
|
20461
|
+
return {
|
|
20462
|
+
ok: false,
|
|
20463
|
+
error: {
|
|
20464
|
+
code: "sessionNotFound",
|
|
20465
|
+
message: "Pi subagent has not published its Session transcript path",
|
|
20466
|
+
retryable: true
|
|
20467
|
+
}
|
|
20468
|
+
};
|
|
20469
|
+
try {
|
|
20470
|
+
return {
|
|
20471
|
+
ok: true,
|
|
20472
|
+
value: await childHistory(record9.outputFile, parentSessionId, gotgenesId(id), true)
|
|
20473
|
+
};
|
|
20474
|
+
} catch (error51) {
|
|
20475
|
+
return {
|
|
20476
|
+
ok: false,
|
|
20477
|
+
error: {
|
|
20478
|
+
code: "unavailable",
|
|
20479
|
+
message: error51 instanceof Error ? error51.message : "Pi child transcript unavailable",
|
|
20480
|
+
retryable: true
|
|
20481
|
+
}
|
|
20482
|
+
};
|
|
20483
|
+
}
|
|
20484
|
+
}
|
|
20485
|
+
|
|
19931
20486
|
// dist/pi-subagent-history.js
|
|
19932
20487
|
import { constants as constants2 } from "node:fs";
|
|
19933
20488
|
import { open as open4 } from "node:fs/promises";
|
|
19934
|
-
import
|
|
19935
|
-
function
|
|
20489
|
+
import path14 from "node:path";
|
|
20490
|
+
function record8(value) {
|
|
19936
20491
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19937
20492
|
}
|
|
19938
20493
|
function state(value) {
|
|
19939
20494
|
return value === "pending" ? "queued" : value === "completed" ? "complete" : value;
|
|
19940
20495
|
}
|
|
19941
20496
|
function piSubagentArtifact(value, runId, parentSessionId) {
|
|
19942
|
-
if (!
|
|
20497
|
+
if (!record8(value) || value.lifecycleArtifactVersion !== 3 || value.runId !== runId || value.sessionId !== parentSessionId || !["single", "parallel", "chain", "workflow"].includes(String(value.mode)))
|
|
19943
20498
|
return null;
|
|
19944
20499
|
if (value.steps !== void 0 && (!Array.isArray(value.steps) || value.steps.length > 128))
|
|
19945
20500
|
return null;
|
|
19946
20501
|
const steps = Array.isArray(value.steps) ? value.steps : [];
|
|
19947
20502
|
const children = [];
|
|
19948
20503
|
for (const [index, step] of steps.entries()) {
|
|
19949
|
-
if (!
|
|
20504
|
+
if (!record8(step) || typeof step.agent !== "string")
|
|
19950
20505
|
return null;
|
|
19951
20506
|
children.push({
|
|
19952
20507
|
id: step.workflowKey ?? step.runId ?? `step:${index}`,
|
|
@@ -19977,19 +20532,20 @@ function piSubagentArtifact(value, runId, parentSessionId) {
|
|
|
19977
20532
|
});
|
|
19978
20533
|
}
|
|
19979
20534
|
async function restorePiSubagents(history, parentSessionId, observer) {
|
|
20535
|
+
restoreGotgenes(history, observer.gotgenes);
|
|
19980
20536
|
const receipts = /* @__PURE__ */ new Map();
|
|
19981
20537
|
for (const entry of activePiEntries(history)) {
|
|
19982
|
-
if (!
|
|
20538
|
+
if (!record8(entry.message) || entry.message.role !== "toolResult" || entry.message.toolName !== "subagent" || entry.message.isError !== false || !record8(entry.message.details))
|
|
19983
20539
|
continue;
|
|
19984
20540
|
const details = entry.message.details;
|
|
19985
|
-
if (!["single", "parallel", "chain", "workflow"].includes(String(details.mode)) || typeof details.asyncId !== "string" || typeof details.asyncDir !== "string" || !
|
|
20541
|
+
if (!["single", "parallel", "chain", "workflow"].includes(String(details.mode)) || typeof details.asyncId !== "string" || typeof details.asyncDir !== "string" || !path14.isAbsolute(details.asyncDir) || path14.basename(details.asyncDir) !== details.asyncId)
|
|
19986
20542
|
continue;
|
|
19987
20543
|
receipts.set(details.asyncId, details.asyncDir);
|
|
19988
20544
|
}
|
|
19989
20545
|
for (const [id, directory] of [...receipts].slice(-128)) {
|
|
19990
20546
|
let file2;
|
|
19991
20547
|
try {
|
|
19992
|
-
file2 = await open4(
|
|
20548
|
+
file2 = await open4(path14.join(directory, "status.json"), constants2.O_RDONLY | (constants2.O_NOFOLLOW ?? 0));
|
|
19993
20549
|
const stat2 = await file2.stat();
|
|
19994
20550
|
if (!stat2.isFile() || stat2.size > 1024 * 1024)
|
|
19995
20551
|
continue;
|
|
@@ -20071,8 +20627,8 @@ async function rollbackPiLastTurn(transport, sourceSessionId, cwd) {
|
|
|
20071
20627
|
|
|
20072
20628
|
// dist/pi-rpc-session.js
|
|
20073
20629
|
import { spawn, spawnSync } from "node:child_process";
|
|
20074
|
-
import { randomUUID as
|
|
20075
|
-
import
|
|
20630
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
20631
|
+
import path15 from "node:path";
|
|
20076
20632
|
|
|
20077
20633
|
// dist/pi-slash-commands.js
|
|
20078
20634
|
var DYNAMIC_ID_PREFIX = "pi.slash.";
|
|
@@ -20094,15 +20650,15 @@ function parsePiNativeCommands(response) {
|
|
|
20094
20650
|
return data.commands.flatMap((entry) => {
|
|
20095
20651
|
if (typeof entry !== "object" || entry === null)
|
|
20096
20652
|
return [];
|
|
20097
|
-
const
|
|
20098
|
-
const name = typeof
|
|
20653
|
+
const record9 = entry;
|
|
20654
|
+
const name = typeof record9.name === "string" ? record9.name.trim().replace(/^\//u, "") : "";
|
|
20099
20655
|
if (!name)
|
|
20100
20656
|
return [];
|
|
20101
20657
|
return [
|
|
20102
20658
|
{
|
|
20103
20659
|
name,
|
|
20104
|
-
...typeof
|
|
20105
|
-
...typeof
|
|
20660
|
+
...typeof record9.description === "string" ? { description: record9.description } : {},
|
|
20661
|
+
...typeof record9.source === "string" ? { source: record9.source } : {}
|
|
20106
20662
|
}
|
|
20107
20663
|
];
|
|
20108
20664
|
});
|
|
@@ -20118,8 +20674,97 @@ function piDynamicCommandPrompt(catalog, commandId, argumentText) {
|
|
|
20118
20674
|
return liveHarnessCommandPrompt(catalog, DYNAMIC_ID_PREFIX, commandId, argumentText);
|
|
20119
20675
|
}
|
|
20120
20676
|
|
|
20677
|
+
// dist/pi-content-stream.js
|
|
20678
|
+
var PiContentStreamConflictError = class extends Error {
|
|
20679
|
+
};
|
|
20680
|
+
var PiContentStream = class {
|
|
20681
|
+
kind;
|
|
20682
|
+
#blocks = /* @__PURE__ */ new Map();
|
|
20683
|
+
#indexed;
|
|
20684
|
+
#legacyBlockIndex = 0;
|
|
20685
|
+
#lastEmittedIndex = -Infinity;
|
|
20686
|
+
constructor(kind) {
|
|
20687
|
+
this.kind = kind;
|
|
20688
|
+
}
|
|
20689
|
+
append(index, delta) {
|
|
20690
|
+
const block = this.#block(this.#key(index));
|
|
20691
|
+
if (block.ended && delta.length > 0)
|
|
20692
|
+
this.#conflict();
|
|
20693
|
+
block.received += delta;
|
|
20694
|
+
return this.#flush();
|
|
20695
|
+
}
|
|
20696
|
+
complete(index, content) {
|
|
20697
|
+
this.#finish(this.#key(index), content);
|
|
20698
|
+
if (this.#indexed === false)
|
|
20699
|
+
this.#legacyBlockIndex += 1;
|
|
20700
|
+
return this.#flush();
|
|
20701
|
+
}
|
|
20702
|
+
finalize(blocks) {
|
|
20703
|
+
if (this.#indexed !== true) {
|
|
20704
|
+
blocks = this.#legacyBlockIndex > 0 ? blocks.map(({ text: text3 }, index) => ({ index, text: text3 })) : [{ index: 0, text: blocks.map(({ text: text3 }) => text3).join("") }];
|
|
20705
|
+
}
|
|
20706
|
+
const indices = new Set(blocks.map(({ index }) => index));
|
|
20707
|
+
for (const [index, block] of this.#blocks) {
|
|
20708
|
+
if (indices.has(index))
|
|
20709
|
+
continue;
|
|
20710
|
+
if (block.emitted.length > 0)
|
|
20711
|
+
this.#conflict();
|
|
20712
|
+
this.#blocks.delete(index);
|
|
20713
|
+
}
|
|
20714
|
+
for (const { index, text: text3 } of blocks)
|
|
20715
|
+
this.#finish(index, text3);
|
|
20716
|
+
return this.#flush();
|
|
20717
|
+
}
|
|
20718
|
+
#key(index) {
|
|
20719
|
+
const indexed = typeof index === "number" && Number.isInteger(index) && index >= 0;
|
|
20720
|
+
this.#indexed ??= indexed;
|
|
20721
|
+
if (!this.#indexed)
|
|
20722
|
+
return this.#legacyBlockIndex;
|
|
20723
|
+
if (!indexed)
|
|
20724
|
+
this.#conflict();
|
|
20725
|
+
return index;
|
|
20726
|
+
}
|
|
20727
|
+
#block(index) {
|
|
20728
|
+
let block = this.#blocks.get(index);
|
|
20729
|
+
if (!block) {
|
|
20730
|
+
block = { received: "", emitted: "", ended: false };
|
|
20731
|
+
this.#blocks.set(index, block);
|
|
20732
|
+
}
|
|
20733
|
+
return block;
|
|
20734
|
+
}
|
|
20735
|
+
#finish(index, content) {
|
|
20736
|
+
const block = this.#block(index);
|
|
20737
|
+
if (!content.startsWith(block.emitted))
|
|
20738
|
+
this.#conflict();
|
|
20739
|
+
block.received = content;
|
|
20740
|
+
block.ended = true;
|
|
20741
|
+
}
|
|
20742
|
+
#flush() {
|
|
20743
|
+
let delta = "";
|
|
20744
|
+
for (const [index, block] of [...this.#blocks].sort(([left], [right]) => left - right)) {
|
|
20745
|
+
const visible = this.kind === "reasoning" && !block.ended ? block.received.replace(/[\r\n]+$/u, "") : block.received;
|
|
20746
|
+
if (!visible.startsWith(block.emitted))
|
|
20747
|
+
this.#conflict();
|
|
20748
|
+
const suffix = visible.slice(block.emitted.length);
|
|
20749
|
+
if (suffix.length > 0) {
|
|
20750
|
+
if (index < this.#lastEmittedIndex)
|
|
20751
|
+
this.#conflict();
|
|
20752
|
+
this.#lastEmittedIndex = index;
|
|
20753
|
+
block.emitted = visible;
|
|
20754
|
+
delta += suffix;
|
|
20755
|
+
}
|
|
20756
|
+
if (!block.ended)
|
|
20757
|
+
break;
|
|
20758
|
+
}
|
|
20759
|
+
return delta;
|
|
20760
|
+
}
|
|
20761
|
+
#conflict() {
|
|
20762
|
+
throw new PiContentStreamConflictError(`Pi ${this.kind} final content conflicts with already streamed content`);
|
|
20763
|
+
}
|
|
20764
|
+
};
|
|
20765
|
+
|
|
20121
20766
|
// dist/pi-subagent-rpc.js
|
|
20122
|
-
import { randomUUID as
|
|
20767
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
20123
20768
|
var PiSubagentRpc = class {
|
|
20124
20769
|
send;
|
|
20125
20770
|
timeoutMs;
|
|
@@ -20161,7 +20806,7 @@ var PiSubagentRpc = class {
|
|
|
20161
20806
|
if (!Array.isArray(data?.commands) || !data.commands.some((command) => command?.name === "subagents-inspect-rpc" && command.source === "extension")) {
|
|
20162
20807
|
throw new Error("Installed Pi has no pi-subagents Host inspection command");
|
|
20163
20808
|
}
|
|
20164
|
-
const requestId =
|
|
20809
|
+
const requestId = randomUUID5();
|
|
20165
20810
|
const reply = new Promise((resolve, reject) => {
|
|
20166
20811
|
const timer = setTimeout(() => {
|
|
20167
20812
|
this.#pending.delete(requestId);
|
|
@@ -20195,6 +20840,12 @@ var PiSubagentRpc = class {
|
|
|
20195
20840
|
};
|
|
20196
20841
|
|
|
20197
20842
|
// dist/pi-rpc-session.js
|
|
20843
|
+
var PiRpcBusyError = class extends Error {
|
|
20844
|
+
constructor() {
|
|
20845
|
+
super("Pi is still running a native Turn; wait for completion or use the active Turn's stop/steer action");
|
|
20846
|
+
this.name = "PiRpcBusyError";
|
|
20847
|
+
}
|
|
20848
|
+
};
|
|
20198
20849
|
var PiRpcFaultError = class extends Error {
|
|
20199
20850
|
kind;
|
|
20200
20851
|
diagnostic;
|
|
@@ -20222,8 +20873,11 @@ var READ_ONLY_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
20222
20873
|
"get_available_thinking_levels"
|
|
20223
20874
|
]);
|
|
20224
20875
|
var MAX_EXPIRED_IDS = 64;
|
|
20876
|
+
function nativeMessageIdentity(active) {
|
|
20877
|
+
return active.assistantNativeMessageIdentity ? { nativeMessageIdentity: active.assistantNativeMessageIdentity } : {};
|
|
20878
|
+
}
|
|
20225
20879
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
20226
|
-
function
|
|
20880
|
+
function isRecord9(value) {
|
|
20227
20881
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20228
20882
|
}
|
|
20229
20883
|
function message2(value) {
|
|
@@ -20235,13 +20889,13 @@ function nonBlankString(value) {
|
|
|
20235
20889
|
function parseNativeModel(value, context) {
|
|
20236
20890
|
if (value === null || value === void 0)
|
|
20237
20891
|
return null;
|
|
20238
|
-
if (!
|
|
20892
|
+
if (!isRecord9(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
20239
20893
|
throw new PiRpcFaultError("protocolError", `Pi RPC returned an invalid ${context} Model`);
|
|
20240
20894
|
}
|
|
20241
20895
|
return { provider: value.provider, id: value.id };
|
|
20242
20896
|
}
|
|
20243
20897
|
function sessionStateData(response) {
|
|
20244
|
-
const data =
|
|
20898
|
+
const data = isRecord9(response.data) ? response.data : null;
|
|
20245
20899
|
if (!data)
|
|
20246
20900
|
throw new PiRpcFaultError("protocolError", "Pi RPC state response has no data");
|
|
20247
20901
|
return data;
|
|
@@ -20249,7 +20903,7 @@ function sessionStateData(response) {
|
|
|
20249
20903
|
function parseSessionState(response) {
|
|
20250
20904
|
const data = sessionStateData(response);
|
|
20251
20905
|
const model2 = parseNativeModel(data.model, "state");
|
|
20252
|
-
const modelReasoning =
|
|
20906
|
+
const modelReasoning = isRecord9(data.model) && typeof data.model.reasoning === "boolean" ? data.model.reasoning : null;
|
|
20253
20907
|
if (!nonBlankString(data.sessionId)) {
|
|
20254
20908
|
throw new PiRpcFaultError("protocolError", "Pi RPC state has no stable Session identity");
|
|
20255
20909
|
}
|
|
@@ -20275,13 +20929,13 @@ function parseSessionStreaming(response) {
|
|
|
20275
20929
|
return isStreaming;
|
|
20276
20930
|
}
|
|
20277
20931
|
function parseSessionHistory(response) {
|
|
20278
|
-
const data =
|
|
20932
|
+
const data = isRecord9(response.data) ? response.data : null;
|
|
20279
20933
|
if (!data || !Array.isArray(data.entries)) {
|
|
20280
20934
|
throw new PiRpcFaultError("protocolError", "Pi RPC entries response has no Entries");
|
|
20281
20935
|
}
|
|
20282
20936
|
const entries = data.entries.map((entry) => {
|
|
20283
20937
|
const parsed = jsonValueSchema.safeParse(entry);
|
|
20284
|
-
if (!parsed.success || !
|
|
20938
|
+
if (!parsed.success || !isRecord9(parsed.data)) {
|
|
20285
20939
|
throw new PiRpcFaultError("protocolError", "Pi RPC entries response contains an invalid Entry");
|
|
20286
20940
|
}
|
|
20287
20941
|
return parsed.data;
|
|
@@ -20292,7 +20946,7 @@ function parseSessionHistory(response) {
|
|
|
20292
20946
|
return { entries, leafId: data.leafId };
|
|
20293
20947
|
}
|
|
20294
20948
|
function parseAvailableThinkingLevels(response) {
|
|
20295
|
-
const data =
|
|
20949
|
+
const data = isRecord9(response.data) ? response.data : null;
|
|
20296
20950
|
if (!data || !Array.isArray(data.levels) || data.levels.length === 0) {
|
|
20297
20951
|
throw new PiRpcFaultError("protocolError", "Pi RPC Thinking catalog response has no levels");
|
|
20298
20952
|
}
|
|
@@ -20309,13 +20963,13 @@ function parseAvailableThinkingLevels(response) {
|
|
|
20309
20963
|
return levels;
|
|
20310
20964
|
}
|
|
20311
20965
|
function parseAvailableModels(response) {
|
|
20312
|
-
const data =
|
|
20966
|
+
const data = isRecord9(response.data) ? response.data : null;
|
|
20313
20967
|
if (!data || !Array.isArray(data.models)) {
|
|
20314
20968
|
throw new PiRpcFaultError("protocolError", "Pi RPC Model catalog response has no models");
|
|
20315
20969
|
}
|
|
20316
20970
|
return data.models.map((model2) => {
|
|
20317
20971
|
const parsed = parseNativeModel(model2, "catalog");
|
|
20318
|
-
if (!parsed || !
|
|
20972
|
+
if (!parsed || !isRecord9(model2) || typeof model2.reasoning !== "boolean") {
|
|
20319
20973
|
throw new PiRpcFaultError("protocolError", "Pi RPC catalog contains a Model without reasoning capability");
|
|
20320
20974
|
}
|
|
20321
20975
|
return {
|
|
@@ -20326,32 +20980,32 @@ function parseAvailableModels(response) {
|
|
|
20326
20980
|
});
|
|
20327
20981
|
}
|
|
20328
20982
|
function assistantText(value) {
|
|
20329
|
-
if (!
|
|
20983
|
+
if (!isRecord9(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
20330
20984
|
return null;
|
|
20331
|
-
return value.content.filter((content) =>
|
|
20985
|
+
return value.content.filter((content) => isRecord9(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
|
|
20332
20986
|
}
|
|
20333
20987
|
function assistantMessageId(value) {
|
|
20334
|
-
if (!
|
|
20988
|
+
if (!isRecord9(value) || value.role !== "assistant")
|
|
20335
20989
|
return null;
|
|
20336
20990
|
return nonBlankString(value.responseId) ? value.responseId : null;
|
|
20337
20991
|
}
|
|
20338
20992
|
function extractReasoningText(content) {
|
|
20339
|
-
if (!
|
|
20993
|
+
if (!isRecord9(content))
|
|
20340
20994
|
return null;
|
|
20341
20995
|
const type = String(content.type ?? "");
|
|
20342
20996
|
if (type === "thinking" || type === "reasoning" || type === "thought") {
|
|
20343
|
-
const
|
|
20344
|
-
return typeof
|
|
20997
|
+
const text3 = content.thinking ?? content.reasoning ?? content.text ?? content.delta;
|
|
20998
|
+
return typeof text3 === "string" ? text3 : null;
|
|
20345
20999
|
}
|
|
20346
21000
|
return null;
|
|
20347
21001
|
}
|
|
20348
21002
|
function assistantReasoning(value) {
|
|
20349
|
-
if (!
|
|
21003
|
+
if (!isRecord9(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
20350
21004
|
return null;
|
|
20351
|
-
return value.content.map(extractReasoningText).filter((
|
|
21005
|
+
return value.content.map(extractReasoningText).filter((text3) => typeof text3 === "string").join("");
|
|
20352
21006
|
}
|
|
20353
21007
|
function assistantFailure(value) {
|
|
20354
|
-
if (!
|
|
21008
|
+
if (!isRecord9(value) || value.role !== "assistant")
|
|
20355
21009
|
return void 0;
|
|
20356
21010
|
if (value.stopReason !== "error" && value.stopReason !== "aborted")
|
|
20357
21011
|
return null;
|
|
@@ -20371,7 +21025,7 @@ function signalProcessTree(child, signal) {
|
|
|
20371
21025
|
try {
|
|
20372
21026
|
process.kill(-child.pid, signal);
|
|
20373
21027
|
} catch (error51) {
|
|
20374
|
-
if (!
|
|
21028
|
+
if (!isRecord9(error51) || error51.code !== "ESRCH")
|
|
20375
21029
|
throw error51;
|
|
20376
21030
|
}
|
|
20377
21031
|
}
|
|
@@ -20408,13 +21062,14 @@ function piRpcProcessCommand(options, dependencies = {}) {
|
|
|
20408
21062
|
const thinkingArguments = options.emptySessionConfiguration ? ["--thinking", options.emptySessionConfiguration.thinkingLevel] : [];
|
|
20409
21063
|
const arguments_ = [
|
|
20410
21064
|
...options.fastExtension ? ["--extension", options.fastExtension] : [],
|
|
21065
|
+
...options.subagentExtension ? ["--extension", options.subagentExtension] : [],
|
|
20411
21066
|
"--mode",
|
|
20412
21067
|
"rpc",
|
|
20413
21068
|
...modelArguments,
|
|
20414
21069
|
...thinkingArguments,
|
|
20415
21070
|
...sessionArguments
|
|
20416
21071
|
];
|
|
20417
|
-
const extension =
|
|
21072
|
+
const extension = path15.win32.extname(command).toLowerCase();
|
|
20418
21073
|
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
20419
21074
|
return { command, arguments: arguments_, windowsVerbatimArguments: false };
|
|
20420
21075
|
}
|
|
@@ -20443,7 +21098,13 @@ var PiRpcSession = class {
|
|
|
20443
21098
|
#options;
|
|
20444
21099
|
#processAdapter;
|
|
20445
21100
|
#activeTurn = null;
|
|
21101
|
+
#runGeneration = 0;
|
|
21102
|
+
#deferredRunFrames = [];
|
|
21103
|
+
#deferredRunBytes = 0;
|
|
21104
|
+
#runWaiters = /* @__PURE__ */ new Set();
|
|
21105
|
+
#messageTimestampCounts = /* @__PURE__ */ new Map();
|
|
20446
21106
|
#autonomousTurnHandler = null;
|
|
21107
|
+
#autonomousLifecycleHandler = null;
|
|
20447
21108
|
#usageHandler = null;
|
|
20448
21109
|
#usageRequestStartedAtMs = null;
|
|
20449
21110
|
// Pieces of the unterminated frame; joined once at its newline so a large frame (a long
|
|
@@ -20463,8 +21124,15 @@ var PiRpcSession = class {
|
|
|
20463
21124
|
#fastAcknowledgement = null;
|
|
20464
21125
|
#latestCacheHitRatePercent;
|
|
20465
21126
|
#manualCompaction = null;
|
|
21127
|
+
#noticeOccurrences = /* @__PURE__ */ new Map();
|
|
21128
|
+
#seenNoticeFrames = /* @__PURE__ */ new Set();
|
|
21129
|
+
#pendingProgress = [];
|
|
21130
|
+
#omittedProgress = 0;
|
|
21131
|
+
#extensionStatuses = /* @__PURE__ */ new Map();
|
|
20466
21132
|
#stderrTail = "";
|
|
20467
21133
|
#subagents;
|
|
21134
|
+
#gotgenesHandler;
|
|
21135
|
+
#gotgenesLatest;
|
|
20468
21136
|
constructor(options, processAdapter = nodeProcessAdapter) {
|
|
20469
21137
|
if (options.sessionFile && options.forkSessionFile) {
|
|
20470
21138
|
throw new Error("Pi RPC cannot combine Session resume and Fork startup");
|
|
@@ -20494,9 +21162,17 @@ var PiRpcSession = class {
|
|
|
20494
21162
|
get stderrTail() {
|
|
20495
21163
|
return this.#stderrTail;
|
|
20496
21164
|
}
|
|
21165
|
+
get isBusy() {
|
|
21166
|
+
return this.#activeTurn !== null || this.#manualCompaction !== null || this.#compactionActive || this.#deferredRunFrames.length > 0;
|
|
21167
|
+
}
|
|
20497
21168
|
setSubagentStatusHandler(handler) {
|
|
20498
21169
|
this.#subagents.setHandler(handler);
|
|
20499
21170
|
}
|
|
21171
|
+
setGotgenesStatusHandler(handler) {
|
|
21172
|
+
this.#gotgenesHandler = handler;
|
|
21173
|
+
if (this.#gotgenesLatest)
|
|
21174
|
+
handler(this.#gotgenesLatest, "idle");
|
|
21175
|
+
}
|
|
20500
21176
|
inspectSubagent(id) {
|
|
20501
21177
|
return this.#subagents.inspect(id);
|
|
20502
21178
|
}
|
|
@@ -20506,17 +21182,18 @@ var PiRpcSession = class {
|
|
|
20506
21182
|
/** Every finished assistant message is one model request, with or without an active Turn. */
|
|
20507
21183
|
#observeUsage(value) {
|
|
20508
21184
|
if (value.type === "message_start") {
|
|
20509
|
-
|
|
21185
|
+
if (isRecord9(value.message) && value.message.role === "assistant")
|
|
21186
|
+
this.#usageRequestStartedAtMs = null;
|
|
20510
21187
|
return;
|
|
20511
21188
|
}
|
|
20512
21189
|
if (value.type === "message_update") {
|
|
20513
21190
|
const event = value.assistantMessageEvent;
|
|
20514
|
-
if (this.#usageRequestStartedAtMs === null &&
|
|
21191
|
+
if (this.#usageRequestStartedAtMs === null && isRecord9(event) && typeof event.type === "string" && /^(text|thinking|reasoning|thought|toolcall)_(start|delta)$/u.test(event.type)) {
|
|
20515
21192
|
this.#usageRequestStartedAtMs = Date.now();
|
|
20516
21193
|
}
|
|
20517
21194
|
return;
|
|
20518
21195
|
}
|
|
20519
|
-
if (value.type === "message_end" &&
|
|
21196
|
+
if (value.type === "message_end" && isRecord9(value.message)) {
|
|
20520
21197
|
if (value.message.role !== "assistant")
|
|
20521
21198
|
return;
|
|
20522
21199
|
const startedAtMs = this.#usageRequestStartedAtMs;
|
|
@@ -20530,14 +21207,21 @@ var PiRpcSession = class {
|
|
|
20530
21207
|
}
|
|
20531
21208
|
setAutonomousTurnHandler(handler) {
|
|
20532
21209
|
this.#autonomousTurnHandler = handler;
|
|
21210
|
+
this.#autonomousLifecycleHandler = null;
|
|
21211
|
+
}
|
|
21212
|
+
setAutonomousTurnLifecycleHandler(handler) {
|
|
21213
|
+
this.#autonomousLifecycleHandler = handler;
|
|
21214
|
+
this.#autonomousTurnHandler = null;
|
|
20533
21215
|
}
|
|
20534
21216
|
async start() {
|
|
20535
21217
|
if (this.#child || this.#closed)
|
|
20536
21218
|
throw new Error("Pi RPC Session cannot be started twice");
|
|
20537
21219
|
const fastExtension = this.#processAdapter === nodeProcessAdapter ? await ensurePiFastExtension({ ...process.env, ...this.#options.environment }) : void 0;
|
|
21220
|
+
const subagentExtension = this.#processAdapter === nodeProcessAdapter ? await ensureGotgenesExtension({ ...process.env, ...this.#options.environment }) : void 0;
|
|
20538
21221
|
const child = this.#processAdapter.spawn({
|
|
20539
21222
|
cwd: this.#options.cwd,
|
|
20540
21223
|
...fastExtension ? { fastExtension } : {},
|
|
21224
|
+
...subagentExtension ? { subagentExtension } : {},
|
|
20541
21225
|
...this.#options.command ? { command: this.#options.command } : {},
|
|
20542
21226
|
environment: withNodeRuntimeOnPath({
|
|
20543
21227
|
...process.env,
|
|
@@ -20561,7 +21245,7 @@ var PiRpcSession = class {
|
|
|
20561
21245
|
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
20562
21246
|
});
|
|
20563
21247
|
child.once("error", (error51) => {
|
|
20564
|
-
const kind =
|
|
21248
|
+
const kind = isRecord9(error51) && error51.code === "ENOENT" ? "notInstalled" : "unavailable";
|
|
20565
21249
|
this.#fail(new PiRpcFaultError(kind, `Pi RPC failed to start: ${error51.message}`, this.stderrTail));
|
|
20566
21250
|
});
|
|
20567
21251
|
child.once("exit", (code, signal) => {
|
|
@@ -20578,6 +21262,7 @@ var PiRpcSession = class {
|
|
|
20578
21262
|
]);
|
|
20579
21263
|
try {
|
|
20580
21264
|
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
21265
|
+
await this.getEntries();
|
|
20581
21266
|
} catch (error51) {
|
|
20582
21267
|
const fault = error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("unavailable", `Pi RPC state unavailable: ${message2(error51)}`);
|
|
20583
21268
|
this.#fail(fault);
|
|
@@ -20591,7 +21276,12 @@ var PiRpcSession = class {
|
|
|
20591
21276
|
}
|
|
20592
21277
|
async getEntries() {
|
|
20593
21278
|
try {
|
|
20594
|
-
|
|
21279
|
+
const history = parseSessionHistory(await this.#send("get_entries", {}));
|
|
21280
|
+
if (!this.#activeTurn && this.#state) {
|
|
21281
|
+
this.#messageTimestampCounts = piHistoryMessageIdentities(this.state.sessionId, activePiEntries(history)).timestampCounts;
|
|
21282
|
+
this.#noticeOccurrences = piHistoryNotices(this.state.sessionId, activePiEntries(history)).occurrences;
|
|
21283
|
+
}
|
|
21284
|
+
return history;
|
|
20595
21285
|
} catch (error51) {
|
|
20596
21286
|
if (error51 instanceof PiRpcFaultError)
|
|
20597
21287
|
this.#fail(error51);
|
|
@@ -20651,11 +21341,15 @@ var PiRpcSession = class {
|
|
|
20651
21341
|
if (entryId.length === 0)
|
|
20652
21342
|
throw new Error("Pi Fork Entry ID must not be empty");
|
|
20653
21343
|
await this.#send("fork", { entryId });
|
|
20654
|
-
|
|
21344
|
+
const state2 = await this.#refreshState("Fork");
|
|
21345
|
+
await this.getEntries();
|
|
21346
|
+
return state2;
|
|
20655
21347
|
}
|
|
20656
21348
|
async clone() {
|
|
20657
21349
|
await this.#send("clone", {});
|
|
20658
|
-
|
|
21350
|
+
const state2 = await this.#refreshState("Clone");
|
|
21351
|
+
await this.getEntries();
|
|
21352
|
+
return state2;
|
|
20659
21353
|
}
|
|
20660
21354
|
verifySessionCwd(expectedCwd) {
|
|
20661
21355
|
return verifyPiSessionCwd({
|
|
@@ -20692,7 +21386,7 @@ var PiRpcSession = class {
|
|
|
20692
21386
|
return this.state;
|
|
20693
21387
|
if (!await this.supportsFastMode())
|
|
20694
21388
|
throw new Error("Installed Pi does not support the Host Fast extension");
|
|
20695
|
-
const nonce =
|
|
21389
|
+
const nonce = randomUUID6();
|
|
20696
21390
|
const mode = enabled ? "on" : "off";
|
|
20697
21391
|
const acknowledgement = { message: `${PI_FAST_ACK}${nonce}:${mode}`, received: false };
|
|
20698
21392
|
this.#fastAcknowledgement = acknowledgement;
|
|
@@ -20732,22 +21426,27 @@ var PiRpcSession = class {
|
|
|
20732
21426
|
throw fault;
|
|
20733
21427
|
}
|
|
20734
21428
|
}
|
|
20735
|
-
async runTurn(
|
|
21429
|
+
async runTurn(text3, onEvent) {
|
|
20736
21430
|
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
20737
21431
|
throw new Error("Pi RPC Session is unavailable");
|
|
20738
21432
|
}
|
|
20739
|
-
if (this
|
|
20740
|
-
throw new
|
|
20741
|
-
if (
|
|
21433
|
+
if (this.isBusy)
|
|
21434
|
+
throw new PiRpcBusyError();
|
|
21435
|
+
if (text3.length === 0)
|
|
20742
21436
|
throw new Error("Pi text Turn must not be empty");
|
|
20743
21437
|
const settled = new Promise((resolve, reject) => {
|
|
20744
21438
|
this.#activeTurn = {
|
|
20745
21439
|
origin: "requested",
|
|
21440
|
+
autonomousRunId: null,
|
|
21441
|
+
runGeneration: this.#runGeneration,
|
|
20746
21442
|
autonomousEvents: null,
|
|
20747
21443
|
nativeTurnKey: null,
|
|
20748
21444
|
nativeCancellationObserved: false,
|
|
20749
21445
|
text: "",
|
|
20750
21446
|
assistantMessageId: null,
|
|
21447
|
+
assistantNativeMessageIdentity: void 0,
|
|
21448
|
+
textStream: new PiContentStream("text"),
|
|
21449
|
+
reasoningStream: new PiContentStream("reasoning"),
|
|
20751
21450
|
sawStreamedMessageText: false,
|
|
20752
21451
|
sawStreamedMessageReasoning: false,
|
|
20753
21452
|
lastFinalizedMessageText: null,
|
|
@@ -20767,7 +21466,8 @@ var PiRpcSession = class {
|
|
|
20767
21466
|
};
|
|
20768
21467
|
});
|
|
20769
21468
|
try {
|
|
20770
|
-
|
|
21469
|
+
this.#drainProgress(onEvent);
|
|
21470
|
+
await this.#send("prompt", { message: text3 });
|
|
20771
21471
|
} catch (error51) {
|
|
20772
21472
|
this.#rejectActiveTurn(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
20773
21473
|
}
|
|
@@ -20839,6 +21539,10 @@ var PiRpcSession = class {
|
|
|
20839
21539
|
void this.close().catch(() => void 0);
|
|
20840
21540
|
}
|
|
20841
21541
|
close() {
|
|
21542
|
+
this.#pendingProgress = [];
|
|
21543
|
+
this.#omittedProgress = 0;
|
|
21544
|
+
this.#seenNoticeFrames.clear();
|
|
21545
|
+
this.#extensionStatuses.clear();
|
|
20842
21546
|
if (!this.#closed) {
|
|
20843
21547
|
this.#closed = true;
|
|
20844
21548
|
this.#rejectAll(new Error("Pi RPC Session closed"));
|
|
@@ -20872,19 +21576,25 @@ var PiRpcSession = class {
|
|
|
20872
21576
|
rest = rest.subarray(newline + 1);
|
|
20873
21577
|
try {
|
|
20874
21578
|
const value = JSON.parse(textDecoder.decode(frame));
|
|
20875
|
-
if (!
|
|
21579
|
+
if (!isRecord9(value) || typeof value.type !== "string") {
|
|
20876
21580
|
throw new PiRpcFaultError("protocolError", "Pi RPC returned an invalid envelope");
|
|
20877
21581
|
}
|
|
20878
21582
|
this.#handle(value);
|
|
20879
21583
|
} catch (error51) {
|
|
20880
|
-
this.#fail(error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("protocolError", `Pi RPC returned invalid JSONL: ${message2(error51)}`));
|
|
21584
|
+
this.#fail(error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("protocolError", error51 instanceof PiContentStreamConflictError ? error51.message : `Pi RPC returned invalid JSONL: ${message2(error51)}`));
|
|
20881
21585
|
}
|
|
20882
21586
|
newline = rest.indexOf(10);
|
|
20883
21587
|
}
|
|
20884
21588
|
if (rest.length !== 0)
|
|
20885
21589
|
this.#buffer.push(rest);
|
|
20886
21590
|
}
|
|
20887
|
-
#handle(value) {
|
|
21591
|
+
#handle(value, observedGeneration) {
|
|
21592
|
+
if (observedGeneration === void 0 && value.type === "agent_start") {
|
|
21593
|
+
this.#runGeneration += 1;
|
|
21594
|
+
for (const waiter of this.#runWaiters)
|
|
21595
|
+
waiter.check();
|
|
21596
|
+
}
|
|
21597
|
+
const generation = observedGeneration ?? this.#runGeneration;
|
|
20888
21598
|
if (value.type === "extension_ui_request" && value.method === "notify" && typeof value.message === "string" && value.message.startsWith(PI_FAST_ACK)) {
|
|
20889
21599
|
if (this.#fastAcknowledgement?.message === value.message)
|
|
20890
21600
|
this.#fastAcknowledgement.received = true;
|
|
@@ -20898,6 +21608,33 @@ var PiRpcSession = class {
|
|
|
20898
21608
|
}
|
|
20899
21609
|
if (this.#subagents.handle(value))
|
|
20900
21610
|
return;
|
|
21611
|
+
const settling = this.#activeTurn;
|
|
21612
|
+
if (settling && settling.settlement !== "pending" && generation > settling.runGeneration) {
|
|
21613
|
+
this.#deferredRunBytes += Buffer.byteLength(JSON.stringify(value));
|
|
21614
|
+
if (this.#deferredRunBytes > 8 * 1024 * 1024) {
|
|
21615
|
+
this.#fail(new PiRpcFaultError("protocolError", "Pi deferred run exceeded its event buffer bound"));
|
|
21616
|
+
return;
|
|
21617
|
+
}
|
|
21618
|
+
this.#deferredRunFrames.push({ value, generation });
|
|
21619
|
+
return;
|
|
21620
|
+
}
|
|
21621
|
+
if (value.type === "agent_start") {
|
|
21622
|
+
if (this.#activeTurn)
|
|
21623
|
+
this.#activeTurn.runGeneration = generation;
|
|
21624
|
+
else if (!this.#manualCompaction && !this.#compactionActive && (this.#autonomousTurnHandler || this.#autonomousLifecycleHandler))
|
|
21625
|
+
this.#startAutonomousTurn(void 0, generation);
|
|
21626
|
+
return;
|
|
21627
|
+
}
|
|
21628
|
+
if (value.type === "extension_ui_request" && value.method === "setWidget" && value.widgetKey === GOTGENES_WIDGET) {
|
|
21629
|
+
const records = parseGotgenesWidget(value);
|
|
21630
|
+
if (records) {
|
|
21631
|
+
this.#gotgenesLatest = records;
|
|
21632
|
+
this.#gotgenesHandler?.(records, this.#activeTurn?.origin ?? "idle");
|
|
21633
|
+
}
|
|
21634
|
+
return;
|
|
21635
|
+
}
|
|
21636
|
+
if (this.#handleProgress(value))
|
|
21637
|
+
return;
|
|
20901
21638
|
this.#observeUsage(value);
|
|
20902
21639
|
if (value.type === "compaction_start") {
|
|
20903
21640
|
this.#compactionActive = true;
|
|
@@ -20921,7 +21658,7 @@ var PiRpcSession = class {
|
|
|
20921
21658
|
this.#armCommandTimeout(id, pending);
|
|
20922
21659
|
}
|
|
20923
21660
|
}
|
|
20924
|
-
const outcome = value.aborted === true ? "cancelled" :
|
|
21661
|
+
const outcome = value.aborted === true ? "cancelled" : isRecord9(value.result) ? "succeeded" : "failed";
|
|
20925
21662
|
const event = {
|
|
20926
21663
|
type: "compaction.completed",
|
|
20927
21664
|
outcome,
|
|
@@ -20938,8 +21675,8 @@ var PiRpcSession = class {
|
|
|
20938
21675
|
return;
|
|
20939
21676
|
}
|
|
20940
21677
|
let active = this.#activeTurn;
|
|
20941
|
-
if (!active && !this.#manualCompaction && !this.#compactionActive && this.#autonomousTurnHandler && value.type === "message_start" && assistantText(value.message) !== null) {
|
|
20942
|
-
active = this.#startAutonomousTurn(value.message);
|
|
21678
|
+
if (!active && !this.#manualCompaction && !this.#compactionActive && (this.#autonomousTurnHandler || this.#autonomousLifecycleHandler) && value.type === "message_start" && assistantText(value.message) !== null) {
|
|
21679
|
+
active = this.#startAutonomousTurn(value.message, generation);
|
|
20943
21680
|
}
|
|
20944
21681
|
if (!active) {
|
|
20945
21682
|
if (value.type === "extension_ui_request" && this.#isBlockingInteraction(value)) {
|
|
@@ -20959,22 +21696,26 @@ var PiRpcSession = class {
|
|
|
20959
21696
|
this.#startAssistantMessage(active, value.message);
|
|
20960
21697
|
return;
|
|
20961
21698
|
}
|
|
20962
|
-
if (value.type === "message_update" &&
|
|
21699
|
+
if (value.type === "message_update" && isRecord9(value.assistantMessageEvent)) {
|
|
20963
21700
|
const event = value.assistantMessageEvent;
|
|
20964
21701
|
const eventType = String(event.type ?? "");
|
|
20965
21702
|
const isThinking = eventType === "thinking_delta" || eventType === "reasoning_delta" || eventType === "thought_delta" || eventType === "thinking" || eventType === "reasoning";
|
|
20966
21703
|
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
20967
|
-
const delta = typeof event.delta === "string" ? event.delta : typeof event.thinking === "string" ? event.thinking : typeof event.reasoning === "string" ? event.reasoning : typeof event.text === "string" ? event.text :
|
|
20968
|
-
|
|
20969
|
-
|
|
20970
|
-
|
|
20971
|
-
active.
|
|
20972
|
-
active.
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
active.
|
|
20976
|
-
|
|
20977
|
-
|
|
21704
|
+
const delta = typeof event.delta === "string" ? event.delta : typeof event.thinking === "string" ? event.thinking : typeof event.reasoning === "string" ? event.reasoning : typeof event.text === "string" ? event.text : isRecord9(event.delta) && typeof event.delta.thinking === "string" ? event.delta.thinking : isRecord9(event.delta) && typeof event.delta.text === "string" ? event.delta.text : null;
|
|
21705
|
+
const endingReasoning = eventType === "thinking_end" || eventType === "reasoning_end";
|
|
21706
|
+
const endingText = eventType === "text_end";
|
|
21707
|
+
if ((endingReasoning || endingText) && typeof event.content === "string") {
|
|
21708
|
+
this.#ensureAssistantMessage(active, value.message);
|
|
21709
|
+
const stream = endingReasoning ? active.reasoningStream : active.textStream;
|
|
21710
|
+
this.#emitContent(active, endingReasoning, stream.complete(event.contentIndex, event.content));
|
|
21711
|
+
} else if ((isThinking || isText) && delta !== null && delta.length > 0) {
|
|
21712
|
+
this.#ensureAssistantMessage(active, value.message);
|
|
21713
|
+
if (isThinking)
|
|
21714
|
+
active.sawStreamedMessageReasoning = true;
|
|
21715
|
+
else
|
|
21716
|
+
active.sawStreamedMessageText = true;
|
|
21717
|
+
const stream = isThinking ? active.reasoningStream : active.textStream;
|
|
21718
|
+
this.#emitContent(active, isThinking, stream.append(event.contentIndex, delta));
|
|
20978
21719
|
} else if (event.type === "error") {
|
|
20979
21720
|
this.#ensureAssistantMessage(active, value.message);
|
|
20980
21721
|
active.failure = assistantFailure(event.error) ?? assistantFailure(value.message) ?? new Error("Pi assistant message failed");
|
|
@@ -21005,25 +21746,36 @@ var PiRpcSession = class {
|
|
|
21005
21746
|
if (active.settlement !== "pending")
|
|
21006
21747
|
return;
|
|
21007
21748
|
active.settlement = "confirming";
|
|
21008
|
-
void this.#confirmSettledTurn(active);
|
|
21749
|
+
void this.#confirmSettledTurn(active, active.runGeneration);
|
|
21009
21750
|
}
|
|
21010
21751
|
}
|
|
21011
|
-
#startAutonomousTurn(value) {
|
|
21752
|
+
#startAutonomousTurn(value, generation) {
|
|
21012
21753
|
const events = [];
|
|
21754
|
+
const runId = randomUUID6();
|
|
21013
21755
|
const active = {
|
|
21014
21756
|
origin: "autonomous",
|
|
21757
|
+
autonomousRunId: runId,
|
|
21758
|
+
runGeneration: generation,
|
|
21015
21759
|
autonomousEvents: events,
|
|
21016
|
-
...
|
|
21760
|
+
...isRecord9(value) ? { autonomousMessage: value } : {},
|
|
21017
21761
|
nativeTurnKey: null,
|
|
21018
21762
|
nativeCancellationObserved: false,
|
|
21019
21763
|
text: "",
|
|
21020
21764
|
assistantMessageId: null,
|
|
21765
|
+
assistantNativeMessageIdentity: void 0,
|
|
21766
|
+
textStream: new PiContentStream("text"),
|
|
21767
|
+
reasoningStream: new PiContentStream("reasoning"),
|
|
21021
21768
|
sawStreamedMessageText: false,
|
|
21022
21769
|
sawStreamedMessageReasoning: false,
|
|
21023
21770
|
lastFinalizedMessageText: null,
|
|
21024
21771
|
lastFinalizedMessageReasoning: null,
|
|
21025
21772
|
reasoningMessageOpen: false,
|
|
21026
|
-
onEvent: (event) =>
|
|
21773
|
+
onEvent: (event) => {
|
|
21774
|
+
if (this.#autonomousLifecycleHandler)
|
|
21775
|
+
this.#autonomousLifecycleHandler({ type: "event", runId, event });
|
|
21776
|
+
else
|
|
21777
|
+
events.push(event);
|
|
21778
|
+
},
|
|
21027
21779
|
resolve: () => void 0,
|
|
21028
21780
|
reject: () => void 0,
|
|
21029
21781
|
failure: null,
|
|
@@ -21036,19 +21788,108 @@ var PiRpcSession = class {
|
|
|
21036
21788
|
abortPromise: null
|
|
21037
21789
|
};
|
|
21038
21790
|
this.#activeTurn = active;
|
|
21791
|
+
this.#autonomousLifecycleHandler?.({ type: "started", runId });
|
|
21792
|
+
this.#drainProgress(active.onEvent);
|
|
21039
21793
|
return active;
|
|
21040
21794
|
}
|
|
21795
|
+
#handleProgress(value) {
|
|
21796
|
+
if ((value.type === "message_start" || value.type === "message_end") && isRecord9(value.message) && value.message.role === "custom") {
|
|
21797
|
+
if (value.type !== "message_end" || !this.#state)
|
|
21798
|
+
return true;
|
|
21799
|
+
const key = piCustomNoticeKey(value.message);
|
|
21800
|
+
if (!key)
|
|
21801
|
+
return true;
|
|
21802
|
+
const timestamp = value.message.timestamp;
|
|
21803
|
+
if ((typeof timestamp === "number" || typeof timestamp === "string") && !this.#acceptNoticeFrame(JSON.stringify([key, timestamp])))
|
|
21804
|
+
return true;
|
|
21805
|
+
const progress = piCustomNotice(value.message, this.state.sessionId, this.#noticeOccurrences);
|
|
21806
|
+
if (progress)
|
|
21807
|
+
this.#publishProgress(progress);
|
|
21808
|
+
return true;
|
|
21809
|
+
}
|
|
21810
|
+
if (value.type === "extension_ui_request" && value.method === "setStatus") {
|
|
21811
|
+
if (typeof value.statusKey !== "string")
|
|
21812
|
+
return true;
|
|
21813
|
+
if (typeof value.statusText !== "string" || !value.statusText.trim()) {
|
|
21814
|
+
if (!this.#extensionStatuses.has(value.statusKey))
|
|
21815
|
+
return true;
|
|
21816
|
+
this.#extensionStatuses.delete(value.statusKey);
|
|
21817
|
+
} else {
|
|
21818
|
+
if (this.#extensionStatuses.get(value.statusKey) === value.statusText)
|
|
21819
|
+
return true;
|
|
21820
|
+
this.#extensionStatuses.set(value.statusKey, value.statusText);
|
|
21821
|
+
}
|
|
21822
|
+
}
|
|
21823
|
+
const text3 = piStatusText(value);
|
|
21824
|
+
if (!text3)
|
|
21825
|
+
return false;
|
|
21826
|
+
if (value.type === "extension_ui_request" && typeof value.id === "string" && !this.#acceptNoticeFrame(JSON.stringify([value.type, value.id])))
|
|
21827
|
+
return true;
|
|
21828
|
+
this.#publishProgress({
|
|
21829
|
+
type: "progress.message",
|
|
21830
|
+
itemId: hostItemIdSchema.parse(`pi-progress-${randomUUID6()}`),
|
|
21831
|
+
text: text3
|
|
21832
|
+
}, value.method === "setStatus" && typeof value.statusKey === "string" ? value.statusKey : void 0);
|
|
21833
|
+
return true;
|
|
21834
|
+
}
|
|
21835
|
+
#acceptNoticeFrame(key) {
|
|
21836
|
+
if (this.#seenNoticeFrames.has(key))
|
|
21837
|
+
return false;
|
|
21838
|
+
this.#seenNoticeFrames.add(key);
|
|
21839
|
+
if (this.#seenNoticeFrames.size > 512)
|
|
21840
|
+
this.#seenNoticeFrames.delete(this.#seenNoticeFrames.values().next().value);
|
|
21841
|
+
return true;
|
|
21842
|
+
}
|
|
21843
|
+
#publishProgress(progress, statusKey) {
|
|
21844
|
+
if (this.#activeTurn?.settlement === "pending") {
|
|
21845
|
+
this.#activeTurn.onEvent(progress);
|
|
21846
|
+
return;
|
|
21847
|
+
}
|
|
21848
|
+
if (statusKey !== void 0) {
|
|
21849
|
+
const previous = this.#pendingProgress.findIndex((pending) => pending.statusKey === statusKey);
|
|
21850
|
+
if (previous >= 0)
|
|
21851
|
+
this.#pendingProgress.splice(previous, 1);
|
|
21852
|
+
}
|
|
21853
|
+
if (this.#pendingProgress.length >= 128) {
|
|
21854
|
+
this.#pendingProgress.shift();
|
|
21855
|
+
this.#omittedProgress += 1;
|
|
21856
|
+
}
|
|
21857
|
+
this.#pendingProgress.push({
|
|
21858
|
+
event: progress,
|
|
21859
|
+
...statusKey !== void 0 ? { statusKey } : {}
|
|
21860
|
+
});
|
|
21861
|
+
}
|
|
21862
|
+
#drainProgress(onEvent) {
|
|
21863
|
+
if (this.#omittedProgress > 0) {
|
|
21864
|
+
onEvent({
|
|
21865
|
+
type: "progress.message",
|
|
21866
|
+
itemId: hostItemIdSchema.parse(`pi-progress-${randomUUID6()}`),
|
|
21867
|
+
text: `Pi notifications: ${this.#omittedProgress} earlier updates were not retained while idle. Persisted notifications remain available in conversation history.`
|
|
21868
|
+
});
|
|
21869
|
+
this.#omittedProgress = 0;
|
|
21870
|
+
}
|
|
21871
|
+
for (const pending of this.#pendingProgress.splice(0))
|
|
21872
|
+
onEvent(pending.event);
|
|
21873
|
+
}
|
|
21041
21874
|
#emitAutonomousTurn(active, result) {
|
|
21042
21875
|
const handler = this.#autonomousTurnHandler;
|
|
21043
|
-
if (active.origin !== "autonomous" || !active.autonomousEvents || !
|
|
21876
|
+
if (active.origin !== "autonomous" || !active.autonomousEvents || !active.autonomousRunId) {
|
|
21044
21877
|
return;
|
|
21045
21878
|
}
|
|
21046
21879
|
try {
|
|
21047
|
-
|
|
21880
|
+
const turn = {
|
|
21048
21881
|
nativeTurnKey: active.nativeTurnKey,
|
|
21049
21882
|
events: [...active.autonomousEvents],
|
|
21050
21883
|
result
|
|
21051
|
-
}
|
|
21884
|
+
};
|
|
21885
|
+
if (this.#autonomousLifecycleHandler)
|
|
21886
|
+
this.#autonomousLifecycleHandler({
|
|
21887
|
+
type: "completed",
|
|
21888
|
+
runId: active.autonomousRunId,
|
|
21889
|
+
turn
|
|
21890
|
+
});
|
|
21891
|
+
else
|
|
21892
|
+
handler?.(turn);
|
|
21052
21893
|
} catch (error51) {
|
|
21053
21894
|
this.#fail(new PiRpcFaultError("protocolError", `Pi autonomous Turn handler failed: ${message2(error51)}`));
|
|
21054
21895
|
}
|
|
@@ -21195,31 +22036,73 @@ var PiRpcSession = class {
|
|
|
21195
22036
|
isError: value.isError
|
|
21196
22037
|
});
|
|
21197
22038
|
}
|
|
21198
|
-
|
|
22039
|
+
#isSettlementCurrent(active, generation) {
|
|
22040
|
+
return this.#activeTurn === active && active.runGeneration === generation && active.settlement === "confirming";
|
|
22041
|
+
}
|
|
22042
|
+
#waitForNextRun(generation) {
|
|
22043
|
+
if (this.#runGeneration > generation)
|
|
22044
|
+
return Promise.resolve();
|
|
22045
|
+
return new Promise((resolve, reject) => {
|
|
22046
|
+
const finish = (error51) => {
|
|
22047
|
+
clearTimeout(timer);
|
|
22048
|
+
this.#runWaiters.delete(waiter);
|
|
22049
|
+
if (error51)
|
|
22050
|
+
reject(error51);
|
|
22051
|
+
else
|
|
22052
|
+
resolve();
|
|
22053
|
+
};
|
|
22054
|
+
const waiter = {
|
|
22055
|
+
check: () => {
|
|
22056
|
+
if (this.#runGeneration > generation)
|
|
22057
|
+
finish();
|
|
22058
|
+
},
|
|
22059
|
+
reject: (error51) => finish(error51)
|
|
22060
|
+
};
|
|
22061
|
+
const timer = setTimeout(() => finish(new PiRpcFaultError("protocolError", "Pi RPC agent_settled state is still Streaming without a subsequent agent_start")), this.#options.commandTimeoutMs);
|
|
22062
|
+
this.#runWaiters.add(waiter);
|
|
22063
|
+
});
|
|
22064
|
+
}
|
|
22065
|
+
#drainDeferredRunFrames() {
|
|
22066
|
+
const frames = this.#deferredRunFrames;
|
|
22067
|
+
this.#deferredRunFrames = [];
|
|
22068
|
+
this.#deferredRunBytes = 0;
|
|
22069
|
+
for (const frame of frames) {
|
|
22070
|
+
if (this.#closed || this.#failed)
|
|
22071
|
+
break;
|
|
22072
|
+
this.#handle(frame.value, frame.generation);
|
|
22073
|
+
}
|
|
22074
|
+
}
|
|
22075
|
+
async #confirmSettledTurn(active, generation) {
|
|
21199
22076
|
try {
|
|
21200
22077
|
const response = await this.#send("get_state", {});
|
|
21201
22078
|
const state2 = parseSessionState(response);
|
|
21202
|
-
if (
|
|
21203
|
-
|
|
21204
|
-
|
|
21205
|
-
|
|
22079
|
+
if (!this.#isSettlementCurrent(active, generation))
|
|
22080
|
+
return;
|
|
22081
|
+
if (parseSessionStreaming(response))
|
|
22082
|
+
await this.#waitForNextRun(generation);
|
|
22083
|
+
if (!this.#isSettlementCurrent(active, generation))
|
|
21206
22084
|
return;
|
|
21207
|
-
if (active.origin === "autonomous") {
|
|
22085
|
+
if (active.origin === "autonomous" && active.autonomousMessage) {
|
|
21208
22086
|
const history = await this.getEntries();
|
|
21209
22087
|
const snapshot = mapPiSnapshot(history, { sessionId: state2.sessionId, model: null });
|
|
21210
|
-
|
|
22088
|
+
if (!this.#isSettlementCurrent(active, generation))
|
|
22089
|
+
return;
|
|
21211
22090
|
const entries = activePiEntries(history);
|
|
21212
|
-
const start = entries.findIndex((entry) => entry.id === turn?.nativeTurnRef.nativeTurnKey);
|
|
21213
|
-
const firstAssistant = entries.slice(start + 1).find((entry) => isRecord8(entry.message) && entry.message.role === "assistant")?.message;
|
|
21214
22091
|
const live = active.autonomousMessage;
|
|
21215
22092
|
const responseId = assistantMessageId(live);
|
|
21216
|
-
const matches =
|
|
21217
|
-
|
|
22093
|
+
const matches = snapshot.turns.filter((turn2) => {
|
|
22094
|
+
if (turn2.input.length !== 0)
|
|
22095
|
+
return false;
|
|
22096
|
+
const start = entries.findIndex((entry) => entry.id === turn2.nativeTurnRef.nativeTurnKey);
|
|
22097
|
+
const firstAssistant = entries.slice(start + 1).find((entry) => isRecord9(entry.message) && entry.message.role === "assistant")?.message;
|
|
22098
|
+
return isRecord9(firstAssistant) && (responseId ? assistantMessageId(firstAssistant) === responseId : typeof live?.timestamp === "number" && firstAssistant.timestamp === live.timestamp);
|
|
22099
|
+
});
|
|
22100
|
+
const turn = matches.length === 1 ? matches[0] : void 0;
|
|
22101
|
+
if (!turn)
|
|
21218
22102
|
throw new PiRpcFaultError("protocolError", "Pi autonomous Turn has no matching persisted custom Entry");
|
|
21219
|
-
}
|
|
21220
22103
|
active.nativeTurnKey = turn.nativeTurnRef.nativeTurnKey;
|
|
21221
22104
|
}
|
|
21222
|
-
if (this.#
|
|
22105
|
+
if (!this.#isSettlementCurrent(active, generation))
|
|
21223
22106
|
return;
|
|
21224
22107
|
this.#state = state2;
|
|
21225
22108
|
active.settlement = "confirmed";
|
|
@@ -21245,7 +22128,13 @@ var PiRpcSession = class {
|
|
|
21245
22128
|
}
|
|
21246
22129
|
this.#activeTurn = null;
|
|
21247
22130
|
if (active.origin === "autonomous") {
|
|
21248
|
-
if (active.
|
|
22131
|
+
if (active.cancellation === "accepted") {
|
|
22132
|
+
this.#emitAutonomousTurn(active, {
|
|
22133
|
+
status: "cancelled",
|
|
22134
|
+
text: active.text,
|
|
22135
|
+
reason: "Cancelled by user"
|
|
22136
|
+
});
|
|
22137
|
+
} else if (active.failure) {
|
|
21249
22138
|
this.#emitAutonomousTurn(active, active.nativeCancellationObserved ? {
|
|
21250
22139
|
status: "cancelled",
|
|
21251
22140
|
text: active.text,
|
|
@@ -21260,6 +22149,7 @@ var PiRpcSession = class {
|
|
|
21260
22149
|
} else {
|
|
21261
22150
|
this.#emitAutonomousTurn(active, { status: "succeeded", text: active.text });
|
|
21262
22151
|
}
|
|
22152
|
+
this.#drainDeferredRunFrames();
|
|
21263
22153
|
return;
|
|
21264
22154
|
}
|
|
21265
22155
|
if (active.cancellation === "accepted") {
|
|
@@ -21271,20 +22161,56 @@ var PiRpcSession = class {
|
|
|
21271
22161
|
} else {
|
|
21272
22162
|
active.resolve({ text: active.text, cancelled: false });
|
|
21273
22163
|
}
|
|
22164
|
+
this.#drainDeferredRunFrames();
|
|
22165
|
+
}
|
|
22166
|
+
#emitContent(active, reasoning, delta) {
|
|
22167
|
+
if (delta.length === 0)
|
|
22168
|
+
return;
|
|
22169
|
+
const messageId = active.assistantMessageId;
|
|
22170
|
+
if (messageId === null)
|
|
22171
|
+
throw new Error("Pi content arrived outside an Assistant message");
|
|
22172
|
+
if (reasoning) {
|
|
22173
|
+
active.reasoningMessageOpen = true;
|
|
22174
|
+
active.sawStreamedMessageReasoning = true;
|
|
22175
|
+
} else {
|
|
22176
|
+
active.text += delta;
|
|
22177
|
+
active.sawStreamedMessageText = true;
|
|
22178
|
+
}
|
|
22179
|
+
active.onEvent({
|
|
22180
|
+
type: reasoning ? "reasoning.delta" : "text.delta",
|
|
22181
|
+
messageId,
|
|
22182
|
+
...nativeMessageIdentity(active),
|
|
22183
|
+
delta
|
|
22184
|
+
});
|
|
21274
22185
|
}
|
|
21275
22186
|
#startAssistantMessage(active, value) {
|
|
22187
|
+
if (active.origin === "autonomous" && !active.autonomousMessage && isRecord9(value))
|
|
22188
|
+
active.autonomousMessage = value;
|
|
21276
22189
|
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
21277
22190
|
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
21278
22191
|
}
|
|
21279
|
-
const
|
|
22192
|
+
const nativeResponseId = assistantMessageId(value);
|
|
22193
|
+
const messageId = nativeResponseId ?? randomUUID6();
|
|
21280
22194
|
active.assistantMessageId = messageId;
|
|
22195
|
+
active.assistantNativeMessageIdentity = piMessageIdentity(this.state.sessionId, value, this.#messageTimestampCounts);
|
|
22196
|
+
active.textStream = new PiContentStream("text");
|
|
22197
|
+
active.reasoningStream = new PiContentStream("reasoning");
|
|
21281
22198
|
active.sawStreamedMessageText = false;
|
|
21282
22199
|
active.sawStreamedMessageReasoning = false;
|
|
21283
22200
|
active.reasoningMessageOpen = false;
|
|
21284
22201
|
return messageId;
|
|
21285
22202
|
}
|
|
21286
22203
|
#ensureAssistantMessage(active, value) {
|
|
21287
|
-
|
|
22204
|
+
if (active.assistantMessageId === null)
|
|
22205
|
+
return this.#startAssistantMessage(active, value);
|
|
22206
|
+
if (!active.sawStreamedMessageText && !active.sawStreamedMessageReasoning) {
|
|
22207
|
+
const nativeResponseId = assistantMessageId(value);
|
|
22208
|
+
if (nativeResponseId) {
|
|
22209
|
+
active.assistantMessageId = nativeResponseId;
|
|
22210
|
+
active.assistantNativeMessageIdentity ??= { responseId: nativeResponseId };
|
|
22211
|
+
}
|
|
22212
|
+
}
|
|
22213
|
+
return active.assistantMessageId;
|
|
21288
22214
|
}
|
|
21289
22215
|
#finalizeAssistantMessage(active, value) {
|
|
21290
22216
|
const finalText = assistantText(value);
|
|
@@ -21297,29 +22223,33 @@ var PiRpcSession = class {
|
|
|
21297
22223
|
return;
|
|
21298
22224
|
}
|
|
21299
22225
|
active.failure = failure;
|
|
21300
|
-
if (active.origin === "autonomous" &&
|
|
22226
|
+
if (active.origin === "autonomous" && piAssistantWasAborted(value)) {
|
|
21301
22227
|
active.nativeCancellationObserved = true;
|
|
21302
22228
|
}
|
|
21303
22229
|
this.#latestCacheHitRatePercent = cacheHitRatePercent;
|
|
21304
22230
|
const messageId = this.#ensureAssistantMessage(active, value);
|
|
21305
|
-
|
|
21306
|
-
|
|
21307
|
-
active
|
|
22231
|
+
const content = value.content;
|
|
22232
|
+
if (failure === null || !active.sawStreamedMessageReasoning) {
|
|
22233
|
+
this.#emitContent(active, true, active.reasoningStream.finalize(content.flatMap((part, index) => {
|
|
22234
|
+
const text3 = extractReasoningText(part);
|
|
22235
|
+
return text3 === null ? [] : [{ index, text: text3 }];
|
|
22236
|
+
})));
|
|
21308
22237
|
}
|
|
21309
22238
|
if (active.reasoningMessageOpen && active.failure === null) {
|
|
21310
22239
|
active.onEvent({ type: "reasoning.completed", messageId });
|
|
21311
22240
|
}
|
|
21312
|
-
if (!active.sawStreamedMessageText
|
|
21313
|
-
active.text
|
|
21314
|
-
active.onEvent({ type: "text.delta", messageId, delta: finalText });
|
|
22241
|
+
if (failure === null || !active.sawStreamedMessageText) {
|
|
22242
|
+
this.#emitContent(active, false, active.textStream.finalize(content.flatMap((part, index) => isRecord9(part) && part.type === "text" && typeof part.text === "string" ? [{ index, text: part.text }] : [])));
|
|
21315
22243
|
}
|
|
21316
22244
|
active.assistantMessageId = null;
|
|
22245
|
+
active.assistantNativeMessageIdentity = void 0;
|
|
21317
22246
|
active.sawStreamedMessageText = false;
|
|
21318
22247
|
active.sawStreamedMessageReasoning = false;
|
|
21319
22248
|
active.reasoningMessageOpen = false;
|
|
21320
22249
|
active.lastFinalizedMessageText = finalText;
|
|
21321
22250
|
active.lastFinalizedMessageReasoning = finalReasoning;
|
|
21322
|
-
|
|
22251
|
+
const phase = piAssistantPhase(value);
|
|
22252
|
+
active.onEvent({ type: "message.completed", messageId, ...phase ? { phase } : {} });
|
|
21323
22253
|
}
|
|
21324
22254
|
#write(value) {
|
|
21325
22255
|
const child = this.#child;
|
|
@@ -21337,7 +22267,7 @@ var PiRpcSession = class {
|
|
|
21337
22267
|
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
21338
22268
|
return Promise.reject(new Error("Pi RPC stdin is unavailable"));
|
|
21339
22269
|
}
|
|
21340
|
-
const id = `codexhost-${
|
|
22270
|
+
const id = `codexhost-${randomUUID6()}`;
|
|
21341
22271
|
return new Promise((resolve, reject) => {
|
|
21342
22272
|
const pending = {
|
|
21343
22273
|
command: type,
|
|
@@ -21427,9 +22357,16 @@ var PiRpcSession = class {
|
|
|
21427
22357
|
} else {
|
|
21428
22358
|
active.reject(error51);
|
|
21429
22359
|
}
|
|
22360
|
+
this.#drainDeferredRunFrames();
|
|
21430
22361
|
}
|
|
21431
22362
|
#rejectAll(error51) {
|
|
22363
|
+
for (const waiter of this.#runWaiters)
|
|
22364
|
+
waiter.reject(error51);
|
|
22365
|
+
this.#deferredRunFrames = [];
|
|
22366
|
+
this.#deferredRunBytes = 0;
|
|
21432
22367
|
this.#subagents.close(error51);
|
|
22368
|
+
this.#gotgenesHandler = void 0;
|
|
22369
|
+
this.#gotgenesLatest = void 0;
|
|
21433
22370
|
for (const pending of this.#pending.values()) {
|
|
21434
22371
|
if (pending.timeout)
|
|
21435
22372
|
clearTimeout(pending.timeout);
|
|
@@ -21465,7 +22402,7 @@ var piCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
|
21465
22402
|
]
|
|
21466
22403
|
});
|
|
21467
22404
|
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
21468
|
-
function
|
|
22405
|
+
function isRecord10(value) {
|
|
21469
22406
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21470
22407
|
}
|
|
21471
22408
|
function errorMessage(error51) {
|
|
@@ -21480,7 +22417,9 @@ var PiAdapterFaultError = class extends Error {
|
|
|
21480
22417
|
}
|
|
21481
22418
|
};
|
|
21482
22419
|
function normalizedError(error51, fallbackCode) {
|
|
21483
|
-
if (
|
|
22420
|
+
if (error51 instanceof PiRpcBusyError)
|
|
22421
|
+
return { code: "sessionBusy", message: error51.message, retryable: true };
|
|
22422
|
+
if (isRecord10(error51) && error51.code === "ENOENT") {
|
|
21484
22423
|
return { code: "notInstalled", message: errorMessage(error51), retryable: false };
|
|
21485
22424
|
}
|
|
21486
22425
|
if (error51 instanceof PiAdapterFaultError)
|
|
@@ -21543,7 +22482,7 @@ function nativeModelForHistory(state2) {
|
|
|
21543
22482
|
return nativeModelFromState(state2);
|
|
21544
22483
|
}
|
|
21545
22484
|
function sessionFileFromRef(ref) {
|
|
21546
|
-
if (ref.harnessId !== piHarnessId2 || !
|
|
22485
|
+
if (ref.harnessId !== piHarnessId2 || !isRecord10(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
|
|
21547
22486
|
throw new Error("Pi Native Session Ref has no resumable Session file");
|
|
21548
22487
|
}
|
|
21549
22488
|
return ref.locator.sessionFile;
|
|
@@ -21558,83 +22497,29 @@ function toolFailure(toolName) {
|
|
|
21558
22497
|
function nativeText(value) {
|
|
21559
22498
|
if (typeof value === "string")
|
|
21560
22499
|
return value;
|
|
21561
|
-
if (!
|
|
22500
|
+
if (!isRecord10(value) || !Array.isArray(value.content))
|
|
21562
22501
|
return "";
|
|
21563
|
-
return value.content.filter((content) =>
|
|
22502
|
+
return value.content.filter((content) => isRecord10(content) && content.type === "text" && typeof content.text === "string").map(({ text: text3 }) => text3).join("");
|
|
21564
22503
|
}
|
|
21565
22504
|
function boundedOutput(value, limit) {
|
|
21566
|
-
const
|
|
21567
|
-
if (
|
|
22505
|
+
const text3 = nativeText(value);
|
|
22506
|
+
if (text3.length === 0)
|
|
21568
22507
|
return void 0;
|
|
21569
|
-
const truncated =
|
|
22508
|
+
const truncated = text3.length > limit;
|
|
21570
22509
|
return {
|
|
21571
|
-
content: [{ type: "text", text: truncated ?
|
|
22510
|
+
content: [{ type: "text", text: truncated ? text3.slice(0, limit) : text3 }],
|
|
21572
22511
|
...truncated ? { truncated: true } : {}
|
|
21573
22512
|
};
|
|
21574
22513
|
}
|
|
21575
22514
|
function outputText(output) {
|
|
21576
|
-
return output?.content.filter((content) => content.type === "text").map(({ text:
|
|
21577
|
-
}
|
|
21578
|
-
function stringField(value, key) {
|
|
21579
|
-
if (!isRecord9(value))
|
|
21580
|
-
return void 0;
|
|
21581
|
-
const field2 = value[key];
|
|
21582
|
-
if (typeof field2 === "string" && field2.length > 0)
|
|
21583
|
-
return field2;
|
|
21584
|
-
if (isRecord9(value.input)) {
|
|
21585
|
-
const nested = value.input[key];
|
|
21586
|
-
if (typeof nested === "string" && nested.length > 0)
|
|
21587
|
-
return nested;
|
|
21588
|
-
}
|
|
21589
|
-
if (isRecord9(value.arguments)) {
|
|
21590
|
-
const nested = value.arguments[key];
|
|
21591
|
-
if (typeof nested === "string" && nested.length > 0)
|
|
21592
|
-
return nested;
|
|
21593
|
-
}
|
|
21594
|
-
return void 0;
|
|
22515
|
+
return output?.content.filter((content) => content.type === "text").map(({ text: text3 }) => text3).join("") ?? "";
|
|
21595
22516
|
}
|
|
21596
22517
|
function numberField(value, key) {
|
|
21597
|
-
if (!
|
|
22518
|
+
if (!isRecord10(value))
|
|
21598
22519
|
return void 0;
|
|
21599
22520
|
const field2 = value[key];
|
|
21600
22521
|
return typeof field2 === "number" || field2 === null ? field2 : void 0;
|
|
21601
22522
|
}
|
|
21602
|
-
function normalizeToolName(name) {
|
|
21603
|
-
const lower = name.toLowerCase();
|
|
21604
|
-
switch (lower) {
|
|
21605
|
-
case "bash":
|
|
21606
|
-
case "exec":
|
|
21607
|
-
case "terminal":
|
|
21608
|
-
case "run":
|
|
21609
|
-
return "bash";
|
|
21610
|
-
case "read":
|
|
21611
|
-
case "read_file":
|
|
21612
|
-
case "fileread":
|
|
21613
|
-
return "Read";
|
|
21614
|
-
case "edit":
|
|
21615
|
-
case "edit_file":
|
|
21616
|
-
case "fileedit":
|
|
21617
|
-
return "Edit";
|
|
21618
|
-
case "write":
|
|
21619
|
-
case "write_file":
|
|
21620
|
-
case "filewrite":
|
|
21621
|
-
return "Write";
|
|
21622
|
-
case "grep":
|
|
21623
|
-
case "grep_search":
|
|
21624
|
-
return "Grep";
|
|
21625
|
-
case "find":
|
|
21626
|
-
case "glob":
|
|
21627
|
-
case "find_files":
|
|
21628
|
-
return "Glob";
|
|
21629
|
-
case "todo":
|
|
21630
|
-
return "Todo";
|
|
21631
|
-
case "web_search":
|
|
21632
|
-
case "websearch":
|
|
21633
|
-
return "WebSearch";
|
|
21634
|
-
default:
|
|
21635
|
-
return name.length > 0 ? `${name[0]?.toUpperCase() ?? ""}${name.slice(1)}` : name;
|
|
21636
|
-
}
|
|
21637
|
-
}
|
|
21638
22523
|
function delay(milliseconds) {
|
|
21639
22524
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
21640
22525
|
}
|
|
@@ -21662,6 +22547,8 @@ var PiHarnessSession = class {
|
|
|
21662
22547
|
#configuring = false;
|
|
21663
22548
|
#phase = "open";
|
|
21664
22549
|
#pendingAutonomousTurns = [];
|
|
22550
|
+
#pendingAutonomousLifecycle = [];
|
|
22551
|
+
#pendingAutonomousLifecycleBytes = 0;
|
|
21665
22552
|
#starting = null;
|
|
21666
22553
|
#state = {};
|
|
21667
22554
|
#transport = null;
|
|
@@ -21710,13 +22597,20 @@ var PiHarnessSession = class {
|
|
|
21710
22597
|
return this.#transport?.state.sessionId === id;
|
|
21711
22598
|
}
|
|
21712
22599
|
async readSubagentHistory(cwd) {
|
|
21713
|
-
if (this.#phase !== "open" ||
|
|
22600
|
+
if (this.#phase !== "open" || path16.resolve(cwd) !== path16.resolve(this.#cwd)) {
|
|
21714
22601
|
throw new Error("Pi Subagent parent workspace or Session is unavailable");
|
|
21715
22602
|
}
|
|
21716
22603
|
return (await this.#ensureTransport()).getEntries();
|
|
21717
22604
|
}
|
|
22605
|
+
async readGotgenesChild(id, cwd) {
|
|
22606
|
+
const history = await this.readSubagentHistory(cwd);
|
|
22607
|
+
const transport = this.#transport;
|
|
22608
|
+
if (!transport)
|
|
22609
|
+
throw new Error("Pi parent Session is closed");
|
|
22610
|
+
return readGotgenesChild(history, transport.state.sessionId, id, this.#subagents.gotgenes.records.get(id));
|
|
22611
|
+
}
|
|
21718
22612
|
async inspectSubagent(id, cwd) {
|
|
21719
|
-
if (this.#phase !== "open" ||
|
|
22613
|
+
if (this.#phase !== "open" || path16.resolve(cwd) !== path16.resolve(this.#cwd)) {
|
|
21720
22614
|
throw new Error("Pi Subagent parent workspace or Session is unavailable");
|
|
21721
22615
|
}
|
|
21722
22616
|
const transport = await this.#ensureTransport();
|
|
@@ -21784,7 +22678,7 @@ var PiHarnessSession = class {
|
|
|
21784
22678
|
}
|
|
21785
22679
|
};
|
|
21786
22680
|
}
|
|
21787
|
-
if (this.#acceptingTurn || this.#active || this.#configuring) {
|
|
22681
|
+
if (this.#acceptingTurn || this.#active || this.#configuring || this.#transport?.isBusy) {
|
|
21788
22682
|
return {
|
|
21789
22683
|
ok: false,
|
|
21790
22684
|
error: {
|
|
@@ -21794,8 +22688,8 @@ var PiHarnessSession = class {
|
|
|
21794
22688
|
}
|
|
21795
22689
|
};
|
|
21796
22690
|
}
|
|
21797
|
-
const
|
|
21798
|
-
if (
|
|
22691
|
+
const text3 = command.input.map((input) => input.text).join("\n");
|
|
22692
|
+
if (text3.length === 0) {
|
|
21799
22693
|
return {
|
|
21800
22694
|
ok: false,
|
|
21801
22695
|
error: {
|
|
@@ -21825,6 +22719,9 @@ var PiHarnessSession = class {
|
|
|
21825
22719
|
} catch (error51) {
|
|
21826
22720
|
return { ok: false, error: normalizedError(error51, "protocolError") };
|
|
21827
22721
|
}
|
|
22722
|
+
if (this.#active || transport.isBusy || this.#pendingAutonomousLifecycle.length > 0 || this.#pendingAutonomousTurns.length > 0) {
|
|
22723
|
+
return { ok: false, error: normalizedError(new PiRpcBusyError(), "sessionBusy") };
|
|
22724
|
+
}
|
|
21828
22725
|
let resolveCompletion = () => void 0;
|
|
21829
22726
|
const completion = new Promise((resolve) => {
|
|
21830
22727
|
resolveCompletion = resolve;
|
|
@@ -21845,21 +22742,27 @@ var PiHarnessSession = class {
|
|
|
21845
22742
|
interactions: /* @__PURE__ */ new Map(),
|
|
21846
22743
|
interactionByNativeId: /* @__PURE__ */ new Map(),
|
|
21847
22744
|
cancellationRequested: false,
|
|
22745
|
+
settling: false,
|
|
21848
22746
|
beforeNativeTurnKeys: new Set(beforeHistory.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey)),
|
|
22747
|
+
progressItems: /* @__PURE__ */ new Set(),
|
|
21849
22748
|
completion,
|
|
21850
22749
|
resolveCompletion
|
|
21851
22750
|
};
|
|
21852
22751
|
this.#active = active;
|
|
21853
22752
|
this.#event({ type: "turn.started", turnId: command.turnId });
|
|
21854
22753
|
this.#event({ type: "item.started", turnId: command.turnId, item });
|
|
21855
|
-
void transport.runTurn(
|
|
22754
|
+
void transport.runTurn(text3, (event) => this.#handleTurnEvent(active, event)).then(async (result) => {
|
|
22755
|
+
active.settling = true;
|
|
21856
22756
|
try {
|
|
21857
22757
|
const identity = await this.#completedTurnIdentity(active, transport);
|
|
21858
22758
|
this.#completeTurn(active, result.cancelled ? {
|
|
21859
22759
|
status: "cancelled",
|
|
21860
22760
|
reason: "Cancelled by user",
|
|
21861
|
-
checkpoint: identity.checkpoint
|
|
21862
|
-
} : {
|
|
22761
|
+
...identity.checkpoint ? { checkpoint: identity.checkpoint } : {}
|
|
22762
|
+
} : {
|
|
22763
|
+
status: "succeeded",
|
|
22764
|
+
...identity.checkpoint ? { checkpoint: identity.checkpoint } : {}
|
|
22765
|
+
}, result.text, identity.nativeTurnRef);
|
|
21863
22766
|
} catch (error51) {
|
|
21864
22767
|
this.#completeTurn(active, {
|
|
21865
22768
|
status: "failed",
|
|
@@ -21867,6 +22770,7 @@ var PiHarnessSession = class {
|
|
|
21867
22770
|
});
|
|
21868
22771
|
}
|
|
21869
22772
|
}).catch(async (error51) => {
|
|
22773
|
+
active.settling = true;
|
|
21870
22774
|
let identity;
|
|
21871
22775
|
try {
|
|
21872
22776
|
identity = await this.#completedTurnIdentity(active, transport);
|
|
@@ -21875,12 +22779,14 @@ var PiHarnessSession = class {
|
|
|
21875
22779
|
this.#completeTurn(active, {
|
|
21876
22780
|
status: "failed",
|
|
21877
22781
|
error: normalizedError(error51, "nativeFailure"),
|
|
21878
|
-
...identity ? { checkpoint: identity.checkpoint } : {}
|
|
22782
|
+
...identity?.checkpoint ? { checkpoint: identity.checkpoint } : {}
|
|
21879
22783
|
}, void 0, identity?.nativeTurnRef);
|
|
21880
22784
|
});
|
|
21881
22785
|
return { ok: true, value: { turnId: command.turnId } };
|
|
21882
22786
|
} finally {
|
|
21883
22787
|
this.#acceptingTurn = false;
|
|
22788
|
+
if (this.#transport)
|
|
22789
|
+
this.#drainPendingAutonomousTurns(this.#transport);
|
|
21884
22790
|
}
|
|
21885
22791
|
}
|
|
21886
22792
|
close() {
|
|
@@ -22008,6 +22914,8 @@ var PiHarnessSession = class {
|
|
|
22008
22914
|
return { ok: true, value: { completed: true } };
|
|
22009
22915
|
} finally {
|
|
22010
22916
|
this.#configuring = false;
|
|
22917
|
+
if (this.#transport)
|
|
22918
|
+
this.#drainPendingAutonomousTurns(this.#transport);
|
|
22011
22919
|
}
|
|
22012
22920
|
}
|
|
22013
22921
|
async #selectThinking(command) {
|
|
@@ -22082,6 +22990,8 @@ var PiHarnessSession = class {
|
|
|
22082
22990
|
return { ok: true, value: { completed: true } };
|
|
22083
22991
|
} finally {
|
|
22084
22992
|
this.#configuring = false;
|
|
22993
|
+
if (this.#transport)
|
|
22994
|
+
this.#drainPendingAutonomousTurns(this.#transport);
|
|
22085
22995
|
}
|
|
22086
22996
|
}
|
|
22087
22997
|
async #cancel(command) {
|
|
@@ -22092,6 +23002,12 @@ var PiHarnessSession = class {
|
|
|
22092
23002
|
error: invalidState("Pi Turn Cancel must reference the active Turn")
|
|
22093
23003
|
};
|
|
22094
23004
|
}
|
|
23005
|
+
if (active.settling) {
|
|
23006
|
+
return {
|
|
23007
|
+
ok: false,
|
|
23008
|
+
error: invalidState("Pi Turn has finished native execution and is recording its completion")
|
|
23009
|
+
};
|
|
23010
|
+
}
|
|
22095
23011
|
if (active.cancellationRequested) {
|
|
22096
23012
|
return { ok: true, value: { cancellationRequested: true } };
|
|
22097
23013
|
}
|
|
@@ -22206,7 +23122,9 @@ var PiHarnessSession = class {
|
|
|
22206
23122
|
interactions: /* @__PURE__ */ new Map(),
|
|
22207
23123
|
interactionByNativeId: /* @__PURE__ */ new Map(),
|
|
22208
23124
|
cancellationRequested: false,
|
|
23125
|
+
settling: false,
|
|
22209
23126
|
beforeNativeTurnKeys: /* @__PURE__ */ new Set(),
|
|
23127
|
+
progressItems: /* @__PURE__ */ new Set(),
|
|
22210
23128
|
completion,
|
|
22211
23129
|
resolveCompletion
|
|
22212
23130
|
};
|
|
@@ -22239,6 +23157,8 @@ var PiHarnessSession = class {
|
|
|
22239
23157
|
return { ok: true, value: { turnId: command.turnId } };
|
|
22240
23158
|
} finally {
|
|
22241
23159
|
this.#acceptingTurn = false;
|
|
23160
|
+
if (this.#transport)
|
|
23161
|
+
this.#drainPendingAutonomousTurns(this.#transport);
|
|
22242
23162
|
}
|
|
22243
23163
|
}
|
|
22244
23164
|
async #ensureTransport() {
|
|
@@ -22289,6 +23209,8 @@ var PiHarnessSession = class {
|
|
|
22289
23209
|
return transport;
|
|
22290
23210
|
}).catch(async (error51) => {
|
|
22291
23211
|
this.#pendingAutonomousTurns = this.#pendingAutonomousTurns.filter((pending) => pending.transport !== transport);
|
|
23212
|
+
this.#pendingAutonomousLifecycle = this.#pendingAutonomousLifecycle.filter((pending) => pending.transport !== transport);
|
|
23213
|
+
this.#pendingAutonomousLifecycleBytes = this.#pendingAutonomousLifecycle.reduce((total, pending) => total + pending.bytes, 0);
|
|
22292
23214
|
await transport.close().catch(() => void 0);
|
|
22293
23215
|
if (this.#phase === "open")
|
|
22294
23216
|
this.#fault(error51);
|
|
@@ -22301,6 +23223,11 @@ var PiHarnessSession = class {
|
|
|
22301
23223
|
return starting;
|
|
22302
23224
|
}
|
|
22303
23225
|
#bindAutonomousTurnHandler(transport) {
|
|
23226
|
+
transport.setGotgenesStatusHandler?.((records, owner) => {
|
|
23227
|
+
if (this.#phase !== "open")
|
|
23228
|
+
return;
|
|
23229
|
+
this.#subagents.observeGotgenes(records, owner === "requested" && this.#active && !this.#active.settling ? { turnId: this.#active.command.turnId, nextItemId: () => this.#newItemId() } : void 0);
|
|
23230
|
+
});
|
|
22304
23231
|
transport.setSubagentStatusHandler?.((runs) => {
|
|
22305
23232
|
if (this.#phase !== "open")
|
|
22306
23233
|
return;
|
|
@@ -22312,12 +23239,16 @@ var PiHarnessSession = class {
|
|
|
22312
23239
|
transport.setUsageHandler?.((observation) => {
|
|
22313
23240
|
if (this.#phase !== "open")
|
|
22314
23241
|
return;
|
|
22315
|
-
const
|
|
22316
|
-
if (
|
|
22317
|
-
this.#event({ type: "usage.request", request:
|
|
22318
|
-
else if (
|
|
23242
|
+
const record9 = piUsageRecord(observation.message, observation);
|
|
23243
|
+
if (record9?.kind === "request")
|
|
23244
|
+
this.#event({ type: "usage.request", request: record9.request });
|
|
23245
|
+
else if (record9?.kind === "missing")
|
|
22319
23246
|
this.#event({ type: "usage.history", complete: false });
|
|
22320
23247
|
});
|
|
23248
|
+
if (transport.setAutonomousTurnLifecycleHandler) {
|
|
23249
|
+
transport.setAutonomousTurnLifecycleHandler((update) => this.#handleAutonomousLifecycle(transport, update));
|
|
23250
|
+
return;
|
|
23251
|
+
}
|
|
22321
23252
|
transport.setAutonomousTurnHandler((turn) => {
|
|
22322
23253
|
if (this.#phase !== "open")
|
|
22323
23254
|
return;
|
|
@@ -22329,6 +23260,20 @@ var PiHarnessSession = class {
|
|
|
22329
23260
|
});
|
|
22330
23261
|
}
|
|
22331
23262
|
#drainPendingAutonomousTurns(transport) {
|
|
23263
|
+
if (this.#phase !== "open" || this.#acceptingTurn || this.#configuring)
|
|
23264
|
+
return;
|
|
23265
|
+
for (; ; ) {
|
|
23266
|
+
const pending2 = this.#pendingAutonomousLifecycle[0];
|
|
23267
|
+
if (!pending2 || pending2.transport !== transport || this.#active && this.#active.autonomousRunId !== pending2.update.runId)
|
|
23268
|
+
break;
|
|
23269
|
+
this.#pendingAutonomousLifecycle.shift();
|
|
23270
|
+
this.#pendingAutonomousLifecycleBytes -= pending2.bytes;
|
|
23271
|
+
this.#applyAutonomousLifecycle(transport, pending2.update);
|
|
23272
|
+
if (this.#phase !== "open")
|
|
23273
|
+
return;
|
|
23274
|
+
}
|
|
23275
|
+
if (this.#active)
|
|
23276
|
+
return;
|
|
22332
23277
|
if (this.#pendingSubagentStatus) {
|
|
22333
23278
|
this.#subagents.observe(this.#pendingSubagentStatus);
|
|
22334
23279
|
this.#pendingSubagentStatus = null;
|
|
@@ -22341,6 +23286,52 @@ var PiHarnessSession = class {
|
|
|
22341
23286
|
this.#handleAutonomousTurn(transport, candidate.turn);
|
|
22342
23287
|
}
|
|
22343
23288
|
}
|
|
23289
|
+
#handleAutonomousLifecycle(transport, update) {
|
|
23290
|
+
if (this.#phase === "closing" && this.#transport === transport && update.type !== "started" && this.#active?.autonomousRunId === update.runId) {
|
|
23291
|
+
this.#applyAutonomousLifecycle(transport, update);
|
|
23292
|
+
return;
|
|
23293
|
+
}
|
|
23294
|
+
if (this.#phase !== "open")
|
|
23295
|
+
return;
|
|
23296
|
+
if (this.#transport !== transport || this.#acceptingTurn || this.#configuring || this.#pendingAutonomousLifecycle.length > 0 || this.#active && this.#active.autonomousRunId !== update.runId) {
|
|
23297
|
+
const bytes = Buffer.byteLength(JSON.stringify(update));
|
|
23298
|
+
if (this.#pendingAutonomousLifecycleBytes + bytes > 8 * 1024 * 1024) {
|
|
23299
|
+
this.#fault(new PiAdapterFaultError({
|
|
23300
|
+
code: "protocolError",
|
|
23301
|
+
message: "Pi autonomous lifecycle exceeded its ordered event buffer bound",
|
|
23302
|
+
retryable: false
|
|
23303
|
+
}));
|
|
23304
|
+
return;
|
|
23305
|
+
}
|
|
23306
|
+
this.#pendingAutonomousLifecycle.push({ transport, update, bytes });
|
|
23307
|
+
this.#pendingAutonomousLifecycleBytes += bytes;
|
|
23308
|
+
if (this.#transport === transport)
|
|
23309
|
+
this.#drainPendingAutonomousTurns(transport);
|
|
23310
|
+
return;
|
|
23311
|
+
}
|
|
23312
|
+
this.#applyAutonomousLifecycle(transport, update);
|
|
23313
|
+
}
|
|
23314
|
+
#applyAutonomousLifecycle(transport, update) {
|
|
23315
|
+
if (update.type === "started" && !this.#active) {
|
|
23316
|
+
this.#startAutonomousHostTurn(update.runId);
|
|
23317
|
+
return;
|
|
23318
|
+
}
|
|
23319
|
+
const active = this.#active;
|
|
23320
|
+
if (!active || active.autonomousRunId !== update.runId || update.type === "started") {
|
|
23321
|
+
this.#fault(new PiAdapterFaultError({
|
|
23322
|
+
code: "protocolError",
|
|
23323
|
+
message: "Pi autonomous event has no matching active run",
|
|
23324
|
+
retryable: false
|
|
23325
|
+
}));
|
|
23326
|
+
return;
|
|
23327
|
+
}
|
|
23328
|
+
if (update.type === "event")
|
|
23329
|
+
this.#handleTurnEvent(active, update.event);
|
|
23330
|
+
else {
|
|
23331
|
+
active.settling = true;
|
|
23332
|
+
this.#finishAutonomousHostTurn(transport, active, update.turn);
|
|
23333
|
+
}
|
|
23334
|
+
}
|
|
22344
23335
|
#handleAutonomousTurn(transport, turn) {
|
|
22345
23336
|
if (this.#phase !== "open")
|
|
22346
23337
|
return;
|
|
@@ -22352,7 +23343,7 @@ var PiHarnessSession = class {
|
|
|
22352
23343
|
}));
|
|
22353
23344
|
return;
|
|
22354
23345
|
}
|
|
22355
|
-
if (this.#active
|
|
23346
|
+
if (this.#active && !this.#active.settling) {
|
|
22356
23347
|
this.#fault(new PiAdapterFaultError({
|
|
22357
23348
|
code: "protocolError",
|
|
22358
23349
|
message: "Pi autonomous Turn overlapped another Host operation",
|
|
@@ -22360,7 +23351,22 @@ var PiHarnessSession = class {
|
|
|
22360
23351
|
}));
|
|
22361
23352
|
return;
|
|
22362
23353
|
}
|
|
22363
|
-
|
|
23354
|
+
if (this.#active || this.#acceptingTurn || this.#configuring) {
|
|
23355
|
+
if (this.#pendingAutonomousTurns.length >= 128) {
|
|
23356
|
+
this.#fault(new PiAdapterFaultError({
|
|
23357
|
+
code: "protocolError",
|
|
23358
|
+
message: "Pi autonomous completion queue exceeded its bound",
|
|
23359
|
+
retryable: false
|
|
23360
|
+
}));
|
|
23361
|
+
} else
|
|
23362
|
+
this.#pendingAutonomousTurns.push({ transport, turn });
|
|
23363
|
+
return;
|
|
23364
|
+
}
|
|
23365
|
+
const active = this.#startAutonomousHostTurn();
|
|
23366
|
+
this.#finishAutonomousHostTurn(transport, active, turn);
|
|
23367
|
+
}
|
|
23368
|
+
#startAutonomousHostTurn(runId) {
|
|
23369
|
+
const turnId = hostTurnIdSchema.parse(randomUUID7());
|
|
22364
23370
|
let resolveCompletion = () => void 0;
|
|
22365
23371
|
const completion = new Promise((resolve) => {
|
|
22366
23372
|
resolveCompletion = resolve;
|
|
@@ -22372,6 +23378,7 @@ var PiHarnessSession = class {
|
|
|
22372
23378
|
};
|
|
22373
23379
|
const active = {
|
|
22374
23380
|
command: { type: "turn.start", turnId, input: [] },
|
|
23381
|
+
...runId ? { autonomousRunId: runId } : {},
|
|
22375
23382
|
agentItem: item,
|
|
22376
23383
|
agentMessageId: null,
|
|
22377
23384
|
compactionItem: null,
|
|
@@ -22381,10 +23388,19 @@ var PiHarnessSession = class {
|
|
|
22381
23388
|
interactions: /* @__PURE__ */ new Map(),
|
|
22382
23389
|
interactionByNativeId: /* @__PURE__ */ new Map(),
|
|
22383
23390
|
cancellationRequested: false,
|
|
23391
|
+
settling: false,
|
|
22384
23392
|
beforeNativeTurnKeys: /* @__PURE__ */ new Set(),
|
|
23393
|
+
progressItems: /* @__PURE__ */ new Set(),
|
|
22385
23394
|
completion,
|
|
22386
23395
|
resolveCompletion
|
|
22387
23396
|
};
|
|
23397
|
+
this.#active = active;
|
|
23398
|
+
this.#event({ type: "turn.autonomous.started", turnId, input: [] });
|
|
23399
|
+
this.#event({ type: "turn.started", turnId });
|
|
23400
|
+
this.#event({ type: "item.started", turnId, item });
|
|
23401
|
+
return active;
|
|
23402
|
+
}
|
|
23403
|
+
#finishAutonomousHostTurn(transport, active, turn) {
|
|
22388
23404
|
const nativeTurnRef = turn.nativeTurnKey ? nativeTurnRefSchema.parse({
|
|
22389
23405
|
harnessId: this.harnessId,
|
|
22390
23406
|
nativeSessionId: transport.state.sessionId,
|
|
@@ -22397,10 +23413,6 @@ var PiHarnessSession = class {
|
|
|
22397
23413
|
checkpointId: nativeTurnRef.nativeTurnKey,
|
|
22398
23414
|
formatVersion: 1
|
|
22399
23415
|
}) : void 0;
|
|
22400
|
-
this.#active = active;
|
|
22401
|
-
this.#event({ type: "turn.autonomous.started", turnId, input: [] });
|
|
22402
|
-
this.#event({ type: "turn.started", turnId });
|
|
22403
|
-
this.#event({ type: "item.started", turnId, item });
|
|
22404
23416
|
try {
|
|
22405
23417
|
for (const event of turn.events)
|
|
22406
23418
|
this.#handleTurnEvent(active, event);
|
|
@@ -22470,17 +23482,35 @@ var PiHarnessSession = class {
|
|
|
22470
23482
|
if (this.#active !== active || this.#phase === "closed" || this.#phase === "faulted")
|
|
22471
23483
|
return;
|
|
22472
23484
|
switch (event.type) {
|
|
23485
|
+
case "progress.message": {
|
|
23486
|
+
if (active.progressItems.has(event.itemId))
|
|
23487
|
+
return;
|
|
23488
|
+
active.progressItems.add(event.itemId);
|
|
23489
|
+
const item = {
|
|
23490
|
+
type: "agentMessage",
|
|
23491
|
+
itemId: event.itemId,
|
|
23492
|
+
text: event.text,
|
|
23493
|
+
phase: "commentary"
|
|
23494
|
+
};
|
|
23495
|
+
this.#event({ type: "item.started", turnId: active.command.turnId, item });
|
|
23496
|
+
this.#completeItem(active, item, { status: "succeeded" });
|
|
23497
|
+
return;
|
|
23498
|
+
}
|
|
22473
23499
|
case "text.delta":
|
|
22474
|
-
this.#activateAgentMessage(active, event.messageId);
|
|
23500
|
+
this.#activateAgentMessage(active, event.messageId, event.nativeMessageIdentity);
|
|
23501
|
+
active.sawAssistantMessage = true;
|
|
22475
23502
|
this.#appendText(active, event.delta);
|
|
22476
23503
|
return;
|
|
22477
23504
|
case "reasoning.delta":
|
|
22478
|
-
this.#
|
|
23505
|
+
this.#activateAgentMessage(active, event.messageId, event.nativeMessageIdentity);
|
|
23506
|
+
this.#appendReasoning(active, event.delta, event.nativeMessageIdentity);
|
|
22479
23507
|
return;
|
|
22480
23508
|
case "reasoning.completed":
|
|
22481
23509
|
this.#completeReasoning(active, { status: "succeeded" });
|
|
22482
23510
|
return;
|
|
22483
23511
|
case "message.completed":
|
|
23512
|
+
if (event.phase && active.agentMessageId === event.messageId && active.agentItem)
|
|
23513
|
+
active.agentItem = { ...active.agentItem, phase: event.phase };
|
|
22484
23514
|
void this.#refreshUsage(active.command.turnId);
|
|
22485
23515
|
return;
|
|
22486
23516
|
case "compaction.started":
|
|
@@ -22538,7 +23568,7 @@ var PiHarnessSession = class {
|
|
|
22538
23568
|
if (active.interactionByNativeId.has(request.requestId)) {
|
|
22539
23569
|
throw new Error("Pi Interaction started more than once");
|
|
22540
23570
|
}
|
|
22541
|
-
const interactionId = hostInteractionIdSchema.parse(
|
|
23571
|
+
const interactionId = hostInteractionIdSchema.parse(randomUUID7());
|
|
22542
23572
|
const question = request.method === "select" ? {
|
|
22543
23573
|
id: "answer",
|
|
22544
23574
|
type: "choice",
|
|
@@ -22595,17 +23625,21 @@ var PiHarnessSession = class {
|
|
|
22595
23625
|
reason
|
|
22596
23626
|
});
|
|
22597
23627
|
}
|
|
22598
|
-
#activateAgentMessage(active, messageId) {
|
|
23628
|
+
#activateAgentMessage(active, messageId, nativeMessageIdentity2) {
|
|
22599
23629
|
if (active.agentMessageId === messageId)
|
|
22600
23630
|
return;
|
|
23631
|
+
const nativeItemId = piMessageItemId(nativeMessageIdentity2, "assistant");
|
|
23632
|
+
if (nativeItemId && active.agentMessageId === null && active.agentItem?.text === "") {
|
|
23633
|
+
this.#completeAgentItem(active, { status: "succeeded" }, true);
|
|
23634
|
+
}
|
|
22601
23635
|
if (active.agentMessageId !== null) {
|
|
22602
23636
|
this.#completeReasoning(active, { status: "succeeded" });
|
|
22603
|
-
this.#completeAgentItem(active, { status: "succeeded" },
|
|
23637
|
+
this.#completeAgentItem(active, { status: "succeeded" }, true);
|
|
22604
23638
|
}
|
|
22605
23639
|
if (!active.agentItem) {
|
|
22606
23640
|
active.agentItem = {
|
|
22607
23641
|
type: "agentMessage",
|
|
22608
|
-
itemId: this.#newItemId(),
|
|
23642
|
+
itemId: nativeItemId ?? this.#newItemId(),
|
|
22609
23643
|
text: ""
|
|
22610
23644
|
};
|
|
22611
23645
|
this.#event({
|
|
@@ -22615,18 +23649,17 @@ var PiHarnessSession = class {
|
|
|
22615
23649
|
});
|
|
22616
23650
|
}
|
|
22617
23651
|
active.agentMessageId = messageId;
|
|
22618
|
-
active.sawAssistantMessage = true;
|
|
22619
23652
|
}
|
|
22620
|
-
#appendText(active,
|
|
23653
|
+
#appendText(active, text3) {
|
|
22621
23654
|
if (active.agentMessageId === null || !active.agentItem) {
|
|
22622
23655
|
throw new Error("Pi Assistant text arrived outside an active message");
|
|
22623
23656
|
}
|
|
22624
|
-
active.agentItem = { ...active.agentItem, text: active.agentItem.text +
|
|
23657
|
+
active.agentItem = { ...active.agentItem, text: active.agentItem.text + text3 };
|
|
22625
23658
|
this.#event({
|
|
22626
23659
|
type: "item.updated",
|
|
22627
23660
|
turnId: active.command.turnId,
|
|
22628
23661
|
itemId: active.agentItem.itemId,
|
|
22629
|
-
update: { type: "text.append", text:
|
|
23662
|
+
update: { type: "text.append", text: text3 }
|
|
22630
23663
|
});
|
|
22631
23664
|
}
|
|
22632
23665
|
#completeAgentItem(active, outcome, completeEmpty) {
|
|
@@ -22637,13 +23670,13 @@ var PiHarnessSession = class {
|
|
|
22637
23670
|
active.agentItem = null;
|
|
22638
23671
|
this.#completeItem(active, item, outcome);
|
|
22639
23672
|
}
|
|
22640
|
-
#appendReasoning(active,
|
|
22641
|
-
if (
|
|
23673
|
+
#appendReasoning(active, text3, nativeMessageIdentity2) {
|
|
23674
|
+
if (text3.length === 0)
|
|
22642
23675
|
return;
|
|
22643
23676
|
if (!active.reasoningItem) {
|
|
22644
23677
|
active.reasoningItem = {
|
|
22645
23678
|
type: "reasoning",
|
|
22646
|
-
itemId: this.#newItemId(),
|
|
23679
|
+
itemId: piMessageItemId(nativeMessageIdentity2, "reasoning") ?? this.#newItemId(),
|
|
22647
23680
|
text: ""
|
|
22648
23681
|
};
|
|
22649
23682
|
this.#event({
|
|
@@ -22654,13 +23687,13 @@ var PiHarnessSession = class {
|
|
|
22654
23687
|
}
|
|
22655
23688
|
active.reasoningItem = {
|
|
22656
23689
|
...active.reasoningItem,
|
|
22657
|
-
text: active.reasoningItem.text +
|
|
23690
|
+
text: active.reasoningItem.text + text3
|
|
22658
23691
|
};
|
|
22659
23692
|
this.#event({
|
|
22660
23693
|
type: "item.updated",
|
|
22661
23694
|
turnId: active.command.turnId,
|
|
22662
23695
|
itemId: active.reasoningItem.itemId,
|
|
22663
|
-
update: { type: "text.append", text:
|
|
23696
|
+
update: { type: "text.append", text: text3 }
|
|
22664
23697
|
});
|
|
22665
23698
|
}
|
|
22666
23699
|
#completeReasoning(active, outcome) {
|
|
@@ -22673,13 +23706,12 @@ var PiHarnessSession = class {
|
|
|
22673
23706
|
#startTool(active, event) {
|
|
22674
23707
|
if (active.tools.has(event.callId))
|
|
22675
23708
|
throw new Error("Pi Tool started more than once");
|
|
22676
|
-
const
|
|
22677
|
-
const
|
|
22678
|
-
const item = command ? {
|
|
23709
|
+
const shell = piToolCommand(event.toolName, event.arguments);
|
|
23710
|
+
const item = shell ? {
|
|
22679
23711
|
type: "commandExecution",
|
|
22680
23712
|
itemId: this.#newItemId(),
|
|
22681
|
-
command,
|
|
22682
|
-
cwd:
|
|
23713
|
+
command: shell.command,
|
|
23714
|
+
cwd: shell.cwd ?? this.#cwd
|
|
22683
23715
|
} : {
|
|
22684
23716
|
type: "toolExecution",
|
|
22685
23717
|
itemId: this.#newItemId(),
|
|
@@ -22797,14 +23829,17 @@ var PiHarnessSession = class {
|
|
|
22797
23829
|
sessionId: transport.state.sessionId,
|
|
22798
23830
|
model: nativeModelForHistory(transport.state)
|
|
22799
23831
|
});
|
|
22800
|
-
const created = snapshot.turns.filter((turn2) => !active.beforeNativeTurnKeys.has(turn2.nativeTurnRef.nativeTurnKey));
|
|
23832
|
+
const created = snapshot.turns.filter((turn2) => turn2.input.length > 0 && !active.beforeNativeTurnKeys.has(turn2.nativeTurnRef.nativeTurnKey));
|
|
22801
23833
|
if (created.length !== 1) {
|
|
22802
23834
|
throw new Error(`Pi Turn persisted ${created.length} new User Entries; exactly one is required`);
|
|
22803
23835
|
}
|
|
22804
23836
|
const turn = created[0];
|
|
22805
|
-
if (!turn
|
|
22806
|
-
throw new Error("Pi Turn has no
|
|
22807
|
-
return {
|
|
23837
|
+
if (!turn)
|
|
23838
|
+
throw new Error("Pi Turn has no persisted User identity");
|
|
23839
|
+
return {
|
|
23840
|
+
nativeTurnRef: turn.nativeTurnRef,
|
|
23841
|
+
...turn.checkpoint ? { checkpoint: turn.checkpoint } : {}
|
|
23842
|
+
};
|
|
22808
23843
|
}
|
|
22809
23844
|
#completeTurn(active, outcome, finalText, nativeTurnRef) {
|
|
22810
23845
|
if (this.#active !== active)
|
|
@@ -22833,14 +23868,20 @@ var PiHarnessSession = class {
|
|
|
22833
23868
|
});
|
|
22834
23869
|
active.resolveCompletion();
|
|
22835
23870
|
queueMicrotask(() => {
|
|
22836
|
-
if (this.#phase
|
|
22837
|
-
|
|
23871
|
+
if (this.#phase !== "open")
|
|
23872
|
+
return;
|
|
23873
|
+
if (this.#transport)
|
|
23874
|
+
this.#drainPendingAutonomousTurns(this.#transport);
|
|
23875
|
+
void this.#refreshUsage(active.command.turnId);
|
|
22838
23876
|
});
|
|
22839
23877
|
}
|
|
22840
23878
|
#fault(error51) {
|
|
22841
23879
|
if (this.#phase === "closed" || this.#phase === "faulted")
|
|
22842
23880
|
return;
|
|
22843
23881
|
const normalized = normalizedError(error51, "internalError");
|
|
23882
|
+
this.#pendingAutonomousTurns = [];
|
|
23883
|
+
this.#pendingAutonomousLifecycle = [];
|
|
23884
|
+
this.#pendingAutonomousLifecycleBytes = 0;
|
|
22844
23885
|
if (this.#active) {
|
|
22845
23886
|
this.#completeTurn(this.#active, { status: "failed", error: normalized });
|
|
22846
23887
|
}
|
|
@@ -22849,6 +23890,9 @@ var PiHarnessSession = class {
|
|
|
22849
23890
|
this.#channel.end();
|
|
22850
23891
|
}
|
|
22851
23892
|
async #close() {
|
|
23893
|
+
this.#pendingAutonomousTurns = [];
|
|
23894
|
+
this.#pendingAutonomousLifecycle = [];
|
|
23895
|
+
this.#pendingAutonomousLifecycleBytes = 0;
|
|
22852
23896
|
if (this.#phase === "closed")
|
|
22853
23897
|
return;
|
|
22854
23898
|
const wasFaulted = this.#phase === "faulted";
|
|
@@ -22881,7 +23925,7 @@ var PiHarnessSession = class {
|
|
|
22881
23925
|
this.#channel.emit({ kind: "event", event });
|
|
22882
23926
|
}
|
|
22883
23927
|
#newItemId() {
|
|
22884
|
-
return hostItemIdSchema.parse(
|
|
23928
|
+
return hostItemIdSchema.parse(randomUUID7());
|
|
22885
23929
|
}
|
|
22886
23930
|
};
|
|
22887
23931
|
var PiAdapter = class {
|
|
@@ -22896,12 +23940,15 @@ var PiAdapter = class {
|
|
|
22896
23940
|
if (this.#closePromise || parent.harnessId !== this.harnessId) {
|
|
22897
23941
|
return { ok: false, error: invalidState("Pi Subagent parent is unavailable") };
|
|
22898
23942
|
}
|
|
23943
|
+
const gotgenes = parseGotgenesId(nativeSubagentId);
|
|
22899
23944
|
const workflow = parsePiWorkflowSubagentId(nativeSubagentId);
|
|
22900
|
-
if (!workflow)
|
|
23945
|
+
if (!workflow && !gotgenes)
|
|
22901
23946
|
parsePiSubagentId(nativeSubagentId);
|
|
22902
23947
|
const live = [...this.#sessions].find((session) => session.ownsNativeSession(parent.nativeSessionId));
|
|
22903
23948
|
let reply;
|
|
22904
23949
|
if (live) {
|
|
23950
|
+
if (gotgenes)
|
|
23951
|
+
return await live.readGotgenesChild(gotgenes, cwd);
|
|
22905
23952
|
if (workflow)
|
|
22906
23953
|
return await readPiWorkflowChild(await live.readSubagentHistory(cwd), parent.nativeSessionId, workflow);
|
|
22907
23954
|
reply = await live.inspectSubagent(nativeSubagentId, cwd);
|
|
@@ -22913,6 +23960,8 @@ var PiAdapter = class {
|
|
|
22913
23960
|
if (transport.state.sessionId !== parent.nativeSessionId)
|
|
22914
23961
|
throw new Error("Pi Subagent parent identity mismatch");
|
|
22915
23962
|
await transport.verifySessionCwd(cwd);
|
|
23963
|
+
if (gotgenes)
|
|
23964
|
+
return await readGotgenesChild(await transport.getEntries(), parent.nativeSessionId, gotgenes);
|
|
22916
23965
|
if (workflow)
|
|
22917
23966
|
return await readPiWorkflowChild(await transport.getEntries(), parent.nativeSessionId, workflow);
|
|
22918
23967
|
if (!transport.inspectSubagent)
|