dsh-github-copilot 0.4.0-alpha.27 → 0.4.0-alpha.28

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/lib/index.js CHANGED
@@ -6,7 +6,7 @@ import { Remote, RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typer
6
6
  import z from "@deepseek-ai/schemastery";
7
7
  import { z as z$1 } from "zod";
8
8
  import * as dshLlm from "@deepseek-ai/dsh-llm";
9
- import { LlmError, attributionHeaders, contentHasImage, isAgentLoopRequest, resolveImageAttachmentAccess, resolveRetryPolicy } from "@deepseek-ai/dsh-llm";
9
+ import { CONTEXT_WINDOW_EXCEEDED_CODE, LlmError, ReasoningEffortId, attributionHeaders, callConfigEquals, contentHasImage, isAgentLoopRequest, resolveImageAttachmentAccess, resolveRetryPolicy } from "@deepseek-ai/dsh-llm";
10
10
  import { WebError } from "@deepseek-ai/dsh-web";
11
11
  import * as dshSettings from "@deepseek-ai/dsh-settings";
12
12
  import { getBuiltinModels } from "@earendil-works/pi-ai/providers/all";
@@ -14,6 +14,7 @@ import { createModels, getSupportedThinkingLevels, hasApi, lazyStream } from "@e
14
14
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
15
15
  import { githubCopilotProvider } from "@earendil-works/pi-ai/providers/github-copilot";
16
16
  import { Config as Config$1, PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
17
+ import { estimateContextTokens, estimateMessageTokens } from "@earendil-works/pi-ai/utils/estimate";
17
18
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "@earendil-works/pi-ai/api/github-copilot-headers";
18
19
  //#region lib/types/dual-model-host.js
19
20
  /** Optional plugin-owned planner/executor sessions; no Core/default-model mutation. */
@@ -226,12 +227,12 @@ function fail$1(reason, creation) {
226
227
  function creationOf(error) {
227
228
  return ownRemoteFailure(error)?.creation ?? "uncertain";
228
229
  }
229
- function object$3(value) {
230
+ function object$4(value) {
230
231
  return typeof value === "object" && value !== null && !Array.isArray(value);
231
232
  }
232
233
  function api$1(ctx, key, methods) {
233
234
  const value = ctx.get(key);
234
- return object$3(value) && methods.every((method) => typeof value[method] === "function") ? value : void 0;
235
+ return object$4(value) && methods.every((method) => typeof value[method] === "function") ? value : void 0;
235
236
  }
236
237
  function revision(value) {
237
238
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
@@ -255,7 +256,7 @@ const ERROR_REASONS = /* @__PURE__ */ new Set([
255
256
  /** Remote errors cross bundle/realm boundaries; constructor identity is not a protocol. */
256
257
  function ownRemoteFailure(error) {
257
258
  try {
258
- if (!object$3(error) || error.isDSHRemoteError !== true || error.code !== "copilot/dual-model" || !object$3(error.details)) return void 0;
259
+ if (!object$4(error) || error.isDSHRemoteError !== true || error.code !== "copilot/dual-model" || !object$4(error.details)) return void 0;
259
260
  const reason = error.details.reason;
260
261
  if (typeof reason !== "string" || !ERROR_REASONS.has(reason)) return void 0;
261
262
  const creation = error.details.creation;
@@ -271,7 +272,7 @@ function reasonOf(error, fallback) {
271
272
  const own = ownRemoteFailure(error);
272
273
  if (own) return own.reason;
273
274
  try {
274
- if (object$3(error) && error.code === "SETTINGS_CONFLICT") return "DUAL_MODEL_REVISION_CONFLICT";
275
+ if (object$4(error) && error.code === "SETTINGS_CONFLICT") return "DUAL_MODEL_REVISION_CONFLICT";
275
276
  } catch {}
276
277
  return fallback;
277
278
  }
@@ -400,7 +401,7 @@ let GitHubCopilotDualModel = (() => {
400
401
  }, { prepend: true });
401
402
  ctx.on("system-prompt/assemble", async (_assembly, context, next) => {
402
403
  const candidate = context.scope;
403
- if (!candidate || !object$3(candidate.session) || !object$3(candidate.session.header) || !dedicatedAddress(candidate)) return next();
404
+ if (!candidate || !object$4(candidate.session) || !object$4(candidate.session.header) || !dedicatedAddress(candidate)) return next();
404
405
  const rehydrating = !this.overlays.has(candidate);
405
406
  if (rehydrating) this.restore(candidate);
406
407
  const installed = this.overlays.get(candidate);
@@ -961,7 +962,7 @@ let SearchRoutingController = (() => {
961
962
  //#endregion
962
963
  //#region package.json
963
964
  var name$1 = "dsh-github-copilot";
964
- var version = "0.4.0-alpha.27";
965
+ var version = "0.4.0-alpha.28";
965
966
  //#endregion
966
967
  //#region lib/types/probe.js
967
968
  /**
@@ -1263,6 +1264,92 @@ async function probeAnthropic(candidate, apiKey, signal) {
1263
1264
  };
1264
1265
  }
1265
1266
  //#endregion
1267
+ //#region lib/types/request-budget.js
1268
+ /** The safety allowance matches the pinned native SDK; pressure is a separate opt-in check. */
1269
+ const DEFAULT_REQUEST_BUDGET_POLICY = Object.freeze({
1270
+ safetyTokens: 4096,
1271
+ pressureRatio: .9,
1272
+ compactionReasoning: "prefer-low"
1273
+ });
1274
+ /** Validate deployment policy before applying defaults; unknown keys fail rather than silently drift. */
1275
+ function resolveRequestBudgetPolicy(config = {}) {
1276
+ const keys = /* @__PURE__ */ new Set([
1277
+ "safetyTokens",
1278
+ "pressureRatio",
1279
+ "compactionReasoning"
1280
+ ]);
1281
+ for (const key of Object.keys(config)) if (!keys.has(key)) throw new Error(`COPILOT_REQUEST_BUDGET_POLICY_INVALID: unknown setting ${key}`);
1282
+ const safetyTokens = config.safetyTokens === void 0 ? DEFAULT_REQUEST_BUDGET_POLICY.safetyTokens : config.safetyTokens;
1283
+ const pressureRatio = config.pressureRatio === void 0 ? DEFAULT_REQUEST_BUDGET_POLICY.pressureRatio : config.pressureRatio;
1284
+ const compactionReasoning = config.compactionReasoning === void 0 ? DEFAULT_REQUEST_BUDGET_POLICY.compactionReasoning : config.compactionReasoning;
1285
+ if (!Number.isSafeInteger(safetyTokens) || safetyTokens < 0) throw new Error("COPILOT_REQUEST_BUDGET_POLICY_INVALID: safetyTokens must be a non-negative safe integer");
1286
+ if (!Number.isFinite(pressureRatio) || pressureRatio <= 0 || pressureRatio > 1) throw new Error("COPILOT_REQUEST_BUDGET_POLICY_INVALID: pressureRatio must be greater than zero and at most one");
1287
+ if (compactionReasoning !== "prefer-low" && compactionReasoning !== "preserve") throw new Error("COPILOT_REQUEST_BUDGET_POLICY_INVALID: unsupported compactionReasoning");
1288
+ return Object.freeze({
1289
+ safetyTokens,
1290
+ pressureRatio,
1291
+ compactionReasoning
1292
+ });
1293
+ }
1294
+ function failure$1(code, message) {
1295
+ return Object.freeze({
1296
+ ok: false,
1297
+ code,
1298
+ message: `${code}: ${message}`
1299
+ });
1300
+ }
1301
+ function positiveInteger$1(value) {
1302
+ return Number.isSafeInteger(value) && value > 0;
1303
+ }
1304
+ /**
1305
+ * Reserve output under the combined context and independently enforce the prompt ceiling.
1306
+ * `policy` must come from resolveRequestBudgetPolicy; no caller cap or catalog object is changed.
1307
+ */
1308
+ function calculateRequestBudget(limits, requestedMaxTokens, policy = DEFAULT_REQUEST_BUDGET_POLICY) {
1309
+ const { contextWindow, maxInputTokens, maxTokens } = limits;
1310
+ if (!positiveInteger$1(contextWindow) || !positiveInteger$1(maxTokens) || maxInputTokens !== void 0 && !positiveInteger$1(maxInputTokens)) return failure$1("COPILOT_REQUEST_INVALID_LIMITS", "model token capacities must be positive safe integers");
1311
+ if (requestedMaxTokens !== void 0 && !positiveInteger$1(requestedMaxTokens)) return failure$1("COPILOT_REQUEST_INVALID_OUTPUT_LIMIT", "request output cap must be a positive safe integer");
1312
+ const outputReservation = requestedMaxTokens ?? maxTokens;
1313
+ if (outputReservation > maxTokens) return failure$1("COPILOT_REQUEST_OUTPUT_LIMIT_EXCEEDED", `request output cap ${outputReservation} exceeds model output capacity ${maxTokens}`);
1314
+ const contextInputLimit = contextWindow - outputReservation;
1315
+ const limitingFactor = maxInputTokens !== void 0 && maxInputTokens <= contextInputLimit ? "prompt" : "context";
1316
+ const hardInputLimit = Math.min(maxInputTokens ?? contextInputLimit, contextInputLimit) - policy.safetyTokens;
1317
+ if (hardInputLimit <= 0) return failure$1("COPILOT_REQUEST_NO_INPUT_HEADROOM", "output reservation and safety allowance leave no positive input budget");
1318
+ return Object.freeze({
1319
+ ok: true,
1320
+ budget: Object.freeze({
1321
+ contextWindow,
1322
+ ...maxInputTokens === void 0 ? {} : { maxInputTokens },
1323
+ maxOutputTokens: maxTokens,
1324
+ outputReservation,
1325
+ hardInputLimit,
1326
+ pressureInputLimit: Math.floor(hardInputLimit * policy.pressureRatio),
1327
+ limitingFactor
1328
+ })
1329
+ });
1330
+ }
1331
+ /**
1332
+ * Check an estimated full prompt; estimates are not provider-exact token counts.
1333
+ * Enable pressure only for an owned ordinary loop call with a compaction recovery path.
1334
+ * Auxiliary and agentless calls use hard admission, including compaction itself.
1335
+ */
1336
+ function assessRequestBudget(estimatedInput, budget, pressure = false) {
1337
+ if (!Number.isFinite(estimatedInput) || estimatedInput < 0 || estimatedInput > Number.MAX_SAFE_INTEGER) return failure$1("COPILOT_REQUEST_INVALID_ESTIMATE", "estimated input must be finite, non-negative, and safely representable");
1338
+ const input = Math.ceil(estimatedInput);
1339
+ if (input > budget.hardInputLimit) return failure$1(budget.limitingFactor === "prompt" ? "COPILOT_REQUEST_INPUT_LIMIT_EXCEEDED" : "COPILOT_REQUEST_CONTEXT_LIMIT_EXCEEDED", `estimated input ${input} exceeds input budget ${budget.hardInputLimit} with output reservation ${budget.outputReservation}`);
1340
+ if (pressure && input > budget.pressureInputLimit) return failure$1("COPILOT_REQUEST_PRESSURE_EXCEEDED", `estimated input ${input} exceeds proactive compaction budget ${budget.pressureInputLimit}`);
1341
+ return Object.freeze({ ok: true });
1342
+ }
1343
+ /**
1344
+ * Select a low-cost supported effort only for a caller-confirmed compaction request.
1345
+ * A supplied effort, including a materialized provider default, wins unchanged; native validation
1346
+ * remains authoritative. Unsupported low-cost controls preserve the provider default, never off/none.
1347
+ */
1348
+ function selectCompactionReasoning(supportedEfforts, requestedEffort, mode = DEFAULT_REQUEST_BUDGET_POLICY.compactionReasoning) {
1349
+ if (requestedEffort !== void 0 || mode === "preserve") return requestedEffort;
1350
+ return supportedEfforts.find((effort) => effort === "minimal") ?? supportedEfforts.find((effort) => effort === "low");
1351
+ }
1352
+ //#endregion
1266
1353
  //#region lib/types/config.js
1267
1354
  /**
1268
1355
  * Settings section of the inline web-search plugin: the narrow-gate switch,
@@ -1283,6 +1370,9 @@ const Config = z.object({
1283
1370
  probeTimeoutMs: z.number().step(1).min(1).max(MAX_TIMEOUT_MS).default(3e4),
1284
1371
  accountModelTtlMs: z.number().step(1).min(0).max(MAX_TIMEOUT_MS).default(864e5),
1285
1372
  accountModelFailureCooldownMs: z.number().step(1).min(0).max(MAX_TIMEOUT_MS).default(3e5),
1373
+ requestBudgetSafetyTokens: z.number().step(1).min(0).max(Number.MAX_SAFE_INTEGER).default(DEFAULT_REQUEST_BUDGET_POLICY.safetyTokens),
1374
+ requestBudgetPressureRatio: z.number().step(.01).min(.01).max(1).default(DEFAULT_REQUEST_BUDGET_POLICY.pressureRatio),
1375
+ compactionReasoning: z.union(["prefer-low", "preserve"]).default(DEFAULT_REQUEST_BUDGET_POLICY.compactionReasoning),
1286
1376
  routeWebSearch: z.boolean().default(true),
1287
1377
  searchFallback: z.union(["none", "deepseek"]).default("deepseek"),
1288
1378
  searchModel: z.string().hidden(),
@@ -3131,19 +3221,19 @@ var TemporaryRouteConflictError = class extends Error {
3131
3221
  this.name = "TemporaryRouteConflictError";
3132
3222
  }
3133
3223
  };
3134
- function object$2(value) {
3224
+ function object$3(value) {
3135
3225
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
3136
3226
  }
3137
3227
  function profileAt(value) {
3138
- return object$2(object$2(object$2(value)?.providers)?.["github-copilot"]);
3228
+ return object$3(object$3(object$3(value)?.providers)?.["github-copilot"]);
3139
3229
  }
3140
3230
  /** Bounded comparison; never stringify or copy unknown model extras or headers. */
3141
3231
  function equalJson(a, b, depth = 0) {
3142
3232
  if (a === b) return true;
3143
3233
  if (depth > 12) return false;
3144
3234
  if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length <= 512 && a.length === b.length && a.every((value, i) => equalJson(value, b[i], depth + 1));
3145
- const left = object$2(a);
3146
- const right = object$2(b);
3235
+ const left = object$3(a);
3236
+ const right = object$3(b);
3147
3237
  if (!left || !right) return false;
3148
3238
  const keys = Object.keys(left);
3149
3239
  return keys.length <= 512 && keys.length === Object.keys(right).length && keys.every((key) => Object.hasOwn(right, key) && equalJson(left[key], right[key], depth + 1));
@@ -3152,7 +3242,7 @@ const MAX_BACKUP = 131072;
3152
3242
  function safeModels(value) {
3153
3243
  if (!Array.isArray(value) || value.length > 512) throw new TemporaryRouteConflictError();
3154
3244
  return value.map((entry) => {
3155
- const model = object$2(entry);
3245
+ const model = object$3(entry);
3156
3246
  if (!model || typeof model.id !== "string" || !/^[a-zA-Z0-9._:/-]{1,200}$/.test(model.id)) throw new TemporaryRouteConflictError();
3157
3247
  const overlay = temporaryGitHubCopilotModel(model.id, /* @__PURE__ */ new Map());
3158
3248
  if (overlay && Object.keys(model).some((key) => key !== "id" && key !== "api")) {
@@ -3183,10 +3273,10 @@ function readBackup(value) {
3183
3273
  if (value === void 0) return void 0;
3184
3274
  if (typeof value !== "string" || value.length > MAX_BACKUP) throw new TemporaryRouteConflictError("TEMPORARY_ROUTE_INVALID_BACKUP");
3185
3275
  try {
3186
- const decoded = object$2(JSON.parse(value));
3276
+ const decoded = object$3(JSON.parse(value));
3187
3277
  if (!decoded) throw new Error();
3188
3278
  if (decoded.version === void 0 || decoded.version === 2 && decoded.sourceEpoch === void 0) throw new TemporaryRouteConflictError("TEMPORARY_ROUTE_LEGACY_CONFLICT");
3189
- if (decoded.version !== 2 || typeof decoded.providerExisted !== "boolean" || typeof decoded.sourceEpoch !== "string" || !/^[a-f0-9-]{36}$/.test(decoded.sourceEpoch) || !Number.isSafeInteger(decoded.sourceRevision) || Number(decoded.sourceRevision) < 0 || !["overlay", "restoring"].includes(String(decoded.phase)) || !object$2(decoded.preimage) || !object$2(decoded.postimage) || !object$2(decoded.ownedHeaders) || Object.keys(decoded).some((key) => ![
3279
+ if (decoded.version !== 2 || typeof decoded.providerExisted !== "boolean" || typeof decoded.sourceEpoch !== "string" || !/^[a-f0-9-]{36}$/.test(decoded.sourceEpoch) || !Number.isSafeInteger(decoded.sourceRevision) || Number(decoded.sourceRevision) < 0 || !["overlay", "restoring"].includes(String(decoded.phase)) || !object$3(decoded.preimage) || !object$3(decoded.postimage) || !object$3(decoded.ownedHeaders) || Object.keys(decoded).some((key) => ![
3190
3280
  "version",
3191
3281
  "providerExisted",
3192
3282
  "preimage",
@@ -3203,15 +3293,15 @@ function readBackup(value) {
3203
3293
  decoded.postimage,
3204
3294
  ...decoded.phase === "restoring" ? [decoded.target] : []
3205
3295
  ]) {
3206
- const record = object$2(leaf);
3296
+ const record = object$3(leaf);
3207
3297
  if (!record || !equalJson(record, leavesOf(record))) throw new Error();
3208
3298
  }
3209
- const models = object$2(decoded.postimage)?.models ?? [];
3299
+ const models = object$3(decoded.postimage)?.models ?? [];
3210
3300
  const knownHeaders = Object.assign({}, ...models.flatMap((model) => {
3211
3301
  const overlay = temporaryGitHubCopilotModelFromProfile(model);
3212
3302
  return overlay ? [overlay.headers] : [];
3213
3303
  }));
3214
- if (!Object.entries(object$2(decoded.ownedHeaders)).every(([name, header]) => knownHeaders[name] === header)) throw new Error();
3304
+ if (!Object.entries(object$3(decoded.ownedHeaders)).every(([name, header]) => knownHeaders[name] === header)) throw new Error();
3215
3305
  if (decoded.removeProfile !== void 0 && typeof decoded.removeProfile !== "boolean") throw new Error();
3216
3306
  return decoded;
3217
3307
  } catch (error) {
@@ -3237,7 +3327,7 @@ function settingsSnapshot(settings) {
3237
3327
  hasOwnedSecrets,
3238
3328
  routeRevision: route.revision,
3239
3329
  markerRevision: marker.revision,
3240
- backup: readBackup(object$2(settings.get("github-copilot"))?.temporaryRouteBackup)
3330
+ backup: readBackup(object$3(settings.get("github-copilot"))?.temporaryRouteBackup)
3241
3331
  };
3242
3332
  }
3243
3333
  function assertOwned(current, backup) {
@@ -3270,7 +3360,7 @@ function leafOperations(current, target) {
3270
3360
  }]);
3271
3361
  }
3272
3362
  function ownedHeaderRemoval(current, backup) {
3273
- return Object.entries(object$2(current?.headers) ?? {}).flatMap(([name, value]) => Object.entries(backup.ownedHeaders).some(([ownedName, ownedValue]) => name.toLowerCase() === ownedName.toLowerCase() && value === ownedValue) ? [{
3363
+ return Object.entries(object$3(current?.headers) ?? {}).flatMap(([name, value]) => Object.entries(backup.ownedHeaders).some(([ownedName, ownedValue]) => name.toLowerCase() === ownedName.toLowerCase() && value === ownedValue) ? [{
3274
3364
  op: "unset",
3275
3365
  path: [
3276
3366
  "providers",
@@ -3292,7 +3382,7 @@ function wholeProfileOwned(snapshot, backup) {
3292
3382
  //#endregion
3293
3383
  //#region lib/types/migration-status.js
3294
3384
  const LIMIT = 1024;
3295
- function object$1(value) {
3385
+ function object$2(value) {
3296
3386
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Invalid evidence");
3297
3387
  return value;
3298
3388
  }
@@ -3301,7 +3391,7 @@ function text$1(value) {
3301
3391
  return value;
3302
3392
  }
3303
3393
  function selection(value, omitDefaultEffort = false) {
3304
- const item = object$1(value);
3394
+ const item = object$2(value);
3305
3395
  const provider = text$1(item.provider), model = text$1(item.model), effort = item.reasoningEffort;
3306
3396
  if (effort !== void 0) text$1(effort);
3307
3397
  return {
@@ -3316,7 +3406,7 @@ function array(value) {
3316
3406
  }
3317
3407
  function api(ctx, name, methods) {
3318
3408
  try {
3319
- const candidate = object$1(ctx.get(name));
3409
+ const candidate = object$2(ctx.get(name));
3320
3410
  return methods.every((key) => typeof candidate[key] === "function") ? candidate : void 0;
3321
3411
  } catch {
3322
3412
  return;
@@ -3386,26 +3476,26 @@ function migrationStatus(ctx) {
3386
3476
  const rows = [], ids = /* @__PURE__ */ new Set();
3387
3477
  let complete = projections !== void 0;
3388
3478
  for (const candidate of array(call(agents, "list"))) {
3389
- const agent = object$1(candidate), id = text$1(agent.id), status = agent.status;
3479
+ const agent = object$2(candidate), id = text$1(agent.id), status = agent.status;
3390
3480
  if (ids.has(id) || status !== "idle" && status !== "running") throw new Error("Invalid agent inventory");
3391
3481
  ids.add(id);
3392
- const session = object$1(agent.session);
3482
+ const session = object$2(agent.session);
3393
3483
  if (text$1(session.id) !== id) throw new Error("Invalid agent identity");
3394
3484
  const header = call(session, "requestHeader");
3395
- const request = header === void 0 ? null : selection(object$1(header).config);
3485
+ const request = header === void 0 ? null : selection(object$2(header).config);
3396
3486
  let effective = null, source = "unknown";
3397
3487
  if (projections) {
3398
3488
  const state = call(projections, "stateOf", session, "modelSelection");
3399
3489
  if (state !== void 0) {
3400
- const pending = object$1(state).pending;
3490
+ const pending = object$2(state).pending;
3401
3491
  if (pending !== null) {
3402
3492
  effective = selection(pending);
3403
3493
  source = "pending";
3404
3494
  } else if (header !== void 0) {
3405
- const defaults = object$1(header).adapterDefaults;
3406
- const defaultEffort = defaults === void 0 ? false : object$1(defaults).reasoningEffort;
3495
+ const defaults = object$2(header).adapterDefaults;
3496
+ const defaultEffort = defaults === void 0 ? false : object$2(defaults).reasoningEffort;
3407
3497
  if (defaultEffort !== void 0 && typeof defaultEffort !== "boolean") throw new Error("Invalid adapter defaults");
3408
- effective = selection(object$1(header).config, defaultEffort === true);
3498
+ effective = selection(object$2(header).config, defaultEffort === true);
3409
3499
  source = "request-header";
3410
3500
  } else if (result.complete.defaultSelection) {
3411
3501
  effective = result.defaultSelection;
@@ -3429,23 +3519,23 @@ function migrationStatus(ctx) {
3429
3519
  const descriptors = array(call(settings, "describe", { redactSecrets: true }));
3430
3520
  const found = /* @__PURE__ */ new Set();
3431
3521
  for (const value of descriptors) {
3432
- const descriptor = object$1(value);
3522
+ const descriptor = object$2(value);
3433
3523
  const ns = text$1(descriptor.ns);
3434
3524
  if (ns !== "llm-pi-ai" && ns !== "github-copilot") continue;
3435
3525
  if (found.has(ns) || !Number.isSafeInteger(descriptor.revision) || descriptor.revision < 0) throw new Error("Invalid settings evidence");
3436
3526
  found.add(ns);
3437
3527
  }
3438
3528
  if (found.size !== 2) throw new Error("Unregistered settings");
3439
- const config = object$1(call(settings, "get", "llm-pi-ai"));
3440
- const profile = (config.providers === void 0 ? void 0 : object$1(config.providers))?.[GITHUB_COPILOT_PROVIDER_ID];
3441
- if (profile !== void 0) object$1(profile);
3529
+ const config = object$2(call(settings, "get", "llm-pi-ai"));
3530
+ const profile = (config.providers === void 0 ? void 0 : object$2(config.providers))?.[GITHUB_COPILOT_PROVIDER_ID];
3531
+ if (profile !== void 0) object$2(profile);
3442
3532
  result.capabilities.settingsCas = true;
3443
3533
  result.routes.nativeConfigured = profile !== void 0;
3444
3534
  } catch {}
3445
3535
  if (llm) try {
3446
3536
  const ids = /* @__PURE__ */ new Set();
3447
3537
  for (const value of array(call(llm, "listProviders"))) {
3448
- const id = text$1(object$1(value).id);
3538
+ const id = text$1(object$2(value).id);
3449
3539
  if (ids.has(id)) throw new Error("Invalid registry evidence");
3450
3540
  ids.add(id);
3451
3541
  }
@@ -3686,7 +3776,7 @@ async function repairGitHubCopilotProviderProfile(ctx) {
3686
3776
  try {
3687
3777
  await settings.mutate(namespace, operations, revision);
3688
3778
  } catch (error) {
3689
- if (object$2(error)?.code === "SETTINGS_CONFLICT") throw new TemporaryRouteConflictError();
3779
+ if (object$3(error)?.code === "SETTINGS_CONFLICT") throw new TemporaryRouteConflictError();
3690
3780
  throw error;
3691
3781
  }
3692
3782
  };
@@ -4283,7 +4373,7 @@ const levels = [
4283
4373
  "xhigh",
4284
4374
  "max"
4285
4375
  ];
4286
- function object(value) {
4376
+ function object$1(value) {
4287
4377
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
4288
4378
  }
4289
4379
  function unavailable() {
@@ -4292,18 +4382,18 @@ function unavailable() {
4292
4382
  /** Resolve only the selected model's declared/native efforts, with the same precedence as Core. */
4293
4383
  function resolveCopilotResponsesReasoning(ctx, request, candidate) {
4294
4384
  if (request.provider !== "github-copilot" || candidate.protocol !== "openai-responses" || candidate.model !== request.model) return unavailable();
4295
- const profile = object(object(object(ctx.get("settings")?.get("llm-pi-ai"))?.providers)?.["github-copilot"]);
4385
+ const profile = object$1(object$1(object$1(ctx.get("settings")?.get("llm-pi-ai"))?.providers)?.["github-copilot"]);
4296
4386
  const effort = request.reasoningEffort ?? profile?.reasoning;
4297
4387
  if (effort === void 0) return void 0;
4298
4388
  const level = levels.find((value) => value === effort);
4299
4389
  if (level === void 0 || profile === void 0) return unavailable();
4300
4390
  const configured = Array.isArray(profile.models) ? profile.models : [];
4301
- const entry = configured.length > 0 ? object(configured.find((value) => object(value)?.id === request.model)) : object(object(profile.modelOverrides)?.[request.model]);
4391
+ const entry = configured.length > 0 ? object$1(configured.find((value) => object$1(value)?.id === request.model)) : object$1(object$1(profile.modelOverrides)?.[request.model]);
4302
4392
  if (configured.length > 0 && entry === void 0) return unavailable();
4303
4393
  const declared = entry?.reasoningEfforts;
4304
4394
  if (declared !== void 0) {
4305
4395
  if (declared === false) return level === "off" ? void 0 : unavailable();
4306
- const mapping = object(declared);
4396
+ const mapping = object$1(declared);
4307
4397
  if (mapping === void 0) return unavailable();
4308
4398
  const wire = mapping[level];
4309
4399
  if (level === "off" && (wire === null || typeof wire === "string" && wire.length > 0)) return void 0;
@@ -4499,6 +4589,7 @@ function createAccountProvider(descriptors, guard, baseURL) {
4499
4589
  guard.assertActive();
4500
4590
  const entry = table.get(model.id);
4501
4591
  if (model.provider !== "github-copilot-preview" || model.id !== selected() || entry === void 0 || model.api !== entry.api) throw new Error("COPILOT_MANAGED_MODEL_MISMATCH");
4592
+ guard.inspectRequest?.(model, context, options);
4502
4593
  const lease = await guard.beforeWire(model, options);
4503
4594
  if (typeof options?.apiKey !== "string" || options.apiKey.length === 0) {
4504
4595
  lease.release();
@@ -5342,6 +5433,118 @@ function createAccountModelSource(dependencies) {
5342
5433
  return new AccountModelSource(dependencies);
5343
5434
  }
5344
5435
  //#endregion
5436
+ //#region lib/types/compaction-pressure.js
5437
+ function object(value) {
5438
+ return typeof value === "object" && value !== null ? value : void 0;
5439
+ }
5440
+ /** Optional public services are not dependencies of the retained development baseline. */
5441
+ function optionalService(ctx, name) {
5442
+ return ctx.get(name);
5443
+ }
5444
+ function positiveInteger(value) {
5445
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
5446
+ }
5447
+ /**
5448
+ * Request a stock overflow reduction before sending an estimated over-budget
5449
+ * conversation. The loop has already logged and frozen this exact request;
5450
+ * only its owner can rebuild it after a durable compaction. Never rewrite the
5451
+ * request, invoke compaction concurrently, or intercept auxiliary summaries.
5452
+ * @param ctx - Host context owning the reversible stream listener.
5453
+ * @param callbacks - synchronous authenticated budget lookup, without discovery.
5454
+ * @returns disposer for the listener, also owned by its Cordis context.
5455
+ */
5456
+ function installCopilotCompactionPressure(ctx, callbacks) {
5457
+ let warned = false;
5458
+ const unavailable = () => {
5459
+ if (warned) return;
5460
+ warned = true;
5461
+ try {
5462
+ if (typeof ctx.logger?.warn === "function") ctx.logger.warn("COPILOT_COMPACTION_PRESSURE_UNAVAILABLE: optional request measurement or stock automatic recovery is unavailable; retaining the native request budget guard.");
5463
+ } catch (_error) {}
5464
+ };
5465
+ const pressureFailure = (request) => {
5466
+ if (!isAgentLoopRequest(request) || request.purpose !== void 0 || request.provider !== "github-copilot-preview" || request.sessionId === void 0 || request.signal?.aborted) return void 0;
5467
+ if (!isPluginPreviewProvider(ctx, request.provider)) return void 0;
5468
+ if (typeof object(ctx.get("agents"))?.currentInitiator !== "function") {
5469
+ unavailable();
5470
+ return;
5471
+ }
5472
+ const owner = currentSearchInitiator(ctx);
5473
+ if (owner === void 0 || owner.session.id !== request.sessionId) return void 0;
5474
+ if (typeof owner.session.requestHeader !== "function") {
5475
+ unavailable();
5476
+ return;
5477
+ }
5478
+ const header = owner.session.requestHeader();
5479
+ if (header === void 0 || !callConfigEquals(header.config, request)) return void 0;
5480
+ const budget = callbacks.resolve(request);
5481
+ if (budget === void 0 || !positiveInteger(budget.inputBudgetTokens)) return void 0;
5482
+ const compaction = object(optionalService(ctx, "compaction"));
5483
+ const config = object(compaction?.config);
5484
+ if (config?.auto === false) return void 0;
5485
+ if (config?.auto !== true || typeof compaction?.compactIfNeeded !== "function") {
5486
+ unavailable();
5487
+ return;
5488
+ }
5489
+ const retries = (Array.isArray(config.modelPolicies) ? object(config.modelPolicies.find((value) => {
5490
+ const candidate = object(value);
5491
+ return candidate?.provider === request.provider && candidate.model === request.model;
5492
+ })) : void 0)?.maxOverflowRetries ?? config.maxOverflowRetries;
5493
+ if (retries === 0) return void 0;
5494
+ if (!positiveInteger(retries)) {
5495
+ unavailable();
5496
+ return;
5497
+ }
5498
+ const meter = object(optionalService(ctx, "tokenMeter"));
5499
+ if (typeof meter?.measure !== "function") {
5500
+ unavailable();
5501
+ return;
5502
+ }
5503
+ const tokens = object(meter.measure(owner.session))?.totalTokens;
5504
+ if (typeof tokens !== "number" || !Number.isSafeInteger(tokens) || tokens < 0) {
5505
+ unavailable();
5506
+ return;
5507
+ }
5508
+ if (tokens <= budget.inputBudgetTokens) return void 0;
5509
+ return {
5510
+ type: "finish",
5511
+ reason: {
5512
+ kind: "error",
5513
+ failure: {
5514
+ code: CONTEXT_WINDOW_EXCEEDED_CODE,
5515
+ message: `Copilot local estimated input budget exceeded (${tokens} estimated tokens > ${budget.inputBudgetTokens} budget tokens); requesting stock compaction before provider dispatch.`
5516
+ }
5517
+ }
5518
+ };
5519
+ };
5520
+ return ctx.on("llm/stream", (request, next) => {
5521
+ let failure;
5522
+ try {
5523
+ failure = pressureFailure(request);
5524
+ } catch (_error) {
5525
+ unavailable();
5526
+ }
5527
+ if (failure === void 0) return next();
5528
+ const terminal = failure;
5529
+ return (async function* () {
5530
+ if (request.signal?.aborted) {
5531
+ yield {
5532
+ type: "finish",
5533
+ reason: {
5534
+ kind: "aborted",
5535
+ failure: {
5536
+ code: "ABORTED",
5537
+ message: "Copilot request cancelled before provider dispatch."
5538
+ }
5539
+ }
5540
+ };
5541
+ return;
5542
+ }
5543
+ yield terminal;
5544
+ })();
5545
+ }, { prepend: true });
5546
+ }
5547
+ //#endregion
5345
5548
  //#region lib/types/preview-route.js
5346
5549
  function failure(code, category = "AUTH") {
5347
5550
  return new LlmError(code, category);
@@ -5535,18 +5738,25 @@ function resolvedProfile(provider, config) {
5535
5738
  modelErrors: /* @__PURE__ */ new Map()
5536
5739
  });
5537
5740
  }
5538
- /** Only ownership/discovery/lifetime guards are added; Core owns model conversion and wire/replay. */
5741
+ /** Classify only an owned admission decision, never an arbitrary provider error string. */
5742
+ function budgetFailure(result) {
5743
+ const contextExceeded = result.code === "COPILOT_REQUEST_INPUT_LIMIT_EXCEEDED" || result.code === "COPILOT_REQUEST_CONTEXT_LIMIT_EXCEEDED";
5744
+ return new LlmError(contextExceeded ? `COPILOT_CONTEXT_BUDGET_EXCEEDED: ${result.message}` : result.message, contextExceeded ? "CONTEXT_WINDOW_EXCEEDED" : "INVALID_REQUEST");
5745
+ }
5746
+ /** Account-bound admission and purpose defaults; Core owns model conversion and wire/replay. */
5539
5747
  var PreviewAdapter = class extends PiAiAdapter {
5540
5748
  lifetime;
5541
5749
  optionsFor;
5542
5750
  discoverSnapshot;
5543
5751
  refreshRejected;
5544
- constructor(lifetime, optionsFor, discoverSnapshot, refreshRejected) {
5752
+ requestBudgetSettings;
5753
+ constructor(lifetime, optionsFor, discoverSnapshot, refreshRejected, requestBudgetSettings) {
5545
5754
  super(optionsFor());
5546
5755
  this.lifetime = lifetime;
5547
5756
  this.optionsFor = optionsFor;
5548
5757
  this.discoverSnapshot = discoverSnapshot;
5549
5758
  this.refreshRejected = refreshRejected;
5759
+ this.requestBudgetSettings = requestBudgetSettings;
5550
5760
  }
5551
5761
  async listModels(provider) {
5552
5762
  owned(provider);
@@ -5578,10 +5788,9 @@ var PreviewAdapter = class extends PiAiAdapter {
5578
5788
  const cached = this.lifetime.source.readSnapshot();
5579
5789
  const snapshot = await this.discoverSnapshot({ signal });
5580
5790
  const lease = await this.lease(snapshot, model, signal, cached === snapshot);
5581
- const prepared = await this.withRecovery(snapshot, signal, () => new PiAiAdapter(this.optionsFor(lease)).prepareCall(provider, model, signal));
5582
5791
  return {
5583
- model: prepared.model,
5584
- stream: (options) => this.guardedStream(lease, prepared.stream, options)
5792
+ model: (await this.withRecovery(snapshot, signal, () => new PiAiAdapter(this.optionsFor(lease)).prepareCall(provider, model, signal))).model,
5793
+ stream: (options) => this.guardedStream(lease, options)
5585
5794
  };
5586
5795
  }
5587
5796
  stream(options) {
@@ -5591,8 +5800,7 @@ var PreviewAdapter = class extends PiAiAdapter {
5591
5800
  const cached = owner.lifetime.source.readSnapshot();
5592
5801
  const snapshot = await owner.discoverSnapshot({ signal: options.signal });
5593
5802
  const lease = await owner.lease(snapshot, options.model, options.signal, cached === snapshot);
5594
- const native = new PiAiAdapter(owner.optionsFor(lease));
5595
- yield* owner.guardedStream(lease, (request) => native.stream(request), options);
5803
+ yield* owner.guardedStream(lease, options);
5596
5804
  })();
5597
5805
  }
5598
5806
  async lease(snapshot, model, signal, reused) {
@@ -5611,40 +5819,76 @@ var PreviewAdapter = class extends PiAiAdapter {
5611
5819
  throw cause;
5612
5820
  }
5613
5821
  }
5614
- guardedStream(lease, dispatch, options) {
5822
+ guardedStream(lease, options) {
5615
5823
  const owner = this;
5616
5824
  return (async function* () {
5617
5825
  owner.lifetime.start(lease);
5618
5826
  owned(options.provider);
5619
5827
  if (options.model !== lease.descriptor.id) throw failure("COPILOT_PREVIEW_MODEL_MISMATCH");
5828
+ const signal = AbortSignal.any([lease.signal, ...options.signal === void 0 ? [] : [options.signal]]);
5829
+ if (signal.aborted) throw failure("COPILOT_PREVIEW_ABORTED", "ABORTED");
5830
+ const policy = resolveRequestBudgetPolicy(owner.requestBudgetSettings());
5831
+ const model = accountModelFromDescriptor(lease.descriptor, lease.proof.baseURL);
5620
5832
  if (options.reasoningEffort !== void 0) {
5621
- const model = accountModelFromDescriptor(lease.descriptor, lease.proof.baseURL);
5622
5833
  const mapping = Object.entries(model.thinkingLevelMap ?? {}).find(([level]) => level === options.reasoningEffort)?.[1];
5623
5834
  if (typeof mapping !== "string" || mapping.length === 0) throw failure("COPILOT_PREVIEW_REASONING_UNSUPPORTED", "INVALID_REQUEST");
5624
5835
  }
5625
- const signal = AbortSignal.any([lease.signal, ...options.signal === void 0 ? [] : [options.signal]]);
5836
+ let admissionFailure;
5837
+ const inspectRequest = (_model, context, nativeOptions) => {
5838
+ if (signal.aborted) throw failure("COPILOT_PREVIEW_ABORTED", "ABORTED");
5839
+ const calculated = calculateRequestBudget(lease.descriptor, nativeOptions?.maxTokens, policy);
5840
+ if (!calculated.ok) {
5841
+ admissionFailure = budgetFailure(calculated);
5842
+ throw admissionFailure;
5843
+ }
5844
+ const prefix = estimateContextTokens({
5845
+ messages: [],
5846
+ ...context.systemPrompt === void 0 ? {} : { systemPrompt: context.systemPrompt },
5847
+ ...context.tools === void 0 ? {} : { tools: context.tools }
5848
+ }).tokens;
5849
+ const fresh = context.messages.reduce((tokens, message) => tokens + estimateMessageTokens(message), prefix);
5850
+ const admitted = assessRequestBudget(Math.max(estimateContextTokens(context).tokens, fresh), calculated.budget);
5851
+ if (!admitted.ok) {
5852
+ admissionFailure = budgetFailure(admitted);
5853
+ throw admissionFailure;
5854
+ }
5855
+ };
5626
5856
  try {
5627
- for await (const chunk of dispatch({
5857
+ const native = new PiAiAdapter(owner.optionsFor(lease, inspectRequest));
5858
+ const prepared = await native.prepareCall(options.provider, options.model, signal);
5859
+ const suppliedEffort = options.reasoningEffort ?? prepared.model.reasoning?.defaultEffort;
5860
+ const effort = options.purpose === "compaction" ? selectCompactionReasoning(getSupportedThinkingLevels(model), suppliedEffort, policy.compactionReasoning) : suppliedEffort;
5861
+ const request = {
5628
5862
  ...options,
5629
- signal
5630
- })) {
5863
+ signal,
5864
+ ...effort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(effort) }
5865
+ };
5866
+ for await (const chunk of native.stream(request)) {
5867
+ if (admissionFailure !== void 0) {
5868
+ if (signal.aborted) throw failure("COPILOT_PREVIEW_ABORTED", "ABORTED");
5869
+ throw admissionFailure;
5870
+ }
5631
5871
  if (chunk.type === "finish" && chunk.reason.kind === "error" && chunk.reason.failure.code === "UNKNOWN_MODEL") await owner.refreshRejected(lease.snapshot, signal);
5632
5872
  yield chunk;
5633
5873
  }
5874
+ if (admissionFailure !== void 0) throw admissionFailure;
5634
5875
  } catch (cause) {
5876
+ if (signal.aborted) throw failure("COPILOT_PREVIEW_ABORTED", "ABORTED");
5635
5877
  if (cause instanceof LlmError && cause.code === "UNKNOWN_MODEL") await owner.refreshRejected(lease.snapshot, signal);
5636
- throw cause;
5878
+ throw admissionFailure ?? cause;
5637
5879
  }
5638
5880
  })();
5639
5881
  }
5640
5882
  };
5641
5883
  /** Register one stable account route; attach/status remain network-free. */
5642
5884
  function apply$1(ctx, config = {}) {
5643
- const { accountModelTtlMs, accountModelFailureCooldownMs, accountModelSettings, ...requestConfig } = config;
5885
+ const { accountModelTtlMs, accountModelFailureCooldownMs, accountModelSettings, requestBudget, requestBudgetSettings, ...requestConfig } = config;
5644
5886
  const cacheSettings = accountModelSettings ?? (() => ({
5645
5887
  accountModelTtlMs,
5646
5888
  accountModelFailureCooldownMs
5647
5889
  }));
5890
+ const budgetSettings = requestBudgetSettings ?? (() => requestBudget ?? {});
5891
+ resolveRequestBudgetPolicy(budgetSettings());
5648
5892
  const store = createGitHubCopilotCredentialStore(ctx, GITHUB_COPILOT_PREVIEW_PROVIDER_ID);
5649
5893
  const nativeAuth = createAccountModelAuth(createGitHubCopilotCredentialStore(ctx));
5650
5894
  const nativeModels = getBuiltinModels("github-copilot");
@@ -5711,7 +5955,7 @@ function apply$1(ctx, config = {}) {
5711
5955
  })) ?? [];
5712
5956
  const warnings = snapshot?.models.flatMap((model) => {
5713
5957
  const codes = [];
5714
- if (model.maxInputTokens !== void 0 && model.maxInputTokens < model.contextWindow) codes.push("INPUT_LIMIT_NOT_ENFORCED_BY_CORE");
5958
+ if (model.maxInputTokens !== void 0 && model.maxInputTokens < model.contextWindow) codes.push("INPUT_LIMIT_ESTIMATED_GUARD");
5715
5959
  if (snapshotProof !== void 0 && accountModelFromDescriptor(model, snapshotProof.baseURL).unmappedReasoningEfforts.length > 0) codes.push("REASONING_EFFORTS_UNSUPPORTED");
5716
5960
  return codes.map((code) => Object.freeze({
5717
5961
  id: model.id,
@@ -5839,8 +6083,12 @@ function apply$1(ctx, config = {}) {
5839
6083
  });
5840
6084
  } catch {}
5841
6085
  };
5842
- const optionsFor = (lease) => {
5843
- const { provider } = createAccountProvider(lease?.snapshot.models ?? [], lifetime.guard(lease), lease?.proof.baseURL ?? "https://api.individual.githubcopilot.com");
6086
+ const optionsFor = (lease, inspectRequest) => {
6087
+ const guard = {
6088
+ ...lifetime.guard(lease),
6089
+ ...inspectRequest === void 0 ? {} : { inspectRequest }
6090
+ };
6091
+ const { provider } = createAccountProvider(lease?.snapshot.models ?? [], guard, lease?.proof.baseURL ?? "https://api.individual.githubcopilot.com");
5844
6092
  const profile = Object.freeze({
5845
6093
  ...template,
5846
6094
  piProvider: provider
@@ -5862,7 +6110,15 @@ function apply$1(ctx, config = {}) {
5862
6110
  resolveImageAccess: (attachments, ref) => resolveImageAttachmentAccess(attachments, (hostPath) => ctx.get("fs")?.processPathFromHostPath(hostPath), ref)
5863
6111
  };
5864
6112
  };
5865
- const registration = ctx.llm.registerAdapter([GITHUB_COPILOT_PREVIEW_PROVIDER_ID], new PreviewAdapter(lifetime, optionsFor, discoverSnapshot, refreshRejected));
6113
+ const registration = ctx.llm.registerAdapter([GITHUB_COPILOT_PREVIEW_PROVIDER_ID], new PreviewAdapter(lifetime, optionsFor, discoverSnapshot, refreshRejected, budgetSettings));
6114
+ installCopilotCompactionPressure(ctx, { resolve(request) {
6115
+ const snapshot = source.readSnapshot();
6116
+ if (snapshot === void 0 || proofFor(snapshot) === void 0) return void 0;
6117
+ const descriptor = snapshot.models.find((model) => model.id === request.model);
6118
+ if (descriptor === void 0) return void 0;
6119
+ const result = calculateRequestBudget(descriptor, request.maxTokens, resolveRequestBudgetPolicy(budgetSettings()));
6120
+ return result.ok ? { inputBudgetTokens: result.budget.pressureInputLimit } : void 0;
6121
+ } });
5866
6122
  notify = () => {
5867
6123
  const view = getView();
5868
6124
  const directory = JSON.stringify({
@@ -6033,7 +6289,17 @@ function activate(ctx, config) {
6033
6289
  searchMode: "auto",
6034
6290
  defaultSearchProvider: "deepseek-official"
6035
6291
  });
6036
- ctx.plugin(preview_route_default, { accountModelSettings: () => current() });
6292
+ ctx.plugin(preview_route_default, {
6293
+ accountModelSettings: () => current(),
6294
+ requestBudgetSettings: () => {
6295
+ const selected = current();
6296
+ return {
6297
+ safetyTokens: selected.requestBudgetSafetyTokens,
6298
+ pressureRatio: selected.requestBudgetPressureRatio,
6299
+ compactionReasoning: selected.compactionReasoning
6300
+ };
6301
+ }
6302
+ });
6037
6303
  ctx.plugin(GitHubCopilotAuthorizationController);
6038
6304
  ctx.plugin(GitHubCopilotDualModel);
6039
6305
  ctx.plugin(SearchRoutingController);