orion-super-agent-dev 0.1.23 → 0.1.25
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/out/brains/darwin-arm64/orion-brain +0 -0
- package/out/brains/darwin-x64/orion-brain +0 -0
- package/out/brains/linux-arm64/orion-brain +0 -0
- package/out/brains/linux-x64/orion-brain +0 -0
- package/out/brains/win32-x64/orion-brain.exe +0 -0
- package/out/main.js +1971 -981
- package/package.json +1 -1
package/out/main.js
CHANGED
|
@@ -2230,7 +2230,7 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
2230
2230
|
if (process.env.NODE_ENV !== "production") {
|
|
2231
2231
|
(function() {
|
|
2232
2232
|
"use strict";
|
|
2233
|
-
var
|
|
2233
|
+
var React33 = require_react();
|
|
2234
2234
|
var REACT_ELEMENT_TYPE = Symbol.for("react.element");
|
|
2235
2235
|
var REACT_PORTAL_TYPE = Symbol.for("react.portal");
|
|
2236
2236
|
var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
|
|
@@ -2256,7 +2256,7 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
2256
2256
|
}
|
|
2257
2257
|
return null;
|
|
2258
2258
|
}
|
|
2259
|
-
var ReactSharedInternals =
|
|
2259
|
+
var ReactSharedInternals = React33.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
2260
2260
|
function error(format2) {
|
|
2261
2261
|
{
|
|
2262
2262
|
{
|
|
@@ -9963,9 +9963,9 @@ var require_react_reconciler_development = __commonJS({
|
|
|
9963
9963
|
module2.exports = function $$$reconciler($$$hostConfig) {
|
|
9964
9964
|
var exports3 = {};
|
|
9965
9965
|
"use strict";
|
|
9966
|
-
var
|
|
9966
|
+
var React33 = require_react();
|
|
9967
9967
|
var Scheduler = require_scheduler();
|
|
9968
|
-
var ReactSharedInternals =
|
|
9968
|
+
var ReactSharedInternals = React33.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
9969
9969
|
var suppressWarning = false;
|
|
9970
9970
|
function setSuppressWarning(newSuppressWarning) {
|
|
9971
9971
|
{
|
|
@@ -29178,6 +29178,8 @@ var require_duetEntry = __commonJS({
|
|
|
29178
29178
|
}();
|
|
29179
29179
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
29180
29180
|
exports2.DUET_HANDOFF_BRIEF_MAX_CHARS = exports2.DUET_HANDOFF_CAPABILITY = exports2.DUET_HANDOFF_TOOL = exports2.DUET_ENTRY_OPTIONS = exports2.DUET_ENTRY_INFO = exports2.DUET_ENTRY_KEY = exports2.DUET_ENTRY_DEFAULT = exports2.DUET_ENTRIES = void 0;
|
|
29181
|
+
exports2.isModelRoutedEntry = isModelRoutedEntry;
|
|
29182
|
+
exports2.effectiveDuetEntry = effectiveDuetEntry;
|
|
29181
29183
|
exports2.duetEntryLabel = duetEntryLabel2;
|
|
29182
29184
|
exports2.normalizeDuetEntry = normalizeDuetEntry2;
|
|
29183
29185
|
exports2.duetHandoffBrief = duetHandoffBrief2;
|
|
@@ -29193,7 +29195,10 @@ var require_duetEntry = __commonJS({
|
|
|
29193
29195
|
var path14 = __importStar(__require("node:path"));
|
|
29194
29196
|
var atomicWrite_js_1 = require_atomicWrite();
|
|
29195
29197
|
var settingsPaths_js_1 = require_settingsPaths();
|
|
29196
|
-
exports2.DUET_ENTRIES = ["planner", "router"];
|
|
29198
|
+
exports2.DUET_ENTRIES = ["planner", "router", "executor"];
|
|
29199
|
+
function isModelRoutedEntry(entry) {
|
|
29200
|
+
return entry === "router" || entry === "executor";
|
|
29201
|
+
}
|
|
29197
29202
|
exports2.DUET_ENTRY_DEFAULT = "planner";
|
|
29198
29203
|
exports2.DUET_ENTRY_KEY = "duetEntry";
|
|
29199
29204
|
exports2.DUET_ENTRY_INFO = {
|
|
@@ -29213,8 +29218,18 @@ var require_duetEntry = __commonJS({
|
|
|
29213
29218
|
value: "router",
|
|
29214
29219
|
label: "Router decides",
|
|
29215
29220
|
description: "Local model routes. No planner call."
|
|
29221
|
+
},
|
|
29222
|
+
{
|
|
29223
|
+
value: "executor",
|
|
29224
|
+
label: "Executor decides",
|
|
29225
|
+
description: "Your executor routes. No planner call, no download."
|
|
29216
29226
|
}
|
|
29217
29227
|
];
|
|
29228
|
+
function effectiveDuetEntry(setting, routerState) {
|
|
29229
|
+
if (setting === "router" && routerState !== "ready")
|
|
29230
|
+
return { entry: "planner", downgraded: true };
|
|
29231
|
+
return { entry: setting, downgraded: false };
|
|
29232
|
+
}
|
|
29218
29233
|
function duetEntryLabel2(entry) {
|
|
29219
29234
|
return exports2.DUET_ENTRY_OPTIONS.find((option) => option.value === entry)?.label ?? entry;
|
|
29220
29235
|
}
|
|
@@ -29222,7 +29237,7 @@ var require_duetEntry = __commonJS({
|
|
|
29222
29237
|
if (typeof raw !== "string")
|
|
29223
29238
|
return null;
|
|
29224
29239
|
const value = raw.trim();
|
|
29225
|
-
return value === "planner" || value === "router" ? value : null;
|
|
29240
|
+
return value === "planner" || value === "router" || value === "executor" ? value : null;
|
|
29226
29241
|
}
|
|
29227
29242
|
exports2.DUET_HANDOFF_TOOL = "hand_off";
|
|
29228
29243
|
exports2.DUET_HANDOFF_CAPABILITY = "duet_handoff";
|
|
@@ -29345,6 +29360,67 @@ var require_duetEntry = __commonJS({
|
|
|
29345
29360
|
}
|
|
29346
29361
|
});
|
|
29347
29362
|
|
|
29363
|
+
// ../packages/orion-client-core/dist/duetExecutorGateStatus.js
|
|
29364
|
+
var require_duetExecutorGateStatus = __commonJS({
|
|
29365
|
+
"../packages/orion-client-core/dist/duetExecutorGateStatus.js"(exports2) {
|
|
29366
|
+
"use strict";
|
|
29367
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
29368
|
+
exports2.executorGateStatusLine = executorGateStatusLine2;
|
|
29369
|
+
exports2.executorGateFallbackNote = executorGateFallbackNote;
|
|
29370
|
+
exports2.executorGateOptionAvailability = executorGateOptionAvailability;
|
|
29371
|
+
function unavailableWhy(reason, problem) {
|
|
29372
|
+
switch (reason) {
|
|
29373
|
+
case "not_resolved":
|
|
29374
|
+
return "its endpoint is not configured";
|
|
29375
|
+
case "unreachable":
|
|
29376
|
+
return "it is not answering";
|
|
29377
|
+
case "no_completions":
|
|
29378
|
+
return "it has no /v1/completions route";
|
|
29379
|
+
case "thinking":
|
|
29380
|
+
return "its completions route answers thinking text, not a plain token";
|
|
29381
|
+
case "unparseable":
|
|
29382
|
+
return "it did not answer E or P";
|
|
29383
|
+
case "error":
|
|
29384
|
+
return `the gate call failed (${problem})`;
|
|
29385
|
+
}
|
|
29386
|
+
}
|
|
29387
|
+
function executorGateStatusLine2(status) {
|
|
29388
|
+
switch (status.state) {
|
|
29389
|
+
case "ready":
|
|
29390
|
+
return `Executor gate: ${status.target.model} on '${status.target.name}' \xB7 ${status.mode} \xB7 threshold ${status.threshold} \xB7 ${status.calibration.passed}/${status.calibration.total} scenarios \xB7 ready`;
|
|
29391
|
+
case "miscalibrated":
|
|
29392
|
+
return `Executor gate: ${status.target.model} on '${status.target.name}' misrouted ${status.calibration.failed.length} of ${status.calibration.total} probe scenarios (${status.mode}, threshold ${status.threshold}) \u2014 tune executorGate.threshold on that endpoint.`;
|
|
29393
|
+
case "platform":
|
|
29394
|
+
return "Executor gate: the Duet executor is a platform model \u2014 this entry routes on Duet's rules.";
|
|
29395
|
+
case "unavailable":
|
|
29396
|
+
return `Executor gate: not asking \u2014 ${unavailableWhy(status.reason, status.problem)}.`;
|
|
29397
|
+
}
|
|
29398
|
+
}
|
|
29399
|
+
function executorGateFallbackNote(status) {
|
|
29400
|
+
const why = status.state === "platform" ? "the Duet executor is a platform model" : status.state === "unavailable" ? unavailableWhy(status.reason, status.problem) : "it could not run";
|
|
29401
|
+
return `Executor decides could not ask your executor (${why}) \u2014 this turn routed on Duet's rules instead.`;
|
|
29402
|
+
}
|
|
29403
|
+
function executorGateOptionAvailability(status) {
|
|
29404
|
+
if (status === null || status.state === "ready")
|
|
29405
|
+
return { disabled: false, note: null };
|
|
29406
|
+
switch (status.state) {
|
|
29407
|
+
case "platform":
|
|
29408
|
+
return { disabled: false, note: "The executor is a platform model \u2014 routes on Duet's rules." };
|
|
29409
|
+
case "miscalibrated":
|
|
29410
|
+
return {
|
|
29411
|
+
disabled: false,
|
|
29412
|
+
note: `The gate misrouted ${status.calibration.failed.length} of ${status.calibration.total} probe scenarios \u2014 tune executorGate.threshold on that endpoint.`
|
|
29413
|
+
};
|
|
29414
|
+
case "unavailable":
|
|
29415
|
+
return {
|
|
29416
|
+
disabled: false,
|
|
29417
|
+
note: `The executor cannot be asked right now (${unavailableWhy(status.reason, status.problem)}) \u2014 routes on Duet's rules.`
|
|
29418
|
+
};
|
|
29419
|
+
}
|
|
29420
|
+
}
|
|
29421
|
+
}
|
|
29422
|
+
});
|
|
29423
|
+
|
|
29348
29424
|
// ../packages/orion-client-core/dist/duetRouterModel.js
|
|
29349
29425
|
var require_duetRouterModel = __commonJS({
|
|
29350
29426
|
"../packages/orion-client-core/dist/duetRouterModel.js"(exports2) {
|
|
@@ -29400,7 +29476,6 @@ var require_duetRouterModel = __commonJS({
|
|
|
29400
29476
|
exports2.classifyWithHeads = classifyWithHeads;
|
|
29401
29477
|
exports2.createDuetRouter = createDuetRouter;
|
|
29402
29478
|
exports2.createTransformersDuetRouterEncoder = createTransformersDuetRouterEncoder;
|
|
29403
|
-
exports2.effectiveDuetEntry = effectiveDuetEntry;
|
|
29404
29479
|
exports2.duetRouterDisplayName = duetRouterDisplayName2;
|
|
29405
29480
|
exports2.duetRouterStatusLine = duetRouterStatusLine2;
|
|
29406
29481
|
exports2.duetRouterDowngradeNote = duetRouterDowngradeNote;
|
|
@@ -29412,6 +29487,8 @@ var require_duetRouterModel = __commonJS({
|
|
|
29412
29487
|
var fs15 = __importStar(__require("node:fs/promises"));
|
|
29413
29488
|
var os9 = __importStar(__require("node:os"));
|
|
29414
29489
|
var path14 = __importStar(__require("node:path"));
|
|
29490
|
+
var duetEntry_js_1 = require_duetEntry();
|
|
29491
|
+
var duetExecutorGateStatus_js_1 = require_duetExecutorGateStatus();
|
|
29415
29492
|
exports2.DUET_ROUTER_WIRE_KEY = "duet_router";
|
|
29416
29493
|
exports2.DUET_ROUTER_BUNDLE_FORMAT = "orion-router-bundle.v1";
|
|
29417
29494
|
exports2.DUET_ROUTER_MODEL_ID = "orion/orion-pe-router-1.0";
|
|
@@ -29425,13 +29502,16 @@ var require_duetRouterModel = __commonJS({
|
|
|
29425
29502
|
];
|
|
29426
29503
|
function duetRouterWireForSegment(verdict) {
|
|
29427
29504
|
return {
|
|
29505
|
+
source: verdict.source,
|
|
29428
29506
|
model: verdict.model,
|
|
29429
29507
|
version: verdict.version,
|
|
29430
29508
|
verdict: verdict.verdict,
|
|
29431
29509
|
p_plan: round6(verdict.pPlan),
|
|
29432
29510
|
asks_for_plan: verdict.asksForPlan,
|
|
29433
29511
|
high_risk: verdict.highRisk,
|
|
29434
|
-
reason: verdict.reason
|
|
29512
|
+
reason: verdict.reason,
|
|
29513
|
+
...verdict.margin !== void 0 ? { margin: round6(verdict.margin) } : {},
|
|
29514
|
+
...verdict.mode !== void 0 ? { mode: verdict.mode } : {}
|
|
29435
29515
|
};
|
|
29436
29516
|
}
|
|
29437
29517
|
function orionModelsDir(homeDir = os9.homedir()) {
|
|
@@ -29662,6 +29742,7 @@ var require_duetRouterModel = __commonJS({
|
|
|
29662
29742
|
if (!vector)
|
|
29663
29743
|
throw new Error("router encoder returned no vector");
|
|
29664
29744
|
return {
|
|
29745
|
+
source: "orion_router",
|
|
29665
29746
|
...classifyWithHeads(vector, bundle),
|
|
29666
29747
|
model: bundle.name,
|
|
29667
29748
|
version: bundle.version,
|
|
@@ -29731,11 +29812,6 @@ var require_duetRouterModel = __commonJS({
|
|
|
29731
29812
|
}
|
|
29732
29813
|
};
|
|
29733
29814
|
}
|
|
29734
|
-
function effectiveDuetEntry(setting, routerState) {
|
|
29735
|
-
if (setting === "router" && routerState !== "ready")
|
|
29736
|
-
return { entry: "planner", downgraded: true };
|
|
29737
|
-
return { entry: setting, downgraded: false };
|
|
29738
|
-
}
|
|
29739
29815
|
function duetRouterDisplayName2(name2, version) {
|
|
29740
29816
|
const trimmed = name2.trim();
|
|
29741
29817
|
const v2 = version.trim();
|
|
@@ -29757,7 +29833,9 @@ var require_duetRouterModel = __commonJS({
|
|
|
29757
29833
|
const why = status.state === "missing" ? "it is not installed" : status.state === "invalid" ? `it is unusable (${status.problem})` : `it failed to load${"problem" in status && status.problem ? ` (${status.problem})` : ""}`;
|
|
29758
29834
|
return `Router decides needs the Orion router model and ${why} \u2014 this turn ran through the planner instead.`;
|
|
29759
29835
|
}
|
|
29760
|
-
function duetEntryOptionAvailability2(entry, status) {
|
|
29836
|
+
function duetEntryOptionAvailability2(entry, status, executorStatus = null) {
|
|
29837
|
+
if (entry === "executor")
|
|
29838
|
+
return (0, duetExecutorGateStatus_js_1.executorGateOptionAvailability)(executorStatus);
|
|
29761
29839
|
if (entry !== "router" || status === null || status.state === "ready")
|
|
29762
29840
|
return { disabled: false, note: null };
|
|
29763
29841
|
return {
|
|
@@ -29797,6 +29875,7 @@ var require_duetRouterModel = __commonJS({
|
|
|
29797
29875
|
let router = null;
|
|
29798
29876
|
let building = null;
|
|
29799
29877
|
let noted = false;
|
|
29878
|
+
let executorNoted = false;
|
|
29800
29879
|
const status = async (o = {}) => {
|
|
29801
29880
|
const now2 = Date.now();
|
|
29802
29881
|
if (!o.refresh && cached !== null && now2 - cached.at < exports2.DUET_ROUTER_STATUS_TTL_MS)
|
|
@@ -29808,11 +29887,18 @@ var require_duetRouterModel = __commonJS({
|
|
|
29808
29887
|
const downgrade = (why) => {
|
|
29809
29888
|
const note = noted ? null : duetRouterDowngradeNote(why);
|
|
29810
29889
|
noted = true;
|
|
29811
|
-
return { ...effectiveDuetEntry("router", why.state), verdict: null, note };
|
|
29890
|
+
return { ...(0, duetEntry_js_1.effectiveDuetEntry)("router", why.state), verdict: null, note };
|
|
29812
29891
|
};
|
|
29813
29892
|
return {
|
|
29814
29893
|
status,
|
|
29815
|
-
async prepareTurn(setting, text) {
|
|
29894
|
+
async prepareTurn(setting, text, ctx = {}) {
|
|
29895
|
+
if (setting === "executor") {
|
|
29896
|
+
if (opts.executorGate !== void 0)
|
|
29897
|
+
return opts.executorGate.prepareTurn(text, ctx);
|
|
29898
|
+
const note = executorNoted ? null : (0, duetExecutorGateStatus_js_1.executorGateFallbackNote)({ state: "unavailable", reason: "error", problem: "this host has no executor gate" });
|
|
29899
|
+
executorNoted = true;
|
|
29900
|
+
return { entry: "executor", verdict: null, note };
|
|
29901
|
+
}
|
|
29816
29902
|
if (setting !== "router")
|
|
29817
29903
|
return { entry: setting, verdict: null, note: null };
|
|
29818
29904
|
if (text.trim() === "")
|
|
@@ -29846,6 +29932,8 @@ var require_duetRouterModel = __commonJS({
|
|
|
29846
29932
|
invalidate() {
|
|
29847
29933
|
cached = null;
|
|
29848
29934
|
noted = false;
|
|
29935
|
+
executorNoted = false;
|
|
29936
|
+
opts.executorGate?.invalidate();
|
|
29849
29937
|
const live = router;
|
|
29850
29938
|
router = null;
|
|
29851
29939
|
building = null;
|
|
@@ -30164,6 +30252,7 @@ var require_duetPlan = __commonJS({
|
|
|
30164
30252
|
exports2.duetReplanFollowupPrompt = duetReplanFollowupPrompt2;
|
|
30165
30253
|
exports2.recordDuetTurnOutcome = recordDuetTurnOutcome;
|
|
30166
30254
|
exports2.foldDuetTurnEnd = foldDuetTurnEnd2;
|
|
30255
|
+
var duetEntry_js_1 = require_duetEntry();
|
|
30167
30256
|
exports2.DUET_PLAN_MAX_LEN = 65536;
|
|
30168
30257
|
exports2.DUET_PLAN_MAX_VERSION = 1e4;
|
|
30169
30258
|
exports2.DUET_PLAN_GRANTS = ["default", "workspace_write"];
|
|
@@ -30306,7 +30395,7 @@ var require_duetPlan = __commonJS({
|
|
|
30306
30395
|
return false;
|
|
30307
30396
|
const noPlan = duetPlanWireForSegment(record) === void 0;
|
|
30308
30397
|
if (noPlan) {
|
|
30309
|
-
if (
|
|
30398
|
+
if (!(0, duetEntry_js_1.isModelRoutedEntry)(entry))
|
|
30310
30399
|
return false;
|
|
30311
30400
|
if (highRiskRequest(text))
|
|
30312
30401
|
return false;
|
|
@@ -30320,7 +30409,7 @@ var require_duetPlan = __commonJS({
|
|
|
30320
30409
|
return false;
|
|
30321
30410
|
if (record.userNegativeFeedback)
|
|
30322
30411
|
return false;
|
|
30323
|
-
if (
|
|
30412
|
+
if (!(0, duetEntry_js_1.isModelRoutedEntry)(entry))
|
|
30324
30413
|
return continuationRequest(text);
|
|
30325
30414
|
return verdict ? verdict.verdict === "execute" : true;
|
|
30326
30415
|
}
|
|
@@ -33386,6 +33475,8 @@ var require_segmentDriver = __commonJS({
|
|
|
33386
33475
|
body2.workspace_root = routing.workspaceRoot;
|
|
33387
33476
|
if (routing.clientType !== void 0)
|
|
33388
33477
|
body2.client_type = routing.clientType;
|
|
33478
|
+
if (routing.clientVersion !== void 0)
|
|
33479
|
+
body2.client_version = routing.clientVersion;
|
|
33389
33480
|
if (routing.mode !== void 0)
|
|
33390
33481
|
body2.mode = routing.mode;
|
|
33391
33482
|
if (routing.reasoning !== void 0)
|
|
@@ -34679,7 +34770,10 @@ var require_frames = __commonJS({
|
|
|
34679
34770
|
if (typeof frame.id !== "string") {
|
|
34680
34771
|
throw new FrameDecodeError("malformed renew_bearer frame");
|
|
34681
34772
|
}
|
|
34682
|
-
|
|
34773
|
+
const decoded = { type: "renew_bearer", id: frame.id };
|
|
34774
|
+
if (typeof frame.refused === "string")
|
|
34775
|
+
decoded.refused = frame.refused;
|
|
34776
|
+
return decoded;
|
|
34683
34777
|
}
|
|
34684
34778
|
case "rpc_result": {
|
|
34685
34779
|
if (typeof frame.id !== "string" || !("result" in frame)) {
|
|
@@ -35269,11 +35363,12 @@ var require_customProviders = __commonJS({
|
|
|
35269
35363
|
};
|
|
35270
35364
|
}();
|
|
35271
35365
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
35272
|
-
exports2.EXECUTOR_LIVENESS_TIMEOUT_MS = exports2.EXECUTOR_LIVENESS_TTL_MS = exports2.PROBE_TIMEOUT_MS = exports2.ROUTING_MODELS_KEY = exports2.MAX_CONTEXT_WINDOW = exports2.MIN_CONTEXT_WINDOW = void 0;
|
|
35366
|
+
exports2.EXECUTOR_LIVENESS_TIMEOUT_MS = exports2.EXECUTOR_LIVENESS_TTL_MS = exports2.PROBE_TIMEOUT_MS = exports2.EXECUTOR_GATE_THRESHOLD_BOUND = exports2.EXECUTOR_GATE_DEFAULT_THRESHOLD = exports2.EXECUTOR_GATE_KEY = exports2.ROUTING_MODELS_KEY = exports2.MAX_CONTEXT_WINDOW = exports2.MIN_CONTEXT_WINDOW = void 0;
|
|
35273
35367
|
exports2.customProviderSettingsPath = customProviderSettingsPath;
|
|
35274
35368
|
exports2.clampContextWindow = clampContextWindow;
|
|
35275
35369
|
exports2.normalizeModelConfig = normalizeModelConfig;
|
|
35276
35370
|
exports2.normalizeRoutingModels = normalizeRoutingModels;
|
|
35371
|
+
exports2.normalizeExecutorGate = normalizeExecutorGate;
|
|
35277
35372
|
exports2.loadCustomProviders = loadCustomProviders3;
|
|
35278
35373
|
exports2.getCustomProvider = getCustomProvider2;
|
|
35279
35374
|
exports2.saveCustomProvider = saveCustomProvider3;
|
|
@@ -35303,6 +35398,9 @@ var require_customProviders = __commonJS({
|
|
|
35303
35398
|
exports2.MIN_CONTEXT_WINDOW = 1024;
|
|
35304
35399
|
exports2.MAX_CONTEXT_WINDOW = 2e6;
|
|
35305
35400
|
exports2.ROUTING_MODELS_KEY = "routingModels";
|
|
35401
|
+
exports2.EXECUTOR_GATE_KEY = "executorGate";
|
|
35402
|
+
exports2.EXECUTOR_GATE_DEFAULT_THRESHOLD = 0;
|
|
35403
|
+
exports2.EXECUTOR_GATE_THRESHOLD_BOUND = 20;
|
|
35306
35404
|
var CUSTOM_REF_PREFIX = "custom:";
|
|
35307
35405
|
var FILE_TIERS = ["user", "project", "local"];
|
|
35308
35406
|
function customProviderSettingsPath(tier, opts = {}) {
|
|
@@ -35372,6 +35470,16 @@ var require_customProviders = __commonJS({
|
|
|
35372
35470
|
}
|
|
35373
35471
|
return Object.keys(out2).length > 0 ? out2 : void 0;
|
|
35374
35472
|
}
|
|
35473
|
+
function normalizeExecutorGate(raw) {
|
|
35474
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
35475
|
+
return void 0;
|
|
35476
|
+
const threshold = raw.threshold;
|
|
35477
|
+
if (typeof threshold !== "number" || !Number.isFinite(threshold))
|
|
35478
|
+
return void 0;
|
|
35479
|
+
return {
|
|
35480
|
+
threshold: Math.max(-exports2.EXECUTOR_GATE_THRESHOLD_BOUND, Math.min(exports2.EXECUTOR_GATE_THRESHOLD_BOUND, threshold))
|
|
35481
|
+
};
|
|
35482
|
+
}
|
|
35375
35483
|
function toEntry(name2, raw) {
|
|
35376
35484
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
35377
35485
|
return null;
|
|
@@ -35397,6 +35505,9 @@ var require_customProviders = __commonJS({
|
|
|
35397
35505
|
const routingModels = normalizeRoutingModels(value[exports2.ROUTING_MODELS_KEY]);
|
|
35398
35506
|
if (routingModels !== void 0)
|
|
35399
35507
|
entry.routingModels = routingModels;
|
|
35508
|
+
const executorGate = normalizeExecutorGate(value[exports2.EXECUTOR_GATE_KEY]);
|
|
35509
|
+
if (executorGate !== void 0)
|
|
35510
|
+
entry.executorGate = executorGate;
|
|
35400
35511
|
return entry;
|
|
35401
35512
|
}
|
|
35402
35513
|
async function readTier(tier, opts) {
|
|
@@ -35667,7 +35778,8 @@ var require_customProviders = __commonJS({
|
|
|
35667
35778
|
// keyless is valid — local servers ignore auth
|
|
35668
35779
|
wire: entry.wire,
|
|
35669
35780
|
...entry.modelConfig ? { modelConfig: entry.modelConfig } : {},
|
|
35670
|
-
...entry.routingModels ? { routingModels: entry.routingModels } : {}
|
|
35781
|
+
...entry.routingModels ? { routingModels: entry.routingModels } : {},
|
|
35782
|
+
...entry.executorGate ? { executorGate: entry.executorGate } : {}
|
|
35671
35783
|
};
|
|
35672
35784
|
routingByRef.set(provider, routing);
|
|
35673
35785
|
while (routingByRef.size > ROUTING_CACHE_MAX) {
|
|
@@ -35783,6 +35895,7 @@ var require_customProviders = __commonJS({
|
|
|
35783
35895
|
const wire = { ...routing };
|
|
35784
35896
|
delete wire.modelConfig;
|
|
35785
35897
|
delete wire.routingModels;
|
|
35898
|
+
delete wire.executorGate;
|
|
35786
35899
|
const declared = routing.modelConfig?.[modelId];
|
|
35787
35900
|
if (declared === void 0)
|
|
35788
35901
|
return wire;
|
|
@@ -36018,75 +36131,9 @@ var require_duetRouterInstall = __commonJS({
|
|
|
36018
36131
|
}
|
|
36019
36132
|
});
|
|
36020
36133
|
|
|
36021
|
-
// ../packages/orion-client-core/dist/
|
|
36022
|
-
var
|
|
36023
|
-
"../packages/orion-client-core/dist/
|
|
36024
|
-
"use strict";
|
|
36025
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
36026
|
-
exports2.mintRunId = mintRunId;
|
|
36027
|
-
exports2.runsRootFor = runsRootFor2;
|
|
36028
|
-
exports2.readJsonFile = readJsonFile;
|
|
36029
|
-
exports2.writeJsonFile = writeJsonFile;
|
|
36030
|
-
exports2.ensureDirFor = ensureDirFor;
|
|
36031
|
-
exports2.listDirNames = listDirNames;
|
|
36032
|
-
exports2.dayKey = dayKey;
|
|
36033
|
-
exports2.clipTail = clipTail;
|
|
36034
|
-
var fs_1 = __require("fs");
|
|
36035
|
-
var os_1 = __require("os");
|
|
36036
|
-
var path_1 = __require("path");
|
|
36037
|
-
var atomicWrite_js_1 = require_atomicWrite();
|
|
36038
|
-
var experienceStore_js_1 = require_experienceStore();
|
|
36039
|
-
var ID_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
36040
|
-
var ID_SUFFIX_LEN = 6;
|
|
36041
|
-
function mintRunId(prefix, nowMs = Date.now(), rand = Math.random) {
|
|
36042
|
-
let suffix = "";
|
|
36043
|
-
for (let i2 = 0; i2 < ID_SUFFIX_LEN; i2 += 1) {
|
|
36044
|
-
suffix += ID_ALPHABET[Math.floor(rand() * ID_ALPHABET.length) % ID_ALPHABET.length];
|
|
36045
|
-
}
|
|
36046
|
-
return `${prefix}_${String(nowMs).padStart(13, "0")}_${suffix}`;
|
|
36047
|
-
}
|
|
36048
|
-
function runsRootFor2(kind, workspaceRoot, home = (0, os_1.homedir)()) {
|
|
36049
|
-
return (0, path_1.join)((0, experienceStore_js_1.projectDirFor)(workspaceRoot, home), "runs", kind);
|
|
36050
|
-
}
|
|
36051
|
-
async function readJsonFile(path14) {
|
|
36052
|
-
try {
|
|
36053
|
-
const raw = await fs_1.promises.readFile(path14, "utf8");
|
|
36054
|
-
return JSON.parse(raw);
|
|
36055
|
-
} catch {
|
|
36056
|
-
return null;
|
|
36057
|
-
}
|
|
36058
|
-
}
|
|
36059
|
-
async function writeJsonFile(path14, value) {
|
|
36060
|
-
await ensureDirFor(path14);
|
|
36061
|
-
await (0, atomicWrite_js_1.atomicWriteFile)(path14, JSON.stringify(value, null, 2));
|
|
36062
|
-
}
|
|
36063
|
-
async function ensureDirFor(path14) {
|
|
36064
|
-
await fs_1.promises.mkdir((0, path_1.dirname)(path14), { recursive: true });
|
|
36065
|
-
}
|
|
36066
|
-
async function listDirNames(path14) {
|
|
36067
|
-
try {
|
|
36068
|
-
return await fs_1.promises.readdir(path14);
|
|
36069
|
-
} catch {
|
|
36070
|
-
return [];
|
|
36071
|
-
}
|
|
36072
|
-
}
|
|
36073
|
-
function dayKey(nowMs = Date.now()) {
|
|
36074
|
-
const d2 = new Date(nowMs);
|
|
36075
|
-
const month = `${d2.getMonth() + 1}`.padStart(2, "0");
|
|
36076
|
-
const day = `${d2.getDate()}`.padStart(2, "0");
|
|
36077
|
-
return `${d2.getFullYear()}-${month}-${day}`;
|
|
36078
|
-
}
|
|
36079
|
-
function clipTail(text, max) {
|
|
36080
|
-
if (text.length <= max)
|
|
36081
|
-
return text;
|
|
36082
|
-
return `\u2026${text.slice(text.length - (max - 1))}`;
|
|
36083
|
-
}
|
|
36084
|
-
}
|
|
36085
|
-
});
|
|
36086
|
-
|
|
36087
|
-
// ../packages/orion-client-core/dist/customProviderModels.js
|
|
36088
|
-
var require_customProviderModels = __commonJS({
|
|
36089
|
-
"../packages/orion-client-core/dist/customProviderModels.js"(exports2) {
|
|
36134
|
+
// ../packages/orion-client-core/dist/duetRoutingLog.js
|
|
36135
|
+
var require_duetRoutingLog = __commonJS({
|
|
36136
|
+
"../packages/orion-client-core/dist/duetRoutingLog.js"(exports2) {
|
|
36090
36137
|
"use strict";
|
|
36091
36138
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
36092
36139
|
if (k2 === void 0) k2 = k;
|
|
@@ -36126,289 +36173,238 @@ var require_customProviderModels = __commonJS({
|
|
|
36126
36173
|
};
|
|
36127
36174
|
}();
|
|
36128
36175
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
36129
|
-
exports2.
|
|
36130
|
-
exports2.
|
|
36131
|
-
exports2.
|
|
36132
|
-
exports2.
|
|
36133
|
-
exports2.
|
|
36134
|
-
exports2.
|
|
36135
|
-
exports2.
|
|
36136
|
-
exports2.
|
|
36137
|
-
exports2.
|
|
36176
|
+
exports2.DUET_ROUTING_LOG_DEFAULT_MODE = exports2.DUET_ROUTING_LOG_KEY = exports2.DUET_ROUTING_LOG_HEAD_CHARS = exports2.DUET_ROUTING_LOG_MAX_BYTES = exports2.DUET_ROUTING_LOG_SCHEMA = void 0;
|
|
36177
|
+
exports2.duetRoutingLogPath = duetRoutingLogPath2;
|
|
36178
|
+
exports2.newDecisionId = newDecisionId;
|
|
36179
|
+
exports2.sessionKey = sessionKey;
|
|
36180
|
+
exports2.lexicalSimilarity = lexicalSimilarity;
|
|
36181
|
+
exports2.planDiffRatio = planDiffRatio;
|
|
36182
|
+
exports2.clearDuetRoutingLogCache = clearDuetRoutingLogCache;
|
|
36183
|
+
exports2.duetRoutingLogMode = duetRoutingLogMode2;
|
|
36184
|
+
exports2.redactRowForMode = redactRowForMode;
|
|
36185
|
+
exports2.appendDuetRoutingRow = appendDuetRoutingRow;
|
|
36186
|
+
exports2.readDuetRoutingLog = readDuetRoutingLog2;
|
|
36187
|
+
exports2.summarizeDuetRoutingLog = summarizeDuetRoutingLog2;
|
|
36188
|
+
exports2.formatDuetRoutingLogSummary = formatDuetRoutingLogSummary2;
|
|
36138
36189
|
var node_crypto_1 = __require("node:crypto");
|
|
36190
|
+
var fs15 = __importStar(__require("node:fs/promises"));
|
|
36139
36191
|
var os9 = __importStar(__require("node:os"));
|
|
36140
36192
|
var path14 = __importStar(__require("node:path"));
|
|
36141
|
-
var
|
|
36142
|
-
|
|
36143
|
-
exports2.
|
|
36144
|
-
exports2.
|
|
36145
|
-
exports2.
|
|
36146
|
-
|
|
36147
|
-
|
|
36148
|
-
return path14.join(homeDir, ".orion", "
|
|
36193
|
+
var settingsPaths_js_1 = require_settingsPaths();
|
|
36194
|
+
exports2.DUET_ROUTING_LOG_SCHEMA = 3;
|
|
36195
|
+
exports2.DUET_ROUTING_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
36196
|
+
exports2.DUET_ROUTING_LOG_HEAD_CHARS = 200;
|
|
36197
|
+
exports2.DUET_ROUTING_LOG_KEY = "duetRoutingLog";
|
|
36198
|
+
exports2.DUET_ROUTING_LOG_DEFAULT_MODE = "full";
|
|
36199
|
+
function duetRoutingLogPath2(opts = {}) {
|
|
36200
|
+
return path14.join(opts.homeDir ?? os9.homedir(), ".orion", "duet-routing-decisions.jsonl");
|
|
36149
36201
|
}
|
|
36150
|
-
function
|
|
36151
|
-
return
|
|
36202
|
+
function newDecisionId() {
|
|
36203
|
+
return (0, node_crypto_1.randomUUID)();
|
|
36152
36204
|
}
|
|
36153
|
-
|
|
36154
|
-
|
|
36155
|
-
|
|
36156
|
-
|
|
36157
|
-
if (record.version !== exports2.CATALOG_SCHEMA_VERSION)
|
|
36158
|
-
return null;
|
|
36159
|
-
if (normalizeBaseUrl(record.baseUrl ?? "") !== normalizeBaseUrl(baseUrl))
|
|
36160
|
-
return null;
|
|
36161
|
-
if (!Array.isArray(record.models))
|
|
36162
|
-
return null;
|
|
36163
|
-
return record;
|
|
36205
|
+
function sessionKey(sessionId) {
|
|
36206
|
+
if (sessionId === void 0 || sessionId === "")
|
|
36207
|
+
return void 0;
|
|
36208
|
+
return (0, node_crypto_1.createHash)("sha256").update(sessionId).digest("hex").slice(0, 12);
|
|
36164
36209
|
}
|
|
36165
|
-
|
|
36166
|
-
|
|
36167
|
-
if (sweptThisProcess)
|
|
36168
|
-
return;
|
|
36169
|
-
sweptThisProcess = true;
|
|
36170
|
-
try {
|
|
36171
|
-
const dir = path14.dirname(catalogPathFor("x", homeDir));
|
|
36172
|
-
const fs15 = await Promise.resolve().then(() => __importStar(__require("node:fs/promises")));
|
|
36173
|
-
for (const name2 of await fs15.readdir(dir)) {
|
|
36174
|
-
if (!name2.endsWith(".json"))
|
|
36175
|
-
continue;
|
|
36176
|
-
const file = path14.join(dir, name2);
|
|
36177
|
-
try {
|
|
36178
|
-
const record = await (0, common_1.readJsonFile)(file);
|
|
36179
|
-
const age = typeof record?.fetchedAt === "number" ? now2 - record.fetchedAt : now2 - (await fs15.stat(file)).mtimeMs;
|
|
36180
|
-
if (age > exports2.CATALOG_GC_MS)
|
|
36181
|
-
await fs15.rm(file, { force: true });
|
|
36182
|
-
} catch {
|
|
36183
|
-
}
|
|
36184
|
-
}
|
|
36185
|
-
} catch {
|
|
36186
|
-
}
|
|
36210
|
+
function tokens(text) {
|
|
36211
|
+
return new Set(text.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 1));
|
|
36187
36212
|
}
|
|
36188
|
-
|
|
36189
|
-
|
|
36190
|
-
|
|
36191
|
-
|
|
36192
|
-
|
|
36193
|
-
|
|
36213
|
+
function jaccard(a, b2) {
|
|
36214
|
+
if (a.size === 0 && b2.size === 0)
|
|
36215
|
+
return 1;
|
|
36216
|
+
let inter = 0;
|
|
36217
|
+
for (const t of a)
|
|
36218
|
+
if (b2.has(t))
|
|
36219
|
+
inter += 1;
|
|
36220
|
+
const union = a.size + b2.size - inter;
|
|
36221
|
+
return union === 0 ? 0 : inter / union;
|
|
36194
36222
|
}
|
|
36195
|
-
|
|
36196
|
-
|
|
36197
|
-
function depsWith(deps2) {
|
|
36198
|
-
return {
|
|
36199
|
-
now: deps2.now ?? (() => Date.now()),
|
|
36200
|
-
probe: deps2.probe ?? customProviders_1.probeModels,
|
|
36201
|
-
readRecord: deps2.readRecord ?? readRecordFromDisk,
|
|
36202
|
-
writeRecord: deps2.writeRecord ?? writeRecordToDisk
|
|
36203
|
-
};
|
|
36223
|
+
function lexicalSimilarity(a, b2) {
|
|
36224
|
+
return Math.round(jaccard(tokens(a), tokens(b2)) * 1e3) / 1e3;
|
|
36204
36225
|
}
|
|
36205
|
-
|
|
36206
|
-
const
|
|
36207
|
-
|
|
36208
|
-
if (existing !== void 0)
|
|
36209
|
-
return existing;
|
|
36210
|
-
const run3 = (async () => {
|
|
36211
|
-
const models = await d2.probe(entry.baseUrl, await (0, customProviders_1.resolveApiKey)(entry));
|
|
36212
|
-
if (models === null || models.length === 0)
|
|
36213
|
-
return models;
|
|
36214
|
-
const record = {
|
|
36215
|
-
version: exports2.CATALOG_SCHEMA_VERSION,
|
|
36216
|
-
baseUrl: entry.baseUrl,
|
|
36217
|
-
fetchedAt: d2.now(),
|
|
36218
|
-
models
|
|
36219
|
-
};
|
|
36220
|
-
memory.set(key, record);
|
|
36221
|
-
await d2.writeRecord(record);
|
|
36222
|
-
return models;
|
|
36223
|
-
})().finally(() => inFlight2.delete(key));
|
|
36224
|
-
inFlight2.set(key, run3);
|
|
36225
|
-
return run3;
|
|
36226
|
+
function planDiffRatio(before, after) {
|
|
36227
|
+
const lines = (plan) => new Set(plan.split(/\r?\n/).map((l3) => l3.trim()).filter((l3) => l3 !== ""));
|
|
36228
|
+
return Math.round((1 - jaccard(lines(before), lines(after))) * 1e3) / 1e3;
|
|
36226
36229
|
}
|
|
36227
|
-
|
|
36228
|
-
|
|
36229
|
-
|
|
36230
|
-
|
|
36231
|
-
if (record === null) {
|
|
36232
|
-
record = await d2.readRecord(entry.baseUrl);
|
|
36233
|
-
if (record !== null)
|
|
36234
|
-
memory.set(key, record);
|
|
36235
|
-
}
|
|
36236
|
-
if (options.cachedOnly === true)
|
|
36237
|
-
return record?.models ?? [];
|
|
36238
|
-
const fresh = record !== null && d2.now() - record.fetchedAt < exports2.CATALOG_TTL_MS;
|
|
36239
|
-
if (record !== null && fresh && options.force !== true)
|
|
36240
|
-
return record.models;
|
|
36241
|
-
if (record !== null) {
|
|
36242
|
-
void probeAndStore(entry, d2).catch(() => void 0);
|
|
36243
|
-
return record.models;
|
|
36244
|
-
}
|
|
36245
|
-
return await probeAndStore(entry, d2) ?? [];
|
|
36230
|
+
var MODE_CACHE_TTL_MS = 5e3;
|
|
36231
|
+
var modeCache = /* @__PURE__ */ new Map();
|
|
36232
|
+
function clearDuetRoutingLogCache() {
|
|
36233
|
+
modeCache.clear();
|
|
36246
36234
|
}
|
|
36247
|
-
function
|
|
36248
|
-
return
|
|
36235
|
+
function coerceMode(raw) {
|
|
36236
|
+
return raw === "full" || raw === "head" || raw === "off" ? raw : null;
|
|
36249
36237
|
}
|
|
36250
|
-
function
|
|
36251
|
-
|
|
36252
|
-
|
|
36253
|
-
|
|
36254
|
-
|
|
36255
|
-
|
|
36256
|
-
|
|
36257
|
-
|
|
36258
|
-
if (maxOutputTokens !== void 0)
|
|
36259
|
-
resolved.maxOutputTokens = maxOutputTokens;
|
|
36260
|
-
if (probed?.reasoning !== void 0)
|
|
36261
|
-
resolved.reasoning = probed.reasoning;
|
|
36262
|
-
for (const knob of ["temperature", "topP", "topK", "repetitionPenalty"]) {
|
|
36263
|
-
const value = declared?.[knob];
|
|
36264
|
-
if (typeof value === "number")
|
|
36265
|
-
resolved[knob] = value;
|
|
36238
|
+
async function readTierMode(file) {
|
|
36239
|
+
if (file === null)
|
|
36240
|
+
return null;
|
|
36241
|
+
try {
|
|
36242
|
+
const parsed = JSON.parse(await fs15.readFile(file, "utf8"));
|
|
36243
|
+
return coerceMode(parsed?.[exports2.DUET_ROUTING_LOG_KEY]?.mode);
|
|
36244
|
+
} catch {
|
|
36245
|
+
return null;
|
|
36266
36246
|
}
|
|
36267
|
-
return resolved;
|
|
36268
|
-
}
|
|
36269
|
-
function catalogModelIds2(entry, catalog) {
|
|
36270
|
-
return entry.models?.length ? entry.models : catalog.map((model) => model.id);
|
|
36271
36247
|
}
|
|
36272
|
-
function
|
|
36273
|
-
|
|
36274
|
-
|
|
36275
|
-
|
|
36276
|
-
|
|
36277
|
-
|
|
36248
|
+
async function duetRoutingLogMode2(opts = {}) {
|
|
36249
|
+
const home = opts.homeDir ?? os9.homedir();
|
|
36250
|
+
const ws = opts.workspaceRoot ?? null;
|
|
36251
|
+
const key = `${home}\0${ws ?? ""}`;
|
|
36252
|
+
const hit = modeCache.get(key);
|
|
36253
|
+
if (hit !== void 0 && Date.now() - hit.at < MODE_CACHE_TTL_MS)
|
|
36254
|
+
return hit.mode;
|
|
36255
|
+
let mode = exports2.DUET_ROUTING_LOG_DEFAULT_MODE;
|
|
36256
|
+
const tiers = ["user", "project", "local"];
|
|
36257
|
+
for (const tier of tiers) {
|
|
36258
|
+
const found = await readTierMode((0, settingsPaths_js_1.settingsFilePath)(tier, { homeDir: home, workspaceRoot: ws }));
|
|
36259
|
+
if (found !== null)
|
|
36260
|
+
mode = found;
|
|
36278
36261
|
}
|
|
36279
|
-
|
|
36280
|
-
|
|
36281
|
-
inFlight2.delete(key);
|
|
36262
|
+
modeCache.set(key, { at: Date.now(), mode });
|
|
36263
|
+
return mode;
|
|
36282
36264
|
}
|
|
36283
|
-
|
|
36284
|
-
|
|
36285
|
-
const pinned = new Set(entry.models ?? []);
|
|
36286
|
-
const ids = [...pinned, ...catalog.map((model) => model.id).filter((id) => !pinned.has(id))];
|
|
36287
|
-
return ids.map((id) => {
|
|
36288
|
-
const resolved = resolveModelSettings2(entry, id, catalog);
|
|
36289
|
-
const declared = entry.modelConfig?.[id];
|
|
36290
|
-
const view = { id, pinned: pinned.has(id) };
|
|
36291
|
-
if (resolved.contextWindow !== void 0)
|
|
36292
|
-
view.contextWindow = resolved.contextWindow;
|
|
36293
|
-
if (resolved.maxOutputTokens !== void 0)
|
|
36294
|
-
view.maxOutputTokens = resolved.maxOutputTokens;
|
|
36295
|
-
if (resolved.reasoning !== void 0)
|
|
36296
|
-
view.reasoning = resolved.reasoning;
|
|
36297
|
-
if (declared?.contextWindow !== void 0 || declared?.maxOutputTokens !== void 0) {
|
|
36298
|
-
view.source = "user";
|
|
36299
|
-
} else if (view.contextWindow !== void 0 || view.maxOutputTokens !== void 0) {
|
|
36300
|
-
view.source = "endpoint";
|
|
36301
|
-
}
|
|
36302
|
-
return view;
|
|
36303
|
-
});
|
|
36265
|
+
function head(text, max) {
|
|
36266
|
+
return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
|
|
36304
36267
|
}
|
|
36305
|
-
|
|
36306
|
-
|
|
36307
|
-
|
|
36308
|
-
|
|
36309
|
-
|
|
36310
|
-
if (
|
|
36311
|
-
|
|
36312
|
-
next.models = update.models;
|
|
36313
|
-
else
|
|
36314
|
-
delete next.models;
|
|
36268
|
+
function redactRowForMode(row, mode) {
|
|
36269
|
+
if (mode === "off")
|
|
36270
|
+
return null;
|
|
36271
|
+
if (mode === "full")
|
|
36272
|
+
return row;
|
|
36273
|
+
if (row.kind === "planner") {
|
|
36274
|
+
return row.brief === void 0 ? row : { ...row, brief: head(row.brief, exports2.DUET_ROUTING_LOG_HEAD_CHARS) };
|
|
36315
36275
|
}
|
|
36316
|
-
if (
|
|
36317
|
-
|
|
36318
|
-
|
|
36319
|
-
|
|
36320
|
-
|
|
36321
|
-
|
|
36276
|
+
if (row.kind !== "decision")
|
|
36277
|
+
return row;
|
|
36278
|
+
return {
|
|
36279
|
+
...row,
|
|
36280
|
+
prompt: head(row.prompt, exports2.DUET_ROUTING_LOG_HEAD_CHARS),
|
|
36281
|
+
assumptions: row.assumptions.map((a) => ({ id: a.id, text: head(a.text, 100) }))
|
|
36282
|
+
};
|
|
36283
|
+
}
|
|
36284
|
+
var writeQueues = /* @__PURE__ */ new Map();
|
|
36285
|
+
async function writeRow(row, file, opts) {
|
|
36286
|
+
const redacted = redactRowForMode(row, await duetRoutingLogMode2(opts));
|
|
36287
|
+
if (redacted === null)
|
|
36288
|
+
return;
|
|
36289
|
+
await fs15.mkdir(path14.dirname(file), { recursive: true });
|
|
36290
|
+
try {
|
|
36291
|
+
const stat = await fs15.stat(file);
|
|
36292
|
+
if (stat.size >= exports2.DUET_ROUTING_LOG_MAX_BYTES)
|
|
36293
|
+
await fs15.rename(file, `${file}.1`);
|
|
36294
|
+
} catch {
|
|
36322
36295
|
}
|
|
36323
|
-
await (
|
|
36324
|
-
|
|
36325
|
-
return true;
|
|
36296
|
+
await fs15.appendFile(file, `${JSON.stringify(redacted)}
|
|
36297
|
+
`, "utf8");
|
|
36326
36298
|
}
|
|
36327
|
-
|
|
36328
|
-
|
|
36329
|
-
|
|
36330
|
-
|
|
36331
|
-
|
|
36332
|
-
|
|
36333
|
-
|
|
36334
|
-
|
|
36335
|
-
|
|
36336
|
-
|
|
36337
|
-
|
|
36338
|
-
exports2.isLocalExecutorChoice = isLocalExecutorChoice;
|
|
36339
|
-
exports2.resolveDuetExecutorChoice = resolveDuetExecutorChoice2;
|
|
36340
|
-
var customProviders_js_1 = require_customProviders();
|
|
36341
|
-
var customProviderModels_js_1 = require_customProviderModels();
|
|
36342
|
-
exports2.LOCAL_EXECUTOR_READ_BUDGET_MS = 3e3;
|
|
36343
|
-
async function localExecutorOptions2(input = {}) {
|
|
36344
|
-
const { catalog, timeoutMs, ...opts } = input;
|
|
36345
|
-
let entries;
|
|
36299
|
+
async function appendDuetRoutingRow(row, opts = {}) {
|
|
36300
|
+
const file = duetRoutingLogPath2(opts);
|
|
36301
|
+
const previous = writeQueues.get(file) ?? Promise.resolve();
|
|
36302
|
+
const next = previous.then(() => writeRow(row, file, opts)).catch(() => void 0);
|
|
36303
|
+
writeQueues.set(file, next);
|
|
36304
|
+
await next;
|
|
36305
|
+
if (writeQueues.get(file) === next)
|
|
36306
|
+
writeQueues.delete(file);
|
|
36307
|
+
}
|
|
36308
|
+
async function readDuetRoutingLog2(opts = {}) {
|
|
36309
|
+
let text;
|
|
36346
36310
|
try {
|
|
36347
|
-
|
|
36311
|
+
text = await fs15.readFile(duetRoutingLogPath2(opts), "utf8");
|
|
36348
36312
|
} catch {
|
|
36349
36313
|
return [];
|
|
36350
36314
|
}
|
|
36351
|
-
|
|
36352
|
-
|
|
36353
|
-
|
|
36315
|
+
const rows = [];
|
|
36316
|
+
for (const line of text.split("\n")) {
|
|
36317
|
+
if (line.trim() === "")
|
|
36318
|
+
continue;
|
|
36354
36319
|
try {
|
|
36355
|
-
const
|
|
36356
|
-
|
|
36357
|
-
|
|
36358
|
-
|
|
36359
|
-
endpoint: entry.name,
|
|
36360
|
-
model: view.id,
|
|
36361
|
-
pinned: view.pinned
|
|
36362
|
-
};
|
|
36363
|
-
if (view.contextWindow !== void 0)
|
|
36364
|
-
option.contextWindow = view.contextWindow;
|
|
36365
|
-
if (view.maxOutputTokens !== void 0)
|
|
36366
|
-
option.maxOutputTokens = view.maxOutputTokens;
|
|
36367
|
-
return option;
|
|
36368
|
-
});
|
|
36320
|
+
const parsed = JSON.parse(line);
|
|
36321
|
+
if (parsed.kind === "decision" || parsed.kind === "turn_end" || parsed.kind === "followup" || parsed.kind === "planner") {
|
|
36322
|
+
rows.push(parsed);
|
|
36323
|
+
}
|
|
36369
36324
|
} catch {
|
|
36370
|
-
return [];
|
|
36371
36325
|
}
|
|
36372
|
-
})).then((perEndpoint) => perEndpoint.flat());
|
|
36373
|
-
const full = read(catalog ?? {});
|
|
36374
|
-
const budget = timeoutMs ?? exports2.LOCAL_EXECUTOR_READ_BUDGET_MS;
|
|
36375
|
-
if (catalog?.cachedOnly === true || budget <= 0)
|
|
36376
|
-
return full;
|
|
36377
|
-
let timer;
|
|
36378
|
-
const fallback = new Promise((resolve5) => {
|
|
36379
|
-
timer = setTimeout(() => resolve5(read({ ...catalog, cachedOnly: true })), budget);
|
|
36380
|
-
});
|
|
36381
|
-
try {
|
|
36382
|
-
return await Promise.race([full, fallback]);
|
|
36383
|
-
} finally {
|
|
36384
|
-
if (timer !== void 0)
|
|
36385
|
-
clearTimeout(timer);
|
|
36386
|
-
void full.catch(() => void 0);
|
|
36387
36326
|
}
|
|
36327
|
+
return rows;
|
|
36388
36328
|
}
|
|
36389
|
-
function
|
|
36390
|
-
|
|
36391
|
-
|
|
36392
|
-
|
|
36393
|
-
|
|
36329
|
+
function summarizeDuetRoutingLog2(rows) {
|
|
36330
|
+
const summary = {
|
|
36331
|
+
decisions: 0,
|
|
36332
|
+
routes: { plan: 0, execute: 0 },
|
|
36333
|
+
stage1PlanReasons: {},
|
|
36334
|
+
advisorEvaluated: 0,
|
|
36335
|
+
advisorFlagged: {},
|
|
36336
|
+
turnEnds: { completed: 0, error: 0, cancelled: 0 },
|
|
36337
|
+
followups: 0,
|
|
36338
|
+
missedEscalations: 0,
|
|
36339
|
+
flaggedWithoutNewPlan: 0,
|
|
36340
|
+
flaggedBarelyChanged: 0,
|
|
36341
|
+
repeats: 0,
|
|
36342
|
+
entries: { planner: 0, router: 0, executor: 0 },
|
|
36343
|
+
plannerVerdicts: { hand_off: 0, plan: 0 }
|
|
36394
36344
|
};
|
|
36395
|
-
|
|
36396
|
-
|
|
36397
|
-
|
|
36398
|
-
|
|
36399
|
-
|
|
36400
|
-
|
|
36401
|
-
|
|
36402
|
-
|
|
36403
|
-
|
|
36404
|
-
|
|
36405
|
-
|
|
36406
|
-
|
|
36407
|
-
|
|
36408
|
-
|
|
36409
|
-
|
|
36410
|
-
|
|
36411
|
-
|
|
36345
|
+
const decisions = /* @__PURE__ */ new Map();
|
|
36346
|
+
for (const row of rows) {
|
|
36347
|
+
if (row.kind !== "decision")
|
|
36348
|
+
continue;
|
|
36349
|
+
decisions.set(row.id, row);
|
|
36350
|
+
summary.decisions += 1;
|
|
36351
|
+
summary.routes[row.route] += 1;
|
|
36352
|
+
summary.entries[row.entry ?? "router"] += 1;
|
|
36353
|
+
if (row.stage1.verdict === "plan") {
|
|
36354
|
+
summary.stage1PlanReasons[row.stage1.reason] = (summary.stage1PlanReasons[row.stage1.reason] ?? 0) + 1;
|
|
36355
|
+
}
|
|
36356
|
+
if (row.advisor !== null) {
|
|
36357
|
+
summary.advisorEvaluated += 1;
|
|
36358
|
+
if (row.advisor.reason !== null) {
|
|
36359
|
+
summary.advisorFlagged[row.advisor.reason] = (summary.advisorFlagged[row.advisor.reason] ?? 0) + 1;
|
|
36360
|
+
}
|
|
36361
|
+
}
|
|
36362
|
+
}
|
|
36363
|
+
for (const row of rows) {
|
|
36364
|
+
if (row.kind === "turn_end") {
|
|
36365
|
+
summary.turnEnds[row.outcome] += 1;
|
|
36366
|
+
} else if (row.kind === "planner") {
|
|
36367
|
+
summary.plannerVerdicts[row.verdict] += 1;
|
|
36368
|
+
} else if (row.kind === "followup") {
|
|
36369
|
+
summary.followups += 1;
|
|
36370
|
+
const decided = decisions.get(row.decisionId);
|
|
36371
|
+
if (row.nextPromptSimilarity !== null && row.nextPromptSimilarity >= 0.8)
|
|
36372
|
+
summary.repeats += 1;
|
|
36373
|
+
if (decided === void 0)
|
|
36374
|
+
continue;
|
|
36375
|
+
if (decided.route === "execute" && (row.replanActor || row.nextExplicitPlanRequest)) {
|
|
36376
|
+
summary.missedEscalations += 1;
|
|
36377
|
+
}
|
|
36378
|
+
if (decided.advisor?.flagged) {
|
|
36379
|
+
if (!row.planVersionChanged)
|
|
36380
|
+
summary.flaggedWithoutNewPlan += 1;
|
|
36381
|
+
else if (row.planDiffRatio !== null && row.planDiffRatio < 0.1)
|
|
36382
|
+
summary.flaggedBarelyChanged += 1;
|
|
36383
|
+
}
|
|
36384
|
+
}
|
|
36385
|
+
}
|
|
36386
|
+
return summary;
|
|
36387
|
+
}
|
|
36388
|
+
function formatDuetRoutingLogSummary2(summary, file, mode) {
|
|
36389
|
+
const byKey = (m2) => Object.entries(m2).sort((a, b2) => b2[1] - a[1]).map(([k, n]) => `${k} ${n}`).join(", ") || "none";
|
|
36390
|
+
return [
|
|
36391
|
+
`Duet routing journal: ${file} (mode: ${mode})`,
|
|
36392
|
+
`decisions ${summary.decisions} \u2014 plan ${summary.routes.plan}, execute ${summary.routes.execute}`,
|
|
36393
|
+
`entry: planner ${summary.entries.planner}, router ${summary.entries.router}, executor ${summary.entries.executor}`,
|
|
36394
|
+
`planner verdicts: handed off ${summary.plannerVerdicts.hand_off}, planned ${summary.plannerVerdicts.plan}`,
|
|
36395
|
+
`stage-1 plan rules: ${byKey(summary.stage1PlanReasons)}`,
|
|
36396
|
+
`advisor evaluated ${summary.advisorEvaluated}; flagged: ${byKey(summary.advisorFlagged)}`,
|
|
36397
|
+
`turn ends \u2014 completed ${summary.turnEnds.completed}, error ${summary.turnEnds.error}, cancelled ${summary.turnEnds.cancelled}`,
|
|
36398
|
+
`follow-ups ${summary.followups} \u2014 missed escalations ${summary.missedEscalations}, flagged without a new plan ${summary.flaggedWithoutNewPlan}, flagged but barely changed ${summary.flaggedBarelyChanged}, repeats ${summary.repeats}`
|
|
36399
|
+
];
|
|
36400
|
+
}
|
|
36401
|
+
}
|
|
36402
|
+
});
|
|
36403
|
+
|
|
36404
|
+
// ../packages/orion-client-core/dist/duetRoutingSignals.js
|
|
36405
|
+
var require_duetRoutingSignals = __commonJS({
|
|
36406
|
+
"../packages/orion-client-core/dist/duetRoutingSignals.js"(exports2) {
|
|
36407
|
+
"use strict";
|
|
36412
36408
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
36413
36409
|
exports2.ROUTING_JUDGE_MAX_TOKENS = exports2.ROUTING_JUDGE_TIMEOUT_MS = exports2.ROUTING_SIGNAL_TIMEOUT_MS = void 0;
|
|
36414
36410
|
exports2.cosineSimilarity = cosineSimilarity;
|
|
@@ -36584,276 +36580,6 @@ Does this message invalidate any plan assumption or require architectural re-pla
|
|
|
36584
36580
|
}
|
|
36585
36581
|
});
|
|
36586
36582
|
|
|
36587
|
-
// ../packages/orion-client-core/dist/duetRoutingLog.js
|
|
36588
|
-
var require_duetRoutingLog = __commonJS({
|
|
36589
|
-
"../packages/orion-client-core/dist/duetRoutingLog.js"(exports2) {
|
|
36590
|
-
"use strict";
|
|
36591
|
-
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
36592
|
-
if (k2 === void 0) k2 = k;
|
|
36593
|
-
var desc = Object.getOwnPropertyDescriptor(m2, k);
|
|
36594
|
-
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
36595
|
-
desc = { enumerable: true, get: function() {
|
|
36596
|
-
return m2[k];
|
|
36597
|
-
} };
|
|
36598
|
-
}
|
|
36599
|
-
Object.defineProperty(o, k2, desc);
|
|
36600
|
-
} : function(o, m2, k, k2) {
|
|
36601
|
-
if (k2 === void 0) k2 = k;
|
|
36602
|
-
o[k2] = m2[k];
|
|
36603
|
-
});
|
|
36604
|
-
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v2) {
|
|
36605
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
36606
|
-
} : function(o, v2) {
|
|
36607
|
-
o["default"] = v2;
|
|
36608
|
-
});
|
|
36609
|
-
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
36610
|
-
var ownKeys = function(o) {
|
|
36611
|
-
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
36612
|
-
var ar = [];
|
|
36613
|
-
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
36614
|
-
return ar;
|
|
36615
|
-
};
|
|
36616
|
-
return ownKeys(o);
|
|
36617
|
-
};
|
|
36618
|
-
return function(mod2) {
|
|
36619
|
-
if (mod2 && mod2.__esModule) return mod2;
|
|
36620
|
-
var result = {};
|
|
36621
|
-
if (mod2 != null) {
|
|
36622
|
-
for (var k = ownKeys(mod2), i2 = 0; i2 < k.length; i2++) if (k[i2] !== "default") __createBinding(result, mod2, k[i2]);
|
|
36623
|
-
}
|
|
36624
|
-
__setModuleDefault(result, mod2);
|
|
36625
|
-
return result;
|
|
36626
|
-
};
|
|
36627
|
-
}();
|
|
36628
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
36629
|
-
exports2.DUET_ROUTING_LOG_DEFAULT_MODE = exports2.DUET_ROUTING_LOG_KEY = exports2.DUET_ROUTING_LOG_HEAD_CHARS = exports2.DUET_ROUTING_LOG_MAX_BYTES = exports2.DUET_ROUTING_LOG_SCHEMA = void 0;
|
|
36630
|
-
exports2.duetRoutingLogPath = duetRoutingLogPath2;
|
|
36631
|
-
exports2.newDecisionId = newDecisionId;
|
|
36632
|
-
exports2.sessionKey = sessionKey;
|
|
36633
|
-
exports2.lexicalSimilarity = lexicalSimilarity;
|
|
36634
|
-
exports2.planDiffRatio = planDiffRatio;
|
|
36635
|
-
exports2.clearDuetRoutingLogCache = clearDuetRoutingLogCache;
|
|
36636
|
-
exports2.duetRoutingLogMode = duetRoutingLogMode2;
|
|
36637
|
-
exports2.redactRowForMode = redactRowForMode;
|
|
36638
|
-
exports2.appendDuetRoutingRow = appendDuetRoutingRow;
|
|
36639
|
-
exports2.readDuetRoutingLog = readDuetRoutingLog2;
|
|
36640
|
-
exports2.summarizeDuetRoutingLog = summarizeDuetRoutingLog2;
|
|
36641
|
-
exports2.formatDuetRoutingLogSummary = formatDuetRoutingLogSummary2;
|
|
36642
|
-
var node_crypto_1 = __require("node:crypto");
|
|
36643
|
-
var fs15 = __importStar(__require("node:fs/promises"));
|
|
36644
|
-
var os9 = __importStar(__require("node:os"));
|
|
36645
|
-
var path14 = __importStar(__require("node:path"));
|
|
36646
|
-
var settingsPaths_js_1 = require_settingsPaths();
|
|
36647
|
-
exports2.DUET_ROUTING_LOG_SCHEMA = 3;
|
|
36648
|
-
exports2.DUET_ROUTING_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
36649
|
-
exports2.DUET_ROUTING_LOG_HEAD_CHARS = 200;
|
|
36650
|
-
exports2.DUET_ROUTING_LOG_KEY = "duetRoutingLog";
|
|
36651
|
-
exports2.DUET_ROUTING_LOG_DEFAULT_MODE = "full";
|
|
36652
|
-
function duetRoutingLogPath2(opts = {}) {
|
|
36653
|
-
return path14.join(opts.homeDir ?? os9.homedir(), ".orion", "duet-routing-decisions.jsonl");
|
|
36654
|
-
}
|
|
36655
|
-
function newDecisionId() {
|
|
36656
|
-
return (0, node_crypto_1.randomUUID)();
|
|
36657
|
-
}
|
|
36658
|
-
function sessionKey(sessionId) {
|
|
36659
|
-
if (sessionId === void 0 || sessionId === "")
|
|
36660
|
-
return void 0;
|
|
36661
|
-
return (0, node_crypto_1.createHash)("sha256").update(sessionId).digest("hex").slice(0, 12);
|
|
36662
|
-
}
|
|
36663
|
-
function tokens(text) {
|
|
36664
|
-
return new Set(text.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 1));
|
|
36665
|
-
}
|
|
36666
|
-
function jaccard(a, b2) {
|
|
36667
|
-
if (a.size === 0 && b2.size === 0)
|
|
36668
|
-
return 1;
|
|
36669
|
-
let inter = 0;
|
|
36670
|
-
for (const t of a)
|
|
36671
|
-
if (b2.has(t))
|
|
36672
|
-
inter += 1;
|
|
36673
|
-
const union = a.size + b2.size - inter;
|
|
36674
|
-
return union === 0 ? 0 : inter / union;
|
|
36675
|
-
}
|
|
36676
|
-
function lexicalSimilarity(a, b2) {
|
|
36677
|
-
return Math.round(jaccard(tokens(a), tokens(b2)) * 1e3) / 1e3;
|
|
36678
|
-
}
|
|
36679
|
-
function planDiffRatio(before, after) {
|
|
36680
|
-
const lines = (plan) => new Set(plan.split(/\r?\n/).map((l3) => l3.trim()).filter((l3) => l3 !== ""));
|
|
36681
|
-
return Math.round((1 - jaccard(lines(before), lines(after))) * 1e3) / 1e3;
|
|
36682
|
-
}
|
|
36683
|
-
var MODE_CACHE_TTL_MS = 5e3;
|
|
36684
|
-
var modeCache = /* @__PURE__ */ new Map();
|
|
36685
|
-
function clearDuetRoutingLogCache() {
|
|
36686
|
-
modeCache.clear();
|
|
36687
|
-
}
|
|
36688
|
-
function coerceMode(raw) {
|
|
36689
|
-
return raw === "full" || raw === "head" || raw === "off" ? raw : null;
|
|
36690
|
-
}
|
|
36691
|
-
async function readTierMode(file) {
|
|
36692
|
-
if (file === null)
|
|
36693
|
-
return null;
|
|
36694
|
-
try {
|
|
36695
|
-
const parsed = JSON.parse(await fs15.readFile(file, "utf8"));
|
|
36696
|
-
return coerceMode(parsed?.[exports2.DUET_ROUTING_LOG_KEY]?.mode);
|
|
36697
|
-
} catch {
|
|
36698
|
-
return null;
|
|
36699
|
-
}
|
|
36700
|
-
}
|
|
36701
|
-
async function duetRoutingLogMode2(opts = {}) {
|
|
36702
|
-
const home = opts.homeDir ?? os9.homedir();
|
|
36703
|
-
const ws = opts.workspaceRoot ?? null;
|
|
36704
|
-
const key = `${home}\0${ws ?? ""}`;
|
|
36705
|
-
const hit = modeCache.get(key);
|
|
36706
|
-
if (hit !== void 0 && Date.now() - hit.at < MODE_CACHE_TTL_MS)
|
|
36707
|
-
return hit.mode;
|
|
36708
|
-
let mode = exports2.DUET_ROUTING_LOG_DEFAULT_MODE;
|
|
36709
|
-
const tiers = ["user", "project", "local"];
|
|
36710
|
-
for (const tier of tiers) {
|
|
36711
|
-
const found = await readTierMode((0, settingsPaths_js_1.settingsFilePath)(tier, { homeDir: home, workspaceRoot: ws }));
|
|
36712
|
-
if (found !== null)
|
|
36713
|
-
mode = found;
|
|
36714
|
-
}
|
|
36715
|
-
modeCache.set(key, { at: Date.now(), mode });
|
|
36716
|
-
return mode;
|
|
36717
|
-
}
|
|
36718
|
-
function head(text, max) {
|
|
36719
|
-
return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
|
|
36720
|
-
}
|
|
36721
|
-
function redactRowForMode(row, mode) {
|
|
36722
|
-
if (mode === "off")
|
|
36723
|
-
return null;
|
|
36724
|
-
if (mode === "full")
|
|
36725
|
-
return row;
|
|
36726
|
-
if (row.kind === "planner") {
|
|
36727
|
-
return row.brief === void 0 ? row : { ...row, brief: head(row.brief, exports2.DUET_ROUTING_LOG_HEAD_CHARS) };
|
|
36728
|
-
}
|
|
36729
|
-
if (row.kind !== "decision")
|
|
36730
|
-
return row;
|
|
36731
|
-
return {
|
|
36732
|
-
...row,
|
|
36733
|
-
prompt: head(row.prompt, exports2.DUET_ROUTING_LOG_HEAD_CHARS),
|
|
36734
|
-
assumptions: row.assumptions.map((a) => ({ id: a.id, text: head(a.text, 100) }))
|
|
36735
|
-
};
|
|
36736
|
-
}
|
|
36737
|
-
var writeQueues = /* @__PURE__ */ new Map();
|
|
36738
|
-
async function writeRow(row, file, opts) {
|
|
36739
|
-
const redacted = redactRowForMode(row, await duetRoutingLogMode2(opts));
|
|
36740
|
-
if (redacted === null)
|
|
36741
|
-
return;
|
|
36742
|
-
await fs15.mkdir(path14.dirname(file), { recursive: true });
|
|
36743
|
-
try {
|
|
36744
|
-
const stat = await fs15.stat(file);
|
|
36745
|
-
if (stat.size >= exports2.DUET_ROUTING_LOG_MAX_BYTES)
|
|
36746
|
-
await fs15.rename(file, `${file}.1`);
|
|
36747
|
-
} catch {
|
|
36748
|
-
}
|
|
36749
|
-
await fs15.appendFile(file, `${JSON.stringify(redacted)}
|
|
36750
|
-
`, "utf8");
|
|
36751
|
-
}
|
|
36752
|
-
async function appendDuetRoutingRow(row, opts = {}) {
|
|
36753
|
-
const file = duetRoutingLogPath2(opts);
|
|
36754
|
-
const previous = writeQueues.get(file) ?? Promise.resolve();
|
|
36755
|
-
const next = previous.then(() => writeRow(row, file, opts)).catch(() => void 0);
|
|
36756
|
-
writeQueues.set(file, next);
|
|
36757
|
-
await next;
|
|
36758
|
-
if (writeQueues.get(file) === next)
|
|
36759
|
-
writeQueues.delete(file);
|
|
36760
|
-
}
|
|
36761
|
-
async function readDuetRoutingLog2(opts = {}) {
|
|
36762
|
-
let text;
|
|
36763
|
-
try {
|
|
36764
|
-
text = await fs15.readFile(duetRoutingLogPath2(opts), "utf8");
|
|
36765
|
-
} catch {
|
|
36766
|
-
return [];
|
|
36767
|
-
}
|
|
36768
|
-
const rows = [];
|
|
36769
|
-
for (const line of text.split("\n")) {
|
|
36770
|
-
if (line.trim() === "")
|
|
36771
|
-
continue;
|
|
36772
|
-
try {
|
|
36773
|
-
const parsed = JSON.parse(line);
|
|
36774
|
-
if (parsed.kind === "decision" || parsed.kind === "turn_end" || parsed.kind === "followup" || parsed.kind === "planner") {
|
|
36775
|
-
rows.push(parsed);
|
|
36776
|
-
}
|
|
36777
|
-
} catch {
|
|
36778
|
-
}
|
|
36779
|
-
}
|
|
36780
|
-
return rows;
|
|
36781
|
-
}
|
|
36782
|
-
function summarizeDuetRoutingLog2(rows) {
|
|
36783
|
-
const summary = {
|
|
36784
|
-
decisions: 0,
|
|
36785
|
-
routes: { plan: 0, execute: 0 },
|
|
36786
|
-
stage1PlanReasons: {},
|
|
36787
|
-
advisorEvaluated: 0,
|
|
36788
|
-
advisorFlagged: {},
|
|
36789
|
-
turnEnds: { completed: 0, error: 0, cancelled: 0 },
|
|
36790
|
-
followups: 0,
|
|
36791
|
-
missedEscalations: 0,
|
|
36792
|
-
flaggedWithoutNewPlan: 0,
|
|
36793
|
-
flaggedBarelyChanged: 0,
|
|
36794
|
-
repeats: 0,
|
|
36795
|
-
entries: { planner: 0, router: 0 },
|
|
36796
|
-
plannerVerdicts: { hand_off: 0, plan: 0 }
|
|
36797
|
-
};
|
|
36798
|
-
const decisions = /* @__PURE__ */ new Map();
|
|
36799
|
-
for (const row of rows) {
|
|
36800
|
-
if (row.kind !== "decision")
|
|
36801
|
-
continue;
|
|
36802
|
-
decisions.set(row.id, row);
|
|
36803
|
-
summary.decisions += 1;
|
|
36804
|
-
summary.routes[row.route] += 1;
|
|
36805
|
-
summary.entries[row.entry ?? "router"] += 1;
|
|
36806
|
-
if (row.stage1.verdict === "plan") {
|
|
36807
|
-
summary.stage1PlanReasons[row.stage1.reason] = (summary.stage1PlanReasons[row.stage1.reason] ?? 0) + 1;
|
|
36808
|
-
}
|
|
36809
|
-
if (row.advisor !== null) {
|
|
36810
|
-
summary.advisorEvaluated += 1;
|
|
36811
|
-
if (row.advisor.reason !== null) {
|
|
36812
|
-
summary.advisorFlagged[row.advisor.reason] = (summary.advisorFlagged[row.advisor.reason] ?? 0) + 1;
|
|
36813
|
-
}
|
|
36814
|
-
}
|
|
36815
|
-
}
|
|
36816
|
-
for (const row of rows) {
|
|
36817
|
-
if (row.kind === "turn_end") {
|
|
36818
|
-
summary.turnEnds[row.outcome] += 1;
|
|
36819
|
-
} else if (row.kind === "planner") {
|
|
36820
|
-
summary.plannerVerdicts[row.verdict] += 1;
|
|
36821
|
-
} else if (row.kind === "followup") {
|
|
36822
|
-
summary.followups += 1;
|
|
36823
|
-
const decided = decisions.get(row.decisionId);
|
|
36824
|
-
if (row.nextPromptSimilarity !== null && row.nextPromptSimilarity >= 0.8)
|
|
36825
|
-
summary.repeats += 1;
|
|
36826
|
-
if (decided === void 0)
|
|
36827
|
-
continue;
|
|
36828
|
-
if (decided.route === "execute" && (row.replanActor || row.nextExplicitPlanRequest)) {
|
|
36829
|
-
summary.missedEscalations += 1;
|
|
36830
|
-
}
|
|
36831
|
-
if (decided.advisor?.flagged) {
|
|
36832
|
-
if (!row.planVersionChanged)
|
|
36833
|
-
summary.flaggedWithoutNewPlan += 1;
|
|
36834
|
-
else if (row.planDiffRatio !== null && row.planDiffRatio < 0.1)
|
|
36835
|
-
summary.flaggedBarelyChanged += 1;
|
|
36836
|
-
}
|
|
36837
|
-
}
|
|
36838
|
-
}
|
|
36839
|
-
return summary;
|
|
36840
|
-
}
|
|
36841
|
-
function formatDuetRoutingLogSummary2(summary, file, mode) {
|
|
36842
|
-
const byKey = (m2) => Object.entries(m2).sort((a, b2) => b2[1] - a[1]).map(([k, n]) => `${k} ${n}`).join(", ") || "none";
|
|
36843
|
-
return [
|
|
36844
|
-
`Duet routing journal: ${file} (mode: ${mode})`,
|
|
36845
|
-
`decisions ${summary.decisions} \u2014 plan ${summary.routes.plan}, execute ${summary.routes.execute}`,
|
|
36846
|
-
`entry: planner ${summary.entries.planner}, router ${summary.entries.router}`,
|
|
36847
|
-
`planner verdicts: handed off ${summary.plannerVerdicts.hand_off}, planned ${summary.plannerVerdicts.plan}`,
|
|
36848
|
-
`stage-1 plan rules: ${byKey(summary.stage1PlanReasons)}`,
|
|
36849
|
-
`advisor evaluated ${summary.advisorEvaluated}; flagged: ${byKey(summary.advisorFlagged)}`,
|
|
36850
|
-
`turn ends \u2014 completed ${summary.turnEnds.completed}, error ${summary.turnEnds.error}, cancelled ${summary.turnEnds.cancelled}`,
|
|
36851
|
-
`follow-ups ${summary.followups} \u2014 missed escalations ${summary.missedEscalations}, flagged without a new plan ${summary.flaggedWithoutNewPlan}, flagged but barely changed ${summary.flaggedBarelyChanged}, repeats ${summary.repeats}`
|
|
36852
|
-
];
|
|
36853
|
-
}
|
|
36854
|
-
}
|
|
36855
|
-
});
|
|
36856
|
-
|
|
36857
36583
|
// ../packages/orion-client-core/dist/duetRoutingAdvisor.js
|
|
36858
36584
|
var require_duetRoutingAdvisor = __commonJS({
|
|
36859
36585
|
"../packages/orion-client-core/dist/duetRoutingAdvisor.js"(exports2) {
|
|
@@ -37180,13 +36906,23 @@ var require_duetRoutingAdvisor = __commonJS({
|
|
|
37180
36906
|
} catch {
|
|
37181
36907
|
}
|
|
37182
36908
|
}
|
|
37183
|
-
function
|
|
36909
|
+
function scorerReason(verdict, highRisk) {
|
|
36910
|
+
const base = verdict.source === "executor_gate" ? "executor_gate" : "router_model";
|
|
36911
|
+
return highRisk ? `${base}_high_risk` : base;
|
|
36912
|
+
}
|
|
36913
|
+
function stage1Verdict(record, text, entry, verdict = null) {
|
|
37184
36914
|
if ((0, duetPlan_js_1.explicitPlanRequest)(text))
|
|
37185
36915
|
return { verdict: "plan", reason: "explicit_plan_request" };
|
|
37186
36916
|
if (record === null) {
|
|
37187
36917
|
if ((0, duetPlan_js_1.highRiskRequest)(text))
|
|
37188
36918
|
return { verdict: "plan", reason: "plan_invalid" };
|
|
37189
|
-
|
|
36919
|
+
if (entry === "planner")
|
|
36920
|
+
return { verdict: "plan", reason: "planner_entry" };
|
|
36921
|
+
if (verdict?.verdict === "plan")
|
|
36922
|
+
return { verdict: "plan", reason: scorerReason(verdict, false) };
|
|
36923
|
+
if (verdict?.highRisk)
|
|
36924
|
+
return { verdict: "plan", reason: scorerReason(verdict, true) };
|
|
36925
|
+
return { verdict: "execute", reason: "no_plan" };
|
|
37190
36926
|
}
|
|
37191
36927
|
if (record.scopeChanged)
|
|
37192
36928
|
return { verdict: "plan", reason: "scope_changed" };
|
|
@@ -37200,6 +36936,8 @@ var require_duetRoutingAdvisor = __commonJS({
|
|
|
37200
36936
|
if (entry === "planner") {
|
|
37201
36937
|
return (0, duetPlan_js_1.continuationRequest)(text) ? { verdict: "execute", reason: "continuation" } : { verdict: "plan", reason: "planner_entry" };
|
|
37202
36938
|
}
|
|
36939
|
+
if (verdict?.verdict === "plan")
|
|
36940
|
+
return { verdict: "plan", reason: scorerReason(verdict, false) };
|
|
37203
36941
|
return { verdict: "execute", reason: "plan_valid" };
|
|
37204
36942
|
}
|
|
37205
36943
|
function executorContext(workspaceRoot) {
|
|
@@ -37274,7 +37012,10 @@ var require_duetRoutingAdvisor = __commonJS({
|
|
|
37274
37012
|
asksForPlan: input.routerVerdict.asksForPlan,
|
|
37275
37013
|
highRisk: input.routerVerdict.highRisk,
|
|
37276
37014
|
reason: input.routerVerdict.reason,
|
|
37277
|
-
latencyMs: input.routerVerdict.latencyMs
|
|
37015
|
+
latencyMs: input.routerVerdict.latencyMs,
|
|
37016
|
+
source: input.routerVerdict.source,
|
|
37017
|
+
...input.routerVerdict.margin !== void 0 ? { margin: Math.round(input.routerVerdict.margin * 1e6) / 1e6 } : {},
|
|
37018
|
+
...input.routerVerdict.mode !== void 0 ? { mode: input.routerVerdict.mode } : {}
|
|
37278
37019
|
} : null;
|
|
37279
37020
|
const sink = sinkFor(input.log, input.homeDir, input.workspaceRoot);
|
|
37280
37021
|
try {
|
|
@@ -37325,7 +37066,7 @@ var require_duetRoutingAdvisor = __commonJS({
|
|
|
37325
37066
|
if (standing === null) {
|
|
37326
37067
|
resetForVersion(state, null);
|
|
37327
37068
|
if (text !== "") {
|
|
37328
|
-
const stage12 = stage1Verdict(null, text, entry);
|
|
37069
|
+
const stage12 = stage1Verdict(null, text, entry, input.routerVerdict ?? null);
|
|
37329
37070
|
journal(stage12, null, stage12.verdict, []);
|
|
37330
37071
|
}
|
|
37331
37072
|
return untouched(record);
|
|
@@ -37337,7 +37078,7 @@ var require_duetRoutingAdvisor = __commonJS({
|
|
|
37337
37078
|
if (text === "")
|
|
37338
37079
|
return untouched(record);
|
|
37339
37080
|
const assumptions = parsePlanAssumptions(plan.plan);
|
|
37340
|
-
const stage1 = stage1Verdict(plan, text, entry);
|
|
37081
|
+
const stage1 = stage1Verdict(plan, text, entry, input.routerVerdict ?? null);
|
|
37341
37082
|
if (stage1.verdict === "plan") {
|
|
37342
37083
|
journal(stage1, null, "plan", assumptions);
|
|
37343
37084
|
return untouched(record);
|
|
@@ -37386,82 +37127,953 @@ var require_duetRoutingAdvisor = __commonJS({
|
|
|
37386
37127
|
}, now2);
|
|
37387
37128
|
}
|
|
37388
37129
|
}
|
|
37389
|
-
if (candidate !== null && state.turnsUnderVersion < exports2.DUET_ADVISOR_THRESHOLDS.cooldownTurns) {
|
|
37390
|
-
decision.guards.cooldown = true;
|
|
37391
|
-
candidate = null;
|
|
37392
|
-
}
|
|
37393
|
-
let advised = plan;
|
|
37394
|
-
if (candidate !== null) {
|
|
37395
|
-
advised = candidate.flag === "user_negative_feedback" ? { ...plan, userNegativeFeedback: true } : { ...plan, architectureDecisionRequired: true };
|
|
37396
|
-
decision.flagged = candidate.flag;
|
|
37397
|
-
decision.reason = candidate.reason;
|
|
37398
|
-
}
|
|
37399
|
-
decision.latencyMs = Math.max(0, now2() - started);
|
|
37400
|
-
journal(stage1, decision, decision.flagged !== null ? "plan" : "execute", assumptions);
|
|
37401
|
-
return {
|
|
37402
|
-
record: advised,
|
|
37403
|
-
flagged: decision.flagged,
|
|
37404
|
-
reason: decision.reason,
|
|
37405
|
-
assumptionIds: candidate?.ids ?? [],
|
|
37406
|
-
decision,
|
|
37407
|
-
note: duetRoutingAdviceNote(decision.reason, candidate?.ids ?? [])
|
|
37408
|
-
};
|
|
37130
|
+
if (candidate !== null && state.turnsUnderVersion < exports2.DUET_ADVISOR_THRESHOLDS.cooldownTurns) {
|
|
37131
|
+
decision.guards.cooldown = true;
|
|
37132
|
+
candidate = null;
|
|
37133
|
+
}
|
|
37134
|
+
let advised = plan;
|
|
37135
|
+
if (candidate !== null) {
|
|
37136
|
+
advised = candidate.flag === "user_negative_feedback" ? { ...plan, userNegativeFeedback: true } : { ...plan, architectureDecisionRequired: true };
|
|
37137
|
+
decision.flagged = candidate.flag;
|
|
37138
|
+
decision.reason = candidate.reason;
|
|
37139
|
+
}
|
|
37140
|
+
decision.latencyMs = Math.max(0, now2() - started);
|
|
37141
|
+
journal(stage1, decision, decision.flagged !== null ? "plan" : "execute", assumptions);
|
|
37142
|
+
return {
|
|
37143
|
+
record: advised,
|
|
37144
|
+
flagged: decision.flagged,
|
|
37145
|
+
reason: decision.reason,
|
|
37146
|
+
assumptionIds: candidate?.ids ?? [],
|
|
37147
|
+
decision,
|
|
37148
|
+
note: duetRoutingAdviceNote(decision.reason, candidate?.ids ?? [])
|
|
37149
|
+
};
|
|
37150
|
+
} catch {
|
|
37151
|
+
return untouched(record);
|
|
37152
|
+
}
|
|
37153
|
+
}
|
|
37154
|
+
function round3(value) {
|
|
37155
|
+
return Math.round(value * 1e3) / 1e3;
|
|
37156
|
+
}
|
|
37157
|
+
async function describeDuetRouting2(workspaceRoot) {
|
|
37158
|
+
try {
|
|
37159
|
+
const choice = await (0, duetMode_js_1.loadDuetExecutor)({ workspaceRoot: workspaceRoot ?? null });
|
|
37160
|
+
if (choice === null || !(0, customProviders_js_1.isCustomProviderRef)(choice.provider))
|
|
37161
|
+
return { kind: "platform" };
|
|
37162
|
+
const name2 = (0, customProviders_js_1.parseCustomProviderRef)(choice.provider) ?? "";
|
|
37163
|
+
const entry = await (0, customProviders_js_1.getCustomProvider)(name2, { workspaceRoot: workspaceRoot ?? null });
|
|
37164
|
+
if (entry === null)
|
|
37165
|
+
return { kind: "missing", name: name2 };
|
|
37166
|
+
return {
|
|
37167
|
+
kind: "local",
|
|
37168
|
+
name: name2,
|
|
37169
|
+
loopback: (0, customProviders_js_1.isLoopbackEndpoint)(entry.baseUrl),
|
|
37170
|
+
embeddings: entry.routingModels?.embeddings !== void 0,
|
|
37171
|
+
rerank: entry.routingModels?.rerank !== void 0,
|
|
37172
|
+
judge: entry.routingModels?.judge ?? null
|
|
37173
|
+
};
|
|
37174
|
+
} catch {
|
|
37175
|
+
return { kind: "platform" };
|
|
37176
|
+
}
|
|
37177
|
+
}
|
|
37178
|
+
function duetRoutingSummaryLine2(summary) {
|
|
37179
|
+
switch (summary.kind) {
|
|
37180
|
+
case "platform":
|
|
37181
|
+
return "Duet routing: rules only \u2014 a local executor with routing models unlocks re-ask detection and plan-assumption checks.";
|
|
37182
|
+
case "missing":
|
|
37183
|
+
return "Duet routing: rules only.";
|
|
37184
|
+
case "local": {
|
|
37185
|
+
const { name: name2, loopback, embeddings, rerank } = summary;
|
|
37186
|
+
if (!embeddings && !rerank) {
|
|
37187
|
+
return `Duet routing: rules only \u2014 add routingModels to '${name2}' to unlock re-ask detection and plan-assumption checks (the /local-ai skill can set this up).`;
|
|
37188
|
+
}
|
|
37189
|
+
if (!loopback) {
|
|
37190
|
+
return `Duet routing: rules only \u2014 semantic checks run only against a loopback endpoint, and '${name2}' is not one.`;
|
|
37191
|
+
}
|
|
37192
|
+
const parts2 = [];
|
|
37193
|
+
const via = [];
|
|
37194
|
+
if (embeddings) {
|
|
37195
|
+
parts2.push("re-ask detection");
|
|
37196
|
+
via.push("embeddings");
|
|
37197
|
+
}
|
|
37198
|
+
if (rerank) {
|
|
37199
|
+
parts2.push("plan-assumption checks");
|
|
37200
|
+
via.push("rerank");
|
|
37201
|
+
}
|
|
37202
|
+
return `Duet routing: rules + ${parts2.join(" + ")} (${via.join(" + ")} on '${name2}').`;
|
|
37203
|
+
}
|
|
37204
|
+
}
|
|
37205
|
+
}
|
|
37206
|
+
}
|
|
37207
|
+
});
|
|
37208
|
+
|
|
37209
|
+
// ../packages/orion-client-core/dist/duetExecutorGate.js
|
|
37210
|
+
var require_duetExecutorGate = __commonJS({
|
|
37211
|
+
"../packages/orion-client-core/dist/duetExecutorGate.js"(exports2) {
|
|
37212
|
+
"use strict";
|
|
37213
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
37214
|
+
if (k2 === void 0) k2 = k;
|
|
37215
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k);
|
|
37216
|
+
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
37217
|
+
desc = { enumerable: true, get: function() {
|
|
37218
|
+
return m2[k];
|
|
37219
|
+
} };
|
|
37220
|
+
}
|
|
37221
|
+
Object.defineProperty(o, k2, desc);
|
|
37222
|
+
} : function(o, m2, k, k2) {
|
|
37223
|
+
if (k2 === void 0) k2 = k;
|
|
37224
|
+
o[k2] = m2[k];
|
|
37225
|
+
});
|
|
37226
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v2) {
|
|
37227
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
37228
|
+
} : function(o, v2) {
|
|
37229
|
+
o["default"] = v2;
|
|
37230
|
+
});
|
|
37231
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
37232
|
+
var ownKeys = function(o) {
|
|
37233
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
37234
|
+
var ar = [];
|
|
37235
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
37236
|
+
return ar;
|
|
37237
|
+
};
|
|
37238
|
+
return ownKeys(o);
|
|
37239
|
+
};
|
|
37240
|
+
return function(mod2) {
|
|
37241
|
+
if (mod2 && mod2.__esModule) return mod2;
|
|
37242
|
+
var result = {};
|
|
37243
|
+
if (mod2 != null) {
|
|
37244
|
+
for (var k = ownKeys(mod2), i2 = 0; i2 < k.length; i2++) if (k[i2] !== "default") __createBinding(result, mod2, k[i2]);
|
|
37245
|
+
}
|
|
37246
|
+
__setModuleDefault(result, mod2);
|
|
37247
|
+
return result;
|
|
37248
|
+
};
|
|
37249
|
+
}();
|
|
37250
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
37251
|
+
exports2.EXECUTOR_GATE_PROBE_SCENARIOS = exports2.EXECUTOR_GATE_MIN_CALIBRATION = exports2.EXECUTOR_GATE_MISSING_LOGPROB = exports2.EXECUTOR_GATE_PLAN_HEAD_CHARS = exports2.EXECUTOR_GATE_REQUEST_MAX_CHARS = exports2.EXECUTOR_GATE_STATUS_TTL_MS = exports2.EXECUTOR_GATE_TIMEOUT_MS = exports2.EXECUTOR_GATE_PROMPT_VERSION = exports2.EXECUTOR_GATE_SOURCE = void 0;
|
|
37252
|
+
exports2.resolveExecutorGateTarget = resolveExecutorGateTarget;
|
|
37253
|
+
exports2.resolveExecutorGateTargetFromSettings = resolveExecutorGateTargetFromSettings;
|
|
37254
|
+
exports2.executorGateStateFrom = executorGateStateFrom;
|
|
37255
|
+
exports2.renderExecutorGatePrompt = renderExecutorGatePrompt;
|
|
37256
|
+
exports2.executorGateLetterOf = executorGateLetterOf;
|
|
37257
|
+
exports2.parseExecutorGateResponse = parseExecutorGateResponse;
|
|
37258
|
+
exports2.decideExecutorGate = decideExecutorGate;
|
|
37259
|
+
exports2.askExecutorGate = askExecutorGate;
|
|
37260
|
+
exports2.executorGateProbeState = executorGateProbeState;
|
|
37261
|
+
exports2.probeExecutorGate = probeExecutorGate;
|
|
37262
|
+
exports2.describeDuetExecutorGate = describeDuetExecutorGate;
|
|
37263
|
+
exports2.clearDuetExecutorGateCache = clearDuetExecutorGateCache;
|
|
37264
|
+
exports2.describeDuetExecutorGateCached = describeDuetExecutorGateCached2;
|
|
37265
|
+
exports2.createDuetExecutorGate = createDuetExecutorGate2;
|
|
37266
|
+
var os9 = __importStar(__require("node:os"));
|
|
37267
|
+
var customProviders_js_1 = require_customProviders();
|
|
37268
|
+
var duetMode_js_1 = require_duetMode();
|
|
37269
|
+
var duetPlan_js_1 = require_duetPlan();
|
|
37270
|
+
var duetRoutingAdvisor_js_1 = require_duetRoutingAdvisor();
|
|
37271
|
+
var duetExecutorGateStatus_js_1 = require_duetExecutorGateStatus();
|
|
37272
|
+
exports2.EXECUTOR_GATE_SOURCE = "executor_gate";
|
|
37273
|
+
exports2.EXECUTOR_GATE_PROMPT_VERSION = "1";
|
|
37274
|
+
exports2.EXECUTOR_GATE_TIMEOUT_MS = 8e3;
|
|
37275
|
+
exports2.EXECUTOR_GATE_STATUS_TTL_MS = 5 * 6e4;
|
|
37276
|
+
exports2.EXECUTOR_GATE_REQUEST_MAX_CHARS = 2e3;
|
|
37277
|
+
exports2.EXECUTOR_GATE_PLAN_HEAD_CHARS = 1200;
|
|
37278
|
+
exports2.EXECUTOR_GATE_MISSING_LOGPROB = -30;
|
|
37279
|
+
exports2.EXECUTOR_GATE_MIN_CALIBRATION = 3;
|
|
37280
|
+
var DEFAULT_RESOLVE_DEPS = {
|
|
37281
|
+
choice: (workspaceRoot) => (0, duetMode_js_1.duetExecutorWireForSegment)(workspaceRoot),
|
|
37282
|
+
routing: (provider) => (0, customProviders_js_1.endpointRoutingFor)(provider),
|
|
37283
|
+
alive: (workspaceRoot) => (0, customProviders_js_1.duetExecutorEndpointForSegment)(workspaceRoot) !== void 0
|
|
37284
|
+
};
|
|
37285
|
+
function resolveExecutorGateTarget(workspaceRoot, deps2 = DEFAULT_RESOLVE_DEPS) {
|
|
37286
|
+
try {
|
|
37287
|
+
const choice = deps2.choice(workspaceRoot);
|
|
37288
|
+
if (choice === void 0 || !(0, customProviders_js_1.isCustomProviderRef)(choice.provider))
|
|
37289
|
+
return { state: "platform" };
|
|
37290
|
+
const name2 = (0, customProviders_js_1.parseCustomProviderRef)(choice.provider) ?? "";
|
|
37291
|
+
const routing = deps2.routing(choice.provider);
|
|
37292
|
+
if (routing === void 0) {
|
|
37293
|
+
return { state: "unavailable", reason: "not_resolved", problem: "the executor's endpoint is not configured", name: name2 };
|
|
37294
|
+
}
|
|
37295
|
+
if (!deps2.alive(workspaceRoot)) {
|
|
37296
|
+
return { state: "unavailable", reason: "unreachable", problem: "the executor is not answering", name: name2 };
|
|
37297
|
+
}
|
|
37298
|
+
return {
|
|
37299
|
+
state: "ready",
|
|
37300
|
+
target: {
|
|
37301
|
+
name: routing.name,
|
|
37302
|
+
baseUrl: routing.baseUrl,
|
|
37303
|
+
...routing.apiKey ? { apiKey: routing.apiKey } : {},
|
|
37304
|
+
model: choice.model,
|
|
37305
|
+
threshold: routing.executorGate?.threshold ?? customProviders_js_1.EXECUTOR_GATE_DEFAULT_THRESHOLD
|
|
37306
|
+
}
|
|
37307
|
+
};
|
|
37308
|
+
} catch {
|
|
37309
|
+
return { state: "unavailable", reason: "error", problem: "the executor could not be resolved" };
|
|
37310
|
+
}
|
|
37311
|
+
}
|
|
37312
|
+
async function resolveExecutorGateTargetFromSettings(opts) {
|
|
37313
|
+
try {
|
|
37314
|
+
const tiers = { workspaceRoot: opts.workspaceRoot ?? null, ...opts.homeDir ? { homeDir: opts.homeDir } : {} };
|
|
37315
|
+
const choice = await (0, duetMode_js_1.loadDuetExecutor)(tiers);
|
|
37316
|
+
if (choice === null || !(0, customProviders_js_1.isCustomProviderRef)(choice.provider))
|
|
37317
|
+
return { state: "platform" };
|
|
37318
|
+
const name2 = (0, customProviders_js_1.parseCustomProviderRef)(choice.provider) ?? "";
|
|
37319
|
+
const entry = await (0, customProviders_js_1.getCustomProvider)(name2, tiers);
|
|
37320
|
+
if (entry === null) {
|
|
37321
|
+
return { state: "unavailable", reason: "not_resolved", problem: "the executor's endpoint is not configured", name: name2 };
|
|
37322
|
+
}
|
|
37323
|
+
const apiKey = await (0, customProviders_js_1.resolveApiKey)(entry);
|
|
37324
|
+
if (!await (0, customProviders_js_1.endpointIsReachable)(entry.baseUrl, apiKey, opts.fetchImpl)) {
|
|
37325
|
+
return { state: "unavailable", reason: "unreachable", problem: "the executor is not answering", name: name2 };
|
|
37326
|
+
}
|
|
37327
|
+
return {
|
|
37328
|
+
state: "ready",
|
|
37329
|
+
target: {
|
|
37330
|
+
name: entry.name,
|
|
37331
|
+
baseUrl: entry.baseUrl,
|
|
37332
|
+
...apiKey ? { apiKey } : {},
|
|
37333
|
+
model: choice.model,
|
|
37334
|
+
threshold: entry.executorGate?.threshold ?? customProviders_js_1.EXECUTOR_GATE_DEFAULT_THRESHOLD
|
|
37335
|
+
}
|
|
37336
|
+
};
|
|
37337
|
+
} catch {
|
|
37338
|
+
return { state: "unavailable", reason: "error", problem: "the executor could not be resolved" };
|
|
37339
|
+
}
|
|
37340
|
+
}
|
|
37341
|
+
function clipCodePoints(text, max) {
|
|
37342
|
+
const points = Array.from(text);
|
|
37343
|
+
return points.length <= max ? text : `${points.slice(0, max - 1).join("")}\u2026`;
|
|
37344
|
+
}
|
|
37345
|
+
function executorGateStateFrom(record, request) {
|
|
37346
|
+
const standing = record != null && (0, duetPlan_js_1.duetPlanWireForSegment)(record) !== void 0 ? record : null;
|
|
37347
|
+
return {
|
|
37348
|
+
planVersion: standing?.version ?? 0,
|
|
37349
|
+
planValid: standing !== null,
|
|
37350
|
+
planHead: standing === null ? "" : clipCodePoints(standing.plan.trim(), exports2.EXECUTOR_GATE_PLAN_HEAD_CHARS),
|
|
37351
|
+
assumptions: standing === null ? [] : (0, duetRoutingAdvisor_js_1.parsePlanAssumptions)(standing.plan).map((a) => ({ id: a.id, text: a.text })),
|
|
37352
|
+
planningFailures: standing?.planningFailures ?? 0,
|
|
37353
|
+
executorFailures: standing?.executorFailures ?? 0,
|
|
37354
|
+
scopeChanged: standing?.scopeChanged ?? false,
|
|
37355
|
+
architectureDecisionRequired: standing?.architectureDecisionRequired ?? false,
|
|
37356
|
+
userNegativeFeedback: standing?.userNegativeFeedback ?? false,
|
|
37357
|
+
request: clipCodePoints(request.trim(), exports2.EXECUTOR_GATE_REQUEST_MAX_CHARS)
|
|
37358
|
+
};
|
|
37359
|
+
}
|
|
37360
|
+
function stableJson(value) {
|
|
37361
|
+
const sort = (v2) => {
|
|
37362
|
+
if (Array.isArray(v2))
|
|
37363
|
+
return v2.map(sort);
|
|
37364
|
+
if (typeof v2 === "object" && v2 !== null) {
|
|
37365
|
+
return Object.fromEntries(Object.keys(v2).sort().map((k) => [k, sort(v2[k])]));
|
|
37366
|
+
}
|
|
37367
|
+
return v2;
|
|
37368
|
+
};
|
|
37369
|
+
return JSON.stringify(sort(value));
|
|
37370
|
+
}
|
|
37371
|
+
function renderExecutorGatePrompt(state) {
|
|
37372
|
+
const taskState = stableJson({
|
|
37373
|
+
plan_version: state.planVersion,
|
|
37374
|
+
plan_valid: state.planValid,
|
|
37375
|
+
planning_failures: state.planningFailures,
|
|
37376
|
+
executor_failures: state.executorFailures,
|
|
37377
|
+
flags: {
|
|
37378
|
+
scope_changed: state.scopeChanged,
|
|
37379
|
+
architecture_decision_required: state.architectureDecisionRequired,
|
|
37380
|
+
user_negative_feedback: state.userNegativeFeedback
|
|
37381
|
+
}
|
|
37382
|
+
});
|
|
37383
|
+
const capsule = stableJson({ assumptions: state.assumptions });
|
|
37384
|
+
const unresolved = state.executorFailures > 0 || state.planningFailures > 0 ? `${state.executorFailures} executor failure(s) and ${state.planningFailures} planning failure(s) under this plan` : "none";
|
|
37385
|
+
const corrections = state.userNegativeFeedback ? "the user pushed back on the current approach" : "none";
|
|
37386
|
+
return [
|
|
37387
|
+
"Routing gate for a coding agent. Decide if the current turn can be executed",
|
|
37388
|
+
"with the existing plan, or needs a new plan from the senior planner.",
|
|
37389
|
+
"",
|
|
37390
|
+
"E = EXECUTION_ONLY - the current plan is valid and local execution continues",
|
|
37391
|
+
"P = PLAN_REQUIRED - a new or revised plan would materially help",
|
|
37392
|
+
"",
|
|
37393
|
+
"Prefer E unless planning is genuinely needed.",
|
|
37394
|
+
"",
|
|
37395
|
+
"--- TASK STATE ---",
|
|
37396
|
+
taskState,
|
|
37397
|
+
"--- CONTEXT CAPSULE ---",
|
|
37398
|
+
capsule,
|
|
37399
|
+
"--- CURRENT PLAN ---",
|
|
37400
|
+
state.planHead === "" ? "(none)" : state.planHead,
|
|
37401
|
+
"--- UNRESOLVED ERRORS ---",
|
|
37402
|
+
unresolved,
|
|
37403
|
+
"--- RECENT USER CORRECTIONS ---",
|
|
37404
|
+
corrections,
|
|
37405
|
+
"--- LATEST USER REQUEST ---",
|
|
37406
|
+
state.request,
|
|
37407
|
+
"",
|
|
37408
|
+
"Answer with exactly one letter, E or P.",
|
|
37409
|
+
"Answer:"
|
|
37410
|
+
].join("\n");
|
|
37411
|
+
}
|
|
37412
|
+
function executorGateLetterOf(token) {
|
|
37413
|
+
const bare2 = token.replace(/^[\s▁Ġ]+/u, "").replace(/\s+$/u, "");
|
|
37414
|
+
return bare2 === "E" || bare2 === "P" ? bare2 : null;
|
|
37415
|
+
}
|
|
37416
|
+
function topLogprobs(choice) {
|
|
37417
|
+
const lp = choice.logprobs;
|
|
37418
|
+
if (typeof lp !== "object" || lp === null)
|
|
37419
|
+
return null;
|
|
37420
|
+
const out2 = {};
|
|
37421
|
+
const add = (token, logprob) => {
|
|
37422
|
+
if (typeof token === "string" && typeof logprob === "number" && Number.isFinite(logprob)) {
|
|
37423
|
+
out2[token] = Math.max(out2[token] ?? Number.NEGATIVE_INFINITY, logprob);
|
|
37424
|
+
}
|
|
37425
|
+
};
|
|
37426
|
+
const legacy = lp.top_logprobs;
|
|
37427
|
+
if (Array.isArray(legacy) && typeof legacy[0] === "object" && legacy[0] !== null && !Array.isArray(legacy[0])) {
|
|
37428
|
+
for (const [token, logprob] of Object.entries(legacy[0]))
|
|
37429
|
+
add(token, logprob);
|
|
37430
|
+
}
|
|
37431
|
+
const content = lp.content;
|
|
37432
|
+
if (Array.isArray(content) && typeof content[0] === "object" && content[0] !== null) {
|
|
37433
|
+
const first = content[0];
|
|
37434
|
+
add(first.token, first.logprob);
|
|
37435
|
+
if (Array.isArray(first.top_logprobs)) {
|
|
37436
|
+
for (const row of first.top_logprobs) {
|
|
37437
|
+
add(row?.token, row?.logprob);
|
|
37438
|
+
}
|
|
37439
|
+
}
|
|
37440
|
+
}
|
|
37441
|
+
const tokens = lp.tokens;
|
|
37442
|
+
const tokenLogprobs = lp.token_logprobs;
|
|
37443
|
+
if (Array.isArray(tokens) && Array.isArray(tokenLogprobs))
|
|
37444
|
+
add(tokens[0], tokenLogprobs[0]);
|
|
37445
|
+
return Object.keys(out2).length > 0 ? out2 : null;
|
|
37446
|
+
}
|
|
37447
|
+
function parseExecutorGateResponse(body2) {
|
|
37448
|
+
const choice = body2?.choices?.[0];
|
|
37449
|
+
if (typeof choice !== "object" || choice === null) {
|
|
37450
|
+
return { ok: false, reason: "unparseable", problem: "the completions response carried no choice" };
|
|
37451
|
+
}
|
|
37452
|
+
const c3 = choice;
|
|
37453
|
+
const message = c3.message;
|
|
37454
|
+
const raw = typeof c3.text === "string" ? c3.text : typeof message?.content === "string" ? message.content : "";
|
|
37455
|
+
const trimmed = raw.trim();
|
|
37456
|
+
if (trimmed.startsWith("<")) {
|
|
37457
|
+
return {
|
|
37458
|
+
ok: false,
|
|
37459
|
+
reason: "thinking",
|
|
37460
|
+
problem: `the executor answered with thinking on (it began "${trimmed.slice(0, 8)}")`
|
|
37461
|
+
};
|
|
37462
|
+
}
|
|
37463
|
+
const letter = executorGateLetterOf(raw);
|
|
37464
|
+
const top = topLogprobs(c3);
|
|
37465
|
+
if (top !== null) {
|
|
37466
|
+
let logE = null;
|
|
37467
|
+
let logP = null;
|
|
37468
|
+
for (const [token, logprob] of Object.entries(top)) {
|
|
37469
|
+
const l3 = executorGateLetterOf(token);
|
|
37470
|
+
if (l3 === "E")
|
|
37471
|
+
logE = Math.max(logE ?? Number.NEGATIVE_INFINITY, logprob);
|
|
37472
|
+
if (l3 === "P")
|
|
37473
|
+
logP = Math.max(logP ?? Number.NEGATIVE_INFINITY, logprob);
|
|
37474
|
+
}
|
|
37475
|
+
if (logE !== null || logP !== null) {
|
|
37476
|
+
return {
|
|
37477
|
+
ok: true,
|
|
37478
|
+
answer: {
|
|
37479
|
+
mode: "logprob",
|
|
37480
|
+
letter,
|
|
37481
|
+
logE: logE ?? exports2.EXECUTOR_GATE_MISSING_LOGPROB,
|
|
37482
|
+
logP: logP ?? exports2.EXECUTOR_GATE_MISSING_LOGPROB,
|
|
37483
|
+
raw
|
|
37484
|
+
}
|
|
37485
|
+
};
|
|
37486
|
+
}
|
|
37487
|
+
}
|
|
37488
|
+
if (letter !== null)
|
|
37489
|
+
return { ok: true, answer: { mode: "greedy", letter, logE: null, logP: null, raw } };
|
|
37490
|
+
return {
|
|
37491
|
+
ok: false,
|
|
37492
|
+
reason: "unparseable",
|
|
37493
|
+
problem: `the executor answered "${trimmed.slice(0, 16)}", not E or P`
|
|
37494
|
+
};
|
|
37495
|
+
}
|
|
37496
|
+
function decideExecutorGate(answer, threshold) {
|
|
37497
|
+
if (answer.mode === "logprob" && answer.logE !== null && answer.logP !== null) {
|
|
37498
|
+
const margin = answer.logP - answer.logE;
|
|
37499
|
+
return { plan: margin >= threshold, margin, pPlan: 1 / (1 + Math.exp(-margin)) };
|
|
37500
|
+
}
|
|
37501
|
+
if (answer.letter === null)
|
|
37502
|
+
return null;
|
|
37503
|
+
return { plan: answer.letter === "P", margin: null, pPlan: answer.letter === "P" ? 1 : 0 };
|
|
37504
|
+
}
|
|
37505
|
+
async function askExecutorGate(target, prompt, opts = {}) {
|
|
37506
|
+
const started = Date.now();
|
|
37507
|
+
const doFetch = opts.fetchImpl ?? fetch;
|
|
37508
|
+
const headers = { "Content-Type": "application/json" };
|
|
37509
|
+
if (target.apiKey)
|
|
37510
|
+
headers.Authorization = `Bearer ${target.apiKey}`;
|
|
37511
|
+
try {
|
|
37512
|
+
const res = await doFetch(`${target.baseUrl.replace(/\/+$/, "")}/completions`, {
|
|
37513
|
+
method: "POST",
|
|
37514
|
+
headers,
|
|
37515
|
+
body: JSON.stringify({
|
|
37516
|
+
model: target.model,
|
|
37517
|
+
prompt,
|
|
37518
|
+
max_tokens: 1,
|
|
37519
|
+
temperature: 0,
|
|
37520
|
+
logprobs: 5,
|
|
37521
|
+
stream: false
|
|
37522
|
+
}),
|
|
37523
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? exports2.EXECUTOR_GATE_TIMEOUT_MS)
|
|
37524
|
+
});
|
|
37525
|
+
const latencyMs = Date.now() - started;
|
|
37526
|
+
if (res.status === 404 || res.status === 405 || res.status === 501) {
|
|
37527
|
+
return {
|
|
37528
|
+
ok: false,
|
|
37529
|
+
reason: "no_completions",
|
|
37530
|
+
problem: `the executor has no completions route (${res.status})`,
|
|
37531
|
+
latencyMs
|
|
37532
|
+
};
|
|
37533
|
+
}
|
|
37534
|
+
if (!res.ok)
|
|
37535
|
+
return { ok: false, reason: "error", problem: `the executor answered ${res.status}`, latencyMs };
|
|
37536
|
+
const parsed = parseExecutorGateResponse(await res.json());
|
|
37537
|
+
if (!parsed.ok)
|
|
37538
|
+
return { ok: false, reason: parsed.reason, problem: parsed.problem, latencyMs };
|
|
37539
|
+
return { ok: true, answer: parsed.answer, latencyMs };
|
|
37540
|
+
} catch (e) {
|
|
37541
|
+
const timedOut = e instanceof Error && e.name === "TimeoutError";
|
|
37542
|
+
return {
|
|
37543
|
+
ok: false,
|
|
37544
|
+
reason: "error",
|
|
37545
|
+
problem: timedOut ? "the gate call timed out" : `the gate call failed (${e instanceof Error ? e.message : String(e)})`,
|
|
37546
|
+
latencyMs: Date.now() - started
|
|
37547
|
+
};
|
|
37548
|
+
}
|
|
37549
|
+
}
|
|
37550
|
+
exports2.EXECUTOR_GATE_PROBE_SCENARIOS = [
|
|
37551
|
+
{ request: "Create this application with auth, billing and audit logging", expect: "P" },
|
|
37552
|
+
{ request: "Implement the next endpoint", expect: "E" },
|
|
37553
|
+
{ request: "We can no longer use the current authentication architecture", expect: "P" },
|
|
37554
|
+
{ request: "continue", expect: "E" }
|
|
37555
|
+
];
|
|
37556
|
+
function executorGateProbeState(request) {
|
|
37557
|
+
return {
|
|
37558
|
+
planVersion: 3,
|
|
37559
|
+
planValid: true,
|
|
37560
|
+
planHead: "# Plan: orders-service (FastAPI)\n1. Add POST /orders and GET /orders/{id}\n2. Wire the billing call behind a feature flag\n3. Tests for both endpoints",
|
|
37561
|
+
assumptions: [
|
|
37562
|
+
{ id: "A1", text: "the service keeps its central authentication middleware" },
|
|
37563
|
+
{ id: "A2", text: "billing stays behind the existing Stripe client" }
|
|
37564
|
+
],
|
|
37565
|
+
planningFailures: 0,
|
|
37566
|
+
executorFailures: 0,
|
|
37567
|
+
scopeChanged: false,
|
|
37568
|
+
architectureDecisionRequired: false,
|
|
37569
|
+
userNegativeFeedback: false,
|
|
37570
|
+
request
|
|
37571
|
+
};
|
|
37572
|
+
}
|
|
37573
|
+
async function probeExecutorGate(target, opts = {}) {
|
|
37574
|
+
const started = Date.now();
|
|
37575
|
+
let mode = null;
|
|
37576
|
+
const failed = [];
|
|
37577
|
+
for (const scenario of exports2.EXECUTOR_GATE_PROBE_SCENARIOS) {
|
|
37578
|
+
const asked = await askExecutorGate(target, renderExecutorGatePrompt(executorGateProbeState(scenario.request)), opts);
|
|
37579
|
+
if (!asked.ok)
|
|
37580
|
+
return { state: "unavailable", reason: asked.reason, problem: asked.problem, name: target.name };
|
|
37581
|
+
mode ??= asked.answer.mode;
|
|
37582
|
+
const decision = decideExecutorGate(asked.answer, target.threshold);
|
|
37583
|
+
if (decision === null || (decision.plan ? "P" : "E") !== scenario.expect)
|
|
37584
|
+
failed.push(scenario.request);
|
|
37585
|
+
}
|
|
37586
|
+
const calibration = {
|
|
37587
|
+
passed: exports2.EXECUTOR_GATE_PROBE_SCENARIOS.length - failed.length,
|
|
37588
|
+
total: exports2.EXECUTOR_GATE_PROBE_SCENARIOS.length,
|
|
37589
|
+
failed
|
|
37590
|
+
};
|
|
37591
|
+
const common = {
|
|
37592
|
+
target: { name: target.name, model: target.model },
|
|
37593
|
+
mode: mode ?? "greedy",
|
|
37594
|
+
threshold: target.threshold,
|
|
37595
|
+
calibration,
|
|
37596
|
+
latencyMs: Date.now() - started
|
|
37597
|
+
};
|
|
37598
|
+
return calibration.passed >= exports2.EXECUTOR_GATE_MIN_CALIBRATION ? { state: "ready", ...common } : { state: "miscalibrated", ...common };
|
|
37599
|
+
}
|
|
37600
|
+
async function describeDuetExecutorGate(opts = {}) {
|
|
37601
|
+
const resolved = await resolveExecutorGateTargetFromSettings(opts);
|
|
37602
|
+
if (resolved.state !== "ready")
|
|
37603
|
+
return resolved;
|
|
37604
|
+
return probeExecutorGate(resolved.target, { fetchImpl: opts.fetchImpl, timeoutMs: opts.timeoutMs });
|
|
37605
|
+
}
|
|
37606
|
+
var describeCache = /* @__PURE__ */ new Map();
|
|
37607
|
+
function clearDuetExecutorGateCache() {
|
|
37608
|
+
describeCache.clear();
|
|
37609
|
+
}
|
|
37610
|
+
async function describeDuetExecutorGateCached2(opts = {}) {
|
|
37611
|
+
const now2 = opts.now ?? Date.now;
|
|
37612
|
+
const key = `${opts.homeDir ?? os9.homedir()}\0${opts.workspaceRoot ?? ""}`;
|
|
37613
|
+
const hit = describeCache.get(key);
|
|
37614
|
+
if (!opts.refresh && hit !== void 0 && now2() - hit.at < (opts.ttlMs ?? exports2.EXECUTOR_GATE_STATUS_TTL_MS)) {
|
|
37615
|
+
return hit.status;
|
|
37616
|
+
}
|
|
37617
|
+
const status = await describeDuetExecutorGate(opts);
|
|
37618
|
+
describeCache.set(key, { at: now2(), status });
|
|
37619
|
+
return status;
|
|
37620
|
+
}
|
|
37621
|
+
function createDuetExecutorGate2(opts = {}) {
|
|
37622
|
+
const now2 = opts.now ?? Date.now;
|
|
37623
|
+
const ttl = opts.statusTtlMs ?? exports2.EXECUTOR_GATE_STATUS_TTL_MS;
|
|
37624
|
+
let cached = null;
|
|
37625
|
+
let noted = false;
|
|
37626
|
+
const fallback = (why) => {
|
|
37627
|
+
const note = noted ? null : (0, duetExecutorGateStatus_js_1.executorGateFallbackNote)(why);
|
|
37628
|
+
noted = true;
|
|
37629
|
+
return { entry: "executor", verdict: null, note };
|
|
37630
|
+
};
|
|
37631
|
+
return {
|
|
37632
|
+
async status(o = {}) {
|
|
37633
|
+
const resolved = await resolveExecutorGateTargetFromSettings({
|
|
37634
|
+
workspaceRoot: o.workspaceRoot,
|
|
37635
|
+
...opts.homeDir ? { homeDir: opts.homeDir } : {},
|
|
37636
|
+
fetchImpl: opts.fetchImpl
|
|
37637
|
+
});
|
|
37638
|
+
if (resolved.state !== "ready")
|
|
37639
|
+
return resolved;
|
|
37640
|
+
const key = `${resolved.target.baseUrl} ${resolved.target.model} ${resolved.target.threshold}`;
|
|
37641
|
+
if (!o.refresh && cached !== null && cached.key === key && now2() - cached.at < ttl)
|
|
37642
|
+
return cached.status;
|
|
37643
|
+
const status = await probeExecutorGate(resolved.target, { fetchImpl: opts.fetchImpl, timeoutMs: opts.timeoutMs });
|
|
37644
|
+
cached = { at: now2(), key, status };
|
|
37645
|
+
return status;
|
|
37646
|
+
},
|
|
37647
|
+
async prepareTurn(text, ctx) {
|
|
37648
|
+
if (text.trim() === "")
|
|
37649
|
+
return { entry: "executor", verdict: null, note: null };
|
|
37650
|
+
const resolved = resolveExecutorGateTarget(ctx.workspaceRoot, opts.resolveDeps);
|
|
37651
|
+
if (resolved.state !== "ready") {
|
|
37652
|
+
opts.onError?.("resolve", resolved.state === "platform" ? "platform executor" : resolved.problem);
|
|
37653
|
+
return fallback(resolved);
|
|
37654
|
+
}
|
|
37655
|
+
const { target } = resolved;
|
|
37656
|
+
const prompt = renderExecutorGatePrompt(executorGateStateFrom(ctx.record, text));
|
|
37657
|
+
const asked = await askExecutorGate(target, prompt, { fetchImpl: opts.fetchImpl, timeoutMs: opts.timeoutMs });
|
|
37658
|
+
if (!asked.ok) {
|
|
37659
|
+
opts.onError?.("ask", asked.problem);
|
|
37660
|
+
return fallback({ state: "unavailable", reason: asked.reason, problem: asked.problem });
|
|
37661
|
+
}
|
|
37662
|
+
const decision = decideExecutorGate(asked.answer, target.threshold);
|
|
37663
|
+
if (decision === null) {
|
|
37664
|
+
const said = asked.answer.raw.trim();
|
|
37665
|
+
opts.onError?.("ask", `undecidable answer "${said}"`);
|
|
37666
|
+
return fallback({ state: "unavailable", reason: "unparseable", problem: `the executor answered "${said}"` });
|
|
37667
|
+
}
|
|
37668
|
+
noted = false;
|
|
37669
|
+
const verdict = {
|
|
37670
|
+
source: exports2.EXECUTOR_GATE_SOURCE,
|
|
37671
|
+
verdict: decision.plan ? "plan" : "execute",
|
|
37672
|
+
pPlan: decision.pPlan,
|
|
37673
|
+
asksForPlan: false,
|
|
37674
|
+
highRisk: false,
|
|
37675
|
+
reason: exports2.EXECUTOR_GATE_SOURCE,
|
|
37676
|
+
model: target.model,
|
|
37677
|
+
version: exports2.EXECUTOR_GATE_PROMPT_VERSION,
|
|
37678
|
+
latencyMs: asked.latencyMs,
|
|
37679
|
+
mode: asked.answer.mode,
|
|
37680
|
+
...decision.margin !== null ? { margin: decision.margin } : {}
|
|
37681
|
+
};
|
|
37682
|
+
return { entry: "executor", verdict, note: null };
|
|
37683
|
+
},
|
|
37684
|
+
invalidate() {
|
|
37685
|
+
cached = null;
|
|
37686
|
+
noted = false;
|
|
37687
|
+
}
|
|
37688
|
+
};
|
|
37689
|
+
}
|
|
37690
|
+
}
|
|
37691
|
+
});
|
|
37692
|
+
|
|
37693
|
+
// ../packages/orion-client-core/dist/runs/common.js
|
|
37694
|
+
var require_common = __commonJS({
|
|
37695
|
+
"../packages/orion-client-core/dist/runs/common.js"(exports2) {
|
|
37696
|
+
"use strict";
|
|
37697
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
37698
|
+
exports2.mintRunId = mintRunId;
|
|
37699
|
+
exports2.runsRootFor = runsRootFor2;
|
|
37700
|
+
exports2.readJsonFile = readJsonFile;
|
|
37701
|
+
exports2.writeJsonFile = writeJsonFile;
|
|
37702
|
+
exports2.ensureDirFor = ensureDirFor;
|
|
37703
|
+
exports2.listDirNames = listDirNames;
|
|
37704
|
+
exports2.dayKey = dayKey;
|
|
37705
|
+
exports2.clipTail = clipTail;
|
|
37706
|
+
var fs_1 = __require("fs");
|
|
37707
|
+
var os_1 = __require("os");
|
|
37708
|
+
var path_1 = __require("path");
|
|
37709
|
+
var atomicWrite_js_1 = require_atomicWrite();
|
|
37710
|
+
var experienceStore_js_1 = require_experienceStore();
|
|
37711
|
+
var ID_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
37712
|
+
var ID_SUFFIX_LEN = 6;
|
|
37713
|
+
function mintRunId(prefix, nowMs = Date.now(), rand = Math.random) {
|
|
37714
|
+
let suffix = "";
|
|
37715
|
+
for (let i2 = 0; i2 < ID_SUFFIX_LEN; i2 += 1) {
|
|
37716
|
+
suffix += ID_ALPHABET[Math.floor(rand() * ID_ALPHABET.length) % ID_ALPHABET.length];
|
|
37717
|
+
}
|
|
37718
|
+
return `${prefix}_${String(nowMs).padStart(13, "0")}_${suffix}`;
|
|
37719
|
+
}
|
|
37720
|
+
function runsRootFor2(kind, workspaceRoot, home = (0, os_1.homedir)()) {
|
|
37721
|
+
return (0, path_1.join)((0, experienceStore_js_1.projectDirFor)(workspaceRoot, home), "runs", kind);
|
|
37722
|
+
}
|
|
37723
|
+
async function readJsonFile(path14) {
|
|
37724
|
+
try {
|
|
37725
|
+
const raw = await fs_1.promises.readFile(path14, "utf8");
|
|
37726
|
+
return JSON.parse(raw);
|
|
37727
|
+
} catch {
|
|
37728
|
+
return null;
|
|
37729
|
+
}
|
|
37730
|
+
}
|
|
37731
|
+
async function writeJsonFile(path14, value) {
|
|
37732
|
+
await ensureDirFor(path14);
|
|
37733
|
+
await (0, atomicWrite_js_1.atomicWriteFile)(path14, JSON.stringify(value, null, 2));
|
|
37734
|
+
}
|
|
37735
|
+
async function ensureDirFor(path14) {
|
|
37736
|
+
await fs_1.promises.mkdir((0, path_1.dirname)(path14), { recursive: true });
|
|
37737
|
+
}
|
|
37738
|
+
async function listDirNames(path14) {
|
|
37739
|
+
try {
|
|
37740
|
+
return await fs_1.promises.readdir(path14);
|
|
37741
|
+
} catch {
|
|
37742
|
+
return [];
|
|
37743
|
+
}
|
|
37744
|
+
}
|
|
37745
|
+
function dayKey(nowMs = Date.now()) {
|
|
37746
|
+
const d2 = new Date(nowMs);
|
|
37747
|
+
const month = `${d2.getMonth() + 1}`.padStart(2, "0");
|
|
37748
|
+
const day = `${d2.getDate()}`.padStart(2, "0");
|
|
37749
|
+
return `${d2.getFullYear()}-${month}-${day}`;
|
|
37750
|
+
}
|
|
37751
|
+
function clipTail(text, max) {
|
|
37752
|
+
if (text.length <= max)
|
|
37753
|
+
return text;
|
|
37754
|
+
return `\u2026${text.slice(text.length - (max - 1))}`;
|
|
37755
|
+
}
|
|
37756
|
+
}
|
|
37757
|
+
});
|
|
37758
|
+
|
|
37759
|
+
// ../packages/orion-client-core/dist/customProviderModels.js
|
|
37760
|
+
var require_customProviderModels = __commonJS({
|
|
37761
|
+
"../packages/orion-client-core/dist/customProviderModels.js"(exports2) {
|
|
37762
|
+
"use strict";
|
|
37763
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
37764
|
+
if (k2 === void 0) k2 = k;
|
|
37765
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k);
|
|
37766
|
+
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
37767
|
+
desc = { enumerable: true, get: function() {
|
|
37768
|
+
return m2[k];
|
|
37769
|
+
} };
|
|
37770
|
+
}
|
|
37771
|
+
Object.defineProperty(o, k2, desc);
|
|
37772
|
+
} : function(o, m2, k, k2) {
|
|
37773
|
+
if (k2 === void 0) k2 = k;
|
|
37774
|
+
o[k2] = m2[k];
|
|
37775
|
+
});
|
|
37776
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v2) {
|
|
37777
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
37778
|
+
} : function(o, v2) {
|
|
37779
|
+
o["default"] = v2;
|
|
37780
|
+
});
|
|
37781
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
37782
|
+
var ownKeys = function(o) {
|
|
37783
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
37784
|
+
var ar = [];
|
|
37785
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
37786
|
+
return ar;
|
|
37787
|
+
};
|
|
37788
|
+
return ownKeys(o);
|
|
37789
|
+
};
|
|
37790
|
+
return function(mod2) {
|
|
37791
|
+
if (mod2 && mod2.__esModule) return mod2;
|
|
37792
|
+
var result = {};
|
|
37793
|
+
if (mod2 != null) {
|
|
37794
|
+
for (var k = ownKeys(mod2), i2 = 0; i2 < k.length; i2++) if (k[i2] !== "default") __createBinding(result, mod2, k[i2]);
|
|
37795
|
+
}
|
|
37796
|
+
__setModuleDefault(result, mod2);
|
|
37797
|
+
return result;
|
|
37798
|
+
};
|
|
37799
|
+
}();
|
|
37800
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
37801
|
+
exports2.CATALOG_GC_MS = exports2.CATALOG_TTL_MS = exports2.CATALOG_SCHEMA_VERSION = void 0;
|
|
37802
|
+
exports2.catalogPathFor = catalogPathFor;
|
|
37803
|
+
exports2.endpointCatalog = endpointCatalog2;
|
|
37804
|
+
exports2.findProbedModel = findProbedModel;
|
|
37805
|
+
exports2.resolveModelSettings = resolveModelSettings2;
|
|
37806
|
+
exports2.catalogModelIds = catalogModelIds2;
|
|
37807
|
+
exports2.clearEndpointCatalog = clearEndpointCatalog3;
|
|
37808
|
+
exports2.endpointModelViews = endpointModelViews2;
|
|
37809
|
+
exports2.updateCustomProviderModels = updateCustomProviderModels2;
|
|
37810
|
+
var node_crypto_1 = __require("node:crypto");
|
|
37811
|
+
var os9 = __importStar(__require("node:os"));
|
|
37812
|
+
var path14 = __importStar(__require("node:path"));
|
|
37813
|
+
var customProviders_1 = require_customProviders();
|
|
37814
|
+
var common_1 = require_common();
|
|
37815
|
+
exports2.CATALOG_SCHEMA_VERSION = 1;
|
|
37816
|
+
exports2.CATALOG_TTL_MS = 9e5;
|
|
37817
|
+
exports2.CATALOG_GC_MS = 45 * 24 * 60 * 60 * 1e3;
|
|
37818
|
+
function catalogPathFor(baseUrl, homeDir = os9.homedir()) {
|
|
37819
|
+
const digest = (0, node_crypto_1.createHash)("sha256").update(normalizeBaseUrl(baseUrl)).digest("hex").slice(0, 16);
|
|
37820
|
+
return path14.join(homeDir, ".orion", "cache", "models", `${digest}.json`);
|
|
37821
|
+
}
|
|
37822
|
+
function normalizeBaseUrl(baseUrl) {
|
|
37823
|
+
return baseUrl.trim().replace(/\/+$/, "");
|
|
37824
|
+
}
|
|
37825
|
+
async function readRecordFromDisk(baseUrl) {
|
|
37826
|
+
const record = await (0, common_1.readJsonFile)(catalogPathFor(baseUrl));
|
|
37827
|
+
if (record === null)
|
|
37828
|
+
return null;
|
|
37829
|
+
if (record.version !== exports2.CATALOG_SCHEMA_VERSION)
|
|
37830
|
+
return null;
|
|
37831
|
+
if (normalizeBaseUrl(record.baseUrl ?? "") !== normalizeBaseUrl(baseUrl))
|
|
37832
|
+
return null;
|
|
37833
|
+
if (!Array.isArray(record.models))
|
|
37834
|
+
return null;
|
|
37835
|
+
return record;
|
|
37836
|
+
}
|
|
37837
|
+
var sweptThisProcess = false;
|
|
37838
|
+
async function gcEndpointCatalogs(now2, homeDir = os9.homedir()) {
|
|
37839
|
+
if (sweptThisProcess)
|
|
37840
|
+
return;
|
|
37841
|
+
sweptThisProcess = true;
|
|
37842
|
+
try {
|
|
37843
|
+
const dir = path14.dirname(catalogPathFor("x", homeDir));
|
|
37844
|
+
const fs15 = await Promise.resolve().then(() => __importStar(__require("node:fs/promises")));
|
|
37845
|
+
for (const name2 of await fs15.readdir(dir)) {
|
|
37846
|
+
if (!name2.endsWith(".json"))
|
|
37847
|
+
continue;
|
|
37848
|
+
const file = path14.join(dir, name2);
|
|
37849
|
+
try {
|
|
37850
|
+
const record = await (0, common_1.readJsonFile)(file);
|
|
37851
|
+
const age = typeof record?.fetchedAt === "number" ? now2 - record.fetchedAt : now2 - (await fs15.stat(file)).mtimeMs;
|
|
37852
|
+
if (age > exports2.CATALOG_GC_MS)
|
|
37853
|
+
await fs15.rm(file, { force: true });
|
|
37854
|
+
} catch {
|
|
37855
|
+
}
|
|
37856
|
+
}
|
|
37409
37857
|
} catch {
|
|
37410
|
-
return untouched(record);
|
|
37411
37858
|
}
|
|
37412
37859
|
}
|
|
37413
|
-
function
|
|
37414
|
-
return Math.round(value * 1e3) / 1e3;
|
|
37415
|
-
}
|
|
37416
|
-
async function describeDuetRouting2(workspaceRoot) {
|
|
37860
|
+
async function writeRecordToDisk(record) {
|
|
37417
37861
|
try {
|
|
37418
|
-
|
|
37419
|
-
if (choice === null || !(0, customProviders_js_1.isCustomProviderRef)(choice.provider))
|
|
37420
|
-
return { kind: "platform" };
|
|
37421
|
-
const name2 = (0, customProviders_js_1.parseCustomProviderRef)(choice.provider) ?? "";
|
|
37422
|
-
const entry = await (0, customProviders_js_1.getCustomProvider)(name2, { workspaceRoot: workspaceRoot ?? null });
|
|
37423
|
-
if (entry === null)
|
|
37424
|
-
return { kind: "missing", name: name2 };
|
|
37425
|
-
return {
|
|
37426
|
-
kind: "local",
|
|
37427
|
-
name: name2,
|
|
37428
|
-
loopback: (0, customProviders_js_1.isLoopbackEndpoint)(entry.baseUrl),
|
|
37429
|
-
embeddings: entry.routingModels?.embeddings !== void 0,
|
|
37430
|
-
rerank: entry.routingModels?.rerank !== void 0,
|
|
37431
|
-
judge: entry.routingModels?.judge ?? null
|
|
37432
|
-
};
|
|
37862
|
+
await (0, common_1.writeJsonFile)(catalogPathFor(record.baseUrl), record);
|
|
37433
37863
|
} catch {
|
|
37434
|
-
return { kind: "platform" };
|
|
37435
37864
|
}
|
|
37865
|
+
void gcEndpointCatalogs(record.fetchedAt);
|
|
37436
37866
|
}
|
|
37437
|
-
|
|
37438
|
-
|
|
37439
|
-
|
|
37440
|
-
|
|
37441
|
-
|
|
37442
|
-
|
|
37443
|
-
|
|
37444
|
-
|
|
37445
|
-
|
|
37446
|
-
|
|
37447
|
-
|
|
37448
|
-
|
|
37449
|
-
|
|
37450
|
-
|
|
37451
|
-
|
|
37452
|
-
|
|
37453
|
-
|
|
37454
|
-
|
|
37455
|
-
|
|
37456
|
-
|
|
37457
|
-
|
|
37458
|
-
|
|
37459
|
-
|
|
37460
|
-
|
|
37461
|
-
|
|
37867
|
+
var memory = /* @__PURE__ */ new Map();
|
|
37868
|
+
var inFlight2 = /* @__PURE__ */ new Map();
|
|
37869
|
+
function depsWith(deps2) {
|
|
37870
|
+
return {
|
|
37871
|
+
now: deps2.now ?? (() => Date.now()),
|
|
37872
|
+
probe: deps2.probe ?? customProviders_1.probeModels,
|
|
37873
|
+
readRecord: deps2.readRecord ?? readRecordFromDisk,
|
|
37874
|
+
writeRecord: deps2.writeRecord ?? writeRecordToDisk
|
|
37875
|
+
};
|
|
37876
|
+
}
|
|
37877
|
+
async function probeAndStore(entry, d2) {
|
|
37878
|
+
const key = normalizeBaseUrl(entry.baseUrl);
|
|
37879
|
+
const existing = inFlight2.get(key);
|
|
37880
|
+
if (existing !== void 0)
|
|
37881
|
+
return existing;
|
|
37882
|
+
const run3 = (async () => {
|
|
37883
|
+
const models = await d2.probe(entry.baseUrl, await (0, customProviders_1.resolveApiKey)(entry));
|
|
37884
|
+
if (models === null || models.length === 0)
|
|
37885
|
+
return models;
|
|
37886
|
+
const record = {
|
|
37887
|
+
version: exports2.CATALOG_SCHEMA_VERSION,
|
|
37888
|
+
baseUrl: entry.baseUrl,
|
|
37889
|
+
fetchedAt: d2.now(),
|
|
37890
|
+
models
|
|
37891
|
+
};
|
|
37892
|
+
memory.set(key, record);
|
|
37893
|
+
await d2.writeRecord(record);
|
|
37894
|
+
return models;
|
|
37895
|
+
})().finally(() => inFlight2.delete(key));
|
|
37896
|
+
inFlight2.set(key, run3);
|
|
37897
|
+
return run3;
|
|
37898
|
+
}
|
|
37899
|
+
async function endpointCatalog2(entry, options = {}) {
|
|
37900
|
+
const d2 = depsWith(options);
|
|
37901
|
+
const key = normalizeBaseUrl(entry.baseUrl);
|
|
37902
|
+
let record = memory.get(key) ?? null;
|
|
37903
|
+
if (record === null) {
|
|
37904
|
+
record = await d2.readRecord(entry.baseUrl);
|
|
37905
|
+
if (record !== null)
|
|
37906
|
+
memory.set(key, record);
|
|
37907
|
+
}
|
|
37908
|
+
if (options.cachedOnly === true)
|
|
37909
|
+
return record?.models ?? [];
|
|
37910
|
+
const fresh = record !== null && d2.now() - record.fetchedAt < exports2.CATALOG_TTL_MS;
|
|
37911
|
+
if (record !== null && fresh && options.force !== true)
|
|
37912
|
+
return record.models;
|
|
37913
|
+
if (record !== null) {
|
|
37914
|
+
void probeAndStore(entry, d2).catch(() => void 0);
|
|
37915
|
+
return record.models;
|
|
37916
|
+
}
|
|
37917
|
+
return await probeAndStore(entry, d2) ?? [];
|
|
37918
|
+
}
|
|
37919
|
+
function findProbedModel(models, id) {
|
|
37920
|
+
return models.find((model) => model.id === id);
|
|
37921
|
+
}
|
|
37922
|
+
function resolveModelSettings2(entry, modelId, catalog = []) {
|
|
37923
|
+
const declared = entry.modelConfig?.[modelId];
|
|
37924
|
+
const probed = findProbedModel(catalog, modelId);
|
|
37925
|
+
const resolved = {};
|
|
37926
|
+
const contextWindow = declared?.contextWindow ?? probed?.contextWindow;
|
|
37927
|
+
if (contextWindow !== void 0)
|
|
37928
|
+
resolved.contextWindow = contextWindow;
|
|
37929
|
+
const maxOutputTokens = declared?.maxOutputTokens ?? probed?.maxOutputTokens;
|
|
37930
|
+
if (maxOutputTokens !== void 0)
|
|
37931
|
+
resolved.maxOutputTokens = maxOutputTokens;
|
|
37932
|
+
if (probed?.reasoning !== void 0)
|
|
37933
|
+
resolved.reasoning = probed.reasoning;
|
|
37934
|
+
for (const knob of ["temperature", "topP", "topK", "repetitionPenalty"]) {
|
|
37935
|
+
const value = declared?.[knob];
|
|
37936
|
+
if (typeof value === "number")
|
|
37937
|
+
resolved[knob] = value;
|
|
37938
|
+
}
|
|
37939
|
+
return resolved;
|
|
37940
|
+
}
|
|
37941
|
+
function catalogModelIds2(entry, catalog) {
|
|
37942
|
+
return entry.models?.length ? entry.models : catalog.map((model) => model.id);
|
|
37943
|
+
}
|
|
37944
|
+
function clearEndpointCatalog3(baseUrl) {
|
|
37945
|
+
if (baseUrl === void 0) {
|
|
37946
|
+
memory.clear();
|
|
37947
|
+
inFlight2.clear();
|
|
37948
|
+
sweptThisProcess = false;
|
|
37949
|
+
return;
|
|
37950
|
+
}
|
|
37951
|
+
const key = normalizeBaseUrl(baseUrl);
|
|
37952
|
+
memory.delete(key);
|
|
37953
|
+
inFlight2.delete(key);
|
|
37954
|
+
}
|
|
37955
|
+
async function endpointModelViews2(entry, options = {}) {
|
|
37956
|
+
const catalog = await endpointCatalog2(entry, options);
|
|
37957
|
+
const pinned = new Set(entry.models ?? []);
|
|
37958
|
+
const ids = [...pinned, ...catalog.map((model) => model.id).filter((id) => !pinned.has(id))];
|
|
37959
|
+
return ids.map((id) => {
|
|
37960
|
+
const resolved = resolveModelSettings2(entry, id, catalog);
|
|
37961
|
+
const declared = entry.modelConfig?.[id];
|
|
37962
|
+
const view = { id, pinned: pinned.has(id) };
|
|
37963
|
+
if (resolved.contextWindow !== void 0)
|
|
37964
|
+
view.contextWindow = resolved.contextWindow;
|
|
37965
|
+
if (resolved.maxOutputTokens !== void 0)
|
|
37966
|
+
view.maxOutputTokens = resolved.maxOutputTokens;
|
|
37967
|
+
if (resolved.reasoning !== void 0)
|
|
37968
|
+
view.reasoning = resolved.reasoning;
|
|
37969
|
+
if (declared?.contextWindow !== void 0 || declared?.maxOutputTokens !== void 0) {
|
|
37970
|
+
view.source = "user";
|
|
37971
|
+
} else if (view.contextWindow !== void 0 || view.maxOutputTokens !== void 0) {
|
|
37972
|
+
view.source = "endpoint";
|
|
37973
|
+
}
|
|
37974
|
+
return view;
|
|
37975
|
+
});
|
|
37976
|
+
}
|
|
37977
|
+
async function updateCustomProviderModels2(name2, update, tier = "user", opts = {}) {
|
|
37978
|
+
const entry = await (0, customProviders_1.getCustomProvider)(name2, opts);
|
|
37979
|
+
if (entry === null)
|
|
37980
|
+
return false;
|
|
37981
|
+
const next = { ...entry };
|
|
37982
|
+
if (update.models !== void 0) {
|
|
37983
|
+
if (update.models.length)
|
|
37984
|
+
next.models = update.models;
|
|
37985
|
+
else
|
|
37986
|
+
delete next.models;
|
|
37987
|
+
}
|
|
37988
|
+
if (update.modelConfig !== void 0) {
|
|
37989
|
+
const kept = Object.entries(update.modelConfig).map(([id, raw]) => [id, (0, customProviders_1.normalizeModelConfig)(raw)]).filter(([, value]) => value !== void 0 && Object.keys(value).length > 0);
|
|
37990
|
+
if (kept.length)
|
|
37991
|
+
next.modelConfig = Object.fromEntries(kept);
|
|
37992
|
+
else
|
|
37993
|
+
delete next.modelConfig;
|
|
37994
|
+
}
|
|
37995
|
+
await (0, customProviders_1.saveCustomProvider)(next, tier, opts);
|
|
37996
|
+
clearEndpointCatalog3(entry.baseUrl);
|
|
37997
|
+
return true;
|
|
37998
|
+
}
|
|
37999
|
+
}
|
|
38000
|
+
});
|
|
38001
|
+
|
|
38002
|
+
// ../packages/orion-client-core/dist/duetExecutorCatalog.js
|
|
38003
|
+
var require_duetExecutorCatalog = __commonJS({
|
|
38004
|
+
"../packages/orion-client-core/dist/duetExecutorCatalog.js"(exports2) {
|
|
38005
|
+
"use strict";
|
|
38006
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38007
|
+
exports2.LOCAL_EXECUTOR_READ_BUDGET_MS = void 0;
|
|
38008
|
+
exports2.localExecutorOptions = localExecutorOptions2;
|
|
38009
|
+
exports2.duetExecutorChoiceFor = duetExecutorChoiceFor2;
|
|
38010
|
+
exports2.isLocalExecutorChoice = isLocalExecutorChoice;
|
|
38011
|
+
exports2.resolveDuetExecutorChoice = resolveDuetExecutorChoice2;
|
|
38012
|
+
var customProviders_js_1 = require_customProviders();
|
|
38013
|
+
var customProviderModels_js_1 = require_customProviderModels();
|
|
38014
|
+
exports2.LOCAL_EXECUTOR_READ_BUDGET_MS = 3e3;
|
|
38015
|
+
async function localExecutorOptions2(input = {}) {
|
|
38016
|
+
const { catalog, timeoutMs, ...opts } = input;
|
|
38017
|
+
let entries;
|
|
38018
|
+
try {
|
|
38019
|
+
entries = await (0, customProviders_js_1.loadCustomProviders)(opts);
|
|
38020
|
+
} catch {
|
|
38021
|
+
return [];
|
|
38022
|
+
}
|
|
38023
|
+
if (entries.length === 0)
|
|
38024
|
+
return [];
|
|
38025
|
+
const read = (options) => Promise.all(entries.map(async (entry) => {
|
|
38026
|
+
try {
|
|
38027
|
+
const views = await (0, customProviderModels_js_1.endpointModelViews)(entry, options);
|
|
38028
|
+
return views.map((view) => {
|
|
38029
|
+
const option = {
|
|
38030
|
+
provider: `custom:${entry.name}`,
|
|
38031
|
+
endpoint: entry.name,
|
|
38032
|
+
model: view.id,
|
|
38033
|
+
pinned: view.pinned
|
|
38034
|
+
};
|
|
38035
|
+
if (view.contextWindow !== void 0)
|
|
38036
|
+
option.contextWindow = view.contextWindow;
|
|
38037
|
+
if (view.maxOutputTokens !== void 0)
|
|
38038
|
+
option.maxOutputTokens = view.maxOutputTokens;
|
|
38039
|
+
return option;
|
|
38040
|
+
});
|
|
38041
|
+
} catch {
|
|
38042
|
+
return [];
|
|
37462
38043
|
}
|
|
38044
|
+
})).then((perEndpoint) => perEndpoint.flat());
|
|
38045
|
+
const full = read(catalog ?? {});
|
|
38046
|
+
const budget = timeoutMs ?? exports2.LOCAL_EXECUTOR_READ_BUDGET_MS;
|
|
38047
|
+
if (catalog?.cachedOnly === true || budget <= 0)
|
|
38048
|
+
return full;
|
|
38049
|
+
let timer;
|
|
38050
|
+
const fallback = new Promise((resolve5) => {
|
|
38051
|
+
timer = setTimeout(() => resolve5(read({ ...catalog, cachedOnly: true })), budget);
|
|
38052
|
+
});
|
|
38053
|
+
try {
|
|
38054
|
+
return await Promise.race([full, fallback]);
|
|
38055
|
+
} finally {
|
|
38056
|
+
if (timer !== void 0)
|
|
38057
|
+
clearTimeout(timer);
|
|
38058
|
+
void full.catch(() => void 0);
|
|
37463
38059
|
}
|
|
37464
38060
|
}
|
|
38061
|
+
function duetExecutorChoiceFor2(option) {
|
|
38062
|
+
return {
|
|
38063
|
+
provider: option.provider,
|
|
38064
|
+
model: option.model,
|
|
38065
|
+
...option.contextWindow !== void 0 ? { contextWindow: option.contextWindow } : {}
|
|
38066
|
+
};
|
|
38067
|
+
}
|
|
38068
|
+
function isLocalExecutorChoice(choice) {
|
|
38069
|
+
return typeof choice?.provider === "string" && choice.provider.startsWith("custom:");
|
|
38070
|
+
}
|
|
38071
|
+
async function resolveDuetExecutorChoice2(choice, input = {}) {
|
|
38072
|
+
if (!isLocalExecutorChoice(choice) || choice.contextWindow !== void 0)
|
|
38073
|
+
return choice;
|
|
38074
|
+
const found = (await localExecutorOptions2(input)).find((option) => option.provider === choice.provider && option.model === choice.model);
|
|
38075
|
+
return found === void 0 ? choice : { ...choice, ...duetExecutorChoiceFor2(found), ...choice.effort ? { effort: choice.effort } : {} };
|
|
38076
|
+
}
|
|
37465
38077
|
}
|
|
37466
38078
|
});
|
|
37467
38079
|
|
|
@@ -38387,6 +38999,58 @@ var require_agentStore = __commonJS({
|
|
|
38387
38999
|
}
|
|
38388
39000
|
});
|
|
38389
39001
|
|
|
39002
|
+
// ../packages/orion-client-core/dist/goalClaim.js
|
|
39003
|
+
var require_goalClaim = __commonJS({
|
|
39004
|
+
"../packages/orion-client-core/dist/goalClaim.js"(exports2) {
|
|
39005
|
+
"use strict";
|
|
39006
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
39007
|
+
exports2.GOAL_REPORT_TOOL = exports2.GOAL_CAPABILITY = void 0;
|
|
39008
|
+
exports2.readGoalReportInput = readGoalReportInput;
|
|
39009
|
+
exports2.goalClaimFromWire = goalClaimFromWire3;
|
|
39010
|
+
exports2.goalReportToolResult = goalReportToolResult3;
|
|
39011
|
+
exports2.GOAL_CAPABILITY = "goal";
|
|
39012
|
+
exports2.GOAL_REPORT_TOOL = "goal_report";
|
|
39013
|
+
function readGoalReportInput(input) {
|
|
39014
|
+
if (!input || typeof input !== "object")
|
|
39015
|
+
return null;
|
|
39016
|
+
const r2 = input;
|
|
39017
|
+
if (typeof r2.done !== "boolean")
|
|
39018
|
+
return null;
|
|
39019
|
+
const note = r2.done ? r2.verified : r2.outstanding;
|
|
39020
|
+
return { done: r2.done, note: typeof note === "string" ? note.trim() : "" };
|
|
39021
|
+
}
|
|
39022
|
+
function goalClaimFromWire3(messages) {
|
|
39023
|
+
if (!Array.isArray(messages))
|
|
39024
|
+
return null;
|
|
39025
|
+
let claim = null;
|
|
39026
|
+
for (const message of messages) {
|
|
39027
|
+
const m2 = message;
|
|
39028
|
+
if (!m2 || m2.role !== "assistant" || !Array.isArray(m2.content))
|
|
39029
|
+
continue;
|
|
39030
|
+
for (const block of m2.content) {
|
|
39031
|
+
const b2 = block;
|
|
39032
|
+
if (!b2 || b2.type !== "tool_use" || b2.name !== exports2.GOAL_REPORT_TOOL)
|
|
39033
|
+
continue;
|
|
39034
|
+
const parsed = readGoalReportInput(b2.input);
|
|
39035
|
+
if (parsed !== null)
|
|
39036
|
+
claim = parsed;
|
|
39037
|
+
}
|
|
39038
|
+
}
|
|
39039
|
+
return claim;
|
|
39040
|
+
}
|
|
39041
|
+
function goalReportToolResult3(params) {
|
|
39042
|
+
const claim = readGoalReportInput(params);
|
|
39043
|
+
if (claim === null) {
|
|
39044
|
+
return "goal_report needs `done` as a boolean: false while ANY part of the goal remains (say what in `outstanding`), true only when every part is verified complete (name what you ran in `verified`).";
|
|
39045
|
+
}
|
|
39046
|
+
if (claim.done) {
|
|
39047
|
+
return "Completion claim recorded. An independent check now reviews the evidence of what you actually did \u2014 the goal ends only if it confirms; otherwise you will be told what is still outstanding. End your turn now.";
|
|
39048
|
+
}
|
|
39049
|
+
return "Status recorded \u2014 the goal continues. If you can take the next step now, keep working; otherwise end your turn and you will be continued.";
|
|
39050
|
+
}
|
|
39051
|
+
}
|
|
39052
|
+
});
|
|
39053
|
+
|
|
38390
39054
|
// ../packages/orion-client-core/dist/goalMarker.js
|
|
38391
39055
|
var require_goalMarker = __commonJS({
|
|
38392
39056
|
"../packages/orion-client-core/dist/goalMarker.js"(exports2) {
|
|
@@ -38808,7 +39472,8 @@ var require_goalEvaluate = __commonJS({
|
|
|
38808
39472
|
const params = { goal: args2.goal, evidence };
|
|
38809
39473
|
if (args2.sessionId)
|
|
38810
39474
|
params.session_id = args2.sessionId;
|
|
38811
|
-
const
|
|
39475
|
+
const sessionFallback = args2.sessionModel && !args2.sessionProvider?.startsWith("custom") ? { model: args2.sessionModel, provider: args2.sessionProvider ?? "" } : void 0;
|
|
39476
|
+
const chosen = await configuredEvaluatorModel(args2) ?? sessionFallback;
|
|
38812
39477
|
if (chosen) {
|
|
38813
39478
|
params.model = chosen.model;
|
|
38814
39479
|
if (chosen.provider)
|
|
@@ -38825,15 +39490,18 @@ var require_goalRunner = __commonJS({
|
|
|
38825
39490
|
"../packages/orion-client-core/dist/goalRunner.js"(exports2) {
|
|
38826
39491
|
"use strict";
|
|
38827
39492
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38828
|
-
exports2.GoalRunner = exports2.GOAL_CONTINUE_DISPLAY = exports2.GOAL_REASON_PROMPT_MAX_CHARS = exports2.GOAL_REASON_MAX_CHARS = exports2.GOAL_MAX_EVALUATOR_FAILURES = exports2.DEFAULT_GOAL_MAX_WALL_MS = exports2.DEFAULT_GOAL_MAX_TURNS = exports2.GOAL_INSTRUCTION = void 0;
|
|
39493
|
+
exports2.GoalRunner = exports2.GOAL_CONTINUE_DISPLAY = exports2.GOAL_REASON_PROMPT_MAX_CHARS = exports2.GOAL_REASON_MAX_CHARS = exports2.GOAL_UNCLAIMED_CHECK_INTERVAL = exports2.GOAL_MAX_EVALUATOR_FAILURES = exports2.DEFAULT_GOAL_MAX_WALL_MS = exports2.DEFAULT_GOAL_MAX_TURNS = exports2.GOAL_INSTRUCTION = void 0;
|
|
38829
39494
|
exports2.buildGoalPrompt = buildGoalPrompt;
|
|
38830
39495
|
exports2.buildContinuationPrompt = buildContinuationPrompt;
|
|
38831
39496
|
exports2.finalAssistantTextFromWire = finalAssistantTextFromWire2;
|
|
38832
39497
|
exports2.describeGoalEnd = describeGoalEnd;
|
|
38833
|
-
exports2.goalReasonLine =
|
|
39498
|
+
exports2.goalReasonLine = goalReasonLine3;
|
|
38834
39499
|
exports2.goalEndRow = goalEndRow2;
|
|
38835
39500
|
exports2.goalNotMetRow = goalNotMetRow2;
|
|
38836
39501
|
exports2.goalStartDisplay = goalStartDisplay2;
|
|
39502
|
+
exports2.goalFromStartDisplay = goalFromStartDisplay;
|
|
39503
|
+
exports2.goalSetRow = goalSetRow2;
|
|
39504
|
+
exports2.goalRoundReason = goalRoundReason2;
|
|
38837
39505
|
exports2.GOAL_INSTRUCTION = [
|
|
38838
39506
|
"",
|
|
38839
39507
|
"---",
|
|
@@ -38842,11 +39510,14 @@ var require_goalRunner = __commonJS({
|
|
|
38842
39510
|
"Do not end your turn with a plan, an intention, or a promise about work you have not done \u2014",
|
|
38843
39511
|
"if the next step is clear, take it now instead of describing it.",
|
|
38844
39512
|
"",
|
|
38845
|
-
"
|
|
38846
|
-
"
|
|
38847
|
-
|
|
38848
|
-
"
|
|
38849
|
-
"
|
|
39513
|
+
"End every turn by calling the goal_report tool \u2014 a status line in prose is not a report.",
|
|
39514
|
+
"While ANY part of the goal remains, report done: false and say in `outstanding` exactly what",
|
|
39515
|
+
'is missing. Be ruthlessly honest \u2014 an honest "not done" costs nothing and keeps you going.',
|
|
39516
|
+
"Report done: true only when you have VERIFIED every part \u2014 ran the tests, executed the",
|
|
39517
|
+
"command, saw the output \u2014 and name in `verified` what you ran and what it showed.",
|
|
39518
|
+
"Your report is a claim, not a verdict: an independent check reviews the evidence of what you",
|
|
39519
|
+
"actually did before the goal can end, and an unverified claim is simply sent back. Reading",
|
|
39520
|
+
"code is not verifying it; reporting a failure honestly is always better than glossing it."
|
|
38850
39521
|
].join("\n");
|
|
38851
39522
|
function buildGoalPrompt(goal) {
|
|
38852
39523
|
return `# Goal
|
|
@@ -38854,7 +39525,7 @@ ${goal}
|
|
|
38854
39525
|
${exports2.GOAL_INSTRUCTION}`;
|
|
38855
39526
|
}
|
|
38856
39527
|
function buildContinuationPrompt(goal, reason) {
|
|
38857
|
-
const line = reason ?
|
|
39528
|
+
const line = reason ? goalReasonLine3(reason, exports2.GOAL_REASON_PROMPT_MAX_CHARS) : "";
|
|
38858
39529
|
const outstanding = line === "" ? "" : `
|
|
38859
39530
|
|
|
38860
39531
|
## What the completion check reported
|
|
@@ -38887,6 +39558,7 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38887
39558
|
exports2.DEFAULT_GOAL_MAX_TURNS = 0;
|
|
38888
39559
|
exports2.DEFAULT_GOAL_MAX_WALL_MS = 0;
|
|
38889
39560
|
exports2.GOAL_MAX_EVALUATOR_FAILURES = 3;
|
|
39561
|
+
exports2.GOAL_UNCLAIMED_CHECK_INTERVAL = 5;
|
|
38890
39562
|
function describeGoalEnd(reason) {
|
|
38891
39563
|
switch (reason) {
|
|
38892
39564
|
case "done":
|
|
@@ -38907,7 +39579,7 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38907
39579
|
}
|
|
38908
39580
|
exports2.GOAL_REASON_MAX_CHARS = 140;
|
|
38909
39581
|
exports2.GOAL_REASON_PROMPT_MAX_CHARS = 500;
|
|
38910
|
-
function
|
|
39582
|
+
function goalReasonLine3(reason, max = exports2.GOAL_REASON_MAX_CHARS) {
|
|
38911
39583
|
const flat = reason.replace(/\s+/g, " ").trim();
|
|
38912
39584
|
if (flat.length <= max)
|
|
38913
39585
|
return flat;
|
|
@@ -38934,7 +39606,7 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38934
39606
|
}
|
|
38935
39607
|
}
|
|
38936
39608
|
function goalNotMetRow2(reason) {
|
|
38937
|
-
const line =
|
|
39609
|
+
const line = goalReasonLine3(reason);
|
|
38938
39610
|
return {
|
|
38939
39611
|
glyph: "\u25CE",
|
|
38940
39612
|
text: line === "" ? "Not met yet" : `Not met yet \u2014 ${line}`,
|
|
@@ -38946,10 +39618,29 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38946
39618
|
function goalStartDisplay2(goal) {
|
|
38947
39619
|
return `/goal ${goal}`;
|
|
38948
39620
|
}
|
|
39621
|
+
function goalFromStartDisplay(display) {
|
|
39622
|
+
return (display.startsWith("/goal ") ? display.slice("/goal ".length) : display).trim();
|
|
39623
|
+
}
|
|
39624
|
+
function goalSetRow2(goal) {
|
|
39625
|
+
const line = goal.replace(/\s+/g, " ").trim();
|
|
39626
|
+
return {
|
|
39627
|
+
glyph: "\u25CE",
|
|
39628
|
+
text: line === "" ? "Goal set" : `Goal set: ${line}`,
|
|
39629
|
+
done: false,
|
|
39630
|
+
progress: true
|
|
39631
|
+
};
|
|
39632
|
+
}
|
|
39633
|
+
function goalRoundReason2(round) {
|
|
39634
|
+
if (round.ruling)
|
|
39635
|
+
return round.ruling.evaluated ? round.ruling.reason : "";
|
|
39636
|
+
if (round.claim && !round.claim.done)
|
|
39637
|
+
return round.claim.note;
|
|
39638
|
+
return "";
|
|
39639
|
+
}
|
|
38949
39640
|
function readOutcome(outcome) {
|
|
38950
39641
|
if (typeof outcome === "string")
|
|
38951
|
-
return { text: outcome, evidence: outcome };
|
|
38952
|
-
return { text: outcome.text ?? "", evidence: outcome.evidence ?? "" };
|
|
39642
|
+
return { text: outcome, evidence: outcome, claim: null };
|
|
39643
|
+
return { text: outcome.text ?? "", evidence: outcome.evidence ?? "", claim: outcome.claim ?? null };
|
|
38953
39644
|
}
|
|
38954
39645
|
var GoalRunner3 = class {
|
|
38955
39646
|
deps;
|
|
@@ -38962,10 +39653,17 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38962
39653
|
/** Wall-clock anchor for the envelope, from the injected clock. */
|
|
38963
39654
|
startedAt = 0;
|
|
38964
39655
|
/** Consecutive evaluator calls that produced no verdict. Any real ruling —
|
|
38965
|
-
* including "not yet" — resets it.
|
|
39656
|
+
* including "not yet" — resets it. Untouched on rounds that run no check:
|
|
39657
|
+
* they say nothing about the evaluator either way. */
|
|
38966
39658
|
evaluatorFailures = 0;
|
|
38967
39659
|
/** The evaluator's last account of what is outstanding. */
|
|
38968
39660
|
lastReason = "";
|
|
39661
|
+
/** Consecutive rounds settled without a check. At
|
|
39662
|
+
* [`GOAL_UNCLAIMED_CHECK_INTERVAL`] the backstop runs one; reset on every
|
|
39663
|
+
* check run, claimed or backstop. */
|
|
39664
|
+
uncheckedRounds = 0;
|
|
39665
|
+
/** The agent's own last `goal_report`. */
|
|
39666
|
+
lastClaim = null;
|
|
38969
39667
|
constructor(deps2) {
|
|
38970
39668
|
this.deps = deps2;
|
|
38971
39669
|
}
|
|
@@ -38975,7 +39673,8 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38975
39673
|
goal: this.goal,
|
|
38976
39674
|
endReason: this.endReason,
|
|
38977
39675
|
turns: this.turns,
|
|
38978
|
-
lastReason: this.lastReason === "" ? null : this.lastReason
|
|
39676
|
+
lastReason: this.lastReason === "" ? null : this.lastReason,
|
|
39677
|
+
lastClaim: this.lastClaim
|
|
38979
39678
|
};
|
|
38980
39679
|
}
|
|
38981
39680
|
/** The user's stop (Esc, `/goal stop`, banner button). The in-flight turn is
|
|
@@ -38995,6 +39694,8 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
38995
39694
|
this.turns = 0;
|
|
38996
39695
|
this.evaluatorFailures = 0;
|
|
38997
39696
|
this.lastReason = "";
|
|
39697
|
+
this.uncheckedRounds = 0;
|
|
39698
|
+
this.lastClaim = null;
|
|
38998
39699
|
this.emit();
|
|
38999
39700
|
this.startedAt = (this.deps.now ?? Date.now)();
|
|
39000
39701
|
let prompt = buildGoalPrompt(goal);
|
|
@@ -39008,30 +39709,40 @@ ${exports2.GOAL_INSTRUCTION}`;
|
|
|
39008
39709
|
this.turns += 1;
|
|
39009
39710
|
if (this.stopRequested)
|
|
39010
39711
|
return this.finish("stopped");
|
|
39011
|
-
const { text, evidence } = readOutcome(outcome);
|
|
39012
|
-
|
|
39712
|
+
const { text, evidence, claim } = readOutcome(outcome);
|
|
39713
|
+
this.lastClaim = claim;
|
|
39714
|
+
this.uncheckedRounds += 1;
|
|
39715
|
+
const check2 = claim?.done === true ? "claimed" : this.uncheckedRounds >= exports2.GOAL_UNCLAIMED_CHECK_INTERVAL || this.envelopeVerdict(this.turns) !== null ? "backstop" : "none";
|
|
39716
|
+
let ruling = null;
|
|
39717
|
+
if (check2 !== "none") {
|
|
39718
|
+
this.uncheckedRounds = 0;
|
|
39719
|
+
ruling = await this.rule(goal, evidence, text);
|
|
39720
|
+
}
|
|
39013
39721
|
if (this.stopRequested)
|
|
39014
39722
|
return this.finish("stopped");
|
|
39015
|
-
if (ruling
|
|
39016
|
-
|
|
39017
|
-
|
|
39018
|
-
|
|
39019
|
-
|
|
39020
|
-
|
|
39021
|
-
|
|
39022
|
-
|
|
39023
|
-
|
|
39024
|
-
|
|
39025
|
-
|
|
39026
|
-
|
|
39027
|
-
|
|
39723
|
+
if (ruling) {
|
|
39724
|
+
if (ruling.evaluated && ruling.ok) {
|
|
39725
|
+
this.lastReason = ruling.reason;
|
|
39726
|
+
return this.finish("done");
|
|
39727
|
+
}
|
|
39728
|
+
if (ruling.evaluated && !ruling.achievable) {
|
|
39729
|
+
this.lastReason = ruling.reason;
|
|
39730
|
+
return this.finish("not_achievable");
|
|
39731
|
+
}
|
|
39732
|
+
if (ruling.evaluated) {
|
|
39733
|
+
this.evaluatorFailures = 0;
|
|
39734
|
+
this.lastReason = ruling.reason;
|
|
39735
|
+
} else if ((this.evaluatorFailures += 1) >= exports2.GOAL_MAX_EVALUATOR_FAILURES) {
|
|
39736
|
+
this.lastReason = ruling.reason;
|
|
39737
|
+
return this.finish("evaluator_failed");
|
|
39738
|
+
}
|
|
39028
39739
|
}
|
|
39029
39740
|
const ceiling = this.envelopeVerdict(this.turns);
|
|
39030
39741
|
if (ceiling !== null)
|
|
39031
39742
|
return this.finish(ceiling);
|
|
39032
|
-
this.
|
|
39743
|
+
this.deps.onRound?.({ turns: this.turns, check: check2, ruling, claim });
|
|
39033
39744
|
this.emit();
|
|
39034
|
-
prompt = buildContinuationPrompt(goal, ruling
|
|
39745
|
+
prompt = buildContinuationPrompt(goal, ruling?.evaluated ? ruling.reason : void 0);
|
|
39035
39746
|
}
|
|
39036
39747
|
}
|
|
39037
39748
|
/** One completion ruling, with the evaluator's own failures absorbed. A judge
|
|
@@ -40898,7 +41609,7 @@ var require_agentAuth = __commonJS({
|
|
|
40898
41609
|
"../packages/orion-client-core/dist/auth/agentAuth.js"(exports2) {
|
|
40899
41610
|
"use strict";
|
|
40900
41611
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
40901
|
-
exports2.USAGE_TOPUP_COVERING_LABEL = exports2.NO_USAGE_LIMIT_LABEL = exports2.AgentSession = exports2.TOKEN_REQUEST_TIMEOUT_MS = exports2.AgentAuthError = void 0;
|
|
41612
|
+
exports2.USAGE_TOPUP_COVERING_LABEL = exports2.NO_USAGE_LIMIT_LABEL = exports2.AgentSession = exports2.BRAIN_RENEW_DEADLINE_MS = exports2.RENEW_BUDGET_MS = exports2.SECRET_READ_TIMEOUT_MS = exports2.TOKEN_REQUEST_TIMEOUT_MS = exports2.AgentAuthError = void 0;
|
|
40902
41613
|
exports2.isAgentSessionKey = isAgentSessionKey;
|
|
40903
41614
|
exports2.pkcePair = pkcePair;
|
|
40904
41615
|
exports2.buildConnectUrl = buildConnectUrl;
|
|
@@ -40979,6 +41690,16 @@ var require_agentAuth = __commonJS({
|
|
|
40979
41690
|
const value = jwtClaim(token, claim);
|
|
40980
41691
|
return typeof value === "string" && value ? value : null;
|
|
40981
41692
|
}
|
|
41693
|
+
function remainingValidityMs(token) {
|
|
41694
|
+
const exp = jwtClaim(token, "exp");
|
|
41695
|
+
return typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 - Date.now() : 0;
|
|
41696
|
+
}
|
|
41697
|
+
function sleep(ms) {
|
|
41698
|
+
return new Promise((resolve5) => {
|
|
41699
|
+
const timer = setTimeout(resolve5, ms);
|
|
41700
|
+
timer.unref?.();
|
|
41701
|
+
});
|
|
41702
|
+
}
|
|
40982
41703
|
async function pkcePair() {
|
|
40983
41704
|
const raw = new Uint8Array(48);
|
|
40984
41705
|
globalThis.crypto.getRandomValues(raw);
|
|
@@ -41066,16 +41787,54 @@ var require_agentAuth = __commonJS({
|
|
|
41066
41787
|
}
|
|
41067
41788
|
var FRESH_TOKEN_BUFFER_MS = 6e4;
|
|
41068
41789
|
var EARLY_REFRESH_MS = 10 * 6e4;
|
|
41790
|
+
exports2.SECRET_READ_TIMEOUT_MS = 5e3;
|
|
41791
|
+
exports2.RENEW_BUDGET_MS = 55e3;
|
|
41792
|
+
exports2.BRAIN_RENEW_DEADLINE_MS = 9e4;
|
|
41793
|
+
var RENEWED_TOKEN_MIN_REMAINING_MS = 5 * 6e4;
|
|
41794
|
+
var READ_TIMED_OUT = Symbol("orion.secret-read-timed-out");
|
|
41069
41795
|
var AgentSession = class {
|
|
41070
41796
|
store;
|
|
41071
41797
|
apiBaseUrl;
|
|
41072
41798
|
options;
|
|
41073
41799
|
inflightRefresh = null;
|
|
41800
|
+
/** The last token set THIS process saved — a write-through mirror of {@link save}, never
|
|
41801
|
+
* of sibling processes' writes (those live only in the shared store). Lets a renewal
|
|
41802
|
+
* answer with our own recent mint when the store read itself is wedged. NEVER used to
|
|
41803
|
+
* START a refresh: a cached refresh token may be rotated-away by a sibling, and replaying
|
|
41804
|
+
* one late revokes the whole token family server-side. */
|
|
41805
|
+
lastSaved = null;
|
|
41074
41806
|
constructor(store, apiBaseUrl, options = {}) {
|
|
41075
41807
|
this.store = store;
|
|
41076
41808
|
this.apiBaseUrl = apiBaseUrl;
|
|
41077
41809
|
this.options = options;
|
|
41078
41810
|
}
|
|
41811
|
+
/** Breadcrumb line (see {@link AgentSessionOptions.trace}); a throwing sink is the host's
|
|
41812
|
+
* bug and must never break the auth path. */
|
|
41813
|
+
trace(line) {
|
|
41814
|
+
try {
|
|
41815
|
+
this.options.trace?.(line);
|
|
41816
|
+
} catch {
|
|
41817
|
+
}
|
|
41818
|
+
}
|
|
41819
|
+
/** One bounded store read. {@link READ_TIMED_OUT} = the store did not answer (timed out
|
|
41820
|
+
* or threw) — an UNREACHABLE store, distinct from `null` = the key is definitively
|
|
41821
|
+
* absent. The renewal path branches on that difference: absent means signed out (fail
|
|
41822
|
+
* closed now); unreachable means retry and degrade, never a declared sign-out. */
|
|
41823
|
+
async boundedRead(key) {
|
|
41824
|
+
const timeoutMs = this.options.secretReadTimeoutMs ?? exports2.SECRET_READ_TIMEOUT_MS;
|
|
41825
|
+
let timer;
|
|
41826
|
+
const timeout = new Promise((resolve5) => {
|
|
41827
|
+
timer = setTimeout(() => resolve5(READ_TIMED_OUT), timeoutMs);
|
|
41828
|
+
timer.unref?.();
|
|
41829
|
+
});
|
|
41830
|
+
try {
|
|
41831
|
+
const read = Promise.resolve(this.store.get(key)).then((value) => value || null, () => READ_TIMED_OUT);
|
|
41832
|
+
return await Promise.race([read, timeout]);
|
|
41833
|
+
} finally {
|
|
41834
|
+
if (timer !== void 0)
|
|
41835
|
+
clearTimeout(timer);
|
|
41836
|
+
}
|
|
41837
|
+
}
|
|
41079
41838
|
async currentAccessToken() {
|
|
41080
41839
|
return await this.store.get(ACCESS_KEY) || null;
|
|
41081
41840
|
}
|
|
@@ -41095,9 +41854,7 @@ var require_agentAuth = __commonJS({
|
|
|
41095
41854
|
const token = await this.currentAccessToken();
|
|
41096
41855
|
if (!token)
|
|
41097
41856
|
return null;
|
|
41098
|
-
const
|
|
41099
|
-
const expiresAtMs = typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 : 0;
|
|
41100
|
-
const remainingMs = expiresAtMs - Date.now();
|
|
41857
|
+
const remainingMs = remainingValidityMs(token);
|
|
41101
41858
|
if (remainingMs > EARLY_REFRESH_MS)
|
|
41102
41859
|
return token;
|
|
41103
41860
|
if (remainingMs > FRESH_TOKEN_BUFFER_MS) {
|
|
@@ -41107,6 +41864,64 @@ var require_agentAuth = __commonJS({
|
|
|
41107
41864
|
await this.refresh();
|
|
41108
41865
|
return this.currentAccessToken();
|
|
41109
41866
|
}
|
|
41867
|
+
/** The FAIL-CLOSED renewal answer for the local brain's `renew_bearer` request — invoked
|
|
41868
|
+
* only after the gateway REFUSED a bearer (401), which makes the server's verdict the
|
|
41869
|
+
* ground truth this method never argues with. Its contract:
|
|
41870
|
+
* - it never answers with `refused` (the token just declared dead) nor with a near-dead
|
|
41871
|
+
* token — a mint is forced instead;
|
|
41872
|
+
* - a DIFFERENT stored token with comfortable validity (a sibling process already
|
|
41873
|
+
* renewed through the shared store) is the answer immediately, no mint;
|
|
41874
|
+
* - otherwise it mints, retrying transient failures with backoff under `renewBudgetMs`,
|
|
41875
|
+
* re-reading the store between tries — a sibling's mint landing while ours failed
|
|
41876
|
+
* (the rotation race's other half, reply-lost rotations included) is a heal;
|
|
41877
|
+
* - a wedged store degrades to this process's own last save for the ACCESS token
|
|
41878
|
+
* (never for starting a refresh — rotation safety, see {@link refresh});
|
|
41879
|
+
* - `null` means the account genuinely cannot produce a fresh token (signed out,
|
|
41880
|
+
* family revoked, or the budget lapsed with everything unreachable) — the brain then
|
|
41881
|
+
* surfaces the honest auth error.
|
|
41882
|
+
*
|
|
41883
|
+
* {@link currentFreshAccessToken} stays the PROACTIVE read with its deliberate fail-OPEN
|
|
41884
|
+
* degradation ("the stored token stands"); this is the REACTIVE one, and the two must
|
|
41885
|
+
* not be merged: the fail-open answer is exactly what let the 2026-08-24/25 stage turns
|
|
41886
|
+
* die — it handed the refused token straight back, and the one heal was spent. */
|
|
41887
|
+
async renewedAccessToken(refused) {
|
|
41888
|
+
const budget = this.options.renewBudgetMs ?? exports2.RENEW_BUDGET_MS;
|
|
41889
|
+
const backoffBase = this.options.renewBackoffBaseMs ?? 500;
|
|
41890
|
+
const deadline = Date.now() + budget;
|
|
41891
|
+
const answerable = (token2, minted) => typeof token2 === "string" && token2 !== "" && token2 !== refused && // A mint vouches for freshness by EVENT (it just happened server-side), sidestepping
|
|
41892
|
+
// the local clock entirely — a fast client clock must not veto a genuinely new token.
|
|
41893
|
+
(minted || remainingValidityMs(token2) > RENEWED_TOKEN_MIN_REMAINING_MS);
|
|
41894
|
+
const storedAccess = async () => {
|
|
41895
|
+
const read = await this.boundedRead(ACCESS_KEY);
|
|
41896
|
+
if (read !== READ_TIMED_OUT)
|
|
41897
|
+
return { token: read, wedged: false };
|
|
41898
|
+
return { token: this.lastSaved?.accessToken ?? null, wedged: true };
|
|
41899
|
+
};
|
|
41900
|
+
let { token, wedged } = await storedAccess();
|
|
41901
|
+
if (answerable(token, false)) {
|
|
41902
|
+
this.trace(wedged ? "renew: answered from the process cache (store unreachable), no mint" : "renew: answered from the store (sibling renewal), no mint");
|
|
41903
|
+
return token;
|
|
41904
|
+
}
|
|
41905
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
41906
|
+
const minted = await this.refresh();
|
|
41907
|
+
({ token, wedged } = await storedAccess());
|
|
41908
|
+
if (answerable(token, minted)) {
|
|
41909
|
+
this.trace(minted ? `renew: minted and answered (attempt ${attempt + 1})` : "renew: a sibling's mint landed \u2014 answered");
|
|
41910
|
+
return token;
|
|
41911
|
+
}
|
|
41912
|
+
const refreshToken = await this.boundedRead(REFRESH_KEY);
|
|
41913
|
+
if (refreshToken === null) {
|
|
41914
|
+
this.trace("renew: no session (signed out / revoked) \u2014 fail-closed");
|
|
41915
|
+
return null;
|
|
41916
|
+
}
|
|
41917
|
+
const wait = Math.min(Math.min(8e3, backoffBase * 2 ** attempt), deadline - Date.now());
|
|
41918
|
+
if (wait <= 0)
|
|
41919
|
+
break;
|
|
41920
|
+
await sleep(wait);
|
|
41921
|
+
}
|
|
41922
|
+
this.trace(`renew: budget (${budget}ms) exhausted \u2014 fail-closed`);
|
|
41923
|
+
return null;
|
|
41924
|
+
}
|
|
41110
41925
|
/** The plan the user is on (free/pro/…), for display + upgrade CTAs. */
|
|
41111
41926
|
async tier() {
|
|
41112
41927
|
return await this.store.get(TIER_KEY) || null;
|
|
@@ -41243,6 +42058,7 @@ var require_agentAuth = __commonJS({
|
|
|
41243
42058
|
return Boolean(await this.store.get(REFRESH_KEY));
|
|
41244
42059
|
}
|
|
41245
42060
|
async save(tokens) {
|
|
42061
|
+
this.lastSaved = tokens;
|
|
41246
42062
|
await this.store.store(ACCESS_KEY, tokens.accessToken);
|
|
41247
42063
|
await this.store.store(REFRESH_KEY, tokens.refreshToken);
|
|
41248
42064
|
await this.store.store(TIER_KEY, tokens.tier);
|
|
@@ -41263,20 +42079,47 @@ var require_agentAuth = __commonJS({
|
|
|
41263
42079
|
return inflight;
|
|
41264
42080
|
}
|
|
41265
42081
|
async doRefresh() {
|
|
41266
|
-
const
|
|
42082
|
+
const started = Date.now();
|
|
42083
|
+
const refreshToken = await this.boundedRead(REFRESH_KEY);
|
|
42084
|
+
if (refreshToken === READ_TIMED_OUT) {
|
|
42085
|
+
this.trace(`refresh: store read unanswered after ${Date.now() - started}ms \u2014 transient`);
|
|
42086
|
+
return false;
|
|
42087
|
+
}
|
|
41267
42088
|
if (!refreshToken)
|
|
41268
42089
|
return false;
|
|
41269
42090
|
try {
|
|
41270
|
-
|
|
42091
|
+
const minted = await refreshTokens({
|
|
41271
42092
|
apiBaseUrl: this.apiBaseUrl(),
|
|
41272
42093
|
refreshToken,
|
|
41273
42094
|
requestTimeoutMs: this.options.requestTimeoutMs
|
|
41274
|
-
})
|
|
42095
|
+
});
|
|
42096
|
+
if (!minted.accessToken) {
|
|
42097
|
+
this.trace("refresh: malformed 200 (empty access token) \u2014 transient");
|
|
42098
|
+
return false;
|
|
42099
|
+
}
|
|
42100
|
+
const tokens = minted.refreshToken ? minted : { ...minted, refreshToken };
|
|
42101
|
+
const written = await Promise.race([
|
|
42102
|
+
this.save(tokens).then(() => true, () => false),
|
|
42103
|
+
sleep(3 * (this.options.secretReadTimeoutMs ?? exports2.SECRET_READ_TIMEOUT_MS)).then(() => false)
|
|
42104
|
+
]);
|
|
42105
|
+
this.trace(written ? `refresh: minted in ${Date.now() - started}ms` : `refresh: minted in ${Date.now() - started}ms, store write still pending \u2014 tokens live in the process cache`);
|
|
41275
42106
|
return true;
|
|
41276
42107
|
} catch (err2) {
|
|
41277
42108
|
if (err2 instanceof AgentAuthError && isDefinitiveAuthRejection(err2)) {
|
|
42109
|
+
const current2 = await this.boundedRead(REFRESH_KEY);
|
|
42110
|
+
if (current2 === READ_TIMED_OUT) {
|
|
42111
|
+
this.trace("refresh: rejected, but the store is unreachable \u2014 clear deferred");
|
|
42112
|
+
return false;
|
|
42113
|
+
}
|
|
42114
|
+
if (current2 && current2 !== refreshToken) {
|
|
42115
|
+
this.trace("refresh: rejection was a rotation-race replay \u2014 sibling's session adopted");
|
|
42116
|
+
return true;
|
|
42117
|
+
}
|
|
42118
|
+
this.trace("refresh: definitively rejected \u2014 session cleared");
|
|
41278
42119
|
await this.clear();
|
|
42120
|
+
return false;
|
|
41279
42121
|
}
|
|
42122
|
+
this.trace(`refresh: transient failure (${err2 instanceof AgentAuthError ? err2.status : "malformed reply"})`);
|
|
41280
42123
|
return false;
|
|
41281
42124
|
}
|
|
41282
42125
|
}
|
|
@@ -41288,6 +42131,7 @@ var require_agentAuth = __commonJS({
|
|
|
41288
42131
|
await this.clear();
|
|
41289
42132
|
}
|
|
41290
42133
|
async clear() {
|
|
42134
|
+
this.lastSaved = null;
|
|
41291
42135
|
await this.store.delete(ACCESS_KEY);
|
|
41292
42136
|
await this.store.delete(REFRESH_KEY);
|
|
41293
42137
|
await this.store.delete(TIER_KEY);
|
|
@@ -41571,8 +42415,8 @@ var require_browserLogin = __commonJS({
|
|
|
41571
42415
|
} catch {
|
|
41572
42416
|
}
|
|
41573
42417
|
}
|
|
41574
|
-
function createAgentSession3(secrets, config) {
|
|
41575
|
-
return new agentAuth_1.AgentSession(secrets, () => config.accountsApiUrl);
|
|
42418
|
+
function createAgentSession3(secrets, config, options = {}) {
|
|
42419
|
+
return new agentAuth_1.AgentSession(secrets, () => config.accountsApiUrl, options);
|
|
41576
42420
|
}
|
|
41577
42421
|
async function signInViaBrowser3(session, config, deps2 = {}) {
|
|
41578
42422
|
if (await session.isSignedIn())
|
|
@@ -69930,7 +70774,7 @@ var require_connection = __commonJS({
|
|
|
69930
70774
|
return;
|
|
69931
70775
|
}
|
|
69932
70776
|
case "renew_bearer": {
|
|
69933
|
-
void this.answerRenew(frame.id);
|
|
70777
|
+
void this.answerRenew(frame.id, frame.refused);
|
|
69934
70778
|
return;
|
|
69935
70779
|
}
|
|
69936
70780
|
case "rpc_result": {
|
|
@@ -69948,15 +70792,19 @@ var require_connection = __commonJS({
|
|
|
69948
70792
|
return;
|
|
69949
70793
|
}
|
|
69950
70794
|
}
|
|
69951
|
-
/** Run (or join) the ONE in-flight
|
|
69952
|
-
*
|
|
69953
|
-
*
|
|
69954
|
-
|
|
70795
|
+
/** Run (or join) the ONE in-flight renewal and answer the renew request with its result.
|
|
70796
|
+
* Joiners share the in-flight answer even when their `refused` differs (a turn's main
|
|
70797
|
+
* call and its interim passes usually 401 on the SAME bearer; when they don't, a shared
|
|
70798
|
+
* answer the gateway still refuses just triggers that call's second renew round, which
|
|
70799
|
+
* runs fresh with ITS refused token — self-correcting, never a loop). A throwing or
|
|
70800
|
+
* absent auth layer answers "no bearer" — a failed renewal at the brain, never a
|
|
70801
|
+
* connection fault. */
|
|
70802
|
+
async answerRenew(id, refused) {
|
|
69955
70803
|
let bearer = null;
|
|
69956
70804
|
if (this.renewBearer) {
|
|
69957
70805
|
this.renewInFlight ??= (async () => {
|
|
69958
70806
|
try {
|
|
69959
|
-
return await this.renewBearer();
|
|
70807
|
+
return await this.renewBearer(refused);
|
|
69960
70808
|
} catch {
|
|
69961
70809
|
return null;
|
|
69962
70810
|
} finally {
|
|
@@ -70770,6 +71618,8 @@ var require_dist = __commonJS({
|
|
|
70770
71618
|
__exportStar(require_duetEntry(), exports2);
|
|
70771
71619
|
__exportStar(require_duetRouterModel(), exports2);
|
|
70772
71620
|
__exportStar(require_duetRouterInstall(), exports2);
|
|
71621
|
+
__exportStar(require_duetExecutorGate(), exports2);
|
|
71622
|
+
__exportStar(require_duetExecutorGateStatus(), exports2);
|
|
70773
71623
|
__exportStar(require_duetPlan(), exports2);
|
|
70774
71624
|
__exportStar(require_duetPlanners(), exports2);
|
|
70775
71625
|
__exportStar(require_repoIdentity(), exports2);
|
|
@@ -70780,6 +71630,7 @@ var require_dist = __commonJS({
|
|
|
70780
71630
|
__exportStar(require_duetRoutingAdvisor(), exports2);
|
|
70781
71631
|
__exportStar(require_cron(), exports2);
|
|
70782
71632
|
__exportStar(require_agentStore(), exports2);
|
|
71633
|
+
__exportStar(require_goalClaim(), exports2);
|
|
70783
71634
|
__exportStar(require_goalMarker(), exports2);
|
|
70784
71635
|
__exportStar(require_goalEvidence(), exports2);
|
|
70785
71636
|
__exportStar(require_goalEvaluate(), exports2);
|
|
@@ -71764,7 +72615,8 @@ var require_toolVisibility = __commonJS({
|
|
|
71764
72615
|
exports2.SILENT_TOOLS = /* @__PURE__ */ new Set([
|
|
71765
72616
|
"ask_user",
|
|
71766
72617
|
"exit_plan_mode",
|
|
71767
|
-
"await_agents"
|
|
72618
|
+
"await_agents",
|
|
72619
|
+
"goal_report"
|
|
71768
72620
|
]);
|
|
71769
72621
|
function isSilentTool3(name2) {
|
|
71770
72622
|
return typeof name2 === "string" && exports2.SILENT_TOOLS.has(name2);
|
|
@@ -87802,8 +88654,19 @@ var darkTheme = {
|
|
|
87802
88654
|
contextCometFragment: "#7c5cbf",
|
|
87803
88655
|
contextCometDust: "#4a3d66",
|
|
87804
88656
|
border: "#808080",
|
|
87805
|
-
|
|
87806
|
-
|
|
88657
|
+
// Diff layers (see the Theme interface): near-black bands a step apart, loud
|
|
88658
|
+
// color reserved for the +/- decorations, bright off-white plain text. The
|
|
88659
|
+
// hues are Orion's own family — EMERALD for additions (cooler than a leaf
|
|
88660
|
+
// green; the decoration green IS the app's semantic green, autoAccept, so
|
|
88661
|
+
// the diff and the posture/success chrome speak one color) and ROSE for
|
|
88662
|
+
// removals (sits naturally beside the violet brand).
|
|
88663
|
+
diffAdd: "#3fb950",
|
|
88664
|
+
diffRemove: "#e5484d",
|
|
88665
|
+
diffAddBg: "#022711",
|
|
88666
|
+
diffRemoveBg: "#330210",
|
|
88667
|
+
diffAddWordBg: "#044921",
|
|
88668
|
+
diffRemoveWordBg: "#4d0416",
|
|
88669
|
+
diffText: "#f8f8f2",
|
|
87807
88670
|
diffContext: "#808080",
|
|
87808
88671
|
gutter: "#808080",
|
|
87809
88672
|
synKeyword: "#569cd6",
|
|
@@ -87813,11 +88676,6 @@ var darkTheme = {
|
|
|
87813
88676
|
synType: "#4ec9b0",
|
|
87814
88677
|
synComment: "#6a9955",
|
|
87815
88678
|
synControl: "#c586c0",
|
|
87816
|
-
// Per-line diff BASE bands (muted). The brighter diffAdd/diffRemove ride on top
|
|
87817
|
-
// as word-level change highlights, so a small edit shows a two-tone line instead
|
|
87818
|
-
// of one flat wash.
|
|
87819
|
-
diffAddBg: "#225c2b",
|
|
87820
|
-
diffRemoveBg: "#7a2936",
|
|
87821
88679
|
autoAccept: "#3fb950",
|
|
87822
88680
|
planMode: "#38bdf8",
|
|
87823
88681
|
duetMode: "#a78bfa",
|
|
@@ -87858,8 +88716,17 @@ var lightTheme = {
|
|
|
87858
88716
|
contextCometFragment: "#8b6fd4",
|
|
87859
88717
|
contextCometDust: "#b9a9dd",
|
|
87860
88718
|
border: "#808080",
|
|
87861
|
-
|
|
87862
|
-
|
|
88719
|
+
// Diff layers (see the Theme interface), mirrored for a light terminal: the
|
|
88720
|
+
// bands are the palest wash, the word step is deeper, decorations deeper
|
|
88721
|
+
// still. Same Orion family as dark — emerald additions (decoration green =
|
|
88722
|
+
// autoAccept, the app's semantic green) and rose removals.
|
|
88723
|
+
diffAdd: "#15803d",
|
|
88724
|
+
diffRemove: "#cf2240",
|
|
88725
|
+
diffAddBg: "#d9fbe8",
|
|
88726
|
+
diffRemoveBg: "#ffdce4",
|
|
88727
|
+
diffAddWordBg: "#aff5cd",
|
|
88728
|
+
diffRemoveWordBg: "#ffc2cf",
|
|
88729
|
+
diffText: "#333333",
|
|
87863
88730
|
diffContext: "#808080",
|
|
87864
88731
|
gutter: "#808080",
|
|
87865
88732
|
synKeyword: "#0000ff",
|
|
@@ -87869,8 +88736,6 @@ var lightTheme = {
|
|
|
87869
88736
|
synType: "#267f99",
|
|
87870
88737
|
synComment: "#008000",
|
|
87871
88738
|
synControl: "#af00db",
|
|
87872
|
-
diffAddBg: "#a6f3b0",
|
|
87873
|
-
diffRemoveBg: "#ffc9d0",
|
|
87874
88739
|
autoAccept: "#15803d",
|
|
87875
88740
|
planMode: "#267f99",
|
|
87876
88741
|
duetMode: "#7c3aed",
|
|
@@ -88114,6 +88979,11 @@ async function transportBearer(session, store, fallback) {
|
|
|
88114
88979
|
if (!token) await syncAccountGate(session, store);
|
|
88115
88980
|
return token ?? fallback ?? null;
|
|
88116
88981
|
}
|
|
88982
|
+
async function renewedTransportBearer(session, store, refused, fallback) {
|
|
88983
|
+
const token = await session.renewedAccessToken(refused);
|
|
88984
|
+
if (!token) await syncAccountGate(session, store);
|
|
88985
|
+
return token ?? fallback ?? null;
|
|
88986
|
+
}
|
|
88117
88987
|
var SIGN_IN_FIRST_MESSAGE = "Sign in first with /signin to start chatting.";
|
|
88118
88988
|
function isAuthDeadError(e) {
|
|
88119
88989
|
return /\bhttp 401\b/.test(e instanceof Error ? e.message : String(e));
|
|
@@ -89101,11 +89971,6 @@ function appendLiveCode(s, id, delta) {
|
|
|
89101
89971
|
if (!live.liveCode || live.liveCode.id !== id) return s;
|
|
89102
89972
|
return { ...s, live: { ...live, liveCode: { ...live.liveCode, code: live.liveCode.code + delta } } };
|
|
89103
89973
|
}
|
|
89104
|
-
function endLiveCode(s, id) {
|
|
89105
|
-
const live = s.live;
|
|
89106
|
-
if (!live?.liveCode || live.liveCode.id !== id) return s;
|
|
89107
|
-
return { ...s, live: { ...live, liveCode: null } };
|
|
89108
|
-
}
|
|
89109
89974
|
function startTool(s, name2, input) {
|
|
89110
89975
|
const flushed = flushLive(s);
|
|
89111
89976
|
const live = flushed.live ?? emptyLive();
|
|
@@ -89134,7 +89999,11 @@ function settleToolEnd(s, id, success, detail) {
|
|
|
89134
89999
|
}
|
|
89135
90000
|
const rest = { ...s.live.pendingWrites };
|
|
89136
90001
|
delete rest[id];
|
|
89137
|
-
const nextLive = {
|
|
90002
|
+
const nextLive = {
|
|
90003
|
+
...s.live,
|
|
90004
|
+
pendingWrites: rest,
|
|
90005
|
+
liveCode: s.live.liveCode && s.live.liveCode.id === id ? null : s.live.liveCode
|
|
90006
|
+
};
|
|
89138
90007
|
if (success) {
|
|
89139
90008
|
return { ...s, live: nextLive };
|
|
89140
90009
|
}
|
|
@@ -89189,7 +90058,10 @@ function fileModified(s, d2) {
|
|
|
89189
90058
|
affectedFiles: d2.affectedFiles,
|
|
89190
90059
|
trust: d2.trust
|
|
89191
90060
|
};
|
|
89192
|
-
|
|
90061
|
+
const block = f.live?.liveCode;
|
|
90062
|
+
const settlesBlock = !!block && (d2.toolId ? block.id === d2.toolId : block.path === d2.path);
|
|
90063
|
+
const live = settlesBlock && f.live ? { ...f.live, liveCode: null } : f.live;
|
|
90064
|
+
return { ...f, live, settled: [...f.settled, item] };
|
|
89193
90065
|
}
|
|
89194
90066
|
function applyTurnComplete(s, data) {
|
|
89195
90067
|
const flushed = flushLive(s);
|
|
@@ -90235,7 +91107,7 @@ function remoteView(r2) {
|
|
|
90235
91107
|
footer: "Switch with /remote on|off \xB7 hide or show this session with /remote hide|show."
|
|
90236
91108
|
};
|
|
90237
91109
|
}
|
|
90238
|
-
function goalView(running, goal, turns = 0, lastReason = null) {
|
|
91110
|
+
function goalView(running, goal, turns = 0, lastReason = null, lastClaim = null) {
|
|
90239
91111
|
if (!running) {
|
|
90240
91112
|
return {
|
|
90241
91113
|
title: "Goal",
|
|
@@ -90244,7 +91116,12 @@ function goalView(running, goal, turns = 0, lastReason = null) {
|
|
|
90244
91116
|
};
|
|
90245
91117
|
}
|
|
90246
91118
|
const rows = [statusRow("info", "Running", goal), statusRow("info", "Turns", String(turns))];
|
|
90247
|
-
if (
|
|
91119
|
+
if (lastClaim) {
|
|
91120
|
+
const claim = lastClaim.done ? "done" : "not done";
|
|
91121
|
+
const note = (0, import_client_core15.goalReasonLine)(lastClaim.note);
|
|
91122
|
+
rows.push(statusRow("info", "Agent reports", note ? `${claim} \u2014 ${note}` : claim));
|
|
91123
|
+
}
|
|
91124
|
+
if (lastReason) rows.push(statusRow("pending", "Last check", (0, import_client_core15.goalReasonLine)(lastReason)));
|
|
90248
91125
|
return {
|
|
90249
91126
|
title: "Goal",
|
|
90250
91127
|
tone: "info",
|
|
@@ -91458,30 +92335,32 @@ ${(0, import_client_core20.duetRoutingSummaryLine)(await (0, import_client_core2
|
|
|
91458
92335
|
kind: "local",
|
|
91459
92336
|
name: "duet-entry",
|
|
91460
92337
|
aliases: ["entry"],
|
|
91461
|
-
description: "Choose who decides plan vs execute in Duet mode \u2014 the planner, or
|
|
91462
|
-
keywords: ["duet", "planner", "router", "plan", "execute", "hand off"],
|
|
91463
|
-
argumentHint: "[planner|router]",
|
|
92338
|
+
description: "Choose who decides plan vs execute in Duet mode \u2014 the planner, the router, or your executor",
|
|
92339
|
+
keywords: ["duet", "planner", "router", "executor", "plan", "execute", "hand off"],
|
|
92340
|
+
argumentHint: "[planner|router|executor]",
|
|
91464
92341
|
run: async (args2, ctx) => {
|
|
91465
92342
|
const workspaceRoot = ctx.config?.workspaceRoot;
|
|
91466
92343
|
const typed = (0, import_client_core20.normalizeDuetEntry)(args2);
|
|
91467
92344
|
const routerStatus = await (0, import_client_core20.describeDuetRouterModel)().catch(() => null);
|
|
92345
|
+
const executorStatus = await (0, import_client_core20.describeDuetExecutorGateCached)({ workspaceRoot }).catch(() => null);
|
|
91468
92346
|
const save = async (entry) => {
|
|
91469
|
-
const availability = (0, import_client_core20.duetEntryOptionAvailability)(entry, routerStatus);
|
|
92347
|
+
const availability = (0, import_client_core20.duetEntryOptionAvailability)(entry, routerStatus, executorStatus);
|
|
91470
92348
|
if (availability.disabled) {
|
|
91471
92349
|
ctx.print(`${(0, import_client_core20.duetEntryLabel)(entry)}: ${availability.note ?? "unavailable"}`, "warning");
|
|
91472
|
-
if (routerStatus !== null) ctx.print((0, import_client_core20.duetRouterStatusLine)(routerStatus), "info");
|
|
92350
|
+
if (entry === "router" && routerStatus !== null) ctx.print((0, import_client_core20.duetRouterStatusLine)(routerStatus), "info");
|
|
91473
92351
|
return;
|
|
91474
92352
|
}
|
|
91475
92353
|
await (0, import_client_core20.setDuetEntry)(entry);
|
|
91476
92354
|
const option = import_client_core20.DUET_ENTRY_OPTIONS.find((o) => o.value === entry);
|
|
91477
92355
|
ctx.print(`${import_client_core20.DUET_ENTRY_INFO.label}: ${(0, import_client_core20.duetEntryLabel)(entry)} \u2014 ${option?.description ?? ""}`, "success");
|
|
92356
|
+
if (entry === "executor" && executorStatus !== null) ctx.print((0, import_client_core20.executorGateStatusLine)(executorStatus), "info");
|
|
91478
92357
|
};
|
|
91479
92358
|
if (typed !== null) {
|
|
91480
92359
|
await save(typed);
|
|
91481
92360
|
return;
|
|
91482
92361
|
}
|
|
91483
92362
|
if (args2.trim() !== "") {
|
|
91484
|
-
ctx.print("Usage: /duet-entry [planner|router]", "warning");
|
|
92363
|
+
ctx.print("Usage: /duet-entry [planner|router|executor]", "warning");
|
|
91485
92364
|
return;
|
|
91486
92365
|
}
|
|
91487
92366
|
const active = await (0, import_client_core20.loadDuetEntry)({ workspaceRoot });
|
|
@@ -91491,11 +92370,13 @@ ${(0, import_client_core20.duetRoutingSummaryLine)(await (0, import_client_core2
|
|
|
91491
92370
|
kind: "select",
|
|
91492
92371
|
title: `${import_client_core20.DUET_ENTRY_INFO.label} \xB7 current: ${(0, import_client_core20.duetEntryLabel)(active)}`,
|
|
91493
92372
|
options: import_client_core20.DUET_ENTRY_OPTIONS.map((option) => {
|
|
91494
|
-
const availability = (0, import_client_core20.duetEntryOptionAvailability)(option.value, routerStatus);
|
|
92373
|
+
const availability = (0, import_client_core20.duetEntryOptionAvailability)(option.value, routerStatus, executorStatus);
|
|
91495
92374
|
return {
|
|
91496
92375
|
label: option.label,
|
|
91497
92376
|
value: option.value,
|
|
91498
|
-
//
|
|
92377
|
+
// The row's note — what this pick means on THIS machine (a refusal reason for
|
|
92378
|
+
// the router, the rules-floor explainer for the executor) — beats the generic
|
|
92379
|
+
// description.
|
|
91499
92380
|
hint: availability.note ?? (option.value === active ? "(active)" : option.description),
|
|
91500
92381
|
accent: option.value === active
|
|
91501
92382
|
};
|
|
@@ -93180,7 +94061,7 @@ Answer with /loops answer <text>, or /loops deny.`,
|
|
|
93180
94061
|
kind: "local",
|
|
93181
94062
|
name: "goal",
|
|
93182
94063
|
aliases: ["goals"],
|
|
93183
|
-
description: "Work continuously until the goal is complete \u2014
|
|
94064
|
+
description: "Work continuously until the goal is complete \u2014 an independent check confirms it's done",
|
|
93184
94065
|
argumentHint: "<what to accomplish | status | stop>",
|
|
93185
94066
|
// Starting a goal starts a TURN — typed mid-turn it defers to the queue
|
|
93186
94067
|
// (runs when the turn ends) rather than racing the live stream. The verb
|
|
@@ -93200,7 +94081,7 @@ Answer with /loops answer <text>, or /loops deny.`,
|
|
|
93200
94081
|
}
|
|
93201
94082
|
if (arg === "" || lower === "status") {
|
|
93202
94083
|
const st2 = ctx.goals.status();
|
|
93203
|
-
return ctx.printInfo(goalView(st2.running, st2.goal, st2.turns ?? 0, st2.lastReason ?? null));
|
|
94084
|
+
return ctx.printInfo(goalView(st2.running, st2.goal, st2.turns ?? 0, st2.lastReason ?? null, st2.lastClaim ?? null));
|
|
93204
94085
|
}
|
|
93205
94086
|
if (ctx.goals.status().running) {
|
|
93206
94087
|
return ctx.print("A goal is already running \u2014 /goal stop first, or steer it by typing normally.", "warning");
|
|
@@ -93786,6 +94667,9 @@ function renderLane(transcript, app, ev) {
|
|
|
93786
94667
|
transcript.setState(
|
|
93787
94668
|
(s) => fileModified(s, {
|
|
93788
94669
|
path: String(d2.path ?? ""),
|
|
94670
|
+
// The causing call — pairs the diff card with the frozen live code
|
|
94671
|
+
// block it settles (rewind-emitted events legitimately omit it).
|
|
94672
|
+
toolId: typeof d2.tool_id === "string" ? d2.tool_id : void 0,
|
|
93789
94673
|
diff: typeof d2.diff === "string" ? d2.diff : null,
|
|
93790
94674
|
insertions: typeof d2.insertions === "number" ? d2.insertions : 0,
|
|
93791
94675
|
deletions: typeof d2.deletions === "number" ? d2.deletions : 0,
|
|
@@ -93996,11 +94880,8 @@ function renderLane(transcript, app, ev) {
|
|
|
93996
94880
|
}
|
|
93997
94881
|
break;
|
|
93998
94882
|
}
|
|
93999
|
-
case "tool_input_end":
|
|
94000
|
-
const id = typeof d2.tool_id === "string" ? d2.tool_id : "";
|
|
94001
|
-
if (id) transcript.setState((s) => endLiveCode(s, id));
|
|
94883
|
+
case "tool_input_end":
|
|
94002
94884
|
break;
|
|
94003
|
-
}
|
|
94004
94885
|
case "tool_progress": {
|
|
94005
94886
|
const kind = typeof d2.kind === "string" ? d2.kind : "working";
|
|
94006
94887
|
app.setState((s) => ({ ...s, statusText: `${kind}\u2026` }));
|
|
@@ -94130,7 +95011,7 @@ function makeGoalRunTurn(deps2) {
|
|
|
94130
95011
|
}
|
|
94131
95012
|
switch (outcome.kind) {
|
|
94132
95013
|
case "complete":
|
|
94133
|
-
return { text: outcome.finalText, evidence: outcome.evidence };
|
|
95014
|
+
return { text: outcome.finalText, evidence: outcome.evidence, claim: outcome.claim };
|
|
94134
95015
|
case "cancelled":
|
|
94135
95016
|
return "";
|
|
94136
95017
|
case "error":
|
|
@@ -94575,7 +95456,7 @@ var WorkPlanApprovalBridge = class {
|
|
|
94575
95456
|
var import_client_ui_core20 = __toESM(require_dist2(), 1);
|
|
94576
95457
|
|
|
94577
95458
|
// src/components/layout/Transcript.tsx
|
|
94578
|
-
var
|
|
95459
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
94579
95460
|
|
|
94580
95461
|
// src/components/messages/MessageView.tsx
|
|
94581
95462
|
var import_react23 = __toESM(require_react(), 1);
|
|
@@ -110590,7 +111471,27 @@ function expandTabs2(s) {
|
|
|
110590
111471
|
}
|
|
110591
111472
|
return out2;
|
|
110592
111473
|
}
|
|
110593
|
-
function
|
|
111474
|
+
function diffLineStyle(theme, kind) {
|
|
111475
|
+
switch (kind) {
|
|
111476
|
+
case "add":
|
|
111477
|
+
return {
|
|
111478
|
+
bg: theme.diffAddBg,
|
|
111479
|
+
wordBg: theme.diffAddWordBg,
|
|
111480
|
+
accent: theme.diffAdd,
|
|
111481
|
+
text: theme.diffText
|
|
111482
|
+
};
|
|
111483
|
+
case "del":
|
|
111484
|
+
return {
|
|
111485
|
+
bg: theme.diffRemoveBg,
|
|
111486
|
+
wordBg: theme.diffRemoveWordBg,
|
|
111487
|
+
accent: theme.diffRemove,
|
|
111488
|
+
text: theme.diffText
|
|
111489
|
+
};
|
|
111490
|
+
case "context":
|
|
111491
|
+
return { accent: theme.gutter, text: theme.diffText };
|
|
111492
|
+
}
|
|
111493
|
+
}
|
|
111494
|
+
function wordRuns(shown, lang, changed, baseBg, brightBg, syntax, plainFg, theme) {
|
|
110594
111495
|
let text;
|
|
110595
111496
|
let fgs;
|
|
110596
111497
|
if (syntax) {
|
|
@@ -110598,12 +111499,12 @@ function wordRuns(shown, lang, changed, baseBg, brightBg, syntax, theme) {
|
|
|
110598
111499
|
text = spans.map((s) => s.text).join("");
|
|
110599
111500
|
fgs = [];
|
|
110600
111501
|
for (const sp of spans) {
|
|
110601
|
-
const fg = synColor(theme, sp.kind);
|
|
111502
|
+
const fg = synColor(theme, sp.kind) ?? plainFg;
|
|
110602
111503
|
for (let c3 = 0; c3 < sp.text.length; c3++) fgs.push(fg);
|
|
110603
111504
|
}
|
|
110604
111505
|
} else {
|
|
110605
111506
|
text = shown;
|
|
110606
|
-
fgs = new Array(shown.length).fill(
|
|
111507
|
+
fgs = new Array(shown.length).fill(plainFg);
|
|
110607
111508
|
}
|
|
110608
111509
|
const bgAt = (k) => changed[k] ? brightBg : baseBg;
|
|
110609
111510
|
const runs = [];
|
|
@@ -110639,8 +111540,10 @@ function StructuredDiff({
|
|
|
110639
111540
|
}
|
|
110640
111541
|
const isAdd = l3.type === "add";
|
|
110641
111542
|
const isDel = l3.type === "del";
|
|
110642
|
-
const bg
|
|
110643
|
-
|
|
111543
|
+
const { bg, wordBg, accent, text } = diffLineStyle(
|
|
111544
|
+
theme,
|
|
111545
|
+
isAdd ? "add" : isDel ? "del" : "context"
|
|
111546
|
+
);
|
|
110644
111547
|
const marker = isAdd ? "+" : isDel ? "-" : " ";
|
|
110645
111548
|
const num = isDel ? l3.oldNo : l3.newNo;
|
|
110646
111549
|
const raw = expandTabs2(l3.text ?? "");
|
|
@@ -110657,7 +111560,7 @@ function StructuredDiff({
|
|
|
110657
111560
|
while (changed.length < shown.length) changed.push(false);
|
|
110658
111561
|
}
|
|
110659
111562
|
}
|
|
110660
|
-
const body2 = changed ? wordRuns(shown, lang, changed, bg,
|
|
111563
|
+
const body2 = changed ? wordRuns(shown, lang, changed, bg, wordBg, isAdd, text, theme) : isDel ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text2, { color: text, children: shown }) : (highlightCode(shown, lang)[0] ?? []).map((sp, k) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text2, { color: synColor(theme, sp.kind) ?? text, children: sp.text }, k));
|
|
110661
111564
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Text2, { backgroundColor: bg, children: [
|
|
110662
111565
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Text2, { color: accent, children: [
|
|
110663
111566
|
gutter(num),
|
|
@@ -111165,7 +112068,7 @@ function OrionRing() {
|
|
|
111165
112068
|
|
|
111166
112069
|
// src/services/version.ts
|
|
111167
112070
|
function tuiVersion() {
|
|
111168
|
-
return "0.1.
|
|
112071
|
+
return "0.1.25".length > 0 ? "0.1.25" : null;
|
|
111169
112072
|
}
|
|
111170
112073
|
|
|
111171
112074
|
// src/components/layout/WelcomeCard.tsx
|
|
@@ -111204,18 +112107,48 @@ var import_client_ui_core9 = __toESM(require_dist2(), 1);
|
|
|
111204
112107
|
var import_client_core29 = __toESM(require_dist(), 1);
|
|
111205
112108
|
|
|
111206
112109
|
// src/components/messages/Thinking.tsx
|
|
112110
|
+
var import_react24 = __toESM(require_react(), 1);
|
|
111207
112111
|
var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
|
|
111208
|
-
var
|
|
111209
|
-
|
|
111210
|
-
|
|
111211
|
-
|
|
111212
|
-
|
|
112112
|
+
var LIVE_ROWS = 12;
|
|
112113
|
+
function wrapPlain(line, width) {
|
|
112114
|
+
const rows = [];
|
|
112115
|
+
let row = null;
|
|
112116
|
+
for (const word of line.split(" ")) {
|
|
112117
|
+
let w2 = word;
|
|
112118
|
+
while (w2.length > width) {
|
|
112119
|
+
if (row !== null) {
|
|
112120
|
+
rows.push(row);
|
|
112121
|
+
row = null;
|
|
112122
|
+
}
|
|
112123
|
+
rows.push(w2.slice(0, width));
|
|
112124
|
+
w2 = w2.slice(width);
|
|
112125
|
+
}
|
|
112126
|
+
if (w2 === "" && word !== "") continue;
|
|
112127
|
+
if (row === null) row = w2;
|
|
112128
|
+
else if (row.length + 1 + w2.length <= width) row += ` ${w2}`;
|
|
112129
|
+
else {
|
|
112130
|
+
rows.push(row);
|
|
112131
|
+
row = w2;
|
|
112132
|
+
}
|
|
112133
|
+
}
|
|
112134
|
+
if (row !== null) rows.push(row);
|
|
112135
|
+
return rows.length ? rows : [""];
|
|
112136
|
+
}
|
|
112137
|
+
function thinkingTailRows(text, width) {
|
|
112138
|
+
const w2 = Math.max(1, Math.floor(width));
|
|
112139
|
+
const tail = text.split("\n").slice(-LIVE_ROWS).join("\n").trimEnd();
|
|
112140
|
+
if (!tail) return [];
|
|
112141
|
+
const rows = [];
|
|
112142
|
+
for (const line of tail.split("\n")) rows.push(...wrapPlain(line, w2));
|
|
112143
|
+
return rows.slice(-LIVE_ROWS);
|
|
111213
112144
|
}
|
|
111214
112145
|
function Thinking({
|
|
111215
112146
|
text,
|
|
111216
112147
|
spinner = ""
|
|
111217
112148
|
}) {
|
|
111218
112149
|
const { columns } = useTerminalSize();
|
|
112150
|
+
const width = Math.max(20, columns - 4);
|
|
112151
|
+
const rows = import_react24.default.useMemo(() => thinkingTailRows(text, width), [text, width]);
|
|
111219
112152
|
if (!text.trim()) return null;
|
|
111220
112153
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
111221
112154
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Box2, { flexDirection: "row", children: [
|
|
@@ -111223,7 +112156,7 @@ function Thinking({
|
|
|
111223
112156
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { dim: true, italic: true, children: "Thinking" }),
|
|
111224
112157
|
spinner ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { colorKey: "spinner", children: ` ${spinner}` }) : null
|
|
111225
112158
|
] }),
|
|
111226
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { width:
|
|
112159
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { width, flexDirection: "column", children: rows.map((row, i2) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { dim: true, italic: true, wrap: "truncate-end", children: row.length ? row : " " }, i2)) }) })
|
|
111227
112160
|
] });
|
|
111228
112161
|
}
|
|
111229
112162
|
|
|
@@ -111301,21 +112234,21 @@ function LiveCode({
|
|
|
111301
112234
|
}
|
|
111302
112235
|
|
|
111303
112236
|
// src/hooks/useStore.ts
|
|
111304
|
-
var
|
|
112237
|
+
var import_react25 = __toESM(require_react(), 1);
|
|
111305
112238
|
function useStoreSelector(store, selector) {
|
|
111306
|
-
return (0,
|
|
112239
|
+
return (0, import_react25.useSyncExternalStore)(
|
|
111307
112240
|
store.subscribe,
|
|
111308
112241
|
() => selector(store.getState())
|
|
111309
112242
|
);
|
|
111310
112243
|
}
|
|
111311
112244
|
|
|
111312
112245
|
// src/hooks/useTranscriptEviction.ts
|
|
111313
|
-
var
|
|
112246
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
111314
112247
|
|
|
111315
112248
|
// src/vendor/ink/hooks/use-committed-rows.ts
|
|
111316
|
-
var
|
|
112249
|
+
var import_react26 = __toESM(require_react(), 1);
|
|
111317
112250
|
function useCommittedRows() {
|
|
111318
|
-
return (0,
|
|
112251
|
+
return (0, import_react26.useContext)(CommittedRowsContext);
|
|
111319
112252
|
}
|
|
111320
112253
|
|
|
111321
112254
|
// src/hooks/useTranscriptEviction.ts
|
|
@@ -111341,14 +112274,14 @@ function useTranscriptEviction({
|
|
|
111341
112274
|
getItemsContainer
|
|
111342
112275
|
}) {
|
|
111343
112276
|
const api = useCommittedRows();
|
|
111344
|
-
const forkSize = (0,
|
|
112277
|
+
const forkSize = (0, import_react27.useContext)(TerminalSizeContext);
|
|
111345
112278
|
const fallbackSize = useTerminalSize();
|
|
111346
112279
|
const rows = forkSize?.rows ?? fallbackSize.rows;
|
|
111347
112280
|
const evictedCount = useStoreSelector(transcriptStore, (s) => s.evictedCount);
|
|
111348
112281
|
const committedCount = useStoreSelector(transcriptStore, (s) => s.committedCount);
|
|
111349
|
-
const apiRef = (0,
|
|
112282
|
+
const apiRef = (0, import_react27.useRef)(api);
|
|
111350
112283
|
apiRef.current = api;
|
|
111351
|
-
(0,
|
|
112284
|
+
(0, import_react27.useLayoutEffect)(() => {
|
|
111352
112285
|
const snap = (s) => ({
|
|
111353
112286
|
sessionId: s.sessionId,
|
|
111354
112287
|
settledLength: s.settled.length,
|
|
@@ -111363,7 +112296,7 @@ function useTranscriptEviction({
|
|
|
111363
112296
|
prev = s;
|
|
111364
112297
|
});
|
|
111365
112298
|
}, [transcriptStore]);
|
|
111366
|
-
(0,
|
|
112299
|
+
(0, import_react27.useEffect)(() => {
|
|
111367
112300
|
if (!enabled || !api || items.length <= 1) return;
|
|
111368
112301
|
const container = getItemsContainer();
|
|
111369
112302
|
if (!container) return;
|
|
@@ -111411,15 +112344,15 @@ function Transcript({
|
|
|
111411
112344
|
const subAgents = useStoreSelector(appStore, (s) => s.subAgents);
|
|
111412
112345
|
const subagentsAwaiting = useStoreSelector(appStore, (s) => s.subagentsAwaiting);
|
|
111413
112346
|
const { columns } = useTerminalSize();
|
|
111414
|
-
const items =
|
|
112347
|
+
const items = import_react28.default.useMemo(
|
|
111415
112348
|
() => groupToolRuns(evictedCount > 0 ? settled.slice(evictedCount) : settled),
|
|
111416
112349
|
[settled, evictedCount]
|
|
111417
112350
|
);
|
|
111418
|
-
const itemsContainerRef =
|
|
111419
|
-
const setItemsContainer =
|
|
112351
|
+
const itemsContainerRef = import_react28.default.useRef(null);
|
|
112352
|
+
const setItemsContainer = import_react28.default.useCallback((el) => {
|
|
111420
112353
|
itemsContainerRef.current = el;
|
|
111421
112354
|
}, []);
|
|
111422
|
-
const getItemsContainer =
|
|
112355
|
+
const getItemsContainer = import_react28.default.useCallback(() => itemsContainerRef.current, []);
|
|
111423
112356
|
useTranscriptEviction({ enabled: evictionEnabled, transcriptStore, items, getItemsContainer });
|
|
111424
112357
|
const running = live?.runningTool ?? null;
|
|
111425
112358
|
const foldTail = running && !verbose ? trailingToolRun(items) : null;
|
|
@@ -111453,10 +112386,10 @@ function Transcript({
|
|
|
111453
112386
|
}
|
|
111454
112387
|
|
|
111455
112388
|
// src/components/layout/ReplFooter.tsx
|
|
111456
|
-
var
|
|
112389
|
+
var import_react47 = __toESM(require_react(), 1);
|
|
111457
112390
|
|
|
111458
112391
|
// src/components/tools/PlanCard.tsx
|
|
111459
|
-
var
|
|
112392
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
111460
112393
|
var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
|
|
111461
112394
|
function planStepView(index, currentStep) {
|
|
111462
112395
|
const done2 = index + 1 < currentStep;
|
|
@@ -111481,8 +112414,8 @@ function PlanCard({ plan }) {
|
|
|
111481
112414
|
const total = plan.steps.length;
|
|
111482
112415
|
const allDone = total > 0 && plan.current_step > total;
|
|
111483
112416
|
const planKey = `${plan.current_step}|${plan.steps.join("\0")}`;
|
|
111484
|
-
const [hiddenKey, setHiddenKey] =
|
|
111485
|
-
|
|
112417
|
+
const [hiddenKey, setHiddenKey] = import_react29.default.useState(null);
|
|
112418
|
+
import_react29.default.useEffect(() => {
|
|
111486
112419
|
if (!allDone) return;
|
|
111487
112420
|
const t = setTimeout(() => setHiddenKey(planKey), DONE_HOLD_MS);
|
|
111488
112421
|
return () => clearTimeout(t);
|
|
@@ -111516,7 +112449,7 @@ function PlanCard({ plan }) {
|
|
|
111516
112449
|
}
|
|
111517
112450
|
|
|
111518
112451
|
// src/components/tools/SubAgentCard.tsx
|
|
111519
|
-
var
|
|
112452
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
111520
112453
|
var import_client_core30 = __toESM(require_dist(), 1);
|
|
111521
112454
|
var import_client_ui_core10 = __toESM(require_dist2(), 1);
|
|
111522
112455
|
var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -111536,8 +112469,8 @@ function SubAgentList({
|
|
|
111536
112469
|
}) {
|
|
111537
112470
|
const running = agents.filter((a) => a.phase !== "finished");
|
|
111538
112471
|
const visible = !awaiting && running.length > 0;
|
|
111539
|
-
const [now2, setNow] =
|
|
111540
|
-
|
|
112472
|
+
const [now2, setNow] = import_react30.default.useState(() => Date.now());
|
|
112473
|
+
import_react30.default.useEffect(() => {
|
|
111541
112474
|
if (!visible) return void 0;
|
|
111542
112475
|
const timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
111543
112476
|
return () => clearInterval(timer);
|
|
@@ -111553,7 +112486,7 @@ function SubAgentList({
|
|
|
111553
112486
|
}
|
|
111554
112487
|
|
|
111555
112488
|
// src/components/input/PromptInput.tsx
|
|
111556
|
-
var
|
|
112489
|
+
var import_react32 = __toESM(require_react(), 1);
|
|
111557
112490
|
|
|
111558
112491
|
// src/components/input/slashSegments.ts
|
|
111559
112492
|
function segmentSlice(text, offset, ranges) {
|
|
@@ -112330,7 +113263,7 @@ function vimKeypress(st2, buffer, input, key) {
|
|
|
112330
113263
|
}
|
|
112331
113264
|
|
|
112332
113265
|
// src/voice/useHoldToTalk.ts
|
|
112333
|
-
var
|
|
113266
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
112334
113267
|
var REPEAT_GAP_MS = 120;
|
|
112335
113268
|
var WARMUP_THRESHOLD = 2;
|
|
112336
113269
|
var HOLD_THRESHOLD = 5;
|
|
@@ -112488,9 +113421,9 @@ function spliceTranscript(value, cursor, text) {
|
|
|
112488
113421
|
return { value: before + inserted + after, cursor: cursor + lead.length + text.length };
|
|
112489
113422
|
}
|
|
112490
113423
|
function useHoldToTalk(opts) {
|
|
112491
|
-
const optsRef = (0,
|
|
113424
|
+
const optsRef = (0, import_react31.useRef)(opts);
|
|
112492
113425
|
optsRef.current = opts;
|
|
112493
|
-
const machineRef = (0,
|
|
113426
|
+
const machineRef = (0, import_react31.useRef)(null);
|
|
112494
113427
|
if (!machineRef.current) {
|
|
112495
113428
|
machineRef.current = createHoldToTalk(
|
|
112496
113429
|
{
|
|
@@ -112570,37 +113503,37 @@ function PromptInput({
|
|
|
112570
113503
|
mode,
|
|
112571
113504
|
permissionMode
|
|
112572
113505
|
}) {
|
|
112573
|
-
const [value, setValue2] = (0,
|
|
112574
|
-
const [cursor, setCursor] = (0,
|
|
112575
|
-
const [history, setHistory] = (0,
|
|
113506
|
+
const [value, setValue2] = (0, import_react32.useState)("");
|
|
113507
|
+
const [cursor, setCursor] = (0, import_react32.useState)(0);
|
|
113508
|
+
const [history, setHistory] = (0, import_react32.useState)(
|
|
112576
113509
|
() => (initialHistory ?? []).slice(0, HISTORY_LIMIT)
|
|
112577
113510
|
);
|
|
112578
|
-
const [vimState, setVimState] = (0,
|
|
112579
|
-
const [menuIdx, setMenuIdx] = (0,
|
|
112580
|
-
const [menuDismissed, setMenuDismissed] = (0,
|
|
112581
|
-
const [search, setSearch] = (0,
|
|
112582
|
-
const [escArmed, setEscArmed] = (0,
|
|
112583
|
-
const [exitArmed, setExitArmed] = (0,
|
|
112584
|
-
const [postureFlash, setPostureFlash] = (0,
|
|
112585
|
-
const chordRef = (0,
|
|
112586
|
-
const escAtRef = (0,
|
|
112587
|
-
const exitAtRef = (0,
|
|
112588
|
-
const valueRef = (0,
|
|
113511
|
+
const [vimState, setVimState] = (0, import_react32.useState)(() => initialVimState("insert"));
|
|
113512
|
+
const [menuIdx, setMenuIdx] = (0, import_react32.useState)(0);
|
|
113513
|
+
const [menuDismissed, setMenuDismissed] = (0, import_react32.useState)(false);
|
|
113514
|
+
const [search, setSearch] = (0, import_react32.useState)(null);
|
|
113515
|
+
const [escArmed, setEscArmed] = (0, import_react32.useState)(false);
|
|
113516
|
+
const [exitArmed, setExitArmed] = (0, import_react32.useState)(null);
|
|
113517
|
+
const [postureFlash, setPostureFlash] = (0, import_react32.useState)(false);
|
|
113518
|
+
const chordRef = (0, import_react32.useRef)(emptyChord());
|
|
113519
|
+
const escAtRef = (0, import_react32.useRef)(0);
|
|
113520
|
+
const exitAtRef = (0, import_react32.useRef)(0);
|
|
113521
|
+
const valueRef = (0, import_react32.useRef)(value);
|
|
112589
113522
|
valueRef.current = value;
|
|
112590
|
-
const cursorRef = (0,
|
|
113523
|
+
const cursorRef = (0, import_react32.useRef)(cursor);
|
|
112591
113524
|
cursorRef.current = cursor;
|
|
112592
|
-
const pasteLedger = (0,
|
|
112593
|
-
const recall = (0,
|
|
112594
|
-
const wheelRef = (0,
|
|
112595
|
-
const flashTimer = (0,
|
|
112596
|
-
const firstPosture = (0,
|
|
113525
|
+
const pasteLedger = (0, import_react32.useRef)({ nextId: 1, texts: /* @__PURE__ */ new Map() });
|
|
113526
|
+
const recall = (0, import_react32.useRef)(NOT_RECALLING);
|
|
113527
|
+
const wheelRef = (0, import_react32.useRef)(createWheelAccel());
|
|
113528
|
+
const flashTimer = (0, import_react32.useRef)(null);
|
|
113529
|
+
const firstPosture = (0, import_react32.useRef)(true);
|
|
112597
113530
|
const theme = useTheme();
|
|
112598
113531
|
const { rows } = useTerminalSize();
|
|
112599
|
-
const [voiceState, setVoiceState] = (0,
|
|
112600
|
-
const [voiceProgress, setVoiceProgress] = (0,
|
|
112601
|
-
const [voiceError, setVoiceError] = (0,
|
|
112602
|
-
const [voiceBlink, setVoiceBlink] = (0,
|
|
112603
|
-
(0,
|
|
113532
|
+
const [voiceState, setVoiceState] = (0, import_react32.useState)("idle");
|
|
113533
|
+
const [voiceProgress, setVoiceProgress] = (0, import_react32.useState)(null);
|
|
113534
|
+
const [voiceError, setVoiceError] = (0, import_react32.useState)(null);
|
|
113535
|
+
const [voiceBlink, setVoiceBlink] = (0, import_react32.useState)(false);
|
|
113536
|
+
(0, import_react32.useEffect)(() => {
|
|
112604
113537
|
if (voiceState !== "recording") return;
|
|
112605
113538
|
const t = setInterval(() => setVoiceBlink((b2) => !b2), 600);
|
|
112606
113539
|
return () => {
|
|
@@ -112608,7 +113541,7 @@ function PromptInput({
|
|
|
112608
113541
|
setVoiceBlink(false);
|
|
112609
113542
|
};
|
|
112610
113543
|
}, [voiceState]);
|
|
112611
|
-
const micRef = (0,
|
|
113544
|
+
const micRef = (0, import_react32.useRef)(null);
|
|
112612
113545
|
const holdToTalk = useHoldToTalk({
|
|
112613
113546
|
getBuffer: () => ({ value: valueRef.current, cursor: cursorRef.current }),
|
|
112614
113547
|
applyBuffer: (v2, c3) => {
|
|
@@ -112644,11 +113577,11 @@ function PromptInput({
|
|
|
112644
113577
|
}
|
|
112645
113578
|
}
|
|
112646
113579
|
});
|
|
112647
|
-
(0,
|
|
112648
|
-
(0,
|
|
113580
|
+
(0, import_react32.useEffect)(() => () => holdToTalk.dispose(), []);
|
|
113581
|
+
(0, import_react32.useEffect)(() => {
|
|
112649
113582
|
if (vim) setVimState(initialVimState("insert"));
|
|
112650
113583
|
}, [vim]);
|
|
112651
|
-
(0,
|
|
113584
|
+
(0, import_react32.useEffect)(() => {
|
|
112652
113585
|
if (firstPosture.current) {
|
|
112653
113586
|
firstPosture.current = false;
|
|
112654
113587
|
return;
|
|
@@ -112660,7 +113593,7 @@ function PromptInput({
|
|
|
112660
113593
|
if (flashTimer.current) clearTimeout(flashTimer.current);
|
|
112661
113594
|
};
|
|
112662
113595
|
}, [mode, permissionMode]);
|
|
112663
|
-
const pickedMentions = (0,
|
|
113596
|
+
const pickedMentions = (0, import_react32.useRef)(/* @__PURE__ */ new Set());
|
|
112664
113597
|
const suggestionsFor = (v2) => v2.startsWith("/") && !v2.includes(" ") ? getCompletions?.(v2) ?? [] : [];
|
|
112665
113598
|
const suggestions = suggestionsFor(value);
|
|
112666
113599
|
const mPfx = mentionPrefix(value, cursor);
|
|
@@ -112668,18 +113601,18 @@ function PromptInput({
|
|
|
112668
113601
|
const menuFiles = fileSuggestions.length > 0;
|
|
112669
113602
|
const menuLen = menuFiles ? fileSuggestions.length : suggestions.length;
|
|
112670
113603
|
const menuOpen = !menuDismissed && menuLen > 0 && (!vim || vimState.mode === "insert");
|
|
112671
|
-
const notifyMenuRef = (0,
|
|
113604
|
+
const notifyMenuRef = (0, import_react32.useRef)(onMenuOpenChange);
|
|
112672
113605
|
notifyMenuRef.current = onMenuOpenChange;
|
|
112673
|
-
(0,
|
|
113606
|
+
(0, import_react32.useEffect)(() => {
|
|
112674
113607
|
notifyMenuRef.current?.(menuOpen);
|
|
112675
113608
|
}, [menuOpen]);
|
|
112676
|
-
(0,
|
|
112677
|
-
(0,
|
|
113609
|
+
(0, import_react32.useEffect)(() => () => notifyMenuRef.current?.(false), []);
|
|
113610
|
+
(0, import_react32.useEffect)(() => {
|
|
112678
113611
|
for (const path14 of pickedMentions.current) {
|
|
112679
113612
|
if (!value.includes(`${import_client_core32.FILE_MENTION_LEADER}${path14}`)) pickedMentions.current.delete(path14);
|
|
112680
113613
|
}
|
|
112681
113614
|
}, [value]);
|
|
112682
|
-
(0,
|
|
113615
|
+
(0, import_react32.useEffect)(() => {
|
|
112683
113616
|
setMenuIdx(0);
|
|
112684
113617
|
setMenuDismissed(false);
|
|
112685
113618
|
setEscArmed(false);
|
|
@@ -113131,7 +114064,7 @@ function PromptInput({
|
|
|
113131
114064
|
}
|
|
113132
114065
|
|
|
113133
114066
|
// src/hooks/useIndexBadge.ts
|
|
113134
|
-
var
|
|
114067
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
113135
114068
|
var READY_BADGE_LINGER_MS = 3e3;
|
|
113136
114069
|
function shouldShowIndexBadge(mode, phase, lingerElapsed) {
|
|
113137
114070
|
if (mode !== "on") return true;
|
|
@@ -113139,8 +114072,8 @@ function shouldShowIndexBadge(mode, phase, lingerElapsed) {
|
|
|
113139
114072
|
return !lingerElapsed;
|
|
113140
114073
|
}
|
|
113141
114074
|
function useIndexBadgeVisible(mode, phase, lingerMs = READY_BADGE_LINGER_MS) {
|
|
113142
|
-
const [lingerElapsed, setLingerElapsed] = (0,
|
|
113143
|
-
(0,
|
|
114075
|
+
const [lingerElapsed, setLingerElapsed] = (0, import_react33.useState)(false);
|
|
114076
|
+
(0, import_react33.useEffect)(() => {
|
|
113144
114077
|
setLingerElapsed(false);
|
|
113145
114078
|
if (phase !== "ready") return;
|
|
113146
114079
|
const timer = setTimeout(() => setLingerElapsed(true), lingerMs);
|
|
@@ -113303,7 +114236,7 @@ function StatusBar({
|
|
|
113303
114236
|
}
|
|
113304
114237
|
|
|
113305
114238
|
// src/components/dialogs/AskUserPrompt.tsx
|
|
113306
|
-
var
|
|
114239
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
113307
114240
|
var import_client_ui_core11 = __toESM(require_dist2(), 1);
|
|
113308
114241
|
|
|
113309
114242
|
// src/components/dialogs/LineEditor.tsx
|
|
@@ -113355,15 +114288,15 @@ function AskUserPrompt({
|
|
|
113355
114288
|
guardMs = 250
|
|
113356
114289
|
}) {
|
|
113357
114290
|
const { requestId, sessionId } = pending;
|
|
113358
|
-
const card = (0,
|
|
114291
|
+
const card = (0, import_react34.useMemo)(() => (0, import_client_ui_core11.buildAskCard)(pending.request), [pending.request]);
|
|
113359
114292
|
const questions = card.questions;
|
|
113360
|
-
const [selections, setSelections] = (0,
|
|
114293
|
+
const [selections, setSelections] = (0, import_react34.useState)(
|
|
113361
114294
|
() => questions.map(() => import_client_ui_core11.EMPTY_SELECTION)
|
|
113362
114295
|
);
|
|
113363
|
-
const [index, setIndex] = (0,
|
|
113364
|
-
const [cursor, setCursor] = (0,
|
|
113365
|
-
const [draft, setDraft] = (0,
|
|
113366
|
-
const guard = (0,
|
|
114296
|
+
const [index, setIndex] = (0, import_react34.useState)(0);
|
|
114297
|
+
const [cursor, setCursor] = (0, import_react34.useState)(0);
|
|
114298
|
+
const [draft, setDraft] = (0, import_react34.useState)(null);
|
|
114299
|
+
const guard = (0, import_react34.useRef)({ id: requestId, at: Date.now() });
|
|
113367
114300
|
if (guard.current.id !== requestId) {
|
|
113368
114301
|
guard.current = { id: requestId, at: Date.now() };
|
|
113369
114302
|
}
|
|
@@ -113509,7 +114442,7 @@ function writtenInPreview(selection) {
|
|
|
113509
114442
|
}
|
|
113510
114443
|
|
|
113511
114444
|
// src/components/dialogs/FeedbackPrompt.tsx
|
|
113512
|
-
var
|
|
114445
|
+
var import_react35 = __toESM(require_react(), 1);
|
|
113513
114446
|
var import_client_ui_core12 = __toESM(require_dist2(), 1);
|
|
113514
114447
|
var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
|
|
113515
114448
|
function FeedbackPrompt({
|
|
@@ -113519,10 +114452,10 @@ function FeedbackPrompt({
|
|
|
113519
114452
|
guardMs = 250
|
|
113520
114453
|
}) {
|
|
113521
114454
|
const { requestId } = pending;
|
|
113522
|
-
const [score, setScore] = (0,
|
|
113523
|
-
const [why, setWhy] = (0,
|
|
114455
|
+
const [score, setScore] = (0, import_react35.useState)(0);
|
|
114456
|
+
const [why, setWhy] = (0, import_react35.useState)(null);
|
|
113524
114457
|
const theme = useTheme();
|
|
113525
|
-
const guard = (0,
|
|
114458
|
+
const guard = (0, import_react35.useRef)({ id: requestId, at: Date.now() });
|
|
113526
114459
|
if (guard.current.id !== requestId) {
|
|
113527
114460
|
guard.current = { id: requestId, at: Date.now() };
|
|
113528
114461
|
}
|
|
@@ -113571,13 +114504,13 @@ function FeedbackPrompt({
|
|
|
113571
114504
|
}
|
|
113572
114505
|
|
|
113573
114506
|
// src/components/dialogs/PermissionPrompt.tsx
|
|
113574
|
-
var
|
|
114507
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
113575
114508
|
var import_client_ui_core13 = __toESM(require_dist2(), 1);
|
|
113576
114509
|
var import_client_ui_core14 = __toESM(require_dist2(), 1);
|
|
113577
114510
|
var import_client_core34 = __toESM(require_dist(), 1);
|
|
113578
114511
|
|
|
113579
114512
|
// src/components/dialogs/SelectList.tsx
|
|
113580
|
-
var
|
|
114513
|
+
var import_react36 = __toESM(require_react(), 1);
|
|
113581
114514
|
var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
|
|
113582
114515
|
function SelectList({
|
|
113583
114516
|
title,
|
|
@@ -113589,17 +114522,17 @@ function SelectList({
|
|
|
113589
114522
|
maxVisible
|
|
113590
114523
|
}) {
|
|
113591
114524
|
const { rows } = useTerminalSize();
|
|
113592
|
-
const [query, setQuery] = (0,
|
|
113593
|
-
const view = (0,
|
|
114525
|
+
const [query, setQuery] = (0, import_react36.useState)("");
|
|
114526
|
+
const view = (0, import_react36.useMemo)(() => {
|
|
113594
114527
|
if (!filterable) return options;
|
|
113595
114528
|
const q2 = query.trim().toLowerCase();
|
|
113596
114529
|
if (!q2) return options;
|
|
113597
114530
|
return options.filter((o) => !o.separator && o.label.toLowerCase().includes(q2));
|
|
113598
114531
|
}, [options, query, filterable]);
|
|
113599
114532
|
const selectable = view.flatMap((o, i2) => o.separator ? [] : [i2]);
|
|
113600
|
-
const [idx, setIdx] = (0,
|
|
114533
|
+
const [idx, setIdx] = (0, import_react36.useState)(selectable[0] ?? 0);
|
|
113601
114534
|
const safeIdx = selectable.includes(idx) ? idx : selectable[0] ?? 0;
|
|
113602
|
-
(0,
|
|
114535
|
+
(0, import_react36.useEffect)(() => {
|
|
113603
114536
|
if (filterable) setIdx(selectable[0] ?? 0);
|
|
113604
114537
|
}, [query, filterable]);
|
|
113605
114538
|
const move = (dir) => {
|
|
@@ -113700,12 +114633,12 @@ function PermissionPrompt({
|
|
|
113700
114633
|
guardMs = 250
|
|
113701
114634
|
}) {
|
|
113702
114635
|
const { data, sessionId } = pending;
|
|
113703
|
-
const model = (0,
|
|
114636
|
+
const model = (0, import_react37.useMemo)(
|
|
113704
114637
|
() => (0, import_client_ui_core13.buildPermissionCard)(data, { agentLabel: pending.agentLabel ?? null }),
|
|
113705
114638
|
[data, pending.agentLabel]
|
|
113706
114639
|
);
|
|
113707
|
-
const [stage, setStage] = (0,
|
|
113708
|
-
const guard = (0,
|
|
114640
|
+
const [stage, setStage] = (0, import_react37.useState)({ kind: "choose" });
|
|
114641
|
+
const guard = (0, import_react37.useRef)({ id: data.request_id, at: Date.now() });
|
|
113709
114642
|
if (guard.current.id !== data.request_id) {
|
|
113710
114643
|
guard.current = { id: data.request_id, at: Date.now() };
|
|
113711
114644
|
if (stage.kind !== "choose") setStage({ kind: "choose" });
|
|
@@ -113880,7 +114813,7 @@ function PermissionPrompt({
|
|
|
113880
114813
|
}
|
|
113881
114814
|
|
|
113882
114815
|
// src/components/dialogs/EndpointsPanel.tsx
|
|
113883
|
-
var
|
|
114816
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
113884
114817
|
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
|
|
113885
114818
|
function maskedKeyState(e) {
|
|
113886
114819
|
if (e.apiKey) return `key \u2022\u2022\u2022\u2022${e.apiKey.slice(-4)}`;
|
|
@@ -113910,20 +114843,20 @@ function EndpointsPanel({
|
|
|
113910
114843
|
deps: deps2,
|
|
113911
114844
|
onClose
|
|
113912
114845
|
}) {
|
|
113913
|
-
const [overlay, setOverlay] = (0,
|
|
113914
|
-
const [name2, setName] = (0,
|
|
113915
|
-
const [url, setUrl] = (0,
|
|
113916
|
-
const [wire, setWire] = (0,
|
|
113917
|
-
const [key, setKey] = (0,
|
|
113918
|
-
const [selected, setSelected] = (0,
|
|
113919
|
-
const [discovered, setDiscovered] = (0,
|
|
113920
|
-
const [modelConfig, setModelConfig] = (0,
|
|
113921
|
-
const [editing, setEditing] = (0,
|
|
113922
|
-
const [configDraft, setConfigDraft] = (0,
|
|
113923
|
-
const [savedPins, setSavedPins] = (0,
|
|
113924
|
-
const [savedConfig, setSavedConfig] = (0,
|
|
113925
|
-
const [fetching, setFetching] = (0,
|
|
113926
|
-
const [note, setNote] = (0,
|
|
114846
|
+
const [overlay, setOverlay] = (0, import_react38.useState)(null);
|
|
114847
|
+
const [name2, setName] = (0, import_react38.useState)("");
|
|
114848
|
+
const [url, setUrl] = (0, import_react38.useState)("");
|
|
114849
|
+
const [wire, setWire] = (0, import_react38.useState)("openai");
|
|
114850
|
+
const [key, setKey] = (0, import_react38.useState)("");
|
|
114851
|
+
const [selected, setSelected] = (0, import_react38.useState)(/* @__PURE__ */ new Set());
|
|
114852
|
+
const [discovered, setDiscovered] = (0, import_react38.useState)(null);
|
|
114853
|
+
const [modelConfig, setModelConfig] = (0, import_react38.useState)({});
|
|
114854
|
+
const [editing, setEditing] = (0, import_react38.useState)(null);
|
|
114855
|
+
const [configDraft, setConfigDraft] = (0, import_react38.useState)("");
|
|
114856
|
+
const [savedPins, setSavedPins] = (0, import_react38.useState)(/* @__PURE__ */ new Set());
|
|
114857
|
+
const [savedConfig, setSavedConfig] = (0, import_react38.useState)({});
|
|
114858
|
+
const [fetching, setFetching] = (0, import_react38.useState)(false);
|
|
114859
|
+
const [note, setNote] = (0, import_react38.useState)(null);
|
|
113927
114860
|
const slots = [
|
|
113928
114861
|
...deps2.entries.map((_2, index) => ({ kind: "entry", index })),
|
|
113929
114862
|
{ kind: "field", field: "name" },
|
|
@@ -113933,9 +114866,9 @@ function EndpointsPanel({
|
|
|
113933
114866
|
{ kind: "action", action: "fetch" },
|
|
113934
114867
|
{ kind: "action", action: "save" }
|
|
113935
114868
|
];
|
|
113936
|
-
const [at, setAt] = (0,
|
|
114869
|
+
const [at, setAt] = (0, import_react38.useState)(deps2.entries.length);
|
|
113937
114870
|
const slot = slots[Math.min(at, slots.length - 1)];
|
|
113938
|
-
const [verifiedFor, setVerifiedFor] = (0,
|
|
114871
|
+
const [verifiedFor, setVerifiedFor] = (0, import_react38.useState)(null);
|
|
113939
114872
|
const fingerprint = `${url.trim()}\0${key}`;
|
|
113940
114873
|
const verified = verifiedFor === fingerprint;
|
|
113941
114874
|
const resetForm = () => {
|
|
@@ -114422,7 +115355,7 @@ function EndpointsPanel({
|
|
|
114422
115355
|
}
|
|
114423
115356
|
|
|
114424
115357
|
// src/components/dialogs/PermissionRulesPanel.tsx
|
|
114425
|
-
var
|
|
115358
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
114426
115359
|
var import_client_core35 = __toESM(require_dist(), 1);
|
|
114427
115360
|
var import_client_ui_core15 = __toESM(require_dist2(), 1);
|
|
114428
115361
|
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -114432,7 +115365,7 @@ function PermissionRulesPanel({
|
|
|
114432
115365
|
add,
|
|
114433
115366
|
onClose
|
|
114434
115367
|
}) {
|
|
114435
|
-
const [stage, setStage] = (0,
|
|
115368
|
+
const [stage, setStage] = (0, import_react39.useState)({ kind: "list" });
|
|
114436
115369
|
use_input_default((input, key) => {
|
|
114437
115370
|
if (stage.kind !== "list") {
|
|
114438
115371
|
if (stage.kind === "add-rule") {
|
|
@@ -114532,7 +115465,7 @@ function PermissionRulesPanel({
|
|
|
114532
115465
|
}
|
|
114533
115466
|
|
|
114534
115467
|
// src/components/dialogs/PlanApprovalPrompt.tsx
|
|
114535
|
-
var
|
|
115468
|
+
var import_react40 = __toESM(require_react(), 1);
|
|
114536
115469
|
var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
|
|
114537
115470
|
function PlanApprovalPrompt({
|
|
114538
115471
|
pending,
|
|
@@ -114541,7 +115474,7 @@ function PlanApprovalPrompt({
|
|
|
114541
115474
|
guardMs = 250
|
|
114542
115475
|
}) {
|
|
114543
115476
|
const { requestId, sessionId } = pending;
|
|
114544
|
-
const guard = (0,
|
|
115477
|
+
const guard = (0, import_react40.useRef)({ id: requestId, at: Date.now() });
|
|
114545
115478
|
if (guard.current.id !== requestId) guard.current = { id: requestId, at: Date.now() };
|
|
114546
115479
|
use_input_default((input, key) => {
|
|
114547
115480
|
if (key.ctrl && input === "c") {
|
|
@@ -114575,7 +115508,7 @@ function PlanApprovalPrompt({
|
|
|
114575
115508
|
}
|
|
114576
115509
|
|
|
114577
115510
|
// src/components/dialogs/WorkPlanApprovalPrompt.tsx
|
|
114578
|
-
var
|
|
115511
|
+
var import_react41 = __toESM(require_react(), 1);
|
|
114579
115512
|
var import_client_core36 = __toESM(require_dist(), 1);
|
|
114580
115513
|
var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
|
|
114581
115514
|
function WorkPlanApprovalPrompt({
|
|
@@ -114585,7 +115518,7 @@ function WorkPlanApprovalPrompt({
|
|
|
114585
115518
|
guardMs = 250
|
|
114586
115519
|
}) {
|
|
114587
115520
|
const { requestId, plan } = pending;
|
|
114588
|
-
const guard = (0,
|
|
115521
|
+
const guard = (0, import_react41.useRef)({ id: requestId, at: Date.now() });
|
|
114589
115522
|
if (guard.current.id !== requestId) guard.current = { id: requestId, at: Date.now() };
|
|
114590
115523
|
use_input_default((input, key) => {
|
|
114591
115524
|
if (key.ctrl && input === "c") {
|
|
@@ -114654,7 +115587,7 @@ function ConfirmDialog({ dialog }) {
|
|
|
114654
115587
|
}
|
|
114655
115588
|
|
|
114656
115589
|
// src/components/dialogs/HooksBrowser.tsx
|
|
114657
|
-
var
|
|
115590
|
+
var import_react42 = __toESM(require_react(), 1);
|
|
114658
115591
|
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
|
|
114659
115592
|
function matcherLabel(m2) {
|
|
114660
115593
|
if (!m2 || typeof m2 !== "object") return "(any)";
|
|
@@ -114722,9 +115655,9 @@ function HooksBrowser({
|
|
|
114722
115655
|
hooks,
|
|
114723
115656
|
onClose
|
|
114724
115657
|
}) {
|
|
114725
|
-
const [event, setEvent] = (0,
|
|
114726
|
-
const [matcher, setMatcher] = (0,
|
|
114727
|
-
const [hookIdx, setHookIdx] = (0,
|
|
115658
|
+
const [event, setEvent] = (0, import_react42.useState)(null);
|
|
115659
|
+
const [matcher, setMatcher] = (0, import_react42.useState)(null);
|
|
115660
|
+
const [hookIdx, setHookIdx] = (0, import_react42.useState)(null);
|
|
114728
115661
|
if (event === null) {
|
|
114729
115662
|
const events = [...new Set(hooks.map((h) => h.event ?? "(unknown)"))].sort();
|
|
114730
115663
|
const options = events.map((e) => {
|
|
@@ -114777,7 +115710,7 @@ function HooksBrowser({
|
|
|
114777
115710
|
}
|
|
114778
115711
|
|
|
114779
115712
|
// src/components/dialogs/PluginManager.tsx
|
|
114780
|
-
var
|
|
115713
|
+
var import_react43 = __toESM(require_react(), 1);
|
|
114781
115714
|
var import_client_core37 = __toESM(require_dist(), 1);
|
|
114782
115715
|
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
|
|
114783
115716
|
function pluginId(p) {
|
|
@@ -114796,8 +115729,8 @@ function PluginManager({
|
|
|
114796
115729
|
install,
|
|
114797
115730
|
onClose
|
|
114798
115731
|
}) {
|
|
114799
|
-
const [view, setView] = (0,
|
|
114800
|
-
const [busy, setBusy] = (0,
|
|
115732
|
+
const [view, setView] = (0, import_react43.useState)({ at: "list" });
|
|
115733
|
+
const [busy, setBusy] = (0, import_react43.useState)(false);
|
|
114801
115734
|
const finish = (work) => {
|
|
114802
115735
|
setBusy(true);
|
|
114803
115736
|
void work.finally(() => {
|
|
@@ -114950,7 +115883,7 @@ Install "${view.id}" from "${view.catalog}" (${scope} scope)?`,
|
|
|
114950
115883
|
}
|
|
114951
115884
|
|
|
114952
115885
|
// src/components/dialogs/RewindPicker.tsx
|
|
114953
|
-
var
|
|
115886
|
+
var import_react44 = __toESM(require_react(), 1);
|
|
114954
115887
|
var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
|
|
114955
115888
|
function statLabel(t) {
|
|
114956
115889
|
if (!t.files) return "no code changes";
|
|
@@ -114965,8 +115898,8 @@ function RewindPicker({
|
|
|
114965
115898
|
apply: apply2,
|
|
114966
115899
|
onClose
|
|
114967
115900
|
}) {
|
|
114968
|
-
const [picked, setPicked] = (0,
|
|
114969
|
-
const [busy, setBusy] = (0,
|
|
115901
|
+
const [picked, setPicked] = (0, import_react44.useState)(null);
|
|
115902
|
+
const [busy, setBusy] = (0, import_react44.useState)(false);
|
|
114970
115903
|
if (busy) {
|
|
114971
115904
|
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
|
|
114972
115905
|
}
|
|
@@ -115004,7 +115937,7 @@ function RewindPicker({
|
|
|
115004
115937
|
}
|
|
115005
115938
|
|
|
115006
115939
|
// src/components/dialogs/McpManager.tsx
|
|
115007
|
-
var
|
|
115940
|
+
var import_react45 = __toESM(require_react(), 1);
|
|
115008
115941
|
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
|
|
115009
115942
|
function statusLabel(s) {
|
|
115010
115943
|
return s.status === "needs_auth" ? "needs auth" : s.status ?? "?";
|
|
@@ -115022,8 +115955,8 @@ function McpManager({
|
|
|
115022
115955
|
act,
|
|
115023
115956
|
onClose
|
|
115024
115957
|
}) {
|
|
115025
|
-
const [view, setView] = (0,
|
|
115026
|
-
const [busy, setBusy] = (0,
|
|
115958
|
+
const [view, setView] = (0, import_react45.useState)({ at: "list" });
|
|
115959
|
+
const [busy, setBusy] = (0, import_react45.useState)(false);
|
|
115027
115960
|
const finish = (work, backTo = { at: "list" }) => {
|
|
115028
115961
|
setBusy(true);
|
|
115029
115962
|
void work.finally(() => {
|
|
@@ -115471,7 +116404,7 @@ function UsageMetricsPanel({
|
|
|
115471
116404
|
}
|
|
115472
116405
|
|
|
115473
116406
|
// src/components/status/WorkingStatus.tsx
|
|
115474
|
-
var
|
|
116407
|
+
var import_react46 = __toESM(require_react(), 1);
|
|
115475
116408
|
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
|
|
115476
116409
|
var FRAME_MS = 50;
|
|
115477
116410
|
function WorkingStatus({
|
|
@@ -115479,14 +116412,14 @@ function WorkingStatus({
|
|
|
115479
116412
|
label,
|
|
115480
116413
|
now: now2 = Date.now
|
|
115481
116414
|
}) {
|
|
115482
|
-
const startRef = (0,
|
|
115483
|
-
const wordsRef = (0,
|
|
115484
|
-
const wordIdxRef = (0,
|
|
115485
|
-
const wordStartRef = (0,
|
|
115486
|
-
const dwellRef = (0,
|
|
115487
|
-
const [, forceFrame] = (0,
|
|
116415
|
+
const startRef = (0, import_react46.useRef)(now2());
|
|
116416
|
+
const wordsRef = (0, import_react46.useRef)(shuffleWords(LOADING_WORDS));
|
|
116417
|
+
const wordIdxRef = (0, import_react46.useRef)(0);
|
|
116418
|
+
const wordStartRef = (0, import_react46.useRef)(startRef.current);
|
|
116419
|
+
const dwellRef = (0, import_react46.useRef)(nextCycleMs());
|
|
116420
|
+
const [, forceFrame] = (0, import_react46.useState)(0);
|
|
115488
116421
|
const tokens = useStoreSelector(store, (s) => s.turnOutputTokens);
|
|
115489
|
-
(0,
|
|
116422
|
+
(0, import_react46.useEffect)(() => {
|
|
115490
116423
|
const timer = setInterval(() => {
|
|
115491
116424
|
const n2 = now2();
|
|
115492
116425
|
if (!label && n2 - startRef.current < META_REVEAL_AFTER_MS && n2 - wordStartRef.current >= dwellRef.current) {
|
|
@@ -115638,11 +116571,11 @@ function ReplFooter({
|
|
|
115638
116571
|
(s) => s.pendingPermissions.length > 0 || !!s.pendingPlanApproval || !!s.pendingAskUser || !!s.pendingWorkPlan
|
|
115639
116572
|
);
|
|
115640
116573
|
const closePanel = () => appStore.setState((s) => ({ ...s, activePanel: null }));
|
|
115641
|
-
const onQueuePop =
|
|
116574
|
+
const onQueuePop = import_react47.default.useCallback(
|
|
115642
116575
|
(draft) => popEditableQueue(appStore, draft),
|
|
115643
116576
|
[appStore]
|
|
115644
116577
|
);
|
|
115645
|
-
const [menuOpen, setMenuOpen] =
|
|
116578
|
+
const [menuOpen, setMenuOpen] = import_react47.default.useState(false);
|
|
115646
116579
|
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
|
|
115647
116580
|
streaming && !parked && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(WorkingStatus, { store: appStore }),
|
|
115648
116581
|
plan && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(PlanCard, { plan }),
|
|
@@ -115758,7 +116691,7 @@ function ReplFooter({
|
|
|
115758
116691
|
}
|
|
115759
116692
|
|
|
115760
116693
|
// src/components/layout/FullscreenLayout.tsx
|
|
115761
|
-
var
|
|
116694
|
+
var import_react48 = __toESM(require_react(), 1);
|
|
115762
116695
|
var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
|
|
115763
116696
|
function FullscreenLayout({
|
|
115764
116697
|
appStore,
|
|
@@ -115780,7 +116713,7 @@ function FullscreenLayout({
|
|
|
115780
116713
|
onCycleMode
|
|
115781
116714
|
}) {
|
|
115782
116715
|
const { columns, rows } = useTerminalSize();
|
|
115783
|
-
const scrollRef = (0,
|
|
116716
|
+
const scrollRef = (0, import_react48.useRef)(null);
|
|
115784
116717
|
const onScroll = (delta) => {
|
|
115785
116718
|
const sb = scrollRef.current;
|
|
115786
116719
|
if (!sb) return;
|
|
@@ -115815,7 +116748,7 @@ function FullscreenLayout({
|
|
|
115815
116748
|
}
|
|
115816
116749
|
|
|
115817
116750
|
// src/components/dialogs/AgentsDashboard.tsx
|
|
115818
|
-
var
|
|
116751
|
+
var import_react49 = __toESM(require_react(), 1);
|
|
115819
116752
|
var import_client_core40 = __toESM(require_dist(), 1);
|
|
115820
116753
|
var import_client_ui_core17 = __toESM(require_dist2(), 1);
|
|
115821
116754
|
var import_strip_ansi4 = __toESM(require_strip_ansi(), 1);
|
|
@@ -115862,51 +116795,51 @@ function AgentsDashboard({
|
|
|
115862
116795
|
onClose
|
|
115863
116796
|
}) {
|
|
115864
116797
|
const { rows } = useTerminalSize();
|
|
115865
|
-
const [screen, setScreen] = (0,
|
|
115866
|
-
const [cursor, setCursor] = (0,
|
|
115867
|
-
const [busy, setBusy] = (0,
|
|
115868
|
-
const [error, setError] = (0,
|
|
115869
|
-
const [liveJob, setLiveJob] = (0,
|
|
115870
|
-
const [events, setEvents] = (0,
|
|
115871
|
-
const [pollError, setPollError] = (0,
|
|
115872
|
-
const [diff3, setDiff] = (0,
|
|
115873
|
-
const diffFetchedFor = (0,
|
|
115874
|
-
const [liveItems, setLiveItems] = (0,
|
|
115875
|
-
const [liveTerm, setLiveTerm] = (0,
|
|
115876
|
-
const [liveFrames, setLiveFrames] = (0,
|
|
115877
|
-
const liveIdRef = (0,
|
|
115878
|
-
const [messaging, setMessaging] = (0,
|
|
115879
|
-
const [messageText, setMessageText] = (0,
|
|
115880
|
-
const [messageNote, setMessageNote] = (0,
|
|
115881
|
-
const [tokenStatus, setTokenStatus] = (0,
|
|
115882
|
-
const [tokenBusy, setTokenBusy] = (0,
|
|
115883
|
-
const [tokenNote, setTokenNote] = (0,
|
|
115884
|
-
const [tokenInput, setTokenInput] = (0,
|
|
115885
|
-
const [tokenDraft, setTokenDraft] = (0,
|
|
115886
|
-
const [jiraStatus, setJiraStatus] = (0,
|
|
115887
|
-
const [jiraBusy, setJiraBusy] = (0,
|
|
115888
|
-
const [jiraNote, setJiraNote] = (0,
|
|
115889
|
-
const [jiraInput, setJiraInput] = (0,
|
|
115890
|
-
const [form, setForm] = (0,
|
|
115891
|
-
const [field2, setField] = (0,
|
|
116798
|
+
const [screen, setScreen] = (0, import_react49.useState)({ kind: "list" });
|
|
116799
|
+
const [cursor, setCursor] = (0, import_react49.useState)(0);
|
|
116800
|
+
const [busy, setBusy] = (0, import_react49.useState)(false);
|
|
116801
|
+
const [error, setError] = (0, import_react49.useState)(null);
|
|
116802
|
+
const [liveJob, setLiveJob] = (0, import_react49.useState)(null);
|
|
116803
|
+
const [events, setEvents] = (0, import_react49.useState)([]);
|
|
116804
|
+
const [pollError, setPollError] = (0, import_react49.useState)(null);
|
|
116805
|
+
const [diff3, setDiff] = (0, import_react49.useState)(null);
|
|
116806
|
+
const diffFetchedFor = (0, import_react49.useRef)(null);
|
|
116807
|
+
const [liveItems, setLiveItems] = (0, import_react49.useState)([]);
|
|
116808
|
+
const [liveTerm, setLiveTerm] = (0, import_react49.useState)("");
|
|
116809
|
+
const [liveFrames, setLiveFrames] = (0, import_react49.useState)(0);
|
|
116810
|
+
const liveIdRef = (0, import_react49.useRef)(0);
|
|
116811
|
+
const [messaging, setMessaging] = (0, import_react49.useState)(false);
|
|
116812
|
+
const [messageText, setMessageText] = (0, import_react49.useState)("");
|
|
116813
|
+
const [messageNote, setMessageNote] = (0, import_react49.useState)(null);
|
|
116814
|
+
const [tokenStatus, setTokenStatus] = (0, import_react49.useState)(null);
|
|
116815
|
+
const [tokenBusy, setTokenBusy] = (0, import_react49.useState)(false);
|
|
116816
|
+
const [tokenNote, setTokenNote] = (0, import_react49.useState)(null);
|
|
116817
|
+
const [tokenInput, setTokenInput] = (0, import_react49.useState)(false);
|
|
116818
|
+
const [tokenDraft, setTokenDraft] = (0, import_react49.useState)("");
|
|
116819
|
+
const [jiraStatus, setJiraStatus] = (0, import_react49.useState)(null);
|
|
116820
|
+
const [jiraBusy, setJiraBusy] = (0, import_react49.useState)(false);
|
|
116821
|
+
const [jiraNote, setJiraNote] = (0, import_react49.useState)(null);
|
|
116822
|
+
const [jiraInput, setJiraInput] = (0, import_react49.useState)(null);
|
|
116823
|
+
const [form, setForm] = (0, import_react49.useState)(EMPTY_FORM);
|
|
116824
|
+
const [field2, setField] = (0, import_react49.useState)(0);
|
|
115892
116825
|
const jobs = panel.jobs;
|
|
115893
116826
|
const safeCursor = Math.min(cursor, Math.max(0, jobs.length - 1));
|
|
115894
116827
|
const detailId = screen.kind === "detail" ? screen.id : null;
|
|
115895
116828
|
const detailJob = detailId ? liveJob ?? jobs.find((j2) => j2.id === detailId) ?? null : null;
|
|
115896
|
-
const panelRef = (0,
|
|
116829
|
+
const panelRef = (0, import_react49.useRef)(panel);
|
|
115897
116830
|
panelRef.current = panel;
|
|
115898
|
-
const screenRef = (0,
|
|
116831
|
+
const screenRef = (0, import_react49.useRef)(screen);
|
|
115899
116832
|
screenRef.current = screen;
|
|
115900
|
-
const oauthAlive = (0,
|
|
115901
|
-
const oauthTimer = (0,
|
|
115902
|
-
(0,
|
|
116833
|
+
const oauthAlive = (0, import_react49.useRef)(true);
|
|
116834
|
+
const oauthTimer = (0, import_react49.useRef)(null);
|
|
116835
|
+
(0, import_react49.useEffect)(
|
|
115903
116836
|
() => () => {
|
|
115904
116837
|
oauthAlive.current = false;
|
|
115905
116838
|
if (oauthTimer.current) clearTimeout(oauthTimer.current);
|
|
115906
116839
|
},
|
|
115907
116840
|
[]
|
|
115908
116841
|
);
|
|
115909
|
-
(0,
|
|
116842
|
+
(0, import_react49.useEffect)(() => {
|
|
115910
116843
|
if (!detailId) return;
|
|
115911
116844
|
let cancelled = false;
|
|
115912
116845
|
let timer = null;
|
|
@@ -115948,7 +116881,7 @@ function AgentsDashboard({
|
|
|
115948
116881
|
};
|
|
115949
116882
|
}, [detailId]);
|
|
115950
116883
|
const branchName = detailJob?.branch_name ?? null;
|
|
115951
|
-
(0,
|
|
116884
|
+
(0, import_react49.useEffect)(() => {
|
|
115952
116885
|
if (!detailId || !branchName) return;
|
|
115953
116886
|
const key = `${detailId}:${branchName}`;
|
|
115954
116887
|
if (diffFetchedFor.current === key) return;
|
|
@@ -115966,7 +116899,7 @@ function AgentsDashboard({
|
|
|
115966
116899
|
};
|
|
115967
116900
|
}, [detailId, branchName]);
|
|
115968
116901
|
const liveSessionId = detailJob && !(0, import_client_core40.isTerminal)(detailJob.status) && detailJob.session_id ? detailJob.session_id : null;
|
|
115969
|
-
(0,
|
|
116902
|
+
(0, import_react49.useEffect)(() => {
|
|
115970
116903
|
if (!liveSessionId) return;
|
|
115971
116904
|
liveIdRef.current = 0;
|
|
115972
116905
|
setLiveItems([]);
|
|
@@ -115987,7 +116920,7 @@ function AgentsDashboard({
|
|
|
115987
116920
|
});
|
|
115988
116921
|
return () => sub.dispose();
|
|
115989
116922
|
}, [liveSessionId]);
|
|
115990
|
-
(0,
|
|
116923
|
+
(0, import_react49.useEffect)(() => {
|
|
115991
116924
|
let cancelled = false;
|
|
115992
116925
|
void (async () => {
|
|
115993
116926
|
try {
|
|
@@ -116643,14 +117576,14 @@ function LaunchFormView({ form, field: field2 }) {
|
|
|
116643
117576
|
}
|
|
116644
117577
|
|
|
116645
117578
|
// src/components/layout/TerminalTitle.tsx
|
|
116646
|
-
var
|
|
117579
|
+
var import_react51 = __toESM(require_react(), 1);
|
|
116647
117580
|
|
|
116648
117581
|
// src/vendor/ink/hooks/use-terminal-title.ts
|
|
116649
|
-
var
|
|
117582
|
+
var import_react50 = __toESM(require_react(), 1);
|
|
116650
117583
|
var import_strip_ansi5 = __toESM(require_strip_ansi(), 1);
|
|
116651
117584
|
function useTerminalTitle(title) {
|
|
116652
|
-
const writeRaw = (0,
|
|
116653
|
-
(0,
|
|
117585
|
+
const writeRaw = (0, import_react50.useContext)(TerminalWriteContext);
|
|
117586
|
+
(0, import_react50.useEffect)(() => {
|
|
116654
117587
|
if (title === null || !writeRaw) return;
|
|
116655
117588
|
const clean = (0, import_strip_ansi5.default)(title);
|
|
116656
117589
|
if (process.platform === "win32") {
|
|
@@ -116676,8 +117609,8 @@ function composeTerminalTitle(sessionTitle, streaming, frame) {
|
|
|
116676
117609
|
function TerminalTitle({ appStore }) {
|
|
116677
117610
|
const sessionTitle = useStoreSelector(appStore, (s) => s.sessionTitle);
|
|
116678
117611
|
const streaming = useStoreSelector(appStore, (s) => s.status === "streaming");
|
|
116679
|
-
const [frame, setFrame] = (0,
|
|
116680
|
-
(0,
|
|
117612
|
+
const [frame, setFrame] = (0, import_react51.useState)(0);
|
|
117613
|
+
(0, import_react51.useEffect)(() => {
|
|
116681
117614
|
if (!streaming) return;
|
|
116682
117615
|
const id = setInterval(
|
|
116683
117616
|
() => setFrame((f) => (f + 1) % TITLE_ANIMATION_FRAMES.length),
|
|
@@ -116776,11 +117709,11 @@ function Root({
|
|
|
116776
117709
|
}
|
|
116777
117710
|
|
|
116778
117711
|
// src/components/layout/SignInScreen.tsx
|
|
116779
|
-
var
|
|
117712
|
+
var import_react53 = __toESM(require_react(), 1);
|
|
116780
117713
|
var import_client_core41 = __toESM(require_dist(), 1);
|
|
116781
117714
|
|
|
116782
117715
|
// src/components/layout/splash/Splash.tsx
|
|
116783
|
-
var
|
|
117716
|
+
var import_react52 = __toESM(require_react(), 1);
|
|
116784
117717
|
|
|
116785
117718
|
// src/components/layout/splash/halfblock.ts
|
|
116786
117719
|
var BLOCK = [" ", "\u2580", "\u2584", "\u2588"];
|
|
@@ -117099,7 +118032,7 @@ var TONE = {
|
|
|
117099
118032
|
function Splash({ columns, rows, frame, copy }) {
|
|
117100
118033
|
const theme = useTheme();
|
|
117101
118034
|
const height = splashHeight(rows);
|
|
117102
|
-
const shell2 =
|
|
118035
|
+
const shell2 = import_react52.default.useMemo(() => orbShell(), []);
|
|
117103
118036
|
const grid = splashFrame({ width: columns, rows: height, frame, shell: shell2, copy });
|
|
117104
118037
|
return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(Box2, { flexDirection: "column", children: grid.map((spans, y2) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(Text2, { wrap: "truncate", children: spans.length === 0 ? " " : spans.map((span, i2) => renderSpan(span, i2, theme)) }, y2)) });
|
|
117105
118038
|
}
|
|
@@ -117145,15 +118078,15 @@ function SignInScreen({
|
|
|
117145
118078
|
onSignedIn
|
|
117146
118079
|
}) {
|
|
117147
118080
|
const { exit } = use_app_default();
|
|
117148
|
-
const [phase, setPhase] =
|
|
117149
|
-
const [url, setUrl] =
|
|
117150
|
-
const [error, setError] =
|
|
117151
|
-
const [frame, setFrame] =
|
|
118081
|
+
const [phase, setPhase] = import_react53.default.useState("idle");
|
|
118082
|
+
const [url, setUrl] = import_react53.default.useState(null);
|
|
118083
|
+
const [error, setError] = import_react53.default.useState(null);
|
|
118084
|
+
const [frame, setFrame] = import_react53.default.useState(0);
|
|
117152
118085
|
const { columns, rows } = useTerminalSize();
|
|
117153
|
-
const caps =
|
|
118086
|
+
const caps = import_react53.default.useMemo(() => detectTerminal2(), []);
|
|
117154
118087
|
const copy = splashCopy(phase, error, url, columns);
|
|
117155
118088
|
const useSplash = !splashDisabled() && caps.unicode && splashFits(columns, rows, copy.length);
|
|
117156
|
-
|
|
118089
|
+
import_react53.default.useEffect(() => {
|
|
117157
118090
|
if (!useSplash || phase !== "idle") return;
|
|
117158
118091
|
const t = setInterval(() => setFrame((f) => f + 1), TICK_MS);
|
|
117159
118092
|
return () => clearInterval(t);
|
|
@@ -117917,7 +118850,9 @@ async function runHeadless(flags2) {
|
|
|
117917
118850
|
const config = loadConfig();
|
|
117918
118851
|
if (flags2.workspace) config.workspaceRoot = flags2.workspace;
|
|
117919
118852
|
const secrets = createSecretStore();
|
|
117920
|
-
const session = (0, import_client_core46.createAgentSession)(secrets, config
|
|
118853
|
+
const session = (0, import_client_core46.createAgentSession)(secrets, config, {
|
|
118854
|
+
trace: (line) => console.error(`[orion-auth] ${line}`)
|
|
118855
|
+
});
|
|
117921
118856
|
const signedIn = await session.isSignedIn();
|
|
117922
118857
|
if (!signedIn && !process.env.ORION_AUTH_TOKEN) {
|
|
117923
118858
|
throw new Error(
|
|
@@ -117958,8 +118893,10 @@ async function runHeadless(flags2) {
|
|
|
117958
118893
|
}),
|
|
117959
118894
|
gatewayUrl: () => config.apiUrl,
|
|
117960
118895
|
clientVersion: tuiVersion() ?? "0.0.0-dev",
|
|
117961
|
-
// Mid-segment token-expiry heal —
|
|
117962
|
-
|
|
118896
|
+
// Mid-segment token-expiry heal — the FAIL-CLOSED renewal, not the fail-open
|
|
118897
|
+
// freshness read the transport authToken below uses (that degradation hands the
|
|
118898
|
+
// refused token back and burns the heal).
|
|
118899
|
+
renewBearer: async (refused) => await session.renewedAccessToken(refused) ?? process.env.ORION_AUTH_TOKEN ?? null,
|
|
117963
118900
|
log: brainLog
|
|
117964
118901
|
});
|
|
117965
118902
|
const turnTransport = (0, import_client_core46.createTurnTransport)({
|
|
@@ -118002,6 +118939,7 @@ async function runHeadless(flags2) {
|
|
|
118002
118939
|
() => permissionStore.rules()
|
|
118003
118940
|
);
|
|
118004
118941
|
executor.enableFileHistorySpill();
|
|
118942
|
+
executor.registerHostTool(import_client_core46.GOAL_REPORT_TOOL, async (params) => (0, import_client_core46.goalReportToolResult)(params));
|
|
118005
118943
|
const boundary = createBoundaryHandlers({
|
|
118006
118944
|
bridge,
|
|
118007
118945
|
executor,
|
|
@@ -118033,6 +118971,9 @@ async function runHeadless(flags2) {
|
|
|
118033
118971
|
permissionMode: a.permissionMode,
|
|
118034
118972
|
workspaceRoot: config.workspaceRoot,
|
|
118035
118973
|
clientType: "tui",
|
|
118974
|
+
// Omitted (not placeholdered) in an unstamped dev/test run — see the interactive
|
|
118975
|
+
// path in main.tsx for why the two absences must stay distinguishable.
|
|
118976
|
+
clientVersion: tuiVersion() ?? void 0,
|
|
118036
118977
|
mode: a.mode,
|
|
118037
118978
|
reasoning: a.reasoning,
|
|
118038
118979
|
tokenSaving: a.tokenSaving,
|
|
@@ -118060,7 +119001,8 @@ async function runHeadless(flags2) {
|
|
|
118060
119001
|
getMessages: () => snapshot,
|
|
118061
119002
|
getClientState: () => clientState,
|
|
118062
119003
|
routing: routing(),
|
|
118063
|
-
|
|
119004
|
+
// Every headless turn is a goal round — the claim tool is always on.
|
|
119005
|
+
clientCapabilities: [import_client_core46.GOAL_CAPABILITY],
|
|
118064
119006
|
drainQueuedInput: () => [],
|
|
118065
119007
|
getOrionResources: () => (0, import_client_core46.buildOrionSnapshot)(config.workspaceRoot, void 0, sessionId),
|
|
118066
119008
|
getFileHistoryManifest: () => executor.fileHistoryManifest(sessionId)
|
|
@@ -118076,7 +119018,11 @@ async function runHeadless(flags2) {
|
|
|
118076
119018
|
throw new Error(typeof data.error === "string" ? data.error : "turn failed");
|
|
118077
119019
|
}
|
|
118078
119020
|
if (Array.isArray(data.messages)) messages = data.messages;
|
|
118079
|
-
return {
|
|
119021
|
+
return {
|
|
119022
|
+
text: extractFinalAssistantText(data),
|
|
119023
|
+
evidence: (0, import_client_core46.goalEvidenceFromWire)(data.messages),
|
|
119024
|
+
claim: (0, import_client_core46.goalClaimFromWire)(data.messages)
|
|
119025
|
+
};
|
|
118080
119026
|
};
|
|
118081
119027
|
const { endReason, turns } = await runGoalLoop({
|
|
118082
119028
|
goal: flags2.goal,
|
|
@@ -118089,7 +119035,12 @@ async function runHeadless(flags2) {
|
|
|
118089
119035
|
evidence,
|
|
118090
119036
|
sessionId,
|
|
118091
119037
|
// Lets the check read the user's `goalEvaluate` model choice.
|
|
118092
|
-
workspaceRoot: config.workspaceRoot ?? null
|
|
119038
|
+
workspaceRoot: config.workspaceRoot ?? null,
|
|
119039
|
+
// The run's own model — the fallback when no evaluator model is
|
|
119040
|
+
// configured, so the check never lands on the gateway's deployment
|
|
119041
|
+
// default (see the interactive TUI's identical wiring).
|
|
119042
|
+
sessionModel: routing().model,
|
|
119043
|
+
sessionProvider: routing().provider
|
|
118093
119044
|
});
|
|
118094
119045
|
if (ruling.evaluated && !ruling.ok && ruling.achievable) {
|
|
118095
119046
|
process.stderr.write(`[headless] not met yet \u2014 ${(0, import_client_core46.goalReasonLine)(ruling.reason)}
|
|
@@ -118253,6 +119204,11 @@ async function main() {
|
|
|
118253
119204
|
const duetAdvisorState = (0, import_client_core49.createDuetAdvisorState)();
|
|
118254
119205
|
const duetRouterGate = (0, import_client_core49.createDuetRouterGate)({
|
|
118255
119206
|
loadEncoder: (0, import_client_core49.createDefaultDuetRouterEncoder)(),
|
|
119207
|
+
// "Executor decides": the same gate object owns the executor's one-token scorer, so the
|
|
119208
|
+
// turn path below has ONE call whichever entry is set (`duetExecutorGate.ts`).
|
|
119209
|
+
executorGate: (0, import_client_core49.createDuetExecutorGate)({
|
|
119210
|
+
onError: (stage, problem) => console.error(`[duet-executor-gate] ${stage} failed: ${problem}`)
|
|
119211
|
+
}),
|
|
118256
119212
|
onError: (stage, error) => (
|
|
118257
119213
|
// Same breadcrumb the IDE and the Power App leave (the log redirect captures it, so it
|
|
118258
119214
|
// never corrupts the alt screen): without it a load or classify failure is invisible
|
|
@@ -118327,7 +119283,11 @@ async function main() {
|
|
|
118327
119283
|
}
|
|
118328
119284
|
});
|
|
118329
119285
|
const secrets = createSecretStore();
|
|
118330
|
-
const session = (0, import_client_core49.createAgentSession)(secrets, config
|
|
119286
|
+
const session = (0, import_client_core49.createAgentSession)(secrets, config, {
|
|
119287
|
+
// Renewal/refresh breadcrumbs (step outcomes + timings, never tokens) — the evidence
|
|
119288
|
+
// the 2026-08-22 refresh-wedge investigation lacked.
|
|
119289
|
+
trace: (line) => console.error(`[orion-auth] ${line}`)
|
|
119290
|
+
});
|
|
118331
119291
|
const outcomes = new import_client_core49.OutcomeReporter({
|
|
118332
119292
|
apiBaseUrl: () => config.accountsApiUrl,
|
|
118333
119293
|
accessToken: () => session.currentAccessToken()
|
|
@@ -118400,10 +119360,10 @@ async function main() {
|
|
|
118400
119360
|
}),
|
|
118401
119361
|
gatewayUrl: () => config.apiUrl,
|
|
118402
119362
|
clientVersion: tuiVersion() ?? "0.0.0-dev",
|
|
118403
|
-
// Mid-segment token-expiry heal: the
|
|
118404
|
-
//
|
|
118405
|
-
//
|
|
118406
|
-
renewBearer: () =>
|
|
119363
|
+
// Mid-segment token-expiry heal: the FAIL-CLOSED renewal seam, NOT the fail-open
|
|
119364
|
+
// per-segment authToken read — the refused token rides in so the answer is decided
|
|
119365
|
+
// on token identity, never local clocks; an emptied store re-gates the chat.
|
|
119366
|
+
renewBearer: (refused) => renewedTransportBearer(session, appStore, refused, process.env.ORION_AUTH_TOKEN),
|
|
118407
119367
|
log: brainLog
|
|
118408
119368
|
});
|
|
118409
119369
|
return brainInstance;
|
|
@@ -119142,6 +120102,11 @@ async function main() {
|
|
|
119142
120102
|
workspaceRoot: config.workspaceRoot,
|
|
119143
120103
|
clientType: "tui",
|
|
119144
120104
|
// usage-telemetry surface tag
|
|
120105
|
+
// …and the build behind that tag. `tuiVersion()` is null in an unstamped dev/test run,
|
|
120106
|
+
// which becomes `undefined` here so the key is OMITTED rather than sent as a placeholder:
|
|
120107
|
+
// "not reported" and "reported but unreadable" are different states downstream, and a dev
|
|
120108
|
+
// build is the former.
|
|
120109
|
+
clientVersion: tuiVersion() ?? void 0,
|
|
119145
120110
|
// mode/reasoning/context_window ride the body too (rule 1) so a cold pod keeps
|
|
119146
120111
|
// plan/ask read-only + the right model settings — not a per-pod set_* RPC.
|
|
119147
120112
|
mode: a.mode,
|
|
@@ -119226,7 +120191,11 @@ async function main() {
|
|
|
119226
120191
|
if (appStore.getState().mode === "duet") {
|
|
119227
120192
|
const routed = await duetRouterGate.prepareTurn(
|
|
119228
120193
|
(0, import_client_core49.duetEntryWireForSegment)(config.workspaceRoot),
|
|
119229
|
-
routerText
|
|
120194
|
+
routerText,
|
|
120195
|
+
// What the executor gate's prompt is built from: the standing record as it stands
|
|
120196
|
+
// BEFORE the advisor runs (the advisor may flag it for this turn; the gate asks the
|
|
120197
|
+
// executor about the request under the plan the user actually approved).
|
|
120198
|
+
{ workspaceRoot: config.workspaceRoot, record: appStore.getState().duetPlan }
|
|
119230
120199
|
);
|
|
119231
120200
|
duetEntry = routed.entry;
|
|
119232
120201
|
duetRouterVerdict = routed.verdict;
|
|
@@ -119305,7 +120274,10 @@ async function main() {
|
|
|
119305
120274
|
import_client_core49.DUET_REPLAN_CAPABILITY,
|
|
119306
120275
|
// …and runs the planner's `hand_off` (leg marker, phase line, journal), so
|
|
119307
120276
|
// planner entry may offer it (further leg-gated backend-side).
|
|
119308
|
-
import_client_core49.DUET_HANDOFF_CAPABILITY
|
|
120277
|
+
import_client_core49.DUET_HANDOFF_CAPABILITY,
|
|
120278
|
+
// `goal` lights up the goal_report claim tool, and only while a goal is
|
|
120279
|
+
// actually driving this conversation — an ordinary chat never sees it.
|
|
120280
|
+
...goalRunner !== null ? [import_client_core49.GOAL_CAPABILITY] : []
|
|
119309
120281
|
],
|
|
119310
120282
|
extraBody: {
|
|
119311
120283
|
...appStore.getState().subagentsEnabled ? agentManager.parentExtraBody() : {},
|
|
@@ -119381,7 +120353,8 @@ async function main() {
|
|
|
119381
120353
|
endSettle = {
|
|
119382
120354
|
kind: "complete",
|
|
119383
120355
|
finalText: (0, import_client_core49.finalAssistantTextFromWire)(data.messages),
|
|
119384
|
-
evidence: (0, import_client_core49.goalEvidenceFromWire)(data.messages)
|
|
120356
|
+
evidence: (0, import_client_core49.goalEvidenceFromWire)(data.messages),
|
|
120357
|
+
claim: (0, import_client_core49.goalClaimFromWire)(data.messages)
|
|
119385
120358
|
};
|
|
119386
120359
|
(0, import_client_core48.recordTurnMetrics)({
|
|
119387
120360
|
app: "tui",
|
|
@@ -119562,6 +120535,7 @@ async function main() {
|
|
|
119562
120535
|
);
|
|
119563
120536
|
return (0, import_client_core49.duetHandoffResult)();
|
|
119564
120537
|
});
|
|
120538
|
+
executor.registerHostTool(import_client_core49.GOAL_REPORT_TOOL, async (params) => (0, import_client_core49.goalReportToolResult)(params));
|
|
119565
120539
|
const loopService = new LoopService({
|
|
119566
120540
|
workspaceRoot: config.workspaceRoot,
|
|
119567
120541
|
schedulePath: loopSchedulePathFor((0, import_client_core49.runsRootFor)("loops", config.workspaceRoot)),
|
|
@@ -119635,12 +120609,27 @@ async function main() {
|
|
|
119635
120609
|
// stranger's routing.
|
|
119636
120610
|
sessionId: goalSessionId ?? void 0,
|
|
119637
120611
|
// Lets the check read the user's `goalEvaluate` model choice.
|
|
119638
|
-
workspaceRoot: currentRouting().workspaceRoot ?? null
|
|
120612
|
+
workspaceRoot: currentRouting().workspaceRoot ?? null,
|
|
120613
|
+
// The session's model as THIS CLIENT knows it — the fallback when no
|
|
120614
|
+
// evaluator model is configured. The gateway's own session record can
|
|
120615
|
+
// still hold the deployment default for a local-brain session (routing
|
|
120616
|
+
// rides segment bodies), and a check on that default is a check on a
|
|
120617
|
+
// model this session never used.
|
|
120618
|
+
sessionModel: currentRouting().model,
|
|
120619
|
+
sessionProvider: currentRouting().provider
|
|
119639
120620
|
});
|
|
119640
|
-
if (ruling.evaluated && !ruling.ok && ruling.achievable) {
|
|
119641
|
-
transcriptStore.setState((s) => appendGoalNoteFor(s, goalSessionId, (0, import_client_core49.goalNotMetRow)(ruling.reason)));
|
|
119642
|
-
}
|
|
119643
120621
|
return ruling;
|
|
120622
|
+
},
|
|
120623
|
+
// A round that did NOT meet the goal says so — in the judge's words when a
|
|
120624
|
+
// check ran, in the agent's own honest not-done report when none did
|
|
120625
|
+
// (goalRoundReason is the one mapping, shared by every client). Without it
|
|
120626
|
+
// a long goal is a wall of identical continuation lines and a stuck one is
|
|
120627
|
+
// indistinguishable from a working one.
|
|
120628
|
+
onRound: (round) => {
|
|
120629
|
+
const reason = (0, import_client_core49.goalRoundReason)(round);
|
|
120630
|
+
if (reason !== "") {
|
|
120631
|
+
transcriptStore.setState((s) => appendGoalNoteFor(s, goalSessionId, (0, import_client_core49.goalNotMetRow)(reason)));
|
|
120632
|
+
}
|
|
119644
120633
|
}
|
|
119645
120634
|
});
|
|
119646
120635
|
goalRunner = runner;
|
|
@@ -119656,6 +120645,7 @@ async function main() {
|
|
|
119656
120645
|
runCommand: routeInput
|
|
119657
120646
|
});
|
|
119658
120647
|
});
|
|
120648
|
+
transcriptStore.setState((s) => appendGoalNoteFor(s, goalSessionId, (0, import_client_core49.goalSetRow)(goal)));
|
|
119659
120649
|
};
|
|
119660
120650
|
const enqueueSteer = (text) => {
|
|
119661
120651
|
appStore.setState((s) => ({ ...s, queuedMessages: [...s.queuedMessages, queuedSteer(text)] }));
|