linkshell-cli 0.10.96 → 0.10.98

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.
@@ -24,9 +24,38 @@ export interface ProMembershipOptions {
24
24
  signal?: AbortSignal;
25
25
  }
26
26
  export declare const LINKSHELL_PRODUCT = "linkshell";
27
- /** The only place a membership is bought. Phones must not link to it (App Store rules). */
28
- export declare const ITOOL_MEMBERSHIP_URL = "https://itool.tech/pro?from=linkshell";
27
+ /**
28
+ * The only place a membership is bought. Phones must not link to it (App Store rules).
29
+ * www and a locale up front: the bare domain costs two redirects (308 to www, 307 to a locale).
30
+ * Chinese, like the rest of the computer UI. The entitlement API below stays on the bare domain:
31
+ * it is exempt from those redirects, and a cross-host redirect would drop the bearer token.
32
+ */
33
+ export declare const ITOOL_MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
29
34
  export declare const ITOOL_ENTITLEMENT_URL = "https://itool.tech/api/membership/entitlement?product=linkshell";
35
+ /**
36
+ * iTool products a membership can unlock: yearly unlocks all of them, monthly the iTool site and LinkShell.
37
+ * Mirrors itool-tech src/lib/membership.ts MEMBERSHIP_PRODUCTS: change them when it changes.
38
+ */
39
+ export declare const MEMBERSHIP_PRODUCT_TOTAL = 7;
40
+ export declare const MONTHLY_PRODUCT_COUNT = 2;
41
+ /**
42
+ * For monthly members: with `checkout=yearly`, itool.tech opens the yearly checkout once the
43
+ * person is signed in. Like the buy page, phones must not link to it (App Store rules).
44
+ * apps/mac mirrors this and the counts in `DesktopModel.swift` (`ITool`).
45
+ */
46
+ export declare const ITOOL_YEARLY_UPGRADE_URL = "https://www.itool.tech/zh/pro?from=linkshell&checkout=yearly";
47
+ /** The upgrade row monthly members see on the computer: what they have, and the way to the rest. */
48
+ export declare const MONTHLY_UPGRADE_COPY: {
49
+ readonly zh: {
50
+ readonly unlocked: "已解锁 2/7 款产品";
51
+ readonly action: "升级年度";
52
+ };
53
+ readonly en: {
54
+ readonly unlocked: "2 of 7 products unlocked";
55
+ readonly action: "Go yearly";
56
+ };
57
+ };
58
+ export declare function monthlyUpgradeLabel(lang?: keyof typeof MONTHLY_UPGRADE_COPY): string;
30
59
  /**
31
60
  * Why a lookup failed. `login` means the token is no good; `unavailable` and `network` say
32
61
  * nothing about the account, so callers keep what they last knew.
@@ -4,9 +4,35 @@
4
4
  * clients just read the entitlement and send people to the buy page.
5
5
  */
6
6
  export const LINKSHELL_PRODUCT = "linkshell";
7
- /** The only place a membership is bought. Phones must not link to it (App Store rules). */
8
- export const ITOOL_MEMBERSHIP_URL = "https://itool.tech/pro?from=linkshell";
7
+ /**
8
+ * The only place a membership is bought. Phones must not link to it (App Store rules).
9
+ * www and a locale up front: the bare domain costs two redirects (308 to www, 307 to a locale).
10
+ * Chinese, like the rest of the computer UI. The entitlement API below stays on the bare domain:
11
+ * it is exempt from those redirects, and a cross-host redirect would drop the bearer token.
12
+ */
13
+ export const ITOOL_MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
9
14
  export const ITOOL_ENTITLEMENT_URL = `https://itool.tech/api/membership/entitlement?product=${LINKSHELL_PRODUCT}`;
15
+ /**
16
+ * iTool products a membership can unlock: yearly unlocks all of them, monthly the iTool site and LinkShell.
17
+ * Mirrors itool-tech src/lib/membership.ts MEMBERSHIP_PRODUCTS: change them when it changes.
18
+ */
19
+ export const MEMBERSHIP_PRODUCT_TOTAL = 7;
20
+ export const MONTHLY_PRODUCT_COUNT = 2;
21
+ /**
22
+ * For monthly members: with `checkout=yearly`, itool.tech opens the yearly checkout once the
23
+ * person is signed in. Like the buy page, phones must not link to it (App Store rules).
24
+ * apps/mac mirrors this and the counts in `DesktopModel.swift` (`ITool`).
25
+ */
26
+ export const ITOOL_YEARLY_UPGRADE_URL = `${ITOOL_MEMBERSHIP_URL}&checkout=yearly`;
27
+ /** The upgrade row monthly members see on the computer: what they have, and the way to the rest. */
28
+ export const MONTHLY_UPGRADE_COPY = {
29
+ zh: { unlocked: `已解锁 ${MONTHLY_PRODUCT_COUNT}/${MEMBERSHIP_PRODUCT_TOTAL} 款产品`, action: "升级年度" },
30
+ en: { unlocked: `${MONTHLY_PRODUCT_COUNT} of ${MEMBERSHIP_PRODUCT_TOTAL} products unlocked`, action: "Go yearly" },
31
+ };
32
+ export function monthlyUpgradeLabel(lang = "zh") {
33
+ const copy = MONTHLY_UPGRADE_COPY[lang];
34
+ return `${copy.unlocked} · ${copy.action}`;
35
+ }
10
36
  const REQUEST_TIMEOUT_MS = 15_000;
11
37
  const LOGIN_REQUIRED = "登录已失效,请重新登录后再试";
12
38
  const MALFORMED = "会员状态返回异常,请稍后重试";
@@ -1 +1 @@
1
- {"version":3,"file":"pro-membership.js","sourceRoot":"","sources":["../../../../client-core/src/pro-membership.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pro-membership.js","sourceRoot":"","sources":["../../../../client-core/src/pro-membership.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAC;AAC7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,8CAA8C,CAAC;AACnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,yDAAyD,iBAAiB,EAAE,CAAC;AAElH;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,oBAAoB,kBAAkB,CAAC;AAElF,oGAAoG;AACpG,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,qBAAqB,IAAI,wBAAwB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;IAChG,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,qBAAqB,OAAO,wBAAwB,oBAAoB,EAAE,MAAM,EAAE,WAAW,EAAE;CAC1G,CAAC;AAEX,MAAM,UAAU,mBAAmB,CAAC,OAA0C,IAAI;IAChF,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,GAAG,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAEnC;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACF;IAAtC,YAAY,OAAe,EAAW,IAAuD;QAC3F,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,SAAI,GAAJ,IAAI,CAAmD;QAE3F,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAgC;IAClE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;AAC3F,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7H,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAc;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC7D,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB;YAAE,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACvF,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,iBAAiB;QAAE,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACxH,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACxF,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/C,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC9F,uFAAuF;IACvF,MAAM,IAAI,GAAmB,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,WAAqB,EAAE,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,IAAiB;IACnD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QACnG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC;gBAAE,MAAM,KAAK,CAAC;QAChF,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;IACrG,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,QAAkB;IACrC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC3G,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,MAAM,IAAI,eAAe,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACpH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AACjF,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,QAAQ,CAAC,OAA6B;IACnD,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,qBAAqB,EAAE;QAC9D,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,OAAO,CAAC,WAAW,EAAE,EAAE;QAC3D,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,yBAAyB,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAwE;IACjG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,gCAAgC,EAAE;QAClH,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,OAAO,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QACxH,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;QACtD,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,yBAAyB,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA6B;IACpE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACjJ,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,UAAU,IAAI,QAAQ;QAC/D,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClF,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yFAAyF;QACzF,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,CAAC,KAAK,YAAY,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC;YAAE,MAAM,KAAK,CAAC;QACzJ,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,EAAE,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { GatewayOptions } from "./relay.js";
2
- export declare const MEMBERSHIP_URL = "https://itool.tech/pro?from=linkshell";
2
+ export declare const MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
3
3
  export interface SubscriptionCheck {
4
4
  /** "unknown": the lookup itself failed, which says nothing about the account. */
5
5
  status: "active" | "inactive" | "unknown";
@@ -1,7 +1,8 @@
1
1
  // The official gateway is part of the iTool membership: any active member (monthly or yearly)
2
2
  // has LinkShell. The gateway asks iTool's `itool_entitlement_for(uid, 'linkshell')` with the
3
3
  // service-role key, on its own behalf, not with the user's token.
4
- export const MEMBERSHIP_URL = "https://itool.tech/pro?from=linkshell";
4
+ // www and a locale up front: the bare domain costs two redirects. Chinese, like the message it ends.
5
+ export const MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
5
6
  /** The RPC's jsonb answer, as the gateway reads it. */
6
7
  export function subscriptionFromEntitlement(value) {
7
8
  const body = value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../gateway/src/subscription.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../gateway/src/subscription.ts"],"names":[],"mappings":"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"}
@@ -95,6 +95,8 @@ export declare class CodexDriver implements AgentDriver {
95
95
  private readonly goalRevision;
96
96
  private skillsRevision;
97
97
  private models?;
98
+ private modelsLoadedAt?;
99
+ private lastModels;
98
100
  private restartTimer?;
99
101
  private restartDelay;
100
102
  private stopped;
@@ -268,12 +270,14 @@ export declare class CodexDriver implements AgentDriver {
268
270
  private sideUpdate;
269
271
  private markFullAccess;
270
272
  private approvePending;
271
- /** From the app-server the driver keeps running: its model list (cached) and the configuration a thread started in `cwd` reads. */
273
+ /** Refresh when a client opens the picker; a long-running host must pick up models added since its first session. */
272
274
  listModels(cwd?: string, model?: string): Promise<import("@linkshell/wire").MethodResult<"agents.models">>;
273
275
  /** The model config.toml (with the project's own layers, for `cwd`) gives a new thread; undefined: Codex's default. */
274
276
  private configuredSettings;
275
277
  private loadModels;
276
278
  private announceConfig;
279
+ private clearModels;
280
+ private publishConfig;
277
281
  private isNews;
278
282
  private loadSkills;
279
283
  /** What `/` offers on a device: the commands above, then the skills this project can use. */
@@ -172,6 +172,8 @@ export class CodexDriver {
172
172
  goalRevision = new Map();
173
173
  skillsRevision = 0;
174
174
  models;
175
+ modelsLoadedAt;
176
+ lastModels = [];
175
177
  restartTimer;
176
178
  restartDelay;
177
179
  stopped = false;
@@ -257,6 +259,7 @@ export class CodexDriver {
257
259
  clearTimeout(timer);
258
260
  this.taskPolls.clear();
259
261
  this.stopped = true;
262
+ this.clearModels();
260
263
  if (this.restartTimer)
261
264
  clearTimeout(this.restartTimer);
262
265
  for (const timer of this.followRetries.values())
@@ -888,6 +891,10 @@ export class CodexDriver {
888
891
  watched(nativeId, open) {
889
892
  if (open) {
890
893
  this.watching.add(nativeId);
894
+ // The hub can keep a session attached after its last viewer leaves.
895
+ // Reopening it must also refresh the choices sent in ls_config.
896
+ if (this.attached.has(nativeId) || this.observed.has(nativeId))
897
+ void this.announceConfig(nativeId);
891
898
  void this.syncTasks(nativeId);
892
899
  this.cancelRelease(nativeId);
893
900
  }
@@ -1601,9 +1608,9 @@ export class CodexDriver {
1601
1608
  this.host?.update(this.id, threadId, { sessionUpdate: "ls_permission_resolved", requestId, optionId });
1602
1609
  }
1603
1610
  }
1604
- /** From the app-server the driver keeps running: its model list (cached) and the configuration a thread started in `cwd` reads. */
1611
+ /** Refresh when a client opens the picker; a long-running host must pick up models added since its first session. */
1605
1612
  async listModels(cwd, model) {
1606
- const [models, configured] = await Promise.all([this.loadModels(true), this.configuredSettings(cwd)]);
1613
+ const [models, configured] = await Promise.all([this.loadModels(true, true), this.configuredSettings(cwd)]);
1607
1614
  const listed = newThreadModels(models, configured.model);
1608
1615
  const selected = model && listed.models.some((entry) => entry.value === model) ? model : undefined;
1609
1616
  return { ...listed, config: configOptions(configured, selected ? { model: selected } : {}, models).filter((option) => option.category === "mode" || option.category === "effort") };
@@ -1620,33 +1627,66 @@ export class CodexDriver {
1620
1627
  return {};
1621
1628
  }
1622
1629
  }
1623
- loadModels(strict = false) {
1624
- this.models ??= (async () => {
1625
- const models = [];
1626
- const cursors = new Set();
1627
- let cursor;
1628
- do {
1629
- const result = await this.rpc("model/list", { includeHidden: false, ...(cursor ? { cursor } : {}) });
1630
- models.push(...result.data);
1631
- cursor = result.nextCursor ?? undefined;
1632
- if (cursor && cursors.has(cursor))
1633
- throw new Error("Codex 返回了重复的模型分页,请重试");
1634
- if (cursor)
1635
- cursors.add(cursor);
1636
- } while (cursor);
1637
- return models;
1638
- })()
1639
- .catch((error) => {
1630
+ loadModels(strict = false, refresh = false) {
1631
+ // Concurrent pickers share the same request. Internal configuration updates can
1632
+ // reuse its result, while the next explicit listing reads the agent again.
1633
+ if (this.modelsLoadedAt !== undefined && (refresh || Date.now() - this.modelsLoadedAt >= 60_000))
1640
1634
  this.models = undefined;
1641
- this.host?.log(`[codex] model/list failed: ${error instanceof Error ? error.message : String(error)}`);
1642
- if (error instanceof RpcError && error.code === RPC_METHOD_NOT_FOUND)
1643
- return [];
1644
- throw error;
1645
- });
1646
- return strict ? this.models : this.models.catch(() => []);
1635
+ if (!this.models) {
1636
+ this.modelsLoadedAt = undefined;
1637
+ const loading = (async () => {
1638
+ const models = [];
1639
+ const cursors = new Set();
1640
+ let cursor;
1641
+ do {
1642
+ const result = await this.rpc("model/list", { includeHidden: false, ...(cursor ? { cursor } : {}) });
1643
+ models.push(...result.data);
1644
+ cursor = result.nextCursor ?? undefined;
1645
+ if (cursor && cursors.has(cursor))
1646
+ throw new Error("Codex 返回了重复的模型分页,请重试");
1647
+ if (cursor)
1648
+ cursors.add(cursor);
1649
+ } while (cursor);
1650
+ return models;
1651
+ })()
1652
+ .then((models) => {
1653
+ if (this.models === loading) {
1654
+ this.modelsLoadedAt = Date.now();
1655
+ this.lastModels = models;
1656
+ // An existing composer reads ls_config, not agents.models. Keep its
1657
+ // current selection while publishing newly discovered choices.
1658
+ for (const nativeId of this.watching) {
1659
+ if (this.attached.has(nativeId) || this.observed.has(nativeId))
1660
+ this.publishConfig(nativeId, models);
1661
+ }
1662
+ }
1663
+ return models;
1664
+ })
1665
+ .catch((error) => {
1666
+ if (this.models === loading)
1667
+ this.models = undefined;
1668
+ this.host?.log(`[codex] model/list failed: ${error instanceof Error ? error.message : String(error)}`);
1669
+ if (error instanceof RpcError && error.code === RPC_METHOD_NOT_FOUND)
1670
+ return [];
1671
+ throw error;
1672
+ });
1673
+ this.models = loading;
1674
+ }
1675
+ return strict ? this.models : this.models.catch(() => this.lastModels);
1647
1676
  }
1648
1677
  async announceConfig(nativeId) {
1678
+ // Permissions and Plan still come from this session when the catalogue
1679
+ // is unavailable; keep its last model choices while publishing new settings.
1649
1680
  const models = await this.loadModels();
1681
+ if (!this.stopped)
1682
+ this.publishConfig(nativeId, models);
1683
+ }
1684
+ clearModels() {
1685
+ this.models = undefined;
1686
+ this.modelsLoadedAt = undefined;
1687
+ this.lastModels = [];
1688
+ }
1689
+ publishConfig(nativeId, models) {
1650
1690
  const options = configOptions(this.settings.get(nativeId) ?? {}, this.overridesOf(nativeId), models);
1651
1691
  if (options.length > 0 && this.isNews(`config:${nativeId}`, options))
1652
1692
  this.host?.update(this.id, nativeId, { sessionUpdate: "ls_config", options });
@@ -1849,7 +1889,7 @@ export class CodexDriver {
1849
1889
  });
1850
1890
  }
1851
1891
  onDown(reason) {
1852
- this.models = undefined;
1892
+ this.clearModels();
1853
1893
  this.skills.clear();
1854
1894
  if (this.stopped)
1855
1895
  return;