@karlorz/codexhost-cli-win32-arm64 0.13.3-6 → 0.14.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +539 -95
- package/app/console-web.js +879 -73
- package/app/cpa-live-voice-hook.js +605 -37
- package/app/desktop-controller.mjs +94 -9
- package/app/host-runtime.mjs +1662 -642
- package/app/plugins/antigravity/plugin.mjs +113 -13
- package/app/plugins/claude-code/plugin.mjs +429 -26
- package/app/plugins/codebuddy/plugin.mjs +139 -22
- package/app/plugins/codex-usage/plugin.mjs +198 -74
- package/app/plugins/copilot/assets/icon.png +0 -0
- package/app/plugins/copilot/manifest.json +26 -0
- package/app/plugins/copilot/plugin.mjs +34645 -0
- package/app/plugins/cursor-cli/plugin.mjs +20877 -44973
- package/app/plugins/deepseek-harness/plugin.mjs +105 -11
- package/app/plugins/enabled.json +1 -0
- package/app/plugins/grok/plugin.mjs +1073 -214
- package/app/plugins/hermes/plugin.mjs +102 -9
- package/app/plugins/kimi-code/plugin.mjs +98 -7
- package/app/plugins/kiro-cli/plugin.mjs +98 -7
- package/app/plugins/omp/plugin.mjs +2177 -2000
- package/app/plugins/opencode/plugin.mjs +107 -11
- package/app/plugins/pi/plugin.mjs +2554 -2285
- package/app/plugins/qoder/plugin.mjs +105 -11
- package/app/plugins/qoder-cn/plugin.mjs +105 -11
- package/app/plugins/workbuddy/plugin.mjs +400 -46
- package/app/plugins/zcode/plugin.mjs +106 -11
- package/app/renderer-extension.js +2717 -1237
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/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;
|
|
@@ -15202,10 +15205,19 @@ var model = external_exports.string().min(1).max(512);
|
|
|
15202
15205
|
var project = external_exports.string().min(1).max(4096);
|
|
15203
15206
|
var usageStatisticsParamsSchema = external_exports.strictObject({
|
|
15204
15207
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
15208
|
+
/** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
|
|
15209
|
+
timeZone: external_exports.string().min(1).max(128).refine((value) => {
|
|
15210
|
+
try {
|
|
15211
|
+
new Intl.DateTimeFormat("en", { timeZone: value });
|
|
15212
|
+
return true;
|
|
15213
|
+
} catch {
|
|
15214
|
+
return false;
|
|
15215
|
+
}
|
|
15216
|
+
}, "Unsupported usage statistics timezone").optional(),
|
|
15205
15217
|
harness: harness.optional(),
|
|
15206
15218
|
model: model.nullable().optional(),
|
|
15207
15219
|
project: project.nullable().optional(),
|
|
15208
|
-
/** One
|
|
15220
|
+
/** One date in the query timezone inside the range. */
|
|
15209
15221
|
date: localDate.optional()
|
|
15210
15222
|
});
|
|
15211
15223
|
var usageStatisticsTotalsSchema = external_exports.strictObject({
|
|
@@ -15241,7 +15253,7 @@ var usageStatisticsSessionSchema = external_exports.strictObject({
|
|
|
15241
15253
|
});
|
|
15242
15254
|
var usageStatisticsResultSchema = external_exports.strictObject({
|
|
15243
15255
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
15244
|
-
/** First
|
|
15256
|
+
/** First date in the query timezone (Host local when omitted); null for all time. */
|
|
15245
15257
|
from: localDate.nullable(),
|
|
15246
15258
|
to: localDate,
|
|
15247
15259
|
/** The filters these figures apply, echoed so a late answer to older filters is recognised. */
|
|
@@ -15281,7 +15293,7 @@ var usageStatisticsResultSchema = external_exports.strictObject({
|
|
|
15281
15293
|
totals: usageStatisticsTotalsSchema,
|
|
15282
15294
|
/** Each date and Harness of the range: every filter except the day. */
|
|
15283
15295
|
daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
|
|
15284
|
-
/**
|
|
15296
|
+
/** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
|
|
15285
15297
|
hourly: external_exports.array(external_exports.strictObject({
|
|
15286
15298
|
weekday: external_exports.number().int().min(0).max(6),
|
|
15287
15299
|
hour: external_exports.number().int().min(0).max(23),
|
|
@@ -15372,8 +15384,12 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
15372
15384
|
"codexhost/harness/display-settings/set",
|
|
15373
15385
|
"codexhost/harness/inspect",
|
|
15374
15386
|
"codexhost/harness/installation",
|
|
15387
|
+
"codexhost/harness/installation/start",
|
|
15388
|
+
"codexhost/harness/installation/status",
|
|
15375
15389
|
"codexhost/harness/launch-settings/get",
|
|
15376
15390
|
"codexhost/harness/launch-settings/set",
|
|
15391
|
+
"codexhost/harness/grok-computer-use/get",
|
|
15392
|
+
"codexhost/harness/grok-computer-use/set",
|
|
15377
15393
|
"codexhost/harness/web-ui/open",
|
|
15378
15394
|
"codexhost/harness/accounts/sources",
|
|
15379
15395
|
"codexhost/harness/accounts/list",
|
|
@@ -15447,7 +15463,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
|
|
|
15447
15463
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
15448
15464
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
15449
15465
|
var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
15466
|
+
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
|
|
15467
|
+
var composerIndicatorsSchema = external_exports.array(external_exports.object({
|
|
15468
|
+
kind: external_exports.literal("countdown"),
|
|
15469
|
+
id: external_exports.string().min(1).max(64),
|
|
15470
|
+
expiresAtUnix: nonNegativeSafeIntegerSchema,
|
|
15471
|
+
label: indicatorTextSchema(256).optional(),
|
|
15472
|
+
tooltip: indicatorTextSchema(1024).optional()
|
|
15473
|
+
}).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
|
|
15474
|
+
message: "Composer indicator IDs must be unique"
|
|
15475
|
+
});
|
|
15450
15476
|
var threadUsageSnapshotSchema = external_exports.object({
|
|
15477
|
+
composerIndicators: composerIndicatorsSchema.optional(),
|
|
15451
15478
|
inputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15452
15479
|
cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15453
15480
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15855,7 +15882,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
|
|
|
15855
15882
|
}).strict().optional(),
|
|
15856
15883
|
autonomousTurns: external_exports.object({
|
|
15857
15884
|
observe: external_exports.boolean()
|
|
15858
|
-
}).strict().optional()
|
|
15885
|
+
}).strict().optional(),
|
|
15886
|
+
/** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
|
|
15887
|
+
steer: external_exports.boolean().optional()
|
|
15859
15888
|
}).strict();
|
|
15860
15889
|
var harnessConfigurationStateSchema = external_exports.object({
|
|
15861
15890
|
effectiveModel: harnessModelRefSchema.optional(),
|
|
@@ -15902,7 +15931,9 @@ var harnessInspectionSchema = external_exports.union([
|
|
|
15902
15931
|
var harnessInspectParamsSchema = external_exports.object({
|
|
15903
15932
|
harnessId: harnessIdSchema,
|
|
15904
15933
|
cwd: nonBlankTextSchema2.max(16384).optional(),
|
|
15905
|
-
refresh: external_exports.boolean().optional()
|
|
15934
|
+
refresh: external_exports.boolean().optional(),
|
|
15935
|
+
/** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
|
|
15936
|
+
purpose: external_exports.literal("availability").optional()
|
|
15906
15937
|
}).strict();
|
|
15907
15938
|
var harnessWebUiOpenParamsSchema = external_exports.object({
|
|
15908
15939
|
harnessId: harnessIdSchema
|
|
@@ -15985,6 +16016,15 @@ var threadOwnershipListResultSchema = external_exports.object({
|
|
|
15985
16016
|
seen.add(thread.threadId);
|
|
15986
16017
|
}
|
|
15987
16018
|
});
|
|
16019
|
+
var threadSteeringInspectParamsSchema = external_exports.object({
|
|
16020
|
+
threadId: hostThreadIdSchema,
|
|
16021
|
+
/** The text about to be steered; a Harness command always stops and restarts. */
|
|
16022
|
+
text: external_exports.string().optional()
|
|
16023
|
+
}).strict();
|
|
16024
|
+
var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
|
|
16025
|
+
var threadSteeringInspectResultSchema = external_exports.object({
|
|
16026
|
+
delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
|
|
16027
|
+
}).strict();
|
|
15988
16028
|
|
|
15989
16029
|
// ../../shared-contracts/dist/harness-plugins.js
|
|
15990
16030
|
var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
|
|
@@ -16076,6 +16116,26 @@ var harnessLaunchSettingsSchema = external_exports.object({
|
|
|
16076
16116
|
restartRequired: external_exports.boolean()
|
|
16077
16117
|
}).strict();
|
|
16078
16118
|
|
|
16119
|
+
// ../../shared-contracts/dist/grok-computer-use.js
|
|
16120
|
+
var grokComputerUseGetSchema = external_exports.object({}).strict();
|
|
16121
|
+
var grokComputerUseSetSchema = external_exports.object({
|
|
16122
|
+
enabled: external_exports.boolean().optional(),
|
|
16123
|
+
browser: external_exports.boolean().optional()
|
|
16124
|
+
}).strict().refine((value) => value.enabled !== void 0 || value.browser !== void 0, {
|
|
16125
|
+
message: "Expected enabled or browser"
|
|
16126
|
+
});
|
|
16127
|
+
var grokComputerUseSettingsSchema = external_exports.object({
|
|
16128
|
+
enabled: external_exports.boolean(),
|
|
16129
|
+
available: external_exports.boolean(),
|
|
16130
|
+
unavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
16131
|
+
browser: external_exports.boolean().optional(),
|
|
16132
|
+
browserFilesPresent: external_exports.boolean().optional(),
|
|
16133
|
+
browserAvailable: external_exports.boolean().optional(),
|
|
16134
|
+
browserUnavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
16135
|
+
applyFailed: external_exports.boolean().optional(),
|
|
16136
|
+
applyError: external_exports.string().min(1).max(500).optional()
|
|
16137
|
+
}).strict();
|
|
16138
|
+
|
|
16079
16139
|
// ../../shared-contracts/dist/harness-installation.js
|
|
16080
16140
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
16081
16141
|
harnessId: harnessIdSchema,
|
|
@@ -16086,6 +16146,10 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
16086
16146
|
latestVersion: external_exports.string().min(1).max(128),
|
|
16087
16147
|
updateAvailable: external_exports.boolean(),
|
|
16088
16148
|
canUpdate: external_exports.boolean(),
|
|
16149
|
+
/** Defaults to CLI; some Harnesses ship only inside a desktop application. */
|
|
16150
|
+
versionKind: external_exports.enum(["cli", "application"]).optional(),
|
|
16151
|
+
/** Official download opened by the user; does not imply an automatic installation. */
|
|
16152
|
+
manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
|
|
16089
16153
|
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
16090
16154
|
message: external_exports.string().max(2048).optional(),
|
|
16091
16155
|
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
@@ -16093,6 +16157,20 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
16093
16157
|
notice: harnessLocalizedTextSchema.optional(),
|
|
16094
16158
|
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
16095
16159
|
}).strict();
|
|
16160
|
+
var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
|
|
16161
|
+
var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
|
|
16162
|
+
external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
|
|
16163
|
+
external_exports.object({
|
|
16164
|
+
taskId: external_exports.string().uuid(),
|
|
16165
|
+
status: external_exports.literal("succeeded"),
|
|
16166
|
+
result: harnessInstallationStateSchema
|
|
16167
|
+
}).strict(),
|
|
16168
|
+
external_exports.object({
|
|
16169
|
+
taskId: external_exports.string().uuid(),
|
|
16170
|
+
status: external_exports.literal("failed"),
|
|
16171
|
+
error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
|
|
16172
|
+
}).strict()
|
|
16173
|
+
]);
|
|
16096
16174
|
|
|
16097
16175
|
// ../../shared-contracts/dist/codex-accounts.js
|
|
16098
16176
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
@@ -16940,6 +17018,18 @@ function sanitizeDiagnosticTail(value) {
|
|
|
16940
17018
|
return redacted.length <= DIAGNOSTIC_TAIL_MAX_LENGTH ? redacted : redacted.slice(-DIAGNOSTIC_TAIL_MAX_LENGTH);
|
|
16941
17019
|
}
|
|
16942
17020
|
|
|
17021
|
+
// ../../harness-adapter/dist/steer.js
|
|
17022
|
+
function unsupportedSteer(harnessLabel) {
|
|
17023
|
+
return {
|
|
17024
|
+
ok: false,
|
|
17025
|
+
error: {
|
|
17026
|
+
code: "unsupported",
|
|
17027
|
+
message: `${harnessLabel} cannot steer an active Turn natively`,
|
|
17028
|
+
retryable: false
|
|
17029
|
+
}
|
|
17030
|
+
};
|
|
17031
|
+
}
|
|
17032
|
+
|
|
16943
17033
|
// ../../harness-adapter/dist/usage.js
|
|
16944
17034
|
var tokenFields = [
|
|
16945
17035
|
"inputTokens",
|
|
@@ -16967,6 +17057,7 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
16967
17057
|
...safeIntegerFields,
|
|
16968
17058
|
...percentFields,
|
|
16969
17059
|
"sessionCacheUsage",
|
|
17060
|
+
"composerIndicators",
|
|
16970
17061
|
"totalCostUsd",
|
|
16971
17062
|
"totalCredits",
|
|
16972
17063
|
"contextUsagePercent",
|
|
@@ -16989,6 +17080,7 @@ function parseHostUsage(value) {
|
|
|
16989
17080
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
16990
17081
|
}
|
|
16991
17082
|
}
|
|
17083
|
+
const indicators = value.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value.composerIndicators) };
|
|
16992
17084
|
for (const field of [
|
|
16993
17085
|
"totalCredits",
|
|
16994
17086
|
"contextUsagePercent",
|
|
@@ -17059,9 +17151,9 @@ function parseHostUsage(value) {
|
|
|
17059
17151
|
if (value.costSource !== "publicPrice") {
|
|
17060
17152
|
throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
|
|
17061
17153
|
}
|
|
17062
|
-
return { ...value, unpricedModels: [...models] };
|
|
17154
|
+
return { ...value, ...indicators, unpricedModels: [...models] };
|
|
17063
17155
|
}
|
|
17064
|
-
return { ...value };
|
|
17156
|
+
return { ...value, ...indicators };
|
|
17065
17157
|
}
|
|
17066
17158
|
var requestTokenFields = [
|
|
17067
17159
|
"inputTokens",
|
|
@@ -17788,857 +17880,283 @@ function createOmpUsageStatistics(environment) {
|
|
|
17788
17880
|
});
|
|
17789
17881
|
}
|
|
17790
17882
|
|
|
17791
|
-
//
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
|
|
17799
|
-
|
|
17800
|
-
|
|
17801
|
-
|
|
17802
|
-
|
|
17803
|
-
|
|
17804
|
-
|
|
17805
|
-
|
|
17883
|
+
// dist/omp-model-list.js
|
|
17884
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
17885
|
+
|
|
17886
|
+
// dist/command.js
|
|
17887
|
+
var ompDiscoverySpec = {
|
|
17888
|
+
id: "omp",
|
|
17889
|
+
command: "omp",
|
|
17890
|
+
commandEnvironmentVariable: "OMP_COMMAND",
|
|
17891
|
+
installRoots: {
|
|
17892
|
+
posix: [
|
|
17893
|
+
"~/.npm-global/bin",
|
|
17894
|
+
"~/.local/bin",
|
|
17895
|
+
VERSION_MANAGER_ROOTS,
|
|
17896
|
+
"/opt/homebrew/bin",
|
|
17897
|
+
"/usr/local/bin"
|
|
17898
|
+
],
|
|
17899
|
+
windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS]
|
|
17806
17900
|
}
|
|
17807
|
-
|
|
17808
|
-
|
|
17809
|
-
|
|
17810
|
-
|
|
17811
|
-
|
|
17812
|
-
|
|
17813
|
-
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
|
|
17901
|
+
};
|
|
17902
|
+
function resolveOmpExecutable(input, dependencies = {}) {
|
|
17903
|
+
const resolution = resolveHarnessExecutable(ompDiscoverySpec, {
|
|
17904
|
+
...input.command ? { command: input.command } : {},
|
|
17905
|
+
environment: input.environment,
|
|
17906
|
+
...dependencies.platform ? { platform: dependencies.platform } : {},
|
|
17907
|
+
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {}
|
|
17908
|
+
}, { ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {} });
|
|
17909
|
+
return resolution?.executable ?? input.command ?? input.environment.OMP_COMMAND ?? "omp";
|
|
17910
|
+
}
|
|
17911
|
+
|
|
17912
|
+
// dist/omp-rpc-session.js
|
|
17913
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
17914
|
+
import { randomUUID } from "node:crypto";
|
|
17915
|
+
import path6 from "node:path";
|
|
17916
|
+
|
|
17917
|
+
// dist/omp-slash-commands.js
|
|
17918
|
+
var OMP_LIVE_COMMAND_ID_PREFIX = "omp.slash.";
|
|
17919
|
+
function isRecord6(value) {
|
|
17920
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17921
|
+
}
|
|
17922
|
+
function parseOmpAvailableCommands(value) {
|
|
17923
|
+
if (!Array.isArray(value))
|
|
17924
|
+
return [];
|
|
17925
|
+
return value.flatMap((entry) => {
|
|
17926
|
+
if (!isRecord6(entry))
|
|
17927
|
+
return [];
|
|
17928
|
+
const name = typeof entry.name === "string" ? entry.name.trim().replace(/^\//u, "") : "";
|
|
17929
|
+
if (!name)
|
|
17930
|
+
return [];
|
|
17931
|
+
return [
|
|
17932
|
+
{
|
|
17933
|
+
name,
|
|
17934
|
+
description: typeof entry.description === "string" ? entry.description : "",
|
|
17935
|
+
source: typeof entry.source === "string" ? entry.source : null
|
|
17818
17936
|
}
|
|
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
|
-
}
|
|
17937
|
+
];
|
|
17938
|
+
});
|
|
17939
|
+
}
|
|
17940
|
+
function ompLiveCommands(native) {
|
|
17941
|
+
return native.filter(({ source, name }) => source !== "builtin" || name === "context").map((command) => ({
|
|
17942
|
+
name: command.name,
|
|
17943
|
+
description: command.description,
|
|
17944
|
+
kind: command.source === "skill" ? "skill" : "command"
|
|
17945
|
+
}));
|
|
17946
|
+
}
|
|
17947
|
+
|
|
17948
|
+
// dist/omp-session-file.js
|
|
17949
|
+
import { createReadStream as createReadStream3 } from "node:fs";
|
|
17950
|
+
import { open, realpath as realpath2 } from "node:fs/promises";
|
|
17951
|
+
import readline from "node:readline";
|
|
17952
|
+
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
17953
|
+
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
17954
|
+
function isRecord7(value) {
|
|
17955
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17956
|
+
}
|
|
17957
|
+
function historyEntry(value) {
|
|
17958
|
+
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") {
|
|
17959
|
+
return null;
|
|
17960
|
+
}
|
|
17961
|
+
return value;
|
|
17962
|
+
}
|
|
17963
|
+
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
17964
|
+
const entries = [];
|
|
17965
|
+
let leafId = null;
|
|
17966
|
+
let incomplete = false;
|
|
17967
|
+
const lines = readline.createInterface({
|
|
17968
|
+
input: createReadStream3(sessionFile, {
|
|
17969
|
+
encoding: "utf8",
|
|
17970
|
+
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
17971
|
+
}),
|
|
17972
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
17973
|
+
});
|
|
17974
|
+
try {
|
|
17975
|
+
for await (const line of lines) {
|
|
17976
|
+
if (line.length === 0)
|
|
17977
|
+
continue;
|
|
17978
|
+
let parsed;
|
|
17979
|
+
try {
|
|
17980
|
+
parsed = JSON.parse(line);
|
|
17981
|
+
} catch {
|
|
17982
|
+
incomplete = true;
|
|
17983
|
+
continue;
|
|
17868
17984
|
}
|
|
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;
|
|
17985
|
+
const entry = historyEntry(parsed);
|
|
17986
|
+
if (!entry) {
|
|
17987
|
+
if (!isRecord7(parsed) || parsed.type !== "title" && parsed.type !== "session") {
|
|
17988
|
+
incomplete = true;
|
|
17887
17989
|
}
|
|
17990
|
+
continue;
|
|
17888
17991
|
}
|
|
17992
|
+
entries.push(entry);
|
|
17993
|
+
leafId = entry.id;
|
|
17889
17994
|
}
|
|
17995
|
+
} finally {
|
|
17996
|
+
lines.close();
|
|
17890
17997
|
}
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
};
|
|
17998
|
+
return { entries, leafId, ...incomplete ? { incomplete: true } : {} };
|
|
17999
|
+
}
|
|
18000
|
+
async function readOmpSessionHeader(sessionFile) {
|
|
18001
|
+
const handle = await open(sessionFile, "r");
|
|
18002
|
+
try {
|
|
18003
|
+
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
18004
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
18005
|
+
const contents = buffer.subarray(0, bytesRead);
|
|
18006
|
+
const newline = contents.indexOf(10);
|
|
18007
|
+
if (newline < 0 && bytesRead === buffer.length) {
|
|
18008
|
+
throw new Error("Omp Session header exceeds the supported size");
|
|
17903
18009
|
}
|
|
17904
|
-
|
|
17905
|
-
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
|
|
17913
|
-
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
18010
|
+
const contentsText = utf8Decoder.decode(contents);
|
|
18011
|
+
for (const line of contentsText.split("\n")) {
|
|
18012
|
+
if (line.length === 0)
|
|
18013
|
+
continue;
|
|
18014
|
+
let parsed;
|
|
18015
|
+
try {
|
|
18016
|
+
parsed = JSON.parse(line);
|
|
18017
|
+
} catch {
|
|
18018
|
+
continue;
|
|
17914
18019
|
}
|
|
17915
|
-
|
|
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]);
|
|
18020
|
+
if (!isRecord7(parsed) || parsed.type !== "session")
|
|
18021
|
+
continue;
|
|
18022
|
+
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
18023
|
+
throw new Error("Omp Session header is invalid");
|
|
17934
18024
|
}
|
|
18025
|
+
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
17935
18026
|
}
|
|
17936
|
-
|
|
17937
|
-
}
|
|
17938
|
-
|
|
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("");
|
|
18027
|
+
throw new Error("Omp Session header is invalid");
|
|
18028
|
+
} finally {
|
|
18029
|
+
await handle.close();
|
|
17948
18030
|
}
|
|
17949
|
-
|
|
17950
|
-
|
|
18031
|
+
}
|
|
18032
|
+
async function verifyOmpSessionCwd(input) {
|
|
18033
|
+
if (!input.sessionFile)
|
|
18034
|
+
throw new Error("Omp Fork Session has no persisted Session file");
|
|
18035
|
+
const header = await readOmpSessionHeader(input.sessionFile);
|
|
18036
|
+
if (header.id !== input.sessionId) {
|
|
18037
|
+
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
17951
18038
|
}
|
|
17952
|
-
|
|
17953
|
-
|
|
18039
|
+
const [actualCwd, expectedCwd] = await Promise.all([
|
|
18040
|
+
realpath2(header.cwd),
|
|
18041
|
+
realpath2(input.expectedCwd)
|
|
18042
|
+
]);
|
|
18043
|
+
if (actualCwd !== expectedCwd) {
|
|
18044
|
+
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
17954
18045
|
}
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
|
|
17958
|
-
|
|
17959
|
-
|
|
17960
|
-
|
|
17961
|
-
|
|
17962
|
-
|
|
18046
|
+
}
|
|
18047
|
+
|
|
18048
|
+
// dist/omp-protocol.js
|
|
18049
|
+
var MAX_FRAME_BYTES = 1024 * 1024;
|
|
18050
|
+
var MAX_REASSEMBLED_BYTES = 64 * 1024 * 1024;
|
|
18051
|
+
var MAX_CHUNK_BYTES = 256 * 1024;
|
|
18052
|
+
function isObject2(value) {
|
|
18053
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18054
|
+
}
|
|
18055
|
+
var OmpFrameDecoder = class {
|
|
18056
|
+
#pending = null;
|
|
18057
|
+
push(value) {
|
|
18058
|
+
if (!isObject2(value))
|
|
18059
|
+
throw new Error("OMP RPC frame must be a JSON object");
|
|
18060
|
+
if (value.type !== "rpc_chunk") {
|
|
18061
|
+
if (this.#pending)
|
|
18062
|
+
throw new Error("OMP RPC chunk sequence was interrupted");
|
|
18063
|
+
return value;
|
|
17963
18064
|
}
|
|
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
|
-
}
|
|
18065
|
+
const chunkId = value.chunkId;
|
|
18066
|
+
const index = value.index;
|
|
18067
|
+
const count2 = value.count;
|
|
18068
|
+
const byteLength = value.byteLength;
|
|
18069
|
+
const data = value.data;
|
|
18070
|
+
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)
|
|
18071
|
+
throw new Error("Invalid OMP RPC chunk metadata");
|
|
18072
|
+
let bytes;
|
|
18073
|
+
try {
|
|
18074
|
+
bytes = Buffer.from(data, "base64");
|
|
18075
|
+
} catch {
|
|
18076
|
+
throw new Error("Invalid OMP RPC chunk data");
|
|
17988
18077
|
}
|
|
17989
|
-
|
|
18078
|
+
if (bytes.length === 0 || bytes.length > MAX_CHUNK_BYTES || bytes.toString("base64") !== data) {
|
|
18079
|
+
throw new Error("Invalid OMP RPC chunk data");
|
|
18080
|
+
}
|
|
18081
|
+
const chunkIndex = index;
|
|
18082
|
+
const chunkCount = count2;
|
|
18083
|
+
const declaredByteLength = byteLength;
|
|
18084
|
+
if (!this.#pending) {
|
|
18085
|
+
if (chunkIndex !== 0)
|
|
18086
|
+
throw new Error("OMP RPC chunk sequence must start at index 0");
|
|
18087
|
+
this.#pending = {
|
|
18088
|
+
chunkId,
|
|
18089
|
+
count: chunkCount,
|
|
18090
|
+
byteLength: declaredByteLength,
|
|
18091
|
+
nextIndex: 0,
|
|
18092
|
+
chunks: [],
|
|
18093
|
+
received: 0
|
|
18094
|
+
};
|
|
18095
|
+
}
|
|
18096
|
+
const pending = this.#pending;
|
|
18097
|
+
if (!pending)
|
|
18098
|
+
throw new Error("OMP RPC chunk state was lost");
|
|
18099
|
+
if (pending.chunkId !== chunkId || pending.count !== chunkCount || pending.byteLength !== declaredByteLength || pending.nextIndex !== chunkIndex) {
|
|
18100
|
+
throw new Error("OMP RPC chunk sequence mismatch");
|
|
18101
|
+
}
|
|
18102
|
+
pending.chunks.push(bytes);
|
|
18103
|
+
pending.received += bytes.length;
|
|
18104
|
+
pending.nextIndex += 1;
|
|
18105
|
+
if (pending.received > pending.byteLength)
|
|
18106
|
+
throw new Error("OMP RPC chunk sequence exceeds its declared length");
|
|
18107
|
+
if (pending.nextIndex < pending.count)
|
|
18108
|
+
return null;
|
|
18109
|
+
if (pending.received !== pending.byteLength)
|
|
18110
|
+
throw new Error("OMP RPC chunk sequence length mismatch");
|
|
18111
|
+
this.#pending = null;
|
|
18112
|
+
let decoded;
|
|
18113
|
+
try {
|
|
18114
|
+
decoded = JSON.parse(Buffer.concat(pending.chunks).toString("utf8"));
|
|
18115
|
+
} catch {
|
|
18116
|
+
throw new Error("Failed to decode reassembled OMP RPC frame");
|
|
18117
|
+
}
|
|
18118
|
+
if (!isObject2(decoded))
|
|
18119
|
+
throw new Error("Reassembled OMP RPC frame must be an object");
|
|
18120
|
+
return decoded;
|
|
17990
18121
|
}
|
|
17991
18122
|
};
|
|
17992
18123
|
|
|
17993
|
-
//
|
|
17994
|
-
var
|
|
17995
|
-
|
|
17996
|
-
|
|
17997
|
-
|
|
18124
|
+
// dist/omp-rpc-session.js
|
|
18125
|
+
var OmpRpcFaultError = class extends Error {
|
|
18126
|
+
kind;
|
|
18127
|
+
diagnostic;
|
|
18128
|
+
constructor(kind, message3, diagnostic) {
|
|
18129
|
+
super(message3);
|
|
18130
|
+
this.kind = kind;
|
|
18131
|
+
this.diagnostic = diagnostic;
|
|
18132
|
+
this.name = "OmpRpcFaultError";
|
|
17998
18133
|
}
|
|
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);
|
|
18134
|
+
};
|
|
18135
|
+
var OmpRpcUnsupportedCommandError = class extends Error {
|
|
18136
|
+
command;
|
|
18137
|
+
constructor(command) {
|
|
18138
|
+
super(`Omp RPC does not support '${command}'`);
|
|
18139
|
+
this.command = command;
|
|
18140
|
+
this.name = "OmpRpcUnsupportedCommandError";
|
|
18016
18141
|
}
|
|
18017
18142
|
};
|
|
18018
|
-
var
|
|
18019
|
-
function
|
|
18020
|
-
return
|
|
18143
|
+
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
18144
|
+
function isRecord8(value) {
|
|
18145
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18021
18146
|
}
|
|
18022
|
-
function
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
retLines[retLines.length - 1] += line;
|
|
18034
|
-
} else {
|
|
18035
|
-
retLines.push(line);
|
|
18036
|
-
}
|
|
18147
|
+
function message2(value) {
|
|
18148
|
+
return value instanceof Error ? value.message : String(value);
|
|
18149
|
+
}
|
|
18150
|
+
function nonBlankString(value) {
|
|
18151
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
18152
|
+
}
|
|
18153
|
+
function parseNativeModel(value, context) {
|
|
18154
|
+
if (value === null || value === void 0)
|
|
18155
|
+
return null;
|
|
18156
|
+
if (!isRecord8(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
18157
|
+
throw new OmpRpcFaultError("protocolError", `Omp RPC returned an invalid ${context} Model`);
|
|
18037
18158
|
}
|
|
18038
|
-
return
|
|
18039
|
-
}
|
|
18040
|
-
|
|
18041
|
-
// ../../../node_modules/diff/libesm/patch/parse.js
|
|
18042
|
-
function parsePatch(uniDiff) {
|
|
18043
|
-
const diffstr = uniDiff.split(/\n/), list = [];
|
|
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
|
-
}
|
|
18074
|
-
}
|
|
18075
|
-
function parseFileHeader(index) {
|
|
18076
|
-
const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
|
|
18077
|
-
if (fileHeader) {
|
|
18078
|
-
const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
|
|
18079
|
-
let fileName = data[0].replace(/\\\\/g, "\\");
|
|
18080
|
-
if (/^".*"$/.test(fileName)) {
|
|
18081
|
-
fileName = fileName.substr(1, fileName.length - 2);
|
|
18082
|
-
}
|
|
18083
|
-
if (fileHeader[1] === "---") {
|
|
18084
|
-
index.oldFileName = fileName;
|
|
18085
|
-
index.oldHeader = header;
|
|
18086
|
-
} else {
|
|
18087
|
-
index.newFileName = fileName;
|
|
18088
|
-
index.newHeader = header;
|
|
18089
|
-
}
|
|
18090
|
-
i++;
|
|
18091
|
-
}
|
|
18092
|
-
}
|
|
18093
|
-
function parseHunk() {
|
|
18094
|
-
var _a3;
|
|
18095
|
-
const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
|
18096
|
-
const hunk = {
|
|
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));
|
|
18137
|
-
}
|
|
18138
|
-
return hunk;
|
|
18139
|
-
}
|
|
18140
|
-
while (i < diffstr.length) {
|
|
18141
|
-
parseIndex();
|
|
18142
|
-
}
|
|
18143
|
-
return list;
|
|
18144
|
-
}
|
|
18145
|
-
|
|
18146
|
-
// ../../../node_modules/diff/libesm/patch/create.js
|
|
18147
|
-
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
18148
|
-
let optionsObj;
|
|
18149
|
-
if (!options) {
|
|
18150
|
-
optionsObj = {};
|
|
18151
|
-
} else if (typeof options === "function") {
|
|
18152
|
-
optionsObj = { callback: options };
|
|
18153
|
-
} else {
|
|
18154
|
-
optionsObj = options;
|
|
18155
|
-
}
|
|
18156
|
-
if (typeof optionsObj.context === "undefined") {
|
|
18157
|
-
optionsObj.context = 4;
|
|
18158
|
-
}
|
|
18159
|
-
const context = optionsObj.context;
|
|
18160
|
-
if (optionsObj.newlineIsToken) {
|
|
18161
|
-
throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
|
|
18162
|
-
}
|
|
18163
|
-
if (!optionsObj.callback) {
|
|
18164
|
-
return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
|
|
18165
|
-
} else {
|
|
18166
|
-
const { callback } = optionsObj;
|
|
18167
|
-
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
|
18168
|
-
const patch = diffLinesResultToPatch(diff);
|
|
18169
|
-
callback(patch);
|
|
18170
|
-
} }));
|
|
18171
|
-
}
|
|
18172
|
-
function diffLinesResultToPatch(diff) {
|
|
18173
|
-
if (!diff) {
|
|
18174
|
-
return;
|
|
18175
|
-
}
|
|
18176
|
-
diff.push({ value: "", lines: [] });
|
|
18177
|
-
function contextLines(lines) {
|
|
18178
|
-
return lines.map(function(entry) {
|
|
18179
|
-
return " " + entry;
|
|
18180
|
-
});
|
|
18181
|
-
}
|
|
18182
|
-
const hunks = [];
|
|
18183
|
-
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
|
18184
|
-
for (let i = 0; i < diff.length; i++) {
|
|
18185
|
-
const current = diff[i], lines = current.lines || splitLines(current.value);
|
|
18186
|
-
current.lines = lines;
|
|
18187
|
-
if (current.added || current.removed) {
|
|
18188
|
-
if (!oldRangeStart) {
|
|
18189
|
-
const prev = diff[i - 1];
|
|
18190
|
-
oldRangeStart = oldLine;
|
|
18191
|
-
newRangeStart = newLine;
|
|
18192
|
-
if (prev) {
|
|
18193
|
-
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
|
|
18194
|
-
oldRangeStart -= curRange.length;
|
|
18195
|
-
newRangeStart -= curRange.length;
|
|
18196
|
-
}
|
|
18197
|
-
}
|
|
18198
|
-
for (const line of lines) {
|
|
18199
|
-
curRange.push((current.added ? "+" : "-") + line);
|
|
18200
|
-
}
|
|
18201
|
-
if (current.added) {
|
|
18202
|
-
newLine += lines.length;
|
|
18203
|
-
} else {
|
|
18204
|
-
oldLine += lines.length;
|
|
18205
|
-
}
|
|
18206
|
-
} else {
|
|
18207
|
-
if (oldRangeStart) {
|
|
18208
|
-
if (lines.length <= context * 2 && i < diff.length - 2) {
|
|
18209
|
-
for (const line of contextLines(lines)) {
|
|
18210
|
-
curRange.push(line);
|
|
18211
|
-
}
|
|
18212
|
-
} else {
|
|
18213
|
-
const contextSize = Math.min(lines.length, context);
|
|
18214
|
-
for (const line of contextLines(lines.slice(0, contextSize))) {
|
|
18215
|
-
curRange.push(line);
|
|
18216
|
-
}
|
|
18217
|
-
const hunk = {
|
|
18218
|
-
oldStart: oldRangeStart,
|
|
18219
|
-
oldLines: oldLine - oldRangeStart + contextSize,
|
|
18220
|
-
newStart: newRangeStart,
|
|
18221
|
-
newLines: newLine - newRangeStart + contextSize,
|
|
18222
|
-
lines: curRange
|
|
18223
|
-
};
|
|
18224
|
-
hunks.push(hunk);
|
|
18225
|
-
oldRangeStart = 0;
|
|
18226
|
-
newRangeStart = 0;
|
|
18227
|
-
curRange = [];
|
|
18228
|
-
}
|
|
18229
|
-
}
|
|
18230
|
-
oldLine += lines.length;
|
|
18231
|
-
newLine += lines.length;
|
|
18232
|
-
}
|
|
18233
|
-
}
|
|
18234
|
-
for (const hunk of hunks) {
|
|
18235
|
-
for (let i = 0; i < hunk.lines.length; i++) {
|
|
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
|
-
}
|
|
18243
|
-
}
|
|
18244
|
-
return {
|
|
18245
|
-
oldFileName,
|
|
18246
|
-
newFileName,
|
|
18247
|
-
oldHeader,
|
|
18248
|
-
newHeader,
|
|
18249
|
-
hunks
|
|
18250
|
-
};
|
|
18251
|
-
}
|
|
18252
|
-
}
|
|
18253
|
-
function formatPatch(patch) {
|
|
18254
|
-
if (Array.isArray(patch)) {
|
|
18255
|
-
return patch.map(formatPatch).join("\n");
|
|
18256
|
-
}
|
|
18257
|
-
const ret = [];
|
|
18258
|
-
if (patch.oldFileName == patch.newFileName) {
|
|
18259
|
-
ret.push("Index: " + patch.oldFileName);
|
|
18260
|
-
}
|
|
18261
|
-
ret.push("===================================================================");
|
|
18262
|
-
ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
|
|
18263
|
-
ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
|
|
18264
|
-
for (let i = 0; i < patch.hunks.length; i++) {
|
|
18265
|
-
const hunk = patch.hunks[i];
|
|
18266
|
-
if (hunk.oldLines === 0) {
|
|
18267
|
-
hunk.oldStart -= 1;
|
|
18268
|
-
}
|
|
18269
|
-
if (hunk.newLines === 0) {
|
|
18270
|
-
hunk.newStart -= 1;
|
|
18271
|
-
}
|
|
18272
|
-
ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
|
|
18273
|
-
for (const line of hunk.lines) {
|
|
18274
|
-
ret.push(line);
|
|
18275
|
-
}
|
|
18276
|
-
}
|
|
18277
|
-
return ret.join("\n") + "\n";
|
|
18278
|
-
}
|
|
18279
|
-
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
18280
|
-
if (typeof options === "function") {
|
|
18281
|
-
options = { callback: options };
|
|
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;
|
|
18287
|
-
}
|
|
18288
|
-
return formatPatch(patchObj);
|
|
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));
|
|
18307
|
-
}
|
|
18308
|
-
return result;
|
|
18309
|
-
}
|
|
18310
|
-
|
|
18311
|
-
// dist/omp-adapter.js
|
|
18312
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
18313
|
-
import { realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
18314
|
-
import path7 from "node:path";
|
|
18315
|
-
|
|
18316
|
-
// dist/omp-slash-commands.js
|
|
18317
|
-
var OMP_LIVE_COMMAND_ID_PREFIX = "omp.slash.";
|
|
18318
|
-
function isRecord6(value) {
|
|
18319
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18320
|
-
}
|
|
18321
|
-
function parseOmpAvailableCommands(value) {
|
|
18322
|
-
if (!Array.isArray(value))
|
|
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
|
|
18335
|
-
}
|
|
18336
|
-
];
|
|
18337
|
-
});
|
|
18338
|
-
}
|
|
18339
|
-
function ompLiveCommands(native) {
|
|
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;
|
|
18383
|
-
}
|
|
18384
|
-
const entry = historyEntry(parsed);
|
|
18385
|
-
if (!entry) {
|
|
18386
|
-
if (!isRecord7(parsed) || parsed.type !== "title" && parsed.type !== "session") {
|
|
18387
|
-
incomplete = true;
|
|
18388
|
-
}
|
|
18389
|
-
continue;
|
|
18390
|
-
}
|
|
18391
|
-
entries.push(entry);
|
|
18392
|
-
leafId = entry.id;
|
|
18393
|
-
}
|
|
18394
|
-
} finally {
|
|
18395
|
-
lines.close();
|
|
18396
|
-
}
|
|
18397
|
-
return { entries, leafId, ...incomplete ? { incomplete: true } : {} };
|
|
18398
|
-
}
|
|
18399
|
-
async function readOmpSessionHeader(sessionFile) {
|
|
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");
|
|
18408
|
-
}
|
|
18409
|
-
const contentsText = utf8Decoder.decode(contents);
|
|
18410
|
-
for (const line of contentsText.split("\n")) {
|
|
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 };
|
|
18425
|
-
}
|
|
18426
|
-
throw new Error("Omp Session header is invalid");
|
|
18427
|
-
} finally {
|
|
18428
|
-
await handle.close();
|
|
18429
|
-
}
|
|
18430
|
-
}
|
|
18431
|
-
async function verifyOmpSessionCwd(input) {
|
|
18432
|
-
if (!input.sessionFile)
|
|
18433
|
-
throw new Error("Omp Fork Session has no persisted Session file");
|
|
18434
|
-
const header = await readOmpSessionHeader(input.sessionFile);
|
|
18435
|
-
if (header.id !== input.sessionId) {
|
|
18436
|
-
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
18437
|
-
}
|
|
18438
|
-
const [actualCwd, expectedCwd] = await Promise.all([
|
|
18439
|
-
realpath2(header.cwd),
|
|
18440
|
-
realpath2(input.expectedCwd)
|
|
18441
|
-
]);
|
|
18442
|
-
if (actualCwd !== expectedCwd) {
|
|
18443
|
-
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
18444
|
-
}
|
|
18445
|
-
}
|
|
18446
|
-
|
|
18447
|
-
// dist/omp-last-turn-rollback.js
|
|
18448
|
-
function modelFromState(state) {
|
|
18449
|
-
if (state.provider === null && state.modelId === null)
|
|
18450
|
-
return null;
|
|
18451
|
-
if (state.provider === null || state.modelId === null) {
|
|
18452
|
-
throw new Error("Omp state contains a partial Model identity");
|
|
18453
|
-
}
|
|
18454
|
-
return { provider: state.provider, id: state.modelId };
|
|
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");
|
|
18472
|
-
}
|
|
18473
|
-
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
18474
|
-
if (!currentModel)
|
|
18475
|
-
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
18476
|
-
state = await transport.selectModel(currentModel);
|
|
18477
|
-
}
|
|
18478
|
-
if (state.thinkingLevel !== currentThinking) {
|
|
18479
|
-
if (!currentThinking)
|
|
18480
|
-
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
18481
|
-
state = await transport.selectThinkingOption(currentThinking);
|
|
18482
|
-
}
|
|
18483
|
-
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
18484
|
-
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
18485
|
-
}
|
|
18486
|
-
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
18487
|
-
sessionId: state.sessionId,
|
|
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");
|
|
18494
|
-
}
|
|
18495
|
-
await transport.verifySessionCwd(cwd);
|
|
18496
|
-
return { ok: true };
|
|
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]
|
|
18518
|
-
}
|
|
18519
|
-
};
|
|
18520
|
-
function resolveOmpExecutable(input, dependencies = {}) {
|
|
18521
|
-
const resolution = resolveHarnessExecutable(ompDiscoverySpec, {
|
|
18522
|
-
...input.command ? { command: input.command } : {},
|
|
18523
|
-
environment: input.environment,
|
|
18524
|
-
...dependencies.platform ? { platform: dependencies.platform } : {},
|
|
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;
|
|
18555
|
-
try {
|
|
18556
|
-
bytes = Buffer.from(data, "base64");
|
|
18557
|
-
} catch {
|
|
18558
|
-
throw new Error("Invalid OMP RPC chunk data");
|
|
18559
|
-
}
|
|
18560
|
-
if (bytes.length === 0 || bytes.length > MAX_CHUNK_BYTES || bytes.toString("base64") !== data) {
|
|
18561
|
-
throw new Error("Invalid OMP RPC chunk data");
|
|
18562
|
-
}
|
|
18563
|
-
const chunkIndex = index;
|
|
18564
|
-
const chunkCount = count2;
|
|
18565
|
-
const declaredByteLength = byteLength;
|
|
18566
|
-
if (!this.#pending) {
|
|
18567
|
-
if (chunkIndex !== 0)
|
|
18568
|
-
throw new Error("OMP RPC chunk sequence must start at index 0");
|
|
18569
|
-
this.#pending = {
|
|
18570
|
-
chunkId,
|
|
18571
|
-
count: chunkCount,
|
|
18572
|
-
byteLength: declaredByteLength,
|
|
18573
|
-
nextIndex: 0,
|
|
18574
|
-
chunks: [],
|
|
18575
|
-
received: 0
|
|
18576
|
-
};
|
|
18577
|
-
}
|
|
18578
|
-
const pending = this.#pending;
|
|
18579
|
-
if (!pending)
|
|
18580
|
-
throw new Error("OMP RPC chunk state was lost");
|
|
18581
|
-
if (pending.chunkId !== chunkId || pending.count !== chunkCount || pending.byteLength !== declaredByteLength || pending.nextIndex !== chunkIndex) {
|
|
18582
|
-
throw new Error("OMP RPC chunk sequence mismatch");
|
|
18583
|
-
}
|
|
18584
|
-
pending.chunks.push(bytes);
|
|
18585
|
-
pending.received += bytes.length;
|
|
18586
|
-
pending.nextIndex += 1;
|
|
18587
|
-
if (pending.received > pending.byteLength)
|
|
18588
|
-
throw new Error("OMP RPC chunk sequence exceeds its declared length");
|
|
18589
|
-
if (pending.nextIndex < pending.count)
|
|
18590
|
-
return null;
|
|
18591
|
-
if (pending.received !== pending.byteLength)
|
|
18592
|
-
throw new Error("OMP RPC chunk sequence length mismatch");
|
|
18593
|
-
this.#pending = null;
|
|
18594
|
-
let decoded;
|
|
18595
|
-
try {
|
|
18596
|
-
decoded = JSON.parse(Buffer.concat(pending.chunks).toString("utf8"));
|
|
18597
|
-
} catch {
|
|
18598
|
-
throw new Error("Failed to decode reassembled OMP RPC frame");
|
|
18599
|
-
}
|
|
18600
|
-
if (!isObject2(decoded))
|
|
18601
|
-
throw new Error("Reassembled OMP RPC frame must be an object");
|
|
18602
|
-
return decoded;
|
|
18603
|
-
}
|
|
18604
|
-
};
|
|
18605
|
-
|
|
18606
|
-
// dist/omp-rpc-session.js
|
|
18607
|
-
var OmpRpcFaultError = class extends Error {
|
|
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 };
|
|
18159
|
+
return { provider: value.provider, id: value.id };
|
|
18642
18160
|
}
|
|
18643
18161
|
function sessionStateData(response) {
|
|
18644
18162
|
const data = isRecord8(response.data) ? response.data : null;
|
|
@@ -18866,1178 +18384,1844 @@ var OmpRpcSession = class {
|
|
|
18866
18384
|
if (options.model && (options.sessionFile || options.forkSessionFile)) {
|
|
18867
18385
|
throw new Error("Omp RPC cannot combine a startup Model with Session restore or Fork");
|
|
18868
18386
|
}
|
|
18869
|
-
this.#options = {
|
|
18870
|
-
commandTimeoutMs: 3e4,
|
|
18871
|
-
compactionTimeoutMs: 3e5,
|
|
18872
|
-
// Native Abort waits for tools, persistence and deferred work to unwind.
|
|
18873
|
-
// Stable cancellation must outlast the Host's 20s steering wait.
|
|
18874
|
-
cancelTimeoutMs: 3e4,
|
|
18875
|
-
closeTimeoutMs: 2e3,
|
|
18876
|
-
...options
|
|
18877
|
-
};
|
|
18878
|
-
this.#processAdapter = processAdapter;
|
|
18387
|
+
this.#options = {
|
|
18388
|
+
commandTimeoutMs: 3e4,
|
|
18389
|
+
compactionTimeoutMs: 3e5,
|
|
18390
|
+
// Native Abort waits for tools, persistence and deferred work to unwind.
|
|
18391
|
+
// Stable cancellation must outlast the Host's 20s steering wait.
|
|
18392
|
+
cancelTimeoutMs: 3e4,
|
|
18393
|
+
closeTimeoutMs: 2e3,
|
|
18394
|
+
...options
|
|
18395
|
+
};
|
|
18396
|
+
this.#processAdapter = processAdapter;
|
|
18397
|
+
}
|
|
18398
|
+
get state() {
|
|
18399
|
+
if (!this.#state)
|
|
18400
|
+
throw new Error("Omp RPC Session has not started");
|
|
18401
|
+
return this.#state;
|
|
18402
|
+
}
|
|
18403
|
+
get stderrTail() {
|
|
18404
|
+
return this.#stderrTail;
|
|
18405
|
+
}
|
|
18406
|
+
async start() {
|
|
18407
|
+
if (this.#child || this.#closed)
|
|
18408
|
+
throw new Error("Omp RPC Session cannot be started twice");
|
|
18409
|
+
const child = this.#processAdapter.spawn({
|
|
18410
|
+
cwd: this.#options.cwd,
|
|
18411
|
+
...this.#options.command ? { command: this.#options.command } : {},
|
|
18412
|
+
environment: withNodeRuntimeOnPath({
|
|
18413
|
+
...process.env,
|
|
18414
|
+
...this.#options.environment,
|
|
18415
|
+
OMP_SKIP_VERSION_CHECK: "1",
|
|
18416
|
+
OMP_TELEMETRY: "0"
|
|
18417
|
+
}),
|
|
18418
|
+
...this.#options.sessionFile ? { sessionFile: this.#options.sessionFile } : {},
|
|
18419
|
+
...this.#options.forkSessionFile ? { forkSessionFile: this.#options.forkSessionFile } : {},
|
|
18420
|
+
...this.#options.model ? { model: this.#options.model } : {},
|
|
18421
|
+
...this.#options.permissionMode ? { permissionMode: this.#options.permissionMode } : {}
|
|
18422
|
+
});
|
|
18423
|
+
this.#child = child;
|
|
18424
|
+
child.stdout.on("data", (chunk) => this.#push(chunk));
|
|
18425
|
+
child.stdout.on("end", () => {
|
|
18426
|
+
if (this.#buffer.length !== 0) {
|
|
18427
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC stdout ended mid-frame"));
|
|
18428
|
+
}
|
|
18429
|
+
});
|
|
18430
|
+
child.stderr.on("data", (chunk) => {
|
|
18431
|
+
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
18432
|
+
});
|
|
18433
|
+
child.once("error", (error51) => {
|
|
18434
|
+
const kind = isRecord8(error51) && error51.code === "ENOENT" ? "notInstalled" : "unavailable";
|
|
18435
|
+
this.#fail(new OmpRpcFaultError(kind, `Omp RPC failed to start: ${error51.message}`, this.stderrTail));
|
|
18436
|
+
});
|
|
18437
|
+
child.once("exit", (code, signal) => {
|
|
18438
|
+
if (!this.#closed) {
|
|
18439
|
+
this.#fail(new OmpRpcFaultError("processExited", `Omp RPC exited (code=${code}, signal=${signal})`, this.stderrTail));
|
|
18440
|
+
}
|
|
18441
|
+
});
|
|
18442
|
+
await Promise.race([
|
|
18443
|
+
new Promise((resolve, reject) => {
|
|
18444
|
+
child.once("spawn", resolve);
|
|
18445
|
+
child.once("error", reject);
|
|
18446
|
+
}),
|
|
18447
|
+
new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Omp RPC start timed out")), this.#options.commandTimeoutMs))
|
|
18448
|
+
]);
|
|
18449
|
+
let readyTimeout;
|
|
18450
|
+
try {
|
|
18451
|
+
await Promise.race([
|
|
18452
|
+
this.#ready,
|
|
18453
|
+
this.#startupFault.then((error51) => {
|
|
18454
|
+
throw error51;
|
|
18455
|
+
}),
|
|
18456
|
+
new Promise((_resolve, reject) => {
|
|
18457
|
+
readyTimeout = setTimeout(() => reject(new Error("Omp RPC ready signal timed out")), this.#options.commandTimeoutMs);
|
|
18458
|
+
})
|
|
18459
|
+
]);
|
|
18460
|
+
} finally {
|
|
18461
|
+
clearTimeout(readyTimeout);
|
|
18462
|
+
}
|
|
18463
|
+
await this.#send("negotiate_protocol", { protocolVersion: 2 }).catch(() => void 0);
|
|
18464
|
+
if (this.#options.subscribeSubagentEvents !== false) {
|
|
18465
|
+
await this.#send("set_subagent_subscription", { level: "events" }).catch(() => void 0);
|
|
18466
|
+
}
|
|
18467
|
+
try {
|
|
18468
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18469
|
+
} catch (error51) {
|
|
18470
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("unavailable", `Omp RPC state unavailable: ${message2(error51)}`);
|
|
18471
|
+
this.#fail(fault);
|
|
18472
|
+
throw fault;
|
|
18473
|
+
}
|
|
18474
|
+
return this;
|
|
18475
|
+
}
|
|
18476
|
+
async getEntries() {
|
|
18477
|
+
try {
|
|
18478
|
+
if (this.state.sessionFile) {
|
|
18479
|
+
try {
|
|
18480
|
+
return await readOmpSessionHistory(this.state.sessionFile);
|
|
18481
|
+
} catch (error51) {
|
|
18482
|
+
if (!isRecord8(error51) || error51.code !== "ENOENT" || this.#options.sessionFile || this.#options.forkSessionFile)
|
|
18483
|
+
throw error51;
|
|
18484
|
+
const response2 = await this.#send("get_messages", {});
|
|
18485
|
+
const data2 = isRecord8(response2.data) ? response2.data : null;
|
|
18486
|
+
if (data2 && Array.isArray(data2.messages) && data2.messages.length === 0) {
|
|
18487
|
+
return { entries: [], leafId: null };
|
|
18488
|
+
}
|
|
18489
|
+
throw error51;
|
|
18490
|
+
}
|
|
18491
|
+
}
|
|
18492
|
+
const response = await this.#send("get_messages", {});
|
|
18493
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18494
|
+
if (!data || !Array.isArray(data.messages)) {
|
|
18495
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC messages response has no messages");
|
|
18496
|
+
}
|
|
18497
|
+
let branchEntryIds = null;
|
|
18498
|
+
try {
|
|
18499
|
+
const branchResponse = await this.#send("get_branch_messages", {});
|
|
18500
|
+
const branchData = isRecord8(branchResponse.data) ? branchResponse.data : null;
|
|
18501
|
+
if (branchData && Array.isArray(branchData.messages)) {
|
|
18502
|
+
const parsed = branchData.messages.flatMap((entry) => {
|
|
18503
|
+
if (!isRecord8(entry) || !nonBlankString(entry.entryId))
|
|
18504
|
+
return [];
|
|
18505
|
+
return [entry.entryId];
|
|
18506
|
+
});
|
|
18507
|
+
if (parsed.length === branchData.messages.length)
|
|
18508
|
+
branchEntryIds = parsed;
|
|
18509
|
+
}
|
|
18510
|
+
} catch (error51) {
|
|
18511
|
+
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18512
|
+
throw error51;
|
|
18513
|
+
}
|
|
18514
|
+
let userIndex = 0;
|
|
18515
|
+
let parentId = null;
|
|
18516
|
+
const entries = data.messages.map((nativeMessage, index) => {
|
|
18517
|
+
const role = isRecord8(nativeMessage) ? nativeMessage.role : void 0;
|
|
18518
|
+
const branchId = role === "user" ? branchEntryIds?.[userIndex] : void 0;
|
|
18519
|
+
if (branchId)
|
|
18520
|
+
userIndex += 1;
|
|
18521
|
+
const id = branchId ?? (isRecord8(nativeMessage) && nonBlankString(nativeMessage.id) ? nativeMessage.id : `omp-message-${index}`);
|
|
18522
|
+
const entry = { id, parentId, type: "message", message: nativeMessage };
|
|
18523
|
+
parentId = id;
|
|
18524
|
+
return entry;
|
|
18525
|
+
});
|
|
18526
|
+
return { entries, leafId: parentId };
|
|
18527
|
+
} catch (error51) {
|
|
18528
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18529
|
+
this.#fail(error51);
|
|
18530
|
+
throw error51;
|
|
18531
|
+
}
|
|
18532
|
+
}
|
|
18533
|
+
async getSubagentMessages(input) {
|
|
18534
|
+
if ((input.subagentId === void 0 || !nonBlankString(input.subagentId)) && (input.sessionFile === void 0 || !nonBlankString(input.sessionFile))) {
|
|
18535
|
+
throw new Error("Omp Subagent transcript requires a Subagent ID or Session file");
|
|
18536
|
+
}
|
|
18537
|
+
if (input.fromByte !== void 0 && (!Number.isSafeInteger(input.fromByte) || input.fromByte < 0)) {
|
|
18538
|
+
throw new Error("Omp Subagent transcript offset is invalid");
|
|
18539
|
+
}
|
|
18540
|
+
const response = await this.#send("get_subagent_messages", {
|
|
18541
|
+
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
18542
|
+
...input.sessionFile ? { sessionFile: input.sessionFile } : {},
|
|
18543
|
+
...input.fromByte !== void 0 ? { fromByte: input.fromByte } : {}
|
|
18544
|
+
});
|
|
18545
|
+
return parseSubagentMessages(response);
|
|
18546
|
+
}
|
|
18547
|
+
async compact(customInstructions, onEvent) {
|
|
18548
|
+
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
18549
|
+
throw new Error("Omp RPC Session is unavailable");
|
|
18550
|
+
}
|
|
18551
|
+
if (this.#activeTurn || this.#manualCompaction || this.#compactionActive) {
|
|
18552
|
+
throw new Error("Omp RPC Session already has an active operation");
|
|
18553
|
+
}
|
|
18554
|
+
const result = new Promise((resolve, reject) => {
|
|
18555
|
+
this.#manualCompaction = { onEvent, resolve, reject };
|
|
18556
|
+
});
|
|
18557
|
+
try {
|
|
18558
|
+
await this.#send("compact", customInstructions ? { customInstructions } : {});
|
|
18559
|
+
} catch (error51) {
|
|
18560
|
+
const pending = this.#manualCompaction;
|
|
18561
|
+
this.#manualCompaction = null;
|
|
18562
|
+
pending?.reject(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
18563
|
+
}
|
|
18564
|
+
return result;
|
|
18565
|
+
}
|
|
18566
|
+
async getSessionUsage() {
|
|
18567
|
+
try {
|
|
18568
|
+
const usage = parseOmpSessionUsage(await this.#send("get_session_stats", {}));
|
|
18569
|
+
await this.#ensureLatestCacheHitRate();
|
|
18570
|
+
return this.#withLatestCacheHitRate(usage);
|
|
18571
|
+
} catch (error51) {
|
|
18572
|
+
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18573
|
+
throw error51;
|
|
18574
|
+
const response = await this.#send("get_state", {});
|
|
18575
|
+
const observedState = parseSessionState(response);
|
|
18576
|
+
if (!this.#state || observedState.sessionId !== this.#state.sessionId || observedState.provider !== this.#state.provider || observedState.modelId !== this.#state.modelId) {
|
|
18577
|
+
throw new Error("Omp RPC Usage fallback does not match the confirmed Session state");
|
|
18578
|
+
}
|
|
18579
|
+
await this.#ensureLatestCacheHitRate();
|
|
18580
|
+
const usage = parseOmpStateContextUsage(response);
|
|
18581
|
+
return usage ? this.#withLatestCacheHitRate(usage) : null;
|
|
18582
|
+
}
|
|
18879
18583
|
}
|
|
18880
|
-
|
|
18881
|
-
if (
|
|
18882
|
-
|
|
18883
|
-
|
|
18584
|
+
async #ensureLatestCacheHitRate() {
|
|
18585
|
+
if (this.#latestCacheHitRatePercent !== void 0)
|
|
18586
|
+
return;
|
|
18587
|
+
try {
|
|
18588
|
+
this.#latestCacheHitRatePercent = latestOmpCacheHitRatePercent(await this.getEntries());
|
|
18589
|
+
} catch {
|
|
18590
|
+
this.#latestCacheHitRatePercent = null;
|
|
18591
|
+
}
|
|
18884
18592
|
}
|
|
18885
|
-
|
|
18886
|
-
return this.#
|
|
18593
|
+
#withLatestCacheHitRate(usage) {
|
|
18594
|
+
return this.#latestCacheHitRatePercent === null || this.#latestCacheHitRatePercent === void 0 ? usage : parseHostUsage({ ...usage, cacheHitRatePercent: this.#latestCacheHitRatePercent });
|
|
18887
18595
|
}
|
|
18888
|
-
async
|
|
18889
|
-
if (
|
|
18890
|
-
throw new Error("Omp RPC
|
|
18891
|
-
|
|
18892
|
-
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
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"));
|
|
18596
|
+
async fork(entryId) {
|
|
18597
|
+
if (!nonBlankString(entryId))
|
|
18598
|
+
throw new Error("Omp RPC Fork requires an Entry identity");
|
|
18599
|
+
try {
|
|
18600
|
+
const response = await this.#send("branch", { entryId });
|
|
18601
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18602
|
+
if (!data || data.cancelled === true) {
|
|
18603
|
+
throw new OmpRpcFaultError("unavailable", "Omp RPC Fork was cancelled");
|
|
18910
18604
|
}
|
|
18605
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18606
|
+
return this.#state;
|
|
18607
|
+
} catch (error51) {
|
|
18608
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18609
|
+
this.#fail(error51);
|
|
18610
|
+
throw error51;
|
|
18611
|
+
}
|
|
18612
|
+
}
|
|
18613
|
+
verifySessionCwd(expectedCwd) {
|
|
18614
|
+
return verifyOmpSessionCwd({
|
|
18615
|
+
sessionFile: this.state.sessionFile,
|
|
18616
|
+
sessionId: this.state.sessionId,
|
|
18617
|
+
expectedCwd
|
|
18911
18618
|
});
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
|
|
18619
|
+
}
|
|
18620
|
+
async getAvailableModels() {
|
|
18621
|
+
try {
|
|
18622
|
+
return parseAvailableModels(await this.#send("get_available_models", {}));
|
|
18623
|
+
} catch (error51) {
|
|
18624
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18625
|
+
this.#fail(error51);
|
|
18626
|
+
throw error51;
|
|
18627
|
+
}
|
|
18628
|
+
}
|
|
18629
|
+
async getAvailableThinkingLevels() {
|
|
18630
|
+
return this.state.availableThinkingLevels;
|
|
18631
|
+
}
|
|
18632
|
+
async selectModel(model2) {
|
|
18633
|
+
await this.#send("set_model", { provider: model2.provider, modelId: model2.id });
|
|
18634
|
+
return this.#refreshState("Model");
|
|
18635
|
+
}
|
|
18636
|
+
async selectThinkingOption(thinkingOptionId) {
|
|
18637
|
+
const level = harnessThinkingOptionIdSchema.parse(thinkingOptionId);
|
|
18638
|
+
await this.#send("set_thinking_level", { level });
|
|
18639
|
+
return this.#refreshState("Thinking");
|
|
18640
|
+
}
|
|
18641
|
+
async #refreshState(operation) {
|
|
18642
|
+
try {
|
|
18643
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18644
|
+
return this.#state;
|
|
18645
|
+
} catch (error51) {
|
|
18646
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
18647
|
+
this.#fail(fault);
|
|
18648
|
+
throw fault;
|
|
18649
|
+
}
|
|
18650
|
+
}
|
|
18651
|
+
async runTurn(text, onEvent) {
|
|
18652
|
+
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
18653
|
+
throw new Error("Omp RPC Session is unavailable");
|
|
18654
|
+
}
|
|
18655
|
+
if (this.#activeTurn)
|
|
18656
|
+
throw new Error("Omp RPC Session already has an active Turn");
|
|
18657
|
+
if (text.length === 0)
|
|
18658
|
+
throw new Error("Omp text Turn must not be empty");
|
|
18659
|
+
const promptId = `codexhost-${randomUUID()}`;
|
|
18660
|
+
const settled = new Promise((resolve, reject) => {
|
|
18661
|
+
this.#activeTurn = {
|
|
18662
|
+
promptId,
|
|
18663
|
+
localResult: null,
|
|
18664
|
+
text: "",
|
|
18665
|
+
assistantMessageId: null,
|
|
18666
|
+
sawStreamedMessageText: false,
|
|
18667
|
+
sawStreamedMessageReasoning: false,
|
|
18668
|
+
lastFinalizedMessageText: null,
|
|
18669
|
+
lastFinalizedMessageReasoning: null,
|
|
18670
|
+
reasoningMessageOpen: false,
|
|
18671
|
+
onEvent,
|
|
18672
|
+
resolve,
|
|
18673
|
+
reject,
|
|
18674
|
+
failure: null,
|
|
18675
|
+
sawTool: false,
|
|
18676
|
+
tools: /* @__PURE__ */ new Map(),
|
|
18677
|
+
interactions: /* @__PURE__ */ new Map(),
|
|
18678
|
+
settlement: "pending",
|
|
18679
|
+
terminalEnd: false,
|
|
18680
|
+
cancellation: "none",
|
|
18681
|
+
cancellationTimeout: null,
|
|
18682
|
+
cancellationRecheck: null,
|
|
18683
|
+
cancellationChecking: false,
|
|
18684
|
+
cancellationReloaded: false,
|
|
18685
|
+
abortPromise: null
|
|
18686
|
+
};
|
|
18923
18687
|
});
|
|
18924
|
-
await Promise.race([
|
|
18925
|
-
new Promise((resolve, reject) => {
|
|
18926
|
-
child.once("spawn", resolve);
|
|
18927
|
-
child.once("error", reject);
|
|
18928
|
-
}),
|
|
18929
|
-
new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Omp RPC start timed out")), this.#options.commandTimeoutMs))
|
|
18930
|
-
]);
|
|
18931
|
-
let readyTimeout;
|
|
18932
18688
|
try {
|
|
18933
|
-
await
|
|
18934
|
-
|
|
18935
|
-
|
|
18936
|
-
throw error51;
|
|
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);
|
|
18689
|
+
await this.#send("prompt", { message: text }, promptId);
|
|
18690
|
+
} catch (error51) {
|
|
18691
|
+
this.#rejectActiveTurn(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
18944
18692
|
}
|
|
18945
|
-
|
|
18946
|
-
|
|
18947
|
-
|
|
18693
|
+
return settled;
|
|
18694
|
+
}
|
|
18695
|
+
respondToInteraction(response) {
|
|
18696
|
+
return this.#resolveInteraction(response, "cancelled" in response ? "cancelled" : "responded");
|
|
18697
|
+
}
|
|
18698
|
+
async #resolveInteraction(response, reason) {
|
|
18699
|
+
const active = this.#activeTurn;
|
|
18700
|
+
const pending = active?.interactions.get(response.requestId);
|
|
18701
|
+
if (!active || !pending || this.#closed || this.#failed) {
|
|
18702
|
+
throw new Error("Omp RPC interaction is not pending");
|
|
18703
|
+
}
|
|
18704
|
+
if ("value" in response && !["select", "input", "editor"].includes(pending.request.method)) {
|
|
18705
|
+
throw new Error("Omp RPC interaction response type does not match the request");
|
|
18706
|
+
}
|
|
18707
|
+
if ("confirmed" in response && pending.request.method !== "confirm") {
|
|
18708
|
+
throw new Error("Omp RPC confirmation does not match the request");
|
|
18709
|
+
}
|
|
18710
|
+
const frame = "cancelled" in response ? {
|
|
18711
|
+
type: "extension_ui_response",
|
|
18712
|
+
id: response.requestId,
|
|
18713
|
+
cancelled: true,
|
|
18714
|
+
...reason === "expired" ? { timedOut: true } : {}
|
|
18715
|
+
} : "confirmed" in response ? { type: "extension_ui_response", id: response.requestId, confirmed: response.confirmed } : { type: "extension_ui_response", id: response.requestId, value: response.value };
|
|
18716
|
+
if (!active.interactions.delete(response.requestId)) {
|
|
18717
|
+
throw new Error("Omp RPC interaction is not pending");
|
|
18948
18718
|
}
|
|
18719
|
+
if (pending.timeout)
|
|
18720
|
+
clearTimeout(pending.timeout);
|
|
18721
|
+
active.onEvent({ type: "interaction.closed", requestId: response.requestId, reason });
|
|
18949
18722
|
try {
|
|
18950
|
-
|
|
18723
|
+
await this.#write(frame);
|
|
18951
18724
|
} catch (error51) {
|
|
18952
|
-
const fault =
|
|
18725
|
+
const fault = new OmpRpcFaultError("protocolError", `Omp RPC interaction response failed: ${message2(error51)}`);
|
|
18953
18726
|
this.#fail(fault);
|
|
18954
18727
|
throw fault;
|
|
18955
18728
|
}
|
|
18956
|
-
return this;
|
|
18957
18729
|
}
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18730
|
+
abort() {
|
|
18731
|
+
const active = this.#activeTurn;
|
|
18732
|
+
if (!active || this.#closed || this.#failed) {
|
|
18733
|
+
return Promise.reject(new Error("Omp RPC Session has no cancellable Turn"));
|
|
18734
|
+
}
|
|
18735
|
+
if (active.abortPromise)
|
|
18736
|
+
return active.abortPromise;
|
|
18737
|
+
active.cancellation = "requesting";
|
|
18738
|
+
active.cancellationTimeout = setTimeout(() => {
|
|
18739
|
+
this.#terminateFailedCancellation(active, new OmpRpcFaultError("protocolError", "Omp Turn cancellation did not settle within its bound"));
|
|
18740
|
+
}, this.#options.cancelTimeoutMs);
|
|
18741
|
+
const aborting = this.#send("abort", {}).then(async () => {
|
|
18742
|
+
if (this.#activeTurn !== active)
|
|
18743
|
+
return;
|
|
18744
|
+
active.cancellation = "accepted";
|
|
18745
|
+
await this.#confirmCancelledTurn(active);
|
|
18746
|
+
}).catch((error51) => {
|
|
18747
|
+
if (this.#activeTurn !== active)
|
|
18748
|
+
throw error51;
|
|
18749
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC Abort failed: ${message2(error51)}`);
|
|
18750
|
+
this.#terminateFailedCancellation(active, fault);
|
|
18751
|
+
throw fault;
|
|
18752
|
+
});
|
|
18753
|
+
active.abortPromise = aborting;
|
|
18754
|
+
return aborting;
|
|
18755
|
+
}
|
|
18756
|
+
#terminateFailedCancellation(active, fault) {
|
|
18757
|
+
if (this.#activeTurn !== active)
|
|
18758
|
+
return;
|
|
18759
|
+
if (active.cancellationTimeout)
|
|
18760
|
+
clearTimeout(active.cancellationTimeout);
|
|
18761
|
+
active.cancellationTimeout = null;
|
|
18762
|
+
this.#fail(fault);
|
|
18763
|
+
void this.close().catch(() => void 0);
|
|
18764
|
+
}
|
|
18765
|
+
close() {
|
|
18766
|
+
if (!this.#closed) {
|
|
18767
|
+
this.#closed = true;
|
|
18768
|
+
this.#rejectAll(new Error("Omp RPC Session closed"));
|
|
18769
|
+
}
|
|
18770
|
+
this.#closePromise ??= this.#stopProcess();
|
|
18771
|
+
return this.#closePromise;
|
|
18772
|
+
}
|
|
18773
|
+
async #stopProcess() {
|
|
18774
|
+
const child = this.#child;
|
|
18775
|
+
if (!child)
|
|
18776
|
+
return;
|
|
18777
|
+
if (child.stdin.writable)
|
|
18778
|
+
child.stdin.end();
|
|
18779
|
+
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
18780
|
+
return;
|
|
18781
|
+
signalProcessTree(child, "SIGTERM");
|
|
18782
|
+
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
18783
|
+
return;
|
|
18784
|
+
signalProcessTree(child, "SIGKILL");
|
|
18785
|
+
if (!await waitForExit(child, this.#options.closeTimeoutMs)) {
|
|
18786
|
+
throw new Error("Omp RPC process tree did not exit within cleanup bounds");
|
|
18787
|
+
}
|
|
18788
|
+
}
|
|
18789
|
+
#push(chunk) {
|
|
18790
|
+
this.#buffer = this.#buffer.length === 0 ? chunk : Buffer.concat([this.#buffer, chunk]);
|
|
18791
|
+
let newline = this.#buffer.indexOf(10);
|
|
18792
|
+
while (newline >= 0) {
|
|
18793
|
+
const frame = this.#buffer.subarray(0, newline);
|
|
18794
|
+
this.#buffer = this.#buffer.subarray(newline + 1);
|
|
18795
|
+
let parsed;
|
|
18796
|
+
try {
|
|
18797
|
+
parsed = JSON.parse(textDecoder.decode(frame));
|
|
18798
|
+
} catch (error51) {
|
|
18799
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC returned invalid JSONL: ${message2(error51)}`));
|
|
18800
|
+
newline = this.#buffer.indexOf(10);
|
|
18801
|
+
continue;
|
|
18978
18802
|
}
|
|
18979
|
-
let branchEntryIds = null;
|
|
18980
18803
|
try {
|
|
18981
|
-
const
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
if (parsed.length === branchData.messages.length)
|
|
18990
|
-
branchEntryIds = parsed;
|
|
18804
|
+
const decoded = this.#frameDecoder.push(parsed);
|
|
18805
|
+
if (decoded === null) {
|
|
18806
|
+
newline = this.#buffer.indexOf(10);
|
|
18807
|
+
continue;
|
|
18808
|
+
}
|
|
18809
|
+
const value = decoded;
|
|
18810
|
+
if (!isRecord8(value) || typeof value.type !== "string") {
|
|
18811
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid envelope");
|
|
18991
18812
|
}
|
|
18813
|
+
this.#handle(value);
|
|
18992
18814
|
} catch (error51) {
|
|
18993
|
-
|
|
18994
|
-
throw error51;
|
|
18815
|
+
this.#fail(error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC frame handling failed: ${message2(error51)}`));
|
|
18995
18816
|
}
|
|
18996
|
-
|
|
18997
|
-
let parentId = null;
|
|
18998
|
-
const entries = data.messages.map((nativeMessage, index) => {
|
|
18999
|
-
const role = isRecord8(nativeMessage) ? nativeMessage.role : void 0;
|
|
19000
|
-
const branchId = role === "user" ? branchEntryIds?.[userIndex] : void 0;
|
|
19001
|
-
if (branchId)
|
|
19002
|
-
userIndex += 1;
|
|
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;
|
|
19007
|
-
});
|
|
19008
|
-
return { entries, leafId: parentId };
|
|
19009
|
-
} catch (error51) {
|
|
19010
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
19011
|
-
this.#fail(error51);
|
|
19012
|
-
throw error51;
|
|
18817
|
+
newline = this.#buffer.indexOf(10);
|
|
19013
18818
|
}
|
|
19014
18819
|
}
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
|
|
18820
|
+
/** Latest `available_commands_update` of the running process, if any. */
|
|
18821
|
+
get availableCommands() {
|
|
18822
|
+
return this.#availableCommands;
|
|
18823
|
+
}
|
|
18824
|
+
#handle(value) {
|
|
18825
|
+
if (this.#closed || this.#failed)
|
|
18826
|
+
return;
|
|
18827
|
+
if (value.type === "available_commands_update") {
|
|
18828
|
+
this.#availableCommands = parseOmpAvailableCommands(value.commands);
|
|
18829
|
+
return;
|
|
19018
18830
|
}
|
|
19019
|
-
if (
|
|
19020
|
-
|
|
18831
|
+
if (value.type === "ready") {
|
|
18832
|
+
this.#readyResolve?.();
|
|
18833
|
+
this.#readyResolve = null;
|
|
18834
|
+
return;
|
|
18835
|
+
}
|
|
18836
|
+
if (value.type === "response") {
|
|
18837
|
+
this.#handleResponse(value);
|
|
18838
|
+
return;
|
|
18839
|
+
}
|
|
18840
|
+
if (value.type === "auto_compaction_start" || value.type === "compaction_start") {
|
|
18841
|
+
this.#compactionActive = true;
|
|
18842
|
+
this.#compactionTurn = this.#activeTurn;
|
|
18843
|
+
this.#compactionTimeout ??= setTimeout(() => {
|
|
18844
|
+
this.#compactionTimeout = null;
|
|
18845
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC compaction timed out after ${this.#options.compactionTimeoutMs}ms`));
|
|
18846
|
+
}, this.#options.compactionTimeoutMs);
|
|
18847
|
+
const onEvent = this.#activeTurn?.onEvent ?? this.#manualCompaction?.onEvent;
|
|
18848
|
+
onEvent?.({ type: "compaction.started" });
|
|
18849
|
+
for (const pending of this.#pending.values()) {
|
|
18850
|
+
if (pending.command !== "prompt" && pending.command !== "compact" || !pending.timeout)
|
|
18851
|
+
continue;
|
|
18852
|
+
clearTimeout(pending.timeout);
|
|
18853
|
+
pending.timeout = null;
|
|
18854
|
+
}
|
|
18855
|
+
return;
|
|
18856
|
+
}
|
|
18857
|
+
if (value.type === "auto_compaction_end" || value.type === "compaction_end") {
|
|
18858
|
+
this.#compactionActive = false;
|
|
18859
|
+
if (this.#compactionTimeout)
|
|
18860
|
+
clearTimeout(this.#compactionTimeout);
|
|
18861
|
+
this.#compactionTimeout = null;
|
|
18862
|
+
const compactionTurn = this.#compactionTurn;
|
|
18863
|
+
this.#compactionTurn = null;
|
|
18864
|
+
for (const [id, pending] of this.#pending) {
|
|
18865
|
+
if (pending.command === "prompt" || pending.command === "compact") {
|
|
18866
|
+
this.#armCommandTimeout(id, pending);
|
|
18867
|
+
}
|
|
18868
|
+
}
|
|
18869
|
+
const outcome = value.aborted === true ? "cancelled" : isRecord8(value.result) ? "succeeded" : "failed";
|
|
18870
|
+
const event = {
|
|
18871
|
+
type: "compaction.completed",
|
|
18872
|
+
outcome,
|
|
18873
|
+
...nonBlankString(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
|
|
18874
|
+
};
|
|
18875
|
+
compactionTurn?.onEvent(event);
|
|
18876
|
+
const manual = this.#manualCompaction;
|
|
18877
|
+
this.#manualCompaction = null;
|
|
18878
|
+
manual?.onEvent(event);
|
|
18879
|
+
manual?.resolve({
|
|
18880
|
+
outcome,
|
|
18881
|
+
...event.errorMessage ? { errorMessage: event.errorMessage } : {}
|
|
18882
|
+
});
|
|
18883
|
+
return;
|
|
18884
|
+
}
|
|
18885
|
+
const active = this.#activeTurn;
|
|
18886
|
+
if (this.#handleSubagentFrame(active, value))
|
|
18887
|
+
return;
|
|
18888
|
+
this.#observeUsage(value);
|
|
18889
|
+
if (value.type === "agent_start" && active)
|
|
18890
|
+
active.terminalEnd = false;
|
|
18891
|
+
if ((value.type === "session_settled" || value.type === "agent_start") && active?.cancellation === "accepted") {
|
|
18892
|
+
void this.#confirmCancelledTurn(active);
|
|
18893
|
+
return;
|
|
18894
|
+
}
|
|
18895
|
+
if (!active) {
|
|
18896
|
+
if (value.type === "extension_ui_request" && this.#isBlockingInteraction(value)) {
|
|
18897
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC requested blocking Extension UI outside an active Turn"));
|
|
18898
|
+
}
|
|
18899
|
+
return;
|
|
18900
|
+
}
|
|
18901
|
+
if (value.type === "command_output") {
|
|
18902
|
+
if (active.settlement !== "pending")
|
|
18903
|
+
return;
|
|
18904
|
+
if (typeof value.text !== "string") {
|
|
18905
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned invalid command output");
|
|
18906
|
+
}
|
|
18907
|
+
active.text += value.text;
|
|
18908
|
+
active.onEvent({ type: "text.delta", messageId: active.promptId, delta: value.text });
|
|
18909
|
+
return;
|
|
18910
|
+
}
|
|
18911
|
+
if (value.type === "prompt_result") {
|
|
18912
|
+
if (value.id !== active.promptId || value.agentInvoked !== false)
|
|
18913
|
+
return;
|
|
18914
|
+
if (value.status === "completed" || value.status === "aborted") {
|
|
18915
|
+
this.#settleLocalTurn(active, { cancelled: value.status === "aborted" });
|
|
18916
|
+
} else if (value.status === "error" && isRecord8(value.error) && typeof value.error.message === "string") {
|
|
18917
|
+
this.#settleLocalTurn(active, { cancelled: false, error: value.error.message });
|
|
18918
|
+
} else {
|
|
18919
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid local prompt result");
|
|
18920
|
+
}
|
|
18921
|
+
return;
|
|
18922
|
+
}
|
|
18923
|
+
if (value.type === "extension_ui_request") {
|
|
18924
|
+
this.#startInteraction(active, value);
|
|
18925
|
+
return;
|
|
18926
|
+
}
|
|
18927
|
+
if (value.type === "message_start" && assistantText(value.message) !== null) {
|
|
18928
|
+
this.#startAssistantMessage(active, value.message);
|
|
18929
|
+
return;
|
|
18930
|
+
}
|
|
18931
|
+
if (value.type === "message_update" && isRecord8(value.assistantMessageEvent)) {
|
|
18932
|
+
const event = value.assistantMessageEvent;
|
|
18933
|
+
const eventType = String(event.type ?? "");
|
|
18934
|
+
const isThinking = eventType === "thinking_delta" || eventType === "reasoning_delta" || eventType === "thought_delta" || eventType === "thinking" || eventType === "reasoning";
|
|
18935
|
+
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
18936
|
+
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;
|
|
18937
|
+
if (isThinking && delta !== null && delta.length > 0) {
|
|
18938
|
+
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18939
|
+
active.reasoningMessageOpen = true;
|
|
18940
|
+
active.sawStreamedMessageReasoning = true;
|
|
18941
|
+
active.onEvent({ type: "reasoning.delta", messageId, delta });
|
|
18942
|
+
} else if (isText && delta !== null && delta.length > 0) {
|
|
18943
|
+
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18944
|
+
active.text += delta;
|
|
18945
|
+
active.sawStreamedMessageText = true;
|
|
18946
|
+
active.onEvent({ type: "text.delta", messageId, delta });
|
|
18947
|
+
} else if (event.type === "error") {
|
|
18948
|
+
this.#ensureAssistantMessage(active, value.message);
|
|
18949
|
+
active.failure = assistantFailure(event.error) ?? assistantFailure(value.message) ?? new Error("Omp assistant message failed");
|
|
18950
|
+
}
|
|
18951
|
+
return;
|
|
18952
|
+
}
|
|
18953
|
+
if (value.type === "message_end") {
|
|
18954
|
+
this.#finalizeAssistantMessage(active, value.message);
|
|
18955
|
+
return;
|
|
18956
|
+
}
|
|
18957
|
+
if (value.type === "turn_end") {
|
|
18958
|
+
this.#finalizeAssistantMessage(active, value.message);
|
|
18959
|
+
return;
|
|
18960
|
+
}
|
|
18961
|
+
if (value.type === "tool_execution_start") {
|
|
18962
|
+
this.#startTool(active, value);
|
|
18963
|
+
return;
|
|
18964
|
+
}
|
|
18965
|
+
if (value.type === "tool_execution_update") {
|
|
18966
|
+
this.#updateTool(active, value);
|
|
18967
|
+
return;
|
|
18968
|
+
}
|
|
18969
|
+
if (value.type === "tool_execution_end") {
|
|
18970
|
+
this.#completeTool(active, value);
|
|
18971
|
+
return;
|
|
18972
|
+
}
|
|
18973
|
+
if (value.type === "agent_end" && Array.isArray(value.messages)) {
|
|
18974
|
+
for (let index = value.messages.length - 1; index >= 0; index -= 1) {
|
|
18975
|
+
const message3 = value.messages[index];
|
|
18976
|
+
if (!isRecord8(message3) || message3.role !== "assistant")
|
|
18977
|
+
continue;
|
|
18978
|
+
this.#finalizeAssistantMessage(active, message3);
|
|
18979
|
+
break;
|
|
18980
|
+
}
|
|
18981
|
+
}
|
|
18982
|
+
if (value.type === "agent_end" && value.isTerminal !== false) {
|
|
18983
|
+
active.terminalEnd = true;
|
|
18984
|
+
if (active.cancellation !== "none") {
|
|
18985
|
+
if (active.cancellation === "accepted")
|
|
18986
|
+
void this.#confirmCancelledTurn(active);
|
|
18987
|
+
return;
|
|
18988
|
+
}
|
|
18989
|
+
if (active.settlement !== "pending")
|
|
18990
|
+
return;
|
|
18991
|
+
active.settlement = "confirming";
|
|
18992
|
+
void this.#confirmSettledTurn(active);
|
|
19021
18993
|
}
|
|
19022
|
-
const response = await this.#send("get_subagent_messages", {
|
|
19023
|
-
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
19024
|
-
...input.sessionFile ? { sessionFile: input.sessionFile } : {},
|
|
19025
|
-
...input.fromByte !== void 0 ? { fromByte: input.fromByte } : {}
|
|
19026
|
-
});
|
|
19027
|
-
return parseSubagentMessages(response);
|
|
19028
18994
|
}
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
18995
|
+
/** Every finished assistant message is one model request, with or without an active Turn. */
|
|
18996
|
+
#observeUsage(value) {
|
|
18997
|
+
if (value.type === "message_start") {
|
|
18998
|
+
this.#usageRequestStartedAtMs = null;
|
|
18999
|
+
return;
|
|
19032
19000
|
}
|
|
19033
|
-
if (
|
|
19034
|
-
|
|
19001
|
+
if (value.type === "message_update") {
|
|
19002
|
+
const event = value.assistantMessageEvent;
|
|
19003
|
+
if (this.#usageRequestStartedAtMs === null && isRecord8(event) && typeof event.type === "string" && /^(text|thinking|reasoning|thought|toolcall)_(start|delta)$/u.test(event.type)) {
|
|
19004
|
+
this.#usageRequestStartedAtMs = Date.now();
|
|
19005
|
+
}
|
|
19006
|
+
return;
|
|
19035
19007
|
}
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19008
|
+
if (value.type === "message_end" && isRecord8(value.message)) {
|
|
19009
|
+
if (value.message.role !== "assistant")
|
|
19010
|
+
return;
|
|
19011
|
+
const startedAtMs = this.#usageRequestStartedAtMs;
|
|
19012
|
+
this.#usageRequestStartedAtMs = null;
|
|
19013
|
+
this.#options.onUsage?.({
|
|
19014
|
+
message: value.message,
|
|
19015
|
+
startedAtMs,
|
|
19016
|
+
completedAtMs: Date.now()
|
|
19017
|
+
});
|
|
19045
19018
|
}
|
|
19046
|
-
return result;
|
|
19047
19019
|
}
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
await this.#ensureLatestCacheHitRate();
|
|
19052
|
-
return this.#withLatestCacheHitRate(usage);
|
|
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;
|
|
19020
|
+
#handleSubagentFrame(active, value) {
|
|
19021
|
+
if (value.type !== "subagent_lifecycle" && value.type !== "subagent_progress" && value.type !== "subagent_event") {
|
|
19022
|
+
return false;
|
|
19064
19023
|
}
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
this.#latestCacheHitRatePercent = latestOmpCacheHitRatePercent(await this.getEntries());
|
|
19071
|
-
} catch {
|
|
19072
|
-
this.#latestCacheHitRatePercent = null;
|
|
19024
|
+
const payload = isRecord8(value.payload) ? value.payload : null;
|
|
19025
|
+
const progressPayload = value.type === "subagent_progress" && payload && isRecord8(payload.progress) ? payload.progress : null;
|
|
19026
|
+
const nativeIdValue = progressPayload?.id ?? payload?.id;
|
|
19027
|
+
if (!payload || !nonBlankString(nativeIdValue)) {
|
|
19028
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent frame has no stable ID");
|
|
19073
19029
|
}
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
const
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19030
|
+
const nativeSubagentId = nativeIdValue;
|
|
19031
|
+
const callId = nativeSubagentId;
|
|
19032
|
+
const emit = active?.onEvent ?? this.#options.onSubagentEvent;
|
|
19033
|
+
if (value.type === "subagent_event") {
|
|
19034
|
+
emit?.({ type: "subagent.transcript.changed", callId, nativeSubagentId });
|
|
19035
|
+
return true;
|
|
19036
|
+
}
|
|
19037
|
+
if (value.type === "subagent_lifecycle") {
|
|
19038
|
+
const status2 = payload.status;
|
|
19039
|
+
if (status2 === "started") {
|
|
19040
|
+
const description = nonBlankString(payload.description) ? payload.description : nonBlankString(payload.agent) ? `${payload.agent} delegation` : "Subagent delegation";
|
|
19041
|
+
emit?.({
|
|
19042
|
+
type: "subagent.started",
|
|
19043
|
+
callId,
|
|
19044
|
+
nativeSubagentId,
|
|
19045
|
+
description,
|
|
19046
|
+
...nonBlankString(payload.agent) ? { role: payload.agent } : {},
|
|
19047
|
+
...nonBlankString(payload.task) ? { prompt: payload.task } : {},
|
|
19048
|
+
background: payload.detached === true,
|
|
19049
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19050
|
+
});
|
|
19051
|
+
return true;
|
|
19086
19052
|
}
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
|
|
19091
|
-
|
|
19092
|
-
|
|
19053
|
+
if (status2 !== "completed" && status2 !== "failed" && status2 !== "aborted") {
|
|
19054
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent lifecycle status is invalid");
|
|
19055
|
+
}
|
|
19056
|
+
emit?.({
|
|
19057
|
+
type: "subagent.completed",
|
|
19058
|
+
callId,
|
|
19059
|
+
nativeSubagentId,
|
|
19060
|
+
isError: status2 !== "completed",
|
|
19061
|
+
...nonBlankString(payload.resultSummary) ? { resultSummary: payload.resultSummary } : {},
|
|
19062
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19063
|
+
});
|
|
19064
|
+
return true;
|
|
19093
19065
|
}
|
|
19094
|
-
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
sessionFile: this.state.sessionFile,
|
|
19098
|
-
sessionId: this.state.sessionId,
|
|
19099
|
-
expectedCwd
|
|
19100
|
-
});
|
|
19101
|
-
}
|
|
19102
|
-
async getAvailableModels() {
|
|
19103
|
-
try {
|
|
19104
|
-
return parseAvailableModels(await this.#send("get_available_models", {}));
|
|
19105
|
-
} catch (error51) {
|
|
19106
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
19107
|
-
this.#fail(error51);
|
|
19108
|
-
throw error51;
|
|
19066
|
+
const progress = progressPayload;
|
|
19067
|
+
if (!progress || !nonBlankString(progress.id) || progress.id !== nativeSubagentId) {
|
|
19068
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent progress is invalid");
|
|
19109
19069
|
}
|
|
19070
|
+
const status = subagentStatus(progress.status);
|
|
19071
|
+
const recentOutput = Array.isArray(progress.recentOutput) ? progress.recentOutput.filter((item) => typeof item === "string") : [];
|
|
19072
|
+
const resultSummary = recentOutput.at(-1);
|
|
19073
|
+
emit?.({
|
|
19074
|
+
type: "subagent.updated",
|
|
19075
|
+
callId,
|
|
19076
|
+
nativeSubagentId,
|
|
19077
|
+
status,
|
|
19078
|
+
...nonBlankString(progress.description) ? { description: progress.description } : nonBlankString(payload.task) ? { description: payload.task } : {},
|
|
19079
|
+
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
19080
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19081
|
+
});
|
|
19082
|
+
return true;
|
|
19110
19083
|
}
|
|
19111
|
-
|
|
19112
|
-
return
|
|
19113
|
-
}
|
|
19114
|
-
async selectModel(model2) {
|
|
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;
|
|
19131
|
-
}
|
|
19084
|
+
#isBlockingInteraction(value) {
|
|
19085
|
+
return ["select", "confirm", "input", "editor"].includes(String(value.method));
|
|
19132
19086
|
}
|
|
19133
|
-
|
|
19134
|
-
if (!this.#
|
|
19135
|
-
|
|
19087
|
+
#startInteraction(active, value) {
|
|
19088
|
+
if (!this.#isBlockingInteraction(value))
|
|
19089
|
+
return;
|
|
19090
|
+
const requestId2 = value.id;
|
|
19091
|
+
const method = value.method;
|
|
19092
|
+
const title = value.title;
|
|
19093
|
+
const timeoutMs = value.timeout;
|
|
19094
|
+
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)) {
|
|
19095
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Interaction request");
|
|
19136
19096
|
}
|
|
19137
|
-
|
|
19138
|
-
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
19148
|
-
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
19152
|
-
|
|
19153
|
-
|
|
19154
|
-
|
|
19155
|
-
|
|
19156
|
-
|
|
19157
|
-
|
|
19158
|
-
|
|
19159
|
-
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19097
|
+
let request;
|
|
19098
|
+
if (method === "select") {
|
|
19099
|
+
if (!Array.isArray(value.options) || value.options.length === 0 || !value.options.every((option) => typeof option === "string" && option.length > 0)) {
|
|
19100
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC select request has invalid options");
|
|
19101
|
+
}
|
|
19102
|
+
let optionDetails;
|
|
19103
|
+
if (value.optionDetails !== void 0) {
|
|
19104
|
+
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"))) {
|
|
19105
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC select option details are invalid");
|
|
19106
|
+
}
|
|
19107
|
+
optionDetails = value.optionDetails.map(({ description }) => description === void 0 ? {} : { description });
|
|
19108
|
+
}
|
|
19109
|
+
request = {
|
|
19110
|
+
requestId: requestId2,
|
|
19111
|
+
method,
|
|
19112
|
+
title,
|
|
19113
|
+
options: [...value.options],
|
|
19114
|
+
...optionDetails ? { optionDetails } : {},
|
|
19115
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19116
|
+
};
|
|
19117
|
+
} else if (method === "confirm") {
|
|
19118
|
+
if (typeof value.message !== "string") {
|
|
19119
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC confirm request has no message");
|
|
19120
|
+
}
|
|
19121
|
+
request = {
|
|
19122
|
+
requestId: requestId2,
|
|
19123
|
+
method,
|
|
19124
|
+
title,
|
|
19125
|
+
message: value.message,
|
|
19126
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19127
|
+
};
|
|
19128
|
+
} else if (method === "input") {
|
|
19129
|
+
if (value.placeholder !== void 0 && typeof value.placeholder !== "string") {
|
|
19130
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC input placeholder is invalid");
|
|
19131
|
+
}
|
|
19132
|
+
request = {
|
|
19133
|
+
requestId: requestId2,
|
|
19134
|
+
method,
|
|
19135
|
+
title,
|
|
19136
|
+
...typeof value.placeholder === "string" ? { placeholder: value.placeholder } : {},
|
|
19137
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19138
|
+
};
|
|
19139
|
+
} else {
|
|
19140
|
+
if (value.prefill !== void 0 && typeof value.prefill !== "string") {
|
|
19141
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC editor prefill is invalid");
|
|
19142
|
+
}
|
|
19143
|
+
request = {
|
|
19144
|
+
requestId: requestId2,
|
|
19145
|
+
method: "editor",
|
|
19146
|
+
title,
|
|
19147
|
+
...typeof value.prefill === "string" ? { prefill: value.prefill } : {},
|
|
19148
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19168
19149
|
};
|
|
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)));
|
|
19174
|
-
}
|
|
19175
|
-
return settled;
|
|
19176
|
-
}
|
|
19177
|
-
respondToInteraction(response) {
|
|
19178
|
-
return this.#resolveInteraction(response, "cancelled" in response ? "cancelled" : "responded");
|
|
19179
|
-
}
|
|
19180
|
-
async #resolveInteraction(response, reason) {
|
|
19181
|
-
const active = this.#activeTurn;
|
|
19182
|
-
const pending = active?.interactions.get(response.requestId);
|
|
19183
|
-
if (!active || !pending || this.#closed || this.#failed) {
|
|
19184
|
-
throw new Error("Omp RPC interaction is not pending");
|
|
19185
19150
|
}
|
|
19186
|
-
|
|
19187
|
-
|
|
19151
|
+
const pending = { request, timeout: null };
|
|
19152
|
+
if (request.timeoutMs !== void 0) {
|
|
19153
|
+
pending.timeout = setTimeout(() => {
|
|
19154
|
+
if (this.#activeTurn !== active || !active.interactions.has(requestId2))
|
|
19155
|
+
return;
|
|
19156
|
+
void this.#resolveInteraction({ requestId: requestId2, cancelled: true }, "expired").catch((error51) => {
|
|
19157
|
+
if (this.#closed || this.#failed)
|
|
19158
|
+
return;
|
|
19159
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC Interaction timeout handling failed: ${message2(error51)}`));
|
|
19160
|
+
});
|
|
19161
|
+
}, request.timeoutMs);
|
|
19188
19162
|
}
|
|
19189
|
-
|
|
19190
|
-
|
|
19163
|
+
active.interactions.set(requestId2, pending);
|
|
19164
|
+
active.onEvent({ type: "interaction.requested", request });
|
|
19165
|
+
}
|
|
19166
|
+
#handleResponse(value) {
|
|
19167
|
+
const id = value.id;
|
|
19168
|
+
if (typeof id !== "string") {
|
|
19169
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response has no id"));
|
|
19170
|
+
return;
|
|
19191
19171
|
}
|
|
19192
|
-
const
|
|
19193
|
-
|
|
19194
|
-
|
|
19195
|
-
|
|
19196
|
-
|
|
19197
|
-
|
|
19198
|
-
|
|
19199
|
-
|
|
19172
|
+
const pending = this.#pending.get(id);
|
|
19173
|
+
const active = this.#activeTurn;
|
|
19174
|
+
if (!pending) {
|
|
19175
|
+
if (active?.promptId === id && value.command === "prompt" && value.success === false) {
|
|
19176
|
+
active.failure = new Error(typeof value.error === "string" ? value.error : "Omp RPC command failed");
|
|
19177
|
+
return;
|
|
19178
|
+
}
|
|
19179
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response id is not pending"));
|
|
19180
|
+
return;
|
|
19200
19181
|
}
|
|
19201
19182
|
if (pending.timeout)
|
|
19202
19183
|
clearTimeout(pending.timeout);
|
|
19203
|
-
|
|
19204
|
-
|
|
19205
|
-
|
|
19206
|
-
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19184
|
+
this.#pending.delete(id);
|
|
19185
|
+
if (value.success === true) {
|
|
19186
|
+
if (pending.command === "prompt" && active?.promptId === id && isRecord8(value.data) && value.data.agentInvoked === false) {
|
|
19187
|
+
this.#settleLocalTurn(active, { cancelled: false });
|
|
19188
|
+
}
|
|
19189
|
+
pending.resolve(value);
|
|
19190
|
+
} else {
|
|
19191
|
+
const error51 = typeof value.error === "string" ? value.error : "Omp RPC command failed";
|
|
19192
|
+
if (value.command === pending.command && error51 === `Unknown command: ${pending.command}`) {
|
|
19193
|
+
pending.reject(new OmpRpcUnsupportedCommandError(pending.command));
|
|
19194
|
+
} else {
|
|
19195
|
+
pending.reject(new Error(error51));
|
|
19196
|
+
}
|
|
19210
19197
|
}
|
|
19211
19198
|
}
|
|
19212
|
-
|
|
19213
|
-
const
|
|
19214
|
-
|
|
19215
|
-
|
|
19199
|
+
#startTool(active, value) {
|
|
19200
|
+
const callId = value.toolCallId;
|
|
19201
|
+
const toolName = value.toolName;
|
|
19202
|
+
const argumentsResult = jsonValueSchema.safeParse(value.args);
|
|
19203
|
+
if (typeof callId !== "string" || callId.length === 0 || typeof toolName !== "string" || toolName.length === 0 || !argumentsResult.success || active.tools.has(callId)) {
|
|
19204
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool start");
|
|
19216
19205
|
}
|
|
19217
|
-
|
|
19218
|
-
|
|
19219
|
-
active.
|
|
19220
|
-
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
if (this.#activeTurn !== active)
|
|
19225
|
-
return;
|
|
19226
|
-
active.cancellation = "accepted";
|
|
19227
|
-
await this.#confirmCancelledTurn(active);
|
|
19228
|
-
}).catch((error51) => {
|
|
19229
|
-
if (this.#activeTurn !== active)
|
|
19230
|
-
throw error51;
|
|
19231
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC Abort failed: ${message2(error51)}`);
|
|
19232
|
-
this.#terminateFailedCancellation(active, fault);
|
|
19233
|
-
throw fault;
|
|
19206
|
+
active.sawTool = true;
|
|
19207
|
+
active.tools.set(callId, toolName);
|
|
19208
|
+
active.onEvent({
|
|
19209
|
+
type: "tool.started",
|
|
19210
|
+
callId,
|
|
19211
|
+
toolName,
|
|
19212
|
+
arguments: argumentsResult.data
|
|
19234
19213
|
});
|
|
19235
|
-
active.abortPromise = aborting;
|
|
19236
|
-
return aborting;
|
|
19237
19214
|
}
|
|
19238
|
-
#
|
|
19239
|
-
|
|
19215
|
+
#updateTool(active, value) {
|
|
19216
|
+
const callId = value.toolCallId;
|
|
19217
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
19218
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19219
|
+
}
|
|
19220
|
+
if (!active.tools.has(callId))
|
|
19240
19221
|
return;
|
|
19241
|
-
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
this.#fail(fault);
|
|
19245
|
-
void this.close().catch(() => void 0);
|
|
19246
|
-
}
|
|
19247
|
-
close() {
|
|
19248
|
-
if (!this.#closed) {
|
|
19249
|
-
this.#closed = true;
|
|
19250
|
-
this.#rejectAll(new Error("Omp RPC Session closed"));
|
|
19222
|
+
const outputResult = jsonValueSchema.safeParse(value.partialResult ?? null);
|
|
19223
|
+
if (!outputResult.success) {
|
|
19224
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19251
19225
|
}
|
|
19252
|
-
|
|
19253
|
-
return this.#closePromise;
|
|
19226
|
+
active.onEvent({ type: "tool.updated", callId, output: outputResult.data });
|
|
19254
19227
|
}
|
|
19255
|
-
|
|
19256
|
-
const
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
signalProcessTree(child, "SIGTERM");
|
|
19264
|
-
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
19228
|
+
#completeTool(active, value) {
|
|
19229
|
+
const callId = value.toolCallId;
|
|
19230
|
+
const toolName = value.toolName;
|
|
19231
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
19232
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19233
|
+
}
|
|
19234
|
+
const expectedName = active.tools.get(callId);
|
|
19235
|
+
if (expectedName === void 0)
|
|
19265
19236
|
return;
|
|
19266
|
-
|
|
19267
|
-
if (
|
|
19268
|
-
throw new
|
|
19237
|
+
const result = jsonValueSchema.safeParse(value.result);
|
|
19238
|
+
if (typeof toolName !== "string" || expectedName !== toolName || value.isError !== void 0 && typeof value.isError !== "boolean" || !result.success) {
|
|
19239
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19269
19240
|
}
|
|
19241
|
+
active.tools.delete(callId);
|
|
19242
|
+
active.onEvent({
|
|
19243
|
+
type: "tool.completed",
|
|
19244
|
+
callId,
|
|
19245
|
+
toolName,
|
|
19246
|
+
result: result.data,
|
|
19247
|
+
isError: value.isError === true
|
|
19248
|
+
});
|
|
19270
19249
|
}
|
|
19271
|
-
#
|
|
19272
|
-
this.#
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19278
|
-
|
|
19279
|
-
|
|
19280
|
-
|
|
19281
|
-
|
|
19282
|
-
|
|
19283
|
-
|
|
19250
|
+
async #confirmCancelledTurn(active) {
|
|
19251
|
+
if (this.#activeTurn !== active || active.cancellation !== "accepted" || active.settlement === "confirming" || active.cancellationChecking)
|
|
19252
|
+
return;
|
|
19253
|
+
active.cancellationChecking = true;
|
|
19254
|
+
if (active.cancellationRecheck)
|
|
19255
|
+
clearTimeout(active.cancellationRecheck);
|
|
19256
|
+
active.cancellationRecheck = null;
|
|
19257
|
+
try {
|
|
19258
|
+
let response = await this.#send("get_state", {});
|
|
19259
|
+
if (this.#activeTurn !== active)
|
|
19260
|
+
return;
|
|
19261
|
+
if (parseSessionStreaming(response)) {
|
|
19262
|
+
await this.#send("abort", {});
|
|
19263
|
+
if (this.#activeTurn !== active)
|
|
19264
|
+
return;
|
|
19265
|
+
response = await this.#send("get_state", {});
|
|
19284
19266
|
}
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19267
|
+
let state = parseSessionState(response);
|
|
19268
|
+
if (this.#activeTurn !== active || active.cancellation !== "accepted")
|
|
19269
|
+
return;
|
|
19270
|
+
const data = sessionStateData(response);
|
|
19271
|
+
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) {
|
|
19272
|
+
await this.verifySessionCwd(this.#options.cwd);
|
|
19273
|
+
if (this.#activeTurn !== active)
|
|
19274
|
+
return;
|
|
19275
|
+
active.cancellationReloaded = true;
|
|
19276
|
+
const reset = await this.#send("new_session", {});
|
|
19277
|
+
if (this.#activeTurn !== active)
|
|
19278
|
+
return;
|
|
19279
|
+
if (!isRecord8(reset.data) || reset.data.cancelled !== false) {
|
|
19280
|
+
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reset was refused");
|
|
19281
|
+
}
|
|
19282
|
+
const reloaded = await this.#send("switch_session", { sessionPath: state.sessionFile });
|
|
19283
|
+
if (this.#activeTurn !== active)
|
|
19284
|
+
return;
|
|
19285
|
+
if (!isRecord8(reloaded.data) || reloaded.data.cancelled !== false) {
|
|
19286
|
+
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reload was refused");
|
|
19287
|
+
}
|
|
19288
|
+
const previous = state;
|
|
19289
|
+
response = await this.#send("get_state", {});
|
|
19290
|
+
state = parseSessionState(response);
|
|
19291
|
+
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile) {
|
|
19292
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity");
|
|
19293
|
+
}
|
|
19294
|
+
if (state.provider !== previous.provider || state.modelId !== previous.modelId) {
|
|
19295
|
+
if (!previous.provider || !previous.modelId) {
|
|
19296
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session has no restorable Model");
|
|
19297
|
+
}
|
|
19298
|
+
await this.#send("set_model", { provider: previous.provider, modelId: previous.modelId });
|
|
19290
19299
|
}
|
|
19291
|
-
|
|
19292
|
-
|
|
19293
|
-
|
|
19300
|
+
if (previous.thinkingLevel && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19301
|
+
await this.#send("set_thinking_level", { level: previous.thinkingLevel });
|
|
19302
|
+
}
|
|
19303
|
+
response = await this.#send("get_state", {});
|
|
19304
|
+
state = parseSessionState(response);
|
|
19305
|
+
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile || state.provider !== previous.provider || state.modelId !== previous.modelId || previous.thinkingLevel !== null && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19306
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity or configuration");
|
|
19294
19307
|
}
|
|
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
19308
|
}
|
|
19299
|
-
|
|
19309
|
+
if (!cancellationSettled(response, active.terminalEnd)) {
|
|
19310
|
+
active.settlement = "pending";
|
|
19311
|
+
active.cancellationRecheck = setTimeout(() => {
|
|
19312
|
+
active.cancellationRecheck = null;
|
|
19313
|
+
void this.#confirmCancelledTurn(active);
|
|
19314
|
+
}, 250);
|
|
19315
|
+
return;
|
|
19316
|
+
}
|
|
19317
|
+
this.#state = state;
|
|
19318
|
+
active.settlement = "confirmed";
|
|
19319
|
+
this.#finishSettledTurn(active);
|
|
19320
|
+
} catch (error51) {
|
|
19321
|
+
if (this.#activeTurn !== active)
|
|
19322
|
+
return;
|
|
19323
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC cancelled Turn state could not be confirmed: ${message2(error51)}`);
|
|
19324
|
+
this.#terminateFailedCancellation(active, fault);
|
|
19325
|
+
} finally {
|
|
19326
|
+
active.cancellationChecking = false;
|
|
19300
19327
|
}
|
|
19301
19328
|
}
|
|
19302
|
-
|
|
19303
|
-
|
|
19304
|
-
return this.#availableCommands;
|
|
19305
|
-
}
|
|
19306
|
-
#handle(value) {
|
|
19307
|
-
if (this.#closed || this.#failed)
|
|
19308
|
-
return;
|
|
19309
|
-
if (value.type === "available_commands_update") {
|
|
19310
|
-
this.#availableCommands = parseOmpAvailableCommands(value.commands);
|
|
19311
|
-
return;
|
|
19312
|
-
}
|
|
19313
|
-
if (value.type === "ready") {
|
|
19314
|
-
this.#readyResolve?.();
|
|
19315
|
-
this.#readyResolve = null;
|
|
19316
|
-
return;
|
|
19317
|
-
}
|
|
19318
|
-
if (value.type === "response") {
|
|
19319
|
-
this.#handleResponse(value);
|
|
19320
|
-
return;
|
|
19321
|
-
}
|
|
19322
|
-
if (value.type === "auto_compaction_start" || value.type === "compaction_start") {
|
|
19323
|
-
this.#compactionActive = true;
|
|
19324
|
-
this.#compactionTurn = this.#activeTurn;
|
|
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
|
-
}
|
|
19329
|
+
#settleLocalTurn(active, result) {
|
|
19330
|
+
if (this.#activeTurn !== active || active.settlement !== "pending")
|
|
19337
19331
|
return;
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
const
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19332
|
+
active.localResult = result;
|
|
19333
|
+
active.settlement = "confirming";
|
|
19334
|
+
void this.#confirmSettledTurn(active);
|
|
19335
|
+
}
|
|
19336
|
+
async #confirmSettledTurn(active) {
|
|
19337
|
+
try {
|
|
19338
|
+
const response = await this.#send("get_state", {});
|
|
19339
|
+
const state = parseSessionState(response);
|
|
19340
|
+
if (this.#activeTurn !== active)
|
|
19341
|
+
return;
|
|
19342
|
+
if (active.cancellation !== "none") {
|
|
19343
|
+
active.settlement = "pending";
|
|
19344
|
+
if (active.cancellation === "accepted")
|
|
19345
|
+
void this.#confirmCancelledTurn(active);
|
|
19346
|
+
return;
|
|
19350
19347
|
}
|
|
19351
|
-
|
|
19352
|
-
|
|
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;
|
|
19366
|
-
}
|
|
19367
|
-
const active = this.#activeTurn;
|
|
19368
|
-
if (this.#handleSubagentFrame(active, value))
|
|
19369
|
-
return;
|
|
19370
|
-
this.#observeUsage(value);
|
|
19371
|
-
if (value.type === "agent_start" && active)
|
|
19372
|
-
active.terminalEnd = false;
|
|
19373
|
-
if ((value.type === "session_settled" || value.type === "agent_start") && active?.cancellation === "accepted") {
|
|
19374
|
-
void this.#confirmCancelledTurn(active);
|
|
19375
|
-
return;
|
|
19376
|
-
}
|
|
19377
|
-
if (!active) {
|
|
19378
|
-
if (value.type === "extension_ui_request" && this.#isBlockingInteraction(value)) {
|
|
19379
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC requested blocking Extension UI outside an active Turn"));
|
|
19348
|
+
if (parseSessionStreaming(response)) {
|
|
19349
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC completed Turn state is still Streaming");
|
|
19380
19350
|
}
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
|
|
19351
|
+
this.#state = state;
|
|
19352
|
+
active.settlement = "confirmed";
|
|
19353
|
+
this.#finishSettledTurn(active);
|
|
19354
|
+
} catch (error51) {
|
|
19355
|
+
if (this.#activeTurn !== active)
|
|
19385
19356
|
return;
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
}
|
|
19389
|
-
active.text += value.text;
|
|
19390
|
-
active.onEvent({ type: "text.delta", messageId: active.promptId, delta: value.text });
|
|
19391
|
-
return;
|
|
19357
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC stable Turn state could not be confirmed: ${message2(error51)}`);
|
|
19358
|
+
this.#fail(fault);
|
|
19392
19359
|
}
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
|
|
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
|
-
}
|
|
19360
|
+
}
|
|
19361
|
+
#finishSettledTurn(active) {
|
|
19362
|
+
if (this.#activeTurn !== active || active.settlement !== "confirmed" || active.cancellation === "requesting") {
|
|
19403
19363
|
return;
|
|
19404
19364
|
}
|
|
19405
|
-
if (
|
|
19406
|
-
|
|
19365
|
+
if (active.cancellationTimeout)
|
|
19366
|
+
clearTimeout(active.cancellationTimeout);
|
|
19367
|
+
active.cancellationTimeout = null;
|
|
19368
|
+
if (active.cancellationRecheck)
|
|
19369
|
+
clearTimeout(active.cancellationRecheck);
|
|
19370
|
+
active.cancellationRecheck = null;
|
|
19371
|
+
this.#closeInteractions(active, active.cancellation === "accepted" ? "cancelled" : "superseded");
|
|
19372
|
+
if (active.tools.size > 0) {
|
|
19373
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC settled with active Tool executions"));
|
|
19407
19374
|
return;
|
|
19408
19375
|
}
|
|
19409
|
-
|
|
19410
|
-
|
|
19411
|
-
|
|
19376
|
+
this.#activeTurn = null;
|
|
19377
|
+
if (active.localResult) {
|
|
19378
|
+
active.resolve({
|
|
19379
|
+
text: active.text,
|
|
19380
|
+
agentInvoked: false,
|
|
19381
|
+
...active.localResult,
|
|
19382
|
+
cancelled: active.localResult.cancelled || active.cancellation === "accepted"
|
|
19383
|
+
});
|
|
19384
|
+
} else if (active.cancellation === "accepted") {
|
|
19385
|
+
active.resolve({ text: active.text, cancelled: true, agentInvoked: true });
|
|
19386
|
+
} else if (active.failure) {
|
|
19387
|
+
active.reject(active.failure);
|
|
19388
|
+
} else if (active.text.trim().length === 0 && !active.sawTool) {
|
|
19389
|
+
active.reject(new Error("Omp RPC settled without displayable output"));
|
|
19390
|
+
} else {
|
|
19391
|
+
active.resolve({ text: active.text, cancelled: false, agentInvoked: true });
|
|
19412
19392
|
}
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
19418
|
-
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;
|
|
19419
|
-
if (isThinking && delta !== null && delta.length > 0) {
|
|
19420
|
-
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
19421
|
-
active.reasoningMessageOpen = true;
|
|
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;
|
|
19393
|
+
}
|
|
19394
|
+
#startAssistantMessage(active, value) {
|
|
19395
|
+
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19396
|
+
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19434
19397
|
}
|
|
19435
|
-
|
|
19436
|
-
|
|
19398
|
+
const messageId = assistantMessageId(value) ?? randomUUID();
|
|
19399
|
+
active.assistantMessageId = messageId;
|
|
19400
|
+
active.sawStreamedMessageText = false;
|
|
19401
|
+
active.sawStreamedMessageReasoning = false;
|
|
19402
|
+
active.reasoningMessageOpen = false;
|
|
19403
|
+
return messageId;
|
|
19404
|
+
}
|
|
19405
|
+
#ensureAssistantMessage(active, value) {
|
|
19406
|
+
return active.assistantMessageId ?? this.#startAssistantMessage(active, value);
|
|
19407
|
+
}
|
|
19408
|
+
#finalizeAssistantMessage(active, value) {
|
|
19409
|
+
const finalText = assistantText(value);
|
|
19410
|
+
const finalReasoning = assistantReasoning(value);
|
|
19411
|
+
const failure = assistantFailure(value);
|
|
19412
|
+
const cacheHitRatePercent = optionalOmpCacheHitRatePercent(value);
|
|
19413
|
+
if (finalText === null || finalReasoning === null || failure === void 0)
|
|
19437
19414
|
return;
|
|
19438
|
-
|
|
19439
|
-
if (value.type === "turn_end") {
|
|
19440
|
-
this.#finalizeAssistantMessage(active, value.message);
|
|
19415
|
+
if (active.assistantMessageId === null && finalText === active.lastFinalizedMessageText && finalReasoning === active.lastFinalizedMessageReasoning && !active.sawStreamedMessageText && !active.sawStreamedMessageReasoning) {
|
|
19441
19416
|
return;
|
|
19442
19417
|
}
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
|
|
19418
|
+
active.failure = failure;
|
|
19419
|
+
this.#latestCacheHitRatePercent = cacheHitRatePercent;
|
|
19420
|
+
const messageId = this.#ensureAssistantMessage(active, value);
|
|
19421
|
+
if (!active.sawStreamedMessageReasoning && finalReasoning.length > 0) {
|
|
19422
|
+
active.reasoningMessageOpen = true;
|
|
19423
|
+
active.onEvent({ type: "reasoning.delta", messageId, delta: finalReasoning });
|
|
19446
19424
|
}
|
|
19447
|
-
if (
|
|
19448
|
-
|
|
19449
|
-
return;
|
|
19425
|
+
if (active.reasoningMessageOpen && active.failure === null) {
|
|
19426
|
+
active.onEvent({ type: "reasoning.completed", messageId });
|
|
19450
19427
|
}
|
|
19451
|
-
if (
|
|
19452
|
-
|
|
19453
|
-
|
|
19428
|
+
if (!active.sawStreamedMessageText && finalText.length > 0) {
|
|
19429
|
+
active.text += finalText;
|
|
19430
|
+
active.onEvent({ type: "text.delta", messageId, delta: finalText });
|
|
19454
19431
|
}
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
|
|
19462
|
-
|
|
19432
|
+
active.assistantMessageId = null;
|
|
19433
|
+
active.sawStreamedMessageText = false;
|
|
19434
|
+
active.sawStreamedMessageReasoning = false;
|
|
19435
|
+
active.reasoningMessageOpen = false;
|
|
19436
|
+
active.lastFinalizedMessageText = finalText;
|
|
19437
|
+
active.lastFinalizedMessageReasoning = finalReasoning;
|
|
19438
|
+
active.onEvent({ type: "message.completed", messageId });
|
|
19439
|
+
}
|
|
19440
|
+
#write(value) {
|
|
19441
|
+
const child = this.#child;
|
|
19442
|
+
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19443
|
+
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
19463
19444
|
}
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
|
|
19469
|
-
|
|
19470
|
-
|
|
19471
|
-
|
|
19472
|
-
|
|
19473
|
-
|
|
19474
|
-
void this.#confirmSettledTurn(active);
|
|
19445
|
+
return new Promise((resolve, reject) => {
|
|
19446
|
+
const frame = Buffer.from(`${JSON.stringify(value)}
|
|
19447
|
+
`, "utf8");
|
|
19448
|
+
child.stdin.write(frame, (error51) => error51 ? reject(error51) : resolve());
|
|
19449
|
+
});
|
|
19450
|
+
}
|
|
19451
|
+
#send(type, payload, id = `codexhost-${randomUUID()}`) {
|
|
19452
|
+
const child = this.#child;
|
|
19453
|
+
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19454
|
+
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
19475
19455
|
}
|
|
19456
|
+
return new Promise((resolve, reject) => {
|
|
19457
|
+
const pending = {
|
|
19458
|
+
command: type,
|
|
19459
|
+
resolve,
|
|
19460
|
+
reject,
|
|
19461
|
+
timeout: null
|
|
19462
|
+
};
|
|
19463
|
+
this.#pending.set(id, pending);
|
|
19464
|
+
this.#armCommandTimeout(id, pending);
|
|
19465
|
+
const frame = Buffer.from(`${JSON.stringify({ id, type, ...payload })}
|
|
19466
|
+
`, "utf8");
|
|
19467
|
+
child.stdin.write(frame, (error51) => {
|
|
19468
|
+
if (error51) {
|
|
19469
|
+
if (pending.timeout)
|
|
19470
|
+
clearTimeout(pending.timeout);
|
|
19471
|
+
this.#pending.delete(id);
|
|
19472
|
+
reject(error51);
|
|
19473
|
+
}
|
|
19474
|
+
});
|
|
19475
|
+
});
|
|
19476
19476
|
}
|
|
19477
|
-
|
|
19478
|
-
|
|
19479
|
-
if (value.type === "message_start") {
|
|
19480
|
-
this.#usageRequestStartedAtMs = null;
|
|
19477
|
+
#armCommandTimeout(id, pending) {
|
|
19478
|
+
if (pending.timeout || this.#pending.get(id) !== pending || (pending.command === "prompt" || pending.command === "compact") && this.#compactionActive) {
|
|
19481
19479
|
return;
|
|
19482
19480
|
}
|
|
19483
|
-
|
|
19484
|
-
|
|
19485
|
-
|
|
19486
|
-
|
|
19481
|
+
pending.timeout = setTimeout(() => {
|
|
19482
|
+
if (this.#pending.get(id) !== pending)
|
|
19483
|
+
return;
|
|
19484
|
+
pending.timeout = null;
|
|
19485
|
+
const error51 = new Error(`Omp RPC '${pending.command}' command timed out`);
|
|
19486
|
+
if (pending.command !== "prompt") {
|
|
19487
|
+
this.#pending.delete(id);
|
|
19488
|
+
pending.reject(error51);
|
|
19489
|
+
return;
|
|
19487
19490
|
}
|
|
19491
|
+
const fault = new OmpRpcFaultError("protocolError", error51.message);
|
|
19492
|
+
void this.#terminateTimedOutPrompt(fault);
|
|
19493
|
+
}, this.#options.commandTimeoutMs);
|
|
19494
|
+
}
|
|
19495
|
+
async #terminateTimedOutPrompt(fault) {
|
|
19496
|
+
if (this.#closed || this.#failed)
|
|
19488
19497
|
return;
|
|
19498
|
+
this.#failed = true;
|
|
19499
|
+
this.#closed = true;
|
|
19500
|
+
for (const pending of this.#pending.values()) {
|
|
19501
|
+
if (pending.timeout)
|
|
19502
|
+
clearTimeout(pending.timeout);
|
|
19503
|
+
pending.timeout = null;
|
|
19489
19504
|
}
|
|
19490
|
-
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
this.#options.onUsage?.({
|
|
19496
|
-
message: value.message,
|
|
19497
|
-
startedAtMs,
|
|
19498
|
-
completedAtMs: Date.now()
|
|
19499
|
-
});
|
|
19505
|
+
let finalFault = fault;
|
|
19506
|
+
try {
|
|
19507
|
+
await this.close();
|
|
19508
|
+
} catch (error51) {
|
|
19509
|
+
finalFault = new OmpRpcFaultError("processExited", `Omp RPC timed-out Prompt cleanup failed: ${message2(error51)}`);
|
|
19500
19510
|
}
|
|
19511
|
+
this.#rejectAll(finalFault);
|
|
19512
|
+
this.#options.onFault?.(finalFault);
|
|
19501
19513
|
}
|
|
19502
|
-
#
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
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");
|
|
19514
|
+
#closeInteractions(active, reason) {
|
|
19515
|
+
for (const [requestId2, pending] of active.interactions) {
|
|
19516
|
+
active.interactions.delete(requestId2);
|
|
19517
|
+
if (pending.timeout)
|
|
19518
|
+
clearTimeout(pending.timeout);
|
|
19519
|
+
active.onEvent({ type: "interaction.closed", requestId: requestId2, reason });
|
|
19511
19520
|
}
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
const
|
|
19515
|
-
if (
|
|
19516
|
-
|
|
19517
|
-
|
|
19521
|
+
}
|
|
19522
|
+
#rejectActiveTurn(error51) {
|
|
19523
|
+
const active = this.#activeTurn;
|
|
19524
|
+
if (!active)
|
|
19525
|
+
return;
|
|
19526
|
+
if (active.cancellationTimeout)
|
|
19527
|
+
clearTimeout(active.cancellationTimeout);
|
|
19528
|
+
if (active.cancellationRecheck)
|
|
19529
|
+
clearTimeout(active.cancellationRecheck);
|
|
19530
|
+
this.#closeInteractions(active, "cancelled");
|
|
19531
|
+
this.#activeTurn = null;
|
|
19532
|
+
active.reject(error51);
|
|
19533
|
+
}
|
|
19534
|
+
#rejectAll(error51) {
|
|
19535
|
+
if (this.#compactionTimeout)
|
|
19536
|
+
clearTimeout(this.#compactionTimeout);
|
|
19537
|
+
this.#compactionTimeout = null;
|
|
19538
|
+
for (const pending of this.#pending.values()) {
|
|
19539
|
+
if (pending.timeout)
|
|
19540
|
+
clearTimeout(pending.timeout);
|
|
19541
|
+
pending.reject(error51);
|
|
19518
19542
|
}
|
|
19519
|
-
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
|
|
19524
|
-
|
|
19525
|
-
|
|
19526
|
-
|
|
19527
|
-
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19543
|
+
this.#pending.clear();
|
|
19544
|
+
const manual = this.#manualCompaction;
|
|
19545
|
+
this.#manualCompaction = null;
|
|
19546
|
+
manual?.reject(error51);
|
|
19547
|
+
this.#rejectActiveTurn(error51);
|
|
19548
|
+
}
|
|
19549
|
+
#fail(error51) {
|
|
19550
|
+
if (this.#closed || this.#failed)
|
|
19551
|
+
return;
|
|
19552
|
+
this.#failed = true;
|
|
19553
|
+
this.#startupFaultResolve?.(error51);
|
|
19554
|
+
this.#startupFaultResolve = null;
|
|
19555
|
+
this.#rejectAll(error51);
|
|
19556
|
+
this.#options.onFault?.(error51);
|
|
19557
|
+
}
|
|
19558
|
+
};
|
|
19559
|
+
|
|
19560
|
+
// dist/omp-model-list.js
|
|
19561
|
+
var OMP_MODEL_LIST_TIMEOUT_MS = 15e3;
|
|
19562
|
+
var OMP_MODEL_LIST_OUTPUT_LIMIT = 4 * 1024 * 1024;
|
|
19563
|
+
function listOmpModels(input) {
|
|
19564
|
+
const environment = withNodeRuntimeOnPath({
|
|
19565
|
+
...process.env,
|
|
19566
|
+
...input.environment,
|
|
19567
|
+
OMP_SKIP_VERSION_CHECK: "1",
|
|
19568
|
+
OMP_TELEMETRY: "0"
|
|
19569
|
+
});
|
|
19570
|
+
const executable = resolveOmpExecutable({
|
|
19571
|
+
...input.command ? { command: input.command } : {},
|
|
19572
|
+
environment
|
|
19573
|
+
});
|
|
19574
|
+
const invocation = commandInvocation(executable, ["models", "--json"], environment);
|
|
19575
|
+
return new Promise((resolve) => {
|
|
19576
|
+
if (input.signal?.aborted)
|
|
19577
|
+
return resolve({ kind: "unanswered" });
|
|
19578
|
+
const child = spawn2(invocation.command, invocation.arguments, {
|
|
19579
|
+
cwd: input.cwd,
|
|
19580
|
+
env: environment,
|
|
19581
|
+
// A process group lets a stop reach OMP and its descendants, not only a launcher shim.
|
|
19582
|
+
detached: process.platform !== "win32",
|
|
19583
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
19584
|
+
windowsHide: true,
|
|
19585
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
19586
|
+
});
|
|
19587
|
+
let settled = false;
|
|
19588
|
+
let stdout = "";
|
|
19589
|
+
const finish = (result, stop = false) => {
|
|
19590
|
+
if (settled)
|
|
19591
|
+
return;
|
|
19592
|
+
settled = true;
|
|
19593
|
+
clearTimeout(timer);
|
|
19594
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
19595
|
+
child.stdout.removeAllListeners("data");
|
|
19596
|
+
if (stop) {
|
|
19597
|
+
child.stdout.destroy();
|
|
19598
|
+
try {
|
|
19599
|
+
signalProcessTree(child, "SIGKILL");
|
|
19600
|
+
} catch {
|
|
19601
|
+
}
|
|
19537
19602
|
}
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
}
|
|
19548
|
-
const progress = progressPayload;
|
|
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 } : {}
|
|
19603
|
+
resolve(result);
|
|
19604
|
+
};
|
|
19605
|
+
const onAbort = () => finish({ kind: "unanswered" }, true);
|
|
19606
|
+
input.signal?.addEventListener("abort", onAbort, { once: true });
|
|
19607
|
+
const timer = setTimeout(() => finish({ kind: "timedOut" }, true), input.timeoutMs ?? OMP_MODEL_LIST_TIMEOUT_MS);
|
|
19608
|
+
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
19609
|
+
stdout += chunk;
|
|
19610
|
+
if (stdout.length > OMP_MODEL_LIST_OUTPUT_LIMIT)
|
|
19611
|
+
finish({ kind: "unanswered" }, true);
|
|
19563
19612
|
});
|
|
19564
|
-
|
|
19613
|
+
child.once("error", (error51) => {
|
|
19614
|
+
finish(error51.code === "ENOENT" ? { kind: "notInstalled", message: "Oh My Pi (omp) is not installed" } : { kind: "unanswered" });
|
|
19615
|
+
});
|
|
19616
|
+
child.once("close", (code) => {
|
|
19617
|
+
if (code !== 0)
|
|
19618
|
+
return finish({ kind: "unanswered" });
|
|
19619
|
+
const models = parseOmpModelList(stdout);
|
|
19620
|
+
finish(models ? { kind: "models", models } : { kind: "unanswered" });
|
|
19621
|
+
});
|
|
19622
|
+
});
|
|
19623
|
+
}
|
|
19624
|
+
function parseOmpModelList(output) {
|
|
19625
|
+
let parsed;
|
|
19626
|
+
try {
|
|
19627
|
+
parsed = JSON.parse(output);
|
|
19628
|
+
} catch {
|
|
19629
|
+
return null;
|
|
19565
19630
|
}
|
|
19566
|
-
|
|
19567
|
-
return
|
|
19631
|
+
if (!isRecord9(parsed) || !Array.isArray(parsed.models))
|
|
19632
|
+
return null;
|
|
19633
|
+
const models = [];
|
|
19634
|
+
for (const model2 of parsed.models) {
|
|
19635
|
+
if (!isRecord9(model2) || !nonBlankString2(model2.provider) || !nonBlankString2(model2.id) || typeof model2.reasoning !== "boolean") {
|
|
19636
|
+
return null;
|
|
19637
|
+
}
|
|
19638
|
+
models.push({ provider: model2.provider, id: model2.id, reasoning: model2.reasoning });
|
|
19568
19639
|
}
|
|
19569
|
-
|
|
19570
|
-
|
|
19571
|
-
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
19577
|
-
|
|
19640
|
+
return models;
|
|
19641
|
+
}
|
|
19642
|
+
function isRecord9(value) {
|
|
19643
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19644
|
+
}
|
|
19645
|
+
function nonBlankString2(value) {
|
|
19646
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
19647
|
+
}
|
|
19648
|
+
|
|
19649
|
+
// ../../../node_modules/diff/libesm/diff/base.js
|
|
19650
|
+
var Diff = class {
|
|
19651
|
+
diff(oldStr, newStr, options = {}) {
|
|
19652
|
+
let callback;
|
|
19653
|
+
if (typeof options === "function") {
|
|
19654
|
+
callback = options;
|
|
19655
|
+
options = {};
|
|
19656
|
+
} else if ("callback" in options) {
|
|
19657
|
+
callback = options.callback;
|
|
19578
19658
|
}
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19659
|
+
const oldString = this.castInput(oldStr, options);
|
|
19660
|
+
const newString = this.castInput(newStr, options);
|
|
19661
|
+
const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
|
|
19662
|
+
const newTokens = this.removeEmpty(this.tokenize(newString, options));
|
|
19663
|
+
return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
|
|
19664
|
+
}
|
|
19665
|
+
diffWithOptionsObj(oldTokens, newTokens, options, callback) {
|
|
19666
|
+
var _a3;
|
|
19667
|
+
const done = (value) => {
|
|
19668
|
+
value = this.postProcess(value, options);
|
|
19669
|
+
if (callback) {
|
|
19670
|
+
setTimeout(function() {
|
|
19671
|
+
callback(value);
|
|
19672
|
+
}, 0);
|
|
19673
|
+
return void 0;
|
|
19674
|
+
} else {
|
|
19675
|
+
return value;
|
|
19583
19676
|
}
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19677
|
+
};
|
|
19678
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
19679
|
+
let editLength = 1;
|
|
19680
|
+
let maxEditLength = newLen + oldLen;
|
|
19681
|
+
if (options.maxEditLength != null) {
|
|
19682
|
+
maxEditLength = Math.min(maxEditLength, options.maxEditLength);
|
|
19683
|
+
}
|
|
19684
|
+
const maxExecutionTime = (_a3 = options.timeout) !== null && _a3 !== void 0 ? _a3 : Infinity;
|
|
19685
|
+
const abortAfterTimestamp = Date.now() + maxExecutionTime;
|
|
19686
|
+
const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
|
|
19687
|
+
let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
|
|
19688
|
+
if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
19689
|
+
return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
|
|
19690
|
+
}
|
|
19691
|
+
let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
|
|
19692
|
+
const execEditLength = () => {
|
|
19693
|
+
for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
|
|
19694
|
+
let basePath;
|
|
19695
|
+
const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
|
|
19696
|
+
if (removePath) {
|
|
19697
|
+
bestPath[diagonalPath - 1] = void 0;
|
|
19698
|
+
}
|
|
19699
|
+
let canAdd = false;
|
|
19700
|
+
if (addPath) {
|
|
19701
|
+
const addPathNewPos = addPath.oldPos - diagonalPath;
|
|
19702
|
+
canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
|
|
19703
|
+
}
|
|
19704
|
+
const canRemove = removePath && removePath.oldPos + 1 < oldLen;
|
|
19705
|
+
if (!canAdd && !canRemove) {
|
|
19706
|
+
bestPath[diagonalPath] = void 0;
|
|
19707
|
+
continue;
|
|
19708
|
+
}
|
|
19709
|
+
if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
|
|
19710
|
+
basePath = this.addToPath(addPath, true, false, 0, options);
|
|
19711
|
+
} else {
|
|
19712
|
+
basePath = this.addToPath(removePath, false, true, 1, options);
|
|
19713
|
+
}
|
|
19714
|
+
newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
|
|
19715
|
+
if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
19716
|
+
return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
|
|
19717
|
+
} else {
|
|
19718
|
+
bestPath[diagonalPath] = basePath;
|
|
19719
|
+
if (basePath.oldPos + 1 >= oldLen) {
|
|
19720
|
+
maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
|
|
19721
|
+
}
|
|
19722
|
+
if (newPos + 1 >= newLen) {
|
|
19723
|
+
minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
|
|
19724
|
+
}
|
|
19588
19725
|
}
|
|
19589
|
-
optionDetails = value.optionDetails.map(({ description }) => description === void 0 ? {} : { description });
|
|
19590
|
-
}
|
|
19591
|
-
request = {
|
|
19592
|
-
requestId: requestId2,
|
|
19593
|
-
method,
|
|
19594
|
-
title,
|
|
19595
|
-
options: [...value.options],
|
|
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
19726
|
}
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19727
|
+
editLength++;
|
|
19728
|
+
};
|
|
19729
|
+
if (callback) {
|
|
19730
|
+
(function exec() {
|
|
19731
|
+
setTimeout(function() {
|
|
19732
|
+
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
19733
|
+
return callback(void 0);
|
|
19734
|
+
}
|
|
19735
|
+
if (!execEditLength()) {
|
|
19736
|
+
exec();
|
|
19737
|
+
}
|
|
19738
|
+
}, 0);
|
|
19739
|
+
})();
|
|
19740
|
+
} else {
|
|
19741
|
+
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
19742
|
+
const ret = execEditLength();
|
|
19743
|
+
if (ret) {
|
|
19744
|
+
return ret;
|
|
19745
|
+
}
|
|
19613
19746
|
}
|
|
19614
|
-
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
|
|
19618
|
-
|
|
19619
|
-
|
|
19747
|
+
}
|
|
19748
|
+
}
|
|
19749
|
+
addToPath(path9, added, removed, oldPosInc, options) {
|
|
19750
|
+
const last = path9.lastComponent;
|
|
19751
|
+
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
19752
|
+
return {
|
|
19753
|
+
oldPos: path9.oldPos + oldPosInc,
|
|
19754
|
+
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
19620
19755
|
};
|
|
19621
19756
|
} else {
|
|
19622
|
-
|
|
19623
|
-
|
|
19624
|
-
|
|
19625
|
-
request = {
|
|
19626
|
-
requestId: requestId2,
|
|
19627
|
-
method: "editor",
|
|
19628
|
-
title,
|
|
19629
|
-
...typeof value.prefill === "string" ? { prefill: value.prefill } : {},
|
|
19630
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19757
|
+
return {
|
|
19758
|
+
oldPos: path9.oldPos + oldPosInc,
|
|
19759
|
+
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
19631
19760
|
};
|
|
19632
19761
|
}
|
|
19633
|
-
|
|
19634
|
-
|
|
19635
|
-
|
|
19636
|
-
|
|
19637
|
-
|
|
19638
|
-
|
|
19639
|
-
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
}
|
|
19643
|
-
}
|
|
19762
|
+
}
|
|
19763
|
+
extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
|
|
19764
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
19765
|
+
let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
|
|
19766
|
+
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
|
|
19767
|
+
newPos++;
|
|
19768
|
+
oldPos++;
|
|
19769
|
+
commonCount++;
|
|
19770
|
+
if (options.oneChangePerToken) {
|
|
19771
|
+
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
19772
|
+
}
|
|
19644
19773
|
}
|
|
19645
|
-
|
|
19646
|
-
|
|
19774
|
+
if (commonCount && !options.oneChangePerToken) {
|
|
19775
|
+
basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
19776
|
+
}
|
|
19777
|
+
basePath.oldPos = oldPos;
|
|
19778
|
+
return newPos;
|
|
19647
19779
|
}
|
|
19648
|
-
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
19652
|
-
return;
|
|
19780
|
+
equals(left, right, options) {
|
|
19781
|
+
if (options.comparator) {
|
|
19782
|
+
return options.comparator(left, right);
|
|
19783
|
+
} else {
|
|
19784
|
+
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
19653
19785
|
}
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19786
|
+
}
|
|
19787
|
+
removeEmpty(array2) {
|
|
19788
|
+
const ret = [];
|
|
19789
|
+
for (let i = 0; i < array2.length; i++) {
|
|
19790
|
+
if (array2[i]) {
|
|
19791
|
+
ret.push(array2[i]);
|
|
19660
19792
|
}
|
|
19661
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response id is not pending"));
|
|
19662
|
-
return;
|
|
19663
19793
|
}
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
|
|
19667
|
-
|
|
19668
|
-
|
|
19669
|
-
|
|
19670
|
-
|
|
19671
|
-
|
|
19672
|
-
|
|
19673
|
-
|
|
19674
|
-
|
|
19675
|
-
|
|
19794
|
+
return ret;
|
|
19795
|
+
}
|
|
19796
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
19797
|
+
castInput(value, options) {
|
|
19798
|
+
return value;
|
|
19799
|
+
}
|
|
19800
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
19801
|
+
tokenize(value, options) {
|
|
19802
|
+
return Array.from(value);
|
|
19803
|
+
}
|
|
19804
|
+
join(chars) {
|
|
19805
|
+
return chars.join("");
|
|
19806
|
+
}
|
|
19807
|
+
postProcess(changeObjects, options) {
|
|
19808
|
+
return changeObjects;
|
|
19809
|
+
}
|
|
19810
|
+
get useLongestToken() {
|
|
19811
|
+
return false;
|
|
19812
|
+
}
|
|
19813
|
+
buildValues(lastComponent, newTokens, oldTokens) {
|
|
19814
|
+
const components = [];
|
|
19815
|
+
let nextComponent;
|
|
19816
|
+
while (lastComponent) {
|
|
19817
|
+
components.push(lastComponent);
|
|
19818
|
+
nextComponent = lastComponent.previousComponent;
|
|
19819
|
+
delete lastComponent.previousComponent;
|
|
19820
|
+
lastComponent = nextComponent;
|
|
19821
|
+
}
|
|
19822
|
+
components.reverse();
|
|
19823
|
+
const componentLen = components.length;
|
|
19824
|
+
let componentPos = 0, newPos = 0, oldPos = 0;
|
|
19825
|
+
for (; componentPos < componentLen; componentPos++) {
|
|
19826
|
+
const component = components[componentPos];
|
|
19827
|
+
if (!component.removed) {
|
|
19828
|
+
if (!component.added && this.useLongestToken) {
|
|
19829
|
+
let value = newTokens.slice(newPos, newPos + component.count);
|
|
19830
|
+
value = value.map(function(value2, i) {
|
|
19831
|
+
const oldValue = oldTokens[oldPos + i];
|
|
19832
|
+
return oldValue.length > value2.length ? oldValue : value2;
|
|
19833
|
+
});
|
|
19834
|
+
component.value = this.join(value);
|
|
19835
|
+
} else {
|
|
19836
|
+
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
19837
|
+
}
|
|
19838
|
+
newPos += component.count;
|
|
19839
|
+
if (!component.added) {
|
|
19840
|
+
oldPos += component.count;
|
|
19841
|
+
}
|
|
19676
19842
|
} else {
|
|
19677
|
-
|
|
19843
|
+
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
19844
|
+
oldPos += component.count;
|
|
19678
19845
|
}
|
|
19679
19846
|
}
|
|
19847
|
+
return components;
|
|
19680
19848
|
}
|
|
19681
|
-
|
|
19682
|
-
|
|
19683
|
-
|
|
19684
|
-
|
|
19685
|
-
|
|
19686
|
-
|
|
19687
|
-
|
|
19688
|
-
active.sawTool = true;
|
|
19689
|
-
active.tools.set(callId, toolName);
|
|
19690
|
-
active.onEvent({
|
|
19691
|
-
type: "tool.started",
|
|
19692
|
-
callId,
|
|
19693
|
-
toolName,
|
|
19694
|
-
arguments: argumentsResult.data
|
|
19695
|
-
});
|
|
19849
|
+
};
|
|
19850
|
+
|
|
19851
|
+
// ../../../node_modules/diff/libesm/diff/line.js
|
|
19852
|
+
var LineDiff = class extends Diff {
|
|
19853
|
+
constructor() {
|
|
19854
|
+
super(...arguments);
|
|
19855
|
+
this.tokenize = tokenize;
|
|
19696
19856
|
}
|
|
19697
|
-
|
|
19698
|
-
|
|
19699
|
-
|
|
19700
|
-
|
|
19701
|
-
|
|
19702
|
-
|
|
19703
|
-
|
|
19704
|
-
|
|
19705
|
-
if (!
|
|
19706
|
-
|
|
19857
|
+
equals(left, right, options) {
|
|
19858
|
+
if (options.ignoreWhitespace) {
|
|
19859
|
+
if (!options.newlineIsToken || !left.includes("\n")) {
|
|
19860
|
+
left = left.trim();
|
|
19861
|
+
}
|
|
19862
|
+
if (!options.newlineIsToken || !right.includes("\n")) {
|
|
19863
|
+
right = right.trim();
|
|
19864
|
+
}
|
|
19865
|
+
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
19866
|
+
if (left.endsWith("\n")) {
|
|
19867
|
+
left = left.slice(0, -1);
|
|
19868
|
+
}
|
|
19869
|
+
if (right.endsWith("\n")) {
|
|
19870
|
+
right = right.slice(0, -1);
|
|
19871
|
+
}
|
|
19707
19872
|
}
|
|
19708
|
-
|
|
19873
|
+
return super.equals(left, right, options);
|
|
19709
19874
|
}
|
|
19710
|
-
|
|
19711
|
-
|
|
19712
|
-
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
|
|
19717
|
-
|
|
19718
|
-
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
|
|
19875
|
+
};
|
|
19876
|
+
var lineDiff = new LineDiff();
|
|
19877
|
+
function diffLines(oldStr, newStr, options) {
|
|
19878
|
+
return lineDiff.diff(oldStr, newStr, options);
|
|
19879
|
+
}
|
|
19880
|
+
function tokenize(value, options) {
|
|
19881
|
+
if (options.stripTrailingCr) {
|
|
19882
|
+
value = value.replace(/\r\n/g, "\n");
|
|
19883
|
+
}
|
|
19884
|
+
const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
|
|
19885
|
+
if (!linesAndNewlines[linesAndNewlines.length - 1]) {
|
|
19886
|
+
linesAndNewlines.pop();
|
|
19887
|
+
}
|
|
19888
|
+
for (let i = 0; i < linesAndNewlines.length; i++) {
|
|
19889
|
+
const line = linesAndNewlines[i];
|
|
19890
|
+
if (i % 2 && !options.newlineIsToken) {
|
|
19891
|
+
retLines[retLines.length - 1] += line;
|
|
19892
|
+
} else {
|
|
19893
|
+
retLines.push(line);
|
|
19722
19894
|
}
|
|
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
19895
|
}
|
|
19732
|
-
|
|
19733
|
-
|
|
19734
|
-
|
|
19735
|
-
|
|
19736
|
-
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
|
|
19740
|
-
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
19746
|
-
return;
|
|
19747
|
-
response = await this.#send("get_state", {});
|
|
19896
|
+
return retLines;
|
|
19897
|
+
}
|
|
19898
|
+
|
|
19899
|
+
// ../../../node_modules/diff/libesm/patch/parse.js
|
|
19900
|
+
function parsePatch(uniDiff) {
|
|
19901
|
+
const diffstr = uniDiff.split(/\n/), list = [];
|
|
19902
|
+
let i = 0;
|
|
19903
|
+
function parseIndex() {
|
|
19904
|
+
const index = {};
|
|
19905
|
+
list.push(index);
|
|
19906
|
+
while (i < diffstr.length) {
|
|
19907
|
+
const line = diffstr[i];
|
|
19908
|
+
if (/^(---|\+\+\+|@@)\s/.test(line)) {
|
|
19909
|
+
break;
|
|
19748
19910
|
}
|
|
19749
|
-
|
|
19750
|
-
if (
|
|
19751
|
-
|
|
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
|
-
}
|
|
19911
|
+
const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
|
|
19912
|
+
if (header) {
|
|
19913
|
+
index.index = header[1];
|
|
19790
19914
|
}
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19915
|
+
i++;
|
|
19916
|
+
}
|
|
19917
|
+
parseFileHeader(index);
|
|
19918
|
+
parseFileHeader(index);
|
|
19919
|
+
index.hunks = [];
|
|
19920
|
+
while (i < diffstr.length) {
|
|
19921
|
+
const line = diffstr[i];
|
|
19922
|
+
if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
|
|
19923
|
+
break;
|
|
19924
|
+
} else if (/^@@/.test(line)) {
|
|
19925
|
+
index.hunks.push(parseHunk());
|
|
19926
|
+
} else if (line) {
|
|
19927
|
+
throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
|
|
19928
|
+
} else {
|
|
19929
|
+
i++;
|
|
19798
19930
|
}
|
|
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
19931
|
}
|
|
19810
19932
|
}
|
|
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;
|
|
19933
|
+
function parseFileHeader(index) {
|
|
19934
|
+
const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
|
|
19935
|
+
if (fileHeader) {
|
|
19936
|
+
const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
|
|
19937
|
+
let fileName = data[0].replace(/\\\\/g, "\\");
|
|
19938
|
+
if (/^".*"$/.test(fileName)) {
|
|
19939
|
+
fileName = fileName.substr(1, fileName.length - 2);
|
|
19829
19940
|
}
|
|
19830
|
-
if (
|
|
19831
|
-
|
|
19941
|
+
if (fileHeader[1] === "---") {
|
|
19942
|
+
index.oldFileName = fileName;
|
|
19943
|
+
index.oldHeader = header;
|
|
19944
|
+
} else {
|
|
19945
|
+
index.newFileName = fileName;
|
|
19946
|
+
index.newHeader = header;
|
|
19947
|
+
}
|
|
19948
|
+
i++;
|
|
19949
|
+
}
|
|
19950
|
+
}
|
|
19951
|
+
function parseHunk() {
|
|
19952
|
+
var _a3;
|
|
19953
|
+
const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
|
19954
|
+
const hunk = {
|
|
19955
|
+
oldStart: +chunkHeader[1],
|
|
19956
|
+
oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
|
|
19957
|
+
newStart: +chunkHeader[3],
|
|
19958
|
+
newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
|
|
19959
|
+
lines: []
|
|
19960
|
+
};
|
|
19961
|
+
if (hunk.oldLines === 0) {
|
|
19962
|
+
hunk.oldStart += 1;
|
|
19963
|
+
}
|
|
19964
|
+
if (hunk.newLines === 0) {
|
|
19965
|
+
hunk.newStart += 1;
|
|
19966
|
+
}
|
|
19967
|
+
let addCount = 0, removeCount = 0;
|
|
19968
|
+
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
|
|
19969
|
+
const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
|
|
19970
|
+
if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
|
|
19971
|
+
hunk.lines.push(diffstr[i]);
|
|
19972
|
+
if (operation === "+") {
|
|
19973
|
+
addCount++;
|
|
19974
|
+
} else if (operation === "-") {
|
|
19975
|
+
removeCount++;
|
|
19976
|
+
} else if (operation === " ") {
|
|
19977
|
+
addCount++;
|
|
19978
|
+
removeCount++;
|
|
19979
|
+
}
|
|
19980
|
+
} else {
|
|
19981
|
+
throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
|
|
19832
19982
|
}
|
|
19833
|
-
this.#state = state;
|
|
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);
|
|
19841
19983
|
}
|
|
19842
|
-
|
|
19843
|
-
|
|
19844
|
-
if (this.#activeTurn !== active || active.settlement !== "confirmed" || active.cancellation === "requesting") {
|
|
19845
|
-
return;
|
|
19984
|
+
if (!addCount && hunk.newLines === 1) {
|
|
19985
|
+
hunk.newLines = 0;
|
|
19846
19986
|
}
|
|
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;
|
|
19987
|
+
if (!removeCount && hunk.oldLines === 1) {
|
|
19988
|
+
hunk.oldLines = 0;
|
|
19857
19989
|
}
|
|
19858
|
-
|
|
19859
|
-
|
|
19860
|
-
active.resolve({
|
|
19861
|
-
text: active.text,
|
|
19862
|
-
agentInvoked: false,
|
|
19863
|
-
...active.localResult,
|
|
19864
|
-
cancelled: active.localResult.cancelled || active.cancellation === "accepted"
|
|
19865
|
-
});
|
|
19866
|
-
} else if (active.cancellation === "accepted") {
|
|
19867
|
-
active.resolve({ text: active.text, cancelled: true, agentInvoked: true });
|
|
19868
|
-
} else if (active.failure) {
|
|
19869
|
-
active.reject(active.failure);
|
|
19870
|
-
} else if (active.text.trim().length === 0 && !active.sawTool) {
|
|
19871
|
-
active.reject(new Error("Omp RPC settled without displayable output"));
|
|
19872
|
-
} else {
|
|
19873
|
-
active.resolve({ text: active.text, cancelled: false, agentInvoked: true });
|
|
19990
|
+
if (addCount !== hunk.newLines) {
|
|
19991
|
+
throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
19874
19992
|
}
|
|
19875
|
-
|
|
19876
|
-
|
|
19877
|
-
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19878
|
-
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19993
|
+
if (removeCount !== hunk.oldLines) {
|
|
19994
|
+
throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
19879
19995
|
}
|
|
19880
|
-
|
|
19881
|
-
active.assistantMessageId = messageId;
|
|
19882
|
-
active.sawStreamedMessageText = false;
|
|
19883
|
-
active.sawStreamedMessageReasoning = false;
|
|
19884
|
-
active.reasoningMessageOpen = false;
|
|
19885
|
-
return messageId;
|
|
19996
|
+
return hunk;
|
|
19886
19997
|
}
|
|
19887
|
-
|
|
19888
|
-
|
|
19998
|
+
while (i < diffstr.length) {
|
|
19999
|
+
parseIndex();
|
|
19889
20000
|
}
|
|
19890
|
-
|
|
19891
|
-
|
|
19892
|
-
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19896
|
-
|
|
19897
|
-
|
|
20001
|
+
return list;
|
|
20002
|
+
}
|
|
20003
|
+
|
|
20004
|
+
// ../../../node_modules/diff/libesm/patch/create.js
|
|
20005
|
+
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
20006
|
+
let optionsObj;
|
|
20007
|
+
if (!options) {
|
|
20008
|
+
optionsObj = {};
|
|
20009
|
+
} else if (typeof options === "function") {
|
|
20010
|
+
optionsObj = { callback: options };
|
|
20011
|
+
} else {
|
|
20012
|
+
optionsObj = options;
|
|
20013
|
+
}
|
|
20014
|
+
if (typeof optionsObj.context === "undefined") {
|
|
20015
|
+
optionsObj.context = 4;
|
|
20016
|
+
}
|
|
20017
|
+
const context = optionsObj.context;
|
|
20018
|
+
if (optionsObj.newlineIsToken) {
|
|
20019
|
+
throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
|
|
20020
|
+
}
|
|
20021
|
+
if (!optionsObj.callback) {
|
|
20022
|
+
return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
|
|
20023
|
+
} else {
|
|
20024
|
+
const { callback } = optionsObj;
|
|
20025
|
+
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
|
20026
|
+
const patch = diffLinesResultToPatch(diff);
|
|
20027
|
+
callback(patch);
|
|
20028
|
+
} }));
|
|
20029
|
+
}
|
|
20030
|
+
function diffLinesResultToPatch(diff) {
|
|
20031
|
+
if (!diff) {
|
|
19898
20032
|
return;
|
|
19899
20033
|
}
|
|
19900
|
-
|
|
19901
|
-
|
|
19902
|
-
|
|
19903
|
-
|
|
19904
|
-
|
|
19905
|
-
active.onEvent({ type: "reasoning.delta", messageId, delta: finalReasoning });
|
|
20034
|
+
diff.push({ value: "", lines: [] });
|
|
20035
|
+
function contextLines(lines) {
|
|
20036
|
+
return lines.map(function(entry) {
|
|
20037
|
+
return " " + entry;
|
|
20038
|
+
});
|
|
19906
20039
|
}
|
|
19907
|
-
|
|
19908
|
-
|
|
20040
|
+
const hunks = [];
|
|
20041
|
+
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
|
20042
|
+
for (let i = 0; i < diff.length; i++) {
|
|
20043
|
+
const current = diff[i], lines = current.lines || splitLines(current.value);
|
|
20044
|
+
current.lines = lines;
|
|
20045
|
+
if (current.added || current.removed) {
|
|
20046
|
+
if (!oldRangeStart) {
|
|
20047
|
+
const prev = diff[i - 1];
|
|
20048
|
+
oldRangeStart = oldLine;
|
|
20049
|
+
newRangeStart = newLine;
|
|
20050
|
+
if (prev) {
|
|
20051
|
+
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
|
|
20052
|
+
oldRangeStart -= curRange.length;
|
|
20053
|
+
newRangeStart -= curRange.length;
|
|
20054
|
+
}
|
|
20055
|
+
}
|
|
20056
|
+
for (const line of lines) {
|
|
20057
|
+
curRange.push((current.added ? "+" : "-") + line);
|
|
20058
|
+
}
|
|
20059
|
+
if (current.added) {
|
|
20060
|
+
newLine += lines.length;
|
|
20061
|
+
} else {
|
|
20062
|
+
oldLine += lines.length;
|
|
20063
|
+
}
|
|
20064
|
+
} else {
|
|
20065
|
+
if (oldRangeStart) {
|
|
20066
|
+
if (lines.length <= context * 2 && i < diff.length - 2) {
|
|
20067
|
+
for (const line of contextLines(lines)) {
|
|
20068
|
+
curRange.push(line);
|
|
20069
|
+
}
|
|
20070
|
+
} else {
|
|
20071
|
+
const contextSize = Math.min(lines.length, context);
|
|
20072
|
+
for (const line of contextLines(lines.slice(0, contextSize))) {
|
|
20073
|
+
curRange.push(line);
|
|
20074
|
+
}
|
|
20075
|
+
const hunk = {
|
|
20076
|
+
oldStart: oldRangeStart,
|
|
20077
|
+
oldLines: oldLine - oldRangeStart + contextSize,
|
|
20078
|
+
newStart: newRangeStart,
|
|
20079
|
+
newLines: newLine - newRangeStart + contextSize,
|
|
20080
|
+
lines: curRange
|
|
20081
|
+
};
|
|
20082
|
+
hunks.push(hunk);
|
|
20083
|
+
oldRangeStart = 0;
|
|
20084
|
+
newRangeStart = 0;
|
|
20085
|
+
curRange = [];
|
|
20086
|
+
}
|
|
20087
|
+
}
|
|
20088
|
+
oldLine += lines.length;
|
|
20089
|
+
newLine += lines.length;
|
|
20090
|
+
}
|
|
19909
20091
|
}
|
|
19910
|
-
|
|
19911
|
-
|
|
19912
|
-
|
|
20092
|
+
for (const hunk of hunks) {
|
|
20093
|
+
for (let i = 0; i < hunk.lines.length; i++) {
|
|
20094
|
+
if (hunk.lines[i].endsWith("\n")) {
|
|
20095
|
+
hunk.lines[i] = hunk.lines[i].slice(0, -1);
|
|
20096
|
+
} else {
|
|
20097
|
+
hunk.lines.splice(i + 1, 0, "\");
|
|
20098
|
+
i++;
|
|
20099
|
+
}
|
|
20100
|
+
}
|
|
19913
20101
|
}
|
|
19914
|
-
|
|
19915
|
-
|
|
19916
|
-
|
|
19917
|
-
|
|
19918
|
-
|
|
19919
|
-
|
|
19920
|
-
|
|
20102
|
+
return {
|
|
20103
|
+
oldFileName,
|
|
20104
|
+
newFileName,
|
|
20105
|
+
oldHeader,
|
|
20106
|
+
newHeader,
|
|
20107
|
+
hunks
|
|
20108
|
+
};
|
|
19921
20109
|
}
|
|
19922
|
-
|
|
19923
|
-
|
|
19924
|
-
|
|
19925
|
-
|
|
19926
|
-
}
|
|
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
|
-
});
|
|
20110
|
+
}
|
|
20111
|
+
function formatPatch(patch) {
|
|
20112
|
+
if (Array.isArray(patch)) {
|
|
20113
|
+
return patch.map(formatPatch).join("\n");
|
|
19932
20114
|
}
|
|
19933
|
-
|
|
19934
|
-
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
|
|
19938
|
-
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
|
|
19947
|
-
|
|
19948
|
-
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
|
|
19952
|
-
clearTimeout(pending.timeout);
|
|
19953
|
-
this.#pending.delete(id);
|
|
19954
|
-
reject(error51);
|
|
19955
|
-
}
|
|
19956
|
-
});
|
|
19957
|
-
});
|
|
20115
|
+
const ret = [];
|
|
20116
|
+
if (patch.oldFileName == patch.newFileName) {
|
|
20117
|
+
ret.push("Index: " + patch.oldFileName);
|
|
20118
|
+
}
|
|
20119
|
+
ret.push("===================================================================");
|
|
20120
|
+
ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
|
|
20121
|
+
ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
|
|
20122
|
+
for (let i = 0; i < patch.hunks.length; i++) {
|
|
20123
|
+
const hunk = patch.hunks[i];
|
|
20124
|
+
if (hunk.oldLines === 0) {
|
|
20125
|
+
hunk.oldStart -= 1;
|
|
20126
|
+
}
|
|
20127
|
+
if (hunk.newLines === 0) {
|
|
20128
|
+
hunk.newStart -= 1;
|
|
20129
|
+
}
|
|
20130
|
+
ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
|
|
20131
|
+
for (const line of hunk.lines) {
|
|
20132
|
+
ret.push(line);
|
|
20133
|
+
}
|
|
19958
20134
|
}
|
|
19959
|
-
|
|
19960
|
-
|
|
20135
|
+
return ret.join("\n") + "\n";
|
|
20136
|
+
}
|
|
20137
|
+
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
20138
|
+
if (typeof options === "function") {
|
|
20139
|
+
options = { callback: options };
|
|
20140
|
+
}
|
|
20141
|
+
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
|
|
20142
|
+
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
20143
|
+
if (!patchObj) {
|
|
19961
20144
|
return;
|
|
19962
20145
|
}
|
|
19963
|
-
|
|
19964
|
-
|
|
19965
|
-
|
|
19966
|
-
|
|
19967
|
-
|
|
19968
|
-
|
|
19969
|
-
|
|
19970
|
-
|
|
19971
|
-
return;
|
|
20146
|
+
return formatPatch(patchObj);
|
|
20147
|
+
} else {
|
|
20148
|
+
const { callback } = options;
|
|
20149
|
+
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
|
|
20150
|
+
if (!patchObj) {
|
|
20151
|
+
callback(void 0);
|
|
20152
|
+
} else {
|
|
20153
|
+
callback(formatPatch(patchObj));
|
|
19972
20154
|
}
|
|
19973
|
-
|
|
19974
|
-
void this.#terminateTimedOutPrompt(fault);
|
|
19975
|
-
}, this.#options.commandTimeoutMs);
|
|
20155
|
+
} }));
|
|
19976
20156
|
}
|
|
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);
|
|
20157
|
+
}
|
|
20158
|
+
function splitLines(text) {
|
|
20159
|
+
const hasTrailingNl = text.endsWith("\n");
|
|
20160
|
+
const result = text.split("\n").map((line) => line + "\n");
|
|
20161
|
+
if (hasTrailingNl) {
|
|
20162
|
+
result.pop();
|
|
20163
|
+
} else {
|
|
20164
|
+
result.push(result.pop().slice(0, -1));
|
|
19995
20165
|
}
|
|
19996
|
-
|
|
19997
|
-
|
|
19998
|
-
|
|
19999
|
-
|
|
20000
|
-
|
|
20001
|
-
|
|
20002
|
-
|
|
20166
|
+
return result;
|
|
20167
|
+
}
|
|
20168
|
+
|
|
20169
|
+
// dist/omp-adapter.js
|
|
20170
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
20171
|
+
import { realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
20172
|
+
import path7 from "node:path";
|
|
20173
|
+
|
|
20174
|
+
// dist/omp-last-turn-rollback.js
|
|
20175
|
+
function modelFromState(state) {
|
|
20176
|
+
if (state.provider === null && state.modelId === null)
|
|
20177
|
+
return null;
|
|
20178
|
+
if (state.provider === null || state.modelId === null) {
|
|
20179
|
+
throw new Error("Omp state contains a partial Model identity");
|
|
20003
20180
|
}
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20012
|
-
|
|
20013
|
-
|
|
20014
|
-
|
|
20181
|
+
return { provider: state.provider, id: state.modelId };
|
|
20182
|
+
}
|
|
20183
|
+
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
20184
|
+
const startupState = transport.state;
|
|
20185
|
+
const startupSessionId = startupState.sessionId;
|
|
20186
|
+
const currentModel = modelFromState(startupState);
|
|
20187
|
+
const currentThinking = startupState.thinkingLevel;
|
|
20188
|
+
const copiedHistory = await transport.getEntries();
|
|
20189
|
+
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
20190
|
+
if (!boundary)
|
|
20191
|
+
return { ok: false, reason: "empty" };
|
|
20192
|
+
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
20193
|
+
sessionId: startupSessionId,
|
|
20194
|
+
model: currentModel
|
|
20195
|
+
});
|
|
20196
|
+
let state = await transport.fork(boundary.lastUserEntryId);
|
|
20197
|
+
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
20198
|
+
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
20015
20199
|
}
|
|
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);
|
|
20200
|
+
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
20201
|
+
if (!currentModel)
|
|
20202
|
+
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
20203
|
+
state = await transport.selectModel(currentModel);
|
|
20030
20204
|
}
|
|
20031
|
-
|
|
20032
|
-
if (
|
|
20033
|
-
|
|
20034
|
-
|
|
20035
|
-
this.#startupFaultResolve?.(error51);
|
|
20036
|
-
this.#startupFaultResolve = null;
|
|
20037
|
-
this.#rejectAll(error51);
|
|
20038
|
-
this.#options.onFault?.(error51);
|
|
20205
|
+
if (state.thinkingLevel !== currentThinking) {
|
|
20206
|
+
if (!currentThinking)
|
|
20207
|
+
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
20208
|
+
state = await transport.selectThinkingOption(currentThinking);
|
|
20039
20209
|
}
|
|
20040
|
-
|
|
20210
|
+
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
20211
|
+
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
20212
|
+
}
|
|
20213
|
+
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
20214
|
+
sessionId: state.sessionId,
|
|
20215
|
+
model: modelFromState(state)
|
|
20216
|
+
});
|
|
20217
|
+
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
20218
|
+
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
20219
|
+
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
20220
|
+
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
20221
|
+
}
|
|
20222
|
+
await transport.verifySessionCwd(cwd);
|
|
20223
|
+
return { ok: true };
|
|
20224
|
+
}
|
|
20041
20225
|
|
|
20042
20226
|
// dist/omp-permission-modes.js
|
|
20043
20227
|
var nativePermissionModes = /* @__PURE__ */ new Set(["always-ask", "write", "yolo"]);
|
|
@@ -20190,6 +20374,24 @@ var OmpSubagentLifecycle = class {
|
|
|
20190
20374
|
};
|
|
20191
20375
|
|
|
20192
20376
|
// dist/omp-adapter.js
|
|
20377
|
+
function closedInspection() {
|
|
20378
|
+
return {
|
|
20379
|
+
status: "unavailable",
|
|
20380
|
+
error: { code: "invalidState", message: "Omp Adapter is closed", retryable: false }
|
|
20381
|
+
};
|
|
20382
|
+
}
|
|
20383
|
+
function ompInspectionCapabilities(selectThinkingOption) {
|
|
20384
|
+
return {
|
|
20385
|
+
configuration: {
|
|
20386
|
+
selectModel: true,
|
|
20387
|
+
selectThinkingOption,
|
|
20388
|
+
selectPermissionMode: true,
|
|
20389
|
+
permissionModeScope: "live"
|
|
20390
|
+
},
|
|
20391
|
+
history: { fork: true, forkAcrossCwd: true, rollbackLastTurn: true },
|
|
20392
|
+
subagents: { observe: true, readTranscript: true }
|
|
20393
|
+
};
|
|
20394
|
+
}
|
|
20193
20395
|
var ompHarnessId2 = harnessIdSchema.parse("omp");
|
|
20194
20396
|
var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
20195
20397
|
commands: [
|
|
@@ -20204,7 +20406,7 @@ var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
|
20204
20406
|
]
|
|
20205
20407
|
});
|
|
20206
20408
|
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
20207
|
-
function
|
|
20409
|
+
function isRecord10(value) {
|
|
20208
20410
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20209
20411
|
}
|
|
20210
20412
|
function errorMessage(error51) {
|
|
@@ -20219,7 +20421,7 @@ var OmpAdapterFaultError = class extends Error {
|
|
|
20219
20421
|
}
|
|
20220
20422
|
};
|
|
20221
20423
|
function normalizedError(error51, fallbackCode) {
|
|
20222
|
-
if (
|
|
20424
|
+
if (isRecord10(error51) && error51.code === "ENOENT") {
|
|
20223
20425
|
return { code: "notInstalled", message: errorMessage(error51), retryable: false };
|
|
20224
20426
|
}
|
|
20225
20427
|
if (error51 instanceof OmpAdapterFaultError)
|
|
@@ -20296,7 +20498,7 @@ function nativeModelForHistory(state) {
|
|
|
20296
20498
|
return nativeModelFromState(state);
|
|
20297
20499
|
}
|
|
20298
20500
|
function sessionFileFromRef(ref) {
|
|
20299
|
-
if (ref.harnessId !== ompHarnessId2 || !
|
|
20501
|
+
if (ref.harnessId !== ompHarnessId2 || !isRecord10(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
|
|
20300
20502
|
throw new Error("Omp Native Session Ref has no resumable Session file");
|
|
20301
20503
|
}
|
|
20302
20504
|
return ref.locator.sessionFile;
|
|
@@ -20351,9 +20553,9 @@ function toolFailure(toolName) {
|
|
|
20351
20553
|
function nativeText(value) {
|
|
20352
20554
|
if (typeof value === "string")
|
|
20353
20555
|
return value;
|
|
20354
|
-
if (!
|
|
20556
|
+
if (!isRecord10(value) || !Array.isArray(value.content))
|
|
20355
20557
|
return "";
|
|
20356
|
-
return value.content.filter((content) =>
|
|
20558
|
+
return value.content.filter((content) => isRecord10(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
|
|
20357
20559
|
}
|
|
20358
20560
|
function boundedOutput(value, limit) {
|
|
20359
20561
|
const text = nativeText(value);
|
|
@@ -20369,17 +20571,17 @@ function outputText(output) {
|
|
|
20369
20571
|
return output?.content.filter((content) => content.type === "text").map(({ text }) => text).join("") ?? "";
|
|
20370
20572
|
}
|
|
20371
20573
|
function stringField2(value, key) {
|
|
20372
|
-
if (!
|
|
20574
|
+
if (!isRecord10(value))
|
|
20373
20575
|
return void 0;
|
|
20374
20576
|
const field = value[key];
|
|
20375
20577
|
if (typeof field === "string" && field.length > 0)
|
|
20376
20578
|
return field;
|
|
20377
|
-
if (
|
|
20579
|
+
if (isRecord10(value.input)) {
|
|
20378
20580
|
const nested = value.input[key];
|
|
20379
20581
|
if (typeof nested === "string" && nested.length > 0)
|
|
20380
20582
|
return nested;
|
|
20381
20583
|
}
|
|
20382
|
-
if (
|
|
20584
|
+
if (isRecord10(value.arguments)) {
|
|
20383
20585
|
const nested = value.arguments[key];
|
|
20384
20586
|
if (typeof nested === "string" && nested.length > 0)
|
|
20385
20587
|
return nested;
|
|
@@ -20387,7 +20589,7 @@ function stringField2(value, key) {
|
|
|
20387
20589
|
return void 0;
|
|
20388
20590
|
}
|
|
20389
20591
|
function numberField(value, key) {
|
|
20390
|
-
if (!
|
|
20592
|
+
if (!isRecord10(value))
|
|
20391
20593
|
return void 0;
|
|
20392
20594
|
const field = value[key];
|
|
20393
20595
|
return typeof field === "number" || field === null ? field : void 0;
|
|
@@ -20426,7 +20628,7 @@ function fileMutatingKind(toolName) {
|
|
|
20426
20628
|
return null;
|
|
20427
20629
|
}
|
|
20428
20630
|
function nestedToolString(value, keys) {
|
|
20429
|
-
if (!
|
|
20631
|
+
if (!isRecord10(value))
|
|
20430
20632
|
return void 0;
|
|
20431
20633
|
for (const key of keys) {
|
|
20432
20634
|
const field = value[key];
|
|
@@ -20441,14 +20643,14 @@ function nestedToolString(value, keys) {
|
|
|
20441
20643
|
return void 0;
|
|
20442
20644
|
}
|
|
20443
20645
|
function patchFromResult(result) {
|
|
20444
|
-
if (!
|
|
20646
|
+
if (!isRecord10(result))
|
|
20445
20647
|
return void 0;
|
|
20446
20648
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
20447
20649
|
const field = result[key];
|
|
20448
20650
|
if (typeof field === "string" && field.length > 0)
|
|
20449
20651
|
return field;
|
|
20450
20652
|
}
|
|
20451
|
-
if (
|
|
20653
|
+
if (isRecord10(result.details)) {
|
|
20452
20654
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
20453
20655
|
const field = result.details[key];
|
|
20454
20656
|
if (typeof field === "string" && field.length > 0)
|
|
@@ -20575,9 +20777,6 @@ var OmpHarnessSession = class {
|
|
|
20575
20777
|
#usage;
|
|
20576
20778
|
#usageGeneration = 0;
|
|
20577
20779
|
#usageRefreshSequence = 0;
|
|
20578
|
-
#backgroundTurnId = null;
|
|
20579
|
-
#backgroundSubagents = /* @__PURE__ */ new Map();
|
|
20580
|
-
#backgroundTurnFailed = false;
|
|
20581
20780
|
constructor(cwd, createTransport, onClosed, options) {
|
|
20582
20781
|
this.#cwd = cwd;
|
|
20583
20782
|
this.#createTransport = createTransport;
|
|
@@ -20635,44 +20834,6 @@ var OmpHarnessSession = class {
|
|
|
20635
20834
|
#backgroundStatus(status) {
|
|
20636
20835
|
return status === "pending" || status === "running" ? "running" : status === "interrupted" ? "interrupted" : status;
|
|
20637
20836
|
}
|
|
20638
|
-
#ensureBackgroundTurn() {
|
|
20639
|
-
if (this.#backgroundTurnId)
|
|
20640
|
-
return this.#backgroundTurnId;
|
|
20641
|
-
const turnId = hostTurnIdSchema.parse(randomUUID2());
|
|
20642
|
-
this.#backgroundTurnId = turnId;
|
|
20643
|
-
this.#backgroundTurnFailed = false;
|
|
20644
|
-
this.#event({
|
|
20645
|
-
type: "turn.autonomous.started",
|
|
20646
|
-
turnId,
|
|
20647
|
-
input: []
|
|
20648
|
-
});
|
|
20649
|
-
return turnId;
|
|
20650
|
-
}
|
|
20651
|
-
#backgroundDelegationStart(event) {
|
|
20652
|
-
const turnId = this.#ensureBackgroundTurn();
|
|
20653
|
-
const description = event.type === "subagent.started" ? event.description : event.type === "subagent.updated" ? event.description ?? "Background subagent" : "Background subagent";
|
|
20654
|
-
const role = event.type === "subagent.started" ? event.role : void 0;
|
|
20655
|
-
const background = event.type === "subagent.started" ? event.background : true;
|
|
20656
|
-
const state = {
|
|
20657
|
-
subagentId: event.nativeSubagentId,
|
|
20658
|
-
nativeSubagentId: event.nativeSubagentId,
|
|
20659
|
-
description,
|
|
20660
|
-
...role ? { role } : {},
|
|
20661
|
-
background,
|
|
20662
|
-
status: "running"
|
|
20663
|
-
};
|
|
20664
|
-
const item = {
|
|
20665
|
-
type: "subagentDelegation",
|
|
20666
|
-
itemId: this.#newItemId(),
|
|
20667
|
-
operation: "spawn",
|
|
20668
|
-
...event.type === "subagent.started" && event.prompt ? { prompt: event.prompt } : {},
|
|
20669
|
-
subagents: [state]
|
|
20670
|
-
};
|
|
20671
|
-
const delegation = { item, turnId };
|
|
20672
|
-
this.#backgroundSubagents.set(event.callId, delegation);
|
|
20673
|
-
this.#event({ type: "item.started", turnId, item });
|
|
20674
|
-
return delegation;
|
|
20675
|
-
}
|
|
20676
20837
|
#handleBackgroundSubagentEvent(event) {
|
|
20677
20838
|
if (event.type === "subagent.transcript.changed") {
|
|
20678
20839
|
this.#event({
|
|
@@ -20684,12 +20845,6 @@ var OmpHarnessSession = class {
|
|
|
20684
20845
|
if (event.type !== "subagent.started" && event.type !== "subagent.updated" && event.type !== "subagent.completed") {
|
|
20685
20846
|
return;
|
|
20686
20847
|
}
|
|
20687
|
-
let delegation = this.#backgroundSubagents.get(event.callId);
|
|
20688
|
-
if (!delegation)
|
|
20689
|
-
delegation = this.#backgroundDelegationStart(event);
|
|
20690
|
-
const current = delegation.item.subagents[0];
|
|
20691
|
-
if (!current)
|
|
20692
|
-
throw new Error("Omp background delegation has no Agent state");
|
|
20693
20848
|
if (event.type === "subagent.started") {
|
|
20694
20849
|
this.#event({
|
|
20695
20850
|
type: "subagent.state.changed",
|
|
@@ -20700,19 +20855,6 @@ var OmpHarnessSession = class {
|
|
|
20700
20855
|
}
|
|
20701
20856
|
if (event.type === "subagent.updated") {
|
|
20702
20857
|
const status2 = this.#backgroundStatus(event.status);
|
|
20703
|
-
const subagent2 = {
|
|
20704
|
-
...current,
|
|
20705
|
-
status: status2,
|
|
20706
|
-
...event.description ? { description: event.description } : {},
|
|
20707
|
-
...event.resultSummary ? { resultSummary: event.resultSummary } : {}
|
|
20708
|
-
};
|
|
20709
|
-
delegation.item = { ...delegation.item, subagents: [subagent2] };
|
|
20710
|
-
this.#event({
|
|
20711
|
-
type: "item.updated",
|
|
20712
|
-
turnId: delegation.turnId,
|
|
20713
|
-
itemId: delegation.item.itemId,
|
|
20714
|
-
update: { type: "subagents.replace", subagents: delegation.item.subagents }
|
|
20715
|
-
});
|
|
20716
20858
|
this.#event({
|
|
20717
20859
|
type: "subagent.state.changed",
|
|
20718
20860
|
nativeSubagentId: event.nativeSubagentId,
|
|
@@ -20722,58 +20864,12 @@ var OmpHarnessSession = class {
|
|
|
20722
20864
|
return;
|
|
20723
20865
|
}
|
|
20724
20866
|
const status = event.isError ? "failed" : "completed";
|
|
20725
|
-
const subagent = {
|
|
20726
|
-
...current,
|
|
20727
|
-
status,
|
|
20728
|
-
...event.resultSummary ? { resultSummary: event.resultSummary } : {}
|
|
20729
|
-
};
|
|
20730
|
-
delegation.item = { ...delegation.item, subagents: [subagent] };
|
|
20731
|
-
this.#event({
|
|
20732
|
-
type: "item.updated",
|
|
20733
|
-
turnId: delegation.turnId,
|
|
20734
|
-
itemId: delegation.item.itemId,
|
|
20735
|
-
update: { type: "subagents.replace", subagents: delegation.item.subagents }
|
|
20736
|
-
});
|
|
20737
|
-
this.#event({
|
|
20738
|
-
type: "item.completed",
|
|
20739
|
-
turnId: delegation.turnId,
|
|
20740
|
-
snapshot: {
|
|
20741
|
-
item: delegation.item,
|
|
20742
|
-
outcome: event.isError ? {
|
|
20743
|
-
status: "failed",
|
|
20744
|
-
error: {
|
|
20745
|
-
code: "nativeFailure",
|
|
20746
|
-
message: "Omp background Subagent failed",
|
|
20747
|
-
retryable: false
|
|
20748
|
-
}
|
|
20749
|
-
} : { status: "succeeded" }
|
|
20750
|
-
}
|
|
20751
|
-
});
|
|
20752
20867
|
this.#event({
|
|
20753
20868
|
type: "subagent.state.changed",
|
|
20754
20869
|
nativeSubagentId: event.nativeSubagentId,
|
|
20755
20870
|
status,
|
|
20756
20871
|
...event.resultSummary ? { resultSummary: event.resultSummary } : {}
|
|
20757
20872
|
});
|
|
20758
|
-
this.#backgroundTurnFailed ||= event.isError;
|
|
20759
|
-
this.#backgroundSubagents.delete(event.callId);
|
|
20760
|
-
if (this.#backgroundSubagents.size === 0 && this.#backgroundTurnId === delegation.turnId) {
|
|
20761
|
-
const turnId = this.#backgroundTurnId;
|
|
20762
|
-
this.#backgroundTurnId = null;
|
|
20763
|
-
this.#event({
|
|
20764
|
-
type: "turn.completed",
|
|
20765
|
-
turnId,
|
|
20766
|
-
outcome: this.#backgroundTurnFailed ? {
|
|
20767
|
-
status: "failed",
|
|
20768
|
-
error: {
|
|
20769
|
-
code: "nativeFailure",
|
|
20770
|
-
message: "Omp background Subagent failed",
|
|
20771
|
-
retryable: false
|
|
20772
|
-
}
|
|
20773
|
-
} : { status: "succeeded" }
|
|
20774
|
-
});
|
|
20775
|
-
this.#backgroundTurnFailed = false;
|
|
20776
|
-
}
|
|
20777
20873
|
}
|
|
20778
20874
|
async readSnapshot() {
|
|
20779
20875
|
if (this.#phase !== "open" && this.#phase !== "faulted") {
|
|
@@ -20828,6 +20924,8 @@ var OmpHarnessSession = class {
|
|
|
20828
20924
|
}
|
|
20829
20925
|
if (command.type === "turn.cancel")
|
|
20830
20926
|
return this.#cancel(command);
|
|
20927
|
+
if (command.type === "turn.steer")
|
|
20928
|
+
return unsupportedSteer("OMP");
|
|
20831
20929
|
if (command.type === "interaction.respond")
|
|
20832
20930
|
return this.#respond(command);
|
|
20833
20931
|
if (command.type === "model.select")
|
|
@@ -22023,6 +22121,9 @@ var OmpAdapter = class {
|
|
|
22023
22121
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
22024
22122
|
#inspectionInFlight = /* @__PURE__ */ new Map();
|
|
22025
22123
|
#inspections = /* @__PURE__ */ new Set();
|
|
22124
|
+
#availabilityInFlight = /* @__PURE__ */ new Map();
|
|
22125
|
+
#availabilityListings = /* @__PURE__ */ new Set();
|
|
22126
|
+
#listModels;
|
|
22026
22127
|
#sessions = /* @__PURE__ */ new Set();
|
|
22027
22128
|
#toolOutputLimit;
|
|
22028
22129
|
#closePromise = null;
|
|
@@ -22031,22 +22132,21 @@ var OmpAdapter = class {
|
|
|
22031
22132
|
createTransport: (sessionOptions) => new OmpRpcSession({ ...options, ...sessionOptions })
|
|
22032
22133
|
}) {
|
|
22033
22134
|
this.#createTransport = dependencies.createTransport;
|
|
22135
|
+
const listModels = dependencies.listModels ?? listOmpModels;
|
|
22136
|
+
this.#listModels = ({ cwd, signal }) => listModels({
|
|
22137
|
+
cwd,
|
|
22138
|
+
signal,
|
|
22139
|
+
...options.command ? { command: options.command } : {},
|
|
22140
|
+
...options.environment ? { environment: options.environment } : {}
|
|
22141
|
+
});
|
|
22034
22142
|
this.sessionImport = new OmpSessionImport({ ...process.env, ...options.environment });
|
|
22035
22143
|
this.usageStatistics = createOmpUsageStatistics({ ...process.env, ...options.environment });
|
|
22036
22144
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? 2e3;
|
|
22037
22145
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT;
|
|
22038
22146
|
}
|
|
22039
22147
|
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
|
-
}
|
|
22148
|
+
if (this.#closePromise)
|
|
22149
|
+
return closedInspection();
|
|
22050
22150
|
const cwd = input.cwd ?? process.cwd();
|
|
22051
22151
|
const inFlight = this.#inspectionInFlight.get(cwd);
|
|
22052
22152
|
if (inFlight)
|
|
@@ -22056,6 +22156,37 @@ var OmpAdapter = class {
|
|
|
22056
22156
|
if (cached2)
|
|
22057
22157
|
return cached2;
|
|
22058
22158
|
}
|
|
22159
|
+
if (input.purpose === "availability")
|
|
22160
|
+
return this.#inspectAvailability(cwd, input.refresh);
|
|
22161
|
+
return this.#startFullInspection(cwd);
|
|
22162
|
+
}
|
|
22163
|
+
/**
|
|
22164
|
+
* Availability without a Session: a Session startup runs OMP's own startup work, including
|
|
22165
|
+
* Provider connection prewarm, for a Harness the user may never select. The listed result
|
|
22166
|
+
* carries no native default Model or Thinking option, so it is neither cached nor used to
|
|
22167
|
+
* update `#thinkingSelectionSupported`. When the list cannot answer, a full inspection answers
|
|
22168
|
+
* instead, reusing one that is in flight or finished meanwhile.
|
|
22169
|
+
*/
|
|
22170
|
+
async #inspectAvailability(cwd, refresh = false) {
|
|
22171
|
+
if (refresh)
|
|
22172
|
+
this.#inspectionCache.delete(cwd);
|
|
22173
|
+
let pending = this.#availabilityInFlight.get(cwd);
|
|
22174
|
+
if (!pending) {
|
|
22175
|
+
const listing = this.#listAvailability(cwd);
|
|
22176
|
+
pending = listing.finally(() => {
|
|
22177
|
+
if (this.#availabilityInFlight.get(cwd) === pending)
|
|
22178
|
+
this.#availabilityInFlight.delete(cwd);
|
|
22179
|
+
});
|
|
22180
|
+
this.#availabilityInFlight.set(cwd, pending);
|
|
22181
|
+
}
|
|
22182
|
+
const listed = await pending;
|
|
22183
|
+
if (listed)
|
|
22184
|
+
return listed;
|
|
22185
|
+
if (this.#closePromise)
|
|
22186
|
+
return closedInspection();
|
|
22187
|
+
return this.#inspectionInFlight.get(cwd) ?? this.#inspectionCache.get(cwd) ?? this.#startFullInspection(cwd);
|
|
22188
|
+
}
|
|
22189
|
+
#startFullInspection(cwd) {
|
|
22059
22190
|
const inspection = this.#inspectCwd(cwd).then((result) => {
|
|
22060
22191
|
if (result.status === "ready")
|
|
22061
22192
|
this.#inspectionCache.set(cwd, result);
|
|
@@ -22068,6 +22199,59 @@ var OmpAdapter = class {
|
|
|
22068
22199
|
}
|
|
22069
22200
|
});
|
|
22070
22201
|
}
|
|
22202
|
+
/** Returns null when a Session must answer: this OMP cannot list Models, or lists none. */
|
|
22203
|
+
async #listAvailability(cwd) {
|
|
22204
|
+
const startedAt = Date.now();
|
|
22205
|
+
const stage = "model-list";
|
|
22206
|
+
const controller = new AbortController();
|
|
22207
|
+
this.#availabilityListings.add(controller);
|
|
22208
|
+
let listed;
|
|
22209
|
+
try {
|
|
22210
|
+
listed = await this.#listModels({ cwd, signal: controller.signal });
|
|
22211
|
+
} finally {
|
|
22212
|
+
this.#availabilityListings.delete(controller);
|
|
22213
|
+
}
|
|
22214
|
+
if (listed.kind === "unanswered")
|
|
22215
|
+
return null;
|
|
22216
|
+
if (listed.kind === "notInstalled") {
|
|
22217
|
+
return {
|
|
22218
|
+
status: "notInstalled",
|
|
22219
|
+
error: {
|
|
22220
|
+
code: "notInstalled",
|
|
22221
|
+
message: listed.message,
|
|
22222
|
+
retryable: false,
|
|
22223
|
+
stage,
|
|
22224
|
+
durationMs: Date.now() - startedAt
|
|
22225
|
+
}
|
|
22226
|
+
};
|
|
22227
|
+
}
|
|
22228
|
+
if (listed.kind === "timedOut") {
|
|
22229
|
+
return {
|
|
22230
|
+
status: "error",
|
|
22231
|
+
error: {
|
|
22232
|
+
code: "unavailable",
|
|
22233
|
+
message: "Oh My Pi did not list its models in time",
|
|
22234
|
+
retryable: true,
|
|
22235
|
+
stage,
|
|
22236
|
+
durationMs: Date.now() - startedAt
|
|
22237
|
+
}
|
|
22238
|
+
};
|
|
22239
|
+
}
|
|
22240
|
+
if (listed.models.length === 0)
|
|
22241
|
+
return null;
|
|
22242
|
+
let catalog;
|
|
22243
|
+
try {
|
|
22244
|
+
catalog = normalizeOmpModelCatalog(listed.models, null, null, null);
|
|
22245
|
+
} catch {
|
|
22246
|
+
return null;
|
|
22247
|
+
}
|
|
22248
|
+
return {
|
|
22249
|
+
status: "ready",
|
|
22250
|
+
catalog,
|
|
22251
|
+
permissionModes: OMP_PERMISSION_MODE_CATALOG,
|
|
22252
|
+
capabilities: ompInspectionCapabilities(false)
|
|
22253
|
+
};
|
|
22254
|
+
}
|
|
22071
22255
|
async #inspectCwd(cwd) {
|
|
22072
22256
|
const startedAt = Date.now();
|
|
22073
22257
|
let stage = "spawn";
|
|
@@ -22091,16 +22275,7 @@ var OmpAdapter = class {
|
|
|
22091
22275
|
status: "ready",
|
|
22092
22276
|
catalog,
|
|
22093
22277
|
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
|
-
}
|
|
22278
|
+
capabilities: ompInspectionCapabilities(thinkingLevels !== null)
|
|
22104
22279
|
};
|
|
22105
22280
|
} catch (error51) {
|
|
22106
22281
|
await transport.close().catch(() => void 0);
|
|
@@ -22311,6 +22486,8 @@ var OmpAdapter = class {
|
|
|
22311
22486
|
}
|
|
22312
22487
|
close() {
|
|
22313
22488
|
if (!this.#closePromise) {
|
|
22489
|
+
for (const listing of this.#availabilityListings)
|
|
22490
|
+
listing.abort();
|
|
22314
22491
|
this.#closePromise = Promise.all([
|
|
22315
22492
|
this.sessionImport.close(),
|
|
22316
22493
|
...[...this.#inspections].map((transport) => transport.close()),
|