@codexhost/cli-darwin-x64 0.13.3 → 0.15.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 +109 -11
- package/app/console-web.js +649 -132
- package/app/desktop-controller.mjs +120 -12
- package/app/host-runtime.mjs +1124 -293
- package/app/plugins/antigravity/plugin.mjs +431 -66
- package/app/plugins/claude-code/plugin.mjs +761 -139
- package/app/plugins/codebuddy/plugin.mjs +322 -68
- package/app/plugins/codex-usage/plugin.mjs +249 -102
- package/app/plugins/copilot/assets/icon.png +0 -0
- package/app/plugins/copilot/manifest.json +26 -0
- package/app/plugins/copilot/plugin.mjs +34591 -0
- package/app/plugins/cursor-cli/plugin.mjs +21011 -44970
- package/app/plugins/deepseek-harness/plugin.mjs +160 -43
- package/app/plugins/enabled.json +1 -0
- package/app/plugins/grok/plugin.mjs +565 -107
- package/app/plugins/hermes/plugin.mjs +128 -12
- package/app/plugins/kimi-code/plugin.mjs +136 -22
- package/app/plugins/kiro-cli/plugin.mjs +136 -22
- package/app/plugins/omp/plugin.mjs +2236 -2036
- package/app/plugins/opencode/plugin.mjs +187 -68
- package/app/plugins/pi/plugin.mjs +2621 -2304
- package/app/plugins/qoder/plugin.mjs +153 -36
- package/app/plugins/qoder-cn/plugin.mjs +153 -36
- package/app/plugins/workbuddy/plugin.mjs +583 -92
- package/app/plugins/zcode/plugin.mjs +183 -40
- package/app/renderer-extension.js +1758 -392
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -424,10 +424,13 @@ function usageSessionTitle(value) {
|
|
|
424
424
|
return void 0;
|
|
425
425
|
if (normalized.length <= MAX_SESSION_TITLE_LENGTH)
|
|
426
426
|
return normalized;
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
427
|
+
let title = "";
|
|
428
|
+
for (const character of normalized) {
|
|
429
|
+
if (title.length + character.length >= MAX_SESSION_TITLE_LENGTH)
|
|
430
|
+
break;
|
|
431
|
+
title += character;
|
|
432
|
+
}
|
|
433
|
+
return `${title.trimEnd()}…`;
|
|
431
434
|
}
|
|
432
435
|
function sessionIdOk(value) {
|
|
433
436
|
return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
|
|
@@ -3580,10 +3583,10 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3580
3583
|
const shape = def.shape;
|
|
3581
3584
|
const propValues = {};
|
|
3582
3585
|
for (const key in shape) {
|
|
3583
|
-
const
|
|
3584
|
-
if (
|
|
3586
|
+
const field2 = shape[key]._zod;
|
|
3587
|
+
if (field2.values) {
|
|
3585
3588
|
propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
|
|
3586
|
-
for (const v of
|
|
3589
|
+
for (const v of field2.values)
|
|
3587
3590
|
propValues[key].add(v);
|
|
3588
3591
|
}
|
|
3589
3592
|
}
|
|
@@ -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),
|
|
@@ -15321,6 +15333,51 @@ var hostInteractionIdSchema = opaqueIdSchema.brand();
|
|
|
15321
15333
|
var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
|
|
15322
15334
|
var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
|
|
15323
15335
|
|
|
15336
|
+
// ../../shared-contracts/dist/thread-questions.js
|
|
15337
|
+
var field = external_exports.discriminatedUnion("type", [
|
|
15338
|
+
external_exports.object({
|
|
15339
|
+
id: external_exports.string().min(1),
|
|
15340
|
+
type: external_exports.literal("choice"),
|
|
15341
|
+
prompt: external_exports.string(),
|
|
15342
|
+
options: external_exports.array(external_exports.object({
|
|
15343
|
+
value: external_exports.string().min(1),
|
|
15344
|
+
label: external_exports.string(),
|
|
15345
|
+
description: external_exports.string().optional()
|
|
15346
|
+
})).min(1),
|
|
15347
|
+
multiple: external_exports.boolean(),
|
|
15348
|
+
allowOther: external_exports.boolean(),
|
|
15349
|
+
optional: external_exports.boolean()
|
|
15350
|
+
}),
|
|
15351
|
+
external_exports.object({
|
|
15352
|
+
id: external_exports.string().min(1),
|
|
15353
|
+
type: external_exports.literal("text"),
|
|
15354
|
+
prompt: external_exports.string(),
|
|
15355
|
+
multiline: external_exports.boolean(),
|
|
15356
|
+
secret: external_exports.literal(false),
|
|
15357
|
+
optional: external_exports.boolean(),
|
|
15358
|
+
placeholder: external_exports.string().optional(),
|
|
15359
|
+
prefill: external_exports.string().optional()
|
|
15360
|
+
})
|
|
15361
|
+
]);
|
|
15362
|
+
var threadQuestionSchema = external_exports.object({
|
|
15363
|
+
interactionId: external_exports.string().min(1),
|
|
15364
|
+
turnId: external_exports.string().min(1),
|
|
15365
|
+
title: external_exports.string().optional(),
|
|
15366
|
+
questions: external_exports.array(field).min(1)
|
|
15367
|
+
}).refine(({ questions }) => questions.some((q) => q.type === "choice" && q.multiple), {
|
|
15368
|
+
message: "Shared cards require at least one multi-select question"
|
|
15369
|
+
});
|
|
15370
|
+
var threadQuestionsListParamsSchema = external_exports.strictObject({ threadId: external_exports.string().min(1) });
|
|
15371
|
+
var threadQuestionsResultSchema = external_exports.object({ questions: external_exports.array(threadQuestionSchema) });
|
|
15372
|
+
var threadQuestionRespondParamsSchema = external_exports.strictObject({
|
|
15373
|
+
threadId: external_exports.string().min(1),
|
|
15374
|
+
turnId: external_exports.string().min(1),
|
|
15375
|
+
interactionId: external_exports.string().min(1),
|
|
15376
|
+
answers: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
|
|
15377
|
+
cancelled: external_exports.boolean().default(false)
|
|
15378
|
+
});
|
|
15379
|
+
var threadQuestionRespondResultSchema = external_exports.object({ accepted: external_exports.literal(true) });
|
|
15380
|
+
|
|
15324
15381
|
// ../../shared-contracts/dist/console.js
|
|
15325
15382
|
var consoleAnnouncementSchema = external_exports.strictObject({
|
|
15326
15383
|
title: external_exports.string().trim().min(1).max(200),
|
|
@@ -15341,6 +15398,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
15341
15398
|
"codexhost/harness/display-settings/set",
|
|
15342
15399
|
"codexhost/harness/inspect",
|
|
15343
15400
|
"codexhost/harness/installation",
|
|
15401
|
+
"codexhost/harness/installation/start",
|
|
15402
|
+
"codexhost/harness/installation/status",
|
|
15344
15403
|
"codexhost/harness/launch-settings/get",
|
|
15345
15404
|
"codexhost/harness/launch-settings/set",
|
|
15346
15405
|
"codexhost/harness/web-ui/open",
|
|
@@ -15416,7 +15475,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
|
|
|
15416
15475
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
15417
15476
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
15418
15477
|
var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
15478
|
+
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
|
|
15479
|
+
var composerIndicatorsSchema = external_exports.array(external_exports.object({
|
|
15480
|
+
kind: external_exports.literal("countdown"),
|
|
15481
|
+
id: external_exports.string().min(1).max(64),
|
|
15482
|
+
expiresAtUnix: nonNegativeSafeIntegerSchema,
|
|
15483
|
+
label: indicatorTextSchema(256).optional(),
|
|
15484
|
+
tooltip: indicatorTextSchema(1024).optional()
|
|
15485
|
+
}).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
|
|
15486
|
+
message: "Composer indicator IDs must be unique"
|
|
15487
|
+
});
|
|
15419
15488
|
var threadUsageSnapshotSchema = external_exports.object({
|
|
15489
|
+
composerIndicators: composerIndicatorsSchema.optional(),
|
|
15420
15490
|
inputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15421
15491
|
cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15422
15492
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15824,7 +15894,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
|
|
|
15824
15894
|
}).strict().optional(),
|
|
15825
15895
|
autonomousTurns: external_exports.object({
|
|
15826
15896
|
observe: external_exports.boolean()
|
|
15827
|
-
}).strict().optional()
|
|
15897
|
+
}).strict().optional(),
|
|
15898
|
+
/** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
|
|
15899
|
+
steer: external_exports.boolean().optional()
|
|
15828
15900
|
}).strict();
|
|
15829
15901
|
var harnessConfigurationStateSchema = external_exports.object({
|
|
15830
15902
|
effectiveModel: harnessModelRefSchema.optional(),
|
|
@@ -15871,7 +15943,9 @@ var harnessInspectionSchema = external_exports.union([
|
|
|
15871
15943
|
var harnessInspectParamsSchema = external_exports.object({
|
|
15872
15944
|
harnessId: harnessIdSchema,
|
|
15873
15945
|
cwd: nonBlankTextSchema2.max(16384).optional(),
|
|
15874
|
-
refresh: external_exports.boolean().optional()
|
|
15946
|
+
refresh: external_exports.boolean().optional(),
|
|
15947
|
+
/** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
|
|
15948
|
+
purpose: external_exports.literal("availability").optional()
|
|
15875
15949
|
}).strict();
|
|
15876
15950
|
var harnessWebUiOpenParamsSchema = external_exports.object({
|
|
15877
15951
|
harnessId: harnessIdSchema
|
|
@@ -15954,6 +16028,15 @@ var threadOwnershipListResultSchema = external_exports.object({
|
|
|
15954
16028
|
seen.add(thread.threadId);
|
|
15955
16029
|
}
|
|
15956
16030
|
});
|
|
16031
|
+
var threadSteeringInspectParamsSchema = external_exports.object({
|
|
16032
|
+
threadId: hostThreadIdSchema,
|
|
16033
|
+
/** The text about to be steered; a Harness command always stops and restarts. */
|
|
16034
|
+
text: external_exports.string().optional()
|
|
16035
|
+
}).strict();
|
|
16036
|
+
var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
|
|
16037
|
+
var threadSteeringInspectResultSchema = external_exports.object({
|
|
16038
|
+
delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
|
|
16039
|
+
}).strict();
|
|
15957
16040
|
|
|
15958
16041
|
// ../../shared-contracts/dist/harness-plugins.js
|
|
15959
16042
|
var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
|
|
@@ -16055,6 +16138,10 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
16055
16138
|
latestVersion: external_exports.string().min(1).max(128),
|
|
16056
16139
|
updateAvailable: external_exports.boolean(),
|
|
16057
16140
|
canUpdate: external_exports.boolean(),
|
|
16141
|
+
/** Defaults to CLI; some Harnesses ship only inside a desktop application. */
|
|
16142
|
+
versionKind: external_exports.enum(["cli", "application"]).optional(),
|
|
16143
|
+
/** Official download opened by the user; does not imply an automatic installation. */
|
|
16144
|
+
manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
|
|
16058
16145
|
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
16059
16146
|
message: external_exports.string().max(2048).optional(),
|
|
16060
16147
|
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
@@ -16062,6 +16149,20 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
16062
16149
|
notice: harnessLocalizedTextSchema.optional(),
|
|
16063
16150
|
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
16064
16151
|
}).strict();
|
|
16152
|
+
var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
|
|
16153
|
+
var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
|
|
16154
|
+
external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
|
|
16155
|
+
external_exports.object({
|
|
16156
|
+
taskId: external_exports.string().uuid(),
|
|
16157
|
+
status: external_exports.literal("succeeded"),
|
|
16158
|
+
result: harnessInstallationStateSchema
|
|
16159
|
+
}).strict(),
|
|
16160
|
+
external_exports.object({
|
|
16161
|
+
taskId: external_exports.string().uuid(),
|
|
16162
|
+
status: external_exports.literal("failed"),
|
|
16163
|
+
error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
|
|
16164
|
+
}).strict()
|
|
16165
|
+
]);
|
|
16065
16166
|
|
|
16066
16167
|
// ../../shared-contracts/dist/codex-accounts.js
|
|
16067
16168
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
@@ -16863,6 +16964,18 @@ function sanitizeDiagnosticTail(value) {
|
|
|
16863
16964
|
return redacted.length <= DIAGNOSTIC_TAIL_MAX_LENGTH ? redacted : redacted.slice(-DIAGNOSTIC_TAIL_MAX_LENGTH);
|
|
16864
16965
|
}
|
|
16865
16966
|
|
|
16967
|
+
// ../../harness-adapter/dist/steer.js
|
|
16968
|
+
function unsupportedSteer(harnessLabel) {
|
|
16969
|
+
return {
|
|
16970
|
+
ok: false,
|
|
16971
|
+
error: {
|
|
16972
|
+
code: "unsupported",
|
|
16973
|
+
message: `${harnessLabel} cannot steer an active Turn natively`,
|
|
16974
|
+
retryable: false
|
|
16975
|
+
}
|
|
16976
|
+
};
|
|
16977
|
+
}
|
|
16978
|
+
|
|
16866
16979
|
// ../../harness-adapter/dist/usage.js
|
|
16867
16980
|
var tokenFields = [
|
|
16868
16981
|
"inputTokens",
|
|
@@ -16890,6 +17003,7 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
16890
17003
|
...safeIntegerFields,
|
|
16891
17004
|
...percentFields,
|
|
16892
17005
|
"sessionCacheUsage",
|
|
17006
|
+
"composerIndicators",
|
|
16893
17007
|
"totalCostUsd",
|
|
16894
17008
|
"totalCredits",
|
|
16895
17009
|
"contextUsagePercent",
|
|
@@ -16912,26 +17026,27 @@ function parseHostUsage(value) {
|
|
|
16912
17026
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
16913
17027
|
}
|
|
16914
17028
|
}
|
|
16915
|
-
|
|
17029
|
+
const indicators = value.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value.composerIndicators) };
|
|
17030
|
+
for (const field2 of [
|
|
16916
17031
|
"totalCredits",
|
|
16917
17032
|
"contextUsagePercent",
|
|
16918
17033
|
"apiOutputTokensPerSecond"
|
|
16919
17034
|
]) {
|
|
16920
|
-
const candidate = value[
|
|
17035
|
+
const candidate = value[field2];
|
|
16921
17036
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
16922
|
-
throw new Error(`Harness Usage '${
|
|
17037
|
+
throw new Error(`Harness Usage '${field2}' must be a finite non-negative number`);
|
|
16923
17038
|
}
|
|
16924
17039
|
}
|
|
16925
|
-
for (const
|
|
16926
|
-
const candidate = value[
|
|
17040
|
+
for (const field2 of tokenFields) {
|
|
17041
|
+
const candidate = value[field2];
|
|
16927
17042
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
16928
|
-
throw new Error(`Harness Usage '${
|
|
17043
|
+
throw new Error(`Harness Usage '${field2}' must be a non-negative safe integer`);
|
|
16929
17044
|
}
|
|
16930
17045
|
}
|
|
16931
|
-
for (const
|
|
16932
|
-
const candidate = value[
|
|
17046
|
+
for (const field2 of safeIntegerFields) {
|
|
17047
|
+
const candidate = value[field2];
|
|
16933
17048
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
16934
|
-
throw new Error(`Harness Usage '${
|
|
17049
|
+
throw new Error(`Harness Usage '${field2}' must be a non-negative safe integer`);
|
|
16935
17050
|
}
|
|
16936
17051
|
}
|
|
16937
17052
|
if (value.outputTokensPerSecond !== void 0 && (typeof value.outputTokensPerSecond !== "number" || !Number.isFinite(value.outputTokensPerSecond) || value.outputTokensPerSecond < 0)) {
|
|
@@ -16940,10 +17055,10 @@ function parseHostUsage(value) {
|
|
|
16940
17055
|
if (value.totalCostUsd !== void 0 && (typeof value.totalCostUsd !== "number" || !Number.isFinite(value.totalCostUsd) || value.totalCostUsd < 0)) {
|
|
16941
17056
|
throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
|
|
16942
17057
|
}
|
|
16943
|
-
for (const
|
|
16944
|
-
const candidate = value[
|
|
17058
|
+
for (const field2 of percentFields) {
|
|
17059
|
+
const candidate = value[field2];
|
|
16945
17060
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0 || candidate > 100)) {
|
|
16946
|
-
throw new Error(`Harness Usage '${
|
|
17061
|
+
throw new Error(`Harness Usage '${field2}' must be between 0 and 100`);
|
|
16947
17062
|
}
|
|
16948
17063
|
}
|
|
16949
17064
|
if (value.sessionCacheUsage !== void 0) {
|
|
@@ -16982,9 +17097,9 @@ function parseHostUsage(value) {
|
|
|
16982
17097
|
if (value.costSource !== "publicPrice") {
|
|
16983
17098
|
throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
|
|
16984
17099
|
}
|
|
16985
|
-
return { ...value, unpricedModels: [...models] };
|
|
17100
|
+
return { ...value, ...indicators, unpricedModels: [...models] };
|
|
16986
17101
|
}
|
|
16987
|
-
return { ...value };
|
|
17102
|
+
return { ...value, ...indicators };
|
|
16988
17103
|
}
|
|
16989
17104
|
var requestTokenFields = [
|
|
16990
17105
|
"inputTokens",
|
|
@@ -17014,19 +17129,19 @@ function parseHostUsageRequest(value) {
|
|
|
17014
17129
|
if (typeof value.requestId !== "string" || value.requestId.length === 0) {
|
|
17015
17130
|
throw new Error("Harness Usage request 'requestId' must be a non-empty string");
|
|
17016
17131
|
}
|
|
17017
|
-
for (const
|
|
17018
|
-
const candidate = value[
|
|
17132
|
+
for (const field2 of ["model", "provider"]) {
|
|
17133
|
+
const candidate = value[field2];
|
|
17019
17134
|
if (candidate !== void 0 && (typeof candidate !== "string" || candidate.length === 0)) {
|
|
17020
|
-
throw new Error(`Harness Usage request '${
|
|
17135
|
+
throw new Error(`Harness Usage request '${field2}' must be a non-empty string`);
|
|
17021
17136
|
}
|
|
17022
17137
|
}
|
|
17023
17138
|
if (value.historical !== void 0 && typeof value.historical !== "boolean") {
|
|
17024
17139
|
throw new Error("Harness Usage request 'historical' must be a boolean");
|
|
17025
17140
|
}
|
|
17026
|
-
for (const
|
|
17027
|
-
const candidate = value[
|
|
17141
|
+
for (const field2 of requestTokenFields) {
|
|
17142
|
+
const candidate = value[field2];
|
|
17028
17143
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
17029
|
-
throw new Error(`Harness Usage request '${
|
|
17144
|
+
throw new Error(`Harness Usage request '${field2}' must be a non-negative safe integer`);
|
|
17030
17145
|
}
|
|
17031
17146
|
}
|
|
17032
17147
|
if (value.inputTokens === void 0 || value.outputTokens === void 0) {
|
|
@@ -17711,857 +17826,283 @@ function createOmpUsageStatistics(environment) {
|
|
|
17711
17826
|
});
|
|
17712
17827
|
}
|
|
17713
17828
|
|
|
17714
|
-
//
|
|
17715
|
-
|
|
17716
|
-
|
|
17717
|
-
|
|
17718
|
-
|
|
17719
|
-
|
|
17720
|
-
|
|
17721
|
-
|
|
17722
|
-
|
|
17723
|
-
|
|
17724
|
-
|
|
17725
|
-
|
|
17726
|
-
|
|
17727
|
-
|
|
17728
|
-
|
|
17829
|
+
// dist/omp-model-list.js
|
|
17830
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
17831
|
+
|
|
17832
|
+
// dist/command.js
|
|
17833
|
+
var ompDiscoverySpec = {
|
|
17834
|
+
id: "omp",
|
|
17835
|
+
command: "omp",
|
|
17836
|
+
commandEnvironmentVariable: "OMP_COMMAND",
|
|
17837
|
+
installRoots: {
|
|
17838
|
+
posix: [
|
|
17839
|
+
"~/.npm-global/bin",
|
|
17840
|
+
"~/.local/bin",
|
|
17841
|
+
VERSION_MANAGER_ROOTS,
|
|
17842
|
+
"/opt/homebrew/bin",
|
|
17843
|
+
"/usr/local/bin"
|
|
17844
|
+
],
|
|
17845
|
+
windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS]
|
|
17729
17846
|
}
|
|
17730
|
-
|
|
17731
|
-
|
|
17732
|
-
|
|
17733
|
-
|
|
17734
|
-
|
|
17735
|
-
|
|
17736
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
17740
|
-
|
|
17847
|
+
};
|
|
17848
|
+
function resolveOmpExecutable(input, dependencies = {}) {
|
|
17849
|
+
const resolution = resolveHarnessExecutable(ompDiscoverySpec, {
|
|
17850
|
+
...input.command ? { command: input.command } : {},
|
|
17851
|
+
environment: input.environment,
|
|
17852
|
+
...dependencies.platform ? { platform: dependencies.platform } : {},
|
|
17853
|
+
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {}
|
|
17854
|
+
}, { ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {} });
|
|
17855
|
+
return resolution?.executable ?? input.command ?? input.environment.OMP_COMMAND ?? "omp";
|
|
17856
|
+
}
|
|
17857
|
+
|
|
17858
|
+
// dist/omp-rpc-session.js
|
|
17859
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
17860
|
+
import { randomUUID } from "node:crypto";
|
|
17861
|
+
import path6 from "node:path";
|
|
17862
|
+
|
|
17863
|
+
// dist/omp-slash-commands.js
|
|
17864
|
+
var OMP_LIVE_COMMAND_ID_PREFIX = "omp.slash.";
|
|
17865
|
+
function isRecord6(value) {
|
|
17866
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17867
|
+
}
|
|
17868
|
+
function parseOmpAvailableCommands(value) {
|
|
17869
|
+
if (!Array.isArray(value))
|
|
17870
|
+
return [];
|
|
17871
|
+
return value.flatMap((entry) => {
|
|
17872
|
+
if (!isRecord6(entry))
|
|
17873
|
+
return [];
|
|
17874
|
+
const name = typeof entry.name === "string" ? entry.name.trim().replace(/^\//u, "") : "";
|
|
17875
|
+
if (!name)
|
|
17876
|
+
return [];
|
|
17877
|
+
return [
|
|
17878
|
+
{
|
|
17879
|
+
name,
|
|
17880
|
+
description: typeof entry.description === "string" ? entry.description : "",
|
|
17881
|
+
source: typeof entry.source === "string" ? entry.source : null
|
|
17741
17882
|
}
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17750
|
-
|
|
17751
|
-
|
|
17752
|
-
|
|
17753
|
-
|
|
17754
|
-
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
|
|
17759
|
-
|
|
17760
|
-
|
|
17761
|
-
|
|
17762
|
-
|
|
17763
|
-
|
|
17764
|
-
|
|
17765
|
-
|
|
17766
|
-
|
|
17767
|
-
|
|
17768
|
-
|
|
17769
|
-
|
|
17770
|
-
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
|
|
17775
|
-
|
|
17776
|
-
|
|
17777
|
-
|
|
17778
|
-
|
|
17779
|
-
|
|
17780
|
-
|
|
17781
|
-
|
|
17782
|
-
|
|
17783
|
-
|
|
17784
|
-
|
|
17785
|
-
|
|
17786
|
-
|
|
17787
|
-
|
|
17788
|
-
|
|
17789
|
-
}
|
|
17790
|
-
}
|
|
17883
|
+
];
|
|
17884
|
+
});
|
|
17885
|
+
}
|
|
17886
|
+
function ompLiveCommands(native) {
|
|
17887
|
+
return native.filter(({ source, name }) => source !== "builtin" || name === "context").map((command) => ({
|
|
17888
|
+
name: command.name,
|
|
17889
|
+
description: command.description,
|
|
17890
|
+
kind: command.source === "skill" ? "skill" : "command"
|
|
17891
|
+
}));
|
|
17892
|
+
}
|
|
17893
|
+
|
|
17894
|
+
// dist/omp-session-file.js
|
|
17895
|
+
import { createReadStream as createReadStream3 } from "node:fs";
|
|
17896
|
+
import { open, realpath as realpath2 } from "node:fs/promises";
|
|
17897
|
+
import readline from "node:readline";
|
|
17898
|
+
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
17899
|
+
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
17900
|
+
function isRecord7(value) {
|
|
17901
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17902
|
+
}
|
|
17903
|
+
function historyEntry(value) {
|
|
17904
|
+
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") {
|
|
17905
|
+
return null;
|
|
17906
|
+
}
|
|
17907
|
+
return value;
|
|
17908
|
+
}
|
|
17909
|
+
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
17910
|
+
const entries = [];
|
|
17911
|
+
let leafId = null;
|
|
17912
|
+
let incomplete = false;
|
|
17913
|
+
const lines = readline.createInterface({
|
|
17914
|
+
input: createReadStream3(sessionFile, {
|
|
17915
|
+
encoding: "utf8",
|
|
17916
|
+
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
17917
|
+
}),
|
|
17918
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
17919
|
+
});
|
|
17920
|
+
try {
|
|
17921
|
+
for await (const line of lines) {
|
|
17922
|
+
if (line.length === 0)
|
|
17923
|
+
continue;
|
|
17924
|
+
let parsed;
|
|
17925
|
+
try {
|
|
17926
|
+
parsed = JSON.parse(line);
|
|
17927
|
+
} catch {
|
|
17928
|
+
incomplete = true;
|
|
17929
|
+
continue;
|
|
17791
17930
|
}
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
setTimeout(function() {
|
|
17797
|
-
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
17798
|
-
return callback(void 0);
|
|
17799
|
-
}
|
|
17800
|
-
if (!execEditLength()) {
|
|
17801
|
-
exec();
|
|
17802
|
-
}
|
|
17803
|
-
}, 0);
|
|
17804
|
-
})();
|
|
17805
|
-
} else {
|
|
17806
|
-
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
17807
|
-
const ret = execEditLength();
|
|
17808
|
-
if (ret) {
|
|
17809
|
-
return ret;
|
|
17931
|
+
const entry = historyEntry(parsed);
|
|
17932
|
+
if (!entry) {
|
|
17933
|
+
if (!isRecord7(parsed) || parsed.type !== "title" && parsed.type !== "session") {
|
|
17934
|
+
incomplete = true;
|
|
17810
17935
|
}
|
|
17936
|
+
continue;
|
|
17811
17937
|
}
|
|
17938
|
+
entries.push(entry);
|
|
17939
|
+
leafId = entry.id;
|
|
17812
17940
|
}
|
|
17941
|
+
} finally {
|
|
17942
|
+
lines.close();
|
|
17813
17943
|
}
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
|
|
17818
|
-
|
|
17819
|
-
|
|
17820
|
-
|
|
17821
|
-
|
|
17822
|
-
|
|
17823
|
-
|
|
17824
|
-
|
|
17825
|
-
};
|
|
17826
|
-
}
|
|
17827
|
-
}
|
|
17828
|
-
extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
|
|
17829
|
-
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
17830
|
-
let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
|
|
17831
|
-
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
|
|
17832
|
-
newPos++;
|
|
17833
|
-
oldPos++;
|
|
17834
|
-
commonCount++;
|
|
17835
|
-
if (options.oneChangePerToken) {
|
|
17836
|
-
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
17837
|
-
}
|
|
17838
|
-
}
|
|
17839
|
-
if (commonCount && !options.oneChangePerToken) {
|
|
17840
|
-
basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
17841
|
-
}
|
|
17842
|
-
basePath.oldPos = oldPos;
|
|
17843
|
-
return newPos;
|
|
17844
|
-
}
|
|
17845
|
-
equals(left, right, options) {
|
|
17846
|
-
if (options.comparator) {
|
|
17847
|
-
return options.comparator(left, right);
|
|
17848
|
-
} else {
|
|
17849
|
-
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
17944
|
+
return { entries, leafId, ...incomplete ? { incomplete: true } : {} };
|
|
17945
|
+
}
|
|
17946
|
+
async function readOmpSessionHeader(sessionFile) {
|
|
17947
|
+
const handle = await open(sessionFile, "r");
|
|
17948
|
+
try {
|
|
17949
|
+
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
17950
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
17951
|
+
const contents = buffer.subarray(0, bytesRead);
|
|
17952
|
+
const newline = contents.indexOf(10);
|
|
17953
|
+
if (newline < 0 && bytesRead === buffer.length) {
|
|
17954
|
+
throw new Error("Omp Session header exceeds the supported size");
|
|
17850
17955
|
}
|
|
17851
|
-
|
|
17852
|
-
|
|
17853
|
-
|
|
17854
|
-
|
|
17855
|
-
|
|
17856
|
-
|
|
17956
|
+
const contentsText = utf8Decoder.decode(contents);
|
|
17957
|
+
for (const line of contentsText.split("\n")) {
|
|
17958
|
+
if (line.length === 0)
|
|
17959
|
+
continue;
|
|
17960
|
+
let parsed;
|
|
17961
|
+
try {
|
|
17962
|
+
parsed = JSON.parse(line);
|
|
17963
|
+
} catch {
|
|
17964
|
+
continue;
|
|
17857
17965
|
}
|
|
17966
|
+
if (!isRecord7(parsed) || parsed.type !== "session")
|
|
17967
|
+
continue;
|
|
17968
|
+
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
17969
|
+
throw new Error("Omp Session header is invalid");
|
|
17970
|
+
}
|
|
17971
|
+
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
17858
17972
|
}
|
|
17859
|
-
|
|
17860
|
-
}
|
|
17861
|
-
|
|
17862
|
-
castInput(value, options) {
|
|
17863
|
-
return value;
|
|
17864
|
-
}
|
|
17865
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17866
|
-
tokenize(value, options) {
|
|
17867
|
-
return Array.from(value);
|
|
17868
|
-
}
|
|
17869
|
-
join(chars) {
|
|
17870
|
-
return chars.join("");
|
|
17973
|
+
throw new Error("Omp Session header is invalid");
|
|
17974
|
+
} finally {
|
|
17975
|
+
await handle.close();
|
|
17871
17976
|
}
|
|
17872
|
-
|
|
17873
|
-
|
|
17977
|
+
}
|
|
17978
|
+
async function verifyOmpSessionCwd(input) {
|
|
17979
|
+
if (!input.sessionFile)
|
|
17980
|
+
throw new Error("Omp Fork Session has no persisted Session file");
|
|
17981
|
+
const header = await readOmpSessionHeader(input.sessionFile);
|
|
17982
|
+
if (header.id !== input.sessionId) {
|
|
17983
|
+
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
17874
17984
|
}
|
|
17875
|
-
|
|
17876
|
-
|
|
17985
|
+
const [actualCwd, expectedCwd] = await Promise.all([
|
|
17986
|
+
realpath2(header.cwd),
|
|
17987
|
+
realpath2(input.expectedCwd)
|
|
17988
|
+
]);
|
|
17989
|
+
if (actualCwd !== expectedCwd) {
|
|
17990
|
+
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
17877
17991
|
}
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
|
|
17885
|
-
|
|
17992
|
+
}
|
|
17993
|
+
|
|
17994
|
+
// dist/omp-protocol.js
|
|
17995
|
+
var MAX_FRAME_BYTES = 1024 * 1024;
|
|
17996
|
+
var MAX_REASSEMBLED_BYTES = 64 * 1024 * 1024;
|
|
17997
|
+
var MAX_CHUNK_BYTES = 256 * 1024;
|
|
17998
|
+
function isObject2(value) {
|
|
17999
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18000
|
+
}
|
|
18001
|
+
var OmpFrameDecoder = class {
|
|
18002
|
+
#pending = null;
|
|
18003
|
+
push(value) {
|
|
18004
|
+
if (!isObject2(value))
|
|
18005
|
+
throw new Error("OMP RPC frame must be a JSON object");
|
|
18006
|
+
if (value.type !== "rpc_chunk") {
|
|
18007
|
+
if (this.#pending)
|
|
18008
|
+
throw new Error("OMP RPC chunk sequence was interrupted");
|
|
18009
|
+
return value;
|
|
17886
18010
|
}
|
|
17887
|
-
|
|
17888
|
-
const
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
component.value = this.join(value);
|
|
17900
|
-
} else {
|
|
17901
|
-
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
17902
|
-
}
|
|
17903
|
-
newPos += component.count;
|
|
17904
|
-
if (!component.added) {
|
|
17905
|
-
oldPos += component.count;
|
|
17906
|
-
}
|
|
17907
|
-
} else {
|
|
17908
|
-
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
17909
|
-
oldPos += component.count;
|
|
17910
|
-
}
|
|
18011
|
+
const chunkId = value.chunkId;
|
|
18012
|
+
const index = value.index;
|
|
18013
|
+
const count2 = value.count;
|
|
18014
|
+
const byteLength = value.byteLength;
|
|
18015
|
+
const data = value.data;
|
|
18016
|
+
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)
|
|
18017
|
+
throw new Error("Invalid OMP RPC chunk metadata");
|
|
18018
|
+
let bytes;
|
|
18019
|
+
try {
|
|
18020
|
+
bytes = Buffer.from(data, "base64");
|
|
18021
|
+
} catch {
|
|
18022
|
+
throw new Error("Invalid OMP RPC chunk data");
|
|
17911
18023
|
}
|
|
17912
|
-
|
|
18024
|
+
if (bytes.length === 0 || bytes.length > MAX_CHUNK_BYTES || bytes.toString("base64") !== data) {
|
|
18025
|
+
throw new Error("Invalid OMP RPC chunk data");
|
|
18026
|
+
}
|
|
18027
|
+
const chunkIndex = index;
|
|
18028
|
+
const chunkCount = count2;
|
|
18029
|
+
const declaredByteLength = byteLength;
|
|
18030
|
+
if (!this.#pending) {
|
|
18031
|
+
if (chunkIndex !== 0)
|
|
18032
|
+
throw new Error("OMP RPC chunk sequence must start at index 0");
|
|
18033
|
+
this.#pending = {
|
|
18034
|
+
chunkId,
|
|
18035
|
+
count: chunkCount,
|
|
18036
|
+
byteLength: declaredByteLength,
|
|
18037
|
+
nextIndex: 0,
|
|
18038
|
+
chunks: [],
|
|
18039
|
+
received: 0
|
|
18040
|
+
};
|
|
18041
|
+
}
|
|
18042
|
+
const pending = this.#pending;
|
|
18043
|
+
if (!pending)
|
|
18044
|
+
throw new Error("OMP RPC chunk state was lost");
|
|
18045
|
+
if (pending.chunkId !== chunkId || pending.count !== chunkCount || pending.byteLength !== declaredByteLength || pending.nextIndex !== chunkIndex) {
|
|
18046
|
+
throw new Error("OMP RPC chunk sequence mismatch");
|
|
18047
|
+
}
|
|
18048
|
+
pending.chunks.push(bytes);
|
|
18049
|
+
pending.received += bytes.length;
|
|
18050
|
+
pending.nextIndex += 1;
|
|
18051
|
+
if (pending.received > pending.byteLength)
|
|
18052
|
+
throw new Error("OMP RPC chunk sequence exceeds its declared length");
|
|
18053
|
+
if (pending.nextIndex < pending.count)
|
|
18054
|
+
return null;
|
|
18055
|
+
if (pending.received !== pending.byteLength)
|
|
18056
|
+
throw new Error("OMP RPC chunk sequence length mismatch");
|
|
18057
|
+
this.#pending = null;
|
|
18058
|
+
let decoded;
|
|
18059
|
+
try {
|
|
18060
|
+
decoded = JSON.parse(Buffer.concat(pending.chunks).toString("utf8"));
|
|
18061
|
+
} catch {
|
|
18062
|
+
throw new Error("Failed to decode reassembled OMP RPC frame");
|
|
18063
|
+
}
|
|
18064
|
+
if (!isObject2(decoded))
|
|
18065
|
+
throw new Error("Reassembled OMP RPC frame must be an object");
|
|
18066
|
+
return decoded;
|
|
17913
18067
|
}
|
|
17914
18068
|
};
|
|
17915
18069
|
|
|
17916
|
-
//
|
|
17917
|
-
var
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
18070
|
+
// dist/omp-rpc-session.js
|
|
18071
|
+
var OmpRpcFaultError = class extends Error {
|
|
18072
|
+
kind;
|
|
18073
|
+
diagnostic;
|
|
18074
|
+
constructor(kind, message3, diagnostic) {
|
|
18075
|
+
super(message3);
|
|
18076
|
+
this.kind = kind;
|
|
18077
|
+
this.diagnostic = diagnostic;
|
|
18078
|
+
this.name = "OmpRpcFaultError";
|
|
17921
18079
|
}
|
|
17922
|
-
|
|
17923
|
-
|
|
17924
|
-
|
|
17925
|
-
|
|
17926
|
-
|
|
17927
|
-
|
|
17928
|
-
|
|
17929
|
-
}
|
|
17930
|
-
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
17931
|
-
if (left.endsWith("\n")) {
|
|
17932
|
-
left = left.slice(0, -1);
|
|
17933
|
-
}
|
|
17934
|
-
if (right.endsWith("\n")) {
|
|
17935
|
-
right = right.slice(0, -1);
|
|
17936
|
-
}
|
|
17937
|
-
}
|
|
17938
|
-
return super.equals(left, right, options);
|
|
18080
|
+
};
|
|
18081
|
+
var OmpRpcUnsupportedCommandError = class extends Error {
|
|
18082
|
+
command;
|
|
18083
|
+
constructor(command) {
|
|
18084
|
+
super(`Omp RPC does not support '${command}'`);
|
|
18085
|
+
this.command = command;
|
|
18086
|
+
this.name = "OmpRpcUnsupportedCommandError";
|
|
17939
18087
|
}
|
|
17940
18088
|
};
|
|
17941
|
-
var
|
|
17942
|
-
function
|
|
17943
|
-
return
|
|
18089
|
+
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
18090
|
+
function isRecord8(value) {
|
|
18091
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17944
18092
|
}
|
|
17945
|
-
function
|
|
17946
|
-
|
|
17947
|
-
|
|
17948
|
-
|
|
17949
|
-
|
|
17950
|
-
|
|
17951
|
-
|
|
17952
|
-
|
|
17953
|
-
|
|
17954
|
-
|
|
17955
|
-
|
|
17956
|
-
retLines[retLines.length - 1] += line;
|
|
17957
|
-
} else {
|
|
17958
|
-
retLines.push(line);
|
|
17959
|
-
}
|
|
18093
|
+
function message2(value) {
|
|
18094
|
+
return value instanceof Error ? value.message : String(value);
|
|
18095
|
+
}
|
|
18096
|
+
function nonBlankString(value) {
|
|
18097
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
18098
|
+
}
|
|
18099
|
+
function parseNativeModel(value, context) {
|
|
18100
|
+
if (value === null || value === void 0)
|
|
18101
|
+
return null;
|
|
18102
|
+
if (!isRecord8(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
18103
|
+
throw new OmpRpcFaultError("protocolError", `Omp RPC returned an invalid ${context} Model`);
|
|
17960
18104
|
}
|
|
17961
|
-
return
|
|
17962
|
-
}
|
|
17963
|
-
|
|
17964
|
-
// ../../../node_modules/diff/libesm/patch/parse.js
|
|
17965
|
-
function parsePatch(uniDiff) {
|
|
17966
|
-
const diffstr = uniDiff.split(/\n/), list = [];
|
|
17967
|
-
let i = 0;
|
|
17968
|
-
function parseIndex() {
|
|
17969
|
-
const index = {};
|
|
17970
|
-
list.push(index);
|
|
17971
|
-
while (i < diffstr.length) {
|
|
17972
|
-
const line = diffstr[i];
|
|
17973
|
-
if (/^(---|\+\+\+|@@)\s/.test(line)) {
|
|
17974
|
-
break;
|
|
17975
|
-
}
|
|
17976
|
-
const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
|
|
17977
|
-
if (header) {
|
|
17978
|
-
index.index = header[1];
|
|
17979
|
-
}
|
|
17980
|
-
i++;
|
|
17981
|
-
}
|
|
17982
|
-
parseFileHeader(index);
|
|
17983
|
-
parseFileHeader(index);
|
|
17984
|
-
index.hunks = [];
|
|
17985
|
-
while (i < diffstr.length) {
|
|
17986
|
-
const line = diffstr[i];
|
|
17987
|
-
if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
|
|
17988
|
-
break;
|
|
17989
|
-
} else if (/^@@/.test(line)) {
|
|
17990
|
-
index.hunks.push(parseHunk());
|
|
17991
|
-
} else if (line) {
|
|
17992
|
-
throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
|
|
17993
|
-
} else {
|
|
17994
|
-
i++;
|
|
17995
|
-
}
|
|
17996
|
-
}
|
|
17997
|
-
}
|
|
17998
|
-
function parseFileHeader(index) {
|
|
17999
|
-
const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
|
|
18000
|
-
if (fileHeader) {
|
|
18001
|
-
const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
|
|
18002
|
-
let fileName = data[0].replace(/\\\\/g, "\\");
|
|
18003
|
-
if (/^".*"$/.test(fileName)) {
|
|
18004
|
-
fileName = fileName.substr(1, fileName.length - 2);
|
|
18005
|
-
}
|
|
18006
|
-
if (fileHeader[1] === "---") {
|
|
18007
|
-
index.oldFileName = fileName;
|
|
18008
|
-
index.oldHeader = header;
|
|
18009
|
-
} else {
|
|
18010
|
-
index.newFileName = fileName;
|
|
18011
|
-
index.newHeader = header;
|
|
18012
|
-
}
|
|
18013
|
-
i++;
|
|
18014
|
-
}
|
|
18015
|
-
}
|
|
18016
|
-
function parseHunk() {
|
|
18017
|
-
var _a3;
|
|
18018
|
-
const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
|
18019
|
-
const hunk = {
|
|
18020
|
-
oldStart: +chunkHeader[1],
|
|
18021
|
-
oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
|
|
18022
|
-
newStart: +chunkHeader[3],
|
|
18023
|
-
newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
|
|
18024
|
-
lines: []
|
|
18025
|
-
};
|
|
18026
|
-
if (hunk.oldLines === 0) {
|
|
18027
|
-
hunk.oldStart += 1;
|
|
18028
|
-
}
|
|
18029
|
-
if (hunk.newLines === 0) {
|
|
18030
|
-
hunk.newStart += 1;
|
|
18031
|
-
}
|
|
18032
|
-
let addCount = 0, removeCount = 0;
|
|
18033
|
-
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
|
|
18034
|
-
const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
|
|
18035
|
-
if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
|
|
18036
|
-
hunk.lines.push(diffstr[i]);
|
|
18037
|
-
if (operation === "+") {
|
|
18038
|
-
addCount++;
|
|
18039
|
-
} else if (operation === "-") {
|
|
18040
|
-
removeCount++;
|
|
18041
|
-
} else if (operation === " ") {
|
|
18042
|
-
addCount++;
|
|
18043
|
-
removeCount++;
|
|
18044
|
-
}
|
|
18045
|
-
} else {
|
|
18046
|
-
throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
|
|
18047
|
-
}
|
|
18048
|
-
}
|
|
18049
|
-
if (!addCount && hunk.newLines === 1) {
|
|
18050
|
-
hunk.newLines = 0;
|
|
18051
|
-
}
|
|
18052
|
-
if (!removeCount && hunk.oldLines === 1) {
|
|
18053
|
-
hunk.oldLines = 0;
|
|
18054
|
-
}
|
|
18055
|
-
if (addCount !== hunk.newLines) {
|
|
18056
|
-
throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
18057
|
-
}
|
|
18058
|
-
if (removeCount !== hunk.oldLines) {
|
|
18059
|
-
throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
18060
|
-
}
|
|
18061
|
-
return hunk;
|
|
18062
|
-
}
|
|
18063
|
-
while (i < diffstr.length) {
|
|
18064
|
-
parseIndex();
|
|
18065
|
-
}
|
|
18066
|
-
return list;
|
|
18067
|
-
}
|
|
18068
|
-
|
|
18069
|
-
// ../../../node_modules/diff/libesm/patch/create.js
|
|
18070
|
-
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
18071
|
-
let optionsObj;
|
|
18072
|
-
if (!options) {
|
|
18073
|
-
optionsObj = {};
|
|
18074
|
-
} else if (typeof options === "function") {
|
|
18075
|
-
optionsObj = { callback: options };
|
|
18076
|
-
} else {
|
|
18077
|
-
optionsObj = options;
|
|
18078
|
-
}
|
|
18079
|
-
if (typeof optionsObj.context === "undefined") {
|
|
18080
|
-
optionsObj.context = 4;
|
|
18081
|
-
}
|
|
18082
|
-
const context = optionsObj.context;
|
|
18083
|
-
if (optionsObj.newlineIsToken) {
|
|
18084
|
-
throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
|
|
18085
|
-
}
|
|
18086
|
-
if (!optionsObj.callback) {
|
|
18087
|
-
return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
|
|
18088
|
-
} else {
|
|
18089
|
-
const { callback } = optionsObj;
|
|
18090
|
-
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
|
18091
|
-
const patch = diffLinesResultToPatch(diff);
|
|
18092
|
-
callback(patch);
|
|
18093
|
-
} }));
|
|
18094
|
-
}
|
|
18095
|
-
function diffLinesResultToPatch(diff) {
|
|
18096
|
-
if (!diff) {
|
|
18097
|
-
return;
|
|
18098
|
-
}
|
|
18099
|
-
diff.push({ value: "", lines: [] });
|
|
18100
|
-
function contextLines(lines) {
|
|
18101
|
-
return lines.map(function(entry) {
|
|
18102
|
-
return " " + entry;
|
|
18103
|
-
});
|
|
18104
|
-
}
|
|
18105
|
-
const hunks = [];
|
|
18106
|
-
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
|
18107
|
-
for (let i = 0; i < diff.length; i++) {
|
|
18108
|
-
const current = diff[i], lines = current.lines || splitLines(current.value);
|
|
18109
|
-
current.lines = lines;
|
|
18110
|
-
if (current.added || current.removed) {
|
|
18111
|
-
if (!oldRangeStart) {
|
|
18112
|
-
const prev = diff[i - 1];
|
|
18113
|
-
oldRangeStart = oldLine;
|
|
18114
|
-
newRangeStart = newLine;
|
|
18115
|
-
if (prev) {
|
|
18116
|
-
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
|
|
18117
|
-
oldRangeStart -= curRange.length;
|
|
18118
|
-
newRangeStart -= curRange.length;
|
|
18119
|
-
}
|
|
18120
|
-
}
|
|
18121
|
-
for (const line of lines) {
|
|
18122
|
-
curRange.push((current.added ? "+" : "-") + line);
|
|
18123
|
-
}
|
|
18124
|
-
if (current.added) {
|
|
18125
|
-
newLine += lines.length;
|
|
18126
|
-
} else {
|
|
18127
|
-
oldLine += lines.length;
|
|
18128
|
-
}
|
|
18129
|
-
} else {
|
|
18130
|
-
if (oldRangeStart) {
|
|
18131
|
-
if (lines.length <= context * 2 && i < diff.length - 2) {
|
|
18132
|
-
for (const line of contextLines(lines)) {
|
|
18133
|
-
curRange.push(line);
|
|
18134
|
-
}
|
|
18135
|
-
} else {
|
|
18136
|
-
const contextSize = Math.min(lines.length, context);
|
|
18137
|
-
for (const line of contextLines(lines.slice(0, contextSize))) {
|
|
18138
|
-
curRange.push(line);
|
|
18139
|
-
}
|
|
18140
|
-
const hunk = {
|
|
18141
|
-
oldStart: oldRangeStart,
|
|
18142
|
-
oldLines: oldLine - oldRangeStart + contextSize,
|
|
18143
|
-
newStart: newRangeStart,
|
|
18144
|
-
newLines: newLine - newRangeStart + contextSize,
|
|
18145
|
-
lines: curRange
|
|
18146
|
-
};
|
|
18147
|
-
hunks.push(hunk);
|
|
18148
|
-
oldRangeStart = 0;
|
|
18149
|
-
newRangeStart = 0;
|
|
18150
|
-
curRange = [];
|
|
18151
|
-
}
|
|
18152
|
-
}
|
|
18153
|
-
oldLine += lines.length;
|
|
18154
|
-
newLine += lines.length;
|
|
18155
|
-
}
|
|
18156
|
-
}
|
|
18157
|
-
for (const hunk of hunks) {
|
|
18158
|
-
for (let i = 0; i < hunk.lines.length; i++) {
|
|
18159
|
-
if (hunk.lines[i].endsWith("\n")) {
|
|
18160
|
-
hunk.lines[i] = hunk.lines[i].slice(0, -1);
|
|
18161
|
-
} else {
|
|
18162
|
-
hunk.lines.splice(i + 1, 0, "\");
|
|
18163
|
-
i++;
|
|
18164
|
-
}
|
|
18165
|
-
}
|
|
18166
|
-
}
|
|
18167
|
-
return {
|
|
18168
|
-
oldFileName,
|
|
18169
|
-
newFileName,
|
|
18170
|
-
oldHeader,
|
|
18171
|
-
newHeader,
|
|
18172
|
-
hunks
|
|
18173
|
-
};
|
|
18174
|
-
}
|
|
18175
|
-
}
|
|
18176
|
-
function formatPatch(patch) {
|
|
18177
|
-
if (Array.isArray(patch)) {
|
|
18178
|
-
return patch.map(formatPatch).join("\n");
|
|
18179
|
-
}
|
|
18180
|
-
const ret = [];
|
|
18181
|
-
if (patch.oldFileName == patch.newFileName) {
|
|
18182
|
-
ret.push("Index: " + patch.oldFileName);
|
|
18183
|
-
}
|
|
18184
|
-
ret.push("===================================================================");
|
|
18185
|
-
ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
|
|
18186
|
-
ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
|
|
18187
|
-
for (let i = 0; i < patch.hunks.length; i++) {
|
|
18188
|
-
const hunk = patch.hunks[i];
|
|
18189
|
-
if (hunk.oldLines === 0) {
|
|
18190
|
-
hunk.oldStart -= 1;
|
|
18191
|
-
}
|
|
18192
|
-
if (hunk.newLines === 0) {
|
|
18193
|
-
hunk.newStart -= 1;
|
|
18194
|
-
}
|
|
18195
|
-
ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
|
|
18196
|
-
for (const line of hunk.lines) {
|
|
18197
|
-
ret.push(line);
|
|
18198
|
-
}
|
|
18199
|
-
}
|
|
18200
|
-
return ret.join("\n") + "\n";
|
|
18201
|
-
}
|
|
18202
|
-
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
18203
|
-
if (typeof options === "function") {
|
|
18204
|
-
options = { callback: options };
|
|
18205
|
-
}
|
|
18206
|
-
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
|
|
18207
|
-
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
18208
|
-
if (!patchObj) {
|
|
18209
|
-
return;
|
|
18210
|
-
}
|
|
18211
|
-
return formatPatch(patchObj);
|
|
18212
|
-
} else {
|
|
18213
|
-
const { callback } = options;
|
|
18214
|
-
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
|
|
18215
|
-
if (!patchObj) {
|
|
18216
|
-
callback(void 0);
|
|
18217
|
-
} else {
|
|
18218
|
-
callback(formatPatch(patchObj));
|
|
18219
|
-
}
|
|
18220
|
-
} }));
|
|
18221
|
-
}
|
|
18222
|
-
}
|
|
18223
|
-
function splitLines(text) {
|
|
18224
|
-
const hasTrailingNl = text.endsWith("\n");
|
|
18225
|
-
const result = text.split("\n").map((line) => line + "\n");
|
|
18226
|
-
if (hasTrailingNl) {
|
|
18227
|
-
result.pop();
|
|
18228
|
-
} else {
|
|
18229
|
-
result.push(result.pop().slice(0, -1));
|
|
18230
|
-
}
|
|
18231
|
-
return result;
|
|
18232
|
-
}
|
|
18233
|
-
|
|
18234
|
-
// dist/omp-adapter.js
|
|
18235
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
18236
|
-
import { realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
18237
|
-
import path7 from "node:path";
|
|
18238
|
-
|
|
18239
|
-
// dist/omp-slash-commands.js
|
|
18240
|
-
var OMP_LIVE_COMMAND_ID_PREFIX = "omp.slash.";
|
|
18241
|
-
function isRecord6(value) {
|
|
18242
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18243
|
-
}
|
|
18244
|
-
function parseOmpAvailableCommands(value) {
|
|
18245
|
-
if (!Array.isArray(value))
|
|
18246
|
-
return [];
|
|
18247
|
-
return value.flatMap((entry) => {
|
|
18248
|
-
if (!isRecord6(entry))
|
|
18249
|
-
return [];
|
|
18250
|
-
const name = typeof entry.name === "string" ? entry.name.trim().replace(/^\//u, "") : "";
|
|
18251
|
-
if (!name)
|
|
18252
|
-
return [];
|
|
18253
|
-
return [
|
|
18254
|
-
{
|
|
18255
|
-
name,
|
|
18256
|
-
description: typeof entry.description === "string" ? entry.description : "",
|
|
18257
|
-
source: typeof entry.source === "string" ? entry.source : null
|
|
18258
|
-
}
|
|
18259
|
-
];
|
|
18260
|
-
});
|
|
18261
|
-
}
|
|
18262
|
-
function ompLiveCommands(native) {
|
|
18263
|
-
return native.filter(({ source, name }) => source !== "builtin" || name === "context").map((command) => ({
|
|
18264
|
-
name: command.name,
|
|
18265
|
-
description: command.description,
|
|
18266
|
-
kind: command.source === "skill" ? "skill" : "command"
|
|
18267
|
-
}));
|
|
18268
|
-
}
|
|
18269
|
-
|
|
18270
|
-
// dist/omp-session-file.js
|
|
18271
|
-
import { createReadStream as createReadStream3 } from "node:fs";
|
|
18272
|
-
import { open, realpath as realpath2 } from "node:fs/promises";
|
|
18273
|
-
import readline from "node:readline";
|
|
18274
|
-
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
18275
|
-
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
18276
|
-
function isRecord7(value) {
|
|
18277
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18278
|
-
}
|
|
18279
|
-
function historyEntry(value) {
|
|
18280
|
-
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") {
|
|
18281
|
-
return null;
|
|
18282
|
-
}
|
|
18283
|
-
return value;
|
|
18284
|
-
}
|
|
18285
|
-
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
18286
|
-
const entries = [];
|
|
18287
|
-
let leafId = null;
|
|
18288
|
-
let incomplete = false;
|
|
18289
|
-
const lines = readline.createInterface({
|
|
18290
|
-
input: createReadStream3(sessionFile, {
|
|
18291
|
-
encoding: "utf8",
|
|
18292
|
-
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
18293
|
-
}),
|
|
18294
|
-
crlfDelay: Number.POSITIVE_INFINITY
|
|
18295
|
-
});
|
|
18296
|
-
try {
|
|
18297
|
-
for await (const line of lines) {
|
|
18298
|
-
if (line.length === 0)
|
|
18299
|
-
continue;
|
|
18300
|
-
let parsed;
|
|
18301
|
-
try {
|
|
18302
|
-
parsed = JSON.parse(line);
|
|
18303
|
-
} catch {
|
|
18304
|
-
incomplete = true;
|
|
18305
|
-
continue;
|
|
18306
|
-
}
|
|
18307
|
-
const entry = historyEntry(parsed);
|
|
18308
|
-
if (!entry) {
|
|
18309
|
-
if (!isRecord7(parsed) || parsed.type !== "title" && parsed.type !== "session") {
|
|
18310
|
-
incomplete = true;
|
|
18311
|
-
}
|
|
18312
|
-
continue;
|
|
18313
|
-
}
|
|
18314
|
-
entries.push(entry);
|
|
18315
|
-
leafId = entry.id;
|
|
18316
|
-
}
|
|
18317
|
-
} finally {
|
|
18318
|
-
lines.close();
|
|
18319
|
-
}
|
|
18320
|
-
return { entries, leafId, ...incomplete ? { incomplete: true } : {} };
|
|
18321
|
-
}
|
|
18322
|
-
async function readOmpSessionHeader(sessionFile) {
|
|
18323
|
-
const handle = await open(sessionFile, "r");
|
|
18324
|
-
try {
|
|
18325
|
-
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
18326
|
-
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
18327
|
-
const contents = buffer.subarray(0, bytesRead);
|
|
18328
|
-
const newline = contents.indexOf(10);
|
|
18329
|
-
if (newline < 0 && bytesRead === buffer.length) {
|
|
18330
|
-
throw new Error("Omp Session header exceeds the supported size");
|
|
18331
|
-
}
|
|
18332
|
-
const contentsText = utf8Decoder.decode(contents);
|
|
18333
|
-
for (const line of contentsText.split("\n")) {
|
|
18334
|
-
if (line.length === 0)
|
|
18335
|
-
continue;
|
|
18336
|
-
let parsed;
|
|
18337
|
-
try {
|
|
18338
|
-
parsed = JSON.parse(line);
|
|
18339
|
-
} catch {
|
|
18340
|
-
continue;
|
|
18341
|
-
}
|
|
18342
|
-
if (!isRecord7(parsed) || parsed.type !== "session")
|
|
18343
|
-
continue;
|
|
18344
|
-
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
18345
|
-
throw new Error("Omp Session header is invalid");
|
|
18346
|
-
}
|
|
18347
|
-
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
18348
|
-
}
|
|
18349
|
-
throw new Error("Omp Session header is invalid");
|
|
18350
|
-
} finally {
|
|
18351
|
-
await handle.close();
|
|
18352
|
-
}
|
|
18353
|
-
}
|
|
18354
|
-
async function verifyOmpSessionCwd(input) {
|
|
18355
|
-
if (!input.sessionFile)
|
|
18356
|
-
throw new Error("Omp Fork Session has no persisted Session file");
|
|
18357
|
-
const header = await readOmpSessionHeader(input.sessionFile);
|
|
18358
|
-
if (header.id !== input.sessionId) {
|
|
18359
|
-
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
18360
|
-
}
|
|
18361
|
-
const [actualCwd, expectedCwd] = await Promise.all([
|
|
18362
|
-
realpath2(header.cwd),
|
|
18363
|
-
realpath2(input.expectedCwd)
|
|
18364
|
-
]);
|
|
18365
|
-
if (actualCwd !== expectedCwd) {
|
|
18366
|
-
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
18367
|
-
}
|
|
18368
|
-
}
|
|
18369
|
-
|
|
18370
|
-
// dist/omp-last-turn-rollback.js
|
|
18371
|
-
function modelFromState(state) {
|
|
18372
|
-
if (state.provider === null && state.modelId === null)
|
|
18373
|
-
return null;
|
|
18374
|
-
if (state.provider === null || state.modelId === null) {
|
|
18375
|
-
throw new Error("Omp state contains a partial Model identity");
|
|
18376
|
-
}
|
|
18377
|
-
return { provider: state.provider, id: state.modelId };
|
|
18378
|
-
}
|
|
18379
|
-
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
18380
|
-
const startupState = transport.state;
|
|
18381
|
-
const startupSessionId = startupState.sessionId;
|
|
18382
|
-
const currentModel = modelFromState(startupState);
|
|
18383
|
-
const currentThinking = startupState.thinkingLevel;
|
|
18384
|
-
const copiedHistory = await transport.getEntries();
|
|
18385
|
-
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
18386
|
-
if (!boundary)
|
|
18387
|
-
return { ok: false, reason: "empty" };
|
|
18388
|
-
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
18389
|
-
sessionId: startupSessionId,
|
|
18390
|
-
model: currentModel
|
|
18391
|
-
});
|
|
18392
|
-
let state = await transport.fork(boundary.lastUserEntryId);
|
|
18393
|
-
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
18394
|
-
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
18395
|
-
}
|
|
18396
|
-
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
18397
|
-
if (!currentModel)
|
|
18398
|
-
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
18399
|
-
state = await transport.selectModel(currentModel);
|
|
18400
|
-
}
|
|
18401
|
-
if (state.thinkingLevel !== currentThinking) {
|
|
18402
|
-
if (!currentThinking)
|
|
18403
|
-
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
18404
|
-
state = await transport.selectThinkingOption(currentThinking);
|
|
18405
|
-
}
|
|
18406
|
-
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
18407
|
-
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
18408
|
-
}
|
|
18409
|
-
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
18410
|
-
sessionId: state.sessionId,
|
|
18411
|
-
model: modelFromState(state)
|
|
18412
|
-
});
|
|
18413
|
-
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
18414
|
-
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
18415
|
-
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
18416
|
-
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
18417
|
-
}
|
|
18418
|
-
await transport.verifySessionCwd(cwd);
|
|
18419
|
-
return { ok: true };
|
|
18420
|
-
}
|
|
18421
|
-
|
|
18422
|
-
// dist/omp-rpc-session.js
|
|
18423
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
18424
|
-
import { randomUUID } from "node:crypto";
|
|
18425
|
-
import path6 from "node:path";
|
|
18426
|
-
|
|
18427
|
-
// dist/command.js
|
|
18428
|
-
var ompDiscoverySpec = {
|
|
18429
|
-
id: "omp",
|
|
18430
|
-
command: "omp",
|
|
18431
|
-
commandEnvironmentVariable: "OMP_COMMAND",
|
|
18432
|
-
installRoots: {
|
|
18433
|
-
posix: [
|
|
18434
|
-
"~/.npm-global/bin",
|
|
18435
|
-
"~/.local/bin",
|
|
18436
|
-
VERSION_MANAGER_ROOTS,
|
|
18437
|
-
"/opt/homebrew/bin",
|
|
18438
|
-
"/usr/local/bin"
|
|
18439
|
-
],
|
|
18440
|
-
windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS]
|
|
18441
|
-
}
|
|
18442
|
-
};
|
|
18443
|
-
function resolveOmpExecutable(input, dependencies = {}) {
|
|
18444
|
-
const resolution = resolveHarnessExecutable(ompDiscoverySpec, {
|
|
18445
|
-
...input.command ? { command: input.command } : {},
|
|
18446
|
-
environment: input.environment,
|
|
18447
|
-
...dependencies.platform ? { platform: dependencies.platform } : {},
|
|
18448
|
-
...dependencies.homeDirectory ? { homeDirectory: dependencies.homeDirectory } : {}
|
|
18449
|
-
}, { ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {} });
|
|
18450
|
-
return resolution?.executable ?? input.command ?? input.environment.OMP_COMMAND ?? "omp";
|
|
18451
|
-
}
|
|
18452
|
-
|
|
18453
|
-
// dist/omp-protocol.js
|
|
18454
|
-
var MAX_FRAME_BYTES = 1024 * 1024;
|
|
18455
|
-
var MAX_REASSEMBLED_BYTES = 64 * 1024 * 1024;
|
|
18456
|
-
var MAX_CHUNK_BYTES = 256 * 1024;
|
|
18457
|
-
function isObject2(value) {
|
|
18458
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18459
|
-
}
|
|
18460
|
-
var OmpFrameDecoder = class {
|
|
18461
|
-
#pending = null;
|
|
18462
|
-
push(value) {
|
|
18463
|
-
if (!isObject2(value))
|
|
18464
|
-
throw new Error("OMP RPC frame must be a JSON object");
|
|
18465
|
-
if (value.type !== "rpc_chunk") {
|
|
18466
|
-
if (this.#pending)
|
|
18467
|
-
throw new Error("OMP RPC chunk sequence was interrupted");
|
|
18468
|
-
return value;
|
|
18469
|
-
}
|
|
18470
|
-
const chunkId = value.chunkId;
|
|
18471
|
-
const index = value.index;
|
|
18472
|
-
const count2 = value.count;
|
|
18473
|
-
const byteLength = value.byteLength;
|
|
18474
|
-
const data = value.data;
|
|
18475
|
-
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)
|
|
18476
|
-
throw new Error("Invalid OMP RPC chunk metadata");
|
|
18477
|
-
let bytes;
|
|
18478
|
-
try {
|
|
18479
|
-
bytes = Buffer.from(data, "base64");
|
|
18480
|
-
} catch {
|
|
18481
|
-
throw new Error("Invalid OMP RPC chunk data");
|
|
18482
|
-
}
|
|
18483
|
-
if (bytes.length === 0 || bytes.length > MAX_CHUNK_BYTES || bytes.toString("base64") !== data) {
|
|
18484
|
-
throw new Error("Invalid OMP RPC chunk data");
|
|
18485
|
-
}
|
|
18486
|
-
const chunkIndex = index;
|
|
18487
|
-
const chunkCount = count2;
|
|
18488
|
-
const declaredByteLength = byteLength;
|
|
18489
|
-
if (!this.#pending) {
|
|
18490
|
-
if (chunkIndex !== 0)
|
|
18491
|
-
throw new Error("OMP RPC chunk sequence must start at index 0");
|
|
18492
|
-
this.#pending = {
|
|
18493
|
-
chunkId,
|
|
18494
|
-
count: chunkCount,
|
|
18495
|
-
byteLength: declaredByteLength,
|
|
18496
|
-
nextIndex: 0,
|
|
18497
|
-
chunks: [],
|
|
18498
|
-
received: 0
|
|
18499
|
-
};
|
|
18500
|
-
}
|
|
18501
|
-
const pending = this.#pending;
|
|
18502
|
-
if (!pending)
|
|
18503
|
-
throw new Error("OMP RPC chunk state was lost");
|
|
18504
|
-
if (pending.chunkId !== chunkId || pending.count !== chunkCount || pending.byteLength !== declaredByteLength || pending.nextIndex !== chunkIndex) {
|
|
18505
|
-
throw new Error("OMP RPC chunk sequence mismatch");
|
|
18506
|
-
}
|
|
18507
|
-
pending.chunks.push(bytes);
|
|
18508
|
-
pending.received += bytes.length;
|
|
18509
|
-
pending.nextIndex += 1;
|
|
18510
|
-
if (pending.received > pending.byteLength)
|
|
18511
|
-
throw new Error("OMP RPC chunk sequence exceeds its declared length");
|
|
18512
|
-
if (pending.nextIndex < pending.count)
|
|
18513
|
-
return null;
|
|
18514
|
-
if (pending.received !== pending.byteLength)
|
|
18515
|
-
throw new Error("OMP RPC chunk sequence length mismatch");
|
|
18516
|
-
this.#pending = null;
|
|
18517
|
-
let decoded;
|
|
18518
|
-
try {
|
|
18519
|
-
decoded = JSON.parse(Buffer.concat(pending.chunks).toString("utf8"));
|
|
18520
|
-
} catch {
|
|
18521
|
-
throw new Error("Failed to decode reassembled OMP RPC frame");
|
|
18522
|
-
}
|
|
18523
|
-
if (!isObject2(decoded))
|
|
18524
|
-
throw new Error("Reassembled OMP RPC frame must be an object");
|
|
18525
|
-
return decoded;
|
|
18526
|
-
}
|
|
18527
|
-
};
|
|
18528
|
-
|
|
18529
|
-
// dist/omp-rpc-session.js
|
|
18530
|
-
var OmpRpcFaultError = class extends Error {
|
|
18531
|
-
kind;
|
|
18532
|
-
diagnostic;
|
|
18533
|
-
constructor(kind, message3, diagnostic) {
|
|
18534
|
-
super(message3);
|
|
18535
|
-
this.kind = kind;
|
|
18536
|
-
this.diagnostic = diagnostic;
|
|
18537
|
-
this.name = "OmpRpcFaultError";
|
|
18538
|
-
}
|
|
18539
|
-
};
|
|
18540
|
-
var OmpRpcUnsupportedCommandError = class extends Error {
|
|
18541
|
-
command;
|
|
18542
|
-
constructor(command) {
|
|
18543
|
-
super(`Omp RPC does not support '${command}'`);
|
|
18544
|
-
this.command = command;
|
|
18545
|
-
this.name = "OmpRpcUnsupportedCommandError";
|
|
18546
|
-
}
|
|
18547
|
-
};
|
|
18548
|
-
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
18549
|
-
function isRecord8(value) {
|
|
18550
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18551
|
-
}
|
|
18552
|
-
function message2(value) {
|
|
18553
|
-
return value instanceof Error ? value.message : String(value);
|
|
18554
|
-
}
|
|
18555
|
-
function nonBlankString(value) {
|
|
18556
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
18557
|
-
}
|
|
18558
|
-
function parseNativeModel(value, context) {
|
|
18559
|
-
if (value === null || value === void 0)
|
|
18560
|
-
return null;
|
|
18561
|
-
if (!isRecord8(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
18562
|
-
throw new OmpRpcFaultError("protocolError", `Omp RPC returned an invalid ${context} Model`);
|
|
18563
|
-
}
|
|
18564
|
-
return { provider: value.provider, id: value.id };
|
|
18105
|
+
return { provider: value.provider, id: value.id };
|
|
18565
18106
|
}
|
|
18566
18107
|
function sessionStateData(response) {
|
|
18567
18108
|
const data = isRecord8(response.data) ? response.data : null;
|
|
@@ -18789,1178 +18330,1844 @@ var OmpRpcSession = class {
|
|
|
18789
18330
|
if (options.model && (options.sessionFile || options.forkSessionFile)) {
|
|
18790
18331
|
throw new Error("Omp RPC cannot combine a startup Model with Session restore or Fork");
|
|
18791
18332
|
}
|
|
18792
|
-
this.#options = {
|
|
18793
|
-
commandTimeoutMs: 3e4,
|
|
18794
|
-
compactionTimeoutMs: 3e5,
|
|
18795
|
-
// Native Abort waits for tools, persistence and deferred work to unwind.
|
|
18796
|
-
// Stable cancellation must outlast the Host's 20s steering wait.
|
|
18797
|
-
cancelTimeoutMs: 3e4,
|
|
18798
|
-
closeTimeoutMs: 2e3,
|
|
18799
|
-
...options
|
|
18800
|
-
};
|
|
18801
|
-
this.#processAdapter = processAdapter;
|
|
18333
|
+
this.#options = {
|
|
18334
|
+
commandTimeoutMs: 3e4,
|
|
18335
|
+
compactionTimeoutMs: 3e5,
|
|
18336
|
+
// Native Abort waits for tools, persistence and deferred work to unwind.
|
|
18337
|
+
// Stable cancellation must outlast the Host's 20s steering wait.
|
|
18338
|
+
cancelTimeoutMs: 3e4,
|
|
18339
|
+
closeTimeoutMs: 2e3,
|
|
18340
|
+
...options
|
|
18341
|
+
};
|
|
18342
|
+
this.#processAdapter = processAdapter;
|
|
18343
|
+
}
|
|
18344
|
+
get state() {
|
|
18345
|
+
if (!this.#state)
|
|
18346
|
+
throw new Error("Omp RPC Session has not started");
|
|
18347
|
+
return this.#state;
|
|
18348
|
+
}
|
|
18349
|
+
get stderrTail() {
|
|
18350
|
+
return this.#stderrTail;
|
|
18351
|
+
}
|
|
18352
|
+
async start() {
|
|
18353
|
+
if (this.#child || this.#closed)
|
|
18354
|
+
throw new Error("Omp RPC Session cannot be started twice");
|
|
18355
|
+
const child = this.#processAdapter.spawn({
|
|
18356
|
+
cwd: this.#options.cwd,
|
|
18357
|
+
...this.#options.command ? { command: this.#options.command } : {},
|
|
18358
|
+
environment: withNodeRuntimeOnPath({
|
|
18359
|
+
...process.env,
|
|
18360
|
+
...this.#options.environment,
|
|
18361
|
+
OMP_SKIP_VERSION_CHECK: "1",
|
|
18362
|
+
OMP_TELEMETRY: "0"
|
|
18363
|
+
}),
|
|
18364
|
+
...this.#options.sessionFile ? { sessionFile: this.#options.sessionFile } : {},
|
|
18365
|
+
...this.#options.forkSessionFile ? { forkSessionFile: this.#options.forkSessionFile } : {},
|
|
18366
|
+
...this.#options.model ? { model: this.#options.model } : {},
|
|
18367
|
+
...this.#options.permissionMode ? { permissionMode: this.#options.permissionMode } : {}
|
|
18368
|
+
});
|
|
18369
|
+
this.#child = child;
|
|
18370
|
+
child.stdout.on("data", (chunk) => this.#push(chunk));
|
|
18371
|
+
child.stdout.on("end", () => {
|
|
18372
|
+
if (this.#buffer.length !== 0) {
|
|
18373
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC stdout ended mid-frame"));
|
|
18374
|
+
}
|
|
18375
|
+
});
|
|
18376
|
+
child.stderr.on("data", (chunk) => {
|
|
18377
|
+
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
18378
|
+
});
|
|
18379
|
+
child.once("error", (error51) => {
|
|
18380
|
+
const kind = isRecord8(error51) && error51.code === "ENOENT" ? "notInstalled" : "unavailable";
|
|
18381
|
+
this.#fail(new OmpRpcFaultError(kind, `Omp RPC failed to start: ${error51.message}`, this.stderrTail));
|
|
18382
|
+
});
|
|
18383
|
+
child.once("exit", (code, signal) => {
|
|
18384
|
+
if (!this.#closed) {
|
|
18385
|
+
this.#fail(new OmpRpcFaultError("processExited", `Omp RPC exited (code=${code}, signal=${signal})`, this.stderrTail));
|
|
18386
|
+
}
|
|
18387
|
+
});
|
|
18388
|
+
await Promise.race([
|
|
18389
|
+
new Promise((resolve, reject) => {
|
|
18390
|
+
child.once("spawn", resolve);
|
|
18391
|
+
child.once("error", reject);
|
|
18392
|
+
}),
|
|
18393
|
+
new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Omp RPC start timed out")), this.#options.commandTimeoutMs))
|
|
18394
|
+
]);
|
|
18395
|
+
let readyTimeout;
|
|
18396
|
+
try {
|
|
18397
|
+
await Promise.race([
|
|
18398
|
+
this.#ready,
|
|
18399
|
+
this.#startupFault.then((error51) => {
|
|
18400
|
+
throw error51;
|
|
18401
|
+
}),
|
|
18402
|
+
new Promise((_resolve, reject) => {
|
|
18403
|
+
readyTimeout = setTimeout(() => reject(new Error("Omp RPC ready signal timed out")), this.#options.commandTimeoutMs);
|
|
18404
|
+
})
|
|
18405
|
+
]);
|
|
18406
|
+
} finally {
|
|
18407
|
+
clearTimeout(readyTimeout);
|
|
18408
|
+
}
|
|
18409
|
+
await this.#send("negotiate_protocol", { protocolVersion: 2 }).catch(() => void 0);
|
|
18410
|
+
if (this.#options.subscribeSubagentEvents !== false) {
|
|
18411
|
+
await this.#send("set_subagent_subscription", { level: "events" }).catch(() => void 0);
|
|
18412
|
+
}
|
|
18413
|
+
try {
|
|
18414
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18415
|
+
} catch (error51) {
|
|
18416
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("unavailable", `Omp RPC state unavailable: ${message2(error51)}`);
|
|
18417
|
+
this.#fail(fault);
|
|
18418
|
+
throw fault;
|
|
18419
|
+
}
|
|
18420
|
+
return this;
|
|
18421
|
+
}
|
|
18422
|
+
async getEntries() {
|
|
18423
|
+
try {
|
|
18424
|
+
if (this.state.sessionFile) {
|
|
18425
|
+
try {
|
|
18426
|
+
return await readOmpSessionHistory(this.state.sessionFile);
|
|
18427
|
+
} catch (error51) {
|
|
18428
|
+
if (!isRecord8(error51) || error51.code !== "ENOENT" || this.#options.sessionFile || this.#options.forkSessionFile)
|
|
18429
|
+
throw error51;
|
|
18430
|
+
const response2 = await this.#send("get_messages", {});
|
|
18431
|
+
const data2 = isRecord8(response2.data) ? response2.data : null;
|
|
18432
|
+
if (data2 && Array.isArray(data2.messages) && data2.messages.length === 0) {
|
|
18433
|
+
return { entries: [], leafId: null };
|
|
18434
|
+
}
|
|
18435
|
+
throw error51;
|
|
18436
|
+
}
|
|
18437
|
+
}
|
|
18438
|
+
const response = await this.#send("get_messages", {});
|
|
18439
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18440
|
+
if (!data || !Array.isArray(data.messages)) {
|
|
18441
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC messages response has no messages");
|
|
18442
|
+
}
|
|
18443
|
+
let branchEntryIds = null;
|
|
18444
|
+
try {
|
|
18445
|
+
const branchResponse = await this.#send("get_branch_messages", {});
|
|
18446
|
+
const branchData = isRecord8(branchResponse.data) ? branchResponse.data : null;
|
|
18447
|
+
if (branchData && Array.isArray(branchData.messages)) {
|
|
18448
|
+
const parsed = branchData.messages.flatMap((entry) => {
|
|
18449
|
+
if (!isRecord8(entry) || !nonBlankString(entry.entryId))
|
|
18450
|
+
return [];
|
|
18451
|
+
return [entry.entryId];
|
|
18452
|
+
});
|
|
18453
|
+
if (parsed.length === branchData.messages.length)
|
|
18454
|
+
branchEntryIds = parsed;
|
|
18455
|
+
}
|
|
18456
|
+
} catch (error51) {
|
|
18457
|
+
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18458
|
+
throw error51;
|
|
18459
|
+
}
|
|
18460
|
+
let userIndex = 0;
|
|
18461
|
+
let parentId = null;
|
|
18462
|
+
const entries = data.messages.map((nativeMessage, index) => {
|
|
18463
|
+
const role = isRecord8(nativeMessage) ? nativeMessage.role : void 0;
|
|
18464
|
+
const branchId = role === "user" ? branchEntryIds?.[userIndex] : void 0;
|
|
18465
|
+
if (branchId)
|
|
18466
|
+
userIndex += 1;
|
|
18467
|
+
const id = branchId ?? (isRecord8(nativeMessage) && nonBlankString(nativeMessage.id) ? nativeMessage.id : `omp-message-${index}`);
|
|
18468
|
+
const entry = { id, parentId, type: "message", message: nativeMessage };
|
|
18469
|
+
parentId = id;
|
|
18470
|
+
return entry;
|
|
18471
|
+
});
|
|
18472
|
+
return { entries, leafId: parentId };
|
|
18473
|
+
} catch (error51) {
|
|
18474
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18475
|
+
this.#fail(error51);
|
|
18476
|
+
throw error51;
|
|
18477
|
+
}
|
|
18478
|
+
}
|
|
18479
|
+
async getSubagentMessages(input) {
|
|
18480
|
+
if ((input.subagentId === void 0 || !nonBlankString(input.subagentId)) && (input.sessionFile === void 0 || !nonBlankString(input.sessionFile))) {
|
|
18481
|
+
throw new Error("Omp Subagent transcript requires a Subagent ID or Session file");
|
|
18482
|
+
}
|
|
18483
|
+
if (input.fromByte !== void 0 && (!Number.isSafeInteger(input.fromByte) || input.fromByte < 0)) {
|
|
18484
|
+
throw new Error("Omp Subagent transcript offset is invalid");
|
|
18485
|
+
}
|
|
18486
|
+
const response = await this.#send("get_subagent_messages", {
|
|
18487
|
+
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
18488
|
+
...input.sessionFile ? { sessionFile: input.sessionFile } : {},
|
|
18489
|
+
...input.fromByte !== void 0 ? { fromByte: input.fromByte } : {}
|
|
18490
|
+
});
|
|
18491
|
+
return parseSubagentMessages(response);
|
|
18492
|
+
}
|
|
18493
|
+
async compact(customInstructions, onEvent) {
|
|
18494
|
+
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
18495
|
+
throw new Error("Omp RPC Session is unavailable");
|
|
18496
|
+
}
|
|
18497
|
+
if (this.#activeTurn || this.#manualCompaction || this.#compactionActive) {
|
|
18498
|
+
throw new Error("Omp RPC Session already has an active operation");
|
|
18499
|
+
}
|
|
18500
|
+
const result = new Promise((resolve, reject) => {
|
|
18501
|
+
this.#manualCompaction = { onEvent, resolve, reject };
|
|
18502
|
+
});
|
|
18503
|
+
try {
|
|
18504
|
+
await this.#send("compact", customInstructions ? { customInstructions } : {});
|
|
18505
|
+
} catch (error51) {
|
|
18506
|
+
const pending = this.#manualCompaction;
|
|
18507
|
+
this.#manualCompaction = null;
|
|
18508
|
+
pending?.reject(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
18509
|
+
}
|
|
18510
|
+
return result;
|
|
18511
|
+
}
|
|
18512
|
+
async getSessionUsage() {
|
|
18513
|
+
try {
|
|
18514
|
+
const usage = parseOmpSessionUsage(await this.#send("get_session_stats", {}));
|
|
18515
|
+
await this.#ensureLatestCacheHitRate();
|
|
18516
|
+
return this.#withLatestCacheHitRate(usage);
|
|
18517
|
+
} catch (error51) {
|
|
18518
|
+
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18519
|
+
throw error51;
|
|
18520
|
+
const response = await this.#send("get_state", {});
|
|
18521
|
+
const observedState = parseSessionState(response);
|
|
18522
|
+
if (!this.#state || observedState.sessionId !== this.#state.sessionId || observedState.provider !== this.#state.provider || observedState.modelId !== this.#state.modelId) {
|
|
18523
|
+
throw new Error("Omp RPC Usage fallback does not match the confirmed Session state");
|
|
18524
|
+
}
|
|
18525
|
+
await this.#ensureLatestCacheHitRate();
|
|
18526
|
+
const usage = parseOmpStateContextUsage(response);
|
|
18527
|
+
return usage ? this.#withLatestCacheHitRate(usage) : null;
|
|
18528
|
+
}
|
|
18802
18529
|
}
|
|
18803
|
-
|
|
18804
|
-
if (
|
|
18805
|
-
|
|
18806
|
-
|
|
18530
|
+
async #ensureLatestCacheHitRate() {
|
|
18531
|
+
if (this.#latestCacheHitRatePercent !== void 0)
|
|
18532
|
+
return;
|
|
18533
|
+
try {
|
|
18534
|
+
this.#latestCacheHitRatePercent = latestOmpCacheHitRatePercent(await this.getEntries());
|
|
18535
|
+
} catch {
|
|
18536
|
+
this.#latestCacheHitRatePercent = null;
|
|
18537
|
+
}
|
|
18807
18538
|
}
|
|
18808
|
-
|
|
18809
|
-
return this.#
|
|
18539
|
+
#withLatestCacheHitRate(usage) {
|
|
18540
|
+
return this.#latestCacheHitRatePercent === null || this.#latestCacheHitRatePercent === void 0 ? usage : parseHostUsage({ ...usage, cacheHitRatePercent: this.#latestCacheHitRatePercent });
|
|
18810
18541
|
}
|
|
18811
|
-
async
|
|
18812
|
-
if (
|
|
18813
|
-
throw new Error("Omp RPC
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
|
|
18817
|
-
|
|
18818
|
-
|
|
18819
|
-
...this.#options.environment,
|
|
18820
|
-
OMP_SKIP_VERSION_CHECK: "1",
|
|
18821
|
-
OMP_TELEMETRY: "0"
|
|
18822
|
-
}),
|
|
18823
|
-
...this.#options.sessionFile ? { sessionFile: this.#options.sessionFile } : {},
|
|
18824
|
-
...this.#options.forkSessionFile ? { forkSessionFile: this.#options.forkSessionFile } : {},
|
|
18825
|
-
...this.#options.model ? { model: this.#options.model } : {},
|
|
18826
|
-
...this.#options.permissionMode ? { permissionMode: this.#options.permissionMode } : {}
|
|
18827
|
-
});
|
|
18828
|
-
this.#child = child;
|
|
18829
|
-
child.stdout.on("data", (chunk) => this.#push(chunk));
|
|
18830
|
-
child.stdout.on("end", () => {
|
|
18831
|
-
if (this.#buffer.length !== 0) {
|
|
18832
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC stdout ended mid-frame"));
|
|
18542
|
+
async fork(entryId) {
|
|
18543
|
+
if (!nonBlankString(entryId))
|
|
18544
|
+
throw new Error("Omp RPC Fork requires an Entry identity");
|
|
18545
|
+
try {
|
|
18546
|
+
const response = await this.#send("branch", { entryId });
|
|
18547
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
18548
|
+
if (!data || data.cancelled === true) {
|
|
18549
|
+
throw new OmpRpcFaultError("unavailable", "Omp RPC Fork was cancelled");
|
|
18833
18550
|
}
|
|
18551
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18552
|
+
return this.#state;
|
|
18553
|
+
} catch (error51) {
|
|
18554
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18555
|
+
this.#fail(error51);
|
|
18556
|
+
throw error51;
|
|
18557
|
+
}
|
|
18558
|
+
}
|
|
18559
|
+
verifySessionCwd(expectedCwd) {
|
|
18560
|
+
return verifyOmpSessionCwd({
|
|
18561
|
+
sessionFile: this.state.sessionFile,
|
|
18562
|
+
sessionId: this.state.sessionId,
|
|
18563
|
+
expectedCwd
|
|
18834
18564
|
});
|
|
18835
|
-
|
|
18836
|
-
|
|
18837
|
-
|
|
18838
|
-
|
|
18839
|
-
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
|
|
18845
|
-
|
|
18565
|
+
}
|
|
18566
|
+
async getAvailableModels() {
|
|
18567
|
+
try {
|
|
18568
|
+
return parseAvailableModels(await this.#send("get_available_models", {}));
|
|
18569
|
+
} catch (error51) {
|
|
18570
|
+
if (error51 instanceof OmpRpcFaultError)
|
|
18571
|
+
this.#fail(error51);
|
|
18572
|
+
throw error51;
|
|
18573
|
+
}
|
|
18574
|
+
}
|
|
18575
|
+
async getAvailableThinkingLevels() {
|
|
18576
|
+
return this.state.availableThinkingLevels;
|
|
18577
|
+
}
|
|
18578
|
+
async selectModel(model2) {
|
|
18579
|
+
await this.#send("set_model", { provider: model2.provider, modelId: model2.id });
|
|
18580
|
+
return this.#refreshState("Model");
|
|
18581
|
+
}
|
|
18582
|
+
async selectThinkingOption(thinkingOptionId) {
|
|
18583
|
+
const level = harnessThinkingOptionIdSchema.parse(thinkingOptionId);
|
|
18584
|
+
await this.#send("set_thinking_level", { level });
|
|
18585
|
+
return this.#refreshState("Thinking");
|
|
18586
|
+
}
|
|
18587
|
+
async #refreshState(operation) {
|
|
18588
|
+
try {
|
|
18589
|
+
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18590
|
+
return this.#state;
|
|
18591
|
+
} catch (error51) {
|
|
18592
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
18593
|
+
this.#fail(fault);
|
|
18594
|
+
throw fault;
|
|
18595
|
+
}
|
|
18596
|
+
}
|
|
18597
|
+
async runTurn(text, onEvent) {
|
|
18598
|
+
if (!this.#child || !this.#state || this.#closed || this.#failed) {
|
|
18599
|
+
throw new Error("Omp RPC Session is unavailable");
|
|
18600
|
+
}
|
|
18601
|
+
if (this.#activeTurn)
|
|
18602
|
+
throw new Error("Omp RPC Session already has an active Turn");
|
|
18603
|
+
if (text.length === 0)
|
|
18604
|
+
throw new Error("Omp text Turn must not be empty");
|
|
18605
|
+
const promptId = `codexhost-${randomUUID()}`;
|
|
18606
|
+
const settled = new Promise((resolve, reject) => {
|
|
18607
|
+
this.#activeTurn = {
|
|
18608
|
+
promptId,
|
|
18609
|
+
localResult: null,
|
|
18610
|
+
text: "",
|
|
18611
|
+
assistantMessageId: null,
|
|
18612
|
+
sawStreamedMessageText: false,
|
|
18613
|
+
sawStreamedMessageReasoning: false,
|
|
18614
|
+
lastFinalizedMessageText: null,
|
|
18615
|
+
lastFinalizedMessageReasoning: null,
|
|
18616
|
+
reasoningMessageOpen: false,
|
|
18617
|
+
onEvent,
|
|
18618
|
+
resolve,
|
|
18619
|
+
reject,
|
|
18620
|
+
failure: null,
|
|
18621
|
+
sawTool: false,
|
|
18622
|
+
tools: /* @__PURE__ */ new Map(),
|
|
18623
|
+
interactions: /* @__PURE__ */ new Map(),
|
|
18624
|
+
settlement: "pending",
|
|
18625
|
+
terminalEnd: false,
|
|
18626
|
+
cancellation: "none",
|
|
18627
|
+
cancellationTimeout: null,
|
|
18628
|
+
cancellationRecheck: null,
|
|
18629
|
+
cancellationChecking: false,
|
|
18630
|
+
cancellationReloaded: false,
|
|
18631
|
+
abortPromise: null
|
|
18632
|
+
};
|
|
18846
18633
|
});
|
|
18847
|
-
await Promise.race([
|
|
18848
|
-
new Promise((resolve, reject) => {
|
|
18849
|
-
child.once("spawn", resolve);
|
|
18850
|
-
child.once("error", reject);
|
|
18851
|
-
}),
|
|
18852
|
-
new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Omp RPC start timed out")), this.#options.commandTimeoutMs))
|
|
18853
|
-
]);
|
|
18854
|
-
let readyTimeout;
|
|
18855
18634
|
try {
|
|
18856
|
-
await
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
throw error51;
|
|
18860
|
-
}),
|
|
18861
|
-
new Promise((_resolve, reject) => {
|
|
18862
|
-
readyTimeout = setTimeout(() => reject(new Error("Omp RPC ready signal timed out")), this.#options.commandTimeoutMs);
|
|
18863
|
-
})
|
|
18864
|
-
]);
|
|
18865
|
-
} finally {
|
|
18866
|
-
clearTimeout(readyTimeout);
|
|
18635
|
+
await this.#send("prompt", { message: text }, promptId);
|
|
18636
|
+
} catch (error51) {
|
|
18637
|
+
this.#rejectActiveTurn(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
18867
18638
|
}
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
|
|
18639
|
+
return settled;
|
|
18640
|
+
}
|
|
18641
|
+
respondToInteraction(response) {
|
|
18642
|
+
return this.#resolveInteraction(response, "cancelled" in response ? "cancelled" : "responded");
|
|
18643
|
+
}
|
|
18644
|
+
async #resolveInteraction(response, reason) {
|
|
18645
|
+
const active = this.#activeTurn;
|
|
18646
|
+
const pending = active?.interactions.get(response.requestId);
|
|
18647
|
+
if (!active || !pending || this.#closed || this.#failed) {
|
|
18648
|
+
throw new Error("Omp RPC interaction is not pending");
|
|
18649
|
+
}
|
|
18650
|
+
if ("value" in response && !["select", "input", "editor"].includes(pending.request.method)) {
|
|
18651
|
+
throw new Error("Omp RPC interaction response type does not match the request");
|
|
18652
|
+
}
|
|
18653
|
+
if ("confirmed" in response && pending.request.method !== "confirm") {
|
|
18654
|
+
throw new Error("Omp RPC confirmation does not match the request");
|
|
18655
|
+
}
|
|
18656
|
+
const frame = "cancelled" in response ? {
|
|
18657
|
+
type: "extension_ui_response",
|
|
18658
|
+
id: response.requestId,
|
|
18659
|
+
cancelled: true,
|
|
18660
|
+
...reason === "expired" ? { timedOut: true } : {}
|
|
18661
|
+
} : "confirmed" in response ? { type: "extension_ui_response", id: response.requestId, confirmed: response.confirmed } : { type: "extension_ui_response", id: response.requestId, value: response.value };
|
|
18662
|
+
if (!active.interactions.delete(response.requestId)) {
|
|
18663
|
+
throw new Error("Omp RPC interaction is not pending");
|
|
18871
18664
|
}
|
|
18665
|
+
if (pending.timeout)
|
|
18666
|
+
clearTimeout(pending.timeout);
|
|
18667
|
+
active.onEvent({ type: "interaction.closed", requestId: response.requestId, reason });
|
|
18872
18668
|
try {
|
|
18873
|
-
|
|
18669
|
+
await this.#write(frame);
|
|
18874
18670
|
} catch (error51) {
|
|
18875
|
-
const fault =
|
|
18671
|
+
const fault = new OmpRpcFaultError("protocolError", `Omp RPC interaction response failed: ${message2(error51)}`);
|
|
18876
18672
|
this.#fail(fault);
|
|
18877
18673
|
throw fault;
|
|
18878
18674
|
}
|
|
18879
|
-
return this;
|
|
18880
18675
|
}
|
|
18881
|
-
|
|
18882
|
-
|
|
18883
|
-
|
|
18884
|
-
|
|
18885
|
-
|
|
18886
|
-
|
|
18887
|
-
|
|
18888
|
-
|
|
18889
|
-
|
|
18890
|
-
|
|
18891
|
-
|
|
18892
|
-
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
|
|
18897
|
-
|
|
18898
|
-
|
|
18899
|
-
|
|
18900
|
-
|
|
18676
|
+
abort() {
|
|
18677
|
+
const active = this.#activeTurn;
|
|
18678
|
+
if (!active || this.#closed || this.#failed) {
|
|
18679
|
+
return Promise.reject(new Error("Omp RPC Session has no cancellable Turn"));
|
|
18680
|
+
}
|
|
18681
|
+
if (active.abortPromise)
|
|
18682
|
+
return active.abortPromise;
|
|
18683
|
+
active.cancellation = "requesting";
|
|
18684
|
+
active.cancellationTimeout = setTimeout(() => {
|
|
18685
|
+
this.#terminateFailedCancellation(active, new OmpRpcFaultError("protocolError", "Omp Turn cancellation did not settle within its bound"));
|
|
18686
|
+
}, this.#options.cancelTimeoutMs);
|
|
18687
|
+
const aborting = this.#send("abort", {}).then(async () => {
|
|
18688
|
+
if (this.#activeTurn !== active)
|
|
18689
|
+
return;
|
|
18690
|
+
active.cancellation = "accepted";
|
|
18691
|
+
await this.#confirmCancelledTurn(active);
|
|
18692
|
+
}).catch((error51) => {
|
|
18693
|
+
if (this.#activeTurn !== active)
|
|
18694
|
+
throw error51;
|
|
18695
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC Abort failed: ${message2(error51)}`);
|
|
18696
|
+
this.#terminateFailedCancellation(active, fault);
|
|
18697
|
+
throw fault;
|
|
18698
|
+
});
|
|
18699
|
+
active.abortPromise = aborting;
|
|
18700
|
+
return aborting;
|
|
18701
|
+
}
|
|
18702
|
+
#terminateFailedCancellation(active, fault) {
|
|
18703
|
+
if (this.#activeTurn !== active)
|
|
18704
|
+
return;
|
|
18705
|
+
if (active.cancellationTimeout)
|
|
18706
|
+
clearTimeout(active.cancellationTimeout);
|
|
18707
|
+
active.cancellationTimeout = null;
|
|
18708
|
+
this.#fail(fault);
|
|
18709
|
+
void this.close().catch(() => void 0);
|
|
18710
|
+
}
|
|
18711
|
+
close() {
|
|
18712
|
+
if (!this.#closed) {
|
|
18713
|
+
this.#closed = true;
|
|
18714
|
+
this.#rejectAll(new Error("Omp RPC Session closed"));
|
|
18715
|
+
}
|
|
18716
|
+
this.#closePromise ??= this.#stopProcess();
|
|
18717
|
+
return this.#closePromise;
|
|
18718
|
+
}
|
|
18719
|
+
async #stopProcess() {
|
|
18720
|
+
const child = this.#child;
|
|
18721
|
+
if (!child)
|
|
18722
|
+
return;
|
|
18723
|
+
if (child.stdin.writable)
|
|
18724
|
+
child.stdin.end();
|
|
18725
|
+
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
18726
|
+
return;
|
|
18727
|
+
signalProcessTree(child, "SIGTERM");
|
|
18728
|
+
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
18729
|
+
return;
|
|
18730
|
+
signalProcessTree(child, "SIGKILL");
|
|
18731
|
+
if (!await waitForExit(child, this.#options.closeTimeoutMs)) {
|
|
18732
|
+
throw new Error("Omp RPC process tree did not exit within cleanup bounds");
|
|
18733
|
+
}
|
|
18734
|
+
}
|
|
18735
|
+
#push(chunk) {
|
|
18736
|
+
this.#buffer = this.#buffer.length === 0 ? chunk : Buffer.concat([this.#buffer, chunk]);
|
|
18737
|
+
let newline = this.#buffer.indexOf(10);
|
|
18738
|
+
while (newline >= 0) {
|
|
18739
|
+
const frame = this.#buffer.subarray(0, newline);
|
|
18740
|
+
this.#buffer = this.#buffer.subarray(newline + 1);
|
|
18741
|
+
let parsed;
|
|
18742
|
+
try {
|
|
18743
|
+
parsed = JSON.parse(textDecoder.decode(frame));
|
|
18744
|
+
} catch (error51) {
|
|
18745
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC returned invalid JSONL: ${message2(error51)}`));
|
|
18746
|
+
newline = this.#buffer.indexOf(10);
|
|
18747
|
+
continue;
|
|
18901
18748
|
}
|
|
18902
|
-
let branchEntryIds = null;
|
|
18903
18749
|
try {
|
|
18904
|
-
const
|
|
18905
|
-
|
|
18906
|
-
|
|
18907
|
-
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
if (parsed.length === branchData.messages.length)
|
|
18913
|
-
branchEntryIds = parsed;
|
|
18750
|
+
const decoded = this.#frameDecoder.push(parsed);
|
|
18751
|
+
if (decoded === null) {
|
|
18752
|
+
newline = this.#buffer.indexOf(10);
|
|
18753
|
+
continue;
|
|
18754
|
+
}
|
|
18755
|
+
const value = decoded;
|
|
18756
|
+
if (!isRecord8(value) || typeof value.type !== "string") {
|
|
18757
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid envelope");
|
|
18914
18758
|
}
|
|
18759
|
+
this.#handle(value);
|
|
18915
18760
|
} catch (error51) {
|
|
18916
|
-
|
|
18917
|
-
throw error51;
|
|
18761
|
+
this.#fail(error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC frame handling failed: ${message2(error51)}`));
|
|
18918
18762
|
}
|
|
18919
|
-
|
|
18920
|
-
let parentId = null;
|
|
18921
|
-
const entries = data.messages.map((nativeMessage, index) => {
|
|
18922
|
-
const role = isRecord8(nativeMessage) ? nativeMessage.role : void 0;
|
|
18923
|
-
const branchId = role === "user" ? branchEntryIds?.[userIndex] : void 0;
|
|
18924
|
-
if (branchId)
|
|
18925
|
-
userIndex += 1;
|
|
18926
|
-
const id = branchId ?? (isRecord8(nativeMessage) && nonBlankString(nativeMessage.id) ? nativeMessage.id : `omp-message-${index}`);
|
|
18927
|
-
const entry = { id, parentId, type: "message", message: nativeMessage };
|
|
18928
|
-
parentId = id;
|
|
18929
|
-
return entry;
|
|
18930
|
-
});
|
|
18931
|
-
return { entries, leafId: parentId };
|
|
18932
|
-
} catch (error51) {
|
|
18933
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
18934
|
-
this.#fail(error51);
|
|
18935
|
-
throw error51;
|
|
18763
|
+
newline = this.#buffer.indexOf(10);
|
|
18936
18764
|
}
|
|
18937
18765
|
}
|
|
18938
|
-
|
|
18939
|
-
|
|
18940
|
-
|
|
18766
|
+
/** Latest `available_commands_update` of the running process, if any. */
|
|
18767
|
+
get availableCommands() {
|
|
18768
|
+
return this.#availableCommands;
|
|
18769
|
+
}
|
|
18770
|
+
#handle(value) {
|
|
18771
|
+
if (this.#closed || this.#failed)
|
|
18772
|
+
return;
|
|
18773
|
+
if (value.type === "available_commands_update") {
|
|
18774
|
+
this.#availableCommands = parseOmpAvailableCommands(value.commands);
|
|
18775
|
+
return;
|
|
18941
18776
|
}
|
|
18942
|
-
if (
|
|
18943
|
-
|
|
18777
|
+
if (value.type === "ready") {
|
|
18778
|
+
this.#readyResolve?.();
|
|
18779
|
+
this.#readyResolve = null;
|
|
18780
|
+
return;
|
|
18781
|
+
}
|
|
18782
|
+
if (value.type === "response") {
|
|
18783
|
+
this.#handleResponse(value);
|
|
18784
|
+
return;
|
|
18785
|
+
}
|
|
18786
|
+
if (value.type === "auto_compaction_start" || value.type === "compaction_start") {
|
|
18787
|
+
this.#compactionActive = true;
|
|
18788
|
+
this.#compactionTurn = this.#activeTurn;
|
|
18789
|
+
this.#compactionTimeout ??= setTimeout(() => {
|
|
18790
|
+
this.#compactionTimeout = null;
|
|
18791
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC compaction timed out after ${this.#options.compactionTimeoutMs}ms`));
|
|
18792
|
+
}, this.#options.compactionTimeoutMs);
|
|
18793
|
+
const onEvent = this.#activeTurn?.onEvent ?? this.#manualCompaction?.onEvent;
|
|
18794
|
+
onEvent?.({ type: "compaction.started" });
|
|
18795
|
+
for (const pending of this.#pending.values()) {
|
|
18796
|
+
if (pending.command !== "prompt" && pending.command !== "compact" || !pending.timeout)
|
|
18797
|
+
continue;
|
|
18798
|
+
clearTimeout(pending.timeout);
|
|
18799
|
+
pending.timeout = null;
|
|
18800
|
+
}
|
|
18801
|
+
return;
|
|
18802
|
+
}
|
|
18803
|
+
if (value.type === "auto_compaction_end" || value.type === "compaction_end") {
|
|
18804
|
+
this.#compactionActive = false;
|
|
18805
|
+
if (this.#compactionTimeout)
|
|
18806
|
+
clearTimeout(this.#compactionTimeout);
|
|
18807
|
+
this.#compactionTimeout = null;
|
|
18808
|
+
const compactionTurn = this.#compactionTurn;
|
|
18809
|
+
this.#compactionTurn = null;
|
|
18810
|
+
for (const [id, pending] of this.#pending) {
|
|
18811
|
+
if (pending.command === "prompt" || pending.command === "compact") {
|
|
18812
|
+
this.#armCommandTimeout(id, pending);
|
|
18813
|
+
}
|
|
18814
|
+
}
|
|
18815
|
+
const outcome = value.aborted === true ? "cancelled" : isRecord8(value.result) ? "succeeded" : "failed";
|
|
18816
|
+
const event = {
|
|
18817
|
+
type: "compaction.completed",
|
|
18818
|
+
outcome,
|
|
18819
|
+
...nonBlankString(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
|
|
18820
|
+
};
|
|
18821
|
+
compactionTurn?.onEvent(event);
|
|
18822
|
+
const manual = this.#manualCompaction;
|
|
18823
|
+
this.#manualCompaction = null;
|
|
18824
|
+
manual?.onEvent(event);
|
|
18825
|
+
manual?.resolve({
|
|
18826
|
+
outcome,
|
|
18827
|
+
...event.errorMessage ? { errorMessage: event.errorMessage } : {}
|
|
18828
|
+
});
|
|
18829
|
+
return;
|
|
18830
|
+
}
|
|
18831
|
+
const active = this.#activeTurn;
|
|
18832
|
+
if (this.#handleSubagentFrame(active, value))
|
|
18833
|
+
return;
|
|
18834
|
+
this.#observeUsage(value);
|
|
18835
|
+
if (value.type === "agent_start" && active)
|
|
18836
|
+
active.terminalEnd = false;
|
|
18837
|
+
if ((value.type === "session_settled" || value.type === "agent_start") && active?.cancellation === "accepted") {
|
|
18838
|
+
void this.#confirmCancelledTurn(active);
|
|
18839
|
+
return;
|
|
18840
|
+
}
|
|
18841
|
+
if (!active) {
|
|
18842
|
+
if (value.type === "extension_ui_request" && this.#isBlockingInteraction(value)) {
|
|
18843
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC requested blocking Extension UI outside an active Turn"));
|
|
18844
|
+
}
|
|
18845
|
+
return;
|
|
18846
|
+
}
|
|
18847
|
+
if (value.type === "command_output") {
|
|
18848
|
+
if (active.settlement !== "pending")
|
|
18849
|
+
return;
|
|
18850
|
+
if (typeof value.text !== "string") {
|
|
18851
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned invalid command output");
|
|
18852
|
+
}
|
|
18853
|
+
active.text += value.text;
|
|
18854
|
+
active.onEvent({ type: "text.delta", messageId: active.promptId, delta: value.text });
|
|
18855
|
+
return;
|
|
18856
|
+
}
|
|
18857
|
+
if (value.type === "prompt_result") {
|
|
18858
|
+
if (value.id !== active.promptId || value.agentInvoked !== false)
|
|
18859
|
+
return;
|
|
18860
|
+
if (value.status === "completed" || value.status === "aborted") {
|
|
18861
|
+
this.#settleLocalTurn(active, { cancelled: value.status === "aborted" });
|
|
18862
|
+
} else if (value.status === "error" && isRecord8(value.error) && typeof value.error.message === "string") {
|
|
18863
|
+
this.#settleLocalTurn(active, { cancelled: false, error: value.error.message });
|
|
18864
|
+
} else {
|
|
18865
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid local prompt result");
|
|
18866
|
+
}
|
|
18867
|
+
return;
|
|
18868
|
+
}
|
|
18869
|
+
if (value.type === "extension_ui_request") {
|
|
18870
|
+
this.#startInteraction(active, value);
|
|
18871
|
+
return;
|
|
18872
|
+
}
|
|
18873
|
+
if (value.type === "message_start" && assistantText(value.message) !== null) {
|
|
18874
|
+
this.#startAssistantMessage(active, value.message);
|
|
18875
|
+
return;
|
|
18876
|
+
}
|
|
18877
|
+
if (value.type === "message_update" && isRecord8(value.assistantMessageEvent)) {
|
|
18878
|
+
const event = value.assistantMessageEvent;
|
|
18879
|
+
const eventType = String(event.type ?? "");
|
|
18880
|
+
const isThinking = eventType === "thinking_delta" || eventType === "reasoning_delta" || eventType === "thought_delta" || eventType === "thinking" || eventType === "reasoning";
|
|
18881
|
+
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
18882
|
+
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;
|
|
18883
|
+
if (isThinking && delta !== null && delta.length > 0) {
|
|
18884
|
+
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18885
|
+
active.reasoningMessageOpen = true;
|
|
18886
|
+
active.sawStreamedMessageReasoning = true;
|
|
18887
|
+
active.onEvent({ type: "reasoning.delta", messageId, delta });
|
|
18888
|
+
} else if (isText && delta !== null && delta.length > 0) {
|
|
18889
|
+
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18890
|
+
active.text += delta;
|
|
18891
|
+
active.sawStreamedMessageText = true;
|
|
18892
|
+
active.onEvent({ type: "text.delta", messageId, delta });
|
|
18893
|
+
} else if (event.type === "error") {
|
|
18894
|
+
this.#ensureAssistantMessage(active, value.message);
|
|
18895
|
+
active.failure = assistantFailure(event.error) ?? assistantFailure(value.message) ?? new Error("Omp assistant message failed");
|
|
18896
|
+
}
|
|
18897
|
+
return;
|
|
18898
|
+
}
|
|
18899
|
+
if (value.type === "message_end") {
|
|
18900
|
+
this.#finalizeAssistantMessage(active, value.message);
|
|
18901
|
+
return;
|
|
18902
|
+
}
|
|
18903
|
+
if (value.type === "turn_end") {
|
|
18904
|
+
this.#finalizeAssistantMessage(active, value.message);
|
|
18905
|
+
return;
|
|
18906
|
+
}
|
|
18907
|
+
if (value.type === "tool_execution_start") {
|
|
18908
|
+
this.#startTool(active, value);
|
|
18909
|
+
return;
|
|
18910
|
+
}
|
|
18911
|
+
if (value.type === "tool_execution_update") {
|
|
18912
|
+
this.#updateTool(active, value);
|
|
18913
|
+
return;
|
|
18914
|
+
}
|
|
18915
|
+
if (value.type === "tool_execution_end") {
|
|
18916
|
+
this.#completeTool(active, value);
|
|
18917
|
+
return;
|
|
18918
|
+
}
|
|
18919
|
+
if (value.type === "agent_end" && Array.isArray(value.messages)) {
|
|
18920
|
+
for (let index = value.messages.length - 1; index >= 0; index -= 1) {
|
|
18921
|
+
const message3 = value.messages[index];
|
|
18922
|
+
if (!isRecord8(message3) || message3.role !== "assistant")
|
|
18923
|
+
continue;
|
|
18924
|
+
this.#finalizeAssistantMessage(active, message3);
|
|
18925
|
+
break;
|
|
18926
|
+
}
|
|
18927
|
+
}
|
|
18928
|
+
if (value.type === "agent_end" && value.isTerminal !== false) {
|
|
18929
|
+
active.terminalEnd = true;
|
|
18930
|
+
if (active.cancellation !== "none") {
|
|
18931
|
+
if (active.cancellation === "accepted")
|
|
18932
|
+
void this.#confirmCancelledTurn(active);
|
|
18933
|
+
return;
|
|
18934
|
+
}
|
|
18935
|
+
if (active.settlement !== "pending")
|
|
18936
|
+
return;
|
|
18937
|
+
active.settlement = "confirming";
|
|
18938
|
+
void this.#confirmSettledTurn(active);
|
|
18944
18939
|
}
|
|
18945
|
-
const response = await this.#send("get_subagent_messages", {
|
|
18946
|
-
...input.subagentId ? { subagentId: input.subagentId } : {},
|
|
18947
|
-
...input.sessionFile ? { sessionFile: input.sessionFile } : {},
|
|
18948
|
-
...input.fromByte !== void 0 ? { fromByte: input.fromByte } : {}
|
|
18949
|
-
});
|
|
18950
|
-
return parseSubagentMessages(response);
|
|
18951
18940
|
}
|
|
18952
|
-
|
|
18953
|
-
|
|
18954
|
-
|
|
18941
|
+
/** Every finished assistant message is one model request, with or without an active Turn. */
|
|
18942
|
+
#observeUsage(value) {
|
|
18943
|
+
if (value.type === "message_start") {
|
|
18944
|
+
this.#usageRequestStartedAtMs = null;
|
|
18945
|
+
return;
|
|
18955
18946
|
}
|
|
18956
|
-
if (
|
|
18957
|
-
|
|
18947
|
+
if (value.type === "message_update") {
|
|
18948
|
+
const event = value.assistantMessageEvent;
|
|
18949
|
+
if (this.#usageRequestStartedAtMs === null && isRecord8(event) && typeof event.type === "string" && /^(text|thinking|reasoning|thought|toolcall)_(start|delta)$/u.test(event.type)) {
|
|
18950
|
+
this.#usageRequestStartedAtMs = Date.now();
|
|
18951
|
+
}
|
|
18952
|
+
return;
|
|
18958
18953
|
}
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18954
|
+
if (value.type === "message_end" && isRecord8(value.message)) {
|
|
18955
|
+
if (value.message.role !== "assistant")
|
|
18956
|
+
return;
|
|
18957
|
+
const startedAtMs = this.#usageRequestStartedAtMs;
|
|
18958
|
+
this.#usageRequestStartedAtMs = null;
|
|
18959
|
+
this.#options.onUsage?.({
|
|
18960
|
+
message: value.message,
|
|
18961
|
+
startedAtMs,
|
|
18962
|
+
completedAtMs: Date.now()
|
|
18963
|
+
});
|
|
18968
18964
|
}
|
|
18969
|
-
return result;
|
|
18970
18965
|
}
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
await this.#ensureLatestCacheHitRate();
|
|
18975
|
-
return this.#withLatestCacheHitRate(usage);
|
|
18976
|
-
} catch (error51) {
|
|
18977
|
-
if (!(error51 instanceof OmpRpcUnsupportedCommandError))
|
|
18978
|
-
throw error51;
|
|
18979
|
-
const response = await this.#send("get_state", {});
|
|
18980
|
-
const observedState = parseSessionState(response);
|
|
18981
|
-
if (!this.#state || observedState.sessionId !== this.#state.sessionId || observedState.provider !== this.#state.provider || observedState.modelId !== this.#state.modelId) {
|
|
18982
|
-
throw new Error("Omp RPC Usage fallback does not match the confirmed Session state");
|
|
18983
|
-
}
|
|
18984
|
-
await this.#ensureLatestCacheHitRate();
|
|
18985
|
-
const usage = parseOmpStateContextUsage(response);
|
|
18986
|
-
return usage ? this.#withLatestCacheHitRate(usage) : null;
|
|
18966
|
+
#handleSubagentFrame(active, value) {
|
|
18967
|
+
if (value.type !== "subagent_lifecycle" && value.type !== "subagent_progress" && value.type !== "subagent_event") {
|
|
18968
|
+
return false;
|
|
18987
18969
|
}
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
18991
|
-
|
|
18992
|
-
|
|
18993
|
-
this.#latestCacheHitRatePercent = latestOmpCacheHitRatePercent(await this.getEntries());
|
|
18994
|
-
} catch {
|
|
18995
|
-
this.#latestCacheHitRatePercent = null;
|
|
18970
|
+
const payload = isRecord8(value.payload) ? value.payload : null;
|
|
18971
|
+
const progressPayload = value.type === "subagent_progress" && payload && isRecord8(payload.progress) ? payload.progress : null;
|
|
18972
|
+
const nativeIdValue = progressPayload?.id ?? payload?.id;
|
|
18973
|
+
if (!payload || !nonBlankString(nativeIdValue)) {
|
|
18974
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent frame has no stable ID");
|
|
18996
18975
|
}
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
19000
|
-
|
|
19001
|
-
|
|
19002
|
-
|
|
19003
|
-
|
|
19004
|
-
|
|
19005
|
-
const
|
|
19006
|
-
|
|
19007
|
-
|
|
19008
|
-
|
|
18976
|
+
const nativeSubagentId = nativeIdValue;
|
|
18977
|
+
const callId = nativeSubagentId;
|
|
18978
|
+
const emit = active?.onEvent ?? this.#options.onSubagentEvent;
|
|
18979
|
+
if (value.type === "subagent_event") {
|
|
18980
|
+
emit?.({ type: "subagent.transcript.changed", callId, nativeSubagentId });
|
|
18981
|
+
return true;
|
|
18982
|
+
}
|
|
18983
|
+
if (value.type === "subagent_lifecycle") {
|
|
18984
|
+
const status2 = payload.status;
|
|
18985
|
+
if (status2 === "started") {
|
|
18986
|
+
const description = nonBlankString(payload.description) ? payload.description : nonBlankString(payload.agent) ? `${payload.agent} delegation` : "Subagent delegation";
|
|
18987
|
+
emit?.({
|
|
18988
|
+
type: "subagent.started",
|
|
18989
|
+
callId,
|
|
18990
|
+
nativeSubagentId,
|
|
18991
|
+
description,
|
|
18992
|
+
...nonBlankString(payload.agent) ? { role: payload.agent } : {},
|
|
18993
|
+
...nonBlankString(payload.task) ? { prompt: payload.task } : {},
|
|
18994
|
+
background: payload.detached === true,
|
|
18995
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
18996
|
+
});
|
|
18997
|
+
return true;
|
|
19009
18998
|
}
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
|
|
19015
|
-
|
|
18999
|
+
if (status2 !== "completed" && status2 !== "failed" && status2 !== "aborted") {
|
|
19000
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent lifecycle status is invalid");
|
|
19001
|
+
}
|
|
19002
|
+
emit?.({
|
|
19003
|
+
type: "subagent.completed",
|
|
19004
|
+
callId,
|
|
19005
|
+
nativeSubagentId,
|
|
19006
|
+
isError: status2 !== "completed",
|
|
19007
|
+
...nonBlankString(payload.resultSummary) ? { resultSummary: payload.resultSummary } : {},
|
|
19008
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19009
|
+
});
|
|
19010
|
+
return true;
|
|
19016
19011
|
}
|
|
19017
|
-
|
|
19018
|
-
|
|
19019
|
-
|
|
19020
|
-
sessionFile: this.state.sessionFile,
|
|
19021
|
-
sessionId: this.state.sessionId,
|
|
19022
|
-
expectedCwd
|
|
19023
|
-
});
|
|
19024
|
-
}
|
|
19025
|
-
async getAvailableModels() {
|
|
19026
|
-
try {
|
|
19027
|
-
return parseAvailableModels(await this.#send("get_available_models", {}));
|
|
19028
|
-
} catch (error51) {
|
|
19029
|
-
if (error51 instanceof OmpRpcFaultError)
|
|
19030
|
-
this.#fail(error51);
|
|
19031
|
-
throw error51;
|
|
19012
|
+
const progress = progressPayload;
|
|
19013
|
+
if (!progress || !nonBlankString(progress.id) || progress.id !== nativeSubagentId) {
|
|
19014
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent progress is invalid");
|
|
19032
19015
|
}
|
|
19016
|
+
const status = subagentStatus(progress.status);
|
|
19017
|
+
const recentOutput = Array.isArray(progress.recentOutput) ? progress.recentOutput.filter((item) => typeof item === "string") : [];
|
|
19018
|
+
const resultSummary = recentOutput.at(-1);
|
|
19019
|
+
emit?.({
|
|
19020
|
+
type: "subagent.updated",
|
|
19021
|
+
callId,
|
|
19022
|
+
nativeSubagentId,
|
|
19023
|
+
status,
|
|
19024
|
+
...nonBlankString(progress.description) ? { description: progress.description } : nonBlankString(payload.task) ? { description: payload.task } : {},
|
|
19025
|
+
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
19026
|
+
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19027
|
+
});
|
|
19028
|
+
return true;
|
|
19033
19029
|
}
|
|
19034
|
-
|
|
19035
|
-
return
|
|
19036
|
-
}
|
|
19037
|
-
async selectModel(model2) {
|
|
19038
|
-
await this.#send("set_model", { provider: model2.provider, modelId: model2.id });
|
|
19039
|
-
return this.#refreshState("Model");
|
|
19040
|
-
}
|
|
19041
|
-
async selectThinkingOption(thinkingOptionId) {
|
|
19042
|
-
const level = harnessThinkingOptionIdSchema.parse(thinkingOptionId);
|
|
19043
|
-
await this.#send("set_thinking_level", { level });
|
|
19044
|
-
return this.#refreshState("Thinking");
|
|
19045
|
-
}
|
|
19046
|
-
async #refreshState(operation) {
|
|
19047
|
-
try {
|
|
19048
|
-
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
19049
|
-
return this.#state;
|
|
19050
|
-
} catch (error51) {
|
|
19051
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
19052
|
-
this.#fail(fault);
|
|
19053
|
-
throw fault;
|
|
19054
|
-
}
|
|
19030
|
+
#isBlockingInteraction(value) {
|
|
19031
|
+
return ["select", "confirm", "input", "editor"].includes(String(value.method));
|
|
19055
19032
|
}
|
|
19056
|
-
|
|
19057
|
-
if (!this.#
|
|
19058
|
-
|
|
19033
|
+
#startInteraction(active, value) {
|
|
19034
|
+
if (!this.#isBlockingInteraction(value))
|
|
19035
|
+
return;
|
|
19036
|
+
const requestId = value.id;
|
|
19037
|
+
const method = value.method;
|
|
19038
|
+
const title = value.title;
|
|
19039
|
+
const timeoutMs = value.timeout;
|
|
19040
|
+
if (typeof requestId !== "string" || requestId.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(requestId)) {
|
|
19041
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Interaction request");
|
|
19059
19042
|
}
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
|
|
19072
|
-
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
|
|
19043
|
+
let request;
|
|
19044
|
+
if (method === "select") {
|
|
19045
|
+
if (!Array.isArray(value.options) || value.options.length === 0 || !value.options.every((option) => typeof option === "string" && option.length > 0)) {
|
|
19046
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC select request has invalid options");
|
|
19047
|
+
}
|
|
19048
|
+
let optionDetails;
|
|
19049
|
+
if (value.optionDetails !== void 0) {
|
|
19050
|
+
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"))) {
|
|
19051
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC select option details are invalid");
|
|
19052
|
+
}
|
|
19053
|
+
optionDetails = value.optionDetails.map(({ description }) => description === void 0 ? {} : { description });
|
|
19054
|
+
}
|
|
19055
|
+
request = {
|
|
19056
|
+
requestId,
|
|
19057
|
+
method,
|
|
19058
|
+
title,
|
|
19059
|
+
options: [...value.options],
|
|
19060
|
+
...optionDetails ? { optionDetails } : {},
|
|
19061
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19062
|
+
};
|
|
19063
|
+
} else if (method === "confirm") {
|
|
19064
|
+
if (typeof value.message !== "string") {
|
|
19065
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC confirm request has no message");
|
|
19066
|
+
}
|
|
19067
|
+
request = {
|
|
19068
|
+
requestId,
|
|
19069
|
+
method,
|
|
19070
|
+
title,
|
|
19071
|
+
message: value.message,
|
|
19072
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19073
|
+
};
|
|
19074
|
+
} else if (method === "input") {
|
|
19075
|
+
if (value.placeholder !== void 0 && typeof value.placeholder !== "string") {
|
|
19076
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC input placeholder is invalid");
|
|
19077
|
+
}
|
|
19078
|
+
request = {
|
|
19079
|
+
requestId,
|
|
19080
|
+
method,
|
|
19081
|
+
title,
|
|
19082
|
+
...typeof value.placeholder === "string" ? { placeholder: value.placeholder } : {},
|
|
19083
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19084
|
+
};
|
|
19085
|
+
} else {
|
|
19086
|
+
if (value.prefill !== void 0 && typeof value.prefill !== "string") {
|
|
19087
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC editor prefill is invalid");
|
|
19088
|
+
}
|
|
19089
|
+
request = {
|
|
19090
|
+
requestId,
|
|
19091
|
+
method: "editor",
|
|
19092
|
+
title,
|
|
19093
|
+
...typeof value.prefill === "string" ? { prefill: value.prefill } : {},
|
|
19094
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19091
19095
|
};
|
|
19092
|
-
});
|
|
19093
|
-
try {
|
|
19094
|
-
await this.#send("prompt", { message: text }, promptId);
|
|
19095
|
-
} catch (error51) {
|
|
19096
|
-
this.#rejectActiveTurn(error51 instanceof Error ? error51 : new Error(message2(error51)));
|
|
19097
|
-
}
|
|
19098
|
-
return settled;
|
|
19099
|
-
}
|
|
19100
|
-
respondToInteraction(response) {
|
|
19101
|
-
return this.#resolveInteraction(response, "cancelled" in response ? "cancelled" : "responded");
|
|
19102
|
-
}
|
|
19103
|
-
async #resolveInteraction(response, reason) {
|
|
19104
|
-
const active = this.#activeTurn;
|
|
19105
|
-
const pending = active?.interactions.get(response.requestId);
|
|
19106
|
-
if (!active || !pending || this.#closed || this.#failed) {
|
|
19107
|
-
throw new Error("Omp RPC interaction is not pending");
|
|
19108
19096
|
}
|
|
19109
|
-
|
|
19110
|
-
|
|
19097
|
+
const pending = { request, timeout: null };
|
|
19098
|
+
if (request.timeoutMs !== void 0) {
|
|
19099
|
+
pending.timeout = setTimeout(() => {
|
|
19100
|
+
if (this.#activeTurn !== active || !active.interactions.has(requestId))
|
|
19101
|
+
return;
|
|
19102
|
+
void this.#resolveInteraction({ requestId, cancelled: true }, "expired").catch((error51) => {
|
|
19103
|
+
if (this.#closed || this.#failed)
|
|
19104
|
+
return;
|
|
19105
|
+
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC Interaction timeout handling failed: ${message2(error51)}`));
|
|
19106
|
+
});
|
|
19107
|
+
}, request.timeoutMs);
|
|
19111
19108
|
}
|
|
19112
|
-
|
|
19113
|
-
|
|
19109
|
+
active.interactions.set(requestId, pending);
|
|
19110
|
+
active.onEvent({ type: "interaction.requested", request });
|
|
19111
|
+
}
|
|
19112
|
+
#handleResponse(value) {
|
|
19113
|
+
const id = value.id;
|
|
19114
|
+
if (typeof id !== "string") {
|
|
19115
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response has no id"));
|
|
19116
|
+
return;
|
|
19114
19117
|
}
|
|
19115
|
-
const
|
|
19116
|
-
|
|
19117
|
-
|
|
19118
|
-
|
|
19119
|
-
|
|
19120
|
-
|
|
19121
|
-
|
|
19122
|
-
|
|
19118
|
+
const pending = this.#pending.get(id);
|
|
19119
|
+
const active = this.#activeTurn;
|
|
19120
|
+
if (!pending) {
|
|
19121
|
+
if (active?.promptId === id && value.command === "prompt" && value.success === false) {
|
|
19122
|
+
active.failure = new Error(typeof value.error === "string" ? value.error : "Omp RPC command failed");
|
|
19123
|
+
return;
|
|
19124
|
+
}
|
|
19125
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response id is not pending"));
|
|
19126
|
+
return;
|
|
19123
19127
|
}
|
|
19124
19128
|
if (pending.timeout)
|
|
19125
19129
|
clearTimeout(pending.timeout);
|
|
19126
|
-
|
|
19127
|
-
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
19130
|
+
this.#pending.delete(id);
|
|
19131
|
+
if (value.success === true) {
|
|
19132
|
+
if (pending.command === "prompt" && active?.promptId === id && isRecord8(value.data) && value.data.agentInvoked === false) {
|
|
19133
|
+
this.#settleLocalTurn(active, { cancelled: false });
|
|
19134
|
+
}
|
|
19135
|
+
pending.resolve(value);
|
|
19136
|
+
} else {
|
|
19137
|
+
const error51 = typeof value.error === "string" ? value.error : "Omp RPC command failed";
|
|
19138
|
+
if (value.command === pending.command && error51 === `Unknown command: ${pending.command}`) {
|
|
19139
|
+
pending.reject(new OmpRpcUnsupportedCommandError(pending.command));
|
|
19140
|
+
} else {
|
|
19141
|
+
pending.reject(new Error(error51));
|
|
19142
|
+
}
|
|
19133
19143
|
}
|
|
19134
19144
|
}
|
|
19135
|
-
|
|
19136
|
-
const
|
|
19137
|
-
|
|
19138
|
-
|
|
19145
|
+
#startTool(active, value) {
|
|
19146
|
+
const callId = value.toolCallId;
|
|
19147
|
+
const toolName = value.toolName;
|
|
19148
|
+
const argumentsResult = jsonValueSchema.safeParse(value.args);
|
|
19149
|
+
if (typeof callId !== "string" || callId.length === 0 || typeof toolName !== "string" || toolName.length === 0 || !argumentsResult.success || active.tools.has(callId)) {
|
|
19150
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool start");
|
|
19139
19151
|
}
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
active.
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
if (this.#activeTurn !== active)
|
|
19148
|
-
return;
|
|
19149
|
-
active.cancellation = "accepted";
|
|
19150
|
-
await this.#confirmCancelledTurn(active);
|
|
19151
|
-
}).catch((error51) => {
|
|
19152
|
-
if (this.#activeTurn !== active)
|
|
19153
|
-
throw error51;
|
|
19154
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC Abort failed: ${message2(error51)}`);
|
|
19155
|
-
this.#terminateFailedCancellation(active, fault);
|
|
19156
|
-
throw fault;
|
|
19152
|
+
active.sawTool = true;
|
|
19153
|
+
active.tools.set(callId, toolName);
|
|
19154
|
+
active.onEvent({
|
|
19155
|
+
type: "tool.started",
|
|
19156
|
+
callId,
|
|
19157
|
+
toolName,
|
|
19158
|
+
arguments: argumentsResult.data
|
|
19157
19159
|
});
|
|
19158
|
-
active.abortPromise = aborting;
|
|
19159
|
-
return aborting;
|
|
19160
19160
|
}
|
|
19161
|
-
#
|
|
19162
|
-
|
|
19161
|
+
#updateTool(active, value) {
|
|
19162
|
+
const callId = value.toolCallId;
|
|
19163
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
19164
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19165
|
+
}
|
|
19166
|
+
if (!active.tools.has(callId))
|
|
19163
19167
|
return;
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
this.#fail(fault);
|
|
19168
|
-
void this.close().catch(() => void 0);
|
|
19169
|
-
}
|
|
19170
|
-
close() {
|
|
19171
|
-
if (!this.#closed) {
|
|
19172
|
-
this.#closed = true;
|
|
19173
|
-
this.#rejectAll(new Error("Omp RPC Session closed"));
|
|
19168
|
+
const outputResult = jsonValueSchema.safeParse(value.partialResult ?? null);
|
|
19169
|
+
if (!outputResult.success) {
|
|
19170
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool update");
|
|
19174
19171
|
}
|
|
19175
|
-
|
|
19176
|
-
return this.#closePromise;
|
|
19172
|
+
active.onEvent({ type: "tool.updated", callId, output: outputResult.data });
|
|
19177
19173
|
}
|
|
19178
|
-
|
|
19179
|
-
const
|
|
19180
|
-
|
|
19181
|
-
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
|
|
19185
|
-
|
|
19186
|
-
signalProcessTree(child, "SIGTERM");
|
|
19187
|
-
if (await waitForExit(child, this.#options.closeTimeoutMs))
|
|
19174
|
+
#completeTool(active, value) {
|
|
19175
|
+
const callId = value.toolCallId;
|
|
19176
|
+
const toolName = value.toolName;
|
|
19177
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
19178
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19179
|
+
}
|
|
19180
|
+
const expectedName = active.tools.get(callId);
|
|
19181
|
+
if (expectedName === void 0)
|
|
19188
19182
|
return;
|
|
19189
|
-
|
|
19190
|
-
if (
|
|
19191
|
-
throw new
|
|
19183
|
+
const result = jsonValueSchema.safeParse(value.result);
|
|
19184
|
+
if (typeof toolName !== "string" || expectedName !== toolName || value.isError !== void 0 && typeof value.isError !== "boolean" || !result.success) {
|
|
19185
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid Tool end");
|
|
19192
19186
|
}
|
|
19187
|
+
active.tools.delete(callId);
|
|
19188
|
+
active.onEvent({
|
|
19189
|
+
type: "tool.completed",
|
|
19190
|
+
callId,
|
|
19191
|
+
toolName,
|
|
19192
|
+
result: result.data,
|
|
19193
|
+
isError: value.isError === true
|
|
19194
|
+
});
|
|
19193
19195
|
}
|
|
19194
|
-
#
|
|
19195
|
-
this.#
|
|
19196
|
-
|
|
19197
|
-
|
|
19198
|
-
|
|
19199
|
-
|
|
19200
|
-
|
|
19201
|
-
|
|
19202
|
-
|
|
19203
|
-
|
|
19204
|
-
|
|
19205
|
-
|
|
19206
|
-
|
|
19196
|
+
async #confirmCancelledTurn(active) {
|
|
19197
|
+
if (this.#activeTurn !== active || active.cancellation !== "accepted" || active.settlement === "confirming" || active.cancellationChecking)
|
|
19198
|
+
return;
|
|
19199
|
+
active.cancellationChecking = true;
|
|
19200
|
+
if (active.cancellationRecheck)
|
|
19201
|
+
clearTimeout(active.cancellationRecheck);
|
|
19202
|
+
active.cancellationRecheck = null;
|
|
19203
|
+
try {
|
|
19204
|
+
let response = await this.#send("get_state", {});
|
|
19205
|
+
if (this.#activeTurn !== active)
|
|
19206
|
+
return;
|
|
19207
|
+
if (parseSessionStreaming(response)) {
|
|
19208
|
+
await this.#send("abort", {});
|
|
19209
|
+
if (this.#activeTurn !== active)
|
|
19210
|
+
return;
|
|
19211
|
+
response = await this.#send("get_state", {});
|
|
19207
19212
|
}
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
19211
|
-
|
|
19212
|
-
|
|
19213
|
+
let state = parseSessionState(response);
|
|
19214
|
+
if (this.#activeTurn !== active || active.cancellation !== "accepted")
|
|
19215
|
+
return;
|
|
19216
|
+
const data = sessionStateData(response);
|
|
19217
|
+
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) {
|
|
19218
|
+
await this.verifySessionCwd(this.#options.cwd);
|
|
19219
|
+
if (this.#activeTurn !== active)
|
|
19220
|
+
return;
|
|
19221
|
+
active.cancellationReloaded = true;
|
|
19222
|
+
const reset = await this.#send("new_session", {});
|
|
19223
|
+
if (this.#activeTurn !== active)
|
|
19224
|
+
return;
|
|
19225
|
+
if (!isRecord8(reset.data) || reset.data.cancelled !== false) {
|
|
19226
|
+
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reset was refused");
|
|
19227
|
+
}
|
|
19228
|
+
const reloaded = await this.#send("switch_session", { sessionPath: state.sessionFile });
|
|
19229
|
+
if (this.#activeTurn !== active)
|
|
19230
|
+
return;
|
|
19231
|
+
if (!isRecord8(reloaded.data) || reloaded.data.cancelled !== false) {
|
|
19232
|
+
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reload was refused");
|
|
19233
|
+
}
|
|
19234
|
+
const previous = state;
|
|
19235
|
+
response = await this.#send("get_state", {});
|
|
19236
|
+
state = parseSessionState(response);
|
|
19237
|
+
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile) {
|
|
19238
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity");
|
|
19239
|
+
}
|
|
19240
|
+
if (state.provider !== previous.provider || state.modelId !== previous.modelId) {
|
|
19241
|
+
if (!previous.provider || !previous.modelId) {
|
|
19242
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session has no restorable Model");
|
|
19243
|
+
}
|
|
19244
|
+
await this.#send("set_model", { provider: previous.provider, modelId: previous.modelId });
|
|
19213
19245
|
}
|
|
19214
|
-
|
|
19215
|
-
|
|
19216
|
-
|
|
19246
|
+
if (previous.thinkingLevel && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19247
|
+
await this.#send("set_thinking_level", { level: previous.thinkingLevel });
|
|
19248
|
+
}
|
|
19249
|
+
response = await this.#send("get_state", {});
|
|
19250
|
+
state = parseSessionState(response);
|
|
19251
|
+
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile || state.provider !== previous.provider || state.modelId !== previous.modelId || previous.thinkingLevel !== null && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19252
|
+
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity or configuration");
|
|
19217
19253
|
}
|
|
19218
|
-
this.#handle(value);
|
|
19219
|
-
} catch (error51) {
|
|
19220
|
-
this.#fail(error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC frame handling failed: ${message2(error51)}`));
|
|
19221
19254
|
}
|
|
19222
|
-
|
|
19255
|
+
if (!cancellationSettled(response, active.terminalEnd)) {
|
|
19256
|
+
active.settlement = "pending";
|
|
19257
|
+
active.cancellationRecheck = setTimeout(() => {
|
|
19258
|
+
active.cancellationRecheck = null;
|
|
19259
|
+
void this.#confirmCancelledTurn(active);
|
|
19260
|
+
}, 250);
|
|
19261
|
+
return;
|
|
19262
|
+
}
|
|
19263
|
+
this.#state = state;
|
|
19264
|
+
active.settlement = "confirmed";
|
|
19265
|
+
this.#finishSettledTurn(active);
|
|
19266
|
+
} catch (error51) {
|
|
19267
|
+
if (this.#activeTurn !== active)
|
|
19268
|
+
return;
|
|
19269
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC cancelled Turn state could not be confirmed: ${message2(error51)}`);
|
|
19270
|
+
this.#terminateFailedCancellation(active, fault);
|
|
19271
|
+
} finally {
|
|
19272
|
+
active.cancellationChecking = false;
|
|
19223
19273
|
}
|
|
19224
19274
|
}
|
|
19225
|
-
|
|
19226
|
-
|
|
19227
|
-
return this.#availableCommands;
|
|
19228
|
-
}
|
|
19229
|
-
#handle(value) {
|
|
19230
|
-
if (this.#closed || this.#failed)
|
|
19231
|
-
return;
|
|
19232
|
-
if (value.type === "available_commands_update") {
|
|
19233
|
-
this.#availableCommands = parseOmpAvailableCommands(value.commands);
|
|
19234
|
-
return;
|
|
19235
|
-
}
|
|
19236
|
-
if (value.type === "ready") {
|
|
19237
|
-
this.#readyResolve?.();
|
|
19238
|
-
this.#readyResolve = null;
|
|
19239
|
-
return;
|
|
19240
|
-
}
|
|
19241
|
-
if (value.type === "response") {
|
|
19242
|
-
this.#handleResponse(value);
|
|
19243
|
-
return;
|
|
19244
|
-
}
|
|
19245
|
-
if (value.type === "auto_compaction_start" || value.type === "compaction_start") {
|
|
19246
|
-
this.#compactionActive = true;
|
|
19247
|
-
this.#compactionTurn = this.#activeTurn;
|
|
19248
|
-
this.#compactionTimeout ??= setTimeout(() => {
|
|
19249
|
-
this.#compactionTimeout = null;
|
|
19250
|
-
this.#fail(new OmpRpcFaultError("protocolError", `Omp RPC compaction timed out after ${this.#options.compactionTimeoutMs}ms`));
|
|
19251
|
-
}, this.#options.compactionTimeoutMs);
|
|
19252
|
-
const onEvent = this.#activeTurn?.onEvent ?? this.#manualCompaction?.onEvent;
|
|
19253
|
-
onEvent?.({ type: "compaction.started" });
|
|
19254
|
-
for (const pending of this.#pending.values()) {
|
|
19255
|
-
if (pending.command !== "prompt" && pending.command !== "compact" || !pending.timeout)
|
|
19256
|
-
continue;
|
|
19257
|
-
clearTimeout(pending.timeout);
|
|
19258
|
-
pending.timeout = null;
|
|
19259
|
-
}
|
|
19275
|
+
#settleLocalTurn(active, result) {
|
|
19276
|
+
if (this.#activeTurn !== active || active.settlement !== "pending")
|
|
19260
19277
|
return;
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
|
|
19267
|
-
const
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
|
|
19278
|
+
active.localResult = result;
|
|
19279
|
+
active.settlement = "confirming";
|
|
19280
|
+
void this.#confirmSettledTurn(active);
|
|
19281
|
+
}
|
|
19282
|
+
async #confirmSettledTurn(active) {
|
|
19283
|
+
try {
|
|
19284
|
+
const response = await this.#send("get_state", {});
|
|
19285
|
+
const state = parseSessionState(response);
|
|
19286
|
+
if (this.#activeTurn !== active)
|
|
19287
|
+
return;
|
|
19288
|
+
if (active.cancellation !== "none") {
|
|
19289
|
+
active.settlement = "pending";
|
|
19290
|
+
if (active.cancellation === "accepted")
|
|
19291
|
+
void this.#confirmCancelledTurn(active);
|
|
19292
|
+
return;
|
|
19273
19293
|
}
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
type: "compaction.completed",
|
|
19277
|
-
outcome,
|
|
19278
|
-
...nonBlankString(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
|
|
19279
|
-
};
|
|
19280
|
-
compactionTurn?.onEvent(event);
|
|
19281
|
-
const manual = this.#manualCompaction;
|
|
19282
|
-
this.#manualCompaction = null;
|
|
19283
|
-
manual?.onEvent(event);
|
|
19284
|
-
manual?.resolve({
|
|
19285
|
-
outcome,
|
|
19286
|
-
...event.errorMessage ? { errorMessage: event.errorMessage } : {}
|
|
19287
|
-
});
|
|
19288
|
-
return;
|
|
19289
|
-
}
|
|
19290
|
-
const active = this.#activeTurn;
|
|
19291
|
-
if (this.#handleSubagentFrame(active, value))
|
|
19292
|
-
return;
|
|
19293
|
-
this.#observeUsage(value);
|
|
19294
|
-
if (value.type === "agent_start" && active)
|
|
19295
|
-
active.terminalEnd = false;
|
|
19296
|
-
if ((value.type === "session_settled" || value.type === "agent_start") && active?.cancellation === "accepted") {
|
|
19297
|
-
void this.#confirmCancelledTurn(active);
|
|
19298
|
-
return;
|
|
19299
|
-
}
|
|
19300
|
-
if (!active) {
|
|
19301
|
-
if (value.type === "extension_ui_request" && this.#isBlockingInteraction(value)) {
|
|
19302
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC requested blocking Extension UI outside an active Turn"));
|
|
19294
|
+
if (parseSessionStreaming(response)) {
|
|
19295
|
+
throw new OmpRpcFaultError("protocolError", "Omp RPC completed Turn state is still Streaming");
|
|
19303
19296
|
}
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19297
|
+
this.#state = state;
|
|
19298
|
+
active.settlement = "confirmed";
|
|
19299
|
+
this.#finishSettledTurn(active);
|
|
19300
|
+
} catch (error51) {
|
|
19301
|
+
if (this.#activeTurn !== active)
|
|
19308
19302
|
return;
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
}
|
|
19312
|
-
active.text += value.text;
|
|
19313
|
-
active.onEvent({ type: "text.delta", messageId: active.promptId, delta: value.text });
|
|
19314
|
-
return;
|
|
19303
|
+
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC stable Turn state could not be confirmed: ${message2(error51)}`);
|
|
19304
|
+
this.#fail(fault);
|
|
19315
19305
|
}
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
if (value.status === "completed" || value.status === "aborted") {
|
|
19320
|
-
this.#settleLocalTurn(active, { cancelled: value.status === "aborted" });
|
|
19321
|
-
} else if (value.status === "error" && isRecord8(value.error) && typeof value.error.message === "string") {
|
|
19322
|
-
this.#settleLocalTurn(active, { cancelled: false, error: value.error.message });
|
|
19323
|
-
} else {
|
|
19324
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid local prompt result");
|
|
19325
|
-
}
|
|
19306
|
+
}
|
|
19307
|
+
#finishSettledTurn(active) {
|
|
19308
|
+
if (this.#activeTurn !== active || active.settlement !== "confirmed" || active.cancellation === "requesting") {
|
|
19326
19309
|
return;
|
|
19327
19310
|
}
|
|
19328
|
-
if (
|
|
19329
|
-
|
|
19311
|
+
if (active.cancellationTimeout)
|
|
19312
|
+
clearTimeout(active.cancellationTimeout);
|
|
19313
|
+
active.cancellationTimeout = null;
|
|
19314
|
+
if (active.cancellationRecheck)
|
|
19315
|
+
clearTimeout(active.cancellationRecheck);
|
|
19316
|
+
active.cancellationRecheck = null;
|
|
19317
|
+
this.#closeInteractions(active, active.cancellation === "accepted" ? "cancelled" : "superseded");
|
|
19318
|
+
if (active.tools.size > 0) {
|
|
19319
|
+
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC settled with active Tool executions"));
|
|
19330
19320
|
return;
|
|
19331
19321
|
}
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19322
|
+
this.#activeTurn = null;
|
|
19323
|
+
if (active.localResult) {
|
|
19324
|
+
active.resolve({
|
|
19325
|
+
text: active.text,
|
|
19326
|
+
agentInvoked: false,
|
|
19327
|
+
...active.localResult,
|
|
19328
|
+
cancelled: active.localResult.cancelled || active.cancellation === "accepted"
|
|
19329
|
+
});
|
|
19330
|
+
} else if (active.cancellation === "accepted") {
|
|
19331
|
+
active.resolve({ text: active.text, cancelled: true, agentInvoked: true });
|
|
19332
|
+
} else if (active.failure) {
|
|
19333
|
+
active.reject(active.failure);
|
|
19334
|
+
} else if (active.text.trim().length === 0 && !active.sawTool) {
|
|
19335
|
+
active.reject(new Error("Omp RPC settled without displayable output"));
|
|
19336
|
+
} else {
|
|
19337
|
+
active.resolve({ text: active.text, cancelled: false, agentInvoked: true });
|
|
19335
19338
|
}
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
19341
|
-
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;
|
|
19342
|
-
if (isThinking && delta !== null && delta.length > 0) {
|
|
19343
|
-
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
19344
|
-
active.reasoningMessageOpen = true;
|
|
19345
|
-
active.sawStreamedMessageReasoning = true;
|
|
19346
|
-
active.onEvent({ type: "reasoning.delta", messageId, delta });
|
|
19347
|
-
} else if (isText && delta !== null && delta.length > 0) {
|
|
19348
|
-
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
19349
|
-
active.text += delta;
|
|
19350
|
-
active.sawStreamedMessageText = true;
|
|
19351
|
-
active.onEvent({ type: "text.delta", messageId, delta });
|
|
19352
|
-
} else if (event.type === "error") {
|
|
19353
|
-
this.#ensureAssistantMessage(active, value.message);
|
|
19354
|
-
active.failure = assistantFailure(event.error) ?? assistantFailure(value.message) ?? new Error("Omp assistant message failed");
|
|
19355
|
-
}
|
|
19356
|
-
return;
|
|
19339
|
+
}
|
|
19340
|
+
#startAssistantMessage(active, value) {
|
|
19341
|
+
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19342
|
+
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19357
19343
|
}
|
|
19358
|
-
|
|
19359
|
-
|
|
19344
|
+
const messageId = assistantMessageId(value) ?? randomUUID();
|
|
19345
|
+
active.assistantMessageId = messageId;
|
|
19346
|
+
active.sawStreamedMessageText = false;
|
|
19347
|
+
active.sawStreamedMessageReasoning = false;
|
|
19348
|
+
active.reasoningMessageOpen = false;
|
|
19349
|
+
return messageId;
|
|
19350
|
+
}
|
|
19351
|
+
#ensureAssistantMessage(active, value) {
|
|
19352
|
+
return active.assistantMessageId ?? this.#startAssistantMessage(active, value);
|
|
19353
|
+
}
|
|
19354
|
+
#finalizeAssistantMessage(active, value) {
|
|
19355
|
+
const finalText = assistantText(value);
|
|
19356
|
+
const finalReasoning = assistantReasoning(value);
|
|
19357
|
+
const failure = assistantFailure(value);
|
|
19358
|
+
const cacheHitRatePercent = optionalOmpCacheHitRatePercent(value);
|
|
19359
|
+
if (finalText === null || finalReasoning === null || failure === void 0)
|
|
19360
19360
|
return;
|
|
19361
|
-
|
|
19362
|
-
if (value.type === "turn_end") {
|
|
19363
|
-
this.#finalizeAssistantMessage(active, value.message);
|
|
19361
|
+
if (active.assistantMessageId === null && finalText === active.lastFinalizedMessageText && finalReasoning === active.lastFinalizedMessageReasoning && !active.sawStreamedMessageText && !active.sawStreamedMessageReasoning) {
|
|
19364
19362
|
return;
|
|
19365
19363
|
}
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
19364
|
+
active.failure = failure;
|
|
19365
|
+
this.#latestCacheHitRatePercent = cacheHitRatePercent;
|
|
19366
|
+
const messageId = this.#ensureAssistantMessage(active, value);
|
|
19367
|
+
if (!active.sawStreamedMessageReasoning && finalReasoning.length > 0) {
|
|
19368
|
+
active.reasoningMessageOpen = true;
|
|
19369
|
+
active.onEvent({ type: "reasoning.delta", messageId, delta: finalReasoning });
|
|
19369
19370
|
}
|
|
19370
|
-
if (
|
|
19371
|
-
|
|
19372
|
-
return;
|
|
19371
|
+
if (active.reasoningMessageOpen && active.failure === null) {
|
|
19372
|
+
active.onEvent({ type: "reasoning.completed", messageId });
|
|
19373
19373
|
}
|
|
19374
|
-
if (
|
|
19375
|
-
|
|
19376
|
-
|
|
19374
|
+
if (!active.sawStreamedMessageText && finalText.length > 0) {
|
|
19375
|
+
active.text += finalText;
|
|
19376
|
+
active.onEvent({ type: "text.delta", messageId, delta: finalText });
|
|
19377
19377
|
}
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
|
|
19385
|
-
|
|
19378
|
+
active.assistantMessageId = null;
|
|
19379
|
+
active.sawStreamedMessageText = false;
|
|
19380
|
+
active.sawStreamedMessageReasoning = false;
|
|
19381
|
+
active.reasoningMessageOpen = false;
|
|
19382
|
+
active.lastFinalizedMessageText = finalText;
|
|
19383
|
+
active.lastFinalizedMessageReasoning = finalReasoning;
|
|
19384
|
+
active.onEvent({ type: "message.completed", messageId });
|
|
19385
|
+
}
|
|
19386
|
+
#write(value) {
|
|
19387
|
+
const child = this.#child;
|
|
19388
|
+
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19389
|
+
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
19386
19390
|
}
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
|
|
19391
|
-
|
|
19392
|
-
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
|
|
19396
|
-
|
|
19397
|
-
void this.#confirmSettledTurn(active);
|
|
19391
|
+
return new Promise((resolve, reject) => {
|
|
19392
|
+
const frame = Buffer.from(`${JSON.stringify(value)}
|
|
19393
|
+
`, "utf8");
|
|
19394
|
+
child.stdin.write(frame, (error51) => error51 ? reject(error51) : resolve());
|
|
19395
|
+
});
|
|
19396
|
+
}
|
|
19397
|
+
#send(type, payload, id = `codexhost-${randomUUID()}`) {
|
|
19398
|
+
const child = this.#child;
|
|
19399
|
+
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19400
|
+
return Promise.reject(new Error("Omp RPC stdin is unavailable"));
|
|
19398
19401
|
}
|
|
19402
|
+
return new Promise((resolve, reject) => {
|
|
19403
|
+
const pending = {
|
|
19404
|
+
command: type,
|
|
19405
|
+
resolve,
|
|
19406
|
+
reject,
|
|
19407
|
+
timeout: null
|
|
19408
|
+
};
|
|
19409
|
+
this.#pending.set(id, pending);
|
|
19410
|
+
this.#armCommandTimeout(id, pending);
|
|
19411
|
+
const frame = Buffer.from(`${JSON.stringify({ id, type, ...payload })}
|
|
19412
|
+
`, "utf8");
|
|
19413
|
+
child.stdin.write(frame, (error51) => {
|
|
19414
|
+
if (error51) {
|
|
19415
|
+
if (pending.timeout)
|
|
19416
|
+
clearTimeout(pending.timeout);
|
|
19417
|
+
this.#pending.delete(id);
|
|
19418
|
+
reject(error51);
|
|
19419
|
+
}
|
|
19420
|
+
});
|
|
19421
|
+
});
|
|
19399
19422
|
}
|
|
19400
|
-
|
|
19401
|
-
|
|
19402
|
-
if (value.type === "message_start") {
|
|
19403
|
-
this.#usageRequestStartedAtMs = null;
|
|
19423
|
+
#armCommandTimeout(id, pending) {
|
|
19424
|
+
if (pending.timeout || this.#pending.get(id) !== pending || (pending.command === "prompt" || pending.command === "compact") && this.#compactionActive) {
|
|
19404
19425
|
return;
|
|
19405
19426
|
}
|
|
19406
|
-
|
|
19407
|
-
|
|
19408
|
-
|
|
19409
|
-
|
|
19427
|
+
pending.timeout = setTimeout(() => {
|
|
19428
|
+
if (this.#pending.get(id) !== pending)
|
|
19429
|
+
return;
|
|
19430
|
+
pending.timeout = null;
|
|
19431
|
+
const error51 = new Error(`Omp RPC '${pending.command}' command timed out`);
|
|
19432
|
+
if (pending.command !== "prompt") {
|
|
19433
|
+
this.#pending.delete(id);
|
|
19434
|
+
pending.reject(error51);
|
|
19435
|
+
return;
|
|
19410
19436
|
}
|
|
19437
|
+
const fault = new OmpRpcFaultError("protocolError", error51.message);
|
|
19438
|
+
void this.#terminateTimedOutPrompt(fault);
|
|
19439
|
+
}, this.#options.commandTimeoutMs);
|
|
19440
|
+
}
|
|
19441
|
+
async #terminateTimedOutPrompt(fault) {
|
|
19442
|
+
if (this.#closed || this.#failed)
|
|
19411
19443
|
return;
|
|
19444
|
+
this.#failed = true;
|
|
19445
|
+
this.#closed = true;
|
|
19446
|
+
for (const pending of this.#pending.values()) {
|
|
19447
|
+
if (pending.timeout)
|
|
19448
|
+
clearTimeout(pending.timeout);
|
|
19449
|
+
pending.timeout = null;
|
|
19412
19450
|
}
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19418
|
-
this.#options.onUsage?.({
|
|
19419
|
-
message: value.message,
|
|
19420
|
-
startedAtMs,
|
|
19421
|
-
completedAtMs: Date.now()
|
|
19422
|
-
});
|
|
19451
|
+
let finalFault = fault;
|
|
19452
|
+
try {
|
|
19453
|
+
await this.close();
|
|
19454
|
+
} catch (error51) {
|
|
19455
|
+
finalFault = new OmpRpcFaultError("processExited", `Omp RPC timed-out Prompt cleanup failed: ${message2(error51)}`);
|
|
19423
19456
|
}
|
|
19457
|
+
this.#rejectAll(finalFault);
|
|
19458
|
+
this.#options.onFault?.(finalFault);
|
|
19424
19459
|
}
|
|
19425
|
-
#
|
|
19426
|
-
|
|
19427
|
-
|
|
19428
|
-
|
|
19429
|
-
|
|
19430
|
-
|
|
19431
|
-
const nativeIdValue = progressPayload?.id ?? payload?.id;
|
|
19432
|
-
if (!payload || !nonBlankString(nativeIdValue)) {
|
|
19433
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent frame has no stable ID");
|
|
19460
|
+
#closeInteractions(active, reason) {
|
|
19461
|
+
for (const [requestId, pending] of active.interactions) {
|
|
19462
|
+
active.interactions.delete(requestId);
|
|
19463
|
+
if (pending.timeout)
|
|
19464
|
+
clearTimeout(pending.timeout);
|
|
19465
|
+
active.onEvent({ type: "interaction.closed", requestId, reason });
|
|
19434
19466
|
}
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
const
|
|
19438
|
-
if (
|
|
19439
|
-
|
|
19440
|
-
|
|
19467
|
+
}
|
|
19468
|
+
#rejectActiveTurn(error51) {
|
|
19469
|
+
const active = this.#activeTurn;
|
|
19470
|
+
if (!active)
|
|
19471
|
+
return;
|
|
19472
|
+
if (active.cancellationTimeout)
|
|
19473
|
+
clearTimeout(active.cancellationTimeout);
|
|
19474
|
+
if (active.cancellationRecheck)
|
|
19475
|
+
clearTimeout(active.cancellationRecheck);
|
|
19476
|
+
this.#closeInteractions(active, "cancelled");
|
|
19477
|
+
this.#activeTurn = null;
|
|
19478
|
+
active.reject(error51);
|
|
19479
|
+
}
|
|
19480
|
+
#rejectAll(error51) {
|
|
19481
|
+
if (this.#compactionTimeout)
|
|
19482
|
+
clearTimeout(this.#compactionTimeout);
|
|
19483
|
+
this.#compactionTimeout = null;
|
|
19484
|
+
for (const pending of this.#pending.values()) {
|
|
19485
|
+
if (pending.timeout)
|
|
19486
|
+
clearTimeout(pending.timeout);
|
|
19487
|
+
pending.reject(error51);
|
|
19441
19488
|
}
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
|
|
19446
|
-
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
|
|
19489
|
+
this.#pending.clear();
|
|
19490
|
+
const manual = this.#manualCompaction;
|
|
19491
|
+
this.#manualCompaction = null;
|
|
19492
|
+
manual?.reject(error51);
|
|
19493
|
+
this.#rejectActiveTurn(error51);
|
|
19494
|
+
}
|
|
19495
|
+
#fail(error51) {
|
|
19496
|
+
if (this.#closed || this.#failed)
|
|
19497
|
+
return;
|
|
19498
|
+
this.#failed = true;
|
|
19499
|
+
this.#startupFaultResolve?.(error51);
|
|
19500
|
+
this.#startupFaultResolve = null;
|
|
19501
|
+
this.#rejectAll(error51);
|
|
19502
|
+
this.#options.onFault?.(error51);
|
|
19503
|
+
}
|
|
19504
|
+
};
|
|
19505
|
+
|
|
19506
|
+
// dist/omp-model-list.js
|
|
19507
|
+
var OMP_MODEL_LIST_TIMEOUT_MS = 15e3;
|
|
19508
|
+
var OMP_MODEL_LIST_OUTPUT_LIMIT = 4 * 1024 * 1024;
|
|
19509
|
+
function listOmpModels(input) {
|
|
19510
|
+
const environment = withNodeRuntimeOnPath({
|
|
19511
|
+
...process.env,
|
|
19512
|
+
...input.environment,
|
|
19513
|
+
OMP_SKIP_VERSION_CHECK: "1",
|
|
19514
|
+
OMP_TELEMETRY: "0"
|
|
19515
|
+
});
|
|
19516
|
+
const executable = resolveOmpExecutable({
|
|
19517
|
+
...input.command ? { command: input.command } : {},
|
|
19518
|
+
environment
|
|
19519
|
+
});
|
|
19520
|
+
const invocation = commandInvocation(executable, ["models", "--json"], environment);
|
|
19521
|
+
return new Promise((resolve) => {
|
|
19522
|
+
if (input.signal?.aborted)
|
|
19523
|
+
return resolve({ kind: "unanswered" });
|
|
19524
|
+
const child = spawn2(invocation.command, invocation.arguments, {
|
|
19525
|
+
cwd: input.cwd,
|
|
19526
|
+
env: environment,
|
|
19527
|
+
// A process group lets a stop reach OMP and its descendants, not only a launcher shim.
|
|
19528
|
+
detached: process.platform !== "win32",
|
|
19529
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
19530
|
+
windowsHide: true,
|
|
19531
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
19532
|
+
});
|
|
19533
|
+
let settled = false;
|
|
19534
|
+
let stdout = "";
|
|
19535
|
+
const finish = (result, stop = false) => {
|
|
19536
|
+
if (settled)
|
|
19537
|
+
return;
|
|
19538
|
+
settled = true;
|
|
19539
|
+
clearTimeout(timer);
|
|
19540
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
19541
|
+
child.stdout.removeAllListeners("data");
|
|
19542
|
+
if (stop) {
|
|
19543
|
+
child.stdout.destroy();
|
|
19544
|
+
try {
|
|
19545
|
+
signalProcessTree(child, "SIGKILL");
|
|
19546
|
+
} catch {
|
|
19547
|
+
}
|
|
19460
19548
|
}
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
|
|
19469
|
-
|
|
19470
|
-
}
|
|
19471
|
-
const progress = progressPayload;
|
|
19472
|
-
if (!progress || !nonBlankString(progress.id) || progress.id !== nativeSubagentId) {
|
|
19473
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent progress is invalid");
|
|
19474
|
-
}
|
|
19475
|
-
const status = subagentStatus(progress.status);
|
|
19476
|
-
const recentOutput = Array.isArray(progress.recentOutput) ? progress.recentOutput.filter((item) => typeof item === "string") : [];
|
|
19477
|
-
const resultSummary = recentOutput.at(-1);
|
|
19478
|
-
emit?.({
|
|
19479
|
-
type: "subagent.updated",
|
|
19480
|
-
callId,
|
|
19481
|
-
nativeSubagentId,
|
|
19482
|
-
status,
|
|
19483
|
-
...nonBlankString(progress.description) ? { description: progress.description } : nonBlankString(payload.task) ? { description: payload.task } : {},
|
|
19484
|
-
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
19485
|
-
...typeof payload.sessionFile === "string" ? { sessionFile: payload.sessionFile } : {}
|
|
19549
|
+
resolve(result);
|
|
19550
|
+
};
|
|
19551
|
+
const onAbort = () => finish({ kind: "unanswered" }, true);
|
|
19552
|
+
input.signal?.addEventListener("abort", onAbort, { once: true });
|
|
19553
|
+
const timer = setTimeout(() => finish({ kind: "timedOut" }, true), input.timeoutMs ?? OMP_MODEL_LIST_TIMEOUT_MS);
|
|
19554
|
+
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
19555
|
+
stdout += chunk;
|
|
19556
|
+
if (stdout.length > OMP_MODEL_LIST_OUTPUT_LIMIT)
|
|
19557
|
+
finish({ kind: "unanswered" }, true);
|
|
19486
19558
|
});
|
|
19487
|
-
|
|
19559
|
+
child.once("error", (error51) => {
|
|
19560
|
+
finish(error51.code === "ENOENT" ? { kind: "notInstalled", message: "Oh My Pi (omp) is not installed" } : { kind: "unanswered" });
|
|
19561
|
+
});
|
|
19562
|
+
child.once("close", (code) => {
|
|
19563
|
+
if (code !== 0)
|
|
19564
|
+
return finish({ kind: "unanswered" });
|
|
19565
|
+
const models = parseOmpModelList(stdout);
|
|
19566
|
+
finish(models ? { kind: "models", models } : { kind: "unanswered" });
|
|
19567
|
+
});
|
|
19568
|
+
});
|
|
19569
|
+
}
|
|
19570
|
+
function parseOmpModelList(output) {
|
|
19571
|
+
let parsed;
|
|
19572
|
+
try {
|
|
19573
|
+
parsed = JSON.parse(output);
|
|
19574
|
+
} catch {
|
|
19575
|
+
return null;
|
|
19488
19576
|
}
|
|
19489
|
-
|
|
19490
|
-
return
|
|
19577
|
+
if (!isRecord9(parsed) || !Array.isArray(parsed.models))
|
|
19578
|
+
return null;
|
|
19579
|
+
const models = [];
|
|
19580
|
+
for (const model2 of parsed.models) {
|
|
19581
|
+
if (!isRecord9(model2) || !nonBlankString2(model2.provider) || !nonBlankString2(model2.id) || typeof model2.reasoning !== "boolean") {
|
|
19582
|
+
return null;
|
|
19583
|
+
}
|
|
19584
|
+
models.push({ provider: model2.provider, id: model2.id, reasoning: model2.reasoning });
|
|
19491
19585
|
}
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19586
|
+
return models;
|
|
19587
|
+
}
|
|
19588
|
+
function isRecord9(value) {
|
|
19589
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19590
|
+
}
|
|
19591
|
+
function nonBlankString2(value) {
|
|
19592
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
19593
|
+
}
|
|
19594
|
+
|
|
19595
|
+
// ../../../node_modules/diff/libesm/diff/base.js
|
|
19596
|
+
var Diff = class {
|
|
19597
|
+
diff(oldStr, newStr, options = {}) {
|
|
19598
|
+
let callback;
|
|
19599
|
+
if (typeof options === "function") {
|
|
19600
|
+
callback = options;
|
|
19601
|
+
options = {};
|
|
19602
|
+
} else if ("callback" in options) {
|
|
19603
|
+
callback = options.callback;
|
|
19501
19604
|
}
|
|
19502
|
-
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19605
|
+
const oldString = this.castInput(oldStr, options);
|
|
19606
|
+
const newString = this.castInput(newStr, options);
|
|
19607
|
+
const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
|
|
19608
|
+
const newTokens = this.removeEmpty(this.tokenize(newString, options));
|
|
19609
|
+
return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
|
|
19610
|
+
}
|
|
19611
|
+
diffWithOptionsObj(oldTokens, newTokens, options, callback) {
|
|
19612
|
+
var _a3;
|
|
19613
|
+
const done = (value) => {
|
|
19614
|
+
value = this.postProcess(value, options);
|
|
19615
|
+
if (callback) {
|
|
19616
|
+
setTimeout(function() {
|
|
19617
|
+
callback(value);
|
|
19618
|
+
}, 0);
|
|
19619
|
+
return void 0;
|
|
19620
|
+
} else {
|
|
19621
|
+
return value;
|
|
19506
19622
|
}
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19623
|
+
};
|
|
19624
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
19625
|
+
let editLength = 1;
|
|
19626
|
+
let maxEditLength = newLen + oldLen;
|
|
19627
|
+
if (options.maxEditLength != null) {
|
|
19628
|
+
maxEditLength = Math.min(maxEditLength, options.maxEditLength);
|
|
19629
|
+
}
|
|
19630
|
+
const maxExecutionTime = (_a3 = options.timeout) !== null && _a3 !== void 0 ? _a3 : Infinity;
|
|
19631
|
+
const abortAfterTimestamp = Date.now() + maxExecutionTime;
|
|
19632
|
+
const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
|
|
19633
|
+
let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
|
|
19634
|
+
if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
19635
|
+
return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
|
|
19636
|
+
}
|
|
19637
|
+
let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
|
|
19638
|
+
const execEditLength = () => {
|
|
19639
|
+
for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
|
|
19640
|
+
let basePath;
|
|
19641
|
+
const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
|
|
19642
|
+
if (removePath) {
|
|
19643
|
+
bestPath[diagonalPath - 1] = void 0;
|
|
19644
|
+
}
|
|
19645
|
+
let canAdd = false;
|
|
19646
|
+
if (addPath) {
|
|
19647
|
+
const addPathNewPos = addPath.oldPos - diagonalPath;
|
|
19648
|
+
canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
|
|
19649
|
+
}
|
|
19650
|
+
const canRemove = removePath && removePath.oldPos + 1 < oldLen;
|
|
19651
|
+
if (!canAdd && !canRemove) {
|
|
19652
|
+
bestPath[diagonalPath] = void 0;
|
|
19653
|
+
continue;
|
|
19654
|
+
}
|
|
19655
|
+
if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
|
|
19656
|
+
basePath = this.addToPath(addPath, true, false, 0, options);
|
|
19657
|
+
} else {
|
|
19658
|
+
basePath = this.addToPath(removePath, false, true, 1, options);
|
|
19659
|
+
}
|
|
19660
|
+
newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
|
|
19661
|
+
if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
19662
|
+
return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
|
|
19663
|
+
} else {
|
|
19664
|
+
bestPath[diagonalPath] = basePath;
|
|
19665
|
+
if (basePath.oldPos + 1 >= oldLen) {
|
|
19666
|
+
maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
|
|
19667
|
+
}
|
|
19668
|
+
if (newPos + 1 >= newLen) {
|
|
19669
|
+
minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
|
|
19670
|
+
}
|
|
19511
19671
|
}
|
|
19512
|
-
optionDetails = value.optionDetails.map(({ description }) => description === void 0 ? {} : { description });
|
|
19513
|
-
}
|
|
19514
|
-
request = {
|
|
19515
|
-
requestId,
|
|
19516
|
-
method,
|
|
19517
|
-
title,
|
|
19518
|
-
options: [...value.options],
|
|
19519
|
-
...optionDetails ? { optionDetails } : {},
|
|
19520
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19521
|
-
};
|
|
19522
|
-
} else if (method === "confirm") {
|
|
19523
|
-
if (typeof value.message !== "string") {
|
|
19524
|
-
throw new OmpRpcFaultError("protocolError", "Omp RPC confirm request has no message");
|
|
19525
19672
|
}
|
|
19526
|
-
|
|
19527
|
-
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19673
|
+
editLength++;
|
|
19674
|
+
};
|
|
19675
|
+
if (callback) {
|
|
19676
|
+
(function exec() {
|
|
19677
|
+
setTimeout(function() {
|
|
19678
|
+
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
19679
|
+
return callback(void 0);
|
|
19680
|
+
}
|
|
19681
|
+
if (!execEditLength()) {
|
|
19682
|
+
exec();
|
|
19683
|
+
}
|
|
19684
|
+
}, 0);
|
|
19685
|
+
})();
|
|
19686
|
+
} else {
|
|
19687
|
+
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
19688
|
+
const ret = execEditLength();
|
|
19689
|
+
if (ret) {
|
|
19690
|
+
return ret;
|
|
19691
|
+
}
|
|
19536
19692
|
}
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19693
|
+
}
|
|
19694
|
+
}
|
|
19695
|
+
addToPath(path9, added, removed, oldPosInc, options) {
|
|
19696
|
+
const last = path9.lastComponent;
|
|
19697
|
+
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
19698
|
+
return {
|
|
19699
|
+
oldPos: path9.oldPos + oldPosInc,
|
|
19700
|
+
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
19543
19701
|
};
|
|
19544
19702
|
} else {
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
request = {
|
|
19549
|
-
requestId,
|
|
19550
|
-
method: "editor",
|
|
19551
|
-
title,
|
|
19552
|
-
...typeof value.prefill === "string" ? { prefill: value.prefill } : {},
|
|
19553
|
-
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
19703
|
+
return {
|
|
19704
|
+
oldPos: path9.oldPos + oldPosInc,
|
|
19705
|
+
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
19554
19706
|
};
|
|
19555
19707
|
}
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
|
|
19562
|
-
|
|
19563
|
-
|
|
19564
|
-
|
|
19565
|
-
}
|
|
19566
|
-
}
|
|
19708
|
+
}
|
|
19709
|
+
extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
|
|
19710
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
19711
|
+
let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
|
|
19712
|
+
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
|
|
19713
|
+
newPos++;
|
|
19714
|
+
oldPos++;
|
|
19715
|
+
commonCount++;
|
|
19716
|
+
if (options.oneChangePerToken) {
|
|
19717
|
+
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
19718
|
+
}
|
|
19567
19719
|
}
|
|
19568
|
-
|
|
19569
|
-
|
|
19720
|
+
if (commonCount && !options.oneChangePerToken) {
|
|
19721
|
+
basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
19722
|
+
}
|
|
19723
|
+
basePath.oldPos = oldPos;
|
|
19724
|
+
return newPos;
|
|
19570
19725
|
}
|
|
19571
|
-
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
return;
|
|
19726
|
+
equals(left, right, options) {
|
|
19727
|
+
if (options.comparator) {
|
|
19728
|
+
return options.comparator(left, right);
|
|
19729
|
+
} else {
|
|
19730
|
+
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
19576
19731
|
}
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19732
|
+
}
|
|
19733
|
+
removeEmpty(array2) {
|
|
19734
|
+
const ret = [];
|
|
19735
|
+
for (let i = 0; i < array2.length; i++) {
|
|
19736
|
+
if (array2[i]) {
|
|
19737
|
+
ret.push(array2[i]);
|
|
19583
19738
|
}
|
|
19584
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC response id is not pending"));
|
|
19585
|
-
return;
|
|
19586
19739
|
}
|
|
19587
|
-
|
|
19588
|
-
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
|
|
19596
|
-
|
|
19597
|
-
|
|
19598
|
-
|
|
19740
|
+
return ret;
|
|
19741
|
+
}
|
|
19742
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
19743
|
+
castInput(value, options) {
|
|
19744
|
+
return value;
|
|
19745
|
+
}
|
|
19746
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
19747
|
+
tokenize(value, options) {
|
|
19748
|
+
return Array.from(value);
|
|
19749
|
+
}
|
|
19750
|
+
join(chars) {
|
|
19751
|
+
return chars.join("");
|
|
19752
|
+
}
|
|
19753
|
+
postProcess(changeObjects, options) {
|
|
19754
|
+
return changeObjects;
|
|
19755
|
+
}
|
|
19756
|
+
get useLongestToken() {
|
|
19757
|
+
return false;
|
|
19758
|
+
}
|
|
19759
|
+
buildValues(lastComponent, newTokens, oldTokens) {
|
|
19760
|
+
const components = [];
|
|
19761
|
+
let nextComponent;
|
|
19762
|
+
while (lastComponent) {
|
|
19763
|
+
components.push(lastComponent);
|
|
19764
|
+
nextComponent = lastComponent.previousComponent;
|
|
19765
|
+
delete lastComponent.previousComponent;
|
|
19766
|
+
lastComponent = nextComponent;
|
|
19767
|
+
}
|
|
19768
|
+
components.reverse();
|
|
19769
|
+
const componentLen = components.length;
|
|
19770
|
+
let componentPos = 0, newPos = 0, oldPos = 0;
|
|
19771
|
+
for (; componentPos < componentLen; componentPos++) {
|
|
19772
|
+
const component = components[componentPos];
|
|
19773
|
+
if (!component.removed) {
|
|
19774
|
+
if (!component.added && this.useLongestToken) {
|
|
19775
|
+
let value = newTokens.slice(newPos, newPos + component.count);
|
|
19776
|
+
value = value.map(function(value2, i) {
|
|
19777
|
+
const oldValue = oldTokens[oldPos + i];
|
|
19778
|
+
return oldValue.length > value2.length ? oldValue : value2;
|
|
19779
|
+
});
|
|
19780
|
+
component.value = this.join(value);
|
|
19781
|
+
} else {
|
|
19782
|
+
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
19783
|
+
}
|
|
19784
|
+
newPos += component.count;
|
|
19785
|
+
if (!component.added) {
|
|
19786
|
+
oldPos += component.count;
|
|
19787
|
+
}
|
|
19599
19788
|
} else {
|
|
19600
|
-
|
|
19789
|
+
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
19790
|
+
oldPos += component.count;
|
|
19601
19791
|
}
|
|
19602
19792
|
}
|
|
19793
|
+
return components;
|
|
19603
19794
|
}
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
active.sawTool = true;
|
|
19612
|
-
active.tools.set(callId, toolName);
|
|
19613
|
-
active.onEvent({
|
|
19614
|
-
type: "tool.started",
|
|
19615
|
-
callId,
|
|
19616
|
-
toolName,
|
|
19617
|
-
arguments: argumentsResult.data
|
|
19618
|
-
});
|
|
19795
|
+
};
|
|
19796
|
+
|
|
19797
|
+
// ../../../node_modules/diff/libesm/diff/line.js
|
|
19798
|
+
var LineDiff = class extends Diff {
|
|
19799
|
+
constructor() {
|
|
19800
|
+
super(...arguments);
|
|
19801
|
+
this.tokenize = tokenize;
|
|
19619
19802
|
}
|
|
19620
|
-
|
|
19621
|
-
|
|
19622
|
-
|
|
19623
|
-
|
|
19624
|
-
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
19628
|
-
if (!
|
|
19629
|
-
|
|
19803
|
+
equals(left, right, options) {
|
|
19804
|
+
if (options.ignoreWhitespace) {
|
|
19805
|
+
if (!options.newlineIsToken || !left.includes("\n")) {
|
|
19806
|
+
left = left.trim();
|
|
19807
|
+
}
|
|
19808
|
+
if (!options.newlineIsToken || !right.includes("\n")) {
|
|
19809
|
+
right = right.trim();
|
|
19810
|
+
}
|
|
19811
|
+
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
19812
|
+
if (left.endsWith("\n")) {
|
|
19813
|
+
left = left.slice(0, -1);
|
|
19814
|
+
}
|
|
19815
|
+
if (right.endsWith("\n")) {
|
|
19816
|
+
right = right.slice(0, -1);
|
|
19817
|
+
}
|
|
19630
19818
|
}
|
|
19631
|
-
|
|
19819
|
+
return super.equals(left, right, options);
|
|
19632
19820
|
}
|
|
19633
|
-
|
|
19634
|
-
|
|
19635
|
-
|
|
19636
|
-
|
|
19637
|
-
|
|
19638
|
-
|
|
19639
|
-
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19643
|
-
|
|
19644
|
-
|
|
19821
|
+
};
|
|
19822
|
+
var lineDiff = new LineDiff();
|
|
19823
|
+
function diffLines(oldStr, newStr, options) {
|
|
19824
|
+
return lineDiff.diff(oldStr, newStr, options);
|
|
19825
|
+
}
|
|
19826
|
+
function tokenize(value, options) {
|
|
19827
|
+
if (options.stripTrailingCr) {
|
|
19828
|
+
value = value.replace(/\r\n/g, "\n");
|
|
19829
|
+
}
|
|
19830
|
+
const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
|
|
19831
|
+
if (!linesAndNewlines[linesAndNewlines.length - 1]) {
|
|
19832
|
+
linesAndNewlines.pop();
|
|
19833
|
+
}
|
|
19834
|
+
for (let i = 0; i < linesAndNewlines.length; i++) {
|
|
19835
|
+
const line = linesAndNewlines[i];
|
|
19836
|
+
if (i % 2 && !options.newlineIsToken) {
|
|
19837
|
+
retLines[retLines.length - 1] += line;
|
|
19838
|
+
} else {
|
|
19839
|
+
retLines.push(line);
|
|
19645
19840
|
}
|
|
19646
|
-
active.tools.delete(callId);
|
|
19647
|
-
active.onEvent({
|
|
19648
|
-
type: "tool.completed",
|
|
19649
|
-
callId,
|
|
19650
|
-
toolName,
|
|
19651
|
-
result: result.data,
|
|
19652
|
-
isError: value.isError === true
|
|
19653
|
-
});
|
|
19654
19841
|
}
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19660
|
-
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
|
|
19667
|
-
|
|
19668
|
-
|
|
19669
|
-
return;
|
|
19670
|
-
response = await this.#send("get_state", {});
|
|
19842
|
+
return retLines;
|
|
19843
|
+
}
|
|
19844
|
+
|
|
19845
|
+
// ../../../node_modules/diff/libesm/patch/parse.js
|
|
19846
|
+
function parsePatch(uniDiff) {
|
|
19847
|
+
const diffstr = uniDiff.split(/\n/), list = [];
|
|
19848
|
+
let i = 0;
|
|
19849
|
+
function parseIndex() {
|
|
19850
|
+
const index = {};
|
|
19851
|
+
list.push(index);
|
|
19852
|
+
while (i < diffstr.length) {
|
|
19853
|
+
const line = diffstr[i];
|
|
19854
|
+
if (/^(---|\+\+\+|@@)\s/.test(line)) {
|
|
19855
|
+
break;
|
|
19671
19856
|
}
|
|
19672
|
-
|
|
19673
|
-
if (
|
|
19674
|
-
|
|
19675
|
-
const data = sessionStateData(response);
|
|
19676
|
-
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) {
|
|
19677
|
-
await this.verifySessionCwd(this.#options.cwd);
|
|
19678
|
-
if (this.#activeTurn !== active)
|
|
19679
|
-
return;
|
|
19680
|
-
active.cancellationReloaded = true;
|
|
19681
|
-
const reset = await this.#send("new_session", {});
|
|
19682
|
-
if (this.#activeTurn !== active)
|
|
19683
|
-
return;
|
|
19684
|
-
if (!isRecord8(reset.data) || reset.data.cancelled !== false) {
|
|
19685
|
-
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reset was refused");
|
|
19686
|
-
}
|
|
19687
|
-
const reloaded = await this.#send("switch_session", { sessionPath: state.sessionFile });
|
|
19688
|
-
if (this.#activeTurn !== active)
|
|
19689
|
-
return;
|
|
19690
|
-
if (!isRecord8(reloaded.data) || reloaded.data.cancelled !== false) {
|
|
19691
|
-
throw new OmpRpcFaultError("unavailable", "Omp cancelled Session reload was refused");
|
|
19692
|
-
}
|
|
19693
|
-
const previous = state;
|
|
19694
|
-
response = await this.#send("get_state", {});
|
|
19695
|
-
state = parseSessionState(response);
|
|
19696
|
-
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile) {
|
|
19697
|
-
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity");
|
|
19698
|
-
}
|
|
19699
|
-
if (state.provider !== previous.provider || state.modelId !== previous.modelId) {
|
|
19700
|
-
if (!previous.provider || !previous.modelId) {
|
|
19701
|
-
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session has no restorable Model");
|
|
19702
|
-
}
|
|
19703
|
-
await this.#send("set_model", { provider: previous.provider, modelId: previous.modelId });
|
|
19704
|
-
}
|
|
19705
|
-
if (previous.thinkingLevel && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19706
|
-
await this.#send("set_thinking_level", { level: previous.thinkingLevel });
|
|
19707
|
-
}
|
|
19708
|
-
response = await this.#send("get_state", {});
|
|
19709
|
-
state = parseSessionState(response);
|
|
19710
|
-
if (state.sessionId !== previous.sessionId || state.sessionFile !== previous.sessionFile || state.provider !== previous.provider || state.modelId !== previous.modelId || previous.thinkingLevel !== null && state.thinkingLevel !== previous.thinkingLevel) {
|
|
19711
|
-
throw new OmpRpcFaultError("protocolError", "Omp cancelled Session reload changed its identity or configuration");
|
|
19712
|
-
}
|
|
19857
|
+
const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
|
|
19858
|
+
if (header) {
|
|
19859
|
+
index.index = header[1];
|
|
19713
19860
|
}
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
|
|
19717
|
-
|
|
19718
|
-
|
|
19719
|
-
|
|
19720
|
-
|
|
19861
|
+
i++;
|
|
19862
|
+
}
|
|
19863
|
+
parseFileHeader(index);
|
|
19864
|
+
parseFileHeader(index);
|
|
19865
|
+
index.hunks = [];
|
|
19866
|
+
while (i < diffstr.length) {
|
|
19867
|
+
const line = diffstr[i];
|
|
19868
|
+
if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
|
|
19869
|
+
break;
|
|
19870
|
+
} else if (/^@@/.test(line)) {
|
|
19871
|
+
index.hunks.push(parseHunk());
|
|
19872
|
+
} else if (line) {
|
|
19873
|
+
throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
|
|
19874
|
+
} else {
|
|
19875
|
+
i++;
|
|
19721
19876
|
}
|
|
19722
|
-
this.#state = state;
|
|
19723
|
-
active.settlement = "confirmed";
|
|
19724
|
-
this.#finishSettledTurn(active);
|
|
19725
|
-
} catch (error51) {
|
|
19726
|
-
if (this.#activeTurn !== active)
|
|
19727
|
-
return;
|
|
19728
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC cancelled Turn state could not be confirmed: ${message2(error51)}`);
|
|
19729
|
-
this.#terminateFailedCancellation(active, fault);
|
|
19730
|
-
} finally {
|
|
19731
|
-
active.cancellationChecking = false;
|
|
19732
19877
|
}
|
|
19733
19878
|
}
|
|
19734
|
-
|
|
19735
|
-
|
|
19736
|
-
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
|
|
19740
|
-
|
|
19741
|
-
async #confirmSettledTurn(active) {
|
|
19742
|
-
try {
|
|
19743
|
-
const response = await this.#send("get_state", {});
|
|
19744
|
-
const state = parseSessionState(response);
|
|
19745
|
-
if (this.#activeTurn !== active)
|
|
19746
|
-
return;
|
|
19747
|
-
if (active.cancellation !== "none") {
|
|
19748
|
-
active.settlement = "pending";
|
|
19749
|
-
if (active.cancellation === "accepted")
|
|
19750
|
-
void this.#confirmCancelledTurn(active);
|
|
19751
|
-
return;
|
|
19879
|
+
function parseFileHeader(index) {
|
|
19880
|
+
const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
|
|
19881
|
+
if (fileHeader) {
|
|
19882
|
+
const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
|
|
19883
|
+
let fileName = data[0].replace(/\\\\/g, "\\");
|
|
19884
|
+
if (/^".*"$/.test(fileName)) {
|
|
19885
|
+
fileName = fileName.substr(1, fileName.length - 2);
|
|
19752
19886
|
}
|
|
19753
|
-
if (
|
|
19754
|
-
|
|
19887
|
+
if (fileHeader[1] === "---") {
|
|
19888
|
+
index.oldFileName = fileName;
|
|
19889
|
+
index.oldHeader = header;
|
|
19890
|
+
} else {
|
|
19891
|
+
index.newFileName = fileName;
|
|
19892
|
+
index.newHeader = header;
|
|
19893
|
+
}
|
|
19894
|
+
i++;
|
|
19895
|
+
}
|
|
19896
|
+
}
|
|
19897
|
+
function parseHunk() {
|
|
19898
|
+
var _a3;
|
|
19899
|
+
const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
|
19900
|
+
const hunk = {
|
|
19901
|
+
oldStart: +chunkHeader[1],
|
|
19902
|
+
oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
|
|
19903
|
+
newStart: +chunkHeader[3],
|
|
19904
|
+
newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
|
|
19905
|
+
lines: []
|
|
19906
|
+
};
|
|
19907
|
+
if (hunk.oldLines === 0) {
|
|
19908
|
+
hunk.oldStart += 1;
|
|
19909
|
+
}
|
|
19910
|
+
if (hunk.newLines === 0) {
|
|
19911
|
+
hunk.newStart += 1;
|
|
19912
|
+
}
|
|
19913
|
+
let addCount = 0, removeCount = 0;
|
|
19914
|
+
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
|
|
19915
|
+
const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
|
|
19916
|
+
if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
|
|
19917
|
+
hunk.lines.push(diffstr[i]);
|
|
19918
|
+
if (operation === "+") {
|
|
19919
|
+
addCount++;
|
|
19920
|
+
} else if (operation === "-") {
|
|
19921
|
+
removeCount++;
|
|
19922
|
+
} else if (operation === " ") {
|
|
19923
|
+
addCount++;
|
|
19924
|
+
removeCount++;
|
|
19925
|
+
}
|
|
19926
|
+
} else {
|
|
19927
|
+
throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
|
|
19755
19928
|
}
|
|
19756
|
-
this.#state = state;
|
|
19757
|
-
active.settlement = "confirmed";
|
|
19758
|
-
this.#finishSettledTurn(active);
|
|
19759
|
-
} catch (error51) {
|
|
19760
|
-
if (this.#activeTurn !== active)
|
|
19761
|
-
return;
|
|
19762
|
-
const fault = error51 instanceof OmpRpcFaultError ? error51 : new OmpRpcFaultError("protocolError", `Omp RPC stable Turn state could not be confirmed: ${message2(error51)}`);
|
|
19763
|
-
this.#fail(fault);
|
|
19764
19929
|
}
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
if (this.#activeTurn !== active || active.settlement !== "confirmed" || active.cancellation === "requesting") {
|
|
19768
|
-
return;
|
|
19930
|
+
if (!addCount && hunk.newLines === 1) {
|
|
19931
|
+
hunk.newLines = 0;
|
|
19769
19932
|
}
|
|
19770
|
-
if (
|
|
19771
|
-
|
|
19772
|
-
active.cancellationTimeout = null;
|
|
19773
|
-
if (active.cancellationRecheck)
|
|
19774
|
-
clearTimeout(active.cancellationRecheck);
|
|
19775
|
-
active.cancellationRecheck = null;
|
|
19776
|
-
this.#closeInteractions(active, active.cancellation === "accepted" ? "cancelled" : "superseded");
|
|
19777
|
-
if (active.tools.size > 0) {
|
|
19778
|
-
this.#fail(new OmpRpcFaultError("protocolError", "Omp RPC settled with active Tool executions"));
|
|
19779
|
-
return;
|
|
19933
|
+
if (!removeCount && hunk.oldLines === 1) {
|
|
19934
|
+
hunk.oldLines = 0;
|
|
19780
19935
|
}
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
active.resolve({
|
|
19784
|
-
text: active.text,
|
|
19785
|
-
agentInvoked: false,
|
|
19786
|
-
...active.localResult,
|
|
19787
|
-
cancelled: active.localResult.cancelled || active.cancellation === "accepted"
|
|
19788
|
-
});
|
|
19789
|
-
} else if (active.cancellation === "accepted") {
|
|
19790
|
-
active.resolve({ text: active.text, cancelled: true, agentInvoked: true });
|
|
19791
|
-
} else if (active.failure) {
|
|
19792
|
-
active.reject(active.failure);
|
|
19793
|
-
} else if (active.text.trim().length === 0 && !active.sawTool) {
|
|
19794
|
-
active.reject(new Error("Omp RPC settled without displayable output"));
|
|
19795
|
-
} else {
|
|
19796
|
-
active.resolve({ text: active.text, cancelled: false, agentInvoked: true });
|
|
19936
|
+
if (addCount !== hunk.newLines) {
|
|
19937
|
+
throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
19797
19938
|
}
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19801
|
-
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19939
|
+
if (removeCount !== hunk.oldLines) {
|
|
19940
|
+
throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
|
|
19802
19941
|
}
|
|
19803
|
-
|
|
19804
|
-
active.assistantMessageId = messageId;
|
|
19805
|
-
active.sawStreamedMessageText = false;
|
|
19806
|
-
active.sawStreamedMessageReasoning = false;
|
|
19807
|
-
active.reasoningMessageOpen = false;
|
|
19808
|
-
return messageId;
|
|
19942
|
+
return hunk;
|
|
19809
19943
|
}
|
|
19810
|
-
|
|
19811
|
-
|
|
19944
|
+
while (i < diffstr.length) {
|
|
19945
|
+
parseIndex();
|
|
19812
19946
|
}
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
|
|
19819
|
-
|
|
19820
|
-
|
|
19947
|
+
return list;
|
|
19948
|
+
}
|
|
19949
|
+
|
|
19950
|
+
// ../../../node_modules/diff/libesm/patch/create.js
|
|
19951
|
+
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
19952
|
+
let optionsObj;
|
|
19953
|
+
if (!options) {
|
|
19954
|
+
optionsObj = {};
|
|
19955
|
+
} else if (typeof options === "function") {
|
|
19956
|
+
optionsObj = { callback: options };
|
|
19957
|
+
} else {
|
|
19958
|
+
optionsObj = options;
|
|
19959
|
+
}
|
|
19960
|
+
if (typeof optionsObj.context === "undefined") {
|
|
19961
|
+
optionsObj.context = 4;
|
|
19962
|
+
}
|
|
19963
|
+
const context = optionsObj.context;
|
|
19964
|
+
if (optionsObj.newlineIsToken) {
|
|
19965
|
+
throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
|
|
19966
|
+
}
|
|
19967
|
+
if (!optionsObj.callback) {
|
|
19968
|
+
return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
|
|
19969
|
+
} else {
|
|
19970
|
+
const { callback } = optionsObj;
|
|
19971
|
+
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
|
19972
|
+
const patch = diffLinesResultToPatch(diff);
|
|
19973
|
+
callback(patch);
|
|
19974
|
+
} }));
|
|
19975
|
+
}
|
|
19976
|
+
function diffLinesResultToPatch(diff) {
|
|
19977
|
+
if (!diff) {
|
|
19821
19978
|
return;
|
|
19822
19979
|
}
|
|
19823
|
-
|
|
19824
|
-
|
|
19825
|
-
|
|
19826
|
-
|
|
19827
|
-
|
|
19828
|
-
active.onEvent({ type: "reasoning.delta", messageId, delta: finalReasoning });
|
|
19980
|
+
diff.push({ value: "", lines: [] });
|
|
19981
|
+
function contextLines(lines) {
|
|
19982
|
+
return lines.map(function(entry) {
|
|
19983
|
+
return " " + entry;
|
|
19984
|
+
});
|
|
19829
19985
|
}
|
|
19830
|
-
|
|
19831
|
-
|
|
19986
|
+
const hunks = [];
|
|
19987
|
+
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
|
19988
|
+
for (let i = 0; i < diff.length; i++) {
|
|
19989
|
+
const current = diff[i], lines = current.lines || splitLines(current.value);
|
|
19990
|
+
current.lines = lines;
|
|
19991
|
+
if (current.added || current.removed) {
|
|
19992
|
+
if (!oldRangeStart) {
|
|
19993
|
+
const prev = diff[i - 1];
|
|
19994
|
+
oldRangeStart = oldLine;
|
|
19995
|
+
newRangeStart = newLine;
|
|
19996
|
+
if (prev) {
|
|
19997
|
+
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
|
|
19998
|
+
oldRangeStart -= curRange.length;
|
|
19999
|
+
newRangeStart -= curRange.length;
|
|
20000
|
+
}
|
|
20001
|
+
}
|
|
20002
|
+
for (const line of lines) {
|
|
20003
|
+
curRange.push((current.added ? "+" : "-") + line);
|
|
20004
|
+
}
|
|
20005
|
+
if (current.added) {
|
|
20006
|
+
newLine += lines.length;
|
|
20007
|
+
} else {
|
|
20008
|
+
oldLine += lines.length;
|
|
20009
|
+
}
|
|
20010
|
+
} else {
|
|
20011
|
+
if (oldRangeStart) {
|
|
20012
|
+
if (lines.length <= context * 2 && i < diff.length - 2) {
|
|
20013
|
+
for (const line of contextLines(lines)) {
|
|
20014
|
+
curRange.push(line);
|
|
20015
|
+
}
|
|
20016
|
+
} else {
|
|
20017
|
+
const contextSize = Math.min(lines.length, context);
|
|
20018
|
+
for (const line of contextLines(lines.slice(0, contextSize))) {
|
|
20019
|
+
curRange.push(line);
|
|
20020
|
+
}
|
|
20021
|
+
const hunk = {
|
|
20022
|
+
oldStart: oldRangeStart,
|
|
20023
|
+
oldLines: oldLine - oldRangeStart + contextSize,
|
|
20024
|
+
newStart: newRangeStart,
|
|
20025
|
+
newLines: newLine - newRangeStart + contextSize,
|
|
20026
|
+
lines: curRange
|
|
20027
|
+
};
|
|
20028
|
+
hunks.push(hunk);
|
|
20029
|
+
oldRangeStart = 0;
|
|
20030
|
+
newRangeStart = 0;
|
|
20031
|
+
curRange = [];
|
|
20032
|
+
}
|
|
20033
|
+
}
|
|
20034
|
+
oldLine += lines.length;
|
|
20035
|
+
newLine += lines.length;
|
|
20036
|
+
}
|
|
19832
20037
|
}
|
|
19833
|
-
|
|
19834
|
-
|
|
19835
|
-
|
|
20038
|
+
for (const hunk of hunks) {
|
|
20039
|
+
for (let i = 0; i < hunk.lines.length; i++) {
|
|
20040
|
+
if (hunk.lines[i].endsWith("\n")) {
|
|
20041
|
+
hunk.lines[i] = hunk.lines[i].slice(0, -1);
|
|
20042
|
+
} else {
|
|
20043
|
+
hunk.lines.splice(i + 1, 0, "\");
|
|
20044
|
+
i++;
|
|
20045
|
+
}
|
|
20046
|
+
}
|
|
19836
20047
|
}
|
|
19837
|
-
|
|
19838
|
-
|
|
19839
|
-
|
|
19840
|
-
|
|
19841
|
-
|
|
19842
|
-
|
|
19843
|
-
|
|
20048
|
+
return {
|
|
20049
|
+
oldFileName,
|
|
20050
|
+
newFileName,
|
|
20051
|
+
oldHeader,
|
|
20052
|
+
newHeader,
|
|
20053
|
+
hunks
|
|
20054
|
+
};
|
|
19844
20055
|
}
|
|
19845
|
-
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
|
|
19849
|
-
}
|
|
19850
|
-
return new Promise((resolve, reject) => {
|
|
19851
|
-
const frame = Buffer.from(`${JSON.stringify(value)}
|
|
19852
|
-
`, "utf8");
|
|
19853
|
-
child.stdin.write(frame, (error51) => error51 ? reject(error51) : resolve());
|
|
19854
|
-
});
|
|
20056
|
+
}
|
|
20057
|
+
function formatPatch(patch) {
|
|
20058
|
+
if (Array.isArray(patch)) {
|
|
20059
|
+
return patch.map(formatPatch).join("\n");
|
|
19855
20060
|
}
|
|
19856
|
-
|
|
19857
|
-
|
|
19858
|
-
|
|
19859
|
-
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
|
|
19864
|
-
|
|
19865
|
-
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
|
|
19869
|
-
|
|
19870
|
-
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
|
|
19874
|
-
|
|
19875
|
-
clearTimeout(pending.timeout);
|
|
19876
|
-
this.#pending.delete(id);
|
|
19877
|
-
reject(error51);
|
|
19878
|
-
}
|
|
19879
|
-
});
|
|
19880
|
-
});
|
|
20061
|
+
const ret = [];
|
|
20062
|
+
if (patch.oldFileName == patch.newFileName) {
|
|
20063
|
+
ret.push("Index: " + patch.oldFileName);
|
|
20064
|
+
}
|
|
20065
|
+
ret.push("===================================================================");
|
|
20066
|
+
ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
|
|
20067
|
+
ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
|
|
20068
|
+
for (let i = 0; i < patch.hunks.length; i++) {
|
|
20069
|
+
const hunk = patch.hunks[i];
|
|
20070
|
+
if (hunk.oldLines === 0) {
|
|
20071
|
+
hunk.oldStart -= 1;
|
|
20072
|
+
}
|
|
20073
|
+
if (hunk.newLines === 0) {
|
|
20074
|
+
hunk.newStart -= 1;
|
|
20075
|
+
}
|
|
20076
|
+
ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
|
|
20077
|
+
for (const line of hunk.lines) {
|
|
20078
|
+
ret.push(line);
|
|
20079
|
+
}
|
|
19881
20080
|
}
|
|
19882
|
-
|
|
19883
|
-
|
|
20081
|
+
return ret.join("\n") + "\n";
|
|
20082
|
+
}
|
|
20083
|
+
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
20084
|
+
if (typeof options === "function") {
|
|
20085
|
+
options = { callback: options };
|
|
20086
|
+
}
|
|
20087
|
+
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
|
|
20088
|
+
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
20089
|
+
if (!patchObj) {
|
|
19884
20090
|
return;
|
|
19885
20091
|
}
|
|
19886
|
-
|
|
19887
|
-
|
|
19888
|
-
|
|
19889
|
-
|
|
19890
|
-
|
|
19891
|
-
|
|
19892
|
-
|
|
19893
|
-
|
|
19894
|
-
return;
|
|
20092
|
+
return formatPatch(patchObj);
|
|
20093
|
+
} else {
|
|
20094
|
+
const { callback } = options;
|
|
20095
|
+
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
|
|
20096
|
+
if (!patchObj) {
|
|
20097
|
+
callback(void 0);
|
|
20098
|
+
} else {
|
|
20099
|
+
callback(formatPatch(patchObj));
|
|
19895
20100
|
}
|
|
19896
|
-
|
|
19897
|
-
void this.#terminateTimedOutPrompt(fault);
|
|
19898
|
-
}, this.#options.commandTimeoutMs);
|
|
20101
|
+
} }));
|
|
19899
20102
|
}
|
|
19900
|
-
|
|
19901
|
-
|
|
19902
|
-
|
|
19903
|
-
|
|
19904
|
-
|
|
19905
|
-
|
|
19906
|
-
|
|
19907
|
-
|
|
19908
|
-
pending.timeout = null;
|
|
19909
|
-
}
|
|
19910
|
-
let finalFault = fault;
|
|
19911
|
-
try {
|
|
19912
|
-
await this.close();
|
|
19913
|
-
} catch (error51) {
|
|
19914
|
-
finalFault = new OmpRpcFaultError("processExited", `Omp RPC timed-out Prompt cleanup failed: ${message2(error51)}`);
|
|
19915
|
-
}
|
|
19916
|
-
this.#rejectAll(finalFault);
|
|
19917
|
-
this.#options.onFault?.(finalFault);
|
|
20103
|
+
}
|
|
20104
|
+
function splitLines(text) {
|
|
20105
|
+
const hasTrailingNl = text.endsWith("\n");
|
|
20106
|
+
const result = text.split("\n").map((line) => line + "\n");
|
|
20107
|
+
if (hasTrailingNl) {
|
|
20108
|
+
result.pop();
|
|
20109
|
+
} else {
|
|
20110
|
+
result.push(result.pop().slice(0, -1));
|
|
19918
20111
|
}
|
|
19919
|
-
|
|
19920
|
-
|
|
19921
|
-
|
|
19922
|
-
|
|
19923
|
-
|
|
19924
|
-
|
|
19925
|
-
|
|
20112
|
+
return result;
|
|
20113
|
+
}
|
|
20114
|
+
|
|
20115
|
+
// dist/omp-adapter.js
|
|
20116
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
20117
|
+
import { realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
20118
|
+
import path7 from "node:path";
|
|
20119
|
+
|
|
20120
|
+
// dist/omp-last-turn-rollback.js
|
|
20121
|
+
function modelFromState(state) {
|
|
20122
|
+
if (state.provider === null && state.modelId === null)
|
|
20123
|
+
return null;
|
|
20124
|
+
if (state.provider === null || state.modelId === null) {
|
|
20125
|
+
throw new Error("Omp state contains a partial Model identity");
|
|
19926
20126
|
}
|
|
19927
|
-
|
|
19928
|
-
|
|
19929
|
-
|
|
19930
|
-
|
|
19931
|
-
|
|
19932
|
-
|
|
19933
|
-
|
|
19934
|
-
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
|
|
20127
|
+
return { provider: state.provider, id: state.modelId };
|
|
20128
|
+
}
|
|
20129
|
+
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
20130
|
+
const startupState = transport.state;
|
|
20131
|
+
const startupSessionId = startupState.sessionId;
|
|
20132
|
+
const currentModel = modelFromState(startupState);
|
|
20133
|
+
const currentThinking = startupState.thinkingLevel;
|
|
20134
|
+
const copiedHistory = await transport.getEntries();
|
|
20135
|
+
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
20136
|
+
if (!boundary)
|
|
20137
|
+
return { ok: false, reason: "empty" };
|
|
20138
|
+
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
20139
|
+
sessionId: startupSessionId,
|
|
20140
|
+
model: currentModel
|
|
20141
|
+
});
|
|
20142
|
+
let state = await transport.fork(boundary.lastUserEntryId);
|
|
20143
|
+
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
20144
|
+
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
19938
20145
|
}
|
|
19939
|
-
|
|
19940
|
-
if (
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
for (const pending of this.#pending.values()) {
|
|
19944
|
-
if (pending.timeout)
|
|
19945
|
-
clearTimeout(pending.timeout);
|
|
19946
|
-
pending.reject(error51);
|
|
19947
|
-
}
|
|
19948
|
-
this.#pending.clear();
|
|
19949
|
-
const manual = this.#manualCompaction;
|
|
19950
|
-
this.#manualCompaction = null;
|
|
19951
|
-
manual?.reject(error51);
|
|
19952
|
-
this.#rejectActiveTurn(error51);
|
|
20146
|
+
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
20147
|
+
if (!currentModel)
|
|
20148
|
+
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
20149
|
+
state = await transport.selectModel(currentModel);
|
|
19953
20150
|
}
|
|
19954
|
-
|
|
19955
|
-
if (
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
this.#startupFaultResolve?.(error51);
|
|
19959
|
-
this.#startupFaultResolve = null;
|
|
19960
|
-
this.#rejectAll(error51);
|
|
19961
|
-
this.#options.onFault?.(error51);
|
|
20151
|
+
if (state.thinkingLevel !== currentThinking) {
|
|
20152
|
+
if (!currentThinking)
|
|
20153
|
+
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
20154
|
+
state = await transport.selectThinkingOption(currentThinking);
|
|
19962
20155
|
}
|
|
19963
|
-
|
|
20156
|
+
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
20157
|
+
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
20158
|
+
}
|
|
20159
|
+
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
20160
|
+
sessionId: state.sessionId,
|
|
20161
|
+
model: modelFromState(state)
|
|
20162
|
+
});
|
|
20163
|
+
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
20164
|
+
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
20165
|
+
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
20166
|
+
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
20167
|
+
}
|
|
20168
|
+
await transport.verifySessionCwd(cwd);
|
|
20169
|
+
return { ok: true };
|
|
20170
|
+
}
|
|
19964
20171
|
|
|
19965
20172
|
// dist/omp-permission-modes.js
|
|
19966
20173
|
var nativePermissionModes = /* @__PURE__ */ new Set(["always-ask", "write", "yolo"]);
|
|
@@ -20113,6 +20320,24 @@ var OmpSubagentLifecycle = class {
|
|
|
20113
20320
|
};
|
|
20114
20321
|
|
|
20115
20322
|
// dist/omp-adapter.js
|
|
20323
|
+
function closedInspection() {
|
|
20324
|
+
return {
|
|
20325
|
+
status: "unavailable",
|
|
20326
|
+
error: { code: "invalidState", message: "Omp Adapter is closed", retryable: false }
|
|
20327
|
+
};
|
|
20328
|
+
}
|
|
20329
|
+
function ompInspectionCapabilities(selectThinkingOption) {
|
|
20330
|
+
return {
|
|
20331
|
+
configuration: {
|
|
20332
|
+
selectModel: true,
|
|
20333
|
+
selectThinkingOption,
|
|
20334
|
+
selectPermissionMode: true,
|
|
20335
|
+
permissionModeScope: "live"
|
|
20336
|
+
},
|
|
20337
|
+
history: { fork: true, forkAcrossCwd: true, rollbackLastTurn: true },
|
|
20338
|
+
subagents: { observe: true, readTranscript: true }
|
|
20339
|
+
};
|
|
20340
|
+
}
|
|
20116
20341
|
var ompHarnessId2 = harnessIdSchema.parse("omp");
|
|
20117
20342
|
var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
20118
20343
|
commands: [
|
|
@@ -20127,7 +20352,7 @@ var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
|
20127
20352
|
]
|
|
20128
20353
|
});
|
|
20129
20354
|
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
20130
|
-
function
|
|
20355
|
+
function isRecord10(value) {
|
|
20131
20356
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20132
20357
|
}
|
|
20133
20358
|
function errorMessage(error51) {
|
|
@@ -20142,7 +20367,7 @@ var OmpAdapterFaultError = class extends Error {
|
|
|
20142
20367
|
}
|
|
20143
20368
|
};
|
|
20144
20369
|
function normalizedError(error51, fallbackCode) {
|
|
20145
|
-
if (
|
|
20370
|
+
if (isRecord10(error51) && error51.code === "ENOENT") {
|
|
20146
20371
|
return { code: "notInstalled", message: errorMessage(error51), retryable: false };
|
|
20147
20372
|
}
|
|
20148
20373
|
if (error51 instanceof OmpAdapterFaultError)
|
|
@@ -20219,7 +20444,7 @@ function nativeModelForHistory(state) {
|
|
|
20219
20444
|
return nativeModelFromState(state);
|
|
20220
20445
|
}
|
|
20221
20446
|
function sessionFileFromRef(ref) {
|
|
20222
|
-
if (ref.harnessId !== ompHarnessId2 || !
|
|
20447
|
+
if (ref.harnessId !== ompHarnessId2 || !isRecord10(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
|
|
20223
20448
|
throw new Error("Omp Native Session Ref has no resumable Session file");
|
|
20224
20449
|
}
|
|
20225
20450
|
return ref.locator.sessionFile;
|
|
@@ -20274,9 +20499,9 @@ function toolFailure(toolName) {
|
|
|
20274
20499
|
function nativeText(value) {
|
|
20275
20500
|
if (typeof value === "string")
|
|
20276
20501
|
return value;
|
|
20277
|
-
if (!
|
|
20502
|
+
if (!isRecord10(value) || !Array.isArray(value.content))
|
|
20278
20503
|
return "";
|
|
20279
|
-
return value.content.filter((content) =>
|
|
20504
|
+
return value.content.filter((content) => isRecord10(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
|
|
20280
20505
|
}
|
|
20281
20506
|
function boundedOutput(value, limit) {
|
|
20282
20507
|
const text = nativeText(value);
|
|
@@ -20292,17 +20517,17 @@ function outputText(output) {
|
|
|
20292
20517
|
return output?.content.filter((content) => content.type === "text").map(({ text }) => text).join("") ?? "";
|
|
20293
20518
|
}
|
|
20294
20519
|
function stringField2(value, key) {
|
|
20295
|
-
if (!
|
|
20520
|
+
if (!isRecord10(value))
|
|
20296
20521
|
return void 0;
|
|
20297
|
-
const
|
|
20298
|
-
if (typeof
|
|
20299
|
-
return
|
|
20300
|
-
if (
|
|
20522
|
+
const field2 = value[key];
|
|
20523
|
+
if (typeof field2 === "string" && field2.length > 0)
|
|
20524
|
+
return field2;
|
|
20525
|
+
if (isRecord10(value.input)) {
|
|
20301
20526
|
const nested = value.input[key];
|
|
20302
20527
|
if (typeof nested === "string" && nested.length > 0)
|
|
20303
20528
|
return nested;
|
|
20304
20529
|
}
|
|
20305
|
-
if (
|
|
20530
|
+
if (isRecord10(value.arguments)) {
|
|
20306
20531
|
const nested = value.arguments[key];
|
|
20307
20532
|
if (typeof nested === "string" && nested.length > 0)
|
|
20308
20533
|
return nested;
|
|
@@ -20310,10 +20535,10 @@ function stringField2(value, key) {
|
|
|
20310
20535
|
return void 0;
|
|
20311
20536
|
}
|
|
20312
20537
|
function numberField(value, key) {
|
|
20313
|
-
if (!
|
|
20538
|
+
if (!isRecord10(value))
|
|
20314
20539
|
return void 0;
|
|
20315
|
-
const
|
|
20316
|
-
return typeof
|
|
20540
|
+
const field2 = value[key];
|
|
20541
|
+
return typeof field2 === "number" || field2 === null ? field2 : void 0;
|
|
20317
20542
|
}
|
|
20318
20543
|
function stripDiffPrefix(pathString) {
|
|
20319
20544
|
if (typeof pathString !== "string" || pathString.length === 0)
|
|
@@ -20349,12 +20574,12 @@ function fileMutatingKind(toolName) {
|
|
|
20349
20574
|
return null;
|
|
20350
20575
|
}
|
|
20351
20576
|
function nestedToolString(value, keys) {
|
|
20352
|
-
if (!
|
|
20577
|
+
if (!isRecord10(value))
|
|
20353
20578
|
return void 0;
|
|
20354
20579
|
for (const key of keys) {
|
|
20355
|
-
const
|
|
20356
|
-
if (typeof
|
|
20357
|
-
return
|
|
20580
|
+
const field2 = value[key];
|
|
20581
|
+
if (typeof field2 === "string" && field2.length > 0)
|
|
20582
|
+
return field2;
|
|
20358
20583
|
}
|
|
20359
20584
|
for (const wrapper of ["input", "arguments", "params", "details"]) {
|
|
20360
20585
|
const nested = nestedToolString(value[wrapper], keys);
|
|
@@ -20364,18 +20589,18 @@ function nestedToolString(value, keys) {
|
|
|
20364
20589
|
return void 0;
|
|
20365
20590
|
}
|
|
20366
20591
|
function patchFromResult(result) {
|
|
20367
|
-
if (!
|
|
20592
|
+
if (!isRecord10(result))
|
|
20368
20593
|
return void 0;
|
|
20369
20594
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
20370
|
-
const
|
|
20371
|
-
if (typeof
|
|
20372
|
-
return
|
|
20595
|
+
const field2 = result[key];
|
|
20596
|
+
if (typeof field2 === "string" && field2.length > 0)
|
|
20597
|
+
return field2;
|
|
20373
20598
|
}
|
|
20374
|
-
if (
|
|
20599
|
+
if (isRecord10(result.details)) {
|
|
20375
20600
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
20376
|
-
const
|
|
20377
|
-
if (typeof
|
|
20378
|
-
return
|
|
20601
|
+
const field2 = result.details[key];
|
|
20602
|
+
if (typeof field2 === "string" && field2.length > 0)
|
|
20603
|
+
return field2;
|
|
20379
20604
|
}
|
|
20380
20605
|
}
|
|
20381
20606
|
return void 0;
|
|
@@ -20498,9 +20723,6 @@ var OmpHarnessSession = class {
|
|
|
20498
20723
|
#usage;
|
|
20499
20724
|
#usageGeneration = 0;
|
|
20500
20725
|
#usageRefreshSequence = 0;
|
|
20501
|
-
#backgroundTurnId = null;
|
|
20502
|
-
#backgroundSubagents = /* @__PURE__ */ new Map();
|
|
20503
|
-
#backgroundTurnFailed = false;
|
|
20504
20726
|
constructor(cwd, createTransport, onClosed, options) {
|
|
20505
20727
|
this.#cwd = cwd;
|
|
20506
20728
|
this.#createTransport = createTransport;
|
|
@@ -20558,44 +20780,6 @@ var OmpHarnessSession = class {
|
|
|
20558
20780
|
#backgroundStatus(status) {
|
|
20559
20781
|
return status === "pending" || status === "running" ? "running" : status === "interrupted" ? "interrupted" : status;
|
|
20560
20782
|
}
|
|
20561
|
-
#ensureBackgroundTurn() {
|
|
20562
|
-
if (this.#backgroundTurnId)
|
|
20563
|
-
return this.#backgroundTurnId;
|
|
20564
|
-
const turnId = hostTurnIdSchema.parse(randomUUID2());
|
|
20565
|
-
this.#backgroundTurnId = turnId;
|
|
20566
|
-
this.#backgroundTurnFailed = false;
|
|
20567
|
-
this.#event({
|
|
20568
|
-
type: "turn.autonomous.started",
|
|
20569
|
-
turnId,
|
|
20570
|
-
input: []
|
|
20571
|
-
});
|
|
20572
|
-
return turnId;
|
|
20573
|
-
}
|
|
20574
|
-
#backgroundDelegationStart(event) {
|
|
20575
|
-
const turnId = this.#ensureBackgroundTurn();
|
|
20576
|
-
const description = event.type === "subagent.started" ? event.description : event.type === "subagent.updated" ? event.description ?? "Background subagent" : "Background subagent";
|
|
20577
|
-
const role = event.type === "subagent.started" ? event.role : void 0;
|
|
20578
|
-
const background = event.type === "subagent.started" ? event.background : true;
|
|
20579
|
-
const state = {
|
|
20580
|
-
subagentId: event.nativeSubagentId,
|
|
20581
|
-
nativeSubagentId: event.nativeSubagentId,
|
|
20582
|
-
description,
|
|
20583
|
-
...role ? { role } : {},
|
|
20584
|
-
background,
|
|
20585
|
-
status: "running"
|
|
20586
|
-
};
|
|
20587
|
-
const item = {
|
|
20588
|
-
type: "subagentDelegation",
|
|
20589
|
-
itemId: this.#newItemId(),
|
|
20590
|
-
operation: "spawn",
|
|
20591
|
-
...event.type === "subagent.started" && event.prompt ? { prompt: event.prompt } : {},
|
|
20592
|
-
subagents: [state]
|
|
20593
|
-
};
|
|
20594
|
-
const delegation = { item, turnId };
|
|
20595
|
-
this.#backgroundSubagents.set(event.callId, delegation);
|
|
20596
|
-
this.#event({ type: "item.started", turnId, item });
|
|
20597
|
-
return delegation;
|
|
20598
|
-
}
|
|
20599
20783
|
#handleBackgroundSubagentEvent(event) {
|
|
20600
20784
|
if (event.type === "subagent.transcript.changed") {
|
|
20601
20785
|
this.#event({
|
|
@@ -20607,12 +20791,6 @@ var OmpHarnessSession = class {
|
|
|
20607
20791
|
if (event.type !== "subagent.started" && event.type !== "subagent.updated" && event.type !== "subagent.completed") {
|
|
20608
20792
|
return;
|
|
20609
20793
|
}
|
|
20610
|
-
let delegation = this.#backgroundSubagents.get(event.callId);
|
|
20611
|
-
if (!delegation)
|
|
20612
|
-
delegation = this.#backgroundDelegationStart(event);
|
|
20613
|
-
const current = delegation.item.subagents[0];
|
|
20614
|
-
if (!current)
|
|
20615
|
-
throw new Error("Omp background delegation has no Agent state");
|
|
20616
20794
|
if (event.type === "subagent.started") {
|
|
20617
20795
|
this.#event({
|
|
20618
20796
|
type: "subagent.state.changed",
|
|
@@ -20623,19 +20801,6 @@ var OmpHarnessSession = class {
|
|
|
20623
20801
|
}
|
|
20624
20802
|
if (event.type === "subagent.updated") {
|
|
20625
20803
|
const status2 = this.#backgroundStatus(event.status);
|
|
20626
|
-
const subagent2 = {
|
|
20627
|
-
...current,
|
|
20628
|
-
status: status2,
|
|
20629
|
-
...event.description ? { description: event.description } : {},
|
|
20630
|
-
...event.resultSummary ? { resultSummary: event.resultSummary } : {}
|
|
20631
|
-
};
|
|
20632
|
-
delegation.item = { ...delegation.item, subagents: [subagent2] };
|
|
20633
|
-
this.#event({
|
|
20634
|
-
type: "item.updated",
|
|
20635
|
-
turnId: delegation.turnId,
|
|
20636
|
-
itemId: delegation.item.itemId,
|
|
20637
|
-
update: { type: "subagents.replace", subagents: delegation.item.subagents }
|
|
20638
|
-
});
|
|
20639
20804
|
this.#event({
|
|
20640
20805
|
type: "subagent.state.changed",
|
|
20641
20806
|
nativeSubagentId: event.nativeSubagentId,
|
|
@@ -20645,58 +20810,12 @@ var OmpHarnessSession = class {
|
|
|
20645
20810
|
return;
|
|
20646
20811
|
}
|
|
20647
20812
|
const status = event.isError ? "failed" : "completed";
|
|
20648
|
-
const subagent = {
|
|
20649
|
-
...current,
|
|
20650
|
-
status,
|
|
20651
|
-
...event.resultSummary ? { resultSummary: event.resultSummary } : {}
|
|
20652
|
-
};
|
|
20653
|
-
delegation.item = { ...delegation.item, subagents: [subagent] };
|
|
20654
|
-
this.#event({
|
|
20655
|
-
type: "item.updated",
|
|
20656
|
-
turnId: delegation.turnId,
|
|
20657
|
-
itemId: delegation.item.itemId,
|
|
20658
|
-
update: { type: "subagents.replace", subagents: delegation.item.subagents }
|
|
20659
|
-
});
|
|
20660
|
-
this.#event({
|
|
20661
|
-
type: "item.completed",
|
|
20662
|
-
turnId: delegation.turnId,
|
|
20663
|
-
snapshot: {
|
|
20664
|
-
item: delegation.item,
|
|
20665
|
-
outcome: event.isError ? {
|
|
20666
|
-
status: "failed",
|
|
20667
|
-
error: {
|
|
20668
|
-
code: "nativeFailure",
|
|
20669
|
-
message: "Omp background Subagent failed",
|
|
20670
|
-
retryable: false
|
|
20671
|
-
}
|
|
20672
|
-
} : { status: "succeeded" }
|
|
20673
|
-
}
|
|
20674
|
-
});
|
|
20675
20813
|
this.#event({
|
|
20676
20814
|
type: "subagent.state.changed",
|
|
20677
20815
|
nativeSubagentId: event.nativeSubagentId,
|
|
20678
20816
|
status,
|
|
20679
20817
|
...event.resultSummary ? { resultSummary: event.resultSummary } : {}
|
|
20680
20818
|
});
|
|
20681
|
-
this.#backgroundTurnFailed ||= event.isError;
|
|
20682
|
-
this.#backgroundSubagents.delete(event.callId);
|
|
20683
|
-
if (this.#backgroundSubagents.size === 0 && this.#backgroundTurnId === delegation.turnId) {
|
|
20684
|
-
const turnId = this.#backgroundTurnId;
|
|
20685
|
-
this.#backgroundTurnId = null;
|
|
20686
|
-
this.#event({
|
|
20687
|
-
type: "turn.completed",
|
|
20688
|
-
turnId,
|
|
20689
|
-
outcome: this.#backgroundTurnFailed ? {
|
|
20690
|
-
status: "failed",
|
|
20691
|
-
error: {
|
|
20692
|
-
code: "nativeFailure",
|
|
20693
|
-
message: "Omp background Subagent failed",
|
|
20694
|
-
retryable: false
|
|
20695
|
-
}
|
|
20696
|
-
} : { status: "succeeded" }
|
|
20697
|
-
});
|
|
20698
|
-
this.#backgroundTurnFailed = false;
|
|
20699
|
-
}
|
|
20700
20819
|
}
|
|
20701
20820
|
async readSnapshot() {
|
|
20702
20821
|
if (this.#phase !== "open" && this.#phase !== "faulted") {
|
|
@@ -20751,6 +20870,8 @@ var OmpHarnessSession = class {
|
|
|
20751
20870
|
}
|
|
20752
20871
|
if (command.type === "turn.cancel")
|
|
20753
20872
|
return this.#cancel(command);
|
|
20873
|
+
if (command.type === "turn.steer")
|
|
20874
|
+
return unsupportedSteer("OMP");
|
|
20754
20875
|
if (command.type === "interaction.respond")
|
|
20755
20876
|
return this.#respond(command);
|
|
20756
20877
|
if (command.type === "model.select")
|
|
@@ -21946,6 +22067,9 @@ var OmpAdapter = class {
|
|
|
21946
22067
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
21947
22068
|
#inspectionInFlight = /* @__PURE__ */ new Map();
|
|
21948
22069
|
#inspections = /* @__PURE__ */ new Set();
|
|
22070
|
+
#availabilityInFlight = /* @__PURE__ */ new Map();
|
|
22071
|
+
#availabilityListings = /* @__PURE__ */ new Set();
|
|
22072
|
+
#listModels;
|
|
21949
22073
|
#sessions = /* @__PURE__ */ new Set();
|
|
21950
22074
|
#toolOutputLimit;
|
|
21951
22075
|
#closePromise = null;
|
|
@@ -21954,22 +22078,21 @@ var OmpAdapter = class {
|
|
|
21954
22078
|
createTransport: (sessionOptions) => new OmpRpcSession({ ...options, ...sessionOptions })
|
|
21955
22079
|
}) {
|
|
21956
22080
|
this.#createTransport = dependencies.createTransport;
|
|
22081
|
+
const listModels = dependencies.listModels ?? listOmpModels;
|
|
22082
|
+
this.#listModels = ({ cwd, signal }) => listModels({
|
|
22083
|
+
cwd,
|
|
22084
|
+
signal,
|
|
22085
|
+
...options.command ? { command: options.command } : {},
|
|
22086
|
+
...options.environment ? { environment: options.environment } : {}
|
|
22087
|
+
});
|
|
21957
22088
|
this.sessionImport = new OmpSessionImport({ ...process.env, ...options.environment });
|
|
21958
22089
|
this.usageStatistics = createOmpUsageStatistics({ ...process.env, ...options.environment });
|
|
21959
22090
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? 2e3;
|
|
21960
22091
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT;
|
|
21961
22092
|
}
|
|
21962
22093
|
async inspect(input = {}) {
|
|
21963
|
-
if (this.#closePromise)
|
|
21964
|
-
return
|
|
21965
|
-
status: "unavailable",
|
|
21966
|
-
error: {
|
|
21967
|
-
code: "invalidState",
|
|
21968
|
-
message: "Omp Adapter is closed",
|
|
21969
|
-
retryable: false
|
|
21970
|
-
}
|
|
21971
|
-
};
|
|
21972
|
-
}
|
|
22094
|
+
if (this.#closePromise)
|
|
22095
|
+
return closedInspection();
|
|
21973
22096
|
const cwd = input.cwd ?? process.cwd();
|
|
21974
22097
|
const inFlight = this.#inspectionInFlight.get(cwd);
|
|
21975
22098
|
if (inFlight)
|
|
@@ -21979,6 +22102,37 @@ var OmpAdapter = class {
|
|
|
21979
22102
|
if (cached2)
|
|
21980
22103
|
return cached2;
|
|
21981
22104
|
}
|
|
22105
|
+
if (input.purpose === "availability")
|
|
22106
|
+
return this.#inspectAvailability(cwd, input.refresh);
|
|
22107
|
+
return this.#startFullInspection(cwd);
|
|
22108
|
+
}
|
|
22109
|
+
/**
|
|
22110
|
+
* Availability without a Session: a Session startup runs OMP's own startup work, including
|
|
22111
|
+
* Provider connection prewarm, for a Harness the user may never select. The listed result
|
|
22112
|
+
* carries no native default Model or Thinking option, so it is neither cached nor used to
|
|
22113
|
+
* update `#thinkingSelectionSupported`. When the list cannot answer, a full inspection answers
|
|
22114
|
+
* instead, reusing one that is in flight or finished meanwhile.
|
|
22115
|
+
*/
|
|
22116
|
+
async #inspectAvailability(cwd, refresh = false) {
|
|
22117
|
+
if (refresh)
|
|
22118
|
+
this.#inspectionCache.delete(cwd);
|
|
22119
|
+
let pending = this.#availabilityInFlight.get(cwd);
|
|
22120
|
+
if (!pending) {
|
|
22121
|
+
const listing = this.#listAvailability(cwd);
|
|
22122
|
+
pending = listing.finally(() => {
|
|
22123
|
+
if (this.#availabilityInFlight.get(cwd) === pending)
|
|
22124
|
+
this.#availabilityInFlight.delete(cwd);
|
|
22125
|
+
});
|
|
22126
|
+
this.#availabilityInFlight.set(cwd, pending);
|
|
22127
|
+
}
|
|
22128
|
+
const listed = await pending;
|
|
22129
|
+
if (listed)
|
|
22130
|
+
return listed;
|
|
22131
|
+
if (this.#closePromise)
|
|
22132
|
+
return closedInspection();
|
|
22133
|
+
return this.#inspectionInFlight.get(cwd) ?? this.#inspectionCache.get(cwd) ?? this.#startFullInspection(cwd);
|
|
22134
|
+
}
|
|
22135
|
+
#startFullInspection(cwd) {
|
|
21982
22136
|
const inspection = this.#inspectCwd(cwd).then((result) => {
|
|
21983
22137
|
if (result.status === "ready")
|
|
21984
22138
|
this.#inspectionCache.set(cwd, result);
|
|
@@ -21991,6 +22145,59 @@ var OmpAdapter = class {
|
|
|
21991
22145
|
}
|
|
21992
22146
|
});
|
|
21993
22147
|
}
|
|
22148
|
+
/** Returns null when a Session must answer: this OMP cannot list Models, or lists none. */
|
|
22149
|
+
async #listAvailability(cwd) {
|
|
22150
|
+
const startedAt = Date.now();
|
|
22151
|
+
const stage = "model-list";
|
|
22152
|
+
const controller = new AbortController();
|
|
22153
|
+
this.#availabilityListings.add(controller);
|
|
22154
|
+
let listed;
|
|
22155
|
+
try {
|
|
22156
|
+
listed = await this.#listModels({ cwd, signal: controller.signal });
|
|
22157
|
+
} finally {
|
|
22158
|
+
this.#availabilityListings.delete(controller);
|
|
22159
|
+
}
|
|
22160
|
+
if (listed.kind === "unanswered")
|
|
22161
|
+
return null;
|
|
22162
|
+
if (listed.kind === "notInstalled") {
|
|
22163
|
+
return {
|
|
22164
|
+
status: "notInstalled",
|
|
22165
|
+
error: {
|
|
22166
|
+
code: "notInstalled",
|
|
22167
|
+
message: listed.message,
|
|
22168
|
+
retryable: false,
|
|
22169
|
+
stage,
|
|
22170
|
+
durationMs: Date.now() - startedAt
|
|
22171
|
+
}
|
|
22172
|
+
};
|
|
22173
|
+
}
|
|
22174
|
+
if (listed.kind === "timedOut") {
|
|
22175
|
+
return {
|
|
22176
|
+
status: "error",
|
|
22177
|
+
error: {
|
|
22178
|
+
code: "unavailable",
|
|
22179
|
+
message: "Oh My Pi did not list its models in time",
|
|
22180
|
+
retryable: true,
|
|
22181
|
+
stage,
|
|
22182
|
+
durationMs: Date.now() - startedAt
|
|
22183
|
+
}
|
|
22184
|
+
};
|
|
22185
|
+
}
|
|
22186
|
+
if (listed.models.length === 0)
|
|
22187
|
+
return null;
|
|
22188
|
+
let catalog;
|
|
22189
|
+
try {
|
|
22190
|
+
catalog = normalizeOmpModelCatalog(listed.models, null, null, null);
|
|
22191
|
+
} catch {
|
|
22192
|
+
return null;
|
|
22193
|
+
}
|
|
22194
|
+
return {
|
|
22195
|
+
status: "ready",
|
|
22196
|
+
catalog,
|
|
22197
|
+
permissionModes: OMP_PERMISSION_MODE_CATALOG,
|
|
22198
|
+
capabilities: ompInspectionCapabilities(false)
|
|
22199
|
+
};
|
|
22200
|
+
}
|
|
21994
22201
|
async #inspectCwd(cwd) {
|
|
21995
22202
|
const startedAt = Date.now();
|
|
21996
22203
|
let stage = "spawn";
|
|
@@ -22014,16 +22221,7 @@ var OmpAdapter = class {
|
|
|
22014
22221
|
status: "ready",
|
|
22015
22222
|
catalog,
|
|
22016
22223
|
permissionModes: OMP_PERMISSION_MODE_CATALOG,
|
|
22017
|
-
capabilities:
|
|
22018
|
-
configuration: {
|
|
22019
|
-
selectModel: true,
|
|
22020
|
-
selectThinkingOption: thinkingLevels !== null,
|
|
22021
|
-
selectPermissionMode: true,
|
|
22022
|
-
permissionModeScope: "live"
|
|
22023
|
-
},
|
|
22024
|
-
history: { fork: true, forkAcrossCwd: true, rollbackLastTurn: true },
|
|
22025
|
-
subagents: { observe: true, readTranscript: true }
|
|
22026
|
-
}
|
|
22224
|
+
capabilities: ompInspectionCapabilities(thinkingLevels !== null)
|
|
22027
22225
|
};
|
|
22028
22226
|
} catch (error51) {
|
|
22029
22227
|
await transport.close().catch(() => void 0);
|
|
@@ -22234,6 +22432,8 @@ var OmpAdapter = class {
|
|
|
22234
22432
|
}
|
|
22235
22433
|
close() {
|
|
22236
22434
|
if (!this.#closePromise) {
|
|
22435
|
+
for (const listing of this.#availabilityListings)
|
|
22436
|
+
listing.abort();
|
|
22237
22437
|
this.#closePromise = Promise.all([
|
|
22238
22438
|
this.sessionImport.close(),
|
|
22239
22439
|
...[...this.#inspections].map((transport) => transport.close()),
|