@karlorz/codexhost-cli-darwin-x64 0.13.3-6 → 0.13.3-7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +484 -91
- package/app/console-web.js +553 -37
- package/app/cpa-live-voice-hook.js +550 -33
- package/app/desktop-controller.mjs +25 -1
- package/app/host-runtime.mjs +985 -478
- package/app/plugins/antigravity/plugin.mjs +25 -1
- package/app/plugins/claude-code/plugin.mjs +32 -5
- package/app/plugins/codebuddy/plugin.mjs +32 -5
- package/app/plugins/codex-usage/plugin.mjs +131 -67
- package/app/plugins/cursor-cli/plugin.mjs +20737 -44915
- package/app/plugins/deepseek-harness/plugin.mjs +32 -5
- package/app/plugins/grok/plugin.mjs +802 -155
- package/app/plugins/hermes/plugin.mjs +32 -5
- package/app/plugins/kimi-code/plugin.mjs +25 -1
- package/app/plugins/kiro-cli/plugin.mjs +25 -1
- package/app/plugins/omp/plugin.mjs +2288 -2072
- package/app/plugins/opencode/plugin.mjs +32 -5
- package/app/plugins/pi/plugin.mjs +2373 -2264
- package/app/plugins/qoder/plugin.mjs +32 -5
- package/app/plugins/qoder-cn/plugin.mjs +32 -5
- package/app/plugins/workbuddy/plugin.mjs +32 -5
- package/app/plugins/zcode/plugin.mjs +32 -5
- package/app/renderer-extension.js +1973 -1085
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -424,10 +424,13 @@ function usageSessionTitle(value) {
|
|
|
424
424
|
return void 0;
|
|
425
425
|
if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
|
|
426
426
|
return normalized;
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
427
|
+
let title = "";
|
|
428
|
+
for (const character of normalized) {
|
|
429
|
+
if (title.length + character.length >= MAX_SESSION_TITLE_LENGTH)
|
|
430
|
+
break;
|
|
431
|
+
title += character;
|
|
432
|
+
}
|
|
433
|
+
return `${title.trimEnd()}…`;
|
|
431
434
|
}
|
|
432
435
|
function sessionIdOk(value) {
|
|
433
436
|
return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
|
|
@@ -15374,6 +15377,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
15374
15377
|
"codexhost/harness/installation",
|
|
15375
15378
|
"codexhost/harness/launch-settings/get",
|
|
15376
15379
|
"codexhost/harness/launch-settings/set",
|
|
15380
|
+
"codexhost/harness/grok-computer-use/get",
|
|
15381
|
+
"codexhost/harness/grok-computer-use/set",
|
|
15377
15382
|
"codexhost/harness/web-ui/open",
|
|
15378
15383
|
"codexhost/harness/accounts/sources",
|
|
15379
15384
|
"codexhost/harness/accounts/list",
|
|
@@ -15902,7 +15907,9 @@ var harnessInspectionSchema = external_exports.union([
|
|
|
15902
15907
|
var harnessInspectParamsSchema = external_exports.object({
|
|
15903
15908
|
harnessId: harnessIdSchema,
|
|
15904
15909
|
cwd: nonBlankTextSchema2.max(16384).optional(),
|
|
15905
|
-
refresh: external_exports.boolean().optional()
|
|
15910
|
+
refresh: external_exports.boolean().optional(),
|
|
15911
|
+
/** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
|
|
15912
|
+
purpose: external_exports.literal("availability").optional()
|
|
15906
15913
|
}).strict();
|
|
15907
15914
|
var harnessWebUiOpenParamsSchema = external_exports.object({
|
|
15908
15915
|
harnessId: harnessIdSchema
|
|
@@ -16076,6 +16083,26 @@ var harnessLaunchSettingsSchema = external_exports.object({
|
|
|
16076
16083
|
restartRequired: external_exports.boolean()
|
|
16077
16084
|
}).strict();
|
|
16078
16085
|
|
|
16086
|
+
// ../../shared-contracts/dist/grok-computer-use.js
|
|
16087
|
+
var grokComputerUseGetSchema = external_exports.object({}).strict();
|
|
16088
|
+
var grokComputerUseSetSchema = external_exports.object({
|
|
16089
|
+
enabled: external_exports.boolean().optional(),
|
|
16090
|
+
browser: external_exports.boolean().optional()
|
|
16091
|
+
}).strict().refine((value) => value.enabled !== void 0 || value.browser !== void 0, {
|
|
16092
|
+
message: "Expected enabled or browser"
|
|
16093
|
+
});
|
|
16094
|
+
var grokComputerUseSettingsSchema = external_exports.object({
|
|
16095
|
+
enabled: external_exports.boolean(),
|
|
16096
|
+
available: external_exports.boolean(),
|
|
16097
|
+
unavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
16098
|
+
browser: external_exports.boolean().optional(),
|
|
16099
|
+
browserFilesPresent: external_exports.boolean().optional(),
|
|
16100
|
+
browserAvailable: external_exports.boolean().optional(),
|
|
16101
|
+
browserUnavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
16102
|
+
applyFailed: external_exports.boolean().optional(),
|
|
16103
|
+
applyError: external_exports.string().min(1).max(500).optional()
|
|
16104
|
+
}).strict();
|
|
16105
|
+
|
|
16079
16106
|
// ../../shared-contracts/dist/harness-installation.js
|
|
16080
16107
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
16081
16108
|
harnessId: harnessIdSchema,
|
|
@@ -17788,2256 +17815,2348 @@ function createOmpUsageStatistics(environment) {
|
|
|
17788
17815
|
});
|
|
17789
17816
|
}
|
|
17790
17817
|
|
|
17791
|
-
//
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
|
|
17799
|
-
|
|
17800
|
-
|
|
17801
|
-
|
|
17802
|
-
|
|
17803
|
-
|
|
17804
|
-
|
|
17805
|
-
|
|
17818
|
+
// dist/omp-model-list.js
|
|
17819
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
17820
|
+
|
|
17821
|
+
// dist/command.js
|
|
17822
|
+
var ompDiscoverySpec = {
|
|
17823
|
+
id: "omp",
|
|
17824
|
+
command: "omp",
|
|
17825
|
+
commandEnvironmentVariable: "OMP_COMMAND",
|
|
17826
|
+
installRoots: {
|
|
17827
|
+
posix: [
|
|
17828
|
+
"~/.npm-global/bin",
|
|
17829
|
+
"~/.local/bin",
|
|
17830
|
+
VERSION_MANAGER_ROOTS,
|
|
17831
|
+
"/opt/homebrew/bin",
|
|
17832
|
+
"/usr/local/bin"
|
|
17833
|
+
],
|
|
17834
|
+
windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS]
|
|
17806
17835
|
}
|
|
17807
|
-
|
|
17808
|
-
|
|
17809
|
-
|
|
17810
|
-
|
|
17811
|
-
|
|
17812
|
-
|
|
17813
|
-
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
|
|
17836
|
+
};
|
|
17837
|
+
function resolveOmpExecutable(input, dependencies = {}) {
|
|
17838
|
+
const resolution = resolveHarnessExecutable(ompDiscoverySpec, {
|
|
17839
|
+
...input.command ? { command: input.command } : {},
|
|
17840
|
+
environment: input.environment,
|
|
17841
|
+
...dependencies.platform ? { platform: dependencies.platform } : {},
|
|
17842
|
+
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {}
|
|
17843
|
+
}, { ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {} });
|
|
17844
|
+
return resolution?.executable ?? input.command ?? input.environment.OMP_COMMAND ?? "omp";
|
|
17845
|
+
}
|
|
17846
|
+
|
|
17847
|
+
// dist/omp-rpc-session.js
|
|
17848
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
17849
|
+
import { randomUUID } from "node:crypto";
|
|
17850
|
+
import path6 from "node:path";
|
|
17851
|
+
|
|
17852
|
+
// dist/omp-slash-commands.js
|
|
17853
|
+
var OMP_LIVE_COMMAND_ID_PREFIX = "omp.slash.";
|
|
17854
|
+
function isRecord6(value) {
|
|
17855
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17856
|
+
}
|
|
17857
|
+
function parseOmpAvailableCommands(value) {
|
|
17858
|
+
if (!Array.isArray(value))
|
|
17859
|
+
return [];
|
|
17860
|
+
return value.flatMap((entry) => {
|
|
17861
|
+
if (!isRecord6(entry))
|
|
17862
|
+
return [];
|
|
17863
|
+
const name = typeof entry.name === "string" ? entry.name.trim().replace(/^\//u, "") : "";
|
|
17864
|
+
if (!name)
|
|
17865
|
+
return [];
|
|
17866
|
+
return [
|
|
17867
|
+
{
|
|
17868
|
+
name,
|
|
17869
|
+
description: typeof entry.description === "string" ? entry.description : "",
|
|
17870
|
+
source: typeof entry.source === "string" ? entry.source : null
|
|
17818
17871
|
}
|
|
17819
|
-
|
|
17820
|
-
|
|
17821
|
-
|
|
17822
|
-
|
|
17823
|
-
|
|
17824
|
-
|
|
17825
|
-
|
|
17826
|
-
|
|
17827
|
-
|
|
17828
|
-
|
|
17829
|
-
|
|
17830
|
-
|
|
17831
|
-
|
|
17832
|
-
|
|
17833
|
-
|
|
17834
|
-
|
|
17835
|
-
|
|
17836
|
-
|
|
17837
|
-
|
|
17838
|
-
|
|
17839
|
-
|
|
17840
|
-
|
|
17841
|
-
|
|
17842
|
-
|
|
17843
|
-
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
|
|
17848
|
-
|
|
17849
|
-
|
|
17850
|
-
|
|
17851
|
-
|
|
17852
|
-
|
|
17853
|
-
|
|
17854
|
-
|
|
17855
|
-
|
|
17856
|
-
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
|
|
17865
|
-
|
|
17866
|
-
}
|
|
17867
|
-
}
|
|
17872
|
+
];
|
|
17873
|
+
});
|
|
17874
|
+
}
|
|
17875
|
+
function ompLiveCommands(native) {
|
|
17876
|
+
return native.filter(({ source, name }) => source !== "builtin" || name === "context").map((command) => ({
|
|
17877
|
+
name: command.name,
|
|
17878
|
+
description: command.description,
|
|
17879
|
+
kind: command.source === "skill" ? "skill" : "command"
|
|
17880
|
+
}));
|
|
17881
|
+
}
|
|
17882
|
+
|
|
17883
|
+
// dist/omp-session-file.js
|
|
17884
|
+
import { createReadStream as createReadStream3 } from "node:fs";
|
|
17885
|
+
import { open, realpath as realpath2 } from "node:fs/promises";
|
|
17886
|
+
import readline from "node:readline";
|
|
17887
|
+
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
17888
|
+
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
17889
|
+
function isRecord7(value) {
|
|
17890
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17891
|
+
}
|
|
17892
|
+
function historyEntry(value) {
|
|
17893
|
+
if (!isRecord7(value) || value.type === "title" || value.type === "session" || typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
|
|
17894
|
+
return null;
|
|
17895
|
+
}
|
|
17896
|
+
return value;
|
|
17897
|
+
}
|
|
17898
|
+
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
17899
|
+
const entries = [];
|
|
17900
|
+
let leafId = null;
|
|
17901
|
+
let incomplete = false;
|
|
17902
|
+
const lines = readline.createInterface({
|
|
17903
|
+
input: createReadStream3(sessionFile, {
|
|
17904
|
+
encoding: "utf8",
|
|
17905
|
+
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
17906
|
+
}),
|
|
17907
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
17908
|
+
});
|
|
17909
|
+
try {
|
|
17910
|
+
for await (const line of lines) {
|
|
17911
|
+
if (line.length === 0)
|
|
17912
|
+
continue;
|
|
17913
|
+
let parsed;
|
|
17914
|
+
try {
|
|
17915
|
+
parsed = JSON.parse(line);
|
|
17916
|
+
} catch {
|
|
17917
|
+
incomplete = true;
|
|
17918
|
+
continue;
|
|
17868
17919
|
}
|
|
17869
|
-
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
setTimeout(function() {
|
|
17874
|
-
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
17875
|
-
return callback(void 0);
|
|
17876
|
-
}
|
|
17877
|
-
if (!execEditLength()) {
|
|
17878
|
-
exec();
|
|
17879
|
-
}
|
|
17880
|
-
}, 0);
|
|
17881
|
-
})();
|
|
17882
|
-
} else {
|
|
17883
|
-
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
17884
|
-
const ret = execEditLength();
|
|
17885
|
-
if (ret) {
|
|
17886
|
-
return ret;
|
|
17920
|
+
const entry = historyEntry(parsed);
|
|
17921
|
+
if (!entry) {
|
|
17922
|
+
if (!isRecord7(parsed) || parsed.type !== "title" && parsed.type !== "session") {
|
|
17923
|
+
incomplete = true;
|
|
17887
17924
|
}
|
|
17925
|
+
continue;
|
|
17888
17926
|
}
|
|
17927
|
+
entries.push(entry);
|
|
17928
|
+
leafId = entry.id;
|
|
17889
17929
|
}
|
|
17930
|
+
} finally {
|
|
17931
|
+
lines.close();
|
|
17890
17932
|
}
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
};
|
|
17933
|
+
return { entries, leafId, ...incomplete ? { incomplete: true } : {} };
|
|
17934
|
+
}
|
|
17935
|
+
async function readOmpSessionHeader(sessionFile) {
|
|
17936
|
+
const handle = await open(sessionFile, "r");
|
|
17937
|
+
try {
|
|
17938
|
+
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
17939
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
17940
|
+
const contents = buffer.subarray(0, bytesRead);
|
|
17941
|
+
const newline = contents.indexOf(10);
|
|
17942
|
+
if (newline < 0 && bytesRead === buffer.length) {
|
|
17943
|
+
throw new Error("Omp Session header exceeds the supported size");
|
|
17903
17944
|
}
|
|
17904
|
-
|
|
17905
|
-
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
|
|
17913
|
-
|
|
17945
|
+
const contentsText = utf8Decoder.decode(contents);
|
|
17946
|
+
for (const line of contentsText.split("\n")) {
|
|
17947
|
+
if (line.length === 0)
|
|
17948
|
+
continue;
|
|
17949
|
+
let parsed;
|
|
17950
|
+
try {
|
|
17951
|
+
parsed = JSON.parse(line);
|
|
17952
|
+
} catch {
|
|
17953
|
+
continue;
|
|
17954
|
+
}
|
|
17955
|
+
if (!isRecord7(parsed) || parsed.type !== "session")
|
|
17956
|
+
continue;
|
|
17957
|
+
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
17958
|
+
throw new Error("Omp Session header is invalid");
|
|
17914
17959
|
}
|
|
17960
|
+
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
17915
17961
|
}
|
|
17916
|
-
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
basePath.oldPos = oldPos;
|
|
17920
|
-
return newPos;
|
|
17921
|
-
}
|
|
17922
|
-
equals(left, right, options) {
|
|
17923
|
-
if (options.comparator) {
|
|
17924
|
-
return options.comparator(left, right);
|
|
17925
|
-
} else {
|
|
17926
|
-
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
17927
|
-
}
|
|
17928
|
-
}
|
|
17929
|
-
removeEmpty(array2) {
|
|
17930
|
-
const ret = [];
|
|
17931
|
-
for (let i = 0; i < array2.length; i++) {
|
|
17932
|
-
if (array2[i]) {
|
|
17933
|
-
ret.push(array2[i]);
|
|
17934
|
-
}
|
|
17935
|
-
}
|
|
17936
|
-
return ret;
|
|
17937
|
-
}
|
|
17938
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17939
|
-
castInput(value, options) {
|
|
17940
|
-
return value;
|
|
17941
|
-
}
|
|
17942
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17943
|
-
tokenize(value, options) {
|
|
17944
|
-
return Array.from(value);
|
|
17945
|
-
}
|
|
17946
|
-
join(chars) {
|
|
17947
|
-
return chars.join("");
|
|
17962
|
+
throw new Error("Omp Session header is invalid");
|
|
17963
|
+
} finally {
|
|
17964
|
+
await handle.close();
|
|
17948
17965
|
}
|
|
17949
|
-
|
|
17950
|
-
|
|
17966
|
+
}
|
|
17967
|
+
async function verifyOmpSessionCwd(input) {
|
|
17968
|
+
if (!input.sessionFile)
|
|
17969
|
+
throw new Error("Omp Fork Session has no persisted Session file");
|
|
17970
|
+
const header = await readOmpSessionHeader(input.sessionFile);
|
|
17971
|
+
if (header.id !== input.sessionId) {
|
|
17972
|
+
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
17951
17973
|
}
|
|
17952
|
-
|
|
17953
|
-
|
|
17974
|
+
const [actualCwd, expectedCwd] = await Promise.all([
|
|
17975
|
+
realpath2(header.cwd),
|
|
17976
|
+
realpath2(input.expectedCwd)
|
|
17977
|
+
]);
|
|
17978
|
+
if (actualCwd !== expectedCwd) {
|
|
17979
|
+
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
17954
17980
|
}
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
|
|
17958
|
-
|
|
17959
|
-
|
|
17960
|
-
|
|
17961
|
-
|
|
17962
|
-
|
|
17981
|
+
}
|
|
17982
|
+
|
|
17983
|
+
// dist/omp-protocol.js
|
|
17984
|
+
var MAX_FRAME_BYTES = 1024 * 1024;
|
|
17985
|
+
var MAX_REASSEMBLED_BYTES = 64 * 1024 * 1024;
|
|
17986
|
+
var MAX_CHUNK_BYTES = 256 * 1024;
|
|
17987
|
+
function isObject2(value) {
|
|
17988
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17989
|
+
}
|
|
17990
|
+
var OmpFrameDecoder = class {
|
|
17991
|
+
#pending = null;
|
|
17992
|
+
push(value) {
|
|
17993
|
+
if (!isObject2(value))
|
|
17994
|
+
throw new Error("OMP RPC frame must be a JSON object");
|
|
17995
|
+
if (value.type !== "rpc_chunk") {
|
|
17996
|
+
if (this.#pending)
|
|
17997
|
+
throw new Error("OMP RPC chunk sequence was interrupted");
|
|
17998
|
+
return value;
|
|
17963
17999
|
}
|
|
17964
|
-
|
|
17965
|
-
const
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
|
|
17969
|
-
|
|
17970
|
-
|
|
17971
|
-
|
|
17972
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
17975
|
-
|
|
17976
|
-
component.value = this.join(value);
|
|
17977
|
-
} else {
|
|
17978
|
-
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
17979
|
-
}
|
|
17980
|
-
newPos += component.count;
|
|
17981
|
-
if (!component.added) {
|
|
17982
|
-
oldPos += component.count;
|
|
17983
|
-
}
|
|
17984
|
-
} else {
|
|
17985
|
-
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
17986
|
-
oldPos += component.count;
|
|
17987
|
-
}
|
|
18000
|
+
const chunkId = value.chunkId;
|
|
18001
|
+
const index = value.index;
|
|
18002
|
+
const count2 = value.count;
|
|
18003
|
+
const byteLength = value.byteLength;
|
|
18004
|
+
const data = value.data;
|
|
18005
|
+
if (typeof chunkId !== "string" || chunkId.length === 0 || chunkId.length > 128 || !Number.isInteger(index) || !Number.isInteger(count2) || !Number.isInteger(byteLength) || index < 0 || count2 < 2 || index >= count2 || byteLength < MAX_FRAME_BYTES || byteLength > MAX_REASSEMBLED_BYTES || typeof data !== "string" || data.length === 0)
|
|
18006
|
+
throw new Error("Invalid OMP RPC chunk metadata");
|
|
18007
|
+
let bytes;
|
|
18008
|
+
try {
|
|
18009
|
+
bytes = Buffer.from(data, "base64");
|
|
18010
|
+
} catch {
|
|
18011
|
+
throw new Error("Invalid OMP RPC chunk data");
|
|
17988
18012
|
}
|
|
17989
|
-
|
|
18013
|
+
if (bytes.length === 0 || bytes.length > MAX_CHUNK_BYTES || bytes.toString("base64") !== data) {
|
|
18014
|
+
throw new Error("Invalid OMP RPC chunk data");
|
|
18015
|
+
}
|
|
18016
|
+
const chunkIndex = index;
|
|
18017
|
+
const chunkCount = count2;
|
|
18018
|
+
const declaredByteLength = byteLength;
|
|
18019
|
+
if (!this.#pending) {
|
|
18020
|
+
if (chunkIndex !== 0)
|
|
18021
|
+
throw new Error("OMP RPC chunk sequence must start at index 0");
|
|
18022
|
+
this.#pending = {
|
|
18023
|
+
chunkId,
|
|
18024
|
+
count: chunkCount,
|
|
18025
|
+
byteLength: declaredByteLength,
|
|
18026
|
+
nextIndex: 0,
|
|
18027
|
+
chunks: [],
|
|
18028
|
+
received: 0
|
|
18029
|
+
};
|
|
18030
|
+
}
|
|
18031
|
+
const pending = this.#pending;
|
|
18032
|
+
if (!pending)
|
|
18033
|
+
throw new Error("OMP RPC chunk state was lost");
|
|
18034
|
+
if (pending.chunkId !== chunkId || pending.count !== chunkCount || pending.byteLength !== declaredByteLength || pending.nextIndex !== chunkIndex) {
|
|
18035
|
+
throw new Error("OMP RPC chunk sequence mismatch");
|
|
18036
|
+
}
|
|
18037
|
+
pending.chunks.push(bytes);
|
|
18038
|
+
pending.received += bytes.length;
|
|
18039
|
+
pending.nextIndex += 1;
|
|
18040
|
+
if (pending.received > pending.byteLength)
|
|
18041
|
+
throw new Error("OMP RPC chunk sequence exceeds its declared length");
|
|
18042
|
+
if (pending.nextIndex < pending.count)
|
|
18043
|
+
return null;
|
|
18044
|
+
if (pending.received !== pending.byteLength)
|
|
18045
|
+
throw new Error("OMP RPC chunk sequence length mismatch");
|
|
18046
|
+
this.#pending = null;
|
|
18047
|
+
let decoded;
|
|
18048
|
+
try {
|
|
18049
|
+
decoded = JSON.parse(Buffer.concat(pending.chunks).toString("utf8"));
|
|
18050
|
+
} catch {
|
|
18051
|
+
throw new Error("Failed to decode reassembled OMP RPC frame");
|
|
18052
|
+
}
|
|
18053
|
+
if (!isObject2(decoded))
|
|
18054
|
+
throw new Error("Reassembled OMP RPC frame must be an object");
|
|
18055
|
+
return decoded;
|
|
17990
18056
|
}
|
|
17991
18057
|
};
|
|
17992
18058
|
|
|
17993
|
-
//
|
|
17994
|
-
var
|
|
17995
|
-
|
|
17996
|
-
|
|
17997
|
-
|
|
18059
|
+
// dist/omp-rpc-session.js
|
|
18060
|
+
var OmpRpcFaultError = class extends Error {
|
|
18061
|
+
kind;
|
|
18062
|
+
diagnostic;
|
|
18063
|
+
constructor(kind, message3, diagnostic) {
|
|
18064
|
+
super(message3);
|
|
18065
|
+
this.kind = kind;
|
|
18066
|
+
this.diagnostic = diagnostic;
|
|
18067
|
+
this.name = "OmpRpcFaultError";
|
|
17998
18068
|
}
|
|
17999
|
-
|
|
18000
|
-
|
|
18001
|
-
|
|
18002
|
-
|
|
18003
|
-
|
|
18004
|
-
|
|
18005
|
-
|
|
18006
|
-
}
|
|
18007
|
-
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
18008
|
-
if (left.endsWith("\n")) {
|
|
18009
|
-
left = left.slice(0, -1);
|
|
18010
|
-
}
|
|
18011
|
-
if (right.endsWith("\n")) {
|
|
18012
|
-
right = right.slice(0, -1);
|
|
18013
|
-
}
|
|
18014
|
-
}
|
|
18015
|
-
return super.equals(left, right, options);
|
|
18069
|
+
};
|
|
18070
|
+
var OmpRpcUnsupportedCommandError = class extends Error {
|
|
18071
|
+
command;
|
|
18072
|
+
constructor(command) {
|
|
18073
|
+
super(`Omp RPC does not support '${command}'`);
|
|
18074
|
+
this.command = command;
|
|
18075
|
+
this.name = "OmpRpcUnsupportedCommandError";
|
|
18016
18076
|
}
|
|
18017
18077
|
};
|
|
18018
|
-
var
|
|
18019
|
-
function
|
|
18020
|
-
return
|
|
18078
|
+
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
18079
|
+
function isRecord8(value) {
|
|
18080
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18021
18081
|
}
|
|
18022
|
-
function
|
|
18023
|
-
|
|
18024
|
-
|
|
18082
|
+
function message2(value) {
|
|
18083
|
+
return value instanceof Error ? value.message : String(value);
|
|
18084
|
+
}
|
|
18085
|
+
function nonBlankString(value) {
|
|
18086
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
18087
|
+
}
|
|
18088
|
+
function parseNativeModel(value, context) {
|
|
18089
|
+
if (value === null || value === void 0)
|
|
18090
|
+
return null;
|
|
18091
|
+
if (!isRecord8(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
18092
|
+
throw new OmpRpcFaultError("protocolError", `Omp RPC returned an invalid ${context} Model`);
|
|
18025
18093
|
}
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18094
|
+
return { provider: value.provider, id: value.id };
|
|
18095
|
+
}
|
|
18096
|
+
function sessionStateData(response) {
|
|
18097
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18098
|
+
if (!data)
|
|
18099
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC state response has no data");
|
|
18100
|
+
return data;
|
|
18101
|
+
}
|
|
18102
|
+
function parseSessionState(response) {
|
|
18103
|
+
const data = sessionStateData(response);
|
|
18104
|
+
const model2 = parseNativeModel(data.model, "state");
|
|
18105
|
+
if (!nonBlankString(data.sessionId)) {
|
|
18106
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC state has no stable Session identity");
|
|
18029
18107
|
}
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
retLines[retLines.length - 1] += line;
|
|
18034
|
-
} else {
|
|
18035
|
-
retLines.push(line);
|
|
18036
|
-
}
|
|
18108
|
+
const thinkingLevel = data.thinkingLevel === void 0 ? null : harnessThinkingOptionIdSchema.safeParse(data.thinkingLevel);
|
|
18109
|
+
if (thinkingLevel !== null && !thinkingLevel.success) {
|
|
18110
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC state has an invalid Thinking level");
|
|
18037
18111
|
}
|
|
18038
|
-
|
|
18112
|
+
const thinking = isRecord8(data.model) && isRecord8(data.model.thinking) ? data.model.thinking : null;
|
|
18113
|
+
const availableThinkingLevels = thinking && Array.isArray(thinking.efforts) ? thinking.efforts.flatMap((level) => {
|
|
18114
|
+
const parsed = harnessThinkingOptionIdSchema.safeParse(level);
|
|
18115
|
+
return parsed.success ? [parsed.data] : [];
|
|
18116
|
+
}) : null;
|
|
18117
|
+
return {
|
|
18118
|
+
sessionId: data.sessionId,
|
|
18119
|
+
sessionFile: typeof data.sessionFile === "string" ? data.sessionFile : null,
|
|
18120
|
+
provider: model2?.provider ?? null,
|
|
18121
|
+
modelId: model2?.id ?? null,
|
|
18122
|
+
thinkingLevel: thinkingLevel?.data ?? null,
|
|
18123
|
+
contextUsage: optionalOmpStateContextUsage(data.contextUsage),
|
|
18124
|
+
availableThinkingLevels
|
|
18125
|
+
};
|
|
18039
18126
|
}
|
|
18040
|
-
|
|
18041
|
-
|
|
18042
|
-
|
|
18043
|
-
|
|
18044
|
-
let i = 0;
|
|
18045
|
-
function parseIndex() {
|
|
18046
|
-
const index = {};
|
|
18047
|
-
list.push(index);
|
|
18048
|
-
while (i < diffstr.length) {
|
|
18049
|
-
const line = diffstr[i];
|
|
18050
|
-
if (/^(---|\+\+\+|@@)\s/.test(line)) {
|
|
18051
|
-
break;
|
|
18052
|
-
}
|
|
18053
|
-
const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
|
|
18054
|
-
if (header) {
|
|
18055
|
-
index.index = header[1];
|
|
18056
|
-
}
|
|
18057
|
-
i++;
|
|
18058
|
-
}
|
|
18059
|
-
parseFileHeader(index);
|
|
18060
|
-
parseFileHeader(index);
|
|
18061
|
-
index.hunks = [];
|
|
18062
|
-
while (i < diffstr.length) {
|
|
18063
|
-
const line = diffstr[i];
|
|
18064
|
-
if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
|
|
18065
|
-
break;
|
|
18066
|
-
} else if (/^@@/.test(line)) {
|
|
18067
|
-
index.hunks.push(parseHunk());
|
|
18068
|
-
} else if (line) {
|
|
18069
|
-
throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
|
|
18070
|
-
} else {
|
|
18071
|
-
i++;
|
|
18072
|
-
}
|
|
18073
|
-
}
|
|
18127
|
+
function parseSessionStreaming(response) {
|
|
18128
|
+
const isStreaming = sessionStateData(response).isStreaming;
|
|
18129
|
+
if (typeof isStreaming !== "boolean") {
|
|
18130
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC state has no Streaming status");
|
|
18074
18131
|
}
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
index.oldHeader = header;
|
|
18086
|
-
} else {
|
|
18087
|
-
index.newFileName = fileName;
|
|
18088
|
-
index.newHeader = header;
|
|
18089
|
-
}
|
|
18090
|
-
i++;
|
|
18091
|
-
}
|
|
18132
|
+
return isStreaming;
|
|
18133
|
+
}
|
|
18134
|
+
function cancellationSettled(response, terminalEnd) {
|
|
18135
|
+
const data = sessionStateData(response);
|
|
18136
|
+
return !parseSessionStreaming(response) && (data.isSettled === true || data.isSettled === void 0 && terminalEnd) && data.isCompacting !== true && data.hasPendingAsyncWork !== true && !(typeof data.queuedMessageCount === "number" && data.queuedMessageCount > 0);
|
|
18137
|
+
}
|
|
18138
|
+
function parseAvailableModels(response) {
|
|
18139
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18140
|
+
if (!data || !Array.isArray(data.models)) {
|
|
18141
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Model catalog response has no models");
|
|
18092
18142
|
}
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
oldStart: +chunkHeader[1],
|
|
18098
|
-
oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
|
|
18099
|
-
newStart: +chunkHeader[3],
|
|
18100
|
-
newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
|
|
18101
|
-
lines: []
|
|
18102
|
-
};
|
|
18103
|
-
if (hunk.oldLines === 0) {
|
|
18104
|
-
hunk.oldStart += 1;
|
|
18105
|
-
}
|
|
18106
|
-
if (hunk.newLines === 0) {
|
|
18107
|
-
hunk.newStart += 1;
|
|
18108
|
-
}
|
|
18109
|
-
let addCount = 0, removeCount = 0;
|
|
18110
|
-
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
|
|
18111
|
-
const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
|
|
18112
|
-
if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
|
|
18113
|
-
hunk.lines.push(diffstr[i]);
|
|
18114
|
-
if (operation === "+") {
|
|
18115
|
-
addCount++;
|
|
18116
|
-
} else if (operation === "-") {
|
|
18117
|
-
removeCount++;
|
|
18118
|
-
} else if (operation === " ") {
|
|
18119
|
-
addCount++;
|
|
18120
|
-
removeCount++;
|
|
18121
|
-
}
|
|
18122
|
-
} else {
|
|
18123
|
-
throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
|
|
18124
|
-
}
|
|
18125
|
-
}
|
|
18126
|
-
if (!addCount && hunk.newLines === 1) {
|
|
18127
|
-
hunk.newLines = 0;
|
|
18128
|
-
}
|
|
18129
|
-
if (!removeCount && hunk.oldLines === 1) {
|
|
18130
|
-
hunk.oldLines = 0;
|
|
18131
|
-
}
|
|
18132
|
-
if (addCount !== hunk.newLines) {
|
|
18133
|
-
throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
18134
|
-
}
|
|
18135
|
-
if (removeCount !== hunk.oldLines) {
|
|
18136
|
-
throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
18143
|
+
return data.models.map((model2) => {
|
|
18144
|
+
const parsed = parseNativeModel(model2, "catalog");
|
|
18145
|
+
if (!parsed || !isRecord8(model2) || typeof model2.reasoning !== "boolean") {
|
|
18146
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC catalog contains a Model without reasoning capability");
|
|
18137
18147
|
}
|
|
18138
|
-
return
|
|
18148
|
+
return { ...parsed, reasoning: model2.reasoning };
|
|
18149
|
+
});
|
|
18150
|
+
}
|
|
18151
|
+
function parseSubagentMessages(response) {
|
|
18152
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18153
|
+
if (!data || !nonBlankString(data.sessionFile) || !Number.isSafeInteger(data.fromByte) || !Number.isSafeInteger(data.nextByte) || data.fromByte < 0 || data.nextByte < data.fromByte || typeof data.reset !== "boolean" || !Array.isArray(data.entries) || !Array.isArray(data.messages)) {
|
|
18154
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent transcript response is invalid");
|
|
18139
18155
|
}
|
|
18140
|
-
|
|
18141
|
-
|
|
18156
|
+
const entries = data.entries.flatMap((value) => isRecord8(value) ? [value] : []);
|
|
18157
|
+
const messages = data.messages.flatMap((value) => isRecord8(value) ? [value] : []);
|
|
18158
|
+
if (entries.length !== data.entries.length || messages.length !== data.messages.length) {
|
|
18159
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent transcript contains invalid data");
|
|
18142
18160
|
}
|
|
18143
|
-
return
|
|
18161
|
+
return {
|
|
18162
|
+
sessionFile: data.sessionFile,
|
|
18163
|
+
fromByte: data.fromByte,
|
|
18164
|
+
nextByte: data.nextByte,
|
|
18165
|
+
reset: data.reset,
|
|
18166
|
+
entries,
|
|
18167
|
+
messages
|
|
18168
|
+
};
|
|
18144
18169
|
}
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18170
|
+
function subagentStatus(value) {
|
|
18171
|
+
if (value === "pending" || value === "running" || value === "completed")
|
|
18172
|
+
return value;
|
|
18173
|
+
if (value === "failed" || value === "aborted" || value === "interrupted")
|
|
18174
|
+
return "failed";
|
|
18175
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent status is invalid");
|
|
18176
|
+
}
|
|
18177
|
+
function assistantText(value) {
|
|
18178
|
+
if (!isRecord8(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
18179
|
+
return null;
|
|
18180
|
+
return value.content.filter((content) => isRecord8(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
|
|
18181
|
+
}
|
|
18182
|
+
function assistantMessageId(value) {
|
|
18183
|
+
if (!isRecord8(value) || value.role !== "assistant")
|
|
18184
|
+
return null;
|
|
18185
|
+
return nonBlankString(value.responseId) ? value.responseId : null;
|
|
18186
|
+
}
|
|
18187
|
+
function extractReasoningText(content) {
|
|
18188
|
+
if (!isRecord8(content))
|
|
18189
|
+
return null;
|
|
18190
|
+
const type = String(content.type ?? "");
|
|
18191
|
+
if (type === "thinking" || type === "reasoning" || type === "thought") {
|
|
18192
|
+
const text = content.thinking ?? content.reasoning ?? content.text ?? content.delta;
|
|
18193
|
+
return typeof text === "string" ? text : null;
|
|
18155
18194
|
}
|
|
18156
|
-
|
|
18157
|
-
|
|
18195
|
+
return null;
|
|
18196
|
+
}
|
|
18197
|
+
function assistantReasoning(value) {
|
|
18198
|
+
if (!isRecord8(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
18199
|
+
return null;
|
|
18200
|
+
return value.content.map(extractReasoningText).filter((text) => typeof text === "string").join("");
|
|
18201
|
+
}
|
|
18202
|
+
function assistantFailure(value) {
|
|
18203
|
+
if (!isRecord8(value) || value.role !== "assistant")
|
|
18204
|
+
return void 0;
|
|
18205
|
+
if (value.stopReason !== "error" && value.stopReason !== "aborted")
|
|
18206
|
+
return null;
|
|
18207
|
+
const fallback = value.stopReason === "aborted" ? "Omp assistant message was aborted" : "Omp assistant message failed";
|
|
18208
|
+
return new Error(nonBlankString(value.errorMessage) ? value.errorMessage : fallback);
|
|
18209
|
+
}
|
|
18210
|
+
function signalProcessTree(child, signal) {
|
|
18211
|
+
if (!child.pid)
|
|
18212
|
+
return;
|
|
18213
|
+
if (process.platform === "win32") {
|
|
18214
|
+
spawnSync("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], {
|
|
18215
|
+
stdio: "ignore",
|
|
18216
|
+
windowsHide: true
|
|
18217
|
+
});
|
|
18218
|
+
return;
|
|
18158
18219
|
}
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18220
|
+
try {
|
|
18221
|
+
process.kill(-child.pid, signal);
|
|
18222
|
+
} catch (error51) {
|
|
18223
|
+
if (!isRecord8(error51) || error51.code !== "ESRCH")
|
|
18224
|
+
throw error51;
|
|
18162
18225
|
}
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18168
|
-
|
|
18169
|
-
|
|
18170
|
-
|
|
18226
|
+
}
|
|
18227
|
+
function waitForExit(child, timeoutMs) {
|
|
18228
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
18229
|
+
return Promise.resolve(true);
|
|
18230
|
+
return Promise.race([
|
|
18231
|
+
new Promise((resolve) => child.once("exit", () => resolve(true))),
|
|
18232
|
+
new Promise((resolve) => setTimeout(() => resolve(false), timeoutMs))
|
|
18233
|
+
]);
|
|
18234
|
+
}
|
|
18235
|
+
function ompRpcProcessCommand(options, dependencies = {}) {
|
|
18236
|
+
if (options.sessionFile && options.forkSessionFile) {
|
|
18237
|
+
throw new Error("Omp RPC cannot combine Session resume and Fork startup");
|
|
18171
18238
|
}
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
}
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18239
|
+
if (options.model && (options.sessionFile || options.forkSessionFile)) {
|
|
18240
|
+
throw new Error("Omp RPC cannot combine a startup Model with Session restore or Fork");
|
|
18241
|
+
}
|
|
18242
|
+
const platform = dependencies.platform ?? process.platform;
|
|
18243
|
+
const command = resolveOmpExecutable({
|
|
18244
|
+
...options.command ? { command: options.command } : {},
|
|
18245
|
+
environment: options.environment
|
|
18246
|
+
}, {
|
|
18247
|
+
platform,
|
|
18248
|
+
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {},
|
|
18249
|
+
...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {}
|
|
18250
|
+
});
|
|
18251
|
+
const sessionArguments = options.forkSessionFile ? ["--fork", options.forkSessionFile] : options.sessionFile ? ["--resume", options.sessionFile] : [];
|
|
18252
|
+
const modelArguments = options.model ? ["--provider", options.model.provider, "--model", options.model.id] : [];
|
|
18253
|
+
const permissionArguments = options.permissionMode ? ["--approval-mode", options.permissionMode] : [];
|
|
18254
|
+
const arguments_ = [
|
|
18255
|
+
"--mode",
|
|
18256
|
+
// OMP only creates ask and connects its tool UI in rpc-ui mode.
|
|
18257
|
+
"rpc-ui",
|
|
18258
|
+
...permissionArguments,
|
|
18259
|
+
...modelArguments,
|
|
18260
|
+
...sessionArguments
|
|
18261
|
+
];
|
|
18262
|
+
const extension = path6.win32.extname(command).toLowerCase();
|
|
18263
|
+
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
18264
|
+
return { command, arguments: arguments_, windowsVerbatimArguments: false };
|
|
18265
|
+
}
|
|
18266
|
+
const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
|
|
18267
|
+
const commandLine = [command, ...arguments_].map(quote).join(" ");
|
|
18268
|
+
return {
|
|
18269
|
+
command: options.environment?.ComSpec ?? options.environment?.COMSPEC ?? "cmd.exe",
|
|
18270
|
+
arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
|
|
18271
|
+
windowsVerbatimArguments: true
|
|
18272
|
+
};
|
|
18273
|
+
}
|
|
18274
|
+
var nodeProcessAdapter = {
|
|
18275
|
+
spawn(options) {
|
|
18276
|
+
const invocation = ompRpcProcessCommand(options);
|
|
18277
|
+
return spawn(invocation.command, invocation.arguments, {
|
|
18278
|
+
cwd: options.cwd,
|
|
18279
|
+
env: options.environment,
|
|
18280
|
+
detached: process.platform !== "win32",
|
|
18281
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
18282
|
+
windowsHide: true,
|
|
18283
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
18284
|
+
});
|
|
18285
|
+
}
|
|
18286
|
+
};
|
|
18287
|
+
var OmpRpcSession = class {
|
|
18288
|
+
#options;
|
|
18289
|
+
#processAdapter;
|
|
18290
|
+
#activeTurn = null;
|
|
18291
|
+
#buffer = Buffer.alloc(0);
|
|
18292
|
+
#child = null;
|
|
18293
|
+
#closed = false;
|
|
18294
|
+
#closePromise = null;
|
|
18295
|
+
#compactionActive = false;
|
|
18296
|
+
#compactionTurn = null;
|
|
18297
|
+
#compactionTimeout = null;
|
|
18298
|
+
#failed = false;
|
|
18299
|
+
#pending = /* @__PURE__ */ new Map();
|
|
18300
|
+
#state = null;
|
|
18301
|
+
#availableCommands = null;
|
|
18302
|
+
#latestCacheHitRatePercent;
|
|
18303
|
+
#manualCompaction = null;
|
|
18304
|
+
#usageRequestStartedAtMs = null;
|
|
18305
|
+
#stderrTail = "";
|
|
18306
|
+
#frameDecoder = new OmpFrameDecoder();
|
|
18307
|
+
#startupFaultResolve = null;
|
|
18308
|
+
#startupFault = new Promise((resolve) => {
|
|
18309
|
+
this.#startupFaultResolve = resolve;
|
|
18310
|
+
});
|
|
18311
|
+
#readyResolve = null;
|
|
18312
|
+
#ready = new Promise((resolve) => {
|
|
18313
|
+
this.#readyResolve = resolve;
|
|
18314
|
+
});
|
|
18315
|
+
constructor(options, processAdapter = nodeProcessAdapter) {
|
|
18316
|
+
if (options.sessionFile && options.forkSessionFile) {
|
|
18317
|
+
throw new Error("Omp RPC cannot combine Session resume and Fork startup");
|
|
18233
18318
|
}
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
if (hunk.lines[i].endsWith("\n")) {
|
|
18237
|
-
hunk.lines[i] = hunk.lines[i].slice(0, -1);
|
|
18238
|
-
} else {
|
|
18239
|
-
hunk.lines.splice(i + 1, 0, "\");
|
|
18240
|
-
i++;
|
|
18241
|
-
}
|
|
18242
|
-
}
|
|
18319
|
+
if (options.model && (options.sessionFile || options.forkSessionFile)) {
|
|
18320
|
+
throw new Error("Omp RPC cannot combine a startup Model with Session restore or Fork");
|
|
18243
18321
|
}
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
18249
|
-
|
|
18322
|
+
this.#options = {
|
|
18323
|
+
commandTimeoutMs: 3e4,
|
|
18324
|
+
compactionTimeoutMs: 3e5,
|
|
18325
|
+
// Native Abort waits for tools, persistence and deferred work to unwind.
|
|
18326
|
+
// Stable cancellation must outlast the Host's 20s steering wait.
|
|
18327
|
+
cancelTimeoutMs: 3e4,
|
|
18328
|
+
closeTimeoutMs: 2e3,
|
|
18329
|
+
...options
|
|
18250
18330
|
};
|
|
18331
|
+
this.#processAdapter = processAdapter;
|
|
18251
18332
|
}
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
return
|
|
18333
|
+
get state() {
|
|
18334
|
+
if (!this.#state)
|
|
18335
|
+
throw new Error("Omp RPC Session has not started");
|
|
18336
|
+
return this.#state;
|
|
18256
18337
|
}
|
|
18257
|
-
|
|
18258
|
-
|
|
18259
|
-
ret.push("Index: " + patch.oldFileName);
|
|
18338
|
+
get stderrTail() {
|
|
18339
|
+
return this.#stderrTail;
|
|
18260
18340
|
}
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
|
|
18270
|
-
|
|
18341
|
+
async start() {
|
|
18342
|
+
if (this.#child || this.#closed)
|
|
18343
|
+
throw new Error("Omp RPC Session cannot be started twice");
|
|
18344
|
+
const child = this.#processAdapter.spawn({
|
|
18345
|
+
cwd: this.#options.cwd,
|
|
18346
|
+
...this.#options.command ? { command: this.#options.command } : {},
|
|
18347
|
+
environment: withNodeRuntimeOnPath({
|
|
18348
|
+
...process.env,
|
|
18349
|
+
...this.#options.environment,
|
|
18350
|
+
OMP_SKIP_VERSION_CHECK: "1",
|
|
18351
|
+
OMP_TELEMETRY: "0"
|
|
18352
|
+
}),
|
|
18353
|
+
...this.#options.sessionFile ? { sessionFile: this.#options.sessionFile } : {},
|
|
18354
|
+
...this.#options.forkSessionFile ? { forkSessionFile: this.#options.forkSessionFile } : {},
|
|
18355
|
+
...this.#options.model ? { model: this.#options.model } : {},
|
|
18356
|
+
...this.#options.permissionMode ? { permissionMode: this.#options.permissionMode } : {}
|
|
18357
|
+
});
|
|
18358
|
+
this.#child = child;
|
|
18359
|
+
child.stdout.on("data", (chunk) => this.#push(chunk));
|
|
18360
|
+
child.stdout.on("end", () => {
|
|
18361
|
+
if (this.#buffer.length !== 0) {
|
|
18362
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC stdout ended mid-frame"));
|
|
18363
|
+
}
|
|
18364
|
+
});
|
|
18365
|
+
child.stderr.on("data", (chunk) => {
|
|
18366
|
+
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
18367
|
+
});
|
|
18368
|
+
child.once("error", (error51) => {
|
|
18369
|
+
const kind = isRecord8(error51) && error51.code === "ENOENT" ? "notInstalled" : "unavailable";
|
|
18370
|
+
this.#fail(new OmpRpcFaultError(kind, `Omp RPC failed to start: ${error51.message}`, this.stderrTail));
|
|
18371
|
+
});
|
|
18372
|
+
child.once("exit", (code, signal) => {
|
|
18373
|
+
if (!this.#closed) {
|
|
18374
|
+
this.#fail(new OmpRpcFaultError("processExited", `Omp RPC exited (code=${code}, signal=${signal})`, this.stderrTail));
|
|
18375
|
+
}
|
|
18376
|
+
});
|
|
18377
|
+
await Promise.race([
|
|
18378
|
+
new Promise((resolve, reject) => {
|
|
18379
|
+
child.once("spawn", resolve);
|
|
18380
|
+
child.once("error", reject);
|
|
18381
|
+
}),
|
|
18382
|
+
new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Omp RPC start timed out")), this.#options.commandTimeoutMs))
|
|
18383
|
+
]);
|
|
18384
|
+
let readyTimeout;
|
|
18385
|
+
try {
|
|
18386
|
+
await Promise.race([
|
|
18387
|
+
this.#ready,
|
|
18388
|
+
this.#startupFault.then((error51) => {
|
|
18389
|
+
throw error51;
|
|
18390
|
+
}),
|
|
18391
|
+
new Promise((_resolve, reject) => {
|
|
18392
|
+
readyTimeout = setTimeout(() => reject(new Error("Omp RPC ready signal timed out")), this.#options.commandTimeoutMs);
|
|
18393
|
+
})
|
|
18394
|
+
]);
|
|
18395
|
+
} finally {
|
|
18396
|
+
clearTimeout(readyTimeout);
|
|
18271
18397
|
}
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18398
|
+
await this.#send("negotiate_protocol", { protocolVersion: 2 }).catch(() => void 0);
|
|
18399
|
+
if (this.#options.subscribeSubagentEvents !== false) {
|
|
18400
|
+
await this.#send("set_subagent_subscription", { level: "events" }).catch(() => void 0);
|
|
18275
18401
|
}
|
|
18276
|
-
|
|
18277
|
-
|
|
18278
|
-
}
|
|
18279
|
-
|
|
18280
|
-
|
|
18281
|
-
|
|
18282
|
-
}
|
|
18283
|
-
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
|
|
18284
|
-
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
18285
|
-
if (!patchObj) {
|
|
18286
|
-
return;
|
|
18402
|
+
try {
|
|
18403
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18404
|
+
} catch (error51) {
|
|
18405
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("unavailable", `Omp RPC state unavailable: ${message2(error51)}`);
|
|
18406
|
+
this.#fail(fault);
|
|
18407
|
+
throw fault;
|
|
18287
18408
|
}
|
|
18288
|
-
return
|
|
18289
|
-
} else {
|
|
18290
|
-
const { callback } = options;
|
|
18291
|
-
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
|
|
18292
|
-
if (!patchObj) {
|
|
18293
|
-
callback(void 0);
|
|
18294
|
-
} else {
|
|
18295
|
-
callback(formatPatch(patchObj));
|
|
18296
|
-
}
|
|
18297
|
-
} }));
|
|
18298
|
-
}
|
|
18299
|
-
}
|
|
18300
|
-
function splitLines(text) {
|
|
18301
|
-
const hasTrailingNl = text.endsWith("\n");
|
|
18302
|
-
const result = text.split("\n").map((line) => line + "\n");
|
|
18303
|
-
if (hasTrailingNl) {
|
|
18304
|
-
result.pop();
|
|
18305
|
-
} else {
|
|
18306
|
-
result.push(result.pop().slice(0, -1));
|
|
18409
|
+
return this;
|
|
18307
18410
|
}
|
|
18308
|
-
|
|
18309
|
-
|
|
18310
|
-
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
}
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
return [];
|
|
18324
|
-
return value.flatMap((entry) => {
|
|
18325
|
-
if (!isRecord6(entry))
|
|
18326
|
-
return [];
|
|
18327
|
-
const name = typeof entry.name === "string" ? entry.name.trim().replace(/^\//u, "") : "";
|
|
18328
|
-
if (!name)
|
|
18329
|
-
return [];
|
|
18330
|
-
return [
|
|
18331
|
-
{
|
|
18332
|
-
name,
|
|
18333
|
-
description: typeof entry.description === "string" ? entry.description : "",
|
|
18334
|
-
source: typeof entry.source === "string" ? entry.source : null
|
|
18411
|
+
async getEntries() {
|
|
18412
|
+
try {
|
|
18413
|
+
if (this.state.sessionFile) {
|
|
18414
|
+
try {
|
|
18415
|
+
return await readOmpSessionHistory(this.state.sessionFile);
|
|
18416
|
+
} catch (error51) {
|
|
18417
|
+
if (!isRecord8(error51) || error51.code !== "ENOENT" || this.#options.sessionFile || this.#options.forkSessionFile)
|
|
18418
|
+
throw error51;
|
|
18419
|
+
const response2 = await this.#send("get_messages", {});
|
|
18420
|
+
const data2 = isRecord8(response2.data) ? response2.data : null;
|
|
18421
|
+
if (data2 && Array.isArray(data2.messages) && data2.messages.length === 0) {
|
|
18422
|
+
return { entries: [], leafId: null };
|
|
18423
|
+
}
|
|
18424
|
+
throw error51;
|
|
18425
|
+
}
|
|
18335
18426
|
}
|
|
18336
|
-
|
|
18337
|
-
|
|
18338
|
-
|
|
18339
|
-
|
|
18340
|
-
return native.filter(({ source, name }) => source !== "builtin" || name === "context").map((command) => ({
|
|
18341
|
-
name: command.name,
|
|
18342
|
-
description: command.description,
|
|
18343
|
-
kind: command.source === "skill" ? "skill" : "command"
|
|
18344
|
-
}));
|
|
18345
|
-
}
|
|
18346
|
-
|
|
18347
|
-
// dist/omp-session-file.js
|
|
18348
|
-
import { createReadStream as createReadStream3 } from "node:fs";
|
|
18349
|
-
import { open, realpath as realpath2 } from "node:fs/promises";
|
|
18350
|
-
import readline from "node:readline";
|
|
18351
|
-
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
18352
|
-
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
18353
|
-
function isRecord7(value) {
|
|
18354
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18355
|
-
}
|
|
18356
|
-
function historyEntry(value) {
|
|
18357
|
-
if (!isRecord7(value) || value.type === "title" || value.type === "session" || typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
|
|
18358
|
-
return null;
|
|
18359
|
-
}
|
|
18360
|
-
return value;
|
|
18361
|
-
}
|
|
18362
|
-
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
18363
|
-
const entries = [];
|
|
18364
|
-
let leafId = null;
|
|
18365
|
-
let incomplete = false;
|
|
18366
|
-
const lines = readline.createInterface({
|
|
18367
|
-
input: createReadStream3(sessionFile, {
|
|
18368
|
-
encoding: "utf8",
|
|
18369
|
-
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
18370
|
-
}),
|
|
18371
|
-
crlfDelay: Number.POSITIVE_INFINITY
|
|
18372
|
-
});
|
|
18373
|
-
try {
|
|
18374
|
-
for await (const line of lines) {
|
|
18375
|
-
if (line.length === 0)
|
|
18376
|
-
continue;
|
|
18377
|
-
let parsed;
|
|
18378
|
-
try {
|
|
18379
|
-
parsed = JSON.parse(line);
|
|
18380
|
-
} catch {
|
|
18381
|
-
incomplete = true;
|
|
18382
|
-
continue;
|
|
18427
|
+
const response = await this.#send("get_messages", {});
|
|
18428
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18429
|
+
if (!data || !Array.isArray(data.messages)) {
|
|
18430
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC messages response has no messages");
|
|
18383
18431
|
}
|
|
18384
|
-
|
|
18385
|
-
|
|
18386
|
-
|
|
18387
|
-
|
|
18432
|
+
let branchEntryIds = null;
|
|
18433
|
+
try {
|
|
18434
|
+
const branchResponse = await this.#send("get_branch_messages", {});
|
|
18435
|
+
const branchData = isRecord8(branchResponse.data) ? branchResponse.data : null;
|
|
18436
|
+
if (branchData && Array.isArray(branchData.messages)) {
|
|
18437
|
+
const parsed = branchData.messages.flatMap((entry) => {
|
|
18438
|
+
if (!isRecord8(entry) || !nonBlankString(entry.entryId))
|
|
18439
|
+
return [];
|
|
18440
|
+
return [entry.entryId];
|
|
18441
|
+
});
|
|
18442
|
+
if (parsed.length === branchData.messages.length)
|
|
18443
|
+
branchEntryIds = parsed;
|
|
18388
18444
|
}
|
|
18389
|
-
|
|
18445
|
+
} catch (error51) {
|
|
18446
|
+
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18447
|
+
throw error51;
|
|
18390
18448
|
}
|
|
18391
|
-
|
|
18392
|
-
|
|
18449
|
+
let userIndex = 0;
|
|
18450
|
+
let parentId = null;
|
|
18451
|
+
const entries = data.messages.map((nativeMessage, index) => {
|
|
18452
|
+
const role = isRecord8(nativeMessage) ? nativeMessage.role : void 0;
|
|
18453
|
+
const branchId = role === "user" ? branchEntryIds?.[userIndex] : void 0;
|
|
18454
|
+
if (branchId)
|
|
18455
|
+
userIndex += 1;
|
|
18456
|
+
const id = branchId ?? (isRecord8(nativeMessage) && nonBlankString(nativeMessage.id) ? nativeMessage.id : `omp-message-${index}`);
|
|
18457
|
+
const entry = { id, parentId, type: "message", message: nativeMessage };
|
|
18458
|
+
parentId = id;
|
|
18459
|
+
return entry;
|
|
18460
|
+
});
|
|
18461
|
+
return { entries, leafId: parentId };
|
|
18462
|
+
} catch (error51) {
|
|
18463
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18464
|
+
this.#fail(error51);
|
|
18465
|
+
throw error51;
|
|
18393
18466
|
}
|
|
18394
|
-
} finally {
|
|
18395
|
-
lines.close();
|
|
18396
18467
|
}
|
|
18397
|
-
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
const handle = await open(sessionFile, "r");
|
|
18401
|
-
try {
|
|
18402
|
-
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
18403
|
-
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
18404
|
-
const contents = buffer.subarray(0, bytesRead);
|
|
18405
|
-
const newline = contents.indexOf(10);
|
|
18406
|
-
if (newline < 0 && bytesRead === buffer.length) {
|
|
18407
|
-
throw new Error("Omp Session header exceeds the supported size");
|
|
18468
|
+
async getSubagentMessages(input) {
|
|
18469
|
+
if ((input.subagentId === void 0 || !nonBlankString(input.subagentId)) && (input.sessionFile === void 0 || !nonBlankString(input.sessionFile))) {
|
|
18470
|
+
throw new Error("Omp Subagent transcript requires a Subagent ID or Session file");
|
|
18408
18471
|
}
|
|
18409
|
-
|
|
18410
|
-
|
|
18411
|
-
if (line.length === 0)
|
|
18412
|
-
continue;
|
|
18413
|
-
let parsed;
|
|
18414
|
-
try {
|
|
18415
|
-
parsed = JSON.parse(line);
|
|
18416
|
-
} catch {
|
|
18417
|
-
continue;
|
|
18418
|
-
}
|
|
18419
|
-
if (!isRecord7(parsed) || parsed.type !== "session")
|
|
18420
|
-
continue;
|
|
18421
|
-
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
18422
|
-
throw new Error("Omp Session header is invalid");
|
|
18423
|
-
}
|
|
18424
|
-
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
18472
|
+
if (input.fromByte !== void 0 && (!Number.isSafeInteger(input.fromByte) || input.fromByte < 0)) {
|
|
18473
|
+
throw new Error("Omp Subagent transcript offset is invalid");
|
|
18425
18474
|
}
|
|
18426
|
-
|
|
18427
|
-
|
|
18428
|
-
|
|
18475
|
+
const response = await this.#send("get_subagent_messages", {
|
|
18476
|
+
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
18477
|
+
...input.sessionFile ? { sessionFile: input.sessionFile } : {},
|
|
18478
|
+
...input.fromByte !== void 0 ? { fromByte: input.fromByte } : {}
|
|
18479
|
+
});
|
|
18480
|
+
return parseSubagentMessages(response);
|
|
18429
18481
|
}
|
|
18430
|
-
|
|
18431
|
-
|
|
18432
|
-
|
|
18433
|
-
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
|
|
18482
|
+
async compact(customInstructions, onEvent) {
|
|
18483
|
+
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
18484
|
+
throw new Error("Omp RPC Session is unavailable");
|
|
18485
|
+
}
|
|
18486
|
+
if (this.#activeTurn || this.#manualCompaction || this.#compactionActive) {
|
|
18487
|
+
throw new Error("Omp RPC Session already has an active operation");
|
|
18488
|
+
}
|
|
18489
|
+
const result = new Promise((resolve, reject) => {
|
|
18490
|
+
this.#manualCompaction = { onEvent, resolve, reject };
|
|
18491
|
+
});
|
|
18492
|
+
try {
|
|
18493
|
+
await this.#send("compact", customInstructions ? { customInstructions } : {});
|
|
18494
|
+
} catch (error51) {
|
|
18495
|
+
const pending = this.#manualCompaction;
|
|
18496
|
+
this.#manualCompaction = null;
|
|
18497
|
+
pending?.reject(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
18498
|
+
}
|
|
18499
|
+
return result;
|
|
18437
18500
|
}
|
|
18438
|
-
|
|
18439
|
-
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18501
|
+
async getSessionUsage() {
|
|
18502
|
+
try {
|
|
18503
|
+
const usage = parseOmpSessionUsage(await this.#send("get_session_stats", {}));
|
|
18504
|
+
await this.#ensureLatestCacheHitRate();
|
|
18505
|
+
return this.#withLatestCacheHitRate(usage);
|
|
18506
|
+
} catch (error51) {
|
|
18507
|
+
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18508
|
+
throw error51;
|
|
18509
|
+
const response = await this.#send("get_state", {});
|
|
18510
|
+
const observedState = parseSessionState(response);
|
|
18511
|
+
if (!this.#state || observedState.sessionId !== this.#state.sessionId || observedState.provider !== this.#state.provider || observedState.modelId !== this.#state.modelId) {
|
|
18512
|
+
throw new Error("Omp RPC Usage fallback does not match the confirmed Session state");
|
|
18513
|
+
}
|
|
18514
|
+
await this.#ensureLatestCacheHitRate();
|
|
18515
|
+
const usage = parseOmpStateContextUsage(response);
|
|
18516
|
+
return usage ? this.#withLatestCacheHitRate(usage) : null;
|
|
18517
|
+
}
|
|
18444
18518
|
}
|
|
18445
|
-
|
|
18446
|
-
|
|
18447
|
-
|
|
18448
|
-
|
|
18449
|
-
|
|
18450
|
-
|
|
18451
|
-
|
|
18452
|
-
|
|
18519
|
+
async #ensureLatestCacheHitRate() {
|
|
18520
|
+
if (this.#latestCacheHitRatePercent !== void 0)
|
|
18521
|
+
return;
|
|
18522
|
+
try {
|
|
18523
|
+
this.#latestCacheHitRatePercent = latestOmpCacheHitRatePercent(await this.getEntries());
|
|
18524
|
+
} catch {
|
|
18525
|
+
this.#latestCacheHitRatePercent = null;
|
|
18526
|
+
}
|
|
18453
18527
|
}
|
|
18454
|
-
|
|
18455
|
-
}
|
|
18456
|
-
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
18457
|
-
const startupState = transport.state;
|
|
18458
|
-
const startupSessionId = startupState.sessionId;
|
|
18459
|
-
const currentModel = modelFromState(startupState);
|
|
18460
|
-
const currentThinking = startupState.thinkingLevel;
|
|
18461
|
-
const copiedHistory = await transport.getEntries();
|
|
18462
|
-
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
18463
|
-
if (!boundary)
|
|
18464
|
-
return { ok: false, reason: "empty" };
|
|
18465
|
-
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
18466
|
-
sessionId: startupSessionId,
|
|
18467
|
-
model: currentModel
|
|
18468
|
-
});
|
|
18469
|
-
let state = await transport.fork(boundary.lastUserEntryId);
|
|
18470
|
-
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
18471
|
-
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
18528
|
+
#withLatestCacheHitRate(usage) {
|
|
18529
|
+
return this.#latestCacheHitRatePercent === null || this.#latestCacheHitRatePercent === void 0 ? usage : parseHostUsage({ ...usage, cacheHitRatePercent: this.#latestCacheHitRatePercent });
|
|
18472
18530
|
}
|
|
18473
|
-
|
|
18474
|
-
if (!
|
|
18475
|
-
throw new Error("Omp
|
|
18476
|
-
|
|
18531
|
+
async fork(entryId) {
|
|
18532
|
+
if (!nonBlankString(entryId))
|
|
18533
|
+
throw new Error("Omp RPC Fork requires an Entry identity");
|
|
18534
|
+
try {
|
|
18535
|
+
const response = await this.#send("branch", { entryId });
|
|
18536
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18537
|
+
if (!data || data.cancelled === true) {
|
|
18538
|
+
throw new OmpRpcFaultError("unavailable", "Omp RPC Fork was cancelled");
|
|
18539
|
+
}
|
|
18540
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18541
|
+
return this.#state;
|
|
18542
|
+
} catch (error51) {
|
|
18543
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18544
|
+
this.#fail(error51);
|
|
18545
|
+
throw error51;
|
|
18546
|
+
}
|
|
18477
18547
|
}
|
|
18478
|
-
|
|
18479
|
-
|
|
18480
|
-
|
|
18481
|
-
|
|
18548
|
+
verifySessionCwd(expectedCwd) {
|
|
18549
|
+
return verifyOmpSessionCwd({
|
|
18550
|
+
sessionFile: this.state.sessionFile,
|
|
18551
|
+
sessionId: this.state.sessionId,
|
|
18552
|
+
expectedCwd
|
|
18553
|
+
});
|
|
18482
18554
|
}
|
|
18483
|
-
|
|
18484
|
-
|
|
18555
|
+
async getAvailableModels() {
|
|
18556
|
+
try {
|
|
18557
|
+
return parseAvailableModels(await this.#send("get_available_models", {}));
|
|
18558
|
+
} catch (error51) {
|
|
18559
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18560
|
+
this.#fail(error51);
|
|
18561
|
+
throw error51;
|
|
18562
|
+
}
|
|
18485
18563
|
}
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
model: modelFromState(state)
|
|
18489
|
-
});
|
|
18490
|
-
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
18491
|
-
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
18492
|
-
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
18493
|
-
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
18564
|
+
async getAvailableThinkingLevels() {
|
|
18565
|
+
return this.state.availableThinkingLevels;
|
|
18494
18566
|
}
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18499
|
-
// dist/omp-rpc-session.js
|
|
18500
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
18501
|
-
import { randomUUID } from "node:crypto";
|
|
18502
|
-
import path6 from "node:path";
|
|
18503
|
-
|
|
18504
|
-
// dist/command.js
|
|
18505
|
-
var ompDiscoverySpec = {
|
|
18506
|
-
id: "omp",
|
|
18507
|
-
command: "omp",
|
|
18508
|
-
commandEnvironmentVariable: "OMP_COMMAND",
|
|
18509
|
-
installRoots: {
|
|
18510
|
-
posix: [
|
|
18511
|
-
"~/.npm-global/bin",
|
|
18512
|
-
"~/.local/bin",
|
|
18513
|
-
VERSION_MANAGER_ROOTS,
|
|
18514
|
-
"/opt/homebrew/bin",
|
|
18515
|
-
"/usr/local/bin"
|
|
18516
|
-
],
|
|
18517
|
-
windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS]
|
|
18567
|
+
async selectModel(model2) {
|
|
18568
|
+
await this.#send("set_model", { provider: model2.provider, modelId: model2.id });
|
|
18569
|
+
return this.#refreshState("Model");
|
|
18518
18570
|
}
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
|
|
18522
|
-
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {}
|
|
18526
|
-
}, { ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {} });
|
|
18527
|
-
return resolution?.executable ?? input.command ?? input.environment.OMP_COMMAND ?? "omp";
|
|
18528
|
-
}
|
|
18529
|
-
|
|
18530
|
-
// dist/omp-protocol.js
|
|
18531
|
-
var MAX_FRAME_BYTES = 1024 * 1024;
|
|
18532
|
-
var MAX_REASSEMBLED_BYTES = 64 * 1024 * 1024;
|
|
18533
|
-
var MAX_CHUNK_BYTES = 256 * 1024;
|
|
18534
|
-
function isObject2(value) {
|
|
18535
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18536
|
-
}
|
|
18537
|
-
var OmpFrameDecoder = class {
|
|
18538
|
-
#pending = null;
|
|
18539
|
-
push(value) {
|
|
18540
|
-
if (!isObject2(value))
|
|
18541
|
-
throw new Error("OMP RPC frame must be a JSON object");
|
|
18542
|
-
if (value.type !== "rpc_chunk") {
|
|
18543
|
-
if (this.#pending)
|
|
18544
|
-
throw new Error("OMP RPC chunk sequence was interrupted");
|
|
18545
|
-
return value;
|
|
18546
|
-
}
|
|
18547
|
-
const chunkId = value.chunkId;
|
|
18548
|
-
const index = value.index;
|
|
18549
|
-
const count2 = value.count;
|
|
18550
|
-
const byteLength = value.byteLength;
|
|
18551
|
-
const data = value.data;
|
|
18552
|
-
if (typeof chunkId !== "string" || chunkId.length === 0 || chunkId.length > 128 || !Number.isInteger(index) || !Number.isInteger(count2) || !Number.isInteger(byteLength) || index < 0 || count2 < 2 || index >= count2 || byteLength < MAX_FRAME_BYTES || byteLength > MAX_REASSEMBLED_BYTES || typeof data !== "string" || data.length === 0)
|
|
18553
|
-
throw new Error("Invalid OMP RPC chunk metadata");
|
|
18554
|
-
let bytes;
|
|
18571
|
+
async selectThinkingOption(thinkingOptionId) {
|
|
18572
|
+
const level = harnessThinkingOptionIdSchema.parse(thinkingOptionId);
|
|
18573
|
+
await this.#send("set_thinking_level", { level });
|
|
18574
|
+
return this.#refreshState("Thinking");
|
|
18575
|
+
}
|
|
18576
|
+
async #refreshState(operation) {
|
|
18555
18577
|
try {
|
|
18556
|
-
|
|
18557
|
-
|
|
18558
|
-
|
|
18578
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18579
|
+
return this.#state;
|
|
18580
|
+
} catch (error51) {
|
|
18581
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
18582
|
+
this.#fail(fault);
|
|
18583
|
+
throw fault;
|
|
18559
18584
|
}
|
|
18560
|
-
|
|
18561
|
-
|
|
18585
|
+
}
|
|
18586
|
+
async runTurn(text, onEvent) {
|
|
18587
|
+
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
18588
|
+
throw new Error("Omp RPC Session is unavailable");
|
|
18562
18589
|
}
|
|
18563
|
-
|
|
18564
|
-
|
|
18565
|
-
|
|
18566
|
-
|
|
18567
|
-
|
|
18568
|
-
|
|
18569
|
-
this.#
|
|
18570
|
-
|
|
18571
|
-
|
|
18572
|
-
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
|
-
|
|
18590
|
+
if (this.#activeTurn)
|
|
18591
|
+
throw new Error("Omp RPC Session already has an active Turn");
|
|
18592
|
+
if (text.length === 0)
|
|
18593
|
+
throw new Error("Omp text Turn must not be empty");
|
|
18594
|
+
const promptId = `codexhost-${randomUUID()}`;
|
|
18595
|
+
const settled = new Promise((resolve, reject) => {
|
|
18596
|
+
this.#activeTurn = {
|
|
18597
|
+
promptId,
|
|
18598
|
+
localResult: null,
|
|
18599
|
+
text: "",
|
|
18600
|
+
assistantMessageId: null,
|
|
18601
|
+
sawStreamedMessageText: false,
|
|
18602
|
+
sawStreamedMessageReasoning: false,
|
|
18603
|
+
lastFinalizedMessageText: null,
|
|
18604
|
+
lastFinalizedMessageReasoning: null,
|
|
18605
|
+
reasoningMessageOpen: false,
|
|
18606
|
+
onEvent,
|
|
18607
|
+
resolve,
|
|
18608
|
+
reject,
|
|
18609
|
+
failure: null,
|
|
18610
|
+
sawTool: false,
|
|
18611
|
+
tools: /* @__PURE__ */ new Map(),
|
|
18612
|
+
interactions: /* @__PURE__ */ new Map(),
|
|
18613
|
+
settlement: "pending",
|
|
18614
|
+
terminalEnd: false,
|
|
18615
|
+
cancellation: "none",
|
|
18616
|
+
cancellationTimeout: null,
|
|
18617
|
+
cancellationRecheck: null,
|
|
18618
|
+
cancellationChecking: false,
|
|
18619
|
+
cancellationReloaded: false,
|
|
18620
|
+
abortPromise: null
|
|
18576
18621
|
};
|
|
18622
|
+
});
|
|
18623
|
+
try {
|
|
18624
|
+
await this.#send("prompt", { message: text }, promptId);
|
|
18625
|
+
} catch (error51) {
|
|
18626
|
+
this.#rejectActiveTurn(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
18577
18627
|
}
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18628
|
+
return settled;
|
|
18629
|
+
}
|
|
18630
|
+
respondToInteraction(response) {
|
|
18631
|
+
return this.#resolveInteraction(response, "cancelled" in response ? "cancelled" : "responded");
|
|
18632
|
+
}
|
|
18633
|
+
async #resolveInteraction(response, reason) {
|
|
18634
|
+
const active = this.#activeTurn;
|
|
18635
|
+
const pending = active?.interactions.get(response.requestId);
|
|
18636
|
+
if (!active || !pending || this.#closed || this.#failed) {
|
|
18637
|
+
throw new Error("Omp RPC interaction is not pending");
|
|
18583
18638
|
}
|
|
18584
|
-
pending.
|
|
18585
|
-
|
|
18586
|
-
|
|
18587
|
-
if (pending.
|
|
18588
|
-
throw new Error("
|
|
18589
|
-
|
|
18590
|
-
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
|
|
18639
|
+
if ("value" in response && !["select", "input", "editor"].includes(pending.request.method)) {
|
|
18640
|
+
throw new Error("Omp RPC interaction response type does not match the request");
|
|
18641
|
+
}
|
|
18642
|
+
if ("confirmed" in response && pending.request.method !== "confirm") {
|
|
18643
|
+
throw new Error("Omp RPC confirmation does not match the request");
|
|
18644
|
+
}
|
|
18645
|
+
const frame = "cancelled" in response ? {
|
|
18646
|
+
type: "extension_ui_response",
|
|
18647
|
+
id: response.requestId,
|
|
18648
|
+
cancelled: true,
|
|
18649
|
+
...reason === "expired" ? { timedOut: true } : {}
|
|
18650
|
+
} : "confirmed" in response ? { type: "extension_ui_response", id: response.requestId, confirmed: response.confirmed } : { type: "extension_ui_response", id: response.requestId, value: response.value };
|
|
18651
|
+
if (!active.interactions.delete(response.requestId)) {
|
|
18652
|
+
throw new Error("Omp RPC interaction is not pending");
|
|
18653
|
+
}
|
|
18654
|
+
if (pending.timeout)
|
|
18655
|
+
clearTimeout(pending.timeout);
|
|
18656
|
+
active.onEvent({ type: "interaction.closed", requestId: response.requestId, reason });
|
|
18595
18657
|
try {
|
|
18596
|
-
|
|
18597
|
-
} catch {
|
|
18598
|
-
|
|
18658
|
+
await this.#write(frame);
|
|
18659
|
+
} catch (error51) {
|
|
18660
|
+
const fault = new OmpRpcFaultError("protocolError", `Omp RPC interaction response failed: ${message2(error51)}`);
|
|
18661
|
+
this.#fail(fault);
|
|
18662
|
+
throw fault;
|
|
18599
18663
|
}
|
|
18600
|
-
if (!isObject2(decoded))
|
|
18601
|
-
throw new Error("Reassembled OMP RPC frame must be an object");
|
|
18602
|
-
return decoded;
|
|
18603
18664
|
}
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
kind;
|
|
18609
|
-
diagnostic;
|
|
18610
|
-
constructor(kind, message3, diagnostic) {
|
|
18611
|
-
super(message3);
|
|
18612
|
-
this.kind = kind;
|
|
18613
|
-
this.diagnostic = diagnostic;
|
|
18614
|
-
this.name = "OmpRpcFaultError";
|
|
18615
|
-
}
|
|
18616
|
-
};
|
|
18617
|
-
var OmpRpcUnsupportedCommandError = class extends Error {
|
|
18618
|
-
command;
|
|
18619
|
-
constructor(command) {
|
|
18620
|
-
super(`Omp RPC does not support '${command}'`);
|
|
18621
|
-
this.command = command;
|
|
18622
|
-
this.name = "OmpRpcUnsupportedCommandError";
|
|
18623
|
-
}
|
|
18624
|
-
};
|
|
18625
|
-
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
18626
|
-
function isRecord8(value) {
|
|
18627
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18628
|
-
}
|
|
18629
|
-
function message2(value) {
|
|
18630
|
-
return value instanceof Error ? value.message : String(value);
|
|
18631
|
-
}
|
|
18632
|
-
function nonBlankString(value) {
|
|
18633
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
18634
|
-
}
|
|
18635
|
-
function parseNativeModel(value, context) {
|
|
18636
|
-
if (value === null || value === void 0)
|
|
18637
|
-
return null;
|
|
18638
|
-
if (!isRecord8(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
18639
|
-
throw new OmpRpcFaultError("protocolError", `Omp RPC returned an invalid ${context} Model`);
|
|
18640
|
-
}
|
|
18641
|
-
return { provider: value.provider, id: value.id };
|
|
18642
|
-
}
|
|
18643
|
-
function sessionStateData(response) {
|
|
18644
|
-
const data = isRecord8(response.data) ? response.data : null;
|
|
18645
|
-
if (!data)
|
|
18646
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC state response has no data");
|
|
18647
|
-
return data;
|
|
18648
|
-
}
|
|
18649
|
-
function parseSessionState(response) {
|
|
18650
|
-
const data = sessionStateData(response);
|
|
18651
|
-
const model2 = parseNativeModel(data.model, "state");
|
|
18652
|
-
if (!nonBlankString(data.sessionId)) {
|
|
18653
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC state has no stable Session identity");
|
|
18654
|
-
}
|
|
18655
|
-
const thinkingLevel = data.thinkingLevel === void 0 ? null : harnessThinkingOptionIdSchema.safeParse(data.thinkingLevel);
|
|
18656
|
-
if (thinkingLevel !== null && !thinkingLevel.success) {
|
|
18657
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC state has an invalid Thinking level");
|
|
18658
|
-
}
|
|
18659
|
-
const thinking = isRecord8(data.model) && isRecord8(data.model.thinking) ? data.model.thinking : null;
|
|
18660
|
-
const availableThinkingLevels = thinking && Array.isArray(thinking.efforts) ? thinking.efforts.flatMap((level) => {
|
|
18661
|
-
const parsed = harnessThinkingOptionIdSchema.safeParse(level);
|
|
18662
|
-
return parsed.success ? [parsed.data] : [];
|
|
18663
|
-
}) : null;
|
|
18664
|
-
return {
|
|
18665
|
-
sessionId: data.sessionId,
|
|
18666
|
-
sessionFile: typeof data.sessionFile === "string" ? data.sessionFile : null,
|
|
18667
|
-
provider: model2?.provider ?? null,
|
|
18668
|
-
modelId: model2?.id ?? null,
|
|
18669
|
-
thinkingLevel: thinkingLevel?.data ?? null,
|
|
18670
|
-
contextUsage: optionalOmpStateContextUsage(data.contextUsage),
|
|
18671
|
-
availableThinkingLevels
|
|
18672
|
-
};
|
|
18673
|
-
}
|
|
18674
|
-
function parseSessionStreaming(response) {
|
|
18675
|
-
const isStreaming = sessionStateData(response).isStreaming;
|
|
18676
|
-
if (typeof isStreaming !== "boolean") {
|
|
18677
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC state has no Streaming status");
|
|
18678
|
-
}
|
|
18679
|
-
return isStreaming;
|
|
18680
|
-
}
|
|
18681
|
-
function cancellationSettled(response, terminalEnd) {
|
|
18682
|
-
const data = sessionStateData(response);
|
|
18683
|
-
return !parseSessionStreaming(response) && (data.isSettled === true || data.isSettled === void 0 && terminalEnd) && data.isCompacting !== true && data.hasPendingAsyncWork !== true && !(typeof data.queuedMessageCount === "number" && data.queuedMessageCount > 0);
|
|
18684
|
-
}
|
|
18685
|
-
function parseAvailableModels(response) {
|
|
18686
|
-
const data = isRecord8(response.data) ? response.data : null;
|
|
18687
|
-
if (!data || !Array.isArray(data.models)) {
|
|
18688
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Model catalog response has no models");
|
|
18689
|
-
}
|
|
18690
|
-
return data.models.map((model2) => {
|
|
18691
|
-
const parsed = parseNativeModel(model2, "catalog");
|
|
18692
|
-
if (!parsed || !isRecord8(model2) || typeof model2.reasoning !== "boolean") {
|
|
18693
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC catalog contains a Model without reasoning capability");
|
|
18665
|
+
abort() {
|
|
18666
|
+
const active = this.#activeTurn;
|
|
18667
|
+
if (!active || this.#closed || this.#failed) {
|
|
18668
|
+
return Promise.reject(new Error("Omp RPC Session has no cancellable Turn"));
|
|
18694
18669
|
}
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
|
|
18670
|
+
if (active.abortPromise)
|
|
18671
|
+
return active.abortPromise;
|
|
18672
|
+
active.cancellation = "requesting";
|
|
18673
|
+
active.cancellationTimeout = setTimeout(() => {
|
|
18674
|
+
this.#terminateFailedCancellation(active, new OmpRpcFaultError("protocolError", "Omp Turn cancellation did not settle within its bound"));
|
|
18675
|
+
}, this.#options.cancelTimeoutMs);
|
|
18676
|
+
const aborting = this.#send("abort", {}).then(async () => {
|
|
18677
|
+
if (this.#activeTurn !== active)
|
|
18678
|
+
return;
|
|
18679
|
+
active.cancellation = "accepted";
|
|
18680
|
+
await this.#confirmCancelledTurn(active);
|
|
18681
|
+
}).catch((error51) => {
|
|
18682
|
+
if (this.#activeTurn !== active)
|
|
18683
|
+
throw error51;
|
|
18684
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC Abort failed: ${message2(error51)}`);
|
|
18685
|
+
this.#terminateFailedCancellation(active, fault);
|
|
18686
|
+
throw fault;
|
|
18687
|
+
});
|
|
18688
|
+
active.abortPromise = aborting;
|
|
18689
|
+
return aborting;
|
|
18707
18690
|
}
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
}
|
|
18717
|
-
function subagentStatus(value) {
|
|
18718
|
-
if (value === "pending" || value === "running" || value === "completed")
|
|
18719
|
-
return value;
|
|
18720
|
-
if (value === "failed" || value === "aborted" || value === "interrupted")
|
|
18721
|
-
return "failed";
|
|
18722
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent status is invalid");
|
|
18723
|
-
}
|
|
18724
|
-
function assistantText(value) {
|
|
18725
|
-
if (!isRecord8(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
18726
|
-
return null;
|
|
18727
|
-
return value.content.filter((content) => isRecord8(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
|
|
18728
|
-
}
|
|
18729
|
-
function assistantMessageId(value) {
|
|
18730
|
-
if (!isRecord8(value) || value.role !== "assistant")
|
|
18731
|
-
return null;
|
|
18732
|
-
return nonBlankString(value.responseId) ? value.responseId : null;
|
|
18733
|
-
}
|
|
18734
|
-
function extractReasoningText(content) {
|
|
18735
|
-
if (!isRecord8(content))
|
|
18736
|
-
return null;
|
|
18737
|
-
const type = String(content.type ?? "");
|
|
18738
|
-
if (type === "thinking" || type === "reasoning" || type === "thought") {
|
|
18739
|
-
const text = content.thinking ?? content.reasoning ?? content.text ?? content.delta;
|
|
18740
|
-
return typeof text === "string" ? text : null;
|
|
18691
|
+
#terminateFailedCancellation(active, fault) {
|
|
18692
|
+
if (this.#activeTurn !== active)
|
|
18693
|
+
return;
|
|
18694
|
+
if (active.cancellationTimeout)
|
|
18695
|
+
clearTimeout(active.cancellationTimeout);
|
|
18696
|
+
active.cancellationTimeout = null;
|
|
18697
|
+
this.#fail(fault);
|
|
18698
|
+
void this.close().catch(() => void 0);
|
|
18741
18699
|
}
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
function assistantFailure(value) {
|
|
18750
|
-
if (!isRecord8(value) || value.role !== "assistant")
|
|
18751
|
-
return void 0;
|
|
18752
|
-
if (value.stopReason !== "error" && value.stopReason !== "aborted")
|
|
18753
|
-
return null;
|
|
18754
|
-
const fallback = value.stopReason === "aborted" ? "Omp assistant message was aborted" : "Omp assistant message failed";
|
|
18755
|
-
return new Error(nonBlankString(value.errorMessage) ? value.errorMessage : fallback);
|
|
18756
|
-
}
|
|
18757
|
-
function signalProcessTree(child, signal) {
|
|
18758
|
-
if (!child.pid)
|
|
18759
|
-
return;
|
|
18760
|
-
if (process.platform === "win32") {
|
|
18761
|
-
spawnSync("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], {
|
|
18762
|
-
stdio: "ignore",
|
|
18763
|
-
windowsHide: true
|
|
18764
|
-
});
|
|
18765
|
-
return;
|
|
18700
|
+
close() {
|
|
18701
|
+
if (!this.#closed) {
|
|
18702
|
+
this.#closed = true;
|
|
18703
|
+
this.#rejectAll(new Error("Omp RPC Session closed"));
|
|
18704
|
+
}
|
|
18705
|
+
this.#closePromise ??= this.#stopProcess();
|
|
18706
|
+
return this.#closePromise;
|
|
18766
18707
|
}
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18708
|
+
async #stopProcess() {
|
|
18709
|
+
const child = this.#child;
|
|
18710
|
+
if (!child)
|
|
18711
|
+
return;
|
|
18712
|
+
if (child.stdin.writable)
|
|
18713
|
+
child.stdin.end();
|
|
18714
|
+
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
18715
|
+
return;
|
|
18716
|
+
signalProcessTree(child, "SIGTERM");
|
|
18717
|
+
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
18718
|
+
return;
|
|
18719
|
+
signalProcessTree(child, "SIGKILL");
|
|
18720
|
+
if (!await waitForExit(child, this.#options.closeTimeoutMs)) {
|
|
18721
|
+
throw new Error("Omp RPC process tree did not exit within cleanup bounds");
|
|
18722
|
+
}
|
|
18772
18723
|
}
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18724
|
+
#push(chunk) {
|
|
18725
|
+
this.#buffer = this.#buffer.length === 0 ? chunk : Buffer.concat([this.#buffer, chunk]);
|
|
18726
|
+
let newline = this.#buffer.indexOf(10);
|
|
18727
|
+
while (newline >= 0) {
|
|
18728
|
+
const frame = this.#buffer.subarray(0, newline);
|
|
18729
|
+
this.#buffer = this.#buffer.subarray(newline + 1);
|
|
18730
|
+
let parsed;
|
|
18731
|
+
try {
|
|
18732
|
+
parsed = JSON.parse(textDecoder.decode(frame));
|
|
18733
|
+
} catch (error51) {
|
|
18734
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC returned invalid JSONL: ${message2(error51)}`));
|
|
18735
|
+
newline = this.#buffer.indexOf(10);
|
|
18736
|
+
continue;
|
|
18737
|
+
}
|
|
18738
|
+
try {
|
|
18739
|
+
const decoded = this.#frameDecoder.push(parsed);
|
|
18740
|
+
if (decoded === null) {
|
|
18741
|
+
newline = this.#buffer.indexOf(10);
|
|
18742
|
+
continue;
|
|
18743
|
+
}
|
|
18744
|
+
const value = decoded;
|
|
18745
|
+
if (!isRecord8(value) || typeof value.type !== "string") {
|
|
18746
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid envelope");
|
|
18747
|
+
}
|
|
18748
|
+
this.#handle(value);
|
|
18749
|
+
} catch (error51) {
|
|
18750
|
+
this.#fail(error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC frame handling failed: ${message2(error51)}`));
|
|
18751
|
+
}
|
|
18752
|
+
newline = this.#buffer.indexOf(10);
|
|
18753
|
+
}
|
|
18785
18754
|
}
|
|
18786
|
-
|
|
18787
|
-
|
|
18755
|
+
/** Latest `available_commands_update` of the running process, if any. */
|
|
18756
|
+
get availableCommands() {
|
|
18757
|
+
return this.#availableCommands;
|
|
18788
18758
|
}
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
|
|
18795
|
-
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {},
|
|
18796
|
-
...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {}
|
|
18797
|
-
});
|
|
18798
|
-
const sessionArguments = options.forkSessionFile ? ["--fork", options.forkSessionFile] : options.sessionFile ? ["--resume", options.sessionFile] : [];
|
|
18799
|
-
const modelArguments = options.model ? ["--provider", options.model.provider, "--model", options.model.id] : [];
|
|
18800
|
-
const permissionArguments = options.permissionMode ? ["--approval-mode", options.permissionMode] : [];
|
|
18801
|
-
const arguments_ = [
|
|
18802
|
-
"--mode",
|
|
18803
|
-
// OMP only creates ask and connects its tool UI in rpc-ui mode.
|
|
18804
|
-
"rpc-ui",
|
|
18805
|
-
...permissionArguments,
|
|
18806
|
-
...modelArguments,
|
|
18807
|
-
...sessionArguments
|
|
18808
|
-
];
|
|
18809
|
-
const extension = path6.win32.extname(command).toLowerCase();
|
|
18810
|
-
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
18811
|
-
return { command, arguments: arguments_, windowsVerbatimArguments: false };
|
|
18812
|
-
}
|
|
18813
|
-
const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
|
|
18814
|
-
const commandLine = [command, ...arguments_].map(quote).join(" ");
|
|
18815
|
-
return {
|
|
18816
|
-
command: options.environment?.ComSpec ?? options.environment?.COMSPEC ?? "cmd.exe",
|
|
18817
|
-
arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
|
|
18818
|
-
windowsVerbatimArguments: true
|
|
18819
|
-
};
|
|
18820
|
-
}
|
|
18821
|
-
var nodeProcessAdapter = {
|
|
18822
|
-
spawn(options) {
|
|
18823
|
-
const invocation = ompRpcProcessCommand(options);
|
|
18824
|
-
return spawn(invocation.command, invocation.arguments, {
|
|
18825
|
-
cwd: options.cwd,
|
|
18826
|
-
env: options.environment,
|
|
18827
|
-
detached: process.platform !== "win32",
|
|
18828
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
18829
|
-
windowsHide: true,
|
|
18830
|
-
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
18831
|
-
});
|
|
18832
|
-
}
|
|
18833
|
-
};
|
|
18834
|
-
var OmpRpcSession = class {
|
|
18835
|
-
#options;
|
|
18836
|
-
#processAdapter;
|
|
18837
|
-
#activeTurn = null;
|
|
18838
|
-
#buffer = Buffer.alloc(0);
|
|
18839
|
-
#child = null;
|
|
18840
|
-
#closed = false;
|
|
18841
|
-
#closePromise = null;
|
|
18842
|
-
#compactionActive = false;
|
|
18843
|
-
#compactionTurn = null;
|
|
18844
|
-
#compactionTimeout = null;
|
|
18845
|
-
#failed = false;
|
|
18846
|
-
#pending = /* @__PURE__ */ new Map();
|
|
18847
|
-
#state = null;
|
|
18848
|
-
#availableCommands = null;
|
|
18849
|
-
#latestCacheHitRatePercent;
|
|
18850
|
-
#manualCompaction = null;
|
|
18851
|
-
#usageRequestStartedAtMs = null;
|
|
18852
|
-
#stderrTail = "";
|
|
18853
|
-
#frameDecoder = new OmpFrameDecoder();
|
|
18854
|
-
#startupFaultResolve = null;
|
|
18855
|
-
#startupFault = new Promise((resolve) => {
|
|
18856
|
-
this.#startupFaultResolve = resolve;
|
|
18857
|
-
});
|
|
18858
|
-
#readyResolve = null;
|
|
18859
|
-
#ready = new Promise((resolve) => {
|
|
18860
|
-
this.#readyResolve = resolve;
|
|
18861
|
-
});
|
|
18862
|
-
constructor(options, processAdapter = nodeProcessAdapter) {
|
|
18863
|
-
if (options.sessionFile && options.forkSessionFile) {
|
|
18864
|
-
throw new Error("Omp RPC cannot combine Session resume and Fork startup");
|
|
18759
|
+
#handle(value) {
|
|
18760
|
+
if (this.#closed || this.#failed)
|
|
18761
|
+
return;
|
|
18762
|
+
if (value.type === "available_commands_update") {
|
|
18763
|
+
this.#availableCommands = parseOmpAvailableCommands(value.commands);
|
|
18764
|
+
return;
|
|
18865
18765
|
}
|
|
18866
|
-
if (
|
|
18867
|
-
|
|
18766
|
+
if (value.type === "ready") {
|
|
18767
|
+
this.#readyResolve?.();
|
|
18768
|
+
this.#readyResolve = null;
|
|
18769
|
+
return;
|
|
18868
18770
|
}
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
|
|
18872
|
-
|
|
18873
|
-
|
|
18874
|
-
|
|
18875
|
-
|
|
18876
|
-
|
|
18877
|
-
|
|
18878
|
-
|
|
18879
|
-
|
|
18880
|
-
|
|
18881
|
-
|
|
18882
|
-
|
|
18883
|
-
|
|
18884
|
-
|
|
18885
|
-
|
|
18886
|
-
|
|
18887
|
-
}
|
|
18888
|
-
async start() {
|
|
18889
|
-
if (this.#child || this.#closed)
|
|
18890
|
-
throw new Error("Omp RPC Session cannot be started twice");
|
|
18891
|
-
const child = this.#processAdapter.spawn({
|
|
18892
|
-
cwd: this.#options.cwd,
|
|
18893
|
-
...this.#options.command ? { command: this.#options.command } : {},
|
|
18894
|
-
environment: withNodeRuntimeOnPath({
|
|
18895
|
-
...process.env,
|
|
18896
|
-
...this.#options.environment,
|
|
18897
|
-
OMP_SKIP_VERSION_CHECK: "1",
|
|
18898
|
-
OMP_TELEMETRY: "0"
|
|
18899
|
-
}),
|
|
18900
|
-
...this.#options.sessionFile ? { sessionFile: this.#options.sessionFile } : {},
|
|
18901
|
-
...this.#options.forkSessionFile ? { forkSessionFile: this.#options.forkSessionFile } : {},
|
|
18902
|
-
...this.#options.model ? { model: this.#options.model } : {},
|
|
18903
|
-
...this.#options.permissionMode ? { permissionMode: this.#options.permissionMode } : {}
|
|
18904
|
-
});
|
|
18905
|
-
this.#child = child;
|
|
18906
|
-
child.stdout.on("data", (chunk) => this.#push(chunk));
|
|
18907
|
-
child.stdout.on("end", () => {
|
|
18908
|
-
if (this.#buffer.length !== 0) {
|
|
18909
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC stdout ended mid-frame"));
|
|
18771
|
+
if (value.type === "response") {
|
|
18772
|
+
this.#handleResponse(value);
|
|
18773
|
+
return;
|
|
18774
|
+
}
|
|
18775
|
+
if (value.type === "auto_compaction_start" || value.type === "compaction_start") {
|
|
18776
|
+
this.#compactionActive = true;
|
|
18777
|
+
this.#compactionTurn = this.#activeTurn;
|
|
18778
|
+
this.#compactionTimeout ??= setTimeout(() => {
|
|
18779
|
+
this.#compactionTimeout = null;
|
|
18780
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC compaction timed out after ${this.#options.compactionTimeoutMs}ms`));
|
|
18781
|
+
}, this.#options.compactionTimeoutMs);
|
|
18782
|
+
const onEvent = this.#activeTurn?.onEvent ?? this.#manualCompaction?.onEvent;
|
|
18783
|
+
onEvent?.({ type: "compaction.started" });
|
|
18784
|
+
for (const pending of this.#pending.values()) {
|
|
18785
|
+
if (pending.command !== "prompt" && pending.command !== "compact" || !pending.timeout)
|
|
18786
|
+
continue;
|
|
18787
|
+
clearTimeout(pending.timeout);
|
|
18788
|
+
pending.timeout = null;
|
|
18910
18789
|
}
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
this.#
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18790
|
+
return;
|
|
18791
|
+
}
|
|
18792
|
+
if (value.type === "auto_compaction_end" || value.type === "compaction_end") {
|
|
18793
|
+
this.#compactionActive = false;
|
|
18794
|
+
if (this.#compactionTimeout)
|
|
18795
|
+
clearTimeout(this.#compactionTimeout);
|
|
18796
|
+
this.#compactionTimeout = null;
|
|
18797
|
+
const compactionTurn = this.#compactionTurn;
|
|
18798
|
+
this.#compactionTurn = null;
|
|
18799
|
+
for (const [id, pending] of this.#pending) {
|
|
18800
|
+
if (pending.command === "prompt" || pending.command === "compact") {
|
|
18801
|
+
this.#armCommandTimeout(id, pending);
|
|
18802
|
+
}
|
|
18922
18803
|
}
|
|
18923
|
-
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
|
|
18928
|
-
}
|
|
18929
|
-
|
|
18930
|
-
|
|
18931
|
-
|
|
18932
|
-
|
|
18933
|
-
|
|
18934
|
-
|
|
18935
|
-
|
|
18936
|
-
|
|
18937
|
-
|
|
18938
|
-
new Promise((_resolve, reject) => {
|
|
18939
|
-
readyTimeout = setTimeout(() => reject(new Error("Omp RPC ready signal timed out")), this.#options.commandTimeoutMs);
|
|
18940
|
-
})
|
|
18941
|
-
]);
|
|
18942
|
-
} finally {
|
|
18943
|
-
clearTimeout(readyTimeout);
|
|
18804
|
+
const outcome = value.aborted === true ? "cancelled" : isRecord8(value.result) ? "succeeded" : "failed";
|
|
18805
|
+
const event = {
|
|
18806
|
+
type: "compaction.completed",
|
|
18807
|
+
outcome,
|
|
18808
|
+
...nonBlankString(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
|
|
18809
|
+
};
|
|
18810
|
+
compactionTurn?.onEvent(event);
|
|
18811
|
+
const manual = this.#manualCompaction;
|
|
18812
|
+
this.#manualCompaction = null;
|
|
18813
|
+
manual?.onEvent(event);
|
|
18814
|
+
manual?.resolve({
|
|
18815
|
+
outcome,
|
|
18816
|
+
...event.errorMessage ? { errorMessage: event.errorMessage } : {}
|
|
18817
|
+
});
|
|
18818
|
+
return;
|
|
18944
18819
|
}
|
|
18945
|
-
|
|
18946
|
-
if (this.#
|
|
18947
|
-
|
|
18820
|
+
const active = this.#activeTurn;
|
|
18821
|
+
if (this.#handleSubagentFrame(active, value))
|
|
18822
|
+
return;
|
|
18823
|
+
this.#observeUsage(value);
|
|
18824
|
+
if (value.type === "agent_start" && active)
|
|
18825
|
+
active.terminalEnd = false;
|
|
18826
|
+
if ((value.type === "session_settled" || value.type === "agent_start") && active?.cancellation === "accepted") {
|
|
18827
|
+
void this.#confirmCancelledTurn(active);
|
|
18828
|
+
return;
|
|
18829
|
+
}
|
|
18830
|
+
if (!active) {
|
|
18831
|
+
if (value.type === "extension_ui_request" && this.#isBlockingInteraction(value)) {
|
|
18832
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC requested blocking Extension UI outside an active Turn"));
|
|
18833
|
+
}
|
|
18834
|
+
return;
|
|
18835
|
+
}
|
|
18836
|
+
if (value.type === "command_output") {
|
|
18837
|
+
if (active.settlement !== "pending")
|
|
18838
|
+
return;
|
|
18839
|
+
if (typeof value.text !== "string") {
|
|
18840
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned invalid command output");
|
|
18841
|
+
}
|
|
18842
|
+
active.text += value.text;
|
|
18843
|
+
active.onEvent({ type: "text.delta", messageId: active.promptId, delta: value.text });
|
|
18844
|
+
return;
|
|
18845
|
+
}
|
|
18846
|
+
if (value.type === "prompt_result") {
|
|
18847
|
+
if (value.id !== active.promptId || value.agentInvoked !== false)
|
|
18848
|
+
return;
|
|
18849
|
+
if (value.status === "completed" || value.status === "aborted") {
|
|
18850
|
+
this.#settleLocalTurn(active, { cancelled: value.status === "aborted" });
|
|
18851
|
+
} else if (value.status === "error" && isRecord8(value.error) && typeof value.error.message === "string") {
|
|
18852
|
+
this.#settleLocalTurn(active, { cancelled: false, error: value.error.message });
|
|
18853
|
+
} else {
|
|
18854
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid local prompt result");
|
|
18855
|
+
}
|
|
18856
|
+
return;
|
|
18857
|
+
}
|
|
18858
|
+
if (value.type === "extension_ui_request") {
|
|
18859
|
+
this.#startInteraction(active, value);
|
|
18860
|
+
return;
|
|
18861
|
+
}
|
|
18862
|
+
if (value.type === "message_start" && assistantText(value.message) !== null) {
|
|
18863
|
+
this.#startAssistantMessage(active, value.message);
|
|
18864
|
+
return;
|
|
18865
|
+
}
|
|
18866
|
+
if (value.type === "message_update" && isRecord8(value.assistantMessageEvent)) {
|
|
18867
|
+
const event = value.assistantMessageEvent;
|
|
18868
|
+
const eventType = String(event.type ?? "");
|
|
18869
|
+
const isThinking = eventType === "thinking_delta" || eventType === "reasoning_delta" || eventType === "thought_delta" || eventType === "thinking" || eventType === "reasoning";
|
|
18870
|
+
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
18871
|
+
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 : isRecord8(event.delta) && typeof event.delta.thinking === "string" ? event.delta.thinking : isRecord8(event.delta) && typeof event.delta.text === "string" ? event.delta.text : null;
|
|
18872
|
+
if (isThinking && delta !== null && delta.length > 0) {
|
|
18873
|
+
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18874
|
+
active.reasoningMessageOpen = true;
|
|
18875
|
+
active.sawStreamedMessageReasoning = true;
|
|
18876
|
+
active.onEvent({ type: "reasoning.delta", messageId, delta });
|
|
18877
|
+
} else if (isText && delta !== null && delta.length > 0) {
|
|
18878
|
+
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18879
|
+
active.text += delta;
|
|
18880
|
+
active.sawStreamedMessageText = true;
|
|
18881
|
+
active.onEvent({ type: "text.delta", messageId, delta });
|
|
18882
|
+
} else if (event.type === "error") {
|
|
18883
|
+
this.#ensureAssistantMessage(active, value.message);
|
|
18884
|
+
active.failure = assistantFailure(event.error) ?? assistantFailure(value.message) ?? new Error("Omp assistant message failed");
|
|
18885
|
+
}
|
|
18886
|
+
return;
|
|
18887
|
+
}
|
|
18888
|
+
if (value.type === "message_end") {
|
|
18889
|
+
this.#finalizeAssistantMessage(active, value.message);
|
|
18890
|
+
return;
|
|
18891
|
+
}
|
|
18892
|
+
if (value.type === "turn_end") {
|
|
18893
|
+
this.#finalizeAssistantMessage(active, value.message);
|
|
18894
|
+
return;
|
|
18895
|
+
}
|
|
18896
|
+
if (value.type === "tool_execution_start") {
|
|
18897
|
+
this.#startTool(active, value);
|
|
18898
|
+
return;
|
|
18899
|
+
}
|
|
18900
|
+
if (value.type === "tool_execution_update") {
|
|
18901
|
+
this.#updateTool(active, value);
|
|
18902
|
+
return;
|
|
18903
|
+
}
|
|
18904
|
+
if (value.type === "tool_execution_end") {
|
|
18905
|
+
this.#completeTool(active, value);
|
|
18906
|
+
return;
|
|
18907
|
+
}
|
|
18908
|
+
if (value.type === "agent_end" && Array.isArray(value.messages)) {
|
|
18909
|
+
for (let index = value.messages.length - 1; index >= 0; index -= 1) {
|
|
18910
|
+
const message3 = value.messages[index];
|
|
18911
|
+
if (!isRecord8(message3) || message3.role !== "assistant")
|
|
18912
|
+
continue;
|
|
18913
|
+
this.#finalizeAssistantMessage(active, message3);
|
|
18914
|
+
break;
|
|
18915
|
+
}
|
|
18916
|
+
}
|
|
18917
|
+
if (value.type === "agent_end" && value.isTerminal !== false) {
|
|
18918
|
+
active.terminalEnd = true;
|
|
18919
|
+
if (active.cancellation !== "none") {
|
|
18920
|
+
if (active.cancellation === "accepted")
|
|
18921
|
+
void this.#confirmCancelledTurn(active);
|
|
18922
|
+
return;
|
|
18923
|
+
}
|
|
18924
|
+
if (active.settlement !== "pending")
|
|
18925
|
+
return;
|
|
18926
|
+
active.settlement = "confirming";
|
|
18927
|
+
void this.#confirmSettledTurn(active);
|
|
18928
|
+
}
|
|
18929
|
+
}
|
|
18930
|
+
/** Every finished assistant message is one model request, with or without an active Turn. */
|
|
18931
|
+
#observeUsage(value) {
|
|
18932
|
+
if (value.type === "message_start") {
|
|
18933
|
+
this.#usageRequestStartedAtMs = null;
|
|
18934
|
+
return;
|
|
18935
|
+
}
|
|
18936
|
+
if (value.type === "message_update") {
|
|
18937
|
+
const event = value.assistantMessageEvent;
|
|
18938
|
+
if (this.#usageRequestStartedAtMs === null && isRecord8(event) && typeof event.type === "string" && /^(text|thinking|reasoning|thought|toolcall)_(start|delta)$/u.test(event.type)) {
|
|
18939
|
+
this.#usageRequestStartedAtMs = Date.now();
|
|
18940
|
+
}
|
|
18941
|
+
return;
|
|
18948
18942
|
}
|
|
18949
|
-
|
|
18950
|
-
|
|
18951
|
-
|
|
18952
|
-
const
|
|
18953
|
-
this.#
|
|
18954
|
-
|
|
18943
|
+
if (value.type === "message_end" && isRecord8(value.message)) {
|
|
18944
|
+
if (value.message.role !== "assistant")
|
|
18945
|
+
return;
|
|
18946
|
+
const startedAtMs = this.#usageRequestStartedAtMs;
|
|
18947
|
+
this.#usageRequestStartedAtMs = null;
|
|
18948
|
+
this.#options.onUsage?.({
|
|
18949
|
+
message: value.message,
|
|
18950
|
+
startedAtMs,
|
|
18951
|
+
completedAtMs: Date.now()
|
|
18952
|
+
});
|
|
18955
18953
|
}
|
|
18956
|
-
return this;
|
|
18957
18954
|
}
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18955
|
+
#handleSubagentFrame(active, value) {
|
|
18956
|
+
if (value.type !== "subagent_lifecycle" && value.type !== "subagent_progress" && value.type !== "subagent_event") {
|
|
18957
|
+
return false;
|
|
18958
|
+
}
|
|
18959
|
+
const payload = isRecord8(value.payload) ? value.payload : null;
|
|
18960
|
+
const progressPayload = value.type === "subagent_progress" && payload && isRecord8(payload.progress) ? payload.progress : null;
|
|
18961
|
+
const nativeIdValue = progressPayload?.id ?? payload?.id;
|
|
18962
|
+
if (!payload || !nonBlankString(nativeIdValue)) {
|
|
18963
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent frame has no stable ID");
|
|
18964
|
+
}
|
|
18965
|
+
const nativeSubagentId = nativeIdValue;
|
|
18966
|
+
const callId = nativeSubagentId;
|
|
18967
|
+
const emit = active?.onEvent ?? this.#options.onSubagentEvent;
|
|
18968
|
+
if (value.type === "subagent_event") {
|
|
18969
|
+
emit?.({ type: "subagent.transcript.changed", callId, nativeSubagentId });
|
|
18970
|
+
return true;
|
|
18971
|
+
}
|
|
18972
|
+
if (value.type === "subagent_lifecycle") {
|
|
18973
|
+
const status2 = payload.status;
|
|
18974
|
+
if (status2 === "started") {
|
|
18975
|
+
const description = nonBlankString(payload.description) ? payload.description : nonBlankString(payload.agent) ? `${payload.agent} delegation` : "Subagent delegation";
|
|
18976
|
+
emit?.({
|
|
18977
|
+
type: "subagent.started",
|
|
18978
|
+
callId,
|
|
18979
|
+
nativeSubagentId,
|
|
18980
|
+
description,
|
|
18981
|
+
...nonBlankString(payload.agent) ? { role: payload.agent } : {},
|
|
18982
|
+
...nonBlankString(payload.task) ? { prompt: payload.task } : {},
|
|
18983
|
+
background: payload.detached === true,
|
|
18984
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
18985
|
+
});
|
|
18986
|
+
return true;
|
|
18978
18987
|
}
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
const branchResponse = await this.#send("get_branch_messages", {});
|
|
18982
|
-
const branchData = isRecord8(branchResponse.data) ? branchResponse.data : null;
|
|
18983
|
-
if (branchData && Array.isArray(branchData.messages)) {
|
|
18984
|
-
const parsed = branchData.messages.flatMap((entry) => {
|
|
18985
|
-
if (!isRecord8(entry) || !nonBlankString(entry.entryId))
|
|
18986
|
-
return [];
|
|
18987
|
-
return [entry.entryId];
|
|
18988
|
-
});
|
|
18989
|
-
if (parsed.length === branchData.messages.length)
|
|
18990
|
-
branchEntryIds = parsed;
|
|
18991
|
-
}
|
|
18992
|
-
} catch (error51) {
|
|
18993
|
-
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18994
|
-
throw error51;
|
|
18988
|
+
if (status2 !== "completed" && status2 !== "failed" && status2 !== "aborted") {
|
|
18989
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent lifecycle status is invalid");
|
|
18995
18990
|
}
|
|
18996
|
-
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
19000
|
-
|
|
19001
|
-
|
|
19002
|
-
|
|
19003
|
-
const id = branchId ?? (isRecord8(nativeMessage) && nonBlankString(nativeMessage.id) ? nativeMessage.id : `omp-message-${index}`);
|
|
19004
|
-
const entry = { id, parentId, type: "message", message: nativeMessage };
|
|
19005
|
-
parentId = id;
|
|
19006
|
-
return entry;
|
|
18991
|
+
emit?.({
|
|
18992
|
+
type: "subagent.completed",
|
|
18993
|
+
callId,
|
|
18994
|
+
nativeSubagentId,
|
|
18995
|
+
isError: status2 !== "completed",
|
|
18996
|
+
...nonBlankString(payload.resultSummary) ? { resultSummary: payload.resultSummary } : {},
|
|
18997
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19007
18998
|
});
|
|
19008
|
-
return
|
|
19009
|
-
} catch (error51) {
|
|
19010
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
19011
|
-
this.#fail(error51);
|
|
19012
|
-
throw error51;
|
|
19013
|
-
}
|
|
19014
|
-
}
|
|
19015
|
-
async getSubagentMessages(input) {
|
|
19016
|
-
if ((input.subagentId === void 0 || !nonBlankString(input.subagentId)) && (input.sessionFile === void 0 || !nonBlankString(input.sessionFile))) {
|
|
19017
|
-
throw new Error("Omp Subagent transcript requires a Subagent ID or Session file");
|
|
18999
|
+
return true;
|
|
19018
19000
|
}
|
|
19019
|
-
|
|
19020
|
-
|
|
19001
|
+
const progress = progressPayload;
|
|
19002
|
+
if (!progress || !nonBlankString(progress.id) || progress.id !== nativeSubagentId) {
|
|
19003
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent progress is invalid");
|
|
19021
19004
|
}
|
|
19022
|
-
const
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19005
|
+
const status = subagentStatus(progress.status);
|
|
19006
|
+
const recentOutput = Array.isArray(progress.recentOutput) ? progress.recentOutput.filter((item) => typeof item === "string") : [];
|
|
19007
|
+
const resultSummary = recentOutput.at(-1);
|
|
19008
|
+
emit?.({
|
|
19009
|
+
type: "subagent.updated",
|
|
19010
|
+
callId,
|
|
19011
|
+
nativeSubagentId,
|
|
19012
|
+
status,
|
|
19013
|
+
...nonBlankString(progress.description) ? { description: progress.description } : nonBlankString(payload.task) ? { description: payload.task } : {},
|
|
19014
|
+
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
19015
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19026
19016
|
});
|
|
19027
|
-
return
|
|
19017
|
+
return true;
|
|
19028
19018
|
}
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19019
|
+
#isBlockingInteraction(value) {
|
|
19020
|
+
return ["select", "confirm", "input", "editor"].includes(String(value.method));
|
|
19021
|
+
}
|
|
19022
|
+
#startInteraction(active, value) {
|
|
19023
|
+
if (!this.#isBlockingInteraction(value))
|
|
19024
|
+
return;
|
|
19025
|
+
const requestId2 = value.id;
|
|
19026
|
+
const method = value.method;
|
|
19027
|
+
const title = value.title;
|
|
19028
|
+
const timeoutMs = value.timeout;
|
|
19029
|
+
if (typeof requestId2 !== "string" || requestId2.length === 0 || typeof method !== "string" || typeof title !== "string" || title.length === 0 || timeoutMs !== void 0 && (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs < 0) || active.interactions.has(requestId2)) {
|
|
19030
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Interaction request");
|
|
19032
19031
|
}
|
|
19033
|
-
|
|
19034
|
-
|
|
19032
|
+
let request;
|
|
19033
|
+
if (method === "select") {
|
|
19034
|
+
if (!Array.isArray(value.options) || value.options.length === 0 || !value.options.every((option) => typeof option === "string" && option.length > 0)) {
|
|
19035
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC select request has invalid options");
|
|
19036
|
+
}
|
|
19037
|
+
let optionDetails;
|
|
19038
|
+
if (value.optionDetails !== void 0) {
|
|
19039
|
+
if (!Array.isArray(value.optionDetails) || value.optionDetails.length !== value.options.length || !value.optionDetails.every((detail) => typeof detail === "object" && detail !== null && !Array.isArray(detail) && (detail.description === void 0 || typeof detail.description === "string"))) {
|
|
19040
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC select option details are invalid");
|
|
19041
|
+
}
|
|
19042
|
+
optionDetails = value.optionDetails.map(({ description }) => description === void 0 ? {} : { description });
|
|
19043
|
+
}
|
|
19044
|
+
request = {
|
|
19045
|
+
requestId: requestId2,
|
|
19046
|
+
method,
|
|
19047
|
+
title,
|
|
19048
|
+
options: [...value.options],
|
|
19049
|
+
...optionDetails ? { optionDetails } : {},
|
|
19050
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19051
|
+
};
|
|
19052
|
+
} else if (method === "confirm") {
|
|
19053
|
+
if (typeof value.message !== "string") {
|
|
19054
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC confirm request has no message");
|
|
19055
|
+
}
|
|
19056
|
+
request = {
|
|
19057
|
+
requestId: requestId2,
|
|
19058
|
+
method,
|
|
19059
|
+
title,
|
|
19060
|
+
message: value.message,
|
|
19061
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19062
|
+
};
|
|
19063
|
+
} else if (method === "input") {
|
|
19064
|
+
if (value.placeholder !== void 0 && typeof value.placeholder !== "string") {
|
|
19065
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC input placeholder is invalid");
|
|
19066
|
+
}
|
|
19067
|
+
request = {
|
|
19068
|
+
requestId: requestId2,
|
|
19069
|
+
method,
|
|
19070
|
+
title,
|
|
19071
|
+
...typeof value.placeholder === "string" ? { placeholder: value.placeholder } : {},
|
|
19072
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19073
|
+
};
|
|
19074
|
+
} else {
|
|
19075
|
+
if (value.prefill !== void 0 && typeof value.prefill !== "string") {
|
|
19076
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC editor prefill is invalid");
|
|
19077
|
+
}
|
|
19078
|
+
request = {
|
|
19079
|
+
requestId: requestId2,
|
|
19080
|
+
method: "editor",
|
|
19081
|
+
title,
|
|
19082
|
+
...typeof value.prefill === "string" ? { prefill: value.prefill } : {},
|
|
19083
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19084
|
+
};
|
|
19035
19085
|
}
|
|
19036
|
-
const
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19086
|
+
const pending = { request, timeout: null };
|
|
19087
|
+
if (request.timeoutMs !== void 0) {
|
|
19088
|
+
pending.timeout = setTimeout(() => {
|
|
19089
|
+
if (this.#activeTurn !== active || !active.interactions.has(requestId2))
|
|
19090
|
+
return;
|
|
19091
|
+
void this.#resolveInteraction({ requestId: requestId2, cancelled: true }, "expired").catch((error51) => {
|
|
19092
|
+
if (this.#closed || this.#failed)
|
|
19093
|
+
return;
|
|
19094
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC Interaction timeout handling failed: ${message2(error51)}`));
|
|
19095
|
+
});
|
|
19096
|
+
}, request.timeoutMs);
|
|
19045
19097
|
}
|
|
19046
|
-
|
|
19098
|
+
active.interactions.set(requestId2, pending);
|
|
19099
|
+
active.onEvent({ type: "interaction.requested", request });
|
|
19047
19100
|
}
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
return
|
|
19053
|
-
} catch (error51) {
|
|
19054
|
-
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
19055
|
-
throw error51;
|
|
19056
|
-
const response = await this.#send("get_state", {});
|
|
19057
|
-
const observedState = parseSessionState(response);
|
|
19058
|
-
if (!this.#state || observedState.sessionId !== this.#state.sessionId || observedState.provider !== this.#state.provider || observedState.modelId !== this.#state.modelId) {
|
|
19059
|
-
throw new Error("Omp RPC Usage fallback does not match the confirmed Session state");
|
|
19060
|
-
}
|
|
19061
|
-
await this.#ensureLatestCacheHitRate();
|
|
19062
|
-
const usage = parseOmpStateContextUsage(response);
|
|
19063
|
-
return usage ? this.#withLatestCacheHitRate(usage) : null;
|
|
19101
|
+
#handleResponse(value) {
|
|
19102
|
+
const id = value.id;
|
|
19103
|
+
if (typeof id !== "string") {
|
|
19104
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response has no id"));
|
|
19105
|
+
return;
|
|
19064
19106
|
}
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
if (
|
|
19107
|
+
const pending = this.#pending.get(id);
|
|
19108
|
+
const active = this.#activeTurn;
|
|
19109
|
+
if (!pending) {
|
|
19110
|
+
if (active?.promptId === id && value.command === "prompt" && value.success === false) {
|
|
19111
|
+
active.failure = new Error(typeof value.error === "string" ? value.error : "Omp RPC command failed");
|
|
19112
|
+
return;
|
|
19113
|
+
}
|
|
19114
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response id is not pending"));
|
|
19068
19115
|
return;
|
|
19069
|
-
try {
|
|
19070
|
-
this.#latestCacheHitRatePercent = latestOmpCacheHitRatePercent(await this.getEntries());
|
|
19071
|
-
} catch {
|
|
19072
|
-
this.#latestCacheHitRatePercent = null;
|
|
19073
19116
|
}
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
const
|
|
19084
|
-
if (
|
|
19085
|
-
|
|
19117
|
+
if (pending.timeout)
|
|
19118
|
+
clearTimeout(pending.timeout);
|
|
19119
|
+
this.#pending.delete(id);
|
|
19120
|
+
if (value.success === true) {
|
|
19121
|
+
if (pending.command === "prompt" && active?.promptId === id && isRecord8(value.data) && value.data.agentInvoked === false) {
|
|
19122
|
+
this.#settleLocalTurn(active, { cancelled: false });
|
|
19123
|
+
}
|
|
19124
|
+
pending.resolve(value);
|
|
19125
|
+
} else {
|
|
19126
|
+
const error51 = typeof value.error === "string" ? value.error : "Omp RPC command failed";
|
|
19127
|
+
if (value.command === pending.command && error51 === `Unknown command: ${pending.command}`) {
|
|
19128
|
+
pending.reject(new OmpRpcUnsupportedCommandError(pending.command));
|
|
19129
|
+
} else {
|
|
19130
|
+
pending.reject(new Error(error51));
|
|
19086
19131
|
}
|
|
19087
|
-
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
19088
|
-
return this.#state;
|
|
19089
|
-
} catch (error51) {
|
|
19090
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
19091
|
-
this.#fail(error51);
|
|
19092
|
-
throw error51;
|
|
19093
19132
|
}
|
|
19094
19133
|
}
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
|
|
19099
|
-
|
|
19134
|
+
#startTool(active, value) {
|
|
19135
|
+
const callId = value.toolCallId;
|
|
19136
|
+
const toolName = value.toolName;
|
|
19137
|
+
const argumentsResult = jsonValueSchema.safeParse(value.args);
|
|
19138
|
+
if (typeof callId !== "string" || callId.length === 0 || typeof toolName !== "string" || toolName.length === 0 || !argumentsResult.success || active.tools.has(callId)) {
|
|
19139
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool start");
|
|
19140
|
+
}
|
|
19141
|
+
active.sawTool = true;
|
|
19142
|
+
active.tools.set(callId, toolName);
|
|
19143
|
+
active.onEvent({
|
|
19144
|
+
type: "tool.started",
|
|
19145
|
+
callId,
|
|
19146
|
+
toolName,
|
|
19147
|
+
arguments: argumentsResult.data
|
|
19100
19148
|
});
|
|
19101
19149
|
}
|
|
19102
|
-
|
|
19103
|
-
|
|
19104
|
-
|
|
19105
|
-
|
|
19106
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
19107
|
-
this.#fail(error51);
|
|
19108
|
-
throw error51;
|
|
19150
|
+
#updateTool(active, value) {
|
|
19151
|
+
const callId = value.toolCallId;
|
|
19152
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
19153
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19109
19154
|
}
|
|
19110
|
-
|
|
19111
|
-
|
|
19112
|
-
|
|
19113
|
-
|
|
19114
|
-
|
|
19115
|
-
await this.#send("set_model", { provider: model2.provider, modelId: model2.id });
|
|
19116
|
-
return this.#refreshState("Model");
|
|
19117
|
-
}
|
|
19118
|
-
async selectThinkingOption(thinkingOptionId) {
|
|
19119
|
-
const level = harnessThinkingOptionIdSchema.parse(thinkingOptionId);
|
|
19120
|
-
await this.#send("set_thinking_level", { level });
|
|
19121
|
-
return this.#refreshState("Thinking");
|
|
19122
|
-
}
|
|
19123
|
-
async #refreshState(operation) {
|
|
19124
|
-
try {
|
|
19125
|
-
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
19126
|
-
return this.#state;
|
|
19127
|
-
} catch (error51) {
|
|
19128
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
19129
|
-
this.#fail(fault);
|
|
19130
|
-
throw fault;
|
|
19155
|
+
if (!active.tools.has(callId))
|
|
19156
|
+
return;
|
|
19157
|
+
const outputResult = jsonValueSchema.safeParse(value.partialResult ?? null);
|
|
19158
|
+
if (!outputResult.success) {
|
|
19159
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19131
19160
|
}
|
|
19161
|
+
active.onEvent({ type: "tool.updated", callId, output: outputResult.data });
|
|
19132
19162
|
}
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19163
|
+
#completeTool(active, value) {
|
|
19164
|
+
const callId = value.toolCallId;
|
|
19165
|
+
const toolName = value.toolName;
|
|
19166
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
19167
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19136
19168
|
}
|
|
19137
|
-
|
|
19138
|
-
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
this.#activeTurn = {
|
|
19144
|
-
promptId,
|
|
19145
|
-
localResult: null,
|
|
19146
|
-
text: "",
|
|
19147
|
-
assistantMessageId: null,
|
|
19148
|
-
sawStreamedMessageText: false,
|
|
19149
|
-
sawStreamedMessageReasoning: false,
|
|
19150
|
-
lastFinalizedMessageText: null,
|
|
19151
|
-
lastFinalizedMessageReasoning: null,
|
|
19152
|
-
reasoningMessageOpen: false,
|
|
19153
|
-
onEvent,
|
|
19154
|
-
resolve,
|
|
19155
|
-
reject,
|
|
19156
|
-
failure: null,
|
|
19157
|
-
sawTool: false,
|
|
19158
|
-
tools: /* @__PURE__ */ new Map(),
|
|
19159
|
-
interactions: /* @__PURE__ */ new Map(),
|
|
19160
|
-
settlement: "pending",
|
|
19161
|
-
terminalEnd: false,
|
|
19162
|
-
cancellation: "none",
|
|
19163
|
-
cancellationTimeout: null,
|
|
19164
|
-
cancellationRecheck: null,
|
|
19165
|
-
cancellationChecking: false,
|
|
19166
|
-
cancellationReloaded: false,
|
|
19167
|
-
abortPromise: null
|
|
19168
|
-
};
|
|
19169
|
-
});
|
|
19170
|
-
try {
|
|
19171
|
-
await this.#send("prompt", { message: text }, promptId);
|
|
19172
|
-
} catch (error51) {
|
|
19173
|
-
this.#rejectActiveTurn(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
19169
|
+
const expectedName = active.tools.get(callId);
|
|
19170
|
+
if (expectedName === void 0)
|
|
19171
|
+
return;
|
|
19172
|
+
const result = jsonValueSchema.safeParse(value.result);
|
|
19173
|
+
if (typeof toolName !== "string" || expectedName !== toolName || value.isError !== void 0 && typeof value.isError !== "boolean" || !result.success) {
|
|
19174
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19174
19175
|
}
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
19176
|
+
active.tools.delete(callId);
|
|
19177
|
+
active.onEvent({
|
|
19178
|
+
type: "tool.completed",
|
|
19179
|
+
callId,
|
|
19180
|
+
toolName,
|
|
19181
|
+
result: result.data,
|
|
19182
|
+
isError: value.isError === true
|
|
19183
|
+
});
|
|
19179
19184
|
}
|
|
19180
|
-
async #
|
|
19181
|
-
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
|
|
19185
|
-
|
|
19186
|
-
|
|
19187
|
-
throw new Error("Omp RPC interaction response type does not match the request");
|
|
19188
|
-
}
|
|
19189
|
-
if ("confirmed" in response && pending.request.method !== "confirm") {
|
|
19190
|
-
throw new Error("Omp RPC confirmation does not match the request");
|
|
19191
|
-
}
|
|
19192
|
-
const frame = "cancelled" in response ? {
|
|
19193
|
-
type: "extension_ui_response",
|
|
19194
|
-
id: response.requestId,
|
|
19195
|
-
cancelled: true,
|
|
19196
|
-
...reason === "expired" ? { timedOut: true } : {}
|
|
19197
|
-
} : "confirmed" in response ? { type: "extension_ui_response", id: response.requestId, confirmed: response.confirmed } : { type: "extension_ui_response", id: response.requestId, value: response.value };
|
|
19198
|
-
if (!active.interactions.delete(response.requestId)) {
|
|
19199
|
-
throw new Error("Omp RPC interaction is not pending");
|
|
19200
|
-
}
|
|
19201
|
-
if (pending.timeout)
|
|
19202
|
-
clearTimeout(pending.timeout);
|
|
19203
|
-
active.onEvent({ type: "interaction.closed", requestId: response.requestId, reason });
|
|
19185
|
+
async #confirmCancelledTurn(active) {
|
|
19186
|
+
if (this.#activeTurn !== active || active.cancellation !== "accepted" || active.settlement === "confirming" || active.cancellationChecking)
|
|
19187
|
+
return;
|
|
19188
|
+
active.cancellationChecking = true;
|
|
19189
|
+
if (active.cancellationRecheck)
|
|
19190
|
+
clearTimeout(active.cancellationRecheck);
|
|
19191
|
+
active.cancellationRecheck = null;
|
|
19204
19192
|
try {
|
|
19205
|
-
await this.#
|
|
19193
|
+
let response = await this.#send("get_state", {});
|
|
19194
|
+
if (this.#activeTurn !== active)
|
|
19195
|
+
return;
|
|
19196
|
+
if (parseSessionStreaming(response)) {
|
|
19197
|
+
await this.#send("abort", {});
|
|
19198
|
+
if (this.#activeTurn !== active)
|
|
19199
|
+
return;
|
|
19200
|
+
response = await this.#send("get_state", {});
|
|
19201
|
+
}
|
|
19202
|
+
let state = parseSessionState(response);
|
|
19203
|
+
if (this.#activeTurn !== active || active.cancellation !== "accepted")
|
|
19204
|
+
return;
|
|
19205
|
+
const data = sessionStateData(response);
|
|
19206
|
+
if (!active.cancellationReloaded && state.sessionFile && state.sessionId === this.state.sessionId && state.sessionFile === this.state.sessionFile && data.isStreaming === false && data.isCompacting === false && data.queuedMessageCount === 0 && data.hasPendingAsyncWork === true && active.tools.size === 0) {
|
|
19207
|
+
await this.verifySessionCwd(this.#options.cwd);
|
|
19208
|
+
if (this.#activeTurn !== active)
|
|
19209
|
+
return;
|
|
19210
|
+
active.cancellationReloaded = true;
|
|
19211
|
+
const reset = await this.#send("new_session", {});
|
|
19212
|
+
if (this.#activeTurn !== active)
|
|
19213
|
+
return;
|
|
19214
|
+
if (!isRecord8(reset.data) || reset.data.cancelled !== false) {
|
|
19215
|
+
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reset was refused");
|
|
19216
|
+
}
|
|
19217
|
+
const reloaded = await this.#send("switch_session", { sessionPath: state.sessionFile });
|
|
19218
|
+
if (this.#activeTurn !== active)
|
|
19219
|
+
return;
|
|
19220
|
+
if (!isRecord8(reloaded.data) || reloaded.data.cancelled !== false) {
|
|
19221
|
+
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reload was refused");
|
|
19222
|
+
}
|
|
19223
|
+
const previous = state;
|
|
19224
|
+
response = await this.#send("get_state", {});
|
|
19225
|
+
state = parseSessionState(response);
|
|
19226
|
+
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile) {
|
|
19227
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity");
|
|
19228
|
+
}
|
|
19229
|
+
if (state.provider !== previous.provider || state.modelId !== previous.modelId) {
|
|
19230
|
+
if (!previous.provider || !previous.modelId) {
|
|
19231
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session has no restorable Model");
|
|
19232
|
+
}
|
|
19233
|
+
await this.#send("set_model", { provider: previous.provider, modelId: previous.modelId });
|
|
19234
|
+
}
|
|
19235
|
+
if (previous.thinkingLevel && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19236
|
+
await this.#send("set_thinking_level", { level: previous.thinkingLevel });
|
|
19237
|
+
}
|
|
19238
|
+
response = await this.#send("get_state", {});
|
|
19239
|
+
state = parseSessionState(response);
|
|
19240
|
+
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile || state.provider !== previous.provider || state.modelId !== previous.modelId || previous.thinkingLevel !== null && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19241
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity or configuration");
|
|
19242
|
+
}
|
|
19243
|
+
}
|
|
19244
|
+
if (!cancellationSettled(response, active.terminalEnd)) {
|
|
19245
|
+
active.settlement = "pending";
|
|
19246
|
+
active.cancellationRecheck = setTimeout(() => {
|
|
19247
|
+
active.cancellationRecheck = null;
|
|
19248
|
+
void this.#confirmCancelledTurn(active);
|
|
19249
|
+
}, 250);
|
|
19250
|
+
return;
|
|
19251
|
+
}
|
|
19252
|
+
this.#state = state;
|
|
19253
|
+
active.settlement = "confirmed";
|
|
19254
|
+
this.#finishSettledTurn(active);
|
|
19206
19255
|
} catch (error51) {
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19256
|
+
if (this.#activeTurn !== active)
|
|
19257
|
+
return;
|
|
19258
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC cancelled Turn state could not be confirmed: ${message2(error51)}`);
|
|
19259
|
+
this.#terminateFailedCancellation(active, fault);
|
|
19260
|
+
} finally {
|
|
19261
|
+
active.cancellationChecking = false;
|
|
19210
19262
|
}
|
|
19211
19263
|
}
|
|
19212
|
-
|
|
19213
|
-
|
|
19214
|
-
|
|
19215
|
-
|
|
19216
|
-
|
|
19217
|
-
|
|
19218
|
-
|
|
19219
|
-
|
|
19220
|
-
|
|
19221
|
-
this.#
|
|
19222
|
-
|
|
19223
|
-
const aborting = this.#send("abort", {}).then(async () => {
|
|
19264
|
+
#settleLocalTurn(active, result) {
|
|
19265
|
+
if (this.#activeTurn !== active || active.settlement !== "pending")
|
|
19266
|
+
return;
|
|
19267
|
+
active.localResult = result;
|
|
19268
|
+
active.settlement = "confirming";
|
|
19269
|
+
void this.#confirmSettledTurn(active);
|
|
19270
|
+
}
|
|
19271
|
+
async #confirmSettledTurn(active) {
|
|
19272
|
+
try {
|
|
19273
|
+
const response = await this.#send("get_state", {});
|
|
19274
|
+
const state = parseSessionState(response);
|
|
19224
19275
|
if (this.#activeTurn !== active)
|
|
19225
19276
|
return;
|
|
19226
|
-
active.cancellation
|
|
19227
|
-
|
|
19228
|
-
|
|
19277
|
+
if (active.cancellation !== "none") {
|
|
19278
|
+
active.settlement = "pending";
|
|
19279
|
+
if (active.cancellation === "accepted")
|
|
19280
|
+
void this.#confirmCancelledTurn(active);
|
|
19281
|
+
return;
|
|
19282
|
+
}
|
|
19283
|
+
if (parseSessionStreaming(response)) {
|
|
19284
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC completed Turn state is still Streaming");
|
|
19285
|
+
}
|
|
19286
|
+
this.#state = state;
|
|
19287
|
+
active.settlement = "confirmed";
|
|
19288
|
+
this.#finishSettledTurn(active);
|
|
19289
|
+
} catch (error51) {
|
|
19229
19290
|
if (this.#activeTurn !== active)
|
|
19230
|
-
|
|
19231
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC
|
|
19232
|
-
this.#
|
|
19233
|
-
|
|
19234
|
-
});
|
|
19235
|
-
active.abortPromise = aborting;
|
|
19236
|
-
return aborting;
|
|
19291
|
+
return;
|
|
19292
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC stable Turn state could not be confirmed: ${message2(error51)}`);
|
|
19293
|
+
this.#fail(fault);
|
|
19294
|
+
}
|
|
19237
19295
|
}
|
|
19238
|
-
#
|
|
19239
|
-
if (this.#activeTurn !== active)
|
|
19296
|
+
#finishSettledTurn(active) {
|
|
19297
|
+
if (this.#activeTurn !== active || active.settlement !== "confirmed" || active.cancellation === "requesting") {
|
|
19240
19298
|
return;
|
|
19299
|
+
}
|
|
19241
19300
|
if (active.cancellationTimeout)
|
|
19242
19301
|
clearTimeout(active.cancellationTimeout);
|
|
19243
19302
|
active.cancellationTimeout = null;
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
if (
|
|
19249
|
-
this.#
|
|
19250
|
-
this.#rejectAll(new Error("Omp RPC Session closed"));
|
|
19251
|
-
}
|
|
19252
|
-
this.#closePromise ??= this.#stopProcess();
|
|
19253
|
-
return this.#closePromise;
|
|
19254
|
-
}
|
|
19255
|
-
async #stopProcess() {
|
|
19256
|
-
const child = this.#child;
|
|
19257
|
-
if (!child)
|
|
19258
|
-
return;
|
|
19259
|
-
if (child.stdin.writable)
|
|
19260
|
-
child.stdin.end();
|
|
19261
|
-
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
19262
|
-
return;
|
|
19263
|
-
signalProcessTree(child, "SIGTERM");
|
|
19264
|
-
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
19303
|
+
if (active.cancellationRecheck)
|
|
19304
|
+
clearTimeout(active.cancellationRecheck);
|
|
19305
|
+
active.cancellationRecheck = null;
|
|
19306
|
+
this.#closeInteractions(active, active.cancellation === "accepted" ? "cancelled" : "superseded");
|
|
19307
|
+
if (active.tools.size > 0) {
|
|
19308
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC settled with active Tool executions"));
|
|
19265
19309
|
return;
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19310
|
+
}
|
|
19311
|
+
this.#activeTurn = null;
|
|
19312
|
+
if (active.localResult) {
|
|
19313
|
+
active.resolve({
|
|
19314
|
+
text: active.text,
|
|
19315
|
+
agentInvoked: false,
|
|
19316
|
+
...active.localResult,
|
|
19317
|
+
cancelled: active.localResult.cancelled || active.cancellation === "accepted"
|
|
19318
|
+
});
|
|
19319
|
+
} else if (active.cancellation === "accepted") {
|
|
19320
|
+
active.resolve({ text: active.text, cancelled: true, agentInvoked: true });
|
|
19321
|
+
} else if (active.failure) {
|
|
19322
|
+
active.reject(active.failure);
|
|
19323
|
+
} else if (active.text.trim().length === 0 && !active.sawTool) {
|
|
19324
|
+
active.reject(new Error("Omp RPC settled without displayable output"));
|
|
19325
|
+
} else {
|
|
19326
|
+
active.resolve({ text: active.text, cancelled: false, agentInvoked: true });
|
|
19269
19327
|
}
|
|
19270
19328
|
}
|
|
19271
|
-
#
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
while (newline >= 0) {
|
|
19275
|
-
const frame = this.#buffer.subarray(0, newline);
|
|
19276
|
-
this.#buffer = this.#buffer.subarray(newline + 1);
|
|
19277
|
-
let parsed;
|
|
19278
|
-
try {
|
|
19279
|
-
parsed = JSON.parse(textDecoder.decode(frame));
|
|
19280
|
-
} catch (error51) {
|
|
19281
|
-
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC returned invalid JSONL: ${message2(error51)}`));
|
|
19282
|
-
newline = this.#buffer.indexOf(10);
|
|
19283
|
-
continue;
|
|
19284
|
-
}
|
|
19285
|
-
try {
|
|
19286
|
-
const decoded = this.#frameDecoder.push(parsed);
|
|
19287
|
-
if (decoded === null) {
|
|
19288
|
-
newline = this.#buffer.indexOf(10);
|
|
19289
|
-
continue;
|
|
19290
|
-
}
|
|
19291
|
-
const value = decoded;
|
|
19292
|
-
if (!isRecord8(value) || typeof value.type !== "string") {
|
|
19293
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid envelope");
|
|
19294
|
-
}
|
|
19295
|
-
this.#handle(value);
|
|
19296
|
-
} catch (error51) {
|
|
19297
|
-
this.#fail(error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC frame handling failed: ${message2(error51)}`));
|
|
19298
|
-
}
|
|
19299
|
-
newline = this.#buffer.indexOf(10);
|
|
19329
|
+
#startAssistantMessage(active, value) {
|
|
19330
|
+
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19331
|
+
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19300
19332
|
}
|
|
19333
|
+
const messageId = assistantMessageId(value) ?? randomUUID();
|
|
19334
|
+
active.assistantMessageId = messageId;
|
|
19335
|
+
active.sawStreamedMessageText = false;
|
|
19336
|
+
active.sawStreamedMessageReasoning = false;
|
|
19337
|
+
active.reasoningMessageOpen = false;
|
|
19338
|
+
return messageId;
|
|
19301
19339
|
}
|
|
19302
|
-
|
|
19303
|
-
|
|
19304
|
-
return this.#availableCommands;
|
|
19340
|
+
#ensureAssistantMessage(active, value) {
|
|
19341
|
+
return active.assistantMessageId ?? this.#startAssistantMessage(active, value);
|
|
19305
19342
|
}
|
|
19306
|
-
#
|
|
19307
|
-
|
|
19343
|
+
#finalizeAssistantMessage(active, value) {
|
|
19344
|
+
const finalText = assistantText(value);
|
|
19345
|
+
const finalReasoning = assistantReasoning(value);
|
|
19346
|
+
const failure = assistantFailure(value);
|
|
19347
|
+
const cacheHitRatePercent = optionalOmpCacheHitRatePercent(value);
|
|
19348
|
+
if (finalText === null || finalReasoning === null || failure === void 0)
|
|
19308
19349
|
return;
|
|
19309
|
-
if (
|
|
19310
|
-
this.#availableCommands = parseOmpAvailableCommands(value.commands);
|
|
19350
|
+
if (active.assistantMessageId === null && finalText === active.lastFinalizedMessageText && finalReasoning === active.lastFinalizedMessageReasoning && !active.sawStreamedMessageText && !active.sawStreamedMessageReasoning) {
|
|
19311
19351
|
return;
|
|
19312
19352
|
}
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19353
|
+
active.failure = failure;
|
|
19354
|
+
this.#latestCacheHitRatePercent = cacheHitRatePercent;
|
|
19355
|
+
const messageId = this.#ensureAssistantMessage(active, value);
|
|
19356
|
+
if (!active.sawStreamedMessageReasoning && finalReasoning.length > 0) {
|
|
19357
|
+
active.reasoningMessageOpen = true;
|
|
19358
|
+
active.onEvent({ type: "reasoning.delta", messageId, delta: finalReasoning });
|
|
19317
19359
|
}
|
|
19318
|
-
if (
|
|
19319
|
-
|
|
19320
|
-
return;
|
|
19360
|
+
if (active.reasoningMessageOpen && active.failure === null) {
|
|
19361
|
+
active.onEvent({ type: "reasoning.completed", messageId });
|
|
19321
19362
|
}
|
|
19322
|
-
if (
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
this.#compactionTimeout ??= setTimeout(() => {
|
|
19326
|
-
this.#compactionTimeout = null;
|
|
19327
|
-
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC compaction timed out after ${this.#options.compactionTimeoutMs}ms`));
|
|
19328
|
-
}, this.#options.compactionTimeoutMs);
|
|
19329
|
-
const onEvent = this.#activeTurn?.onEvent ?? this.#manualCompaction?.onEvent;
|
|
19330
|
-
onEvent?.({ type: "compaction.started" });
|
|
19331
|
-
for (const pending of this.#pending.values()) {
|
|
19332
|
-
if (pending.command !== "prompt" && pending.command !== "compact" || !pending.timeout)
|
|
19333
|
-
continue;
|
|
19334
|
-
clearTimeout(pending.timeout);
|
|
19335
|
-
pending.timeout = null;
|
|
19336
|
-
}
|
|
19337
|
-
return;
|
|
19363
|
+
if (!active.sawStreamedMessageText && finalText.length > 0) {
|
|
19364
|
+
active.text += finalText;
|
|
19365
|
+
active.onEvent({ type: "text.delta", messageId, delta: finalText });
|
|
19338
19366
|
}
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19350
|
-
|
|
19351
|
-
const outcome = value.aborted === true ? "cancelled" : isRecord8(value.result) ? "succeeded" : "failed";
|
|
19352
|
-
const event = {
|
|
19353
|
-
type: "compaction.completed",
|
|
19354
|
-
outcome,
|
|
19355
|
-
...nonBlankString(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
|
|
19356
|
-
};
|
|
19357
|
-
compactionTurn?.onEvent(event);
|
|
19358
|
-
const manual = this.#manualCompaction;
|
|
19359
|
-
this.#manualCompaction = null;
|
|
19360
|
-
manual?.onEvent(event);
|
|
19361
|
-
manual?.resolve({
|
|
19362
|
-
outcome,
|
|
19363
|
-
...event.errorMessage ? { errorMessage: event.errorMessage } : {}
|
|
19364
|
-
});
|
|
19365
|
-
return;
|
|
19367
|
+
active.assistantMessageId = null;
|
|
19368
|
+
active.sawStreamedMessageText = false;
|
|
19369
|
+
active.sawStreamedMessageReasoning = false;
|
|
19370
|
+
active.reasoningMessageOpen = false;
|
|
19371
|
+
active.lastFinalizedMessageText = finalText;
|
|
19372
|
+
active.lastFinalizedMessageReasoning = finalReasoning;
|
|
19373
|
+
active.onEvent({ type: "message.completed", messageId });
|
|
19374
|
+
}
|
|
19375
|
+
#write(value) {
|
|
19376
|
+
const child = this.#child;
|
|
19377
|
+
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19378
|
+
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
19366
19379
|
}
|
|
19367
|
-
|
|
19368
|
-
|
|
19369
|
-
|
|
19370
|
-
|
|
19371
|
-
|
|
19372
|
-
|
|
19373
|
-
|
|
19374
|
-
|
|
19375
|
-
|
|
19380
|
+
return new Promise((resolve, reject) => {
|
|
19381
|
+
const frame = Buffer.from(`${JSON.stringify(value)}
|
|
19382
|
+
`, "utf8");
|
|
19383
|
+
child.stdin.write(frame, (error51) => error51 ? reject(error51) : resolve());
|
|
19384
|
+
});
|
|
19385
|
+
}
|
|
19386
|
+
#send(type, payload, id = `codexhost-${randomUUID()}`) {
|
|
19387
|
+
const child = this.#child;
|
|
19388
|
+
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19389
|
+
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
19376
19390
|
}
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19391
|
+
return new Promise((resolve, reject) => {
|
|
19392
|
+
const pending = {
|
|
19393
|
+
command: type,
|
|
19394
|
+
resolve,
|
|
19395
|
+
reject,
|
|
19396
|
+
timeout: null
|
|
19397
|
+
};
|
|
19398
|
+
this.#pending.set(id, pending);
|
|
19399
|
+
this.#armCommandTimeout(id, pending);
|
|
19400
|
+
const frame = Buffer.from(`${JSON.stringify({ id, type, ...payload })}
|
|
19401
|
+
`, "utf8");
|
|
19402
|
+
child.stdin.write(frame, (error51) => {
|
|
19403
|
+
if (error51) {
|
|
19404
|
+
if (pending.timeout)
|
|
19405
|
+
clearTimeout(pending.timeout);
|
|
19406
|
+
this.#pending.delete(id);
|
|
19407
|
+
reject(error51);
|
|
19408
|
+
}
|
|
19409
|
+
});
|
|
19410
|
+
});
|
|
19411
|
+
}
|
|
19412
|
+
#armCommandTimeout(id, pending) {
|
|
19413
|
+
if (pending.timeout || this.#pending.get(id) !== pending || (pending.command === "prompt" || pending.command === "compact") && this.#compactionActive) {
|
|
19381
19414
|
return;
|
|
19382
19415
|
}
|
|
19383
|
-
|
|
19384
|
-
if (
|
|
19416
|
+
pending.timeout = setTimeout(() => {
|
|
19417
|
+
if (this.#pending.get(id) !== pending)
|
|
19385
19418
|
return;
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
|
|
19391
|
-
return;
|
|
19392
|
-
}
|
|
19393
|
-
if (value.type === "prompt_result") {
|
|
19394
|
-
if (value.id !== active.promptId || value.agentInvoked !== false)
|
|
19419
|
+
pending.timeout = null;
|
|
19420
|
+
const error51 = new Error(`Omp RPC '${pending.command}' command timed out`);
|
|
19421
|
+
if (pending.command !== "prompt") {
|
|
19422
|
+
this.#pending.delete(id);
|
|
19423
|
+
pending.reject(error51);
|
|
19395
19424
|
return;
|
|
19396
|
-
if (value.status === "completed" || value.status === "aborted") {
|
|
19397
|
-
this.#settleLocalTurn(active, { cancelled: value.status === "aborted" });
|
|
19398
|
-
} else if (value.status === "error" && isRecord8(value.error) && typeof value.error.message === "string") {
|
|
19399
|
-
this.#settleLocalTurn(active, { cancelled: false, error: value.error.message });
|
|
19400
|
-
} else {
|
|
19401
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid local prompt result");
|
|
19402
19425
|
}
|
|
19426
|
+
const fault = new OmpRpcFaultError("protocolError", error51.message);
|
|
19427
|
+
void this.#terminateTimedOutPrompt(fault);
|
|
19428
|
+
}, this.#options.commandTimeoutMs);
|
|
19429
|
+
}
|
|
19430
|
+
async #terminateTimedOutPrompt(fault) {
|
|
19431
|
+
if (this.#closed || this.#failed)
|
|
19403
19432
|
return;
|
|
19433
|
+
this.#failed = true;
|
|
19434
|
+
this.#closed = true;
|
|
19435
|
+
for (const pending of this.#pending.values()) {
|
|
19436
|
+
if (pending.timeout)
|
|
19437
|
+
clearTimeout(pending.timeout);
|
|
19438
|
+
pending.timeout = null;
|
|
19404
19439
|
}
|
|
19405
|
-
|
|
19406
|
-
|
|
19407
|
-
|
|
19408
|
-
}
|
|
19409
|
-
|
|
19410
|
-
this.#startAssistantMessage(active, value.message);
|
|
19411
|
-
return;
|
|
19440
|
+
let finalFault = fault;
|
|
19441
|
+
try {
|
|
19442
|
+
await this.close();
|
|
19443
|
+
} catch (error51) {
|
|
19444
|
+
finalFault = new OmpRpcFaultError("processExited", `Omp RPC timed-out Prompt cleanup failed: ${message2(error51)}`);
|
|
19412
19445
|
}
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
if (
|
|
19420
|
-
|
|
19421
|
-
|
|
19422
|
-
active.sawStreamedMessageReasoning = true;
|
|
19423
|
-
active.onEvent({ type: "reasoning.delta", messageId, delta });
|
|
19424
|
-
} else if (isText && delta !== null && delta.length > 0) {
|
|
19425
|
-
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
19426
|
-
active.text += delta;
|
|
19427
|
-
active.sawStreamedMessageText = true;
|
|
19428
|
-
active.onEvent({ type: "text.delta", messageId, delta });
|
|
19429
|
-
} else if (event.type === "error") {
|
|
19430
|
-
this.#ensureAssistantMessage(active, value.message);
|
|
19431
|
-
active.failure = assistantFailure(event.error) ?? assistantFailure(value.message) ?? new Error("Omp assistant message failed");
|
|
19432
|
-
}
|
|
19433
|
-
return;
|
|
19446
|
+
this.#rejectAll(finalFault);
|
|
19447
|
+
this.#options.onFault?.(finalFault);
|
|
19448
|
+
}
|
|
19449
|
+
#closeInteractions(active, reason) {
|
|
19450
|
+
for (const [requestId2, pending] of active.interactions) {
|
|
19451
|
+
active.interactions.delete(requestId2);
|
|
19452
|
+
if (pending.timeout)
|
|
19453
|
+
clearTimeout(pending.timeout);
|
|
19454
|
+
active.onEvent({ type: "interaction.closed", requestId: requestId2, reason });
|
|
19434
19455
|
}
|
|
19435
|
-
|
|
19436
|
-
|
|
19456
|
+
}
|
|
19457
|
+
#rejectActiveTurn(error51) {
|
|
19458
|
+
const active = this.#activeTurn;
|
|
19459
|
+
if (!active)
|
|
19437
19460
|
return;
|
|
19461
|
+
if (active.cancellationTimeout)
|
|
19462
|
+
clearTimeout(active.cancellationTimeout);
|
|
19463
|
+
if (active.cancellationRecheck)
|
|
19464
|
+
clearTimeout(active.cancellationRecheck);
|
|
19465
|
+
this.#closeInteractions(active, "cancelled");
|
|
19466
|
+
this.#activeTurn = null;
|
|
19467
|
+
active.reject(error51);
|
|
19468
|
+
}
|
|
19469
|
+
#rejectAll(error51) {
|
|
19470
|
+
if (this.#compactionTimeout)
|
|
19471
|
+
clearTimeout(this.#compactionTimeout);
|
|
19472
|
+
this.#compactionTimeout = null;
|
|
19473
|
+
for (const pending of this.#pending.values()) {
|
|
19474
|
+
if (pending.timeout)
|
|
19475
|
+
clearTimeout(pending.timeout);
|
|
19476
|
+
pending.reject(error51);
|
|
19438
19477
|
}
|
|
19439
|
-
|
|
19440
|
-
|
|
19478
|
+
this.#pending.clear();
|
|
19479
|
+
const manual = this.#manualCompaction;
|
|
19480
|
+
this.#manualCompaction = null;
|
|
19481
|
+
manual?.reject(error51);
|
|
19482
|
+
this.#rejectActiveTurn(error51);
|
|
19483
|
+
}
|
|
19484
|
+
#fail(error51) {
|
|
19485
|
+
if (this.#closed || this.#failed)
|
|
19441
19486
|
return;
|
|
19487
|
+
this.#failed = true;
|
|
19488
|
+
this.#startupFaultResolve?.(error51);
|
|
19489
|
+
this.#startupFaultResolve = null;
|
|
19490
|
+
this.#rejectAll(error51);
|
|
19491
|
+
this.#options.onFault?.(error51);
|
|
19492
|
+
}
|
|
19493
|
+
};
|
|
19494
|
+
|
|
19495
|
+
// dist/omp-model-list.js
|
|
19496
|
+
var OMP_MODEL_LIST_TIMEOUT_MS = 15e3;
|
|
19497
|
+
var OMP_MODEL_LIST_OUTPUT_LIMIT = 4 * 1024 * 1024;
|
|
19498
|
+
function listOmpModels(input) {
|
|
19499
|
+
const environment = withNodeRuntimeOnPath({
|
|
19500
|
+
...process.env,
|
|
19501
|
+
...input.environment,
|
|
19502
|
+
OMP_SKIP_VERSION_CHECK: "1",
|
|
19503
|
+
OMP_TELEMETRY: "0"
|
|
19504
|
+
});
|
|
19505
|
+
const executable = resolveOmpExecutable({
|
|
19506
|
+
...input.command ? { command: input.command } : {},
|
|
19507
|
+
environment
|
|
19508
|
+
});
|
|
19509
|
+
const invocation = commandInvocation(executable, ["models", "--json"], environment);
|
|
19510
|
+
return new Promise((resolve) => {
|
|
19511
|
+
if (input.signal?.aborted)
|
|
19512
|
+
return resolve({ kind: "unanswered" });
|
|
19513
|
+
const child = spawn2(invocation.command, invocation.arguments, {
|
|
19514
|
+
cwd: input.cwd,
|
|
19515
|
+
env: environment,
|
|
19516
|
+
// A process group lets a stop reach OMP and its descendants, not only a launcher shim.
|
|
19517
|
+
detached: process.platform !== "win32",
|
|
19518
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
19519
|
+
windowsHide: true,
|
|
19520
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
19521
|
+
});
|
|
19522
|
+
let settled = false;
|
|
19523
|
+
let stdout = "";
|
|
19524
|
+
const finish = (result, stop = false) => {
|
|
19525
|
+
if (settled)
|
|
19526
|
+
return;
|
|
19527
|
+
settled = true;
|
|
19528
|
+
clearTimeout(timer);
|
|
19529
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
19530
|
+
child.stdout.removeAllListeners("data");
|
|
19531
|
+
if (stop) {
|
|
19532
|
+
child.stdout.destroy();
|
|
19533
|
+
try {
|
|
19534
|
+
signalProcessTree(child, "SIGKILL");
|
|
19535
|
+
} catch {
|
|
19536
|
+
}
|
|
19537
|
+
}
|
|
19538
|
+
resolve(result);
|
|
19539
|
+
};
|
|
19540
|
+
const onAbort = () => finish({ kind: "unanswered" }, true);
|
|
19541
|
+
input.signal?.addEventListener("abort", onAbort, { once: true });
|
|
19542
|
+
const timer = setTimeout(() => finish({ kind: "timedOut" }, true), input.timeoutMs ?? OMP_MODEL_LIST_TIMEOUT_MS);
|
|
19543
|
+
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
19544
|
+
stdout += chunk;
|
|
19545
|
+
if (stdout.length > OMP_MODEL_LIST_OUTPUT_LIMIT)
|
|
19546
|
+
finish({ kind: "unanswered" }, true);
|
|
19547
|
+
});
|
|
19548
|
+
child.once("error", (error51) => {
|
|
19549
|
+
finish(error51.code === "ENOENT" ? { kind: "notInstalled", message: "Oh My Pi (omp) is not installed" } : { kind: "unanswered" });
|
|
19550
|
+
});
|
|
19551
|
+
child.once("close", (code) => {
|
|
19552
|
+
if (code !== 0)
|
|
19553
|
+
return finish({ kind: "unanswered" });
|
|
19554
|
+
const models = parseOmpModelList(stdout);
|
|
19555
|
+
finish(models ? { kind: "models", models } : { kind: "unanswered" });
|
|
19556
|
+
});
|
|
19557
|
+
});
|
|
19558
|
+
}
|
|
19559
|
+
function parseOmpModelList(output) {
|
|
19560
|
+
let parsed;
|
|
19561
|
+
try {
|
|
19562
|
+
parsed = JSON.parse(output);
|
|
19563
|
+
} catch {
|
|
19564
|
+
return null;
|
|
19565
|
+
}
|
|
19566
|
+
if (!isRecord9(parsed) || !Array.isArray(parsed.models))
|
|
19567
|
+
return null;
|
|
19568
|
+
const models = [];
|
|
19569
|
+
for (const model2 of parsed.models) {
|
|
19570
|
+
if (!isRecord9(model2) || !nonBlankString2(model2.provider) || !nonBlankString2(model2.id) || typeof model2.reasoning !== "boolean") {
|
|
19571
|
+
return null;
|
|
19442
19572
|
}
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
|
|
19573
|
+
models.push({ provider: model2.provider, id: model2.id, reasoning: model2.reasoning });
|
|
19574
|
+
}
|
|
19575
|
+
return models;
|
|
19576
|
+
}
|
|
19577
|
+
function isRecord9(value) {
|
|
19578
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19579
|
+
}
|
|
19580
|
+
function nonBlankString2(value) {
|
|
19581
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
19582
|
+
}
|
|
19583
|
+
|
|
19584
|
+
// ../../../node_modules/diff/libesm/diff/base.js
|
|
19585
|
+
var Diff = class {
|
|
19586
|
+
diff(oldStr, newStr, options = {}) {
|
|
19587
|
+
let callback;
|
|
19588
|
+
if (typeof options === "function") {
|
|
19589
|
+
callback = options;
|
|
19590
|
+
options = {};
|
|
19591
|
+
} else if ("callback" in options) {
|
|
19592
|
+
callback = options.callback;
|
|
19446
19593
|
}
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19594
|
+
const oldString = this.castInput(oldStr, options);
|
|
19595
|
+
const newString = this.castInput(newStr, options);
|
|
19596
|
+
const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
|
|
19597
|
+
const newTokens = this.removeEmpty(this.tokenize(newString, options));
|
|
19598
|
+
return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
|
|
19599
|
+
}
|
|
19600
|
+
diffWithOptionsObj(oldTokens, newTokens, options, callback) {
|
|
19601
|
+
var _a3;
|
|
19602
|
+
const done = (value) => {
|
|
19603
|
+
value = this.postProcess(value, options);
|
|
19604
|
+
if (callback) {
|
|
19605
|
+
setTimeout(function() {
|
|
19606
|
+
callback(value);
|
|
19607
|
+
}, 0);
|
|
19608
|
+
return void 0;
|
|
19609
|
+
} else {
|
|
19610
|
+
return value;
|
|
19611
|
+
}
|
|
19612
|
+
};
|
|
19613
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
19614
|
+
let editLength = 1;
|
|
19615
|
+
let maxEditLength = newLen + oldLen;
|
|
19616
|
+
if (options.maxEditLength != null) {
|
|
19617
|
+
maxEditLength = Math.min(maxEditLength, options.maxEditLength);
|
|
19450
19618
|
}
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
|
|
19619
|
+
const maxExecutionTime = (_a3 = options.timeout) !== null && _a3 !== void 0 ? _a3 : Infinity;
|
|
19620
|
+
const abortAfterTimestamp = Date.now() + maxExecutionTime;
|
|
19621
|
+
const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
|
|
19622
|
+
let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
|
|
19623
|
+
if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
19624
|
+
return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
|
|
19454
19625
|
}
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19626
|
+
let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
|
|
19627
|
+
const execEditLength = () => {
|
|
19628
|
+
for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
|
|
19629
|
+
let basePath;
|
|
19630
|
+
const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
|
|
19631
|
+
if (removePath) {
|
|
19632
|
+
bestPath[diagonalPath - 1] = void 0;
|
|
19633
|
+
}
|
|
19634
|
+
let canAdd = false;
|
|
19635
|
+
if (addPath) {
|
|
19636
|
+
const addPathNewPos = addPath.oldPos - diagonalPath;
|
|
19637
|
+
canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
|
|
19638
|
+
}
|
|
19639
|
+
const canRemove = removePath && removePath.oldPos + 1 < oldLen;
|
|
19640
|
+
if (!canAdd && !canRemove) {
|
|
19641
|
+
bestPath[diagonalPath] = void 0;
|
|
19459
19642
|
continue;
|
|
19460
|
-
|
|
19461
|
-
|
|
19643
|
+
}
|
|
19644
|
+
if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
|
|
19645
|
+
basePath = this.addToPath(addPath, true, false, 0, options);
|
|
19646
|
+
} else {
|
|
19647
|
+
basePath = this.addToPath(removePath, false, true, 1, options);
|
|
19648
|
+
}
|
|
19649
|
+
newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
|
|
19650
|
+
if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
19651
|
+
return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
|
|
19652
|
+
} else {
|
|
19653
|
+
bestPath[diagonalPath] = basePath;
|
|
19654
|
+
if (basePath.oldPos + 1 >= oldLen) {
|
|
19655
|
+
maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
|
|
19656
|
+
}
|
|
19657
|
+
if (newPos + 1 >= newLen) {
|
|
19658
|
+
minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
|
|
19659
|
+
}
|
|
19660
|
+
}
|
|
19462
19661
|
}
|
|
19463
|
-
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
|
|
19469
|
-
|
|
19662
|
+
editLength++;
|
|
19663
|
+
};
|
|
19664
|
+
if (callback) {
|
|
19665
|
+
(function exec() {
|
|
19666
|
+
setTimeout(function() {
|
|
19667
|
+
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
19668
|
+
return callback(void 0);
|
|
19669
|
+
}
|
|
19670
|
+
if (!execEditLength()) {
|
|
19671
|
+
exec();
|
|
19672
|
+
}
|
|
19673
|
+
}, 0);
|
|
19674
|
+
})();
|
|
19675
|
+
} else {
|
|
19676
|
+
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
19677
|
+
const ret = execEditLength();
|
|
19678
|
+
if (ret) {
|
|
19679
|
+
return ret;
|
|
19680
|
+
}
|
|
19470
19681
|
}
|
|
19471
|
-
if (active.settlement !== "pending")
|
|
19472
|
-
return;
|
|
19473
|
-
active.settlement = "confirming";
|
|
19474
|
-
void this.#confirmSettledTurn(active);
|
|
19475
19682
|
}
|
|
19476
19683
|
}
|
|
19477
|
-
|
|
19478
|
-
|
|
19479
|
-
if (
|
|
19480
|
-
|
|
19481
|
-
|
|
19684
|
+
addToPath(path9, added, removed, oldPosInc, options) {
|
|
19685
|
+
const last = path9.lastComponent;
|
|
19686
|
+
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
19687
|
+
return {
|
|
19688
|
+
oldPos: path9.oldPos + oldPosInc,
|
|
19689
|
+
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
19690
|
+
};
|
|
19691
|
+
} else {
|
|
19692
|
+
return {
|
|
19693
|
+
oldPos: path9.oldPos + oldPosInc,
|
|
19694
|
+
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
19695
|
+
};
|
|
19482
19696
|
}
|
|
19483
|
-
|
|
19484
|
-
|
|
19485
|
-
|
|
19486
|
-
|
|
19697
|
+
}
|
|
19698
|
+
extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
|
|
19699
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
19700
|
+
let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
|
|
19701
|
+
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
|
|
19702
|
+
newPos++;
|
|
19703
|
+
oldPos++;
|
|
19704
|
+
commonCount++;
|
|
19705
|
+
if (options.oneChangePerToken) {
|
|
19706
|
+
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
19487
19707
|
}
|
|
19488
|
-
return;
|
|
19489
19708
|
}
|
|
19490
|
-
if (
|
|
19491
|
-
|
|
19492
|
-
return;
|
|
19493
|
-
const startedAtMs = this.#usageRequestStartedAtMs;
|
|
19494
|
-
this.#usageRequestStartedAtMs = null;
|
|
19495
|
-
this.#options.onUsage?.({
|
|
19496
|
-
message: value.message,
|
|
19497
|
-
startedAtMs,
|
|
19498
|
-
completedAtMs: Date.now()
|
|
19499
|
-
});
|
|
19709
|
+
if (commonCount && !options.oneChangePerToken) {
|
|
19710
|
+
basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
19500
19711
|
}
|
|
19712
|
+
basePath.oldPos = oldPos;
|
|
19713
|
+
return newPos;
|
|
19501
19714
|
}
|
|
19502
|
-
|
|
19503
|
-
if (
|
|
19504
|
-
return
|
|
19505
|
-
}
|
|
19506
|
-
|
|
19507
|
-
const progressPayload = value.type === "subagent_progress" && payload && isRecord8(payload.progress) ? payload.progress : null;
|
|
19508
|
-
const nativeIdValue = progressPayload?.id ?? payload?.id;
|
|
19509
|
-
if (!payload || !nonBlankString(nativeIdValue)) {
|
|
19510
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent frame has no stable ID");
|
|
19511
|
-
}
|
|
19512
|
-
const nativeSubagentId = nativeIdValue;
|
|
19513
|
-
const callId = nativeSubagentId;
|
|
19514
|
-
const emit = active?.onEvent ?? this.#options.onSubagentEvent;
|
|
19515
|
-
if (value.type === "subagent_event") {
|
|
19516
|
-
emit?.({ type: "subagent.transcript.changed", callId, nativeSubagentId });
|
|
19517
|
-
return true;
|
|
19715
|
+
equals(left, right, options) {
|
|
19716
|
+
if (options.comparator) {
|
|
19717
|
+
return options.comparator(left, right);
|
|
19718
|
+
} else {
|
|
19719
|
+
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
19518
19720
|
}
|
|
19519
|
-
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
|
|
19524
|
-
|
|
19525
|
-
callId,
|
|
19526
|
-
nativeSubagentId,
|
|
19527
|
-
description,
|
|
19528
|
-
...nonBlankString(payload.agent) ? { role: payload.agent } : {},
|
|
19529
|
-
...nonBlankString(payload.task) ? { prompt: payload.task } : {},
|
|
19530
|
-
background: payload.detached === true,
|
|
19531
|
-
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19532
|
-
});
|
|
19533
|
-
return true;
|
|
19534
|
-
}
|
|
19535
|
-
if (status2 !== "completed" && status2 !== "failed" && status2 !== "aborted") {
|
|
19536
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent lifecycle status is invalid");
|
|
19721
|
+
}
|
|
19722
|
+
removeEmpty(array2) {
|
|
19723
|
+
const ret = [];
|
|
19724
|
+
for (let i = 0; i < array2.length; i++) {
|
|
19725
|
+
if (array2[i]) {
|
|
19726
|
+
ret.push(array2[i]);
|
|
19537
19727
|
}
|
|
19538
|
-
emit?.({
|
|
19539
|
-
type: "subagent.completed",
|
|
19540
|
-
callId,
|
|
19541
|
-
nativeSubagentId,
|
|
19542
|
-
isError: status2 !== "completed",
|
|
19543
|
-
...nonBlankString(payload.resultSummary) ? { resultSummary: payload.resultSummary } : {},
|
|
19544
|
-
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19545
|
-
});
|
|
19546
|
-
return true;
|
|
19547
19728
|
}
|
|
19548
|
-
|
|
19549
|
-
if (!progress || !nonBlankString(progress.id) || progress.id !== nativeSubagentId) {
|
|
19550
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent progress is invalid");
|
|
19551
|
-
}
|
|
19552
|
-
const status = subagentStatus(progress.status);
|
|
19553
|
-
const recentOutput = Array.isArray(progress.recentOutput) ? progress.recentOutput.filter((item) => typeof item === "string") : [];
|
|
19554
|
-
const resultSummary = recentOutput.at(-1);
|
|
19555
|
-
emit?.({
|
|
19556
|
-
type: "subagent.updated",
|
|
19557
|
-
callId,
|
|
19558
|
-
nativeSubagentId,
|
|
19559
|
-
status,
|
|
19560
|
-
...nonBlankString(progress.description) ? { description: progress.description } : nonBlankString(payload.task) ? { description: payload.task } : {},
|
|
19561
|
-
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
19562
|
-
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19563
|
-
});
|
|
19564
|
-
return true;
|
|
19729
|
+
return ret;
|
|
19565
19730
|
}
|
|
19566
|
-
|
|
19567
|
-
|
|
19731
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
19732
|
+
castInput(value, options) {
|
|
19733
|
+
return value;
|
|
19568
19734
|
}
|
|
19569
|
-
|
|
19570
|
-
|
|
19571
|
-
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
19577
|
-
|
|
19735
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
19736
|
+
tokenize(value, options) {
|
|
19737
|
+
return Array.from(value);
|
|
19738
|
+
}
|
|
19739
|
+
join(chars) {
|
|
19740
|
+
return chars.join("");
|
|
19741
|
+
}
|
|
19742
|
+
postProcess(changeObjects, options) {
|
|
19743
|
+
return changeObjects;
|
|
19744
|
+
}
|
|
19745
|
+
get useLongestToken() {
|
|
19746
|
+
return false;
|
|
19747
|
+
}
|
|
19748
|
+
buildValues(lastComponent, newTokens, oldTokens) {
|
|
19749
|
+
const components = [];
|
|
19750
|
+
let nextComponent;
|
|
19751
|
+
while (lastComponent) {
|
|
19752
|
+
components.push(lastComponent);
|
|
19753
|
+
nextComponent = lastComponent.previousComponent;
|
|
19754
|
+
delete lastComponent.previousComponent;
|
|
19755
|
+
lastComponent = nextComponent;
|
|
19578
19756
|
}
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19757
|
+
components.reverse();
|
|
19758
|
+
const componentLen = components.length;
|
|
19759
|
+
let componentPos = 0, newPos = 0, oldPos = 0;
|
|
19760
|
+
for (; componentPos < componentLen; componentPos++) {
|
|
19761
|
+
const component = components[componentPos];
|
|
19762
|
+
if (!component.removed) {
|
|
19763
|
+
if (!component.added && this.useLongestToken) {
|
|
19764
|
+
let value = newTokens.slice(newPos, newPos + component.count);
|
|
19765
|
+
value = value.map(function(value2, i) {
|
|
19766
|
+
const oldValue = oldTokens[oldPos + i];
|
|
19767
|
+
return oldValue.length > value2.length ? oldValue : value2;
|
|
19768
|
+
});
|
|
19769
|
+
component.value = this.join(value);
|
|
19770
|
+
} else {
|
|
19771
|
+
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
19588
19772
|
}
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
|
|
19596
|
-
...optionDetails ? { optionDetails } : {},
|
|
19597
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19598
|
-
};
|
|
19599
|
-
} else if (method === "confirm") {
|
|
19600
|
-
if (typeof value.message !== "string") {
|
|
19601
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC confirm request has no message");
|
|
19602
|
-
}
|
|
19603
|
-
request = {
|
|
19604
|
-
requestId: requestId2,
|
|
19605
|
-
method,
|
|
19606
|
-
title,
|
|
19607
|
-
message: value.message,
|
|
19608
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19609
|
-
};
|
|
19610
|
-
} else if (method === "input") {
|
|
19611
|
-
if (value.placeholder !== void 0 && typeof value.placeholder !== "string") {
|
|
19612
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC input placeholder is invalid");
|
|
19613
|
-
}
|
|
19614
|
-
request = {
|
|
19615
|
-
requestId: requestId2,
|
|
19616
|
-
method,
|
|
19617
|
-
title,
|
|
19618
|
-
...typeof value.placeholder === "string" ? { placeholder: value.placeholder } : {},
|
|
19619
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19620
|
-
};
|
|
19621
|
-
} else {
|
|
19622
|
-
if (value.prefill !== void 0 && typeof value.prefill !== "string") {
|
|
19623
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC editor prefill is invalid");
|
|
19773
|
+
newPos += component.count;
|
|
19774
|
+
if (!component.added) {
|
|
19775
|
+
oldPos += component.count;
|
|
19776
|
+
}
|
|
19777
|
+
} else {
|
|
19778
|
+
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
19779
|
+
oldPos += component.count;
|
|
19624
19780
|
}
|
|
19625
|
-
request = {
|
|
19626
|
-
requestId: requestId2,
|
|
19627
|
-
method: "editor",
|
|
19628
|
-
title,
|
|
19629
|
-
...typeof value.prefill === "string" ? { prefill: value.prefill } : {},
|
|
19630
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19631
|
-
};
|
|
19632
|
-
}
|
|
19633
|
-
const pending = { request, timeout: null };
|
|
19634
|
-
if (request.timeoutMs !== void 0) {
|
|
19635
|
-
pending.timeout = setTimeout(() => {
|
|
19636
|
-
if (this.#activeTurn !== active || !active.interactions.has(requestId2))
|
|
19637
|
-
return;
|
|
19638
|
-
void this.#resolveInteraction({ requestId: requestId2, cancelled: true }, "expired").catch((error51) => {
|
|
19639
|
-
if (this.#closed || this.#failed)
|
|
19640
|
-
return;
|
|
19641
|
-
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC Interaction timeout handling failed: ${message2(error51)}`));
|
|
19642
|
-
});
|
|
19643
|
-
}, request.timeoutMs);
|
|
19644
19781
|
}
|
|
19645
|
-
|
|
19646
|
-
active.onEvent({ type: "interaction.requested", request });
|
|
19782
|
+
return components;
|
|
19647
19783
|
}
|
|
19648
|
-
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
19652
|
-
|
|
19653
|
-
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19784
|
+
};
|
|
19785
|
+
|
|
19786
|
+
// ../../../node_modules/diff/libesm/diff/line.js
|
|
19787
|
+
var LineDiff = class extends Diff {
|
|
19788
|
+
constructor() {
|
|
19789
|
+
super(...arguments);
|
|
19790
|
+
this.tokenize = tokenize;
|
|
19791
|
+
}
|
|
19792
|
+
equals(left, right, options) {
|
|
19793
|
+
if (options.ignoreWhitespace) {
|
|
19794
|
+
if (!options.newlineIsToken || !left.includes("\n")) {
|
|
19795
|
+
left = left.trim();
|
|
19660
19796
|
}
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
}
|
|
19664
|
-
if (pending.timeout)
|
|
19665
|
-
clearTimeout(pending.timeout);
|
|
19666
|
-
this.#pending.delete(id);
|
|
19667
|
-
if (value.success === true) {
|
|
19668
|
-
if (pending.command === "prompt" && active?.promptId === id && isRecord8(value.data) && value.data.agentInvoked === false) {
|
|
19669
|
-
this.#settleLocalTurn(active, { cancelled: false });
|
|
19797
|
+
if (!options.newlineIsToken || !right.includes("\n")) {
|
|
19798
|
+
right = right.trim();
|
|
19670
19799
|
}
|
|
19671
|
-
|
|
19672
|
-
|
|
19673
|
-
|
|
19674
|
-
|
|
19675
|
-
|
|
19676
|
-
|
|
19677
|
-
pending.reject(new Error(error51));
|
|
19800
|
+
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
19801
|
+
if (left.endsWith("\n")) {
|
|
19802
|
+
left = left.slice(0, -1);
|
|
19803
|
+
}
|
|
19804
|
+
if (right.endsWith("\n")) {
|
|
19805
|
+
right = right.slice(0, -1);
|
|
19678
19806
|
}
|
|
19679
19807
|
}
|
|
19808
|
+
return super.equals(left, right, options);
|
|
19680
19809
|
}
|
|
19681
|
-
|
|
19682
|
-
|
|
19683
|
-
|
|
19684
|
-
|
|
19685
|
-
|
|
19686
|
-
|
|
19687
|
-
|
|
19688
|
-
|
|
19689
|
-
active.tools.set(callId, toolName);
|
|
19690
|
-
active.onEvent({
|
|
19691
|
-
type: "tool.started",
|
|
19692
|
-
callId,
|
|
19693
|
-
toolName,
|
|
19694
|
-
arguments: argumentsResult.data
|
|
19695
|
-
});
|
|
19810
|
+
};
|
|
19811
|
+
var lineDiff = new LineDiff();
|
|
19812
|
+
function diffLines(oldStr, newStr, options) {
|
|
19813
|
+
return lineDiff.diff(oldStr, newStr, options);
|
|
19814
|
+
}
|
|
19815
|
+
function tokenize(value, options) {
|
|
19816
|
+
if (options.stripTrailingCr) {
|
|
19817
|
+
value = value.replace(/\r\n/g, "\n");
|
|
19696
19818
|
}
|
|
19697
|
-
|
|
19698
|
-
|
|
19699
|
-
|
|
19700
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19701
|
-
}
|
|
19702
|
-
if (!active.tools.has(callId))
|
|
19703
|
-
return;
|
|
19704
|
-
const outputResult = jsonValueSchema.safeParse(value.partialResult ?? null);
|
|
19705
|
-
if (!outputResult.success) {
|
|
19706
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19707
|
-
}
|
|
19708
|
-
active.onEvent({ type: "tool.updated", callId, output: outputResult.data });
|
|
19819
|
+
const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
|
|
19820
|
+
if (!linesAndNewlines[linesAndNewlines.length - 1]) {
|
|
19821
|
+
linesAndNewlines.pop();
|
|
19709
19822
|
}
|
|
19710
|
-
|
|
19711
|
-
const
|
|
19712
|
-
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
const expectedName = active.tools.get(callId);
|
|
19717
|
-
if (expectedName === void 0)
|
|
19718
|
-
return;
|
|
19719
|
-
const result = jsonValueSchema.safeParse(value.result);
|
|
19720
|
-
if (typeof toolName !== "string" || expectedName !== toolName || value.isError !== void 0 && typeof value.isError !== "boolean" || !result.success) {
|
|
19721
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19823
|
+
for (let i = 0; i < linesAndNewlines.length; i++) {
|
|
19824
|
+
const line = linesAndNewlines[i];
|
|
19825
|
+
if (i % 2 && !options.newlineIsToken) {
|
|
19826
|
+
retLines[retLines.length - 1] += line;
|
|
19827
|
+
} else {
|
|
19828
|
+
retLines.push(line);
|
|
19722
19829
|
}
|
|
19723
|
-
active.tools.delete(callId);
|
|
19724
|
-
active.onEvent({
|
|
19725
|
-
type: "tool.completed",
|
|
19726
|
-
callId,
|
|
19727
|
-
toolName,
|
|
19728
|
-
result: result.data,
|
|
19729
|
-
isError: value.isError === true
|
|
19730
|
-
});
|
|
19731
19830
|
}
|
|
19732
|
-
|
|
19733
|
-
|
|
19734
|
-
|
|
19735
|
-
|
|
19736
|
-
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
|
|
19740
|
-
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
19746
|
-
return;
|
|
19747
|
-
response = await this.#send("get_state", {});
|
|
19748
|
-
}
|
|
19749
|
-
let state = parseSessionState(response);
|
|
19750
|
-
if (this.#activeTurn !== active || active.cancellation !== "accepted")
|
|
19751
|
-
return;
|
|
19752
|
-
const data = sessionStateData(response);
|
|
19753
|
-
if (!active.cancellationReloaded && state.sessionFile && state.sessionId === this.state.sessionId && state.sessionFile === this.state.sessionFile && data.isStreaming === false && data.isCompacting === false && data.queuedMessageCount === 0 && data.hasPendingAsyncWork === true && active.tools.size === 0) {
|
|
19754
|
-
await this.verifySessionCwd(this.#options.cwd);
|
|
19755
|
-
if (this.#activeTurn !== active)
|
|
19756
|
-
return;
|
|
19757
|
-
active.cancellationReloaded = true;
|
|
19758
|
-
const reset = await this.#send("new_session", {});
|
|
19759
|
-
if (this.#activeTurn !== active)
|
|
19760
|
-
return;
|
|
19761
|
-
if (!isRecord8(reset.data) || reset.data.cancelled !== false) {
|
|
19762
|
-
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reset was refused");
|
|
19763
|
-
}
|
|
19764
|
-
const reloaded = await this.#send("switch_session", { sessionPath: state.sessionFile });
|
|
19765
|
-
if (this.#activeTurn !== active)
|
|
19766
|
-
return;
|
|
19767
|
-
if (!isRecord8(reloaded.data) || reloaded.data.cancelled !== false) {
|
|
19768
|
-
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reload was refused");
|
|
19769
|
-
}
|
|
19770
|
-
const previous = state;
|
|
19771
|
-
response = await this.#send("get_state", {});
|
|
19772
|
-
state = parseSessionState(response);
|
|
19773
|
-
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile) {
|
|
19774
|
-
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity");
|
|
19775
|
-
}
|
|
19776
|
-
if (state.provider !== previous.provider || state.modelId !== previous.modelId) {
|
|
19777
|
-
if (!previous.provider || !previous.modelId) {
|
|
19778
|
-
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session has no restorable Model");
|
|
19779
|
-
}
|
|
19780
|
-
await this.#send("set_model", { provider: previous.provider, modelId: previous.modelId });
|
|
19781
|
-
}
|
|
19782
|
-
if (previous.thinkingLevel && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19783
|
-
await this.#send("set_thinking_level", { level: previous.thinkingLevel });
|
|
19784
|
-
}
|
|
19785
|
-
response = await this.#send("get_state", {});
|
|
19786
|
-
state = parseSessionState(response);
|
|
19787
|
-
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile || state.provider !== previous.provider || state.modelId !== previous.modelId || previous.thinkingLevel !== null && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19788
|
-
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity or configuration");
|
|
19789
|
-
}
|
|
19831
|
+
return retLines;
|
|
19832
|
+
}
|
|
19833
|
+
|
|
19834
|
+
// ../../../node_modules/diff/libesm/patch/parse.js
|
|
19835
|
+
function parsePatch(uniDiff) {
|
|
19836
|
+
const diffstr = uniDiff.split(/\n/), list = [];
|
|
19837
|
+
let i = 0;
|
|
19838
|
+
function parseIndex() {
|
|
19839
|
+
const index = {};
|
|
19840
|
+
list.push(index);
|
|
19841
|
+
while (i < diffstr.length) {
|
|
19842
|
+
const line = diffstr[i];
|
|
19843
|
+
if (/^(---|\+\+\+|@@)\s/.test(line)) {
|
|
19844
|
+
break;
|
|
19790
19845
|
}
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19846
|
+
const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
|
|
19847
|
+
if (header) {
|
|
19848
|
+
index.index = header[1];
|
|
19849
|
+
}
|
|
19850
|
+
i++;
|
|
19851
|
+
}
|
|
19852
|
+
parseFileHeader(index);
|
|
19853
|
+
parseFileHeader(index);
|
|
19854
|
+
index.hunks = [];
|
|
19855
|
+
while (i < diffstr.length) {
|
|
19856
|
+
const line = diffstr[i];
|
|
19857
|
+
if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
|
|
19858
|
+
break;
|
|
19859
|
+
} else if (/^@@/.test(line)) {
|
|
19860
|
+
index.hunks.push(parseHunk());
|
|
19861
|
+
} else if (line) {
|
|
19862
|
+
throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
|
|
19863
|
+
} else {
|
|
19864
|
+
i++;
|
|
19798
19865
|
}
|
|
19799
|
-
this.#state = state;
|
|
19800
|
-
active.settlement = "confirmed";
|
|
19801
|
-
this.#finishSettledTurn(active);
|
|
19802
|
-
} catch (error51) {
|
|
19803
|
-
if (this.#activeTurn !== active)
|
|
19804
|
-
return;
|
|
19805
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC cancelled Turn state could not be confirmed: ${message2(error51)}`);
|
|
19806
|
-
this.#terminateFailedCancellation(active, fault);
|
|
19807
|
-
} finally {
|
|
19808
|
-
active.cancellationChecking = false;
|
|
19809
19866
|
}
|
|
19810
19867
|
}
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
async #confirmSettledTurn(active) {
|
|
19819
|
-
try {
|
|
19820
|
-
const response = await this.#send("get_state", {});
|
|
19821
|
-
const state = parseSessionState(response);
|
|
19822
|
-
if (this.#activeTurn !== active)
|
|
19823
|
-
return;
|
|
19824
|
-
if (active.cancellation !== "none") {
|
|
19825
|
-
active.settlement = "pending";
|
|
19826
|
-
if (active.cancellation === "accepted")
|
|
19827
|
-
void this.#confirmCancelledTurn(active);
|
|
19828
|
-
return;
|
|
19868
|
+
function parseFileHeader(index) {
|
|
19869
|
+
const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
|
|
19870
|
+
if (fileHeader) {
|
|
19871
|
+
const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
|
|
19872
|
+
let fileName = data[0].replace(/\\\\/g, "\\");
|
|
19873
|
+
if (/^".*"$/.test(fileName)) {
|
|
19874
|
+
fileName = fileName.substr(1, fileName.length - 2);
|
|
19829
19875
|
}
|
|
19830
|
-
if (
|
|
19831
|
-
|
|
19876
|
+
if (fileHeader[1] === "---") {
|
|
19877
|
+
index.oldFileName = fileName;
|
|
19878
|
+
index.oldHeader = header;
|
|
19879
|
+
} else {
|
|
19880
|
+
index.newFileName = fileName;
|
|
19881
|
+
index.newHeader = header;
|
|
19832
19882
|
}
|
|
19833
|
-
|
|
19834
|
-
active.settlement = "confirmed";
|
|
19835
|
-
this.#finishSettledTurn(active);
|
|
19836
|
-
} catch (error51) {
|
|
19837
|
-
if (this.#activeTurn !== active)
|
|
19838
|
-
return;
|
|
19839
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC stable Turn state could not be confirmed: ${message2(error51)}`);
|
|
19840
|
-
this.#fail(fault);
|
|
19883
|
+
i++;
|
|
19841
19884
|
}
|
|
19842
19885
|
}
|
|
19843
|
-
|
|
19844
|
-
|
|
19845
|
-
|
|
19886
|
+
function parseHunk() {
|
|
19887
|
+
var _a3;
|
|
19888
|
+
const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
|
19889
|
+
const hunk = {
|
|
19890
|
+
oldStart: +chunkHeader[1],
|
|
19891
|
+
oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
|
|
19892
|
+
newStart: +chunkHeader[3],
|
|
19893
|
+
newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
|
|
19894
|
+
lines: []
|
|
19895
|
+
};
|
|
19896
|
+
if (hunk.oldLines === 0) {
|
|
19897
|
+
hunk.oldStart += 1;
|
|
19846
19898
|
}
|
|
19847
|
-
if (
|
|
19848
|
-
|
|
19849
|
-
active.cancellationTimeout = null;
|
|
19850
|
-
if (active.cancellationRecheck)
|
|
19851
|
-
clearTimeout(active.cancellationRecheck);
|
|
19852
|
-
active.cancellationRecheck = null;
|
|
19853
|
-
this.#closeInteractions(active, active.cancellation === "accepted" ? "cancelled" : "superseded");
|
|
19854
|
-
if (active.tools.size > 0) {
|
|
19855
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC settled with active Tool executions"));
|
|
19856
|
-
return;
|
|
19899
|
+
if (hunk.newLines === 0) {
|
|
19900
|
+
hunk.newStart += 1;
|
|
19857
19901
|
}
|
|
19858
|
-
|
|
19859
|
-
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
|
|
19864
|
-
|
|
19865
|
-
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
|
|
19869
|
-
|
|
19870
|
-
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
|
|
19902
|
+
let addCount = 0, removeCount = 0;
|
|
19903
|
+
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
|
|
19904
|
+
const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
|
|
19905
|
+
if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
|
|
19906
|
+
hunk.lines.push(diffstr[i]);
|
|
19907
|
+
if (operation === "+") {
|
|
19908
|
+
addCount++;
|
|
19909
|
+
} else if (operation === "-") {
|
|
19910
|
+
removeCount++;
|
|
19911
|
+
} else if (operation === " ") {
|
|
19912
|
+
addCount++;
|
|
19913
|
+
removeCount++;
|
|
19914
|
+
}
|
|
19915
|
+
} else {
|
|
19916
|
+
throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
|
|
19917
|
+
}
|
|
19874
19918
|
}
|
|
19875
|
-
|
|
19876
|
-
|
|
19877
|
-
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19878
|
-
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19919
|
+
if (!addCount && hunk.newLines === 1) {
|
|
19920
|
+
hunk.newLines = 0;
|
|
19879
19921
|
}
|
|
19880
|
-
|
|
19881
|
-
|
|
19882
|
-
|
|
19883
|
-
|
|
19884
|
-
|
|
19885
|
-
|
|
19922
|
+
if (!removeCount && hunk.oldLines === 1) {
|
|
19923
|
+
hunk.oldLines = 0;
|
|
19924
|
+
}
|
|
19925
|
+
if (addCount !== hunk.newLines) {
|
|
19926
|
+
throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
19927
|
+
}
|
|
19928
|
+
if (removeCount !== hunk.oldLines) {
|
|
19929
|
+
throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
19930
|
+
}
|
|
19931
|
+
return hunk;
|
|
19886
19932
|
}
|
|
19887
|
-
|
|
19888
|
-
|
|
19933
|
+
while (i < diffstr.length) {
|
|
19934
|
+
parseIndex();
|
|
19889
19935
|
}
|
|
19890
|
-
|
|
19891
|
-
|
|
19892
|
-
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19896
|
-
|
|
19897
|
-
|
|
19936
|
+
return list;
|
|
19937
|
+
}
|
|
19938
|
+
|
|
19939
|
+
// ../../../node_modules/diff/libesm/patch/create.js
|
|
19940
|
+
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
19941
|
+
let optionsObj;
|
|
19942
|
+
if (!options) {
|
|
19943
|
+
optionsObj = {};
|
|
19944
|
+
} else if (typeof options === "function") {
|
|
19945
|
+
optionsObj = { callback: options };
|
|
19946
|
+
} else {
|
|
19947
|
+
optionsObj = options;
|
|
19948
|
+
}
|
|
19949
|
+
if (typeof optionsObj.context === "undefined") {
|
|
19950
|
+
optionsObj.context = 4;
|
|
19951
|
+
}
|
|
19952
|
+
const context = optionsObj.context;
|
|
19953
|
+
if (optionsObj.newlineIsToken) {
|
|
19954
|
+
throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
|
|
19955
|
+
}
|
|
19956
|
+
if (!optionsObj.callback) {
|
|
19957
|
+
return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
|
|
19958
|
+
} else {
|
|
19959
|
+
const { callback } = optionsObj;
|
|
19960
|
+
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
|
19961
|
+
const patch = diffLinesResultToPatch(diff);
|
|
19962
|
+
callback(patch);
|
|
19963
|
+
} }));
|
|
19964
|
+
}
|
|
19965
|
+
function diffLinesResultToPatch(diff) {
|
|
19966
|
+
if (!diff) {
|
|
19898
19967
|
return;
|
|
19899
19968
|
}
|
|
19900
|
-
|
|
19901
|
-
|
|
19902
|
-
|
|
19903
|
-
|
|
19904
|
-
|
|
19905
|
-
active.onEvent({ type: "reasoning.delta", messageId, delta: finalReasoning });
|
|
19969
|
+
diff.push({ value: "", lines: [] });
|
|
19970
|
+
function contextLines(lines) {
|
|
19971
|
+
return lines.map(function(entry) {
|
|
19972
|
+
return " " + entry;
|
|
19973
|
+
});
|
|
19906
19974
|
}
|
|
19907
|
-
|
|
19908
|
-
|
|
19975
|
+
const hunks = [];
|
|
19976
|
+
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
|
19977
|
+
for (let i = 0; i < diff.length; i++) {
|
|
19978
|
+
const current = diff[i], lines = current.lines || splitLines(current.value);
|
|
19979
|
+
current.lines = lines;
|
|
19980
|
+
if (current.added || current.removed) {
|
|
19981
|
+
if (!oldRangeStart) {
|
|
19982
|
+
const prev = diff[i - 1];
|
|
19983
|
+
oldRangeStart = oldLine;
|
|
19984
|
+
newRangeStart = newLine;
|
|
19985
|
+
if (prev) {
|
|
19986
|
+
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
|
|
19987
|
+
oldRangeStart -= curRange.length;
|
|
19988
|
+
newRangeStart -= curRange.length;
|
|
19989
|
+
}
|
|
19990
|
+
}
|
|
19991
|
+
for (const line of lines) {
|
|
19992
|
+
curRange.push((current.added ? "+" : "-") + line);
|
|
19993
|
+
}
|
|
19994
|
+
if (current.added) {
|
|
19995
|
+
newLine += lines.length;
|
|
19996
|
+
} else {
|
|
19997
|
+
oldLine += lines.length;
|
|
19998
|
+
}
|
|
19999
|
+
} else {
|
|
20000
|
+
if (oldRangeStart) {
|
|
20001
|
+
if (lines.length <= context * 2 && i < diff.length - 2) {
|
|
20002
|
+
for (const line of contextLines(lines)) {
|
|
20003
|
+
curRange.push(line);
|
|
20004
|
+
}
|
|
20005
|
+
} else {
|
|
20006
|
+
const contextSize = Math.min(lines.length, context);
|
|
20007
|
+
for (const line of contextLines(lines.slice(0, contextSize))) {
|
|
20008
|
+
curRange.push(line);
|
|
20009
|
+
}
|
|
20010
|
+
const hunk = {
|
|
20011
|
+
oldStart: oldRangeStart,
|
|
20012
|
+
oldLines: oldLine - oldRangeStart + contextSize,
|
|
20013
|
+
newStart: newRangeStart,
|
|
20014
|
+
newLines: newLine - newRangeStart + contextSize,
|
|
20015
|
+
lines: curRange
|
|
20016
|
+
};
|
|
20017
|
+
hunks.push(hunk);
|
|
20018
|
+
oldRangeStart = 0;
|
|
20019
|
+
newRangeStart = 0;
|
|
20020
|
+
curRange = [];
|
|
20021
|
+
}
|
|
20022
|
+
}
|
|
20023
|
+
oldLine += lines.length;
|
|
20024
|
+
newLine += lines.length;
|
|
20025
|
+
}
|
|
20026
|
+
}
|
|
20027
|
+
for (const hunk of hunks) {
|
|
20028
|
+
for (let i = 0; i < hunk.lines.length; i++) {
|
|
20029
|
+
if (hunk.lines[i].endsWith("\n")) {
|
|
20030
|
+
hunk.lines[i] = hunk.lines[i].slice(0, -1);
|
|
20031
|
+
} else {
|
|
20032
|
+
hunk.lines.splice(i + 1, 0, "\");
|
|
20033
|
+
i++;
|
|
20034
|
+
}
|
|
20035
|
+
}
|
|
20036
|
+
}
|
|
20037
|
+
return {
|
|
20038
|
+
oldFileName,
|
|
20039
|
+
newFileName,
|
|
20040
|
+
oldHeader,
|
|
20041
|
+
newHeader,
|
|
20042
|
+
hunks
|
|
20043
|
+
};
|
|
20044
|
+
}
|
|
20045
|
+
}
|
|
20046
|
+
function formatPatch(patch) {
|
|
20047
|
+
if (Array.isArray(patch)) {
|
|
20048
|
+
return patch.map(formatPatch).join("\n");
|
|
20049
|
+
}
|
|
20050
|
+
const ret = [];
|
|
20051
|
+
if (patch.oldFileName == patch.newFileName) {
|
|
20052
|
+
ret.push("Index: " + patch.oldFileName);
|
|
20053
|
+
}
|
|
20054
|
+
ret.push("===================================================================");
|
|
20055
|
+
ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
|
|
20056
|
+
ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
|
|
20057
|
+
for (let i = 0; i < patch.hunks.length; i++) {
|
|
20058
|
+
const hunk = patch.hunks[i];
|
|
20059
|
+
if (hunk.oldLines === 0) {
|
|
20060
|
+
hunk.oldStart -= 1;
|
|
19909
20061
|
}
|
|
19910
|
-
if (
|
|
19911
|
-
|
|
19912
|
-
active.onEvent({ type: "text.delta", messageId, delta: finalText });
|
|
20062
|
+
if (hunk.newLines === 0) {
|
|
20063
|
+
hunk.newStart -= 1;
|
|
19913
20064
|
}
|
|
19914
|
-
|
|
19915
|
-
|
|
19916
|
-
|
|
19917
|
-
active.reasoningMessageOpen = false;
|
|
19918
|
-
active.lastFinalizedMessageText = finalText;
|
|
19919
|
-
active.lastFinalizedMessageReasoning = finalReasoning;
|
|
19920
|
-
active.onEvent({ type: "message.completed", messageId });
|
|
19921
|
-
}
|
|
19922
|
-
#write(value) {
|
|
19923
|
-
const child = this.#child;
|
|
19924
|
-
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19925
|
-
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
20065
|
+
ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
|
|
20066
|
+
for (const line of hunk.lines) {
|
|
20067
|
+
ret.push(line);
|
|
19926
20068
|
}
|
|
19927
|
-
return new Promise((resolve, reject) => {
|
|
19928
|
-
const frame = Buffer.from(`${JSON.stringify(value)}
|
|
19929
|
-
`, "utf8");
|
|
19930
|
-
child.stdin.write(frame, (error51) => error51 ? reject(error51) : resolve());
|
|
19931
|
-
});
|
|
19932
20069
|
}
|
|
19933
|
-
|
|
19934
|
-
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
}
|
|
19938
|
-
return new Promise((resolve, reject) => {
|
|
19939
|
-
const pending = {
|
|
19940
|
-
command: type,
|
|
19941
|
-
resolve,
|
|
19942
|
-
reject,
|
|
19943
|
-
timeout: null
|
|
19944
|
-
};
|
|
19945
|
-
this.#pending.set(id, pending);
|
|
19946
|
-
this.#armCommandTimeout(id, pending);
|
|
19947
|
-
const frame = Buffer.from(`${JSON.stringify({ id, type, ...payload })}
|
|
19948
|
-
`, "utf8");
|
|
19949
|
-
child.stdin.write(frame, (error51) => {
|
|
19950
|
-
if (error51) {
|
|
19951
|
-
if (pending.timeout)
|
|
19952
|
-
clearTimeout(pending.timeout);
|
|
19953
|
-
this.#pending.delete(id);
|
|
19954
|
-
reject(error51);
|
|
19955
|
-
}
|
|
19956
|
-
});
|
|
19957
|
-
});
|
|
20070
|
+
return ret.join("\n") + "\n";
|
|
20071
|
+
}
|
|
20072
|
+
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
20073
|
+
if (typeof options === "function") {
|
|
20074
|
+
options = { callback: options };
|
|
19958
20075
|
}
|
|
19959
|
-
|
|
19960
|
-
|
|
20076
|
+
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
|
|
20077
|
+
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
20078
|
+
if (!patchObj) {
|
|
19961
20079
|
return;
|
|
19962
20080
|
}
|
|
19963
|
-
|
|
19964
|
-
|
|
19965
|
-
|
|
19966
|
-
|
|
19967
|
-
|
|
19968
|
-
|
|
19969
|
-
|
|
19970
|
-
|
|
19971
|
-
return;
|
|
20081
|
+
return formatPatch(patchObj);
|
|
20082
|
+
} else {
|
|
20083
|
+
const { callback } = options;
|
|
20084
|
+
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
|
|
20085
|
+
if (!patchObj) {
|
|
20086
|
+
callback(void 0);
|
|
20087
|
+
} else {
|
|
20088
|
+
callback(formatPatch(patchObj));
|
|
19972
20089
|
}
|
|
19973
|
-
|
|
19974
|
-
void this.#terminateTimedOutPrompt(fault);
|
|
19975
|
-
}, this.#options.commandTimeoutMs);
|
|
20090
|
+
} }));
|
|
19976
20091
|
}
|
|
19977
|
-
|
|
19978
|
-
|
|
19979
|
-
|
|
19980
|
-
|
|
19981
|
-
|
|
19982
|
-
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
pending.timeout = null;
|
|
19986
|
-
}
|
|
19987
|
-
let finalFault = fault;
|
|
19988
|
-
try {
|
|
19989
|
-
await this.close();
|
|
19990
|
-
} catch (error51) {
|
|
19991
|
-
finalFault = new OmpRpcFaultError("processExited", `Omp RPC timed-out Prompt cleanup failed: ${message2(error51)}`);
|
|
19992
|
-
}
|
|
19993
|
-
this.#rejectAll(finalFault);
|
|
19994
|
-
this.#options.onFault?.(finalFault);
|
|
20092
|
+
}
|
|
20093
|
+
function splitLines(text) {
|
|
20094
|
+
const hasTrailingNl = text.endsWith("\n");
|
|
20095
|
+
const result = text.split("\n").map((line) => line + "\n");
|
|
20096
|
+
if (hasTrailingNl) {
|
|
20097
|
+
result.pop();
|
|
20098
|
+
} else {
|
|
20099
|
+
result.push(result.pop().slice(0, -1));
|
|
19995
20100
|
}
|
|
19996
|
-
|
|
19997
|
-
|
|
19998
|
-
|
|
19999
|
-
|
|
20000
|
-
|
|
20001
|
-
|
|
20002
|
-
|
|
20101
|
+
return result;
|
|
20102
|
+
}
|
|
20103
|
+
|
|
20104
|
+
// dist/omp-adapter.js
|
|
20105
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
20106
|
+
import { realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
20107
|
+
import path7 from "node:path";
|
|
20108
|
+
|
|
20109
|
+
// dist/omp-last-turn-rollback.js
|
|
20110
|
+
function modelFromState(state) {
|
|
20111
|
+
if (state.provider === null && state.modelId === null)
|
|
20112
|
+
return null;
|
|
20113
|
+
if (state.provider === null || state.modelId === null) {
|
|
20114
|
+
throw new Error("Omp state contains a partial Model identity");
|
|
20003
20115
|
}
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20012
|
-
|
|
20013
|
-
|
|
20014
|
-
|
|
20116
|
+
return { provider: state.provider, id: state.modelId };
|
|
20117
|
+
}
|
|
20118
|
+
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
20119
|
+
const startupState = transport.state;
|
|
20120
|
+
const startupSessionId = startupState.sessionId;
|
|
20121
|
+
const currentModel = modelFromState(startupState);
|
|
20122
|
+
const currentThinking = startupState.thinkingLevel;
|
|
20123
|
+
const copiedHistory = await transport.getEntries();
|
|
20124
|
+
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
20125
|
+
if (!boundary)
|
|
20126
|
+
return { ok: false, reason: "empty" };
|
|
20127
|
+
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
20128
|
+
sessionId: startupSessionId,
|
|
20129
|
+
model: currentModel
|
|
20130
|
+
});
|
|
20131
|
+
let state = await transport.fork(boundary.lastUserEntryId);
|
|
20132
|
+
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
20133
|
+
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
20015
20134
|
}
|
|
20016
|
-
|
|
20017
|
-
if (
|
|
20018
|
-
|
|
20019
|
-
|
|
20020
|
-
for (const pending of this.#pending.values()) {
|
|
20021
|
-
if (pending.timeout)
|
|
20022
|
-
clearTimeout(pending.timeout);
|
|
20023
|
-
pending.reject(error51);
|
|
20024
|
-
}
|
|
20025
|
-
this.#pending.clear();
|
|
20026
|
-
const manual = this.#manualCompaction;
|
|
20027
|
-
this.#manualCompaction = null;
|
|
20028
|
-
manual?.reject(error51);
|
|
20029
|
-
this.#rejectActiveTurn(error51);
|
|
20135
|
+
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
20136
|
+
if (!currentModel)
|
|
20137
|
+
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
20138
|
+
state = await transport.selectModel(currentModel);
|
|
20030
20139
|
}
|
|
20031
|
-
|
|
20032
|
-
if (
|
|
20033
|
-
|
|
20034
|
-
|
|
20035
|
-
this.#startupFaultResolve?.(error51);
|
|
20036
|
-
this.#startupFaultResolve = null;
|
|
20037
|
-
this.#rejectAll(error51);
|
|
20038
|
-
this.#options.onFault?.(error51);
|
|
20140
|
+
if (state.thinkingLevel !== currentThinking) {
|
|
20141
|
+
if (!currentThinking)
|
|
20142
|
+
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
20143
|
+
state = await transport.selectThinkingOption(currentThinking);
|
|
20039
20144
|
}
|
|
20040
|
-
|
|
20145
|
+
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
20146
|
+
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
20147
|
+
}
|
|
20148
|
+
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
20149
|
+
sessionId: state.sessionId,
|
|
20150
|
+
model: modelFromState(state)
|
|
20151
|
+
});
|
|
20152
|
+
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
20153
|
+
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
20154
|
+
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
20155
|
+
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
20156
|
+
}
|
|
20157
|
+
await transport.verifySessionCwd(cwd);
|
|
20158
|
+
return { ok: true };
|
|
20159
|
+
}
|
|
20041
20160
|
|
|
20042
20161
|
// dist/omp-permission-modes.js
|
|
20043
20162
|
var nativePermissionModes = /* @__PURE__ */ new Set(["always-ask", "write", "yolo"]);
|
|
@@ -20190,6 +20309,24 @@ var OmpSubagentLifecycle = class {
|
|
|
20190
20309
|
};
|
|
20191
20310
|
|
|
20192
20311
|
// dist/omp-adapter.js
|
|
20312
|
+
function closedInspection() {
|
|
20313
|
+
return {
|
|
20314
|
+
status: "unavailable",
|
|
20315
|
+
error: { code: "invalidState", message: "Omp Adapter is closed", retryable: false }
|
|
20316
|
+
};
|
|
20317
|
+
}
|
|
20318
|
+
function ompInspectionCapabilities(selectThinkingOption) {
|
|
20319
|
+
return {
|
|
20320
|
+
configuration: {
|
|
20321
|
+
selectModel: true,
|
|
20322
|
+
selectThinkingOption,
|
|
20323
|
+
selectPermissionMode: true,
|
|
20324
|
+
permissionModeScope: "live"
|
|
20325
|
+
},
|
|
20326
|
+
history: { fork: true, forkAcrossCwd: true, rollbackLastTurn: true },
|
|
20327
|
+
subagents: { observe: true, readTranscript: true }
|
|
20328
|
+
};
|
|
20329
|
+
}
|
|
20193
20330
|
var ompHarnessId2 = harnessIdSchema.parse("omp");
|
|
20194
20331
|
var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
20195
20332
|
commands: [
|
|
@@ -20204,7 +20341,7 @@ var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
|
20204
20341
|
]
|
|
20205
20342
|
});
|
|
20206
20343
|
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
20207
|
-
function
|
|
20344
|
+
function isRecord10(value) {
|
|
20208
20345
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20209
20346
|
}
|
|
20210
20347
|
function errorMessage(error51) {
|
|
@@ -20219,7 +20356,7 @@ var OmpAdapterFaultError = class extends Error {
|
|
|
20219
20356
|
}
|
|
20220
20357
|
};
|
|
20221
20358
|
function normalizedError(error51, fallbackCode) {
|
|
20222
|
-
if (
|
|
20359
|
+
if (isRecord10(error51) && error51.code === "ENOENT") {
|
|
20223
20360
|
return { code: "notInstalled", message: errorMessage(error51), retryable: false };
|
|
20224
20361
|
}
|
|
20225
20362
|
if (error51 instanceof OmpAdapterFaultError)
|
|
@@ -20296,7 +20433,7 @@ function nativeModelForHistory(state) {
|
|
|
20296
20433
|
return nativeModelFromState(state);
|
|
20297
20434
|
}
|
|
20298
20435
|
function sessionFileFromRef(ref) {
|
|
20299
|
-
if (ref.harnessId !== ompHarnessId2 || !
|
|
20436
|
+
if (ref.harnessId !== ompHarnessId2 || !isRecord10(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
|
|
20300
20437
|
throw new Error("Omp Native Session Ref has no resumable Session file");
|
|
20301
20438
|
}
|
|
20302
20439
|
return ref.locator.sessionFile;
|
|
@@ -20351,9 +20488,9 @@ function toolFailure(toolName) {
|
|
|
20351
20488
|
function nativeText(value) {
|
|
20352
20489
|
if (typeof value === "string")
|
|
20353
20490
|
return value;
|
|
20354
|
-
if (!
|
|
20491
|
+
if (!isRecord10(value) || !Array.isArray(value.content))
|
|
20355
20492
|
return "";
|
|
20356
|
-
return value.content.filter((content) =>
|
|
20493
|
+
return value.content.filter((content) => isRecord10(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
|
|
20357
20494
|
}
|
|
20358
20495
|
function boundedOutput(value, limit) {
|
|
20359
20496
|
const text = nativeText(value);
|
|
@@ -20369,17 +20506,17 @@ function outputText(output) {
|
|
|
20369
20506
|
return output?.content.filter((content) => content.type === "text").map(({ text }) => text).join("") ?? "";
|
|
20370
20507
|
}
|
|
20371
20508
|
function stringField2(value, key) {
|
|
20372
|
-
if (!
|
|
20509
|
+
if (!isRecord10(value))
|
|
20373
20510
|
return void 0;
|
|
20374
20511
|
const field = value[key];
|
|
20375
20512
|
if (typeof field === "string" && field.length > 0)
|
|
20376
20513
|
return field;
|
|
20377
|
-
if (
|
|
20514
|
+
if (isRecord10(value.input)) {
|
|
20378
20515
|
const nested = value.input[key];
|
|
20379
20516
|
if (typeof nested === "string" && nested.length > 0)
|
|
20380
20517
|
return nested;
|
|
20381
20518
|
}
|
|
20382
|
-
if (
|
|
20519
|
+
if (isRecord10(value.arguments)) {
|
|
20383
20520
|
const nested = value.arguments[key];
|
|
20384
20521
|
if (typeof nested === "string" && nested.length > 0)
|
|
20385
20522
|
return nested;
|
|
@@ -20387,7 +20524,7 @@ function stringField2(value, key) {
|
|
|
20387
20524
|
return void 0;
|
|
20388
20525
|
}
|
|
20389
20526
|
function numberField(value, key) {
|
|
20390
|
-
if (!
|
|
20527
|
+
if (!isRecord10(value))
|
|
20391
20528
|
return void 0;
|
|
20392
20529
|
const field = value[key];
|
|
20393
20530
|
return typeof field === "number" || field === null ? field : void 0;
|
|
@@ -20426,7 +20563,7 @@ function fileMutatingKind(toolName) {
|
|
|
20426
20563
|
return null;
|
|
20427
20564
|
}
|
|
20428
20565
|
function nestedToolString(value, keys) {
|
|
20429
|
-
if (!
|
|
20566
|
+
if (!isRecord10(value))
|
|
20430
20567
|
return void 0;
|
|
20431
20568
|
for (const key of keys) {
|
|
20432
20569
|
const field = value[key];
|
|
@@ -20441,14 +20578,14 @@ function nestedToolString(value, keys) {
|
|
|
20441
20578
|
return void 0;
|
|
20442
20579
|
}
|
|
20443
20580
|
function patchFromResult(result) {
|
|
20444
|
-
if (!
|
|
20581
|
+
if (!isRecord10(result))
|
|
20445
20582
|
return void 0;
|
|
20446
20583
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
20447
20584
|
const field = result[key];
|
|
20448
20585
|
if (typeof field === "string" && field.length > 0)
|
|
20449
20586
|
return field;
|
|
20450
20587
|
}
|
|
20451
|
-
if (
|
|
20588
|
+
if (isRecord10(result.details)) {
|
|
20452
20589
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
20453
20590
|
const field = result.details[key];
|
|
20454
20591
|
if (typeof field === "string" && field.length > 0)
|
|
@@ -22023,6 +22160,9 @@ var OmpAdapter = class {
|
|
|
22023
22160
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
22024
22161
|
#inspectionInFlight = /* @__PURE__ */ new Map();
|
|
22025
22162
|
#inspections = /* @__PURE__ */ new Set();
|
|
22163
|
+
#availabilityInFlight = /* @__PURE__ */ new Map();
|
|
22164
|
+
#availabilityListings = /* @__PURE__ */ new Set();
|
|
22165
|
+
#listModels;
|
|
22026
22166
|
#sessions = /* @__PURE__ */ new Set();
|
|
22027
22167
|
#toolOutputLimit;
|
|
22028
22168
|
#closePromise = null;
|
|
@@ -22031,22 +22171,21 @@ var OmpAdapter = class {
|
|
|
22031
22171
|
createTransport: (sessionOptions) => new OmpRpcSession({ ...options, ...sessionOptions })
|
|
22032
22172
|
}) {
|
|
22033
22173
|
this.#createTransport = dependencies.createTransport;
|
|
22174
|
+
const listModels = dependencies.listModels ?? listOmpModels;
|
|
22175
|
+
this.#listModels = ({ cwd, signal }) => listModels({
|
|
22176
|
+
cwd,
|
|
22177
|
+
signal,
|
|
22178
|
+
...options.command ? { command: options.command } : {},
|
|
22179
|
+
...options.environment ? { environment: options.environment } : {}
|
|
22180
|
+
});
|
|
22034
22181
|
this.sessionImport = new OmpSessionImport({ ...process.env, ...options.environment });
|
|
22035
22182
|
this.usageStatistics = createOmpUsageStatistics({ ...process.env, ...options.environment });
|
|
22036
22183
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? 2e3;
|
|
22037
22184
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT;
|
|
22038
22185
|
}
|
|
22039
22186
|
async inspect(input = {}) {
|
|
22040
|
-
if (this.#closePromise)
|
|
22041
|
-
return
|
|
22042
|
-
status: "unavailable",
|
|
22043
|
-
error: {
|
|
22044
|
-
code: "invalidState",
|
|
22045
|
-
message: "Omp Adapter is closed",
|
|
22046
|
-
retryable: false
|
|
22047
|
-
}
|
|
22048
|
-
};
|
|
22049
|
-
}
|
|
22187
|
+
if (this.#closePromise)
|
|
22188
|
+
return closedInspection();
|
|
22050
22189
|
const cwd = input.cwd ?? process.cwd();
|
|
22051
22190
|
const inFlight = this.#inspectionInFlight.get(cwd);
|
|
22052
22191
|
if (inFlight)
|
|
@@ -22056,6 +22195,37 @@ var OmpAdapter = class {
|
|
|
22056
22195
|
if (cached2)
|
|
22057
22196
|
return cached2;
|
|
22058
22197
|
}
|
|
22198
|
+
if (input.purpose === "availability")
|
|
22199
|
+
return this.#inspectAvailability(cwd, input.refresh);
|
|
22200
|
+
return this.#startFullInspection(cwd);
|
|
22201
|
+
}
|
|
22202
|
+
/**
|
|
22203
|
+
* Availability without a Session: a Session startup runs OMP's own startup work, including
|
|
22204
|
+
* Provider connection prewarm, for a Harness the user may never select. The listed result
|
|
22205
|
+
* carries no native default Model or Thinking option, so it is neither cached nor used to
|
|
22206
|
+
* update `#thinkingSelectionSupported`. When the list cannot answer, a full inspection answers
|
|
22207
|
+
* instead, reusing one that is in flight or finished meanwhile.
|
|
22208
|
+
*/
|
|
22209
|
+
async #inspectAvailability(cwd, refresh = false) {
|
|
22210
|
+
if (refresh)
|
|
22211
|
+
this.#inspectionCache.delete(cwd);
|
|
22212
|
+
let pending = this.#availabilityInFlight.get(cwd);
|
|
22213
|
+
if (!pending) {
|
|
22214
|
+
const listing = this.#listAvailability(cwd);
|
|
22215
|
+
pending = listing.finally(() => {
|
|
22216
|
+
if (this.#availabilityInFlight.get(cwd) === pending)
|
|
22217
|
+
this.#availabilityInFlight.delete(cwd);
|
|
22218
|
+
});
|
|
22219
|
+
this.#availabilityInFlight.set(cwd, pending);
|
|
22220
|
+
}
|
|
22221
|
+
const listed = await pending;
|
|
22222
|
+
if (listed)
|
|
22223
|
+
return listed;
|
|
22224
|
+
if (this.#closePromise)
|
|
22225
|
+
return closedInspection();
|
|
22226
|
+
return this.#inspectionInFlight.get(cwd) ?? this.#inspectionCache.get(cwd) ?? this.#startFullInspection(cwd);
|
|
22227
|
+
}
|
|
22228
|
+
#startFullInspection(cwd) {
|
|
22059
22229
|
const inspection = this.#inspectCwd(cwd).then((result) => {
|
|
22060
22230
|
if (result.status === "ready")
|
|
22061
22231
|
this.#inspectionCache.set(cwd, result);
|
|
@@ -22068,6 +22238,59 @@ var OmpAdapter = class {
|
|
|
22068
22238
|
}
|
|
22069
22239
|
});
|
|
22070
22240
|
}
|
|
22241
|
+
/** Returns null when a Session must answer: this OMP cannot list Models, or lists none. */
|
|
22242
|
+
async #listAvailability(cwd) {
|
|
22243
|
+
const startedAt = Date.now();
|
|
22244
|
+
const stage = "model-list";
|
|
22245
|
+
const controller = new AbortController();
|
|
22246
|
+
this.#availabilityListings.add(controller);
|
|
22247
|
+
let listed;
|
|
22248
|
+
try {
|
|
22249
|
+
listed = await this.#listModels({ cwd, signal: controller.signal });
|
|
22250
|
+
} finally {
|
|
22251
|
+
this.#availabilityListings.delete(controller);
|
|
22252
|
+
}
|
|
22253
|
+
if (listed.kind === "unanswered")
|
|
22254
|
+
return null;
|
|
22255
|
+
if (listed.kind === "notInstalled") {
|
|
22256
|
+
return {
|
|
22257
|
+
status: "notInstalled",
|
|
22258
|
+
error: {
|
|
22259
|
+
code: "notInstalled",
|
|
22260
|
+
message: listed.message,
|
|
22261
|
+
retryable: false,
|
|
22262
|
+
stage,
|
|
22263
|
+
durationMs: Date.now() - startedAt
|
|
22264
|
+
}
|
|
22265
|
+
};
|
|
22266
|
+
}
|
|
22267
|
+
if (listed.kind === "timedOut") {
|
|
22268
|
+
return {
|
|
22269
|
+
status: "error",
|
|
22270
|
+
error: {
|
|
22271
|
+
code: "unavailable",
|
|
22272
|
+
message: "Oh My Pi did not list its models in time",
|
|
22273
|
+
retryable: true,
|
|
22274
|
+
stage,
|
|
22275
|
+
durationMs: Date.now() - startedAt
|
|
22276
|
+
}
|
|
22277
|
+
};
|
|
22278
|
+
}
|
|
22279
|
+
if (listed.models.length === 0)
|
|
22280
|
+
return null;
|
|
22281
|
+
let catalog;
|
|
22282
|
+
try {
|
|
22283
|
+
catalog = normalizeOmpModelCatalog(listed.models, null, null, null);
|
|
22284
|
+
} catch {
|
|
22285
|
+
return null;
|
|
22286
|
+
}
|
|
22287
|
+
return {
|
|
22288
|
+
status: "ready",
|
|
22289
|
+
catalog,
|
|
22290
|
+
permissionModes: OMP_PERMISSION_MODE_CATALOG,
|
|
22291
|
+
capabilities: ompInspectionCapabilities(false)
|
|
22292
|
+
};
|
|
22293
|
+
}
|
|
22071
22294
|
async #inspectCwd(cwd) {
|
|
22072
22295
|
const startedAt = Date.now();
|
|
22073
22296
|
let stage = "spawn";
|
|
@@ -22091,16 +22314,7 @@ var OmpAdapter = class {
|
|
|
22091
22314
|
status: "ready",
|
|
22092
22315
|
catalog,
|
|
22093
22316
|
permissionModes: OMP_PERMISSION_MODE_CATALOG,
|
|
22094
|
-
capabilities:
|
|
22095
|
-
configuration: {
|
|
22096
|
-
selectModel: true,
|
|
22097
|
-
selectThinkingOption: thinkingLevels !== null,
|
|
22098
|
-
selectPermissionMode: true,
|
|
22099
|
-
permissionModeScope: "live"
|
|
22100
|
-
},
|
|
22101
|
-
history: { fork: true, forkAcrossCwd: true, rollbackLastTurn: true },
|
|
22102
|
-
subagents: { observe: true, readTranscript: true }
|
|
22103
|
-
}
|
|
22317
|
+
capabilities: ompInspectionCapabilities(thinkingLevels !== null)
|
|
22104
22318
|
};
|
|
22105
22319
|
} catch (error51) {
|
|
22106
22320
|
await transport.close().catch(() => void 0);
|
|
@@ -22311,6 +22525,8 @@ var OmpAdapter = class {
|
|
|
22311
22525
|
}
|
|
22312
22526
|
close() {
|
|
22313
22527
|
if (!this.#closePromise) {
|
|
22528
|
+
for (const listing of this.#availabilityListings)
|
|
22529
|
+
listing.abort();
|
|
22314
22530
|
this.#closePromise = Promise.all([
|
|
22315
22531
|
this.sessionImport.close(),
|
|
22316
22532
|
...[...this.#inspections].map((transport) => transport.close()),
|