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

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
@@ -962,7 +962,7 @@ let SearchRoutingController = (() => {
962
962
  //#endregion
963
963
  //#region package.json
964
964
  var name$1 = "dsh-github-copilot";
965
- var version = "0.4.0-alpha.28";
965
+ var version = "0.4.0-alpha.30";
966
966
  //#endregion
967
967
  //#region lib/types/probe.js
968
968
  /**
@@ -6371,39 +6371,54 @@ function activate(ctx, config) {
6371
6371
  return false;
6372
6372
  }
6373
6373
  }
6374
- function createPlan(candidates, cfg, route, plans) {
6374
+ function createPlan(candidates, cfg, provider, plans, operation) {
6375
6375
  const startedAt = generation;
6376
- const signal = plans === void 0 ? proofCancellation.signal : AbortSignal.any([proofCancellation.signal, plans.cancellation.signal]);
6377
- const provider = route?.provider;
6378
- function bind(candidate) {
6376
+ const signal = AbortSignal.any([proofCancellation.signal, ...plans === void 0 ? [] : [plans.cancellation.signal]]);
6377
+ const probeSignal = operation?.signal === void 0 ? signal : AbortSignal.any([signal, operation.signal]);
6378
+ function bind(candidate, lifetime) {
6379
6379
  candidateGenerations.set(candidate, startedAt);
6380
- candidateSignals.set(candidate, signal);
6380
+ candidateSignals.set(candidate, lifetime);
6381
6381
  if (provider !== void 0) candidateProviders.set(candidate, provider);
6382
6382
  }
6383
- for (const candidate of candidates) bind(candidate);
6384
- const nextPlan = new SearchPlan(candidates, (candidate) => probeCandidate(candidate, hooks.resolveApiKey, cfg.probeTimeoutMs, signal), cfg.probe, signal);
6383
+ for (const candidate of candidates) bind(candidate, cfg.probe ? probeSignal : signal);
6384
+ const nextPlan = new SearchPlan(candidates, (candidate) => probeCandidate(candidate, async (selected) => {
6385
+ operation?.assertCurrent();
6386
+ const auth = await hooks.resolveApiKey(selected);
6387
+ operation?.assertCurrent();
6388
+ return auth;
6389
+ }, cfg.probeTimeoutMs, probeSignal), cfg.probe, signal);
6385
6390
  nextPlan.settled.then(() => {
6386
6391
  const chosen = nextPlan.chosenCandidate();
6387
- if (chosen !== void 0) bind(chosen);
6392
+ if (chosen !== void 0) bind(chosen, signal);
6388
6393
  });
6389
6394
  return nextPlan;
6390
6395
  }
6391
6396
  function matches(cached, route, candidates, cfg) {
6392
- return cached !== void 0 && cached.generation === generation && sameRoute(route, cached.route) && cached.probe.enabled === cfg.probe && cached.probe.timeoutMs === cfg.probeTimeoutMs && sameCandidates(candidates, cached.plan.candidates);
6397
+ try {
6398
+ cached?.assertProof?.();
6399
+ } catch {
6400
+ return false;
6401
+ }
6402
+ if (cached?.assertProof !== void 0 && cached.plan.chosenCandidate() === void 0 && (cached.plan.available() || cached.probeSignal?.aborted === true)) return false;
6403
+ return cached !== void 0 && cached.generation === generation && cached.plan.signal?.aborted !== true && sameRoute(route, cached.route) && cached.probe.enabled === cfg.probe && cached.probe.timeoutMs === cfg.probeTimeoutMs && sameCandidates(candidates, cached.plan.candidates);
6393
6404
  }
6394
- function plan(route, cfg, owner, surface) {
6405
+ function plan(route, cfg, owner, surface, operation) {
6395
6406
  const plans = owner === void 0 ? void 0 : plansFor(owner);
6396
- const candidates = surface === "inline" ? candidatesForRoute(route) : surface === "configured" ? configuredCandidates(route, cfg) : traditionalCandidates(route, cfg);
6407
+ const candidates = surface === "inline" ? candidatesForRoute(route) : surface === "configured" ? configuredCandidates(cfg) : traditionalCandidates(route, cfg);
6397
6408
  const cached = plans?.[surface];
6398
6409
  if (matches(cached, route, candidates, cfg)) return cached.plan;
6399
6410
  const startedAt = generation;
6400
- const nextPlan = createPlan(candidates, cfg, route, plans);
6411
+ const nextPlan = createPlan(candidates, cfg, surface === "configured" ? GITHUB_COPILOT_PREVIEW_PROVIDER_ID : route?.provider, plans, operation);
6401
6412
  if (generation === startedAt && active && plans?.cancellation.signal.aborted !== true) {
6402
6413
  if (plans !== void 0) plans[surface] = {
6403
6414
  plan: nextPlan,
6404
6415
  route,
6405
6416
  probe: probeSettings(cfg),
6406
- generation: startedAt
6417
+ generation: startedAt,
6418
+ ...operation === void 0 ? {} : {
6419
+ assertProof: operation.assertProof,
6420
+ ...operation.signal === void 0 ? {} : { probeSignal: operation.signal }
6421
+ }
6407
6422
  };
6408
6423
  }
6409
6424
  if (surface === "inline") {
@@ -6439,13 +6454,13 @@ function activate(ctx, config) {
6439
6454
  model
6440
6455
  };
6441
6456
  }
6442
- /** Build a Copilot search plan from the provider-owned search model, not the chat route. */
6443
- async function configuredWebPlan(signal) {
6457
+ /** Resolve provider-owned candidates only on an actual search, never from Chat defaults. */
6458
+ async function configuredWebPlan(assertCurrent, assertProof, signal) {
6444
6459
  const owner = currentSearchInitiator(ctx);
6445
6460
  const cfg = current();
6446
6461
  const selection = configuredSearchSelection(cfg);
6447
6462
  const startedAt = generation;
6448
- if (owner === void 0 || disposedOwners.has(owner) || selection === void 0) throw new Error("github-copilot: independent hosted search requires an initiating Agent and github-copilot.searchModel");
6463
+ if (owner === void 0 || disposedOwners.has(owner) || !configuredAllowed(cfg)) throw new Error("github-copilot: independent hosted search requires an initiating Agent and an allowed Copilot provider");
6449
6464
  const plans = plansFor(owner);
6450
6465
  const signals = [proofCancellation.signal, plans.cancellation.signal];
6451
6466
  if (signal !== void 0) signals.push(signal);
@@ -6453,18 +6468,39 @@ function activate(ctx, config) {
6453
6468
  force: false,
6454
6469
  signal: AbortSignal.any(signals)
6455
6470
  });
6471
+ assertCurrent();
6456
6472
  if (!active || startedAt !== generation || plans.cancellation.signal.aborted || signal?.aborted === true) throw new Error("github-copilot: configured search proof invalidated during route resolution");
6457
- return plan(currentChatRoute(ctx, selection), cfg, owner, "configured");
6473
+ return plan(selection === void 0 ? void 0 : currentChatRoute(ctx, selection), cfg, owner, "configured", {
6474
+ assertCurrent,
6475
+ assertProof,
6476
+ ...signal === void 0 ? {} : { signal }
6477
+ });
6458
6478
  }
6459
6479
  function traditionalCandidates(route, cfg) {
6460
6480
  if (!cfg.enabled || route === void 0) return [];
6461
6481
  if (cfg.providers.length > 0 && !cfg.providers.includes(route.provider)) return [];
6462
6482
  return candidatesForRoute(route).filter((candidate) => candidate.protocol === "openai-responses");
6463
6483
  }
6464
- function configuredCandidates(route, cfg) {
6465
- if (!cfg.enabled || route === void 0) return [];
6466
- if (!(cfg.providers.length === 0 || cfg.providers.includes("github-copilot") || cfg.providers.includes("github-copilot-preview"))) return [];
6467
- return candidatesForRoute(route).filter((candidate) => candidate.protocol === "openai-responses");
6484
+ function configuredAllowed(cfg) {
6485
+ return cfg.enabled && (cfg.providers.length === 0 || cfg.providers.includes("github-copilot") || cfg.providers.includes("github-copilot-preview"));
6486
+ }
6487
+ function configuredCandidates(cfg) {
6488
+ if (!configuredAllowed(cfg)) return [];
6489
+ const selection = configuredSearchSelection(cfg);
6490
+ if (selection !== void 0) return candidatesForRoute(currentChatRoute(ctx, selection)).filter((candidate) => candidate.protocol === "openai-responses");
6491
+ const preview = ctx.get("githubCopilotPreview");
6492
+ const ids = [...new Set(preview?.getView().models.map((model) => model.id) ?? [])].sort();
6493
+ const candidates = [];
6494
+ for (const model of ids) {
6495
+ const route = currentChatRoute(ctx, {
6496
+ provider: GITHUB_COPILOT_PREVIEW_PROVIDER_ID,
6497
+ model
6498
+ });
6499
+ if (route?.api !== "openai-responses") continue;
6500
+ candidates.push(...candidatesForRoute(route));
6501
+ if (candidates.length === 3) break;
6502
+ }
6503
+ return candidates;
6468
6504
  }
6469
6505
  /** Local checks only; availability must never start a credential lookup or probe. */
6470
6506
  function traditionalAvailable() {
@@ -6486,13 +6522,13 @@ function activate(ctx, config) {
6486
6522
  const owner = currentSearchInitiator(ctx);
6487
6523
  if (owner === void 0 || disposedOwners.has(owner)) return false;
6488
6524
  const cfg = current();
6525
+ if (!configuredAllowed(cfg)) return false;
6489
6526
  const selection = configuredSearchSelection(cfg);
6490
- if (selection === void 0) return false;
6491
- const route = currentChatRoute(ctx, selection);
6492
- const candidates = configuredCandidates(route, cfg);
6527
+ const route = selection === void 0 ? void 0 : currentChatRoute(ctx, selection);
6528
+ const candidates = configuredCandidates(cfg);
6493
6529
  if (candidates.length === 0) {
6494
- const allowed = cfg.providers.length === 0 || cfg.providers.includes("github-copilot") || cfg.providers.includes("github-copilot-preview");
6495
- return cfg.enabled && allowed && route?.provider === "github-copilot-preview" && route.api === void 0 && ctx.get("githubCopilotPreview")?.getView().configured === true;
6530
+ const view = ctx.get("githubCopilotPreview")?.getView();
6531
+ return view?.configured === true && (selection === void 0 ? view.state !== "ready" : route?.provider === "github-copilot-preview" && route.api === void 0);
6496
6532
  }
6497
6533
  const cached = ownerPlans.get(owner)?.configured;
6498
6534
  return !matches(cached, route, candidates, cfg) || cached.plan.available();
@@ -6504,14 +6540,17 @@ function activate(ctx, config) {
6504
6540
  const cfg = current();
6505
6541
  const preview = ctx.get("githubCopilotPreview");
6506
6542
  const proof = preview?.captureSearchProof();
6543
+ const assertProof = () => {
6544
+ if (!active || generation !== startedGeneration || owner === void 0 || disposedOwners.has(owner) || preview === void 0 || ctx.get("githubCopilotPreview") !== preview || proof?.() !== true) throw new ConfiguredSearchProofInvalidated();
6545
+ };
6507
6546
  const assertCurrent = () => {
6508
6547
  if (signal?.aborted) throw new WebError("web search aborted", "WEB_ABORTED");
6509
- if (!active || generation !== startedGeneration || owner === void 0 || disposedOwners.has(owner) || preview === void 0 || ctx.get("githubCopilotPreview") !== preview || proof?.() !== true) throw new ConfiguredSearchProofInvalidated();
6548
+ assertProof();
6510
6549
  };
6511
6550
  assertCurrent();
6512
6551
  const provider = createTraditionalSearchProvider(configuredAvailable, async (requestSignal) => {
6513
6552
  assertCurrent();
6514
- const searchPlan = await configuredWebPlan(requestSignal);
6553
+ const searchPlan = await configuredWebPlan(assertCurrent, assertProof, requestSignal);
6515
6554
  assertCurrent();
6516
6555
  return searchPlan;
6517
6556
  }, {
@@ -6522,7 +6561,7 @@ function activate(ctx, config) {
6522
6561
  assertCurrent();
6523
6562
  return auth;
6524
6563
  }
6525
- }, () => cfg, "github-copilot-hosted requires github-copilot.searchModel selecting an account-authorized OpenAI Responses model");
6564
+ }, () => cfg, "github-copilot-hosted requires an eligible account-authorized Responses search candidate; an explicit searchModel override must also be eligible");
6526
6565
  try {
6527
6566
  const result = await provider.search(request, signal);
6528
6567
  assertCurrent();
@@ -39,7 +39,7 @@ export interface InlineConfig {
39
39
  routeWebSearch?: boolean;
40
40
  /** Automatic fallback, disclosed in results; no per-search approval dialog. */
41
41
  searchFallback?: 'none' | 'deepseek';
42
- /** Copilot model used when `github-copilot-hosted` serves independently of the initiating chat model. */
42
+ /** Optional authoritative legacy override; otherwise hosted search resolves bounded account-owned candidates independently of Chat. */
43
43
  searchModel?: string;
44
44
  /** Internal JSON backup of route leaves temporarily owned by the GPT-6 overlay. */
45
45
  temporaryRouteBackup?: string;
@@ -2,10 +2,9 @@ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
2
  import type { ReactElement } from 'react';
3
3
  interface SearchRoutingCardProps {
4
4
  readonly settings: ClientContext['remote']['settings'];
5
- readonly copilot: ClientContext['remote']['githubCopilot'];
6
5
  readonly routing: ClientContext['remote']['githubCopilotSearchRouting'];
7
6
  }
8
- /** Provider-level primary and final fallback; model choice stays with each provider. */
7
+ /** Save provider routing independently of account discovery and provider-specific model settings. */
9
8
  export declare function WebSearchRoutingCard(props: SearchRoutingCardProps): ReactElement;
10
9
  export {};
11
10
  //# sourceMappingURL=web-search-routing-card.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-github-copilot",
3
3
  "description": "DSH companion for GitHub Copilot sign-in, account-aware model profiles, tool compatibility, and provider-hosted search.",
4
- "version": "0.4.0-alpha.28",
4
+ "version": "0.4.0-alpha.30",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "registry": "https://registry.npmjs.org/",