dsh-neartoken 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -137,8 +137,11 @@
137
137
 
138
138
  | 通道 | 判定 | 请求 | 响应 |
139
139
  |---|---|---|---|
140
- | `images` | `supported_endpoint_types` 含 `image-generation`(gpt-image 系) | `POST /v1/images/generations` | `data[0].b64_json` 或临时 `url` |
141
- | `chat` | 其余(nano-banana、`gemini-*-image`、grok-imagine) | `POST /v1/chat/completions` | 回复文本里的 `data:image/...;base64,` 或图片链接 |
140
+ | `images` | 声明含 `image-generation`(gpt-image 系) | `POST /v1/images/generations` | `data[0].b64_json` 或临时 `url` |
141
+ | `genai` | 声明含 `gemini`(nano-banana、`gemini-*-image`) | `POST /v1beta/models/<model>:generateContent` | `candidates[0].content.parts[].inlineData`(结构化) |
142
+ | `chat` | 其余(只有 `openai` 的,如 grok-imagine) | `POST /v1/chat/completions` | 回复文本里的 `data:image/...;base64,` 或图片链接 |
143
+
144
+ Gemini 系走原生 surface 而不是 openai 兼容层:同模型同提示词实测 **74 秒**(原生,返回 `inlineData`)对 **110 秒**(chat,返回 markdown data URL)。原生拿的是结构化字段,不用从文本里抠图,也不依赖网关的转换实现。
142
145
 
143
146
  实测数据:`gpt-image-2.5-flare` 走促销分组 `#39` 约 43 秒返回 1.3 MB PNG(base64);`nano-banana-pro` 打 images 端点会被站点拒绝(`only imagen models are supported`),走 chat 才出图;`grok-imagine-image` 两条都通。拿到 bytes 后按 magic bytes 判格式(PNG/JPEG/WebP/GIF),再交给 attachment 服务落盘。
144
147
 
@@ -148,10 +151,11 @@
148
151
 
149
152
  `images` 传工作区里的图片路径,工具读成 data URL 后按通道发送:
150
153
 
151
- - **images 通道**:作为 `image` 数组发给 `/v1/images/generations`(站点 DTO 里没有可用的 `edits` 路由,参考图只能搭生成请求)
154
+ - **images 通道**:作为 `image` 数组(data URL)发给 `/v1/images/generations`(站点 DTO 里没有可用的 `edits` 路由,参考图只能搭生成请求)
155
+ - **genai 通道**:作为 `inlineData` part 与提示词一起进 `contents[0].parts`
152
156
  - **chat 通道**:作为 `image_url` content part 与提示词一起进 `messages`
153
157
 
154
- 实测(`nano-banana-pro` + 一张 2.1 MB 的 PNG 参考图):chat 通道 110 秒出图,返回 jpeg。参考图在**发请求前**读盘并校验(存在、是普通文件、是 PNG/JPEG/WebP/GIF、≤ 20 MB),所以缺文件不会白花一次生成。
158
+ 实测(`nano-banana-pro` + 一张 2.1 MB 的 PNG 参考图):chat 通道 110 秒出图返回 jpeg;同一模型单轮文生图走 genai 通道 74 秒返回 PNG。参考图在**发请求前**读盘并校验(存在、是普通文件、是 PNG/JPEG/WebP/GIF、≤ 20 MB),所以缺文件不会白花一次生成。
155
159
 
156
160
  ### 落盘
157
161
 
package/lib/client.js CHANGED
@@ -321,21 +321,21 @@ window.__ModuleLoader__.load({
321
321
  document.head.appendChild(tag);
322
322
  }
323
323
  var group_tags_module_css_default = {
324
- "toneOrange": "FotuUq_toneOrange",
324
+ "ratioBase": "FotuUq_ratioBase",
325
+ "toneCyan": "FotuUq_toneCyan",
326
+ "toneLime": "FotuUq_toneLime",
325
327
  "toneRose": "FotuUq_toneRose",
326
328
  "tonePink": "FotuUq_tonePink",
327
- "toneCyan": "FotuUq_toneCyan",
328
- "toneTeal": "FotuUq_toneTeal",
329
+ "toneIndigo": "FotuUq_toneIndigo",
330
+ "toneOrange": "FotuUq_toneOrange",
329
331
  "ratioCheap": "FotuUq_ratioCheap",
330
- "ratioBase": "FotuUq_ratioBase",
331
- "tag": "FotuUq_tag",
332
+ "ratioChip": "FotuUq_ratioChip",
333
+ "toneTeal": "FotuUq_toneTeal",
332
334
  "toneViolet": "FotuUq_toneViolet",
333
335
  "toneSky": "FotuUq_toneSky",
334
- "toneFuchsia": "FotuUq_toneFuchsia",
335
- "toneIndigo": "FotuUq_toneIndigo",
336
- "ratioChip": "FotuUq_ratioChip",
337
336
  "toneAmber": "FotuUq_toneAmber",
338
- "toneLime": "FotuUq_toneLime",
337
+ "toneFuchsia": "FotuUq_toneFuchsia",
338
+ "tag": "FotuUq_tag",
339
339
  "ratioPricey": "FotuUq_ratioPricey",
340
340
  "toneEmerald": "FotuUq_toneEmerald"
341
341
  };
@@ -392,39 +392,39 @@ window.__ModuleLoader__.load({
392
392
  document.head.appendChild(tag);
393
393
  }
394
394
  var ModelGroupSelect_module_css_default = {
395
- "triggerIcon": "_2pt-bW_triggerIcon",
396
- "modelOption": "_2pt-bW_modelOption",
397
- "search": "_2pt-bW_search",
398
- "toast": "_2pt-bW_toast",
399
- "optionTrailing": "_2pt-bW_optionTrailing",
400
395
  "searchRow": "_2pt-bW_searchRow",
401
- "searchClear": "_2pt-bW_searchClear",
402
- "error": "_2pt-bW_error",
403
- "cellValue": "_2pt-bW_cellValue",
396
+ "cellChevron": "_2pt-bW_cellChevron",
397
+ "toast": "_2pt-bW_toast",
404
398
  "chevron": "_2pt-bW_chevron",
405
- "selected": "_2pt-bW_selected",
406
- "check": "_2pt-bW_check",
407
- "groupOptionLabel": "_2pt-bW_groupOptionLabel",
408
- "triggerLabel": "_2pt-bW_triggerLabel",
409
- "empty": "_2pt-bW_empty",
410
- "optionCopy": "_2pt-bW_optionCopy",
411
399
  "retry": "_2pt-bW_retry",
412
- "optionActive": "_2pt-bW_optionActive",
413
- "menu": "_2pt-bW_menu",
414
400
  "option": "_2pt-bW_option",
415
- "warning": "_2pt-bW_warning",
416
- "cellChevron": "_2pt-bW_cellChevron",
417
- "status": "_2pt-bW_status",
418
- "trigger": "_2pt-bW_trigger",
419
- "triggerEffort": "_2pt-bW_triggerEffort",
420
401
  "groups": "_2pt-bW_groups",
421
- "variantCount": "_2pt-bW_variantCount",
422
- "groupName": "_2pt-bW_groupName",
423
- "cellLabel": "_2pt-bW_cellLabel",
424
- "cell": "_2pt-bW_cell",
425
402
  "modelName": "_2pt-bW_modelName",
403
+ "groupOptionLabel": "_2pt-bW_groupOptionLabel",
404
+ "groupInline": "_2pt-bW_groupInline",
405
+ "triggerIcon": "_2pt-bW_triggerIcon",
406
+ "optionTrailing": "_2pt-bW_optionTrailing",
407
+ "cellLabel": "_2pt-bW_cellLabel",
408
+ "error": "_2pt-bW_error",
409
+ "modelOption": "_2pt-bW_modelOption",
410
+ "groupName": "_2pt-bW_groupName",
411
+ "search": "_2pt-bW_search",
412
+ "triggerEffort": "_2pt-bW_triggerEffort",
413
+ "variantCount": "_2pt-bW_variantCount",
414
+ "check": "_2pt-bW_check",
415
+ "cellValue": "_2pt-bW_cellValue",
416
+ "status": "_2pt-bW_status",
417
+ "warning": "_2pt-bW_warning",
418
+ "optionCopy": "_2pt-bW_optionCopy",
426
419
  "root": "_2pt-bW_root",
427
- "groupInline": "_2pt-bW_groupInline"
420
+ "trigger": "_2pt-bW_trigger",
421
+ "menu": "_2pt-bW_menu",
422
+ "triggerLabel": "_2pt-bW_triggerLabel",
423
+ "empty": "_2pt-bW_empty",
424
+ "searchClear": "_2pt-bW_searchClear",
425
+ "optionActive": "_2pt-bW_optionActive",
426
+ "selected": "_2pt-bW_selected",
427
+ "cell": "_2pt-bW_cell"
428
428
  };
429
429
  //#endregion
430
430
  //#region src/client/ModelGroupSelect.tsx
@@ -990,48 +990,48 @@ window.__ModuleLoader__.load({
990
990
  document.head.appendChild(tag);
991
991
  }
992
992
  var NearTokenSection_module_css_default = {
993
- "chevron": "_02HI2q_chevron",
994
- "rowMeta": "_02HI2q_rowMeta",
995
- "rowRatio": "_02HI2q_rowRatio",
996
- "autosave": "_02HI2q_autosave",
997
- "badgeOn": "_02HI2q_badgeOn",
993
+ "facts": "_02HI2q_facts",
994
+ "cardToggle": "_02HI2q_cardToggle",
995
+ "cardHead": "_02HI2q_cardHead",
996
+ "fact": "_02HI2q_fact",
997
+ "actions": "_02HI2q_actions",
998
+ "codeRow": "_02HI2q_codeRow",
998
999
  "handle": "_02HI2q_handle",
999
- "hint": "_02HI2q_hint",
1000
+ "autosave": "_02HI2q_autosave",
1000
1001
  "tipGroupName": "_02HI2q_tipGroupName",
1001
- "codeRow": "_02HI2q_codeRow",
1002
- "notice": "_02HI2q_notice",
1003
- "fact": "_02HI2q_fact",
1004
- "search": "_02HI2q_search",
1005
- "row": "_02HI2q_row",
1006
- "tipGroup": "_02HI2q_tipGroup",
1002
+ "button": "_02HI2q_button",
1007
1003
  "label": "_02HI2q_label",
1008
- "section": "_02HI2q_section",
1004
+ "rowName": "_02HI2q_rowName",
1005
+ "card": "_02HI2q_card",
1006
+ "intro": "_02HI2q_intro",
1007
+ "code": "_02HI2q_code",
1008
+ "rowRatio": "_02HI2q_rowRatio",
1009
+ "tipRow": "_02HI2q_tipRow",
1009
1010
  "select": "_02HI2q_select",
1011
+ "countDot": "_02HI2q_countDot",
1012
+ "tipGroup": "_02HI2q_tipGroup",
1010
1013
  "name": "_02HI2q_name",
1011
- "chevronOpen": "_02HI2q_chevronOpen",
1012
- "card": "_02HI2q_card",
1013
- "factValue": "_02HI2q_factValue",
1014
- "form": "_02HI2q_form",
1015
- "button": "_02HI2q_button",
1016
- "facts": "_02HI2q_facts",
1017
- "cardToggle": "_02HI2q_cardToggle",
1018
- "cardHead": "_02HI2q_cardHead",
1019
- "factLabel": "_02HI2q_factLabel",
1014
+ "notice": "_02HI2q_notice",
1020
1015
  "list": "_02HI2q_list",
1021
- "buttonPrimary": "_02HI2q_buttonPrimary",
1022
- "intro": "_02HI2q_intro",
1023
- "rowName": "_02HI2q_rowName",
1016
+ "factLabel": "_02HI2q_factLabel",
1017
+ "form": "_02HI2q_form",
1018
+ "tip": "_02HI2q_tip",
1019
+ "badge": "_02HI2q_badge",
1020
+ "rowMeta": "_02HI2q_rowMeta",
1021
+ "chevron": "_02HI2q_chevron",
1022
+ "chevronOpen": "_02HI2q_chevronOpen",
1024
1023
  "toolbar": "_02HI2q_toolbar",
1024
+ "hint": "_02HI2q_hint",
1025
+ "search": "_02HI2q_search",
1025
1026
  "tipTitle": "_02HI2q_tipTitle",
1026
- "title": "_02HI2q_title",
1027
- "actions": "_02HI2q_actions",
1028
- "countDot": "_02HI2q_countDot",
1029
- "code": "_02HI2q_code",
1030
1027
  "count": "_02HI2q_count",
1031
- "badge": "_02HI2q_badge",
1032
- "tip": "_02HI2q_tip",
1033
1028
  "countPicked": "_02HI2q_countPicked",
1034
- "tipRow": "_02HI2q_tipRow"
1029
+ "factValue": "_02HI2q_factValue",
1030
+ "buttonPrimary": "_02HI2q_buttonPrimary",
1031
+ "row": "_02HI2q_row",
1032
+ "badgeOn": "_02HI2q_badgeOn",
1033
+ "title": "_02HI2q_title",
1034
+ "section": "_02HI2q_section"
1035
1035
  };
1036
1036
  //#endregion
1037
1037
  //#region src/client/NearTokenSection.tsx
@@ -1785,7 +1785,7 @@ window.__ModuleLoader__.load({
1785
1785
  }),
1786
1786
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1787
1787
  className: NearTokenSection_module_css_default.rowMeta,
1788
- children: t(entry.channel === "images" ? "images.channel.images" : "images.channel.chat")
1788
+ children: t(entry.channel === "images" ? "images.channel.images" : entry.channel === "genai" ? "images.channel.genai" : "images.channel.chat")
1789
1789
  })
1790
1790
  ]
1791
1791
  }, entry.model))
@@ -1904,6 +1904,7 @@ window.__ModuleLoader__.load({
1904
1904
  "images.intro": "开启后模型可以调用 generate_image 工具生图。勾选要用的生图模型,并为每个模型指定走哪个分组(决定计费与可用性)。",
1905
1905
  "images.enable": "启用 generate_image 工具",
1906
1906
  "images.channel.images": "images 接口",
1907
+ "images.channel.genai": "gemini 接口",
1907
1908
  "images.channel.chat": "chat 接口",
1908
1909
  "images.save": "保存",
1909
1910
  "images.saving": "正在保存…",
@@ -1988,6 +1989,7 @@ window.__ModuleLoader__.load({
1988
1989
  "images.intro": "Once on, the model can call the generate_image tool. Check the picture models you want and pick the group each one bills to.",
1989
1990
  "images.enable": "Enable the generate_image tool",
1990
1991
  "images.channel.images": "images endpoint",
1992
+ "images.channel.genai": "gemini endpoint",
1991
1993
  "images.channel.chat": "chat endpoint",
1992
1994
  "images.save": "Save",
1993
1995
  "images.saving": "Saving…",
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["css","useSyncExternalStore","useState","useRef","useId","useMemo","css","IconDataOutlineRegular","StateDot","IconChevronDownOutlineRegular","createPortal","MenuSurface","IconChevronRightOutlineRegular","Input","IconCloseFillRegular","MenuGroup","IconCheckOutlineRegular","useState","useCallback","css","useRef","IconChevronDownOutlineRegular"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/groups.ts","../src/client/group-tags.tsx","../src/client/ModelGroupSelect.tsx","../src/client/NearTokenSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/**\n * The wire vocabulary shared by the Host routes and the browser section: four\n * route paths and the JSON each answers. Both build faces import this file, so\n * a route rename cannot leave the browser calling a path the Host stopped\n * serving.\n *\n * Nothing here carries a password: the plugin never collects site credentials.\n * A connection is authorized by the site's own device-authorization flow, in\n * the user's browser — the Host only polls its result.\n *\n * @module\n */\n\n/** State read by the settings page before it draws, and while it waits. */\nexport const STATUS_PATH = '/neartoken/status'\n/** Start a device authorization (the Host then polls the site). */\nexport const AUTHORIZE_PATH = '/neartoken/authorize'\n/** Abandon the authorization in progress. */\nexport const CANCEL_PATH = '/neartoken/cancel'\n/** Forget the stored key and revoke it on the site. */\nexport const LOGOUT_PATH = '/neartoken/logout'\n/** Read the catalog beside the stored whitelist; POST a new whitelist. */\nexport const MODELS_PATH = '/neartoken/models'\n/** Read the picture models and the image-generation setting; POST one change to it. */\nexport const IMAGES_PATH = '/neartoken/images'\n\n/** One account's facts, as the settings card shows them. */\nexport interface NearTokenAccountSummary {\n /** The dashboard user name. */\n readonly username: string\n /** The display name when the site set one, otherwise the user name. */\n readonly displayName: string\n /** The user's own group, which is the default group a request routes by. */\n readonly group: string\n /** Remaining quota, formatted in the site's own display currency. */\n readonly balance: string\n /** Quota already spent, formatted the same way. */\n readonly used: string\n}\n\n/** One authorization the human must finish in their browser. */\nexport interface NearTokenPendingAuthorization {\n /** The short code the site shows on its confirmation page. */\n readonly userCode: string\n /** The page to open; carries no code of its own. */\n readonly verificationUri: string\n /** The same page with the code prefilled. */\n readonly verificationUriComplete: string\n /** When this attempt stops being valid, as epoch milliseconds. */\n readonly expiresAt: number\n}\n\n/** The `GET /neartoken/status` answer. */\nexport interface NearTokenStatus {\n /** Whether an API key is stored, i.e. whether the provider route is mounted. */\n readonly configured: boolean\n /** Site root the plugin talks to. */\n readonly baseURL: string\n /** Name of the token the site created for this plugin. */\n readonly tokenName: string\n /** Account facts, absent until a connection obtained them. */\n readonly account?: NearTokenAccountSummary\n /** The authorization in progress, while one is running. */\n readonly pending?: NearTokenPendingAuthorization\n /** Why the last attempt ended without a key, until the next one starts. */\n readonly error?: string\n}\n\n/** One group's offering of a model, as the whitelist list shows it. */\nexport interface NearTokenModelGroup {\n /** Group name exactly as the site publishes it, badge prefixes included. */\n readonly group: string\n /** The group's multiplier caption (`0.4x`), absent when the site published none. */\n readonly ratio?: string\n}\n\n/** One model the whitelist can show or hide. */\nexport interface NearTokenModelEntry {\n /** Bare model name: the whitelist key, and what the site's API takes. */\n readonly model: string\n /** Every group offering this model, in catalog order. */\n readonly groups: readonly NearTokenModelGroup[]\n /**\n * The cheapest multiplier among those groups, when the site published one.\n * The list shows it beside the group count; the per-group detail stays in\n * the hover panel.\n */\n readonly minRatio?: number\n}\n\n/** The `GET /neartoken/models` answer. */\nexport interface NearTokenModelsState {\n /** Every model the site offers, in catalog order. */\n readonly models: readonly NearTokenModelEntry[]\n /** The stored whitelist; empty means no whitelist, so every model is shown. */\n readonly enabled: readonly string[]\n}\n\n/** The `POST /neartoken/models` request body. */\nexport interface NearTokenModelsPatch {\n /** Model names to keep visible; an empty list restores the whole catalog. */\n readonly enabled: readonly string[]\n}\n\n/** The `POST /neartoken/authorize` answer. */\nexport type BeginAuthorizationOutcome =\n | { readonly status: 'pending'; readonly pending: NearTokenPendingAuthorization }\n | { readonly status: 'failed'; readonly message: string }\n\n/** Which request shape one picture model speaks: the images endpoint or a chat completion. */\nexport type NearTokenImageChannel = 'images' | 'chat'\n\n/** One picture model the image-generation setting can enable. */\nexport interface NearTokenImageModelEntry {\n /** Bare model name, as the site's API takes it. */\n readonly model: string\n /** The request shape this model answers. */\n readonly channel: NearTokenImageChannel\n /** Every group offering this model, in catalog order. */\n readonly groups: readonly NearTokenModelGroup[]\n /** The cheapest multiplier among those groups, when the site published one. */\n readonly minRatio?: number\n}\n\n/** The `GET /neartoken/images` answer. */\nexport interface NearTokenImagesState {\n /** Whether the `generate_image` tool is mounted for this profile. */\n readonly enabled: boolean\n /** Every picture model the site offers, in catalog order. */\n readonly models: readonly NearTokenImageModelEntry[]\n /** The enabled models and the group each one routes through; empty means the tool has no model to call. */\n readonly selection: Readonly<Record<string, string>>\n}\n\n/** The `POST /neartoken/images` request body. */\nexport interface NearTokenImagesPatch {\n /** Whether the tool should be mounted. */\n readonly enabled: boolean\n /** Bare model name to the group name it must route through. */\n readonly models: Readonly<Record<string, string>>\n}\n\n","/**\n * The browser half of the settings-page carrier: four same-origin calls to the\n * Host routes declared in ../protocol.ts.\n *\n * @module\n */\nimport {\n AUTHORIZE_PATH, CANCEL_PATH, IMAGES_PATH, LOGOUT_PATH, MODELS_PATH, STATUS_PATH,\n} from '../protocol.ts'\nimport type {\n BeginAuthorizationOutcome, NearTokenImagesPatch, NearTokenImagesState, NearTokenModelsPatch,\n NearTokenModelsState, NearTokenStatus,\n} from '../protocol.ts'\n\n/** The HTTP carrier, injectable so the section's behavior is testable. */\nexport type Fetch = (input: string, init?: RequestInit) => Promise<Response>\n\n/** What the section calls. */\nexport interface NearTokenApi {\n /** Read the key state, the account card, and any authorization in progress. */\n status(): Promise<NearTokenStatus>\n /** Start a device authorization; the Host polls the site from then on. */\n begin(): Promise<BeginAuthorizationOutcome>\n /** Abandon the authorization in progress. */\n cancel(): Promise<void>\n /** Forget the stored key and revoke it on the site. */\n signOut(): Promise<void>\n /** Read the site's model catalog beside the stored whitelist. */\n models(): Promise<NearTokenModelsState>\n /** Save a whitelist; an empty list shows every model again. */\n saveModels(enabled: readonly string[]): Promise<void>\n /** Read the picture models beside the stored image-generation setting. */\n images(): Promise<NearTokenImagesState>\n /** Save the image-generation setting: the tool's switch and one group per enabled model. */\n saveImages(patch: NearTokenImagesPatch): Promise<void>\n}\n\n/**\n * Read one JSON answer, turning an HTTP refusal into a thrown error.\n * @param response - the pending response.\n * @returns the parsed body.\n * @throws {Error} when the route answered a non-2xx status.\n */\nasync function jsonOf<T>(response: Response): Promise<T> {\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`)\n return await response.json() as T\n}\n\n/**\n * Build the carrier.\n * @param fetcher - HTTP carrier; defaults to the page's own fetch.\n * @returns the section's four calls.\n */\nexport function createNearTokenApi(fetcher: Fetch = (input, init) => fetch(input, init)): NearTokenApi {\n /** POST one empty JSON body and read its JSON answer. */\n const post = async <T>(path: string): Promise<T> => jsonOf<T>(await fetcher(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: '{}',\n }))\n return {\n async status() {\n return await jsonOf<NearTokenStatus>(await fetcher(STATUS_PATH, { headers: { accept: 'application/json' } }))\n },\n async begin() {\n return await post<BeginAuthorizationOutcome>(AUTHORIZE_PATH)\n },\n async cancel() {\n await post<unknown>(CANCEL_PATH)\n },\n async signOut() {\n await post<unknown>(LOGOUT_PATH)\n },\n async models() {\n return await jsonOf<NearTokenModelsState>(await fetcher(MODELS_PATH, { headers: { accept: 'application/json' } }))\n },\n async saveModels(enabled) {\n await jsonOf<unknown>(await fetcher(MODELS_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ enabled } satisfies NearTokenModelsPatch),\n }))\n },\n async images() {\n return await jsonOf<NearTokenImagesState>(await fetcher(IMAGES_PATH, { headers: { accept: 'application/json' } }))\n },\n async saveImages(patch) {\n const response = await fetcher(IMAGES_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n })\n if (!response.ok) {\n // The Host refuses a selection its catalog does not have; its message\n // names the reason, so the page shows that rather than a status code.\n const refusal = await response.json().catch(() => ({ message: `HTTP ${String(response.status)}` })) as { message?: string }\n throw new Error(refusal.message ?? `HTTP ${String(response.status)}`)\n }\n },\n }\n}\n","/**\n * The group dimension, folded out of catalog names.\n *\n * The NearToken provider (this plugin's own host half) expands the site's\n * `/api/pricing` into one catalog model per (group, model) pair, named\n * `\"<model> @ <group>\"`. The picker folds those back into one row per model\n * and turns the group into its own selectable level.\n *\n * Group names carry a badge convention on the site: a run of bracketed tags\n * before the group's own name (`[低价][反重力] Claude`). Those render as\n * colored capsules; the ratio comes through the catalog entry's description\n * (`分组倍率 0.4x`).\n *\n * Prototype scope: the provider allowlist and the name separator are\n * hardcoded. They become Config fields once the shape settles.\n */\n\n/** Providers whose catalog names carry a group suffix. */\nexport const GROUPED_PROVIDERS: readonly string[] = ['neartoken']\n\n/**\n * Capsule tone of one group badge. Tier tags keep a fixed hue so a long list\n * reads at a glance; any other tag takes a hue derived from its own text.\n */\nexport type BadgeTone =\n | 'rose' | 'emerald' | 'violet' | 'sky' | 'amber' | 'cyan'\n | 'fuchsia' | 'indigo' | 'teal' | 'lime' | 'orange' | 'pink'\n\n/** Tags that carry a tier meaning, with the hue the site gives each of them. */\nconst KNOWN_TAG_TONES: Record<string, BadgeTone> = {\n 满血: 'rose',\n 低价: 'emerald',\n 神秘: 'violet',\n 官Key: 'sky',\n 官key: 'sky',\n 可蒸馏: 'amber',\n 反重力: 'cyan',\n 生图: 'fuchsia',\n AIS: 'indigo',\n 稳定: 'teal',\n}\n\n/** Hues used by tags with no tier meaning, spread out so neighbours differ. */\nconst FALLBACK_TONES: readonly BadgeTone[] = [\n 'sky', 'amber', 'cyan', 'fuchsia', 'indigo', 'teal',\n 'lime', 'orange', 'pink', 'emerald', 'violet', 'rose',\n]\n\n/**\n * @param tag - one bracketed tag's text.\n * @returns a stable bucket for hue selection.\n */\nfunction hashTag(tag: string): number {\n let hash = 0\n for (const char of tag) hash = (hash * 31 + (char.codePointAt(0) ?? 0)) % 100_003\n return hash\n}\n\n/** One capsule rendered before the group's own name. */\nexport interface GroupBadge {\n readonly text: string\n readonly tone: BadgeTone\n}\n\n/** One group label split into its badge capsules and its own name. */\nexport interface ParsedGroup {\n readonly badges: readonly GroupBadge[]\n readonly label: string\n}\n\n/** Separator between a model name and its group suffix in the catalog name. */\nconst GROUP_SEPARATOR = ' @ '\n\n/**\n * Split one catalog name into the model's own name and the optional group.\n * @param name - the catalog model name, e.g. `glm-5.3 @ [低价][满血] 国模`.\n * @returns the model name without the suffix, plus the group when present.\n */\nexport function splitModelName(name: string): { model: string; group?: string } {\n const at = name.lastIndexOf(GROUP_SEPARATOR)\n if (at <= 0) return { model: name }\n const group = name.slice(at + GROUP_SEPARATOR.length).trim()\n const model = name.slice(0, at).trim()\n if (model === '' || group === '') return { model: name }\n return { model, group }\n}\n\n/**\n * Parse one group name's bracketed badge prefix.\n * @param name - the raw group name, e.g. `[低价][反重力] Claude`.\n * @returns the badge capsules (in order) and the group's own name.\n */\nexport function parseGroupLabel(name: string): ParsedGroup {\n const badges: GroupBadge[] = []\n let rest = name\n while (rest.startsWith('[')) {\n const end = rest.indexOf(']')\n if (end <= 1) break\n badges.push(badgeOf(rest.slice(1, end)))\n rest = rest.slice(end + 1)\n }\n return { badges, label: rest.trim() }\n}\n\n/**\n * @param text - one bracketed badge's text.\n * @returns the capsule tone that text renders in.\n */\nfunction badgeOf(text: string): GroupBadge {\n const known = KNOWN_TAG_TONES[text.trim()]\n if (known !== undefined) return { text, tone: known }\n return { text, tone: FALLBACK_TONES[hashTag(text) % FALLBACK_TONES.length] ?? 'sky' }\n}\n\n/**\n * The capitals each vendor writes its own family name with.\n *\n * The catalog publishes ids in lowercase only, so the display name has to put\n * them back: GPT and GLM are acronyms, DeepSeek is camel case, MiniMax and MiMo\n * keep an inner capital, and the `xhigh` effort is spelled `XHigh` everywhere\n * else in the product.\n */\nconst BRAND_SPELLING: Readonly<Record<string, string>> = {\n gpt: 'GPT',\n glm: 'GLM',\n deepseek: 'DeepSeek',\n minimax: 'MiniMax',\n mimo: 'MiMo',\n xhigh: 'XHigh',\n tts: 'TTS',\n}\n\n/**\n * Render a model name the way the pickers show it: hyphens become separators\n * and every word is capitalized, so `claude-opus-5-c` reads `Claude Opus 5 C`.\n * A vendor's own spelling wins over that rule (`gpt-5.5` reads `GPT 5.5`).\n *\n * The trailing `-c` stays a word on purpose: the site pairs every such model\n * with a twin that lacks the suffix (`claude-opus-5` beside `claude-opus-5-c`),\n * so dropping it from the display would leave two different models with the\n * same name. {@link isCodingUnfriendly} is what tells the reader which one it\n * is looking at.\n * @param model - a bare model name.\n * @returns the display name.\n */\nexport function displayModelName(model: string): string {\n return model\n .split('-')\n .filter(part => part.length > 0)\n .map(part => BRAND_SPELLING[part.toLowerCase()] ?? part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n}\n\n/**\n * Read the group ratio out of the host-provided catalog description.\n * @param description - the catalog entry's description (`分组倍率 0.4x`).\n * @returns the ratio caption, or undefined when the entry carries none.\n */\nexport function ratioOf(description: string | undefined): string | undefined {\n if (description === undefined) return undefined\n const match = description.match(/([\\d.]+)x/)\n return match === null ? undefined : `${match[1]}x`\n}\n\n/**\n * @param provider - a catalog provider id.\n * @returns whether this provider's model names carry group suffixes.\n */\nexport function isGroupedProvider(provider: string): boolean {\n return GROUPED_PROVIDERS.includes(provider)\n}\n\n/** One group's take on a model: the exact catalog entry that routes it. */\nexport interface ModelVariant<M> {\n readonly provider: string\n readonly group?: string\n readonly model: M\n}\n\n/** One model row: the display name plus every group that offers it. */\nexport interface ModelOption<M> {\n /** Fold key: the model name without its group suffix. */\n readonly key: string\n /** Displayed model name. */\n readonly label: string\n readonly variants: readonly ModelVariant<M>[]\n}\n\n/**\n * Fold one provider's models into rows, one per model name.\n *\n * A provider outside {@link GROUPED_PROVIDERS} keeps a 1:1 mapping (no suffix\n * parsing), so its rows behave exactly like the built-in picker's.\n * @param provider - the catalog provider id.\n * @param models - that provider's catalog models, in catalog order.\n * @returns one option per distinct model name, in first-seen order.\n */\nexport function foldModels<M extends { readonly id: string; readonly name: string }>(\n provider: string, models: readonly M[],\n): ModelOption<M>[] {\n const grouped = isGroupedProvider(provider)\n const byKey = new Map<string, { label: string; variants: ModelVariant<M>[] }>()\n for (const model of models) {\n const { model: label, group } = grouped ? splitModelName(model.name) : { model: model.name, group: undefined }\n const key = grouped ? label : model.id\n const row = byKey.get(key)\n const variant: ModelVariant<M> = { provider, model, ...group === undefined ? {} : { group } }\n if (row === undefined) byKey.set(key, { label, variants: [variant] })\n else row.variants.push(variant)\n }\n return [...byKey].map(([key, row]) => ({ key, label: row.label, variants: row.variants }))\n}\n\n/**\n * Pick the variant a model row should route to.\n * @param option - the row being chosen.\n * @param preferredProvider - the currently selected provider, kept when it offers the model.\n * @param preferredGroup - the currently selected group, kept when that provider offers it.\n * @returns the variant to submit.\n */\nexport function chooseVariant<M>(\n option: ModelOption<M>, preferredProvider: string | undefined, preferredGroup: string | undefined,\n): ModelVariant<M> | undefined {\n const local = option.variants.filter(variant => variant.provider === preferredProvider)\n const pool = local.length > 0 ? local : option.variants\n return pool.find(variant => variant.group === preferredGroup) ?? pool[0]\n}\n","/**\n * The site's group vocabulary, rendered the way the site renders it: a group\n * name's leading tags become colour-coded capsules, its multiplier becomes a\n * capsule that reads green below the base price, and a model the site marks\n * with a `-c` suffix carries a note.\n *\n * Both surfaces that show groups — the settings page's whitelist and the\n * composer's model seat — share these so one group never looks like two\n * different things in the same product.\n */\nimport type { BadgeTone } from './groups.ts'\nimport css from './group-tags.module.css'\n\n/** CSS Module class carrying each tone's hue, kept parallel to {@link BadgeTone}. */\nconst TONE_CLASS: Record<BadgeTone, string> = {\n rose: css.toneRose,\n emerald: css.toneEmerald,\n violet: css.toneViolet,\n sky: css.toneSky,\n amber: css.toneAmber,\n cyan: css.toneCyan,\n fuchsia: css.toneFuchsia,\n indigo: css.toneIndigo,\n teal: css.toneTeal,\n lime: css.toneLime,\n orange: css.toneOrange,\n pink: css.tonePink,\n}\n\n/** One bracketed group tag as a coloured capsule. */\nexport function GroupTag(props: { text: string; tone: BadgeTone }) {\n return <span className={css.tag + ' ' + TONE_CLASS[props.tone]}>{props.text}</span>\n}\n\n/**\n * One group's multiplier as a capsule.\n * @param props - the multiplier caption the catalog carried (`0.3x`).\n * @returns the capsule, toned by whether it beats the base price.\n */\nexport function RatioChip(props: { ratio: string }) {\n const value = Number.parseFloat(props.ratio)\n let tone = css.ratioBase\n if (Number.isFinite(value)) {\n if (value < 1) tone = css.ratioCheap\n else if (value > 1) tone = css.ratioPricey\n }\n return <span className={css.ratioChip + ' ' + tone}>{props.ratio}</span>\n}\n","/**\n * ModelGroupSelect: a drop-in replacement for the composer's model seat\n * ('conversation.input.model') that adds a THIRD level between the model and\n * the reasoning effort.\n *\n * The root menu is a row triple — Model / Group / Effort — where the Group row\n * appears only while the selected model comes from a provider whose catalog\n * names carry a group suffix (see groups.ts). The trigger states all three:\n * \"GLM 5.3 · Zhang · high\".\n *\n * Registered at priority -1, one step below the built-in seat, so the shipped\n * picker stays untouched and simply does not render.\n */\nimport { MenuGroup, MenuSurface, Input } from '@deepseek-ai/dsh-client-ui-primitives'\nimport {\n useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore,\n type CSSProperties, type KeyboardEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport type { ModelReasoningEffort, ModelSelection } from '@deepseek-ai/dsh-api-remotes/client'\nimport {\n IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconChevronRightOutlineRegular,\n IconCloseFillRegular, IconDataOutlineRegular, StateDot,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ModelGroupSelectInjected } from './slots.ts'\nimport type { ModelCatalogModel } from '@deepseek-ai/dsh-api-session-controller/types'\nimport {\n chooseVariant, displayModelName, foldModels, isGroupedProvider, parseGroupLabel, ratioOf,\n type ModelOption, type ModelVariant,\n} from './groups.ts'\nimport { GroupTag, RatioChip } from './group-tags.tsx'\nimport css from './ModelGroupSelect.module.css'\n\n/** Which pane the dropdown shows: the three-row root or one drilled-in list. */\ntype Pane = 'root' | 'model' | 'group' | 'effort'\n\n/** Unplaced portal card: hidden but laid out at a fixed origin so offset sizes are real. */\nconst MEASURE_STYLE: CSSProperties = { visibility: 'hidden', left: 0, top: 0 }\n\n/** One provider's folded rows. */\ninterface ProviderRows<M> {\n readonly id: string\n readonly name: string\n readonly options: readonly ModelOption<M>[]\n}\n\n/** Provider display order: account first, official next, then catalog order. */\nfunction providerRank(id: string): number {\n return id === 'deepseek-account' ? 0 : id === 'deepseek-official' ? 1 : 2\n}\n\n/**\n * Case-insensitive containment filter for the model search.\n * @param label - the row's display name.\n * @param query - the trimmed search text; empty keeps every row.\n * @returns whether the row stays visible.\n */\nfunction matchesQuery(label: string, query: string): boolean {\n return query === '' || label.toLowerCase().includes(query.toLowerCase())\n}\n\n/**\n * Keep the effort the user already picked when the new model offers it.\n * @param model - the catalog model the selection will route to.\n * @param previous - the effort in use before the switch.\n * @returns the effort to submit, or undefined for a model without reasoning.\n */\nfunction effortFor(model: ModelCatalogModel, previous: string | undefined): string | undefined {\n const reasoning = model.reasoning\n if (reasoning === undefined) return undefined\n if (previous !== undefined && reasoning.efforts.some(level => level.id === previous)) return previous\n return reasoning.defaultEffort\n}\n\n/**\n * Render the composer model seat with the group level.\n * @param props - owner share (locked) + injected directory face + the locale seat.\n * @returns the trigger and, while open, the three-level menu.\n */\nexport function ModelGroupSelect(\n { locked, available, directory, load, select, t }:\n ModelGroupSelectInjected & Pick<PropsRuntime<'conversation.input.model'>, 'locked'> & PropsLocale<'modelGroups'>,\n) {\n const state = useSyncExternalStore(\n fn => directory.subscribe(fn),\n () => directory.getSnapshot(),\n )\n const [open, setOpen] = useState(false)\n const [pane, setPane] = useState<Pane>('root')\n const [query, setQuery] = useState('')\n const [highlighted, setHighlighted] = useState(0)\n const [toast, setToast] = useState<string | null>(null)\n const rootRef = useRef<HTMLDivElement | null>(null)\n const triggerRef = useRef<HTMLButtonElement | null>(null)\n const menuRef = useRef<HTMLDivElement | null>(null)\n const searchRef = useRef<HTMLInputElement | null>(null)\n const [menuPos, setMenuPos] = useState<CSSProperties | null>(null)\n const id = useId()\n\n const accountName = t('provider.account')\n const providers = useMemo<ProviderRows<ModelCatalogModel>[]>(() => state.groups\n .map(group => ({\n id: group.id,\n name: group.id === 'deepseek-account' ? accountName : group.name,\n options: foldModels(group.id, group.models),\n }))\n .toSorted((left, right) => providerRank(left.id) - providerRank(right.id)), [state.groups, accountName])\n\n const current = state.current\n const located = useMemo(() => {\n for (const provider of providers) {\n for (const option of provider.options) {\n for (const variant of option.variants) {\n if (variant.provider === current?.provider && variant.model.id === current.model) {\n return { provider, option, variant }\n }\n }\n }\n }\n return undefined\n }, [providers, current])\n\n const reasoning = located?.variant.model.reasoning\n const effectiveEffort = current?.reasoningEffort ?? reasoning?.defaultEffort\n const effortLabel = located === undefined\n ? undefined\n : reasoning === undefined\n ? state.retainedEffort\n : effectiveEffort === undefined\n ? t('effort.providerDefault')\n : reasoning.efforts.find((level: ModelReasoningEffort) => level.id === effectiveEffort)?.name ?? effectiveEffort\n\n const currentGroup = located?.variant.group\n const groupChoices = useMemo(() => located === undefined || currentGroup === undefined\n ? []\n : located.option.variants.filter(variant => variant.provider === located.provider.id\n && variant.group !== undefined), [located, currentGroup])\n\n const filteredProviders = useMemo(() => {\n const trimmed = query.trim()\n return providers\n .map(provider => ({\n ...provider,\n options: provider.options.filter(option => matchesQuery(option.label, trimmed)),\n }))\n .filter(provider => provider.options.length > 0)\n }, [providers, query])\n\n const visibleOptions = useMemo(() => filteredProviders.flatMap(provider =>\n provider.options.map(option => ({ provider, option }))), [filteredProviders])\n const showSearch = providers.reduce((total, provider) => total + provider.options.length, 0) > 4\n const activeIndex = Math.min(highlighted, Math.max(0, visibleOptions.length - 1))\n const { pending } = state\n const busy = pending !== null\n const waiting = located === undefined && state.status === 'loading'\n\n const show = (): void => {\n triggerRef.current?.focus()\n setQuery('')\n setHighlighted(0)\n setPane(located === undefined ? 'model' : 'root')\n setOpen(true)\n load()\n }\n\n const close = (restoreFocus = false): void => {\n setOpen(false)\n setPane('root')\n if (restoreFocus) queueMicrotask(() => { triggerRef.current?.focus() })\n }\n\n useEffect(() => {\n if (!open) return\n const closeOutside = (event: MouseEvent): void => {\n if (rootRef.current?.contains(event.target as Node) === true) return\n if (menuRef.current?.contains(event.target as Node) === true) return\n setOpen(false)\n setPane('root')\n }\n document.addEventListener('mousedown', closeOutside)\n return () => { document.removeEventListener('mousedown', closeOutside) }\n }, [open])\n\n useLayoutEffect(() => {\n if (!available || !open) { setMenuPos(null); return }\n const place = (): void => {\n const rect = triggerRef.current?.getBoundingClientRect()\n if (rect === undefined) return\n const MARGIN = 12\n const width = menuRef.current?.offsetWidth ?? 0\n const height = menuRef.current?.offsetHeight ?? 0\n let x = rect.right - width\n let y = rect.top - 8 - height\n if (width > 0) x = Math.min(Math.max(x, MARGIN), window.innerWidth - width - MARGIN)\n if (height > 0) y = Math.min(Math.max(y, MARGIN), window.innerHeight - height - MARGIN)\n setMenuPos({ left: x, top: y })\n }\n place()\n window.addEventListener('scroll', place, true)\n window.addEventListener('resize', place)\n return () => {\n window.removeEventListener('scroll', place, true)\n window.removeEventListener('resize', place)\n }\n }, [available, open, pane, state, query])\n\n useLayoutEffect(() => {\n if (open && pane === 'model' && showSearch) searchRef.current?.focus()\n }, [open, pane, showSearch])\n\n if (!available) return null\n\n const settle = (result: Awaited<ReturnType<ModelGroupSelectInjected['select']>>): void => {\n if (result === undefined) return\n if (result.ok) {\n setOpen(false)\n setPane('root')\n return\n }\n const { error } = result\n setToast(error.code === 'session/writer-held'\n ? t('error.sessionInUse')\n : t('error.action', { message: `${error.code}: ${error.message}` }))\n }\n\n const submit = (selection: ModelSelection): void => {\n triggerRef.current?.focus()\n void select(selection).then(settle)\n }\n\n const chooseOption = (option: ModelOption<ModelCatalogModel>): void => {\n const variant = chooseVariant(option, current?.provider, currentGroup)\n if (variant === undefined) return\n if (current?.provider === variant.provider && current.model === variant.model.id) {\n close(true)\n return\n }\n const effort = effortFor(variant.model, effectiveEffort)\n submit({\n provider: variant.provider,\n model: variant.model.id,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n })\n }\n\n const chooseGroup = (variant: ModelVariant<ModelCatalogModel>): void => {\n if (current === null) return\n if (variant.model.id === current.model) {\n close(true)\n return\n }\n const effort = effortFor(variant.model, effectiveEffort)\n submit({\n provider: variant.provider,\n model: variant.model.id,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n })\n }\n\n const chooseEffort = (effort: string | undefined): void => {\n if (current === null) return\n if (effectiveEffort === effort) {\n close(true)\n return\n }\n submit({\n provider: current.provider,\n model: current.model,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n })\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {\n if (event.nativeEvent.isComposing) return\n if (event.key === 'Escape' && open) {\n event.preventDefault()\n if (pane !== 'root' && located !== undefined) setPane('root')\n else close(true)\n return\n }\n if (!open || pane !== 'root') return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n setPane('root')\n }\n }\n\n // Only this plugin's own provider gets the rewritten name: every other\n // provider's models are the application's own catalog entries, so the seat\n // must keep showing them exactly as the built-in seat does. The group is a\n // routing dimension and is never spelled out here.\n const ownProvider = located !== undefined && isGroupedProvider(located.provider.id)\n const modelLabel = waiting\n ? t('trigger.loading')\n : located === undefined\n ? t('trigger.fallback')\n : ownProvider\n ? `${displayModelName(located.option.label)} @ ${located.provider.name}`\n : located.option.label\n const triggerParts = [modelLabel, effortLabel].filter(part => part !== undefined && part !== '')\n const triggerLabel = triggerParts.join(' · ')\n const triggerAria = waiting\n ? t('trigger.loading')\n : located === undefined\n ? t('trigger.selectAria')\n : t('trigger.aria', { model: modelLabel })\n\n let optionIndex = 0\n\n return (\n <div ref={rootRef} className={css.root} onKeyDown={onKeyDown}>\n <button\n ref={triggerRef}\n type=\"button\"\n className={css.trigger}\n aria-label={triggerAria}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? `${id}-menu` : undefined}\n title={triggerLabel}\n aria-busy={busy}\n disabled={locked}\n onClick={() => { if (open) close(true); else show() }}\n >\n <IconDataOutlineRegular className={css.triggerIcon} size={16} />\n <span className={css.triggerLabel}>{modelLabel}</span>\n {effortLabel !== undefined && <span className={css.triggerEffort}>{effortLabel}</span>}\n {busy\n ? <StateDot state=\"ongoing\" />\n : <IconChevronDownOutlineRegular className={css.chevron} />}\n </button>\n\n {open && createPortal(\n <MenuSurface\n ref={menuRef}\n id={`${id}-menu`}\n className={css.menu}\n style={menuPos ?? MEASURE_STYLE}\n role={pane === 'model' || pane === 'group' ? 'group' : 'menu'}\n aria-label={t('menu.aria')}\n aria-busy={state.status === 'loading' || busy}\n >\n {pane === 'root' && (\n <>\n <button type=\"button\" role=\"menuitem\" className={css.cell} onClick={() => { setPane('model') }}>\n <span className={css.cellLabel}>{t('menu.model')}</span>\n <span className={css.cellValue}>{modelLabel}</span>\n <IconChevronRightOutlineRegular className={css.cellChevron} />\n </button>\n {currentGroup !== undefined && (\n <button\n type=\"button\"\n role=\"menuitem\"\n className={css.cell}\n disabled={groupChoices.length < 2}\n onClick={() => { setPane('group') }}\n >\n <span className={css.cellLabel}>{t('menu.group')}</span>\n <span className={css.cellValue}>\n <GroupInline group={currentGroup} description={located?.variant.model.description} showRatio />\n </span>\n {groupChoices.length > 1 && <IconChevronRightOutlineRegular className={css.cellChevron} />}\n </button>\n )}\n {reasoning !== undefined && (\n <button type=\"button\" role=\"menuitem\" className={css.cell} onClick={() => { setPane('effort') }}>\n <span className={css.cellLabel}>{t('menu.effort')}</span>\n <span className={css.cellValue}>{effortLabel}</span>\n <IconChevronRightOutlineRegular className={css.cellChevron} />\n </button>\n )}\n </>\n )}\n\n {pane === 'model' && (\n <>\n {showSearch && (\n <div className={css.searchRow}>\n <Input\n ref={searchRef}\n className={css.search}\n type=\"text\"\n role=\"searchbox\"\n aria-label={t('search.placeholder')}\n placeholder={t('search.placeholder')}\n value={query}\n readOnly={busy}\n onChange={(event) => { setQuery(event.target.value); setHighlighted(0) }}\n />\n {query !== '' && (\n <button\n type=\"button\"\n className={css.searchClear}\n aria-label={t('search.clear')}\n disabled={busy}\n onClick={() => { setQuery(''); searchRef.current?.focus() }}\n >\n <IconCloseFillRegular />\n </button>\n )}\n </div>\n )}\n {state.status === 'loading' && <div className={css.status}>{t('status.loading')}</div>}\n {state.error !== null && (\n <div className={css.error}>\n <span>{t('error.action', { message: state.error })}</span>\n <button type=\"button\" className={css.retry} onClick={load}>{t('action.reload')}</button>\n </div>\n )}\n {state.failures.map(failure => (\n <div className={css.warning} key={failure.id}>\n <span>{t('warning.groupLoad', { name: failure.id === 'deepseek-account' ? accountName : failure.name, message: failure.message })}</span>\n <button type=\"button\" className={css.retry} onClick={load}>{t('action.reload')}</button>\n </div>\n ))}\n <div className={css.groups} role=\"menu\" aria-label={t('menu.model')} hidden={filteredProviders.length === 0}>\n {filteredProviders.map(provider => (\n <MenuGroup key={provider.id} label={provider.name}>\n {provider.options.map(option => {\n const index = optionIndex++\n const isCurrent = located !== undefined && located.option.key === option.key\n && located.provider.id === provider.id\n const groups = option.variants.filter(variant => variant.group !== undefined)\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isCurrent}\n id={`${id}-model-${index}`}\n tabIndex={showSearch ? -1 : 0}\n onFocus={() => { setHighlighted(index) }}\n data-highlighted={index === activeIndex ? '' : undefined}\n className={css.option + ' ' + css.modelOption + ' ' + (index === activeIndex ? css.optionActive : '')}\n key={option.key}\n title={option.label}\n disabled={busy}\n onMouseMove={() => { setHighlighted(index) }}\n onClick={() => { chooseOption(option) }}\n >\n <span className={css.optionCopy}>\n <span className={css.modelName}>\n {isGroupedProvider(provider.id) ? displayModelName(option.label) : option.label}\n </span>\n\n </span>\n <span className={css.optionTrailing}>\n {groups.length > 1 && <span className={css.variantCount}>{groups.length}</span>}\n <span className={css.check}>\n {isCurrent ? <IconCheckOutlineRegular /> : null}\n </span>\n </span>\n </button>\n )\n })}\n </MenuGroup>\n ))}\n </div>\n {state.status === 'ready' && filteredProviders.length === 0 && (\n <div className={css.empty} role=\"status\">\n {t(providers.length === 0 ? 'empty.models' : 'search.empty')}\n </div>\n )}\n </>\n )}\n\n {pane === 'group' && (\n <>\n {groupChoices.length === 0\n ? <div className={css.empty}>{t('empty.groups')}</div>\n : groupChoices.map((variant) => {\n const isCurrent = variant.model.id === current?.model\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isCurrent}\n className={css.option + (isCurrent ? ' ' + css.selected : '')}\n key={variant.model.id}\n disabled={busy}\n onClick={() => { chooseGroup(variant) }}\n >\n <span className={css.optionCopy}>\n <span className={css.groupOptionLabel}>\n <GroupInline group={variant.group ?? ''} description={variant.model.description} showRatio />\n </span>\n </span>\n <span className={css.check}>\n {isCurrent ? <IconCheckOutlineRegular /> : null}\n </span>\n </button>\n )\n })}\n </>\n )}\n\n {pane === 'effort' && (\n <>\n {(reasoning?.efforts.length ?? 0) === 0\n ? <div className={css.empty}>{t('empty.efforts')}</div>\n : [\n ...reasoning?.defaultEffort === undefined\n ? [{ id: undefined as string | undefined, name: t('effort.providerDefault') }]\n : [],\n ...(reasoning?.efforts ?? []).map((level: ModelReasoningEffort) => ({ id: level.id as string | undefined, name: level.name })),\n ].map(level => (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={effectiveEffort === level.id}\n className={css.option + (effectiveEffort === level.id ? ' ' + css.selected : '')}\n key={level.id ?? 'provider-default'}\n disabled={busy}\n onClick={() => { chooseEffort(level.id) }}\n >\n <span className={css.optionCopy}>\n <span className={css.modelName}>{level.name}</span>\n </span>\n <span className={css.check}>\n {effectiveEffort === level.id ? <IconCheckOutlineRegular /> : null}\n </span>\n </button>\n ))}\n </>\n )}\n </MenuSurface>,\n document.body,\n )}\n {toast !== null && <div className={css.toast} role=\"status\">{toast}</div>}\n </div>\n )\n}\n\n/**\n * One group's inline rendering: badge capsules, its own name, and optionally the\n * ratio badge.\n * @param props - the group key, its hardcoded style, and whether to show the ratio.\n * @returns the inline group value.\n */\nfunction GroupInline(\n { group, description, showRatio = false }: { group: string; description?: string; showRatio?: boolean },\n) {\n const { badges, label } = parseGroupLabel(group)\n const ratio = showRatio ? ratioOf(description) : undefined\n return (\n <span className={css.groupInline}>\n {badges.map(badge => <GroupTag key={badge.text} text={badge.text} tone={badge.tone} />)}\n <span className={css.groupName}>{label}</span>\n {ratio !== undefined && <RatioChip ratio={ratio} />}\n </span>\n )\n}\n\n\n","/**\n * The NearToken settings page: connect the plugin to the site's account through\n * the site's own device-authorization flow, show whose account is connected, and\n * disconnect.\n *\n * The page never asks for a password. It shows the short code the site issued,\n * offers the site's confirmation page, and re-reads the Host while the Host polls\n * — the key and the provider insertion both happen on the Host side of a grant.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { IconChevronDownOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {\n NearTokenImageModelEntry, NearTokenImagesState, NearTokenModelEntry, NearTokenModelsState, NearTokenStatus,\n} from '../protocol.ts'\nimport type { NearTokenApi } from './api.ts'\nimport { parseGroupLabel } from './groups.ts'\nimport { GroupTag, RatioChip } from './group-tags.tsx'\nimport type { GroupKey } from './locales.ts'\nimport css from './NearTokenSection.module.css'\n\n/** How often the page re-reads the Host while an authorization is pending. */\nconst PENDING_REFRESH_MS = 1_500\n\n/** How long a burst of checkbox clicks waits before one save is written. */\nconst AUTOSAVE_DELAY_MS = 400\n\n/** What this section receives from its registration. */\nexport interface NearTokenSectionInjected {\n /** The Host's four routes. */\n api: NearTokenApi\n /** Bound translate for this plugin's dictionary. */\n t: (key: GroupKey, vars?: Record<string, string>) => string\n}\n\n/** Full component props: the section owner share plus this section's injected face. */\nexport type NearTokenSectionProps = PropsRuntime<'settings.section'> & NearTokenSectionInjected\n\n/**\n * Render the NearToken settings page.\n * @param props - the injected route carrier and translate, plus slot owner props.\n * @returns the section element tree.\n */\nexport function NearTokenSection({ api, t }: NearTokenSectionProps) {\n const [status, setStatus] = useState<NearTokenStatus | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | undefined>(undefined)\n\n /** Re-read the Host state and publish it. */\n const refresh = useCallback(async (): Promise<void> => {\n try {\n setStatus(await api.status())\n } catch (failure: unknown) {\n setError(t('account.failed', { message: messageOf(failure) }))\n }\n }, [api, t])\n\n // The page opens on whatever the Host already knows, so a reload neither\n // restarts a pending authorization nor forgets a finished one.\n useEffect(() => {\n void refresh()\n }, [refresh])\n\n const pendingCode = status?.pending?.userCode\n const waiting = pendingCode !== undefined\n // While the Host polls the site, the page polls the Host: the grant, the\n // refusal, and the expiry all arrive as a changed status.\n useEffect(() => {\n if (!waiting) return\n const timer = setInterval(() => { void refresh() }, PENDING_REFRESH_MS)\n return () => { clearInterval(timer) }\n }, [waiting, pendingCode, refresh])\n\n /** Run one Host call with the busy flag and the error channel wired. */\n const run = useCallback(async (action: () => Promise<void>): Promise<void> => {\n setBusy(true)\n setError(undefined)\n try {\n await action()\n } catch (failure: unknown) {\n setError(t('account.failed', { message: messageOf(failure) }))\n } finally {\n setBusy(false)\n }\n }, [t])\n\n const connect = (): void => {\n void run(async () => {\n const outcome = await api.begin()\n if (outcome.status === 'failed') setError(t('account.failed', { message: outcome.message }))\n await refresh()\n })\n }\n const cancel = (): void => {\n void run(async () => {\n await api.cancel()\n await refresh()\n })\n }\n const signOut = (): void => {\n void run(async () => {\n await api.signOut()\n await refresh()\n })\n }\n\n const account = status?.account\n const pending = status?.pending\n const minutes = pending === undefined ? 0 : Math.max(1, Math.round((pending.expiresAt - Date.now()) / 60_000))\n return (\n <div className={css.section}>\n <h2 className={css.title}>{t('account.title')}</h2>\n {status === undefined\n ? <p className={css.hint}>{t('account.loading')}</p>\n : status.configured\n ? (\n <section className={css.card}>\n <div className={css.cardHead}>\n <span className={css.name}>{account?.displayName ?? 'NearToken'}</span>\n {account === undefined ? null : <span className={css.handle}>@{account.username}</span>}\n <span className={`${css.badge} ${css.badgeOn}`}>{t('account.connected')}</span>\n </div>\n <dl className={css.facts}>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.group')}</dt>\n <dd className={css.factValue}>{account?.group ?? '—'}</dd>\n </div>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.balance')}</dt>\n <dd className={css.factValue}>{account?.balance ?? '—'}</dd>\n </div>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.used')}</dt>\n <dd className={css.factValue}>{account?.used ?? '—'}</dd>\n </div>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.token')}</dt>\n <dd className={css.factValue}>{status.tokenName}</dd>\n </div>\n </dl>\n <div className={css.actions}>\n <button type=\"button\" className={css.button} disabled={busy} onClick={signOut}>\n {busy ? t('account.signingOut') : t('account.signOut')}\n </button>\n </div>\n </section>\n )\n : (\n <section className={css.card}>\n <div className={css.cardHead}>\n <span className={css.name}>{t('account.title')}</span>\n <span className={css.badge}>{t('account.disconnected')}</span>\n </div>\n <p className={css.hint}>{t('account.site')}:{status.baseURL}</p>\n {pending === undefined\n ? (\n <div className={css.actions}>\n <button\n type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={busy} onClick={connect}\n >\n {busy ? t('account.connecting') : t('account.connect')}\n </button>\n </div>\n )\n : (\n <div className={css.form}>\n <p className={css.hint}>{t('account.waiting')}</p>\n <div className={css.codeRow}>\n <span className={css.label}>{t('account.userCode')}</span>\n <code className={css.code}>{pending.userCode}</code>\n </div>\n <div className={css.actions}>\n <button\n type=\"button\" className={`${css.button} ${css.buttonPrimary}`}\n onClick={() => { window.open(pending.verificationUriComplete, '_blank', 'noopener,noreferrer') }}\n >\n {t('account.openBrowser')}\n </button>\n <button type=\"button\" className={css.button} disabled={busy} onClick={cancel}>\n {busy ? t('account.cancelling') : t('account.cancel')}\n </button>\n </div>\n <p className={css.hint}>{t('account.expiresIn', { minutes: String(minutes) })}</p>\n </div>\n )}\n </section>\n )}\n {error === undefined ? null : <p className={css.notice}>{error}</p>}\n {status?.error === undefined ? null : <p className={css.notice}>{t('account.failed', { message: status.error })}</p>}\n {status?.configured === true ? <ModelWhitelist api={api} t={t} /> : null}\n {status?.configured === true ? <ImageGeneration api={api} t={t} /> : null}\n </div>\n )\n}\n\n/**\n * The model whitelist block: which of the site's models the provider keeps in\n * the model picker, edited through the same-origin models carrier.\n *\n * An empty stored list means \"no whitelist\", so the boxes start all checked —\n * that is what the picker currently shows. Saving an empty list is refused\n * here, because it would read as the same \"no whitelist\" state; \"Show all\"\n * (which saves exactly that) is the explicit way back to the whole catalog.\n * @param props - the injected route carrier and translate.\n * @returns the whitelist block.\n */\nfunction ModelWhitelist({ api, t }: NearTokenSectionInjected) {\n const [state, setState] = useState<NearTokenModelsState | undefined>(undefined)\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set())\n const [query, setQuery] = useState('')\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | undefined>(undefined)\n const [saved, setSaved] = useState(false)\n /** Why the last edit could not be applied; cleared by the next one. */\n const [notice, setNotice] = useState<string | undefined>(undefined)\n /** Whether the list itself is showing; the card opens collapsed. */\n const [open, setOpen] = useState(false)\n /** The queued save, while a burst of clicks is still settling. */\n const pending = useRef<number | undefined>(undefined)\n // The row whose group detail is showing, positioned in viewport coordinates:\n // the list scrolls, so the panel must escape its clip box rather than live in\n // the row's flow.\n const [tip, setTip] = useState<{ entry: NearTokenModelEntry; top: number; left: number } | undefined>(undefined)\n\n /** Publish one host answer: the boxes show the stored list, or all when none is stored. */\n const adopt = useCallback((next: NearTokenModelsState): void => {\n setState(next)\n setSelected(new Set(next.enabled.length === 0 ? next.models.map(entry => entry.model) : next.enabled))\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n adopt(await api.models())\n } catch (failure: unknown) {\n setError(t('whitelist.failed', { message: messageOf(failure) }))\n }\n }, [adopt, api, t])\n\n useEffect(() => { void load() }, [load])\n\n const models = state?.models ?? []\n const needle = query.trim().toLowerCase()\n const visible = needle === ''\n ? models\n : models.filter(entry => entry.model.toLowerCase().includes(needle))\n\n /** Cancel the pending save, if one is queued. */\n const cancelPending = useCallback((): void => {\n if (pending.current === undefined) return\n window.clearTimeout(pending.current)\n pending.current = undefined\n }, [])\n\n // A queued save must not outlive the page it belongs to.\n useEffect(() => cancelPending, [cancelPending])\n\n /**\n * Apply an edit to the boxes and queue one save.\n *\n * The list is stored as it is edited — there is no Save button to forget —\n * so the delay only coalesces a burst of clicks into one profile write.\n */\n const edit = (next: ReadonlySet<string>): void => {\n setSaved(false)\n setNotice(undefined)\n setSelected(next)\n cancelPending()\n // Catalog order, not click order: the stored list reads like the picker.\n const enabled = models.filter(entry => next.has(entry.model)).map(entry => entry.model)\n pending.current = window.setTimeout(() => {\n pending.current = undefined\n void persist(enabled)\n }, AUTOSAVE_DELAY_MS)\n }\n\n const toggle = (model: string): void => {\n const next = new Set(selected)\n if (next.has(model)) next.delete(model)\n else next.add(model)\n // An empty list means \"no whitelist\", i.e. show everything — the opposite\n // of what unchecking the last box asks for.\n if (next.size === 0) {\n setNotice(t('whitelist.keepOne'))\n return\n }\n edit(next)\n }\n /** Show one row's groups just below it, above it when there is no room. */\n const showTip = (entry: NearTokenModelEntry, anchor: HTMLElement): void => {\n const rect = anchor.getBoundingClientRect()\n const height = Math.min(240, 34 + entry.groups.length * 20)\n const below = rect.bottom + 6\n setTip({\n entry,\n top: below + height > window.innerHeight ? Math.max(12, rect.top - height - 6) : below,\n left: Math.max(12, Math.min(rect.left + 24, window.innerWidth - 292)),\n })\n }\n const checkVisible = (): void => {\n edit(new Set([...selected, ...visible.map(entry => entry.model)]))\n }\n /**\n * Empty the boxes the filter is showing.\n *\n * An emptied selection cannot be saved as such: an empty stored list means\n * \"no whitelist\", i.e. show every model, which is the opposite of the click.\n * So the boxes empty at once and the saved list is left alone; the next check\n * box saves the set the user actually wants, and \"Show all\" is the way back.\n */\n const uncheckVisible = (): void => {\n const hidden = new Set(visible.map(entry => entry.model))\n const next = new Set([...selected].filter(model => !hidden.has(model)))\n if (next.size > 0) {\n edit(next)\n return\n }\n cancelPending()\n setSaved(false)\n setSelected(next)\n setNotice(t('whitelist.cleared'))\n }\n\n /**\n * Write one list to the Host, which re-declares the provider route so the\n * model picker refetches without a page reload.\n * @param enabled - the model names to keep visible; empty restores everything.\n */\n const persist = useCallback(async (enabled: readonly string[]): Promise<void> => {\n setSaving(true)\n setError(undefined)\n try {\n await api.saveModels(enabled)\n setSaved(true)\n } catch (failure: unknown) {\n setError(t('whitelist.failed', { message: messageOf(failure) }))\n } finally {\n setSaving(false)\n }\n }, [api, t])\n\n /** Restore the whole catalog: nothing hidden, nothing stored. */\n const showEverything = (): void => {\n cancelPending()\n setSelected(new Set(models.map(entry => entry.model)))\n void persist([])\n }\n\n return (\n <section className={css.card}>\n <button\n type=\"button\"\n className={css.cardToggle}\n aria-expanded={open}\n aria-label={t(open ? 'card.collapse' : 'card.expand')}\n onClick={() => { setOpen((current) => !current) }}\n >\n <span className={css.name}>{t('whitelist.title')}</span>\n <span className={css.count}>\n <span className={css.countTotal}>{t('whitelist.count', { total: String(models.length) })}</span>\n <span className={css.countDot} aria-hidden=\"true\" />\n <span className={css.countPicked}>{t('whitelist.picked', { selected: String(selected.size) })}</span>\n </span>\n <IconChevronDownOutlineRegular\n className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron}\n size={14}\n />\n </button>\n {!open ? null : <>\n <p className={css.intro}>{t('whitelist.intro')}</p>\n {state === undefined\n ? (error === undefined ? <p className={css.hint}>{t('whitelist.loading')}</p> : null)\n : (\n <div className={css.form}>\n <input\n className={css.search}\n type=\"search\"\n value={query}\n placeholder={t('whitelist.search')}\n aria-label={t('whitelist.search')}\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <div className={css.toolbar}>\n <button type=\"button\" className={css.button} disabled={saving || visible.length === 0} onClick={checkVisible}>\n {t('whitelist.selectAll')}\n </button>\n <button type=\"button\" className={css.button} disabled={saving || visible.length === 0} onClick={uncheckVisible}>\n {t('whitelist.clear')}\n </button>\n <button type=\"button\" className={css.button} disabled={saving} onClick={showEverything}>\n {t('whitelist.reset')}\n </button>\n <span className={css.autosave} aria-live=\"polite\">\n {saving ? t('whitelist.saving') : saved ? t('whitelist.autoSaved') : ''}\n </span>\n </div>\n {models.length === 0\n ? <p className={css.hint}>{t('whitelist.empty')}</p>\n : (\n <div className={css.list} onScroll={() => { setTip(undefined) }}>\n {visible.length === 0\n ? <p className={css.hint}>{t('whitelist.noMatch')}</p>\n : visible.map(entry => (\n <label\n key={entry.model}\n className={css.row}\n onMouseEnter={(event) => { showTip(entry, event.currentTarget) }}\n onMouseLeave={() => { setTip(undefined) }}\n >\n <input\n type=\"checkbox\"\n checked={selected.has(entry.model)}\n onChange={() => { toggle(entry.model) }}\n />\n <span className={css.rowName}>{entry.model}</span>\n <span className={css.rowMeta}>\n {entry.groups.length === 0 ? null : (\n <span>{t('whitelist.groupsCount', { count: String(entry.groups.length) })}</span>\n )}\n {entry.minRatio === undefined ? null : (\n <>\n <span className={css.rowRatio}>{t('whitelist.minRatio')}</span>\n <RatioChip ratio={String(entry.minRatio) + 'x'} />\n </>\n )}\n </span>\n </label>\n ))}\n {tip === undefined ? null : (\n <div className={css.tip} style={{ top: tip.top, left: tip.left }} role=\"tooltip\">\n <span className={css.tipTitle}>{t('whitelist.groupsTitle')}</span>\n {tip.entry.groups.map(group => {\n const parsed = parseGroupLabel(group.group)\n return (\n <span key={group.group} className={css.tipRow}>\n <span className={css.tipGroup}>\n {parsed.badges.map(badge => (\n <GroupTag key={badge.text} text={badge.text} tone={badge.tone} />\n ))}\n <span className={css.tipGroupName}>{parsed.label}</span>\n </span>\n {group.ratio === undefined ? null : <RatioChip ratio={group.ratio} />}\n </span>\n )\n })}\n </div>\n )}\n </div>\n )}\n <p className={css.hint}>{t('whitelist.hint')}</p>\n {notice === undefined ? null : <p className={css.notice}>{notice}</p>}\n </div>\n )}\n {error === undefined ? null : <p className={css.notice}>{error}</p>}\n </>}\n </section>\n )\n}\n\n/**\n * The image-generation card: the `generate_image` tool's switch and, per picture\n * model, the group its requests route through.\n *\n * Unlike the whitelist this block saves on a button, not on every click: the two\n * members describe one setting, and a group choice made before the model is\n * checked would otherwise be written as nothing.\n * @param props - the injected route carrier and translate.\n * @returns the image-generation block.\n */\nfunction ImageGeneration({ api, t }: NearTokenSectionInjected) {\n const [state, setState] = useState<NearTokenImagesState | undefined>(undefined)\n const [enabled, setEnabled] = useState(false)\n const [selection, setSelection] = useState<Readonly<Record<string, string>>>({})\n const [busy, setBusy] = useState(false)\n const [dirty, setDirty] = useState(false)\n const [error, setError] = useState<string | undefined>(undefined)\n const [saved, setSaved] = useState(false)\n /** Whether the controls are showing; the card opens collapsed. */\n const [open, setOpen] = useState(false)\n\n /** Publish one host answer into the controls. */\n const adopt = useCallback((next: NearTokenImagesState): void => {\n setState(next)\n setEnabled(next.enabled)\n setSelection({ ...next.selection })\n setDirty(false)\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n adopt(await api.images())\n } catch (failure: unknown) {\n setError(t('images.failed', { message: messageOf(failure) }))\n }\n }, [adopt, api, t])\n\n useEffect(() => { void load() }, [load])\n\n const models = state?.models ?? []\n const enabledCount = Object.keys(selection).length\n\n /** Check or uncheck one model; the first group of a newly checked model is its route. */\n const toggle = (model: string, groups: NearTokenImageModelEntry['groups']): void => {\n setSaved(false)\n setDirty(true)\n setSelection((current) => {\n if (current[model] !== undefined) {\n const next = { ...current }\n delete next[model]\n return next\n }\n const first = groups[0]?.group\n return first === undefined ? current : { ...current, [model]: first }\n })\n }\n\n const chooseGroup = (model: string, group: string): void => {\n setSaved(false)\n setDirty(true)\n setSelection(current => ({ ...current, [model]: group }))\n }\n\n const save = async (): Promise<void> => {\n setBusy(true)\n setError(undefined)\n setSaved(false)\n try {\n await api.saveImages({ enabled, models: selection })\n setSaved(true)\n setDirty(false)\n } catch (failure: unknown) {\n setError(t('images.failed', { message: messageOf(failure) }))\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <section className={css.card}>\n <button\n type=\"button\"\n className={css.cardToggle}\n aria-expanded={open}\n aria-label={t(open ? 'card.collapse' : 'card.expand')}\n onClick={() => { setOpen((current) => !current) }}\n >\n <span className={css.name}>{t('images.title')}</span>\n <span className={css.count}>\n <span className={css.countTotal}>{t('images.count', { total: String(models.length) })}</span>\n <span className={css.countDot} aria-hidden=\"true\" />\n <span className={css.countPicked}>{t('images.picked', { selected: String(enabledCount) })}</span>\n </span>\n <IconChevronDownOutlineRegular\n className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron}\n size={14}\n />\n </button>\n {!open ? null : <>\n <p className={css.intro}>{t('images.intro')}</p>\n {state === undefined\n ? (error === undefined ? <p className={css.hint}>{t('images.loading')}</p> : null)\n : (\n <div className={css.form}>\n <label className={css.row}>\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(event) => { setSaved(false); setDirty(true); setEnabled(event.target.checked) }}\n />\n <span className={css.rowName}>{t('images.enable')}</span>\n </label>\n {models.length === 0\n ? <p className={css.hint}>{t('images.empty')}</p>\n : (\n <div className={css.list}>\n {models.map(entry => (\n <label key={entry.model} className={css.row}>\n <input\n type=\"checkbox\"\n checked={selection[entry.model] !== undefined}\n onChange={() => { toggle(entry.model, entry.groups) }}\n />\n <span className={css.rowName}>{entry.model}</span>\n <select\n className={css.select}\n aria-label={t('images.groupAria', { model: entry.model })}\n disabled={selection[entry.model] === undefined}\n value={selection[entry.model] ?? entry.groups[0]?.group ?? ''}\n onChange={(event) => { chooseGroup(entry.model, event.target.value) }}\n >\n {entry.groups.map(group => (\n <option key={group.group} value={group.group}>\n {group.group}{group.ratio === undefined ? '' : ` · ${group.ratio}`}\n </option>\n ))}\n </select>\n <span className={css.rowMeta}>\n {t(entry.channel === 'images' ? 'images.channel.images' : 'images.channel.chat')}\n </span>\n </label>\n ))}\n </div>\n )}\n <div className={css.toolbar}>\n <button type=\"button\" className={css.button} disabled={busy || !dirty} onClick={() => { void save() }}>\n {busy ? t('images.saving') : t('images.save')}\n </button>\n <span className={css.autosave} aria-live=\"polite\">\n {dirty ? t('images.dirty') : saved ? t('images.saved') : ''}\n </span>\n </div>\n <p className={css.hint}>{t('images.hint')}</p>\n {error === undefined ? null : <p className={css.notice}>{error}</p>}\n </div>\n )}\n </>}\n </section>\n )\n}\n\n/**\n * Render one thrown value as the message the page shows.\n * @param error - whatever the call threw.\n * @returns the error's message, or its text.\n */\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}","/**\n * `modelGroups` namespace dictionaries. Copy mirrors the built-in model seat so\n * the two readings of the same control stay identical; only the group keys are\n * new.\n */\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'provider.account': 'DeepSeek 账号',\n 'trigger.fallback': '请选择模型',\n 'trigger.loading': '正在加载模型…',\n 'trigger.selectAria': '请选择模型',\n 'trigger.aria': '选择模型,当前 {model}',\n 'trigger.ariaEffort': '选择模型,当前 {model},推理等级 {effort}',\n 'menu.aria': '模型、分组与推理等级',\n 'menu.model': '模型',\n 'menu.group': '分组',\n 'menu.effort': '推理等级',\n 'effort.providerDefault': 'Default',\n 'status.loading': '正在刷新模型列表…',\n 'error.action': '模型操作失败:{message}',\n 'error.sessionInUse': '当前会话已被占用,可能是其他正在运行的 DSH 导致的(如其他 dsh web、桌面端),请退出其他正在运行的 DSH 后重试。',\n 'action.reload': '重新加载',\n 'warning.groupLoad': '{name} 加载失败:{message}',\n 'search.placeholder': '搜索模型…',\n 'search.clear': '清除搜索',\n 'search.empty': '没有匹配的模型。',\n 'empty.models': '暂无可用模型',\n 'empty.groups': '当前模型没有其它分组。',\n 'empty.efforts': '当前模型未提供推理等级。',\n 'account.nav': 'NearToken',\n 'account.title': 'NearToken 账号',\n 'account.site': '站点',\n 'account.connect': '连接 NearToken',\n 'account.connecting': '正在发起…',\n 'account.waiting': '已发起授权,请在浏览器中确认。',\n 'account.userCode': '确认码',\n 'account.openBrowser': '打开浏览器确认',\n 'account.expiresIn': '本次确认 {minutes} 分钟内有效',\n 'account.cancel': '取消',\n 'account.cancelling': '正在取消…',\n 'account.connected': '已接入',\n 'account.disconnected': '未连接',\n 'account.group': '用户分组',\n 'account.balance': '剩余额度',\n 'account.used': '已用额度',\n 'account.token': 'API 令牌',\n 'account.signOut': '断开连接',\n 'account.signingOut': '正在断开…',\n 'account.loading': '正在读取连接状态…',\n 'account.failed': '操作失败:{message}',\n 'whitelist.title': '模型白名单',\n 'whitelist.intro': '勾选要出现在 DSH 模型选择器里的模型;未勾选的不会出现。白名单写在插件配置里,重启后依然生效。',\n 'whitelist.loading': '正在读取模型清单…',\n 'whitelist.failed': '模型白名单操作失败:{message}',\n 'whitelist.search': '搜索模型…',\n 'whitelist.noMatch': '没有匹配的模型。',\n 'whitelist.empty': '站点没有返回任何模型。',\n 'whitelist.count': '{total} 个模型',\n 'whitelist.picked': '已选 {selected}',\n 'card.expand': '展开',\n 'card.collapse': '收起',\n 'whitelist.groupsCount': '{count} 个分组',\n 'whitelist.minRatio': '最低',\n 'whitelist.groupsTitle': '可用分组',\n 'whitelist.selectAll': '全选',\n 'whitelist.clear': '清空',\n 'whitelist.reset': '全部显示',\n 'whitelist.saving': '正在保存…',\n 'whitelist.autoSaved': '已自动保存,模型选择器已刷新',\n 'whitelist.hint': '勾选即自动保存;没勾选的不会出现在模型选择器里。「全部显示」会清空白名单。',\n 'whitelist.keepOne': '至少要保留一个模型;想放开全部请点「全部显示」。',\n 'whitelist.cleared': '已清空勾选;勾选要显示的模型后会立即保存。',\n 'images.title': '图像生成',\n 'images.intro': '开启后模型可以调用 generate_image 工具生图。勾选要用的生图模型,并为每个模型指定走哪个分组(决定计费与可用性)。',\n 'images.enable': '启用 generate_image 工具',\n 'images.channel.images': 'images 接口',\n 'images.channel.chat': 'chat 接口',\n 'images.save': '保存',\n 'images.saving': '正在保存…',\n 'images.saved': '已保存,工具已按新设置生效',\n 'images.dirty': '有未保存的改动',\n 'images.hint': '生图一次约 20-60 秒;不勾选的模型模型看不到也调不到。改完记得点保存。',\n 'images.failed': '图像生成设置失败:{message}',\n 'images.empty': '站点没有返回任何生图模型。',\n 'images.loading': '正在读取生图模型…',\n 'images.count': '{total} 个生图模型',\n 'images.picked': '已启用 {selected}',\n 'images.groupAria': '{model} 使用的分组',\n} satisfies Record<string, string>\n\n/** The dictionary key union. */\nexport type GroupKey = keyof typeof zh\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en = {\n 'provider.account': 'DeepSeek Account',\n 'trigger.fallback': 'Select model',\n 'trigger.loading': 'Loading models…',\n 'trigger.selectAria': 'Select model',\n 'trigger.aria': 'Select model, current {model}',\n 'trigger.ariaEffort': 'Select model, current {model}, reasoning effort {effort}',\n 'menu.aria': 'Model, group, and reasoning effort',\n 'menu.model': 'Model',\n 'menu.group': 'Group',\n 'menu.effort': 'Effort',\n 'effort.providerDefault': 'Default',\n 'status.loading': 'Refreshing model list…',\n 'error.action': 'Model operation failed: {message}',\n 'error.sessionInUse': 'This session is already in use, possibly by another running DSH instance (such as dsh web or the desktop app). Quit other running DSH instances and try again.',\n 'action.reload': 'Reload',\n 'warning.groupLoad': '{name} failed to load: {message}',\n 'search.placeholder': 'Search models…',\n 'search.clear': 'Clear search',\n 'search.empty': 'No matching models.',\n 'empty.models': 'No models available.',\n 'empty.groups': 'This model offers no other group.',\n 'empty.efforts': 'This model provides no reasoning effort levels.',\n 'account.nav': 'NearToken',\n 'account.title': 'NearToken account',\n 'account.site': 'Site',\n 'account.connect': 'Connect NearToken',\n 'account.connecting': 'Starting…',\n 'account.waiting': 'Authorization started. Confirm it in your browser.',\n 'account.userCode': 'Code',\n 'account.openBrowser': 'Open browser to confirm',\n 'account.expiresIn': 'This confirmation is valid for {minutes} minutes',\n 'account.cancel': 'Cancel',\n 'account.cancelling': 'Cancelling…',\n 'account.connected': 'Connected',\n 'account.disconnected': 'Not connected',\n 'account.group': 'Group',\n 'account.balance': 'Balance',\n 'account.used': 'Used',\n 'account.token': 'API token',\n 'account.signOut': 'Disconnect',\n 'account.signingOut': 'Disconnecting…',\n 'account.loading': 'Reading connection state…',\n 'account.failed': 'Failed: {message}',\n 'whitelist.title': 'Model whitelist',\n 'whitelist.intro': 'Check the models that should appear in the DSH model picker; unchecked models stay hidden. The list is stored in the plugin configuration and survives a restart.',\n 'whitelist.loading': 'Reading the model list…',\n 'whitelist.failed': 'Model whitelist failed: {message}',\n 'whitelist.search': 'Search models…',\n 'whitelist.noMatch': 'No matching models.',\n 'whitelist.empty': 'The site returned no models.',\n 'whitelist.count': '{total} models',\n 'whitelist.picked': '{selected} selected',\n 'card.expand': 'Expand',\n 'card.collapse': 'Collapse',\n 'whitelist.groupsCount': '{count} groups',\n 'whitelist.minRatio': 'from',\n 'whitelist.groupsTitle': 'Available groups',\n 'whitelist.selectAll': 'Check all',\n 'whitelist.clear': 'Clear',\n 'whitelist.reset': 'Show all',\n 'whitelist.saving': 'Saving…',\n 'whitelist.autoSaved': 'Saved; the model picker has been refreshed',\n 'whitelist.hint': 'Every change saves itself; unchecked models stay out of the picker. \"Show all\" clears the whitelist.',\n 'whitelist.keepOne': 'Keep at least one model; use \"Show all\" to offer everything again.',\n 'whitelist.cleared': 'Boxes cleared; checking a model saves the list you want.',\n 'images.title': 'Image generation',\n 'images.intro': 'Once on, the model can call the generate_image tool. Check the picture models you want and pick the group each one bills to.',\n 'images.enable': 'Enable the generate_image tool',\n 'images.channel.images': 'images endpoint',\n 'images.channel.chat': 'chat endpoint',\n 'images.save': 'Save',\n 'images.saving': 'Saving…',\n 'images.saved': 'Saved; the tool now runs with these settings',\n 'images.dirty': 'Unsaved changes',\n 'images.hint': 'One picture takes 20-60 seconds; an unchecked model is invisible to the model and cannot be called. Remember to save.',\n 'images.failed': 'Image generation settings failed: {message}',\n 'images.empty': 'The site returned no picture models.',\n 'images.loading': 'Reading the picture models…',\n 'images.count': '{total} picture models',\n 'images.picked': '{selected} enabled',\n 'images.groupAria': 'Group used by {model}',\n} satisfies Record<GroupKey, string>\n","/**\n * NearToken provider plugin, browser half. Registers two surfaces: the NearToken\n * settings page (sign in, account facts, sign out) and a replacement for the\n * composer's model seat at priority -1, so the slot's lowest-priority\n * registration renders and the shipped picker stays in place without drawing.\n *\n * The seat shares the SAME per-session directory the built-in picker uses\n * (`ctx.modelDirectories`), so selection state, pending markers, the /model\n * popup, and Session persistence are unaffected: this plugin only changes what\n * the control looks like and adds the group level on top of it.\n *\n * The seat's declared child ('conversation.input.model.label') is owned by the\n * shipped registration, so this one declares none and renders catalog names\n * directly.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: the carrier types and the ctx.modelDirectories / ctx.remote merges.\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the ui-conversation SlotMap merge (the input.model seat).\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-session/client'\nimport type { ModelSelection } from '@deepseek-ai/dsh-api-session-controller/types'\n// Type-only: pulls the settings shell's SlotMap merge ('settings.section').\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { createNearTokenApi } from './api.ts'\nimport { ModelGroupSelect } from './ModelGroupSelect.tsx'\nimport { NearTokenSection, type NearTokenSectionInjected } from './NearTokenSection.tsx'\nimport { en, zh, type GroupKey } from './locales.ts'\nimport type { ModelGroupSelectInjected } from './slots.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The replacement model seat's copy. */\n modelGroups: GroupKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'modelGroups'\n\n/** Required services: the slot registry, locale, sessions, and the directory service. */\nexport const inject = ['slots', 'locale', 'sessions', 'remote', 'remote.session']\n\n/**\n * Client plugin body: register the dictionaries, add the NearToken settings page,\n * then shadow the composer model seat over the shared model directory.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-neartoken-provider: dictionaries')\n // One carrier for the page's whole life: the registration closure hands the\n // same object back on every render, so the section's load effect runs once.\n const api = createNearTokenApi()\n const t = ctx.locale.bind(NS) as NearTokenSectionInjected['t']\n // The near-token page sits between the account page (-10) and the general\n // page (0): both answer \"who am I signed in as\".\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'neartoken',\n order: -5,\n label: () => t('account.nav'),\n locale: NS,\n inject: (): NearTokenSectionInjected => ({ api, t }),\n }, NearTokenSection))\n\n ctx.inject(['slots', 'modelDirectories'], (scope: ClientContext) => {\n const models = scope.modelDirectories\n const sessions = scope.sessions\n scope.slots.inject('conversation.input.model', () => scope.slots.register({\n name: 'conversation.input.model',\n // Shipped seat registers at the default priority 0; lower renders.\n priority: -1,\n locale: NS,\n inject: (sessionId): ModelGroupSelectInjected => {\n const directory = models.directoryFor(sessionId)\n const available = sessions.subagentAddress(sessionId) === undefined\n return {\n available,\n directory: directory.store,\n load: () => {\n if (available) directory.load().catch(() => { /* surfaced on the store */ })\n },\n select: (selection: ModelSelection) => available\n ? directory.select(selection)\n : Promise.resolve(undefined),\n }\n },\n }, ModelGroupSelect))\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["css","useSyncExternalStore","useState","useRef","useId","useMemo","css","IconDataOutlineRegular","StateDot","IconChevronDownOutlineRegular","createPortal","MenuSurface","IconChevronRightOutlineRegular","Input","IconCloseFillRegular","MenuGroup","IconCheckOutlineRegular","useState","useCallback","css","useRef","IconChevronDownOutlineRegular"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/groups.ts","../src/client/group-tags.tsx","../src/client/ModelGroupSelect.tsx","../src/client/NearTokenSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/**\n * The wire vocabulary shared by the Host routes and the browser section: four\n * route paths and the JSON each answers. Both build faces import this file, so\n * a route rename cannot leave the browser calling a path the Host stopped\n * serving.\n *\n * Nothing here carries a password: the plugin never collects site credentials.\n * A connection is authorized by the site's own device-authorization flow, in\n * the user's browser — the Host only polls its result.\n *\n * @module\n */\n\n/** State read by the settings page before it draws, and while it waits. */\nexport const STATUS_PATH = '/neartoken/status'\n/** Start a device authorization (the Host then polls the site). */\nexport const AUTHORIZE_PATH = '/neartoken/authorize'\n/** Abandon the authorization in progress. */\nexport const CANCEL_PATH = '/neartoken/cancel'\n/** Forget the stored key and revoke it on the site. */\nexport const LOGOUT_PATH = '/neartoken/logout'\n/** Read the catalog beside the stored whitelist; POST a new whitelist. */\nexport const MODELS_PATH = '/neartoken/models'\n/** Read the picture models and the image-generation setting; POST one change to it. */\nexport const IMAGES_PATH = '/neartoken/images'\n\n/** One account's facts, as the settings card shows them. */\nexport interface NearTokenAccountSummary {\n /** The dashboard user name. */\n readonly username: string\n /** The display name when the site set one, otherwise the user name. */\n readonly displayName: string\n /** The user's own group, which is the default group a request routes by. */\n readonly group: string\n /** Remaining quota, formatted in the site's own display currency. */\n readonly balance: string\n /** Quota already spent, formatted the same way. */\n readonly used: string\n}\n\n/** One authorization the human must finish in their browser. */\nexport interface NearTokenPendingAuthorization {\n /** The short code the site shows on its confirmation page. */\n readonly userCode: string\n /** The page to open; carries no code of its own. */\n readonly verificationUri: string\n /** The same page with the code prefilled. */\n readonly verificationUriComplete: string\n /** When this attempt stops being valid, as epoch milliseconds. */\n readonly expiresAt: number\n}\n\n/** The `GET /neartoken/status` answer. */\nexport interface NearTokenStatus {\n /** Whether an API key is stored, i.e. whether the provider route is mounted. */\n readonly configured: boolean\n /** Site root the plugin talks to. */\n readonly baseURL: string\n /** Name of the token the site created for this plugin. */\n readonly tokenName: string\n /** Account facts, absent until a connection obtained them. */\n readonly account?: NearTokenAccountSummary\n /** The authorization in progress, while one is running. */\n readonly pending?: NearTokenPendingAuthorization\n /** Why the last attempt ended without a key, until the next one starts. */\n readonly error?: string\n}\n\n/** One group's offering of a model, as the whitelist list shows it. */\nexport interface NearTokenModelGroup {\n /** Group name exactly as the site publishes it, badge prefixes included. */\n readonly group: string\n /** The group's multiplier caption (`0.4x`), absent when the site published none. */\n readonly ratio?: string\n}\n\n/** One model the whitelist can show or hide. */\nexport interface NearTokenModelEntry {\n /** Bare model name: the whitelist key, and what the site's API takes. */\n readonly model: string\n /** Every group offering this model, in catalog order. */\n readonly groups: readonly NearTokenModelGroup[]\n /**\n * The cheapest multiplier among those groups, when the site published one.\n * The list shows it beside the group count; the per-group detail stays in\n * the hover panel.\n */\n readonly minRatio?: number\n}\n\n/** The `GET /neartoken/models` answer. */\nexport interface NearTokenModelsState {\n /** Every model the site offers, in catalog order. */\n readonly models: readonly NearTokenModelEntry[]\n /** The stored whitelist; empty means no whitelist, so every model is shown. */\n readonly enabled: readonly string[]\n}\n\n/** The `POST /neartoken/models` request body. */\nexport interface NearTokenModelsPatch {\n /** Model names to keep visible; an empty list restores the whole catalog. */\n readonly enabled: readonly string[]\n}\n\n/** The `POST /neartoken/authorize` answer. */\nexport type BeginAuthorizationOutcome =\n | { readonly status: 'pending'; readonly pending: NearTokenPendingAuthorization }\n | { readonly status: 'failed'; readonly message: string }\n\n/**\n * Which request shape one picture model speaks: the images endpoint, Gemini's\n * own generateContent, or a chat completion.\n */\nexport type NearTokenImageChannel = 'images' | 'genai' | 'chat'\n\n/** One picture model the image-generation setting can enable. */\nexport interface NearTokenImageModelEntry {\n /** Bare model name, as the site's API takes it. */\n readonly model: string\n /** The request shape this model answers. */\n readonly channel: NearTokenImageChannel\n /** Every group offering this model, in catalog order. */\n readonly groups: readonly NearTokenModelGroup[]\n /** The cheapest multiplier among those groups, when the site published one. */\n readonly minRatio?: number\n}\n\n/** The `GET /neartoken/images` answer. */\nexport interface NearTokenImagesState {\n /** Whether the `generate_image` tool is mounted for this profile. */\n readonly enabled: boolean\n /** Every picture model the site offers, in catalog order. */\n readonly models: readonly NearTokenImageModelEntry[]\n /** The enabled models and the group each one routes through; empty means the tool has no model to call. */\n readonly selection: Readonly<Record<string, string>>\n}\n\n/** The `POST /neartoken/images` request body. */\nexport interface NearTokenImagesPatch {\n /** Whether the tool should be mounted. */\n readonly enabled: boolean\n /** Bare model name to the group name it must route through. */\n readonly models: Readonly<Record<string, string>>\n}\n\n","/**\n * The browser half of the settings-page carrier: four same-origin calls to the\n * Host routes declared in ../protocol.ts.\n *\n * @module\n */\nimport {\n AUTHORIZE_PATH, CANCEL_PATH, IMAGES_PATH, LOGOUT_PATH, MODELS_PATH, STATUS_PATH,\n} from '../protocol.ts'\nimport type {\n BeginAuthorizationOutcome, NearTokenImagesPatch, NearTokenImagesState, NearTokenModelsPatch,\n NearTokenModelsState, NearTokenStatus,\n} from '../protocol.ts'\n\n/** The HTTP carrier, injectable so the section's behavior is testable. */\nexport type Fetch = (input: string, init?: RequestInit) => Promise<Response>\n\n/** What the section calls. */\nexport interface NearTokenApi {\n /** Read the key state, the account card, and any authorization in progress. */\n status(): Promise<NearTokenStatus>\n /** Start a device authorization; the Host polls the site from then on. */\n begin(): Promise<BeginAuthorizationOutcome>\n /** Abandon the authorization in progress. */\n cancel(): Promise<void>\n /** Forget the stored key and revoke it on the site. */\n signOut(): Promise<void>\n /** Read the site's model catalog beside the stored whitelist. */\n models(): Promise<NearTokenModelsState>\n /** Save a whitelist; an empty list shows every model again. */\n saveModels(enabled: readonly string[]): Promise<void>\n /** Read the picture models beside the stored image-generation setting. */\n images(): Promise<NearTokenImagesState>\n /** Save the image-generation setting: the tool's switch and one group per enabled model. */\n saveImages(patch: NearTokenImagesPatch): Promise<void>\n}\n\n/**\n * Read one JSON answer, turning an HTTP refusal into a thrown error.\n * @param response - the pending response.\n * @returns the parsed body.\n * @throws {Error} when the route answered a non-2xx status.\n */\nasync function jsonOf<T>(response: Response): Promise<T> {\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`)\n return await response.json() as T\n}\n\n/**\n * Build the carrier.\n * @param fetcher - HTTP carrier; defaults to the page's own fetch.\n * @returns the section's four calls.\n */\nexport function createNearTokenApi(fetcher: Fetch = (input, init) => fetch(input, init)): NearTokenApi {\n /** POST one empty JSON body and read its JSON answer. */\n const post = async <T>(path: string): Promise<T> => jsonOf<T>(await fetcher(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: '{}',\n }))\n return {\n async status() {\n return await jsonOf<NearTokenStatus>(await fetcher(STATUS_PATH, { headers: { accept: 'application/json' } }))\n },\n async begin() {\n return await post<BeginAuthorizationOutcome>(AUTHORIZE_PATH)\n },\n async cancel() {\n await post<unknown>(CANCEL_PATH)\n },\n async signOut() {\n await post<unknown>(LOGOUT_PATH)\n },\n async models() {\n return await jsonOf<NearTokenModelsState>(await fetcher(MODELS_PATH, { headers: { accept: 'application/json' } }))\n },\n async saveModels(enabled) {\n await jsonOf<unknown>(await fetcher(MODELS_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ enabled } satisfies NearTokenModelsPatch),\n }))\n },\n async images() {\n return await jsonOf<NearTokenImagesState>(await fetcher(IMAGES_PATH, { headers: { accept: 'application/json' } }))\n },\n async saveImages(patch) {\n const response = await fetcher(IMAGES_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n })\n if (!response.ok) {\n // The Host refuses a selection its catalog does not have; its message\n // names the reason, so the page shows that rather than a status code.\n const refusal = await response.json().catch(() => ({ message: `HTTP ${String(response.status)}` })) as { message?: string }\n throw new Error(refusal.message ?? `HTTP ${String(response.status)}`)\n }\n },\n }\n}\n","/**\n * The group dimension, folded out of catalog names.\n *\n * The NearToken provider (this plugin's own host half) expands the site's\n * `/api/pricing` into one catalog model per (group, model) pair, named\n * `\"<model> @ <group>\"`. The picker folds those back into one row per model\n * and turns the group into its own selectable level.\n *\n * Group names carry a badge convention on the site: a run of bracketed tags\n * before the group's own name (`[低价][反重力] Claude`). Those render as\n * colored capsules; the ratio comes through the catalog entry's description\n * (`分组倍率 0.4x`).\n *\n * Prototype scope: the provider allowlist and the name separator are\n * hardcoded. They become Config fields once the shape settles.\n */\n\n/** Providers whose catalog names carry a group suffix. */\nexport const GROUPED_PROVIDERS: readonly string[] = ['neartoken']\n\n/**\n * Capsule tone of one group badge. Tier tags keep a fixed hue so a long list\n * reads at a glance; any other tag takes a hue derived from its own text.\n */\nexport type BadgeTone =\n | 'rose' | 'emerald' | 'violet' | 'sky' | 'amber' | 'cyan'\n | 'fuchsia' | 'indigo' | 'teal' | 'lime' | 'orange' | 'pink'\n\n/** Tags that carry a tier meaning, with the hue the site gives each of them. */\nconst KNOWN_TAG_TONES: Record<string, BadgeTone> = {\n 满血: 'rose',\n 低价: 'emerald',\n 神秘: 'violet',\n 官Key: 'sky',\n 官key: 'sky',\n 可蒸馏: 'amber',\n 反重力: 'cyan',\n 生图: 'fuchsia',\n AIS: 'indigo',\n 稳定: 'teal',\n}\n\n/** Hues used by tags with no tier meaning, spread out so neighbours differ. */\nconst FALLBACK_TONES: readonly BadgeTone[] = [\n 'sky', 'amber', 'cyan', 'fuchsia', 'indigo', 'teal',\n 'lime', 'orange', 'pink', 'emerald', 'violet', 'rose',\n]\n\n/**\n * @param tag - one bracketed tag's text.\n * @returns a stable bucket for hue selection.\n */\nfunction hashTag(tag: string): number {\n let hash = 0\n for (const char of tag) hash = (hash * 31 + (char.codePointAt(0) ?? 0)) % 100_003\n return hash\n}\n\n/** One capsule rendered before the group's own name. */\nexport interface GroupBadge {\n readonly text: string\n readonly tone: BadgeTone\n}\n\n/** One group label split into its badge capsules and its own name. */\nexport interface ParsedGroup {\n readonly badges: readonly GroupBadge[]\n readonly label: string\n}\n\n/** Separator between a model name and its group suffix in the catalog name. */\nconst GROUP_SEPARATOR = ' @ '\n\n/**\n * Split one catalog name into the model's own name and the optional group.\n * @param name - the catalog model name, e.g. `glm-5.3 @ [低价][满血] 国模`.\n * @returns the model name without the suffix, plus the group when present.\n */\nexport function splitModelName(name: string): { model: string; group?: string } {\n const at = name.lastIndexOf(GROUP_SEPARATOR)\n if (at <= 0) return { model: name }\n const group = name.slice(at + GROUP_SEPARATOR.length).trim()\n const model = name.slice(0, at).trim()\n if (model === '' || group === '') return { model: name }\n return { model, group }\n}\n\n/**\n * Parse one group name's bracketed badge prefix.\n * @param name - the raw group name, e.g. `[低价][反重力] Claude`.\n * @returns the badge capsules (in order) and the group's own name.\n */\nexport function parseGroupLabel(name: string): ParsedGroup {\n const badges: GroupBadge[] = []\n let rest = name\n while (rest.startsWith('[')) {\n const end = rest.indexOf(']')\n if (end <= 1) break\n badges.push(badgeOf(rest.slice(1, end)))\n rest = rest.slice(end + 1)\n }\n return { badges, label: rest.trim() }\n}\n\n/**\n * @param text - one bracketed badge's text.\n * @returns the capsule tone that text renders in.\n */\nfunction badgeOf(text: string): GroupBadge {\n const known = KNOWN_TAG_TONES[text.trim()]\n if (known !== undefined) return { text, tone: known }\n return { text, tone: FALLBACK_TONES[hashTag(text) % FALLBACK_TONES.length] ?? 'sky' }\n}\n\n/**\n * The capitals each vendor writes its own family name with.\n *\n * The catalog publishes ids in lowercase only, so the display name has to put\n * them back: GPT and GLM are acronyms, DeepSeek is camel case, MiniMax and MiMo\n * keep an inner capital, and the `xhigh` effort is spelled `XHigh` everywhere\n * else in the product.\n */\nconst BRAND_SPELLING: Readonly<Record<string, string>> = {\n gpt: 'GPT',\n glm: 'GLM',\n deepseek: 'DeepSeek',\n minimax: 'MiniMax',\n mimo: 'MiMo',\n xhigh: 'XHigh',\n tts: 'TTS',\n}\n\n/**\n * Render a model name the way the pickers show it: hyphens become separators\n * and every word is capitalized, so `claude-opus-5-c` reads `Claude Opus 5 C`.\n * A vendor's own spelling wins over that rule (`gpt-5.5` reads `GPT 5.5`).\n *\n * The trailing `-c` stays a word on purpose: the site pairs every such model\n * with a twin that lacks the suffix (`claude-opus-5` beside `claude-opus-5-c`),\n * so dropping it from the display would leave two different models with the\n * same name. {@link isCodingUnfriendly} is what tells the reader which one it\n * is looking at.\n * @param model - a bare model name.\n * @returns the display name.\n */\nexport function displayModelName(model: string): string {\n return model\n .split('-')\n .filter(part => part.length > 0)\n .map(part => BRAND_SPELLING[part.toLowerCase()] ?? part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n}\n\n/**\n * Read the group ratio out of the host-provided catalog description.\n * @param description - the catalog entry's description (`分组倍率 0.4x`).\n * @returns the ratio caption, or undefined when the entry carries none.\n */\nexport function ratioOf(description: string | undefined): string | undefined {\n if (description === undefined) return undefined\n const match = description.match(/([\\d.]+)x/)\n return match === null ? undefined : `${match[1]}x`\n}\n\n/**\n * @param provider - a catalog provider id.\n * @returns whether this provider's model names carry group suffixes.\n */\nexport function isGroupedProvider(provider: string): boolean {\n return GROUPED_PROVIDERS.includes(provider)\n}\n\n/** One group's take on a model: the exact catalog entry that routes it. */\nexport interface ModelVariant<M> {\n readonly provider: string\n readonly group?: string\n readonly model: M\n}\n\n/** One model row: the display name plus every group that offers it. */\nexport interface ModelOption<M> {\n /** Fold key: the model name without its group suffix. */\n readonly key: string\n /** Displayed model name. */\n readonly label: string\n readonly variants: readonly ModelVariant<M>[]\n}\n\n/**\n * Fold one provider's models into rows, one per model name.\n *\n * A provider outside {@link GROUPED_PROVIDERS} keeps a 1:1 mapping (no suffix\n * parsing), so its rows behave exactly like the built-in picker's.\n * @param provider - the catalog provider id.\n * @param models - that provider's catalog models, in catalog order.\n * @returns one option per distinct model name, in first-seen order.\n */\nexport function foldModels<M extends { readonly id: string; readonly name: string }>(\n provider: string, models: readonly M[],\n): ModelOption<M>[] {\n const grouped = isGroupedProvider(provider)\n const byKey = new Map<string, { label: string; variants: ModelVariant<M>[] }>()\n for (const model of models) {\n const { model: label, group } = grouped ? splitModelName(model.name) : { model: model.name, group: undefined }\n const key = grouped ? label : model.id\n const row = byKey.get(key)\n const variant: ModelVariant<M> = { provider, model, ...group === undefined ? {} : { group } }\n if (row === undefined) byKey.set(key, { label, variants: [variant] })\n else row.variants.push(variant)\n }\n return [...byKey].map(([key, row]) => ({ key, label: row.label, variants: row.variants }))\n}\n\n/**\n * Pick the variant a model row should route to.\n * @param option - the row being chosen.\n * @param preferredProvider - the currently selected provider, kept when it offers the model.\n * @param preferredGroup - the currently selected group, kept when that provider offers it.\n * @returns the variant to submit.\n */\nexport function chooseVariant<M>(\n option: ModelOption<M>, preferredProvider: string | undefined, preferredGroup: string | undefined,\n): ModelVariant<M> | undefined {\n const local = option.variants.filter(variant => variant.provider === preferredProvider)\n const pool = local.length > 0 ? local : option.variants\n return pool.find(variant => variant.group === preferredGroup) ?? pool[0]\n}\n","/**\n * The site's group vocabulary, rendered the way the site renders it: a group\n * name's leading tags become colour-coded capsules, its multiplier becomes a\n * capsule that reads green below the base price, and a model the site marks\n * with a `-c` suffix carries a note.\n *\n * Both surfaces that show groups — the settings page's whitelist and the\n * composer's model seat — share these so one group never looks like two\n * different things in the same product.\n */\nimport type { BadgeTone } from './groups.ts'\nimport css from './group-tags.module.css'\n\n/** CSS Module class carrying each tone's hue, kept parallel to {@link BadgeTone}. */\nconst TONE_CLASS: Record<BadgeTone, string> = {\n rose: css.toneRose,\n emerald: css.toneEmerald,\n violet: css.toneViolet,\n sky: css.toneSky,\n amber: css.toneAmber,\n cyan: css.toneCyan,\n fuchsia: css.toneFuchsia,\n indigo: css.toneIndigo,\n teal: css.toneTeal,\n lime: css.toneLime,\n orange: css.toneOrange,\n pink: css.tonePink,\n}\n\n/** One bracketed group tag as a coloured capsule. */\nexport function GroupTag(props: { text: string; tone: BadgeTone }) {\n return <span className={css.tag + ' ' + TONE_CLASS[props.tone]}>{props.text}</span>\n}\n\n/**\n * One group's multiplier as a capsule.\n * @param props - the multiplier caption the catalog carried (`0.3x`).\n * @returns the capsule, toned by whether it beats the base price.\n */\nexport function RatioChip(props: { ratio: string }) {\n const value = Number.parseFloat(props.ratio)\n let tone = css.ratioBase\n if (Number.isFinite(value)) {\n if (value < 1) tone = css.ratioCheap\n else if (value > 1) tone = css.ratioPricey\n }\n return <span className={css.ratioChip + ' ' + tone}>{props.ratio}</span>\n}\n","/**\n * ModelGroupSelect: a drop-in replacement for the composer's model seat\n * ('conversation.input.model') that adds a THIRD level between the model and\n * the reasoning effort.\n *\n * The root menu is a row triple — Model / Group / Effort — where the Group row\n * appears only while the selected model comes from a provider whose catalog\n * names carry a group suffix (see groups.ts). The trigger states all three:\n * \"GLM 5.3 · Zhang · high\".\n *\n * Registered at priority -1, one step below the built-in seat, so the shipped\n * picker stays untouched and simply does not render.\n */\nimport { MenuGroup, MenuSurface, Input } from '@deepseek-ai/dsh-client-ui-primitives'\nimport {\n useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore,\n type CSSProperties, type KeyboardEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport type { ModelReasoningEffort, ModelSelection } from '@deepseek-ai/dsh-api-remotes/client'\nimport {\n IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconChevronRightOutlineRegular,\n IconCloseFillRegular, IconDataOutlineRegular, StateDot,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ModelGroupSelectInjected } from './slots.ts'\nimport type { ModelCatalogModel } from '@deepseek-ai/dsh-api-session-controller/types'\nimport {\n chooseVariant, displayModelName, foldModels, isGroupedProvider, parseGroupLabel, ratioOf,\n type ModelOption, type ModelVariant,\n} from './groups.ts'\nimport { GroupTag, RatioChip } from './group-tags.tsx'\nimport css from './ModelGroupSelect.module.css'\n\n/** Which pane the dropdown shows: the three-row root or one drilled-in list. */\ntype Pane = 'root' | 'model' | 'group' | 'effort'\n\n/** Unplaced portal card: hidden but laid out at a fixed origin so offset sizes are real. */\nconst MEASURE_STYLE: CSSProperties = { visibility: 'hidden', left: 0, top: 0 }\n\n/** One provider's folded rows. */\ninterface ProviderRows<M> {\n readonly id: string\n readonly name: string\n readonly options: readonly ModelOption<M>[]\n}\n\n/** Provider display order: account first, official next, then catalog order. */\nfunction providerRank(id: string): number {\n return id === 'deepseek-account' ? 0 : id === 'deepseek-official' ? 1 : 2\n}\n\n/**\n * Case-insensitive containment filter for the model search.\n * @param label - the row's display name.\n * @param query - the trimmed search text; empty keeps every row.\n * @returns whether the row stays visible.\n */\nfunction matchesQuery(label: string, query: string): boolean {\n return query === '' || label.toLowerCase().includes(query.toLowerCase())\n}\n\n/**\n * Keep the effort the user already picked when the new model offers it.\n * @param model - the catalog model the selection will route to.\n * @param previous - the effort in use before the switch.\n * @returns the effort to submit, or undefined for a model without reasoning.\n */\nfunction effortFor(model: ModelCatalogModel, previous: string | undefined): string | undefined {\n const reasoning = model.reasoning\n if (reasoning === undefined) return undefined\n if (previous !== undefined && reasoning.efforts.some(level => level.id === previous)) return previous\n return reasoning.defaultEffort\n}\n\n/**\n * Render the composer model seat with the group level.\n * @param props - owner share (locked) + injected directory face + the locale seat.\n * @returns the trigger and, while open, the three-level menu.\n */\nexport function ModelGroupSelect(\n { locked, available, directory, load, select, t }:\n ModelGroupSelectInjected & Pick<PropsRuntime<'conversation.input.model'>, 'locked'> & PropsLocale<'modelGroups'>,\n) {\n const state = useSyncExternalStore(\n fn => directory.subscribe(fn),\n () => directory.getSnapshot(),\n )\n const [open, setOpen] = useState(false)\n const [pane, setPane] = useState<Pane>('root')\n const [query, setQuery] = useState('')\n const [highlighted, setHighlighted] = useState(0)\n const [toast, setToast] = useState<string | null>(null)\n const rootRef = useRef<HTMLDivElement | null>(null)\n const triggerRef = useRef<HTMLButtonElement | null>(null)\n const menuRef = useRef<HTMLDivElement | null>(null)\n const searchRef = useRef<HTMLInputElement | null>(null)\n const [menuPos, setMenuPos] = useState<CSSProperties | null>(null)\n const id = useId()\n\n const accountName = t('provider.account')\n const providers = useMemo<ProviderRows<ModelCatalogModel>[]>(() => state.groups\n .map(group => ({\n id: group.id,\n name: group.id === 'deepseek-account' ? accountName : group.name,\n options: foldModels(group.id, group.models),\n }))\n .toSorted((left, right) => providerRank(left.id) - providerRank(right.id)), [state.groups, accountName])\n\n const current = state.current\n const located = useMemo(() => {\n for (const provider of providers) {\n for (const option of provider.options) {\n for (const variant of option.variants) {\n if (variant.provider === current?.provider && variant.model.id === current.model) {\n return { provider, option, variant }\n }\n }\n }\n }\n return undefined\n }, [providers, current])\n\n const reasoning = located?.variant.model.reasoning\n const effectiveEffort = current?.reasoningEffort ?? reasoning?.defaultEffort\n const effortLabel = located === undefined\n ? undefined\n : reasoning === undefined\n ? state.retainedEffort\n : effectiveEffort === undefined\n ? t('effort.providerDefault')\n : reasoning.efforts.find((level: ModelReasoningEffort) => level.id === effectiveEffort)?.name ?? effectiveEffort\n\n const currentGroup = located?.variant.group\n const groupChoices = useMemo(() => located === undefined || currentGroup === undefined\n ? []\n : located.option.variants.filter(variant => variant.provider === located.provider.id\n && variant.group !== undefined), [located, currentGroup])\n\n const filteredProviders = useMemo(() => {\n const trimmed = query.trim()\n return providers\n .map(provider => ({\n ...provider,\n options: provider.options.filter(option => matchesQuery(option.label, trimmed)),\n }))\n .filter(provider => provider.options.length > 0)\n }, [providers, query])\n\n const visibleOptions = useMemo(() => filteredProviders.flatMap(provider =>\n provider.options.map(option => ({ provider, option }))), [filteredProviders])\n const showSearch = providers.reduce((total, provider) => total + provider.options.length, 0) > 4\n const activeIndex = Math.min(highlighted, Math.max(0, visibleOptions.length - 1))\n const { pending } = state\n const busy = pending !== null\n const waiting = located === undefined && state.status === 'loading'\n\n const show = (): void => {\n triggerRef.current?.focus()\n setQuery('')\n setHighlighted(0)\n setPane(located === undefined ? 'model' : 'root')\n setOpen(true)\n load()\n }\n\n const close = (restoreFocus = false): void => {\n setOpen(false)\n setPane('root')\n if (restoreFocus) queueMicrotask(() => { triggerRef.current?.focus() })\n }\n\n useEffect(() => {\n if (!open) return\n const closeOutside = (event: MouseEvent): void => {\n if (rootRef.current?.contains(event.target as Node) === true) return\n if (menuRef.current?.contains(event.target as Node) === true) return\n setOpen(false)\n setPane('root')\n }\n document.addEventListener('mousedown', closeOutside)\n return () => { document.removeEventListener('mousedown', closeOutside) }\n }, [open])\n\n useLayoutEffect(() => {\n if (!available || !open) { setMenuPos(null); return }\n const place = (): void => {\n const rect = triggerRef.current?.getBoundingClientRect()\n if (rect === undefined) return\n const MARGIN = 12\n const width = menuRef.current?.offsetWidth ?? 0\n const height = menuRef.current?.offsetHeight ?? 0\n let x = rect.right - width\n let y = rect.top - 8 - height\n if (width > 0) x = Math.min(Math.max(x, MARGIN), window.innerWidth - width - MARGIN)\n if (height > 0) y = Math.min(Math.max(y, MARGIN), window.innerHeight - height - MARGIN)\n setMenuPos({ left: x, top: y })\n }\n place()\n window.addEventListener('scroll', place, true)\n window.addEventListener('resize', place)\n return () => {\n window.removeEventListener('scroll', place, true)\n window.removeEventListener('resize', place)\n }\n }, [available, open, pane, state, query])\n\n useLayoutEffect(() => {\n if (open && pane === 'model' && showSearch) searchRef.current?.focus()\n }, [open, pane, showSearch])\n\n if (!available) return null\n\n const settle = (result: Awaited<ReturnType<ModelGroupSelectInjected['select']>>): void => {\n if (result === undefined) return\n if (result.ok) {\n setOpen(false)\n setPane('root')\n return\n }\n const { error } = result\n setToast(error.code === 'session/writer-held'\n ? t('error.sessionInUse')\n : t('error.action', { message: `${error.code}: ${error.message}` }))\n }\n\n const submit = (selection: ModelSelection): void => {\n triggerRef.current?.focus()\n void select(selection).then(settle)\n }\n\n const chooseOption = (option: ModelOption<ModelCatalogModel>): void => {\n const variant = chooseVariant(option, current?.provider, currentGroup)\n if (variant === undefined) return\n if (current?.provider === variant.provider && current.model === variant.model.id) {\n close(true)\n return\n }\n const effort = effortFor(variant.model, effectiveEffort)\n submit({\n provider: variant.provider,\n model: variant.model.id,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n })\n }\n\n const chooseGroup = (variant: ModelVariant<ModelCatalogModel>): void => {\n if (current === null) return\n if (variant.model.id === current.model) {\n close(true)\n return\n }\n const effort = effortFor(variant.model, effectiveEffort)\n submit({\n provider: variant.provider,\n model: variant.model.id,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n })\n }\n\n const chooseEffort = (effort: string | undefined): void => {\n if (current === null) return\n if (effectiveEffort === effort) {\n close(true)\n return\n }\n submit({\n provider: current.provider,\n model: current.model,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n })\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {\n if (event.nativeEvent.isComposing) return\n if (event.key === 'Escape' && open) {\n event.preventDefault()\n if (pane !== 'root' && located !== undefined) setPane('root')\n else close(true)\n return\n }\n if (!open || pane !== 'root') return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n setPane('root')\n }\n }\n\n // Only this plugin's own provider gets the rewritten name: every other\n // provider's models are the application's own catalog entries, so the seat\n // must keep showing them exactly as the built-in seat does. The group is a\n // routing dimension and is never spelled out here.\n const ownProvider = located !== undefined && isGroupedProvider(located.provider.id)\n const modelLabel = waiting\n ? t('trigger.loading')\n : located === undefined\n ? t('trigger.fallback')\n : ownProvider\n ? `${displayModelName(located.option.label)} @ ${located.provider.name}`\n : located.option.label\n const triggerParts = [modelLabel, effortLabel].filter(part => part !== undefined && part !== '')\n const triggerLabel = triggerParts.join(' · ')\n const triggerAria = waiting\n ? t('trigger.loading')\n : located === undefined\n ? t('trigger.selectAria')\n : t('trigger.aria', { model: modelLabel })\n\n let optionIndex = 0\n\n return (\n <div ref={rootRef} className={css.root} onKeyDown={onKeyDown}>\n <button\n ref={triggerRef}\n type=\"button\"\n className={css.trigger}\n aria-label={triggerAria}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? `${id}-menu` : undefined}\n title={triggerLabel}\n aria-busy={busy}\n disabled={locked}\n onClick={() => { if (open) close(true); else show() }}\n >\n <IconDataOutlineRegular className={css.triggerIcon} size={16} />\n <span className={css.triggerLabel}>{modelLabel}</span>\n {effortLabel !== undefined && <span className={css.triggerEffort}>{effortLabel}</span>}\n {busy\n ? <StateDot state=\"ongoing\" />\n : <IconChevronDownOutlineRegular className={css.chevron} />}\n </button>\n\n {open && createPortal(\n <MenuSurface\n ref={menuRef}\n id={`${id}-menu`}\n className={css.menu}\n style={menuPos ?? MEASURE_STYLE}\n role={pane === 'model' || pane === 'group' ? 'group' : 'menu'}\n aria-label={t('menu.aria')}\n aria-busy={state.status === 'loading' || busy}\n >\n {pane === 'root' && (\n <>\n <button type=\"button\" role=\"menuitem\" className={css.cell} onClick={() => { setPane('model') }}>\n <span className={css.cellLabel}>{t('menu.model')}</span>\n <span className={css.cellValue}>{modelLabel}</span>\n <IconChevronRightOutlineRegular className={css.cellChevron} />\n </button>\n {currentGroup !== undefined && (\n <button\n type=\"button\"\n role=\"menuitem\"\n className={css.cell}\n disabled={groupChoices.length < 2}\n onClick={() => { setPane('group') }}\n >\n <span className={css.cellLabel}>{t('menu.group')}</span>\n <span className={css.cellValue}>\n <GroupInline group={currentGroup} description={located?.variant.model.description} showRatio />\n </span>\n {groupChoices.length > 1 && <IconChevronRightOutlineRegular className={css.cellChevron} />}\n </button>\n )}\n {reasoning !== undefined && (\n <button type=\"button\" role=\"menuitem\" className={css.cell} onClick={() => { setPane('effort') }}>\n <span className={css.cellLabel}>{t('menu.effort')}</span>\n <span className={css.cellValue}>{effortLabel}</span>\n <IconChevronRightOutlineRegular className={css.cellChevron} />\n </button>\n )}\n </>\n )}\n\n {pane === 'model' && (\n <>\n {showSearch && (\n <div className={css.searchRow}>\n <Input\n ref={searchRef}\n className={css.search}\n type=\"text\"\n role=\"searchbox\"\n aria-label={t('search.placeholder')}\n placeholder={t('search.placeholder')}\n value={query}\n readOnly={busy}\n onChange={(event) => { setQuery(event.target.value); setHighlighted(0) }}\n />\n {query !== '' && (\n <button\n type=\"button\"\n className={css.searchClear}\n aria-label={t('search.clear')}\n disabled={busy}\n onClick={() => { setQuery(''); searchRef.current?.focus() }}\n >\n <IconCloseFillRegular />\n </button>\n )}\n </div>\n )}\n {state.status === 'loading' && <div className={css.status}>{t('status.loading')}</div>}\n {state.error !== null && (\n <div className={css.error}>\n <span>{t('error.action', { message: state.error })}</span>\n <button type=\"button\" className={css.retry} onClick={load}>{t('action.reload')}</button>\n </div>\n )}\n {state.failures.map(failure => (\n <div className={css.warning} key={failure.id}>\n <span>{t('warning.groupLoad', { name: failure.id === 'deepseek-account' ? accountName : failure.name, message: failure.message })}</span>\n <button type=\"button\" className={css.retry} onClick={load}>{t('action.reload')}</button>\n </div>\n ))}\n <div className={css.groups} role=\"menu\" aria-label={t('menu.model')} hidden={filteredProviders.length === 0}>\n {filteredProviders.map(provider => (\n <MenuGroup key={provider.id} label={provider.name}>\n {provider.options.map(option => {\n const index = optionIndex++\n const isCurrent = located !== undefined && located.option.key === option.key\n && located.provider.id === provider.id\n const groups = option.variants.filter(variant => variant.group !== undefined)\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isCurrent}\n id={`${id}-model-${index}`}\n tabIndex={showSearch ? -1 : 0}\n onFocus={() => { setHighlighted(index) }}\n data-highlighted={index === activeIndex ? '' : undefined}\n className={css.option + ' ' + css.modelOption + ' ' + (index === activeIndex ? css.optionActive : '')}\n key={option.key}\n title={option.label}\n disabled={busy}\n onMouseMove={() => { setHighlighted(index) }}\n onClick={() => { chooseOption(option) }}\n >\n <span className={css.optionCopy}>\n <span className={css.modelName}>\n {isGroupedProvider(provider.id) ? displayModelName(option.label) : option.label}\n </span>\n\n </span>\n <span className={css.optionTrailing}>\n {groups.length > 1 && <span className={css.variantCount}>{groups.length}</span>}\n <span className={css.check}>\n {isCurrent ? <IconCheckOutlineRegular /> : null}\n </span>\n </span>\n </button>\n )\n })}\n </MenuGroup>\n ))}\n </div>\n {state.status === 'ready' && filteredProviders.length === 0 && (\n <div className={css.empty} role=\"status\">\n {t(providers.length === 0 ? 'empty.models' : 'search.empty')}\n </div>\n )}\n </>\n )}\n\n {pane === 'group' && (\n <>\n {groupChoices.length === 0\n ? <div className={css.empty}>{t('empty.groups')}</div>\n : groupChoices.map((variant) => {\n const isCurrent = variant.model.id === current?.model\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isCurrent}\n className={css.option + (isCurrent ? ' ' + css.selected : '')}\n key={variant.model.id}\n disabled={busy}\n onClick={() => { chooseGroup(variant) }}\n >\n <span className={css.optionCopy}>\n <span className={css.groupOptionLabel}>\n <GroupInline group={variant.group ?? ''} description={variant.model.description} showRatio />\n </span>\n </span>\n <span className={css.check}>\n {isCurrent ? <IconCheckOutlineRegular /> : null}\n </span>\n </button>\n )\n })}\n </>\n )}\n\n {pane === 'effort' && (\n <>\n {(reasoning?.efforts.length ?? 0) === 0\n ? <div className={css.empty}>{t('empty.efforts')}</div>\n : [\n ...reasoning?.defaultEffort === undefined\n ? [{ id: undefined as string | undefined, name: t('effort.providerDefault') }]\n : [],\n ...(reasoning?.efforts ?? []).map((level: ModelReasoningEffort) => ({ id: level.id as string | undefined, name: level.name })),\n ].map(level => (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={effectiveEffort === level.id}\n className={css.option + (effectiveEffort === level.id ? ' ' + css.selected : '')}\n key={level.id ?? 'provider-default'}\n disabled={busy}\n onClick={() => { chooseEffort(level.id) }}\n >\n <span className={css.optionCopy}>\n <span className={css.modelName}>{level.name}</span>\n </span>\n <span className={css.check}>\n {effectiveEffort === level.id ? <IconCheckOutlineRegular /> : null}\n </span>\n </button>\n ))}\n </>\n )}\n </MenuSurface>,\n document.body,\n )}\n {toast !== null && <div className={css.toast} role=\"status\">{toast}</div>}\n </div>\n )\n}\n\n/**\n * One group's inline rendering: badge capsules, its own name, and optionally the\n * ratio badge.\n * @param props - the group key, its hardcoded style, and whether to show the ratio.\n * @returns the inline group value.\n */\nfunction GroupInline(\n { group, description, showRatio = false }: { group: string; description?: string; showRatio?: boolean },\n) {\n const { badges, label } = parseGroupLabel(group)\n const ratio = showRatio ? ratioOf(description) : undefined\n return (\n <span className={css.groupInline}>\n {badges.map(badge => <GroupTag key={badge.text} text={badge.text} tone={badge.tone} />)}\n <span className={css.groupName}>{label}</span>\n {ratio !== undefined && <RatioChip ratio={ratio} />}\n </span>\n )\n}\n\n\n","/**\n * The NearToken settings page: connect the plugin to the site's account through\n * the site's own device-authorization flow, show whose account is connected, and\n * disconnect.\n *\n * The page never asks for a password. It shows the short code the site issued,\n * offers the site's confirmation page, and re-reads the Host while the Host polls\n * — the key and the provider insertion both happen on the Host side of a grant.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { IconChevronDownOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {\n NearTokenImageModelEntry, NearTokenImagesState, NearTokenModelEntry, NearTokenModelsState, NearTokenStatus,\n} from '../protocol.ts'\nimport type { NearTokenApi } from './api.ts'\nimport { parseGroupLabel } from './groups.ts'\nimport { GroupTag, RatioChip } from './group-tags.tsx'\nimport type { GroupKey } from './locales.ts'\nimport css from './NearTokenSection.module.css'\n\n/** How often the page re-reads the Host while an authorization is pending. */\nconst PENDING_REFRESH_MS = 1_500\n\n/** How long a burst of checkbox clicks waits before one save is written. */\nconst AUTOSAVE_DELAY_MS = 400\n\n/** What this section receives from its registration. */\nexport interface NearTokenSectionInjected {\n /** The Host's four routes. */\n api: NearTokenApi\n /** Bound translate for this plugin's dictionary. */\n t: (key: GroupKey, vars?: Record<string, string>) => string\n}\n\n/** Full component props: the section owner share plus this section's injected face. */\nexport type NearTokenSectionProps = PropsRuntime<'settings.section'> & NearTokenSectionInjected\n\n/**\n * Render the NearToken settings page.\n * @param props - the injected route carrier and translate, plus slot owner props.\n * @returns the section element tree.\n */\nexport function NearTokenSection({ api, t }: NearTokenSectionProps) {\n const [status, setStatus] = useState<NearTokenStatus | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | undefined>(undefined)\n\n /** Re-read the Host state and publish it. */\n const refresh = useCallback(async (): Promise<void> => {\n try {\n setStatus(await api.status())\n } catch (failure: unknown) {\n setError(t('account.failed', { message: messageOf(failure) }))\n }\n }, [api, t])\n\n // The page opens on whatever the Host already knows, so a reload neither\n // restarts a pending authorization nor forgets a finished one.\n useEffect(() => {\n void refresh()\n }, [refresh])\n\n const pendingCode = status?.pending?.userCode\n const waiting = pendingCode !== undefined\n // While the Host polls the site, the page polls the Host: the grant, the\n // refusal, and the expiry all arrive as a changed status.\n useEffect(() => {\n if (!waiting) return\n const timer = setInterval(() => { void refresh() }, PENDING_REFRESH_MS)\n return () => { clearInterval(timer) }\n }, [waiting, pendingCode, refresh])\n\n /** Run one Host call with the busy flag and the error channel wired. */\n const run = useCallback(async (action: () => Promise<void>): Promise<void> => {\n setBusy(true)\n setError(undefined)\n try {\n await action()\n } catch (failure: unknown) {\n setError(t('account.failed', { message: messageOf(failure) }))\n } finally {\n setBusy(false)\n }\n }, [t])\n\n const connect = (): void => {\n void run(async () => {\n const outcome = await api.begin()\n if (outcome.status === 'failed') setError(t('account.failed', { message: outcome.message }))\n await refresh()\n })\n }\n const cancel = (): void => {\n void run(async () => {\n await api.cancel()\n await refresh()\n })\n }\n const signOut = (): void => {\n void run(async () => {\n await api.signOut()\n await refresh()\n })\n }\n\n const account = status?.account\n const pending = status?.pending\n const minutes = pending === undefined ? 0 : Math.max(1, Math.round((pending.expiresAt - Date.now()) / 60_000))\n return (\n <div className={css.section}>\n <h2 className={css.title}>{t('account.title')}</h2>\n {status === undefined\n ? <p className={css.hint}>{t('account.loading')}</p>\n : status.configured\n ? (\n <section className={css.card}>\n <div className={css.cardHead}>\n <span className={css.name}>{account?.displayName ?? 'NearToken'}</span>\n {account === undefined ? null : <span className={css.handle}>@{account.username}</span>}\n <span className={`${css.badge} ${css.badgeOn}`}>{t('account.connected')}</span>\n </div>\n <dl className={css.facts}>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.group')}</dt>\n <dd className={css.factValue}>{account?.group ?? '—'}</dd>\n </div>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.balance')}</dt>\n <dd className={css.factValue}>{account?.balance ?? '—'}</dd>\n </div>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.used')}</dt>\n <dd className={css.factValue}>{account?.used ?? '—'}</dd>\n </div>\n <div className={css.fact}>\n <dt className={css.factLabel}>{t('account.token')}</dt>\n <dd className={css.factValue}>{status.tokenName}</dd>\n </div>\n </dl>\n <div className={css.actions}>\n <button type=\"button\" className={css.button} disabled={busy} onClick={signOut}>\n {busy ? t('account.signingOut') : t('account.signOut')}\n </button>\n </div>\n </section>\n )\n : (\n <section className={css.card}>\n <div className={css.cardHead}>\n <span className={css.name}>{t('account.title')}</span>\n <span className={css.badge}>{t('account.disconnected')}</span>\n </div>\n <p className={css.hint}>{t('account.site')}:{status.baseURL}</p>\n {pending === undefined\n ? (\n <div className={css.actions}>\n <button\n type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={busy} onClick={connect}\n >\n {busy ? t('account.connecting') : t('account.connect')}\n </button>\n </div>\n )\n : (\n <div className={css.form}>\n <p className={css.hint}>{t('account.waiting')}</p>\n <div className={css.codeRow}>\n <span className={css.label}>{t('account.userCode')}</span>\n <code className={css.code}>{pending.userCode}</code>\n </div>\n <div className={css.actions}>\n <button\n type=\"button\" className={`${css.button} ${css.buttonPrimary}`}\n onClick={() => { window.open(pending.verificationUriComplete, '_blank', 'noopener,noreferrer') }}\n >\n {t('account.openBrowser')}\n </button>\n <button type=\"button\" className={css.button} disabled={busy} onClick={cancel}>\n {busy ? t('account.cancelling') : t('account.cancel')}\n </button>\n </div>\n <p className={css.hint}>{t('account.expiresIn', { minutes: String(minutes) })}</p>\n </div>\n )}\n </section>\n )}\n {error === undefined ? null : <p className={css.notice}>{error}</p>}\n {status?.error === undefined ? null : <p className={css.notice}>{t('account.failed', { message: status.error })}</p>}\n {status?.configured === true ? <ModelWhitelist api={api} t={t} /> : null}\n {status?.configured === true ? <ImageGeneration api={api} t={t} /> : null}\n </div>\n )\n}\n\n/**\n * The model whitelist block: which of the site's models the provider keeps in\n * the model picker, edited through the same-origin models carrier.\n *\n * An empty stored list means \"no whitelist\", so the boxes start all checked —\n * that is what the picker currently shows. Saving an empty list is refused\n * here, because it would read as the same \"no whitelist\" state; \"Show all\"\n * (which saves exactly that) is the explicit way back to the whole catalog.\n * @param props - the injected route carrier and translate.\n * @returns the whitelist block.\n */\nfunction ModelWhitelist({ api, t }: NearTokenSectionInjected) {\n const [state, setState] = useState<NearTokenModelsState | undefined>(undefined)\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set())\n const [query, setQuery] = useState('')\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | undefined>(undefined)\n const [saved, setSaved] = useState(false)\n /** Why the last edit could not be applied; cleared by the next one. */\n const [notice, setNotice] = useState<string | undefined>(undefined)\n /** Whether the list itself is showing; the card opens collapsed. */\n const [open, setOpen] = useState(false)\n /** The queued save, while a burst of clicks is still settling. */\n const pending = useRef<number | undefined>(undefined)\n // The row whose group detail is showing, positioned in viewport coordinates:\n // the list scrolls, so the panel must escape its clip box rather than live in\n // the row's flow.\n const [tip, setTip] = useState<{ entry: NearTokenModelEntry; top: number; left: number } | undefined>(undefined)\n\n /** Publish one host answer: the boxes show the stored list, or all when none is stored. */\n const adopt = useCallback((next: NearTokenModelsState): void => {\n setState(next)\n setSelected(new Set(next.enabled.length === 0 ? next.models.map(entry => entry.model) : next.enabled))\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n adopt(await api.models())\n } catch (failure: unknown) {\n setError(t('whitelist.failed', { message: messageOf(failure) }))\n }\n }, [adopt, api, t])\n\n useEffect(() => { void load() }, [load])\n\n const models = state?.models ?? []\n const needle = query.trim().toLowerCase()\n const visible = needle === ''\n ? models\n : models.filter(entry => entry.model.toLowerCase().includes(needle))\n\n /** Cancel the pending save, if one is queued. */\n const cancelPending = useCallback((): void => {\n if (pending.current === undefined) return\n window.clearTimeout(pending.current)\n pending.current = undefined\n }, [])\n\n // A queued save must not outlive the page it belongs to.\n useEffect(() => cancelPending, [cancelPending])\n\n /**\n * Apply an edit to the boxes and queue one save.\n *\n * The list is stored as it is edited — there is no Save button to forget —\n * so the delay only coalesces a burst of clicks into one profile write.\n */\n const edit = (next: ReadonlySet<string>): void => {\n setSaved(false)\n setNotice(undefined)\n setSelected(next)\n cancelPending()\n // Catalog order, not click order: the stored list reads like the picker.\n const enabled = models.filter(entry => next.has(entry.model)).map(entry => entry.model)\n pending.current = window.setTimeout(() => {\n pending.current = undefined\n void persist(enabled)\n }, AUTOSAVE_DELAY_MS)\n }\n\n const toggle = (model: string): void => {\n const next = new Set(selected)\n if (next.has(model)) next.delete(model)\n else next.add(model)\n // An empty list means \"no whitelist\", i.e. show everything — the opposite\n // of what unchecking the last box asks for.\n if (next.size === 0) {\n setNotice(t('whitelist.keepOne'))\n return\n }\n edit(next)\n }\n /** Show one row's groups just below it, above it when there is no room. */\n const showTip = (entry: NearTokenModelEntry, anchor: HTMLElement): void => {\n const rect = anchor.getBoundingClientRect()\n const height = Math.min(240, 34 + entry.groups.length * 20)\n const below = rect.bottom + 6\n setTip({\n entry,\n top: below + height > window.innerHeight ? Math.max(12, rect.top - height - 6) : below,\n left: Math.max(12, Math.min(rect.left + 24, window.innerWidth - 292)),\n })\n }\n const checkVisible = (): void => {\n edit(new Set([...selected, ...visible.map(entry => entry.model)]))\n }\n /**\n * Empty the boxes the filter is showing.\n *\n * An emptied selection cannot be saved as such: an empty stored list means\n * \"no whitelist\", i.e. show every model, which is the opposite of the click.\n * So the boxes empty at once and the saved list is left alone; the next check\n * box saves the set the user actually wants, and \"Show all\" is the way back.\n */\n const uncheckVisible = (): void => {\n const hidden = new Set(visible.map(entry => entry.model))\n const next = new Set([...selected].filter(model => !hidden.has(model)))\n if (next.size > 0) {\n edit(next)\n return\n }\n cancelPending()\n setSaved(false)\n setSelected(next)\n setNotice(t('whitelist.cleared'))\n }\n\n /**\n * Write one list to the Host, which re-declares the provider route so the\n * model picker refetches without a page reload.\n * @param enabled - the model names to keep visible; empty restores everything.\n */\n const persist = useCallback(async (enabled: readonly string[]): Promise<void> => {\n setSaving(true)\n setError(undefined)\n try {\n await api.saveModels(enabled)\n setSaved(true)\n } catch (failure: unknown) {\n setError(t('whitelist.failed', { message: messageOf(failure) }))\n } finally {\n setSaving(false)\n }\n }, [api, t])\n\n /** Restore the whole catalog: nothing hidden, nothing stored. */\n const showEverything = (): void => {\n cancelPending()\n setSelected(new Set(models.map(entry => entry.model)))\n void persist([])\n }\n\n return (\n <section className={css.card}>\n <button\n type=\"button\"\n className={css.cardToggle}\n aria-expanded={open}\n aria-label={t(open ? 'card.collapse' : 'card.expand')}\n onClick={() => { setOpen((current) => !current) }}\n >\n <span className={css.name}>{t('whitelist.title')}</span>\n <span className={css.count}>\n <span className={css.countTotal}>{t('whitelist.count', { total: String(models.length) })}</span>\n <span className={css.countDot} aria-hidden=\"true\" />\n <span className={css.countPicked}>{t('whitelist.picked', { selected: String(selected.size) })}</span>\n </span>\n <IconChevronDownOutlineRegular\n className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron}\n size={14}\n />\n </button>\n {!open ? null : <>\n <p className={css.intro}>{t('whitelist.intro')}</p>\n {state === undefined\n ? (error === undefined ? <p className={css.hint}>{t('whitelist.loading')}</p> : null)\n : (\n <div className={css.form}>\n <input\n className={css.search}\n type=\"search\"\n value={query}\n placeholder={t('whitelist.search')}\n aria-label={t('whitelist.search')}\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <div className={css.toolbar}>\n <button type=\"button\" className={css.button} disabled={saving || visible.length === 0} onClick={checkVisible}>\n {t('whitelist.selectAll')}\n </button>\n <button type=\"button\" className={css.button} disabled={saving || visible.length === 0} onClick={uncheckVisible}>\n {t('whitelist.clear')}\n </button>\n <button type=\"button\" className={css.button} disabled={saving} onClick={showEverything}>\n {t('whitelist.reset')}\n </button>\n <span className={css.autosave} aria-live=\"polite\">\n {saving ? t('whitelist.saving') : saved ? t('whitelist.autoSaved') : ''}\n </span>\n </div>\n {models.length === 0\n ? <p className={css.hint}>{t('whitelist.empty')}</p>\n : (\n <div className={css.list} onScroll={() => { setTip(undefined) }}>\n {visible.length === 0\n ? <p className={css.hint}>{t('whitelist.noMatch')}</p>\n : visible.map(entry => (\n <label\n key={entry.model}\n className={css.row}\n onMouseEnter={(event) => { showTip(entry, event.currentTarget) }}\n onMouseLeave={() => { setTip(undefined) }}\n >\n <input\n type=\"checkbox\"\n checked={selected.has(entry.model)}\n onChange={() => { toggle(entry.model) }}\n />\n <span className={css.rowName}>{entry.model}</span>\n <span className={css.rowMeta}>\n {entry.groups.length === 0 ? null : (\n <span>{t('whitelist.groupsCount', { count: String(entry.groups.length) })}</span>\n )}\n {entry.minRatio === undefined ? null : (\n <>\n <span className={css.rowRatio}>{t('whitelist.minRatio')}</span>\n <RatioChip ratio={String(entry.minRatio) + 'x'} />\n </>\n )}\n </span>\n </label>\n ))}\n {tip === undefined ? null : (\n <div className={css.tip} style={{ top: tip.top, left: tip.left }} role=\"tooltip\">\n <span className={css.tipTitle}>{t('whitelist.groupsTitle')}</span>\n {tip.entry.groups.map(group => {\n const parsed = parseGroupLabel(group.group)\n return (\n <span key={group.group} className={css.tipRow}>\n <span className={css.tipGroup}>\n {parsed.badges.map(badge => (\n <GroupTag key={badge.text} text={badge.text} tone={badge.tone} />\n ))}\n <span className={css.tipGroupName}>{parsed.label}</span>\n </span>\n {group.ratio === undefined ? null : <RatioChip ratio={group.ratio} />}\n </span>\n )\n })}\n </div>\n )}\n </div>\n )}\n <p className={css.hint}>{t('whitelist.hint')}</p>\n {notice === undefined ? null : <p className={css.notice}>{notice}</p>}\n </div>\n )}\n {error === undefined ? null : <p className={css.notice}>{error}</p>}\n </>}\n </section>\n )\n}\n\n/**\n * The image-generation card: the `generate_image` tool's switch and, per picture\n * model, the group its requests route through.\n *\n * Unlike the whitelist this block saves on a button, not on every click: the two\n * members describe one setting, and a group choice made before the model is\n * checked would otherwise be written as nothing.\n * @param props - the injected route carrier and translate.\n * @returns the image-generation block.\n */\nfunction ImageGeneration({ api, t }: NearTokenSectionInjected) {\n const [state, setState] = useState<NearTokenImagesState | undefined>(undefined)\n const [enabled, setEnabled] = useState(false)\n const [selection, setSelection] = useState<Readonly<Record<string, string>>>({})\n const [busy, setBusy] = useState(false)\n const [dirty, setDirty] = useState(false)\n const [error, setError] = useState<string | undefined>(undefined)\n const [saved, setSaved] = useState(false)\n /** Whether the controls are showing; the card opens collapsed. */\n const [open, setOpen] = useState(false)\n\n /** Publish one host answer into the controls. */\n const adopt = useCallback((next: NearTokenImagesState): void => {\n setState(next)\n setEnabled(next.enabled)\n setSelection({ ...next.selection })\n setDirty(false)\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n adopt(await api.images())\n } catch (failure: unknown) {\n setError(t('images.failed', { message: messageOf(failure) }))\n }\n }, [adopt, api, t])\n\n useEffect(() => { void load() }, [load])\n\n const models = state?.models ?? []\n const enabledCount = Object.keys(selection).length\n\n /** Check or uncheck one model; the first group of a newly checked model is its route. */\n const toggle = (model: string, groups: NearTokenImageModelEntry['groups']): void => {\n setSaved(false)\n setDirty(true)\n setSelection((current) => {\n if (current[model] !== undefined) {\n const next = { ...current }\n delete next[model]\n return next\n }\n const first = groups[0]?.group\n return first === undefined ? current : { ...current, [model]: first }\n })\n }\n\n const chooseGroup = (model: string, group: string): void => {\n setSaved(false)\n setDirty(true)\n setSelection(current => ({ ...current, [model]: group }))\n }\n\n const save = async (): Promise<void> => {\n setBusy(true)\n setError(undefined)\n setSaved(false)\n try {\n await api.saveImages({ enabled, models: selection })\n setSaved(true)\n setDirty(false)\n } catch (failure: unknown) {\n setError(t('images.failed', { message: messageOf(failure) }))\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <section className={css.card}>\n <button\n type=\"button\"\n className={css.cardToggle}\n aria-expanded={open}\n aria-label={t(open ? 'card.collapse' : 'card.expand')}\n onClick={() => { setOpen((current) => !current) }}\n >\n <span className={css.name}>{t('images.title')}</span>\n <span className={css.count}>\n <span className={css.countTotal}>{t('images.count', { total: String(models.length) })}</span>\n <span className={css.countDot} aria-hidden=\"true\" />\n <span className={css.countPicked}>{t('images.picked', { selected: String(enabledCount) })}</span>\n </span>\n <IconChevronDownOutlineRegular\n className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron}\n size={14}\n />\n </button>\n {!open ? null : <>\n <p className={css.intro}>{t('images.intro')}</p>\n {state === undefined\n ? (error === undefined ? <p className={css.hint}>{t('images.loading')}</p> : null)\n : (\n <div className={css.form}>\n <label className={css.row}>\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(event) => { setSaved(false); setDirty(true); setEnabled(event.target.checked) }}\n />\n <span className={css.rowName}>{t('images.enable')}</span>\n </label>\n {models.length === 0\n ? <p className={css.hint}>{t('images.empty')}</p>\n : (\n <div className={css.list}>\n {models.map(entry => (\n <label key={entry.model} className={css.row}>\n <input\n type=\"checkbox\"\n checked={selection[entry.model] !== undefined}\n onChange={() => { toggle(entry.model, entry.groups) }}\n />\n <span className={css.rowName}>{entry.model}</span>\n <select\n className={css.select}\n aria-label={t('images.groupAria', { model: entry.model })}\n disabled={selection[entry.model] === undefined}\n value={selection[entry.model] ?? entry.groups[0]?.group ?? ''}\n onChange={(event) => { chooseGroup(entry.model, event.target.value) }}\n >\n {entry.groups.map(group => (\n <option key={group.group} value={group.group}>\n {group.group}{group.ratio === undefined ? '' : ` · ${group.ratio}`}\n </option>\n ))}\n </select>\n <span className={css.rowMeta}>\n {t(entry.channel === 'images'\n ? 'images.channel.images'\n : entry.channel === 'genai' ? 'images.channel.genai' : 'images.channel.chat')}\n </span>\n </label>\n ))}\n </div>\n )}\n <div className={css.toolbar}>\n <button type=\"button\" className={css.button} disabled={busy || !dirty} onClick={() => { void save() }}>\n {busy ? t('images.saving') : t('images.save')}\n </button>\n <span className={css.autosave} aria-live=\"polite\">\n {dirty ? t('images.dirty') : saved ? t('images.saved') : ''}\n </span>\n </div>\n <p className={css.hint}>{t('images.hint')}</p>\n {error === undefined ? null : <p className={css.notice}>{error}</p>}\n </div>\n )}\n </>}\n </section>\n )\n}\n\n/**\n * Render one thrown value as the message the page shows.\n * @param error - whatever the call threw.\n * @returns the error's message, or its text.\n */\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}","/**\n * `modelGroups` namespace dictionaries. Copy mirrors the built-in model seat so\n * the two readings of the same control stay identical; only the group keys are\n * new.\n */\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'provider.account': 'DeepSeek 账号',\n 'trigger.fallback': '请选择模型',\n 'trigger.loading': '正在加载模型…',\n 'trigger.selectAria': '请选择模型',\n 'trigger.aria': '选择模型,当前 {model}',\n 'trigger.ariaEffort': '选择模型,当前 {model},推理等级 {effort}',\n 'menu.aria': '模型、分组与推理等级',\n 'menu.model': '模型',\n 'menu.group': '分组',\n 'menu.effort': '推理等级',\n 'effort.providerDefault': 'Default',\n 'status.loading': '正在刷新模型列表…',\n 'error.action': '模型操作失败:{message}',\n 'error.sessionInUse': '当前会话已被占用,可能是其他正在运行的 DSH 导致的(如其他 dsh web、桌面端),请退出其他正在运行的 DSH 后重试。',\n 'action.reload': '重新加载',\n 'warning.groupLoad': '{name} 加载失败:{message}',\n 'search.placeholder': '搜索模型…',\n 'search.clear': '清除搜索',\n 'search.empty': '没有匹配的模型。',\n 'empty.models': '暂无可用模型',\n 'empty.groups': '当前模型没有其它分组。',\n 'empty.efforts': '当前模型未提供推理等级。',\n 'account.nav': 'NearToken',\n 'account.title': 'NearToken 账号',\n 'account.site': '站点',\n 'account.connect': '连接 NearToken',\n 'account.connecting': '正在发起…',\n 'account.waiting': '已发起授权,请在浏览器中确认。',\n 'account.userCode': '确认码',\n 'account.openBrowser': '打开浏览器确认',\n 'account.expiresIn': '本次确认 {minutes} 分钟内有效',\n 'account.cancel': '取消',\n 'account.cancelling': '正在取消…',\n 'account.connected': '已接入',\n 'account.disconnected': '未连接',\n 'account.group': '用户分组',\n 'account.balance': '剩余额度',\n 'account.used': '已用额度',\n 'account.token': 'API 令牌',\n 'account.signOut': '断开连接',\n 'account.signingOut': '正在断开…',\n 'account.loading': '正在读取连接状态…',\n 'account.failed': '操作失败:{message}',\n 'whitelist.title': '模型白名单',\n 'whitelist.intro': '勾选要出现在 DSH 模型选择器里的模型;未勾选的不会出现。白名单写在插件配置里,重启后依然生效。',\n 'whitelist.loading': '正在读取模型清单…',\n 'whitelist.failed': '模型白名单操作失败:{message}',\n 'whitelist.search': '搜索模型…',\n 'whitelist.noMatch': '没有匹配的模型。',\n 'whitelist.empty': '站点没有返回任何模型。',\n 'whitelist.count': '{total} 个模型',\n 'whitelist.picked': '已选 {selected}',\n 'card.expand': '展开',\n 'card.collapse': '收起',\n 'whitelist.groupsCount': '{count} 个分组',\n 'whitelist.minRatio': '最低',\n 'whitelist.groupsTitle': '可用分组',\n 'whitelist.selectAll': '全选',\n 'whitelist.clear': '清空',\n 'whitelist.reset': '全部显示',\n 'whitelist.saving': '正在保存…',\n 'whitelist.autoSaved': '已自动保存,模型选择器已刷新',\n 'whitelist.hint': '勾选即自动保存;没勾选的不会出现在模型选择器里。「全部显示」会清空白名单。',\n 'whitelist.keepOne': '至少要保留一个模型;想放开全部请点「全部显示」。',\n 'whitelist.cleared': '已清空勾选;勾选要显示的模型后会立即保存。',\n 'images.title': '图像生成',\n 'images.intro': '开启后模型可以调用 generate_image 工具生图。勾选要用的生图模型,并为每个模型指定走哪个分组(决定计费与可用性)。',\n 'images.enable': '启用 generate_image 工具',\n 'images.channel.images': 'images 接口',\n 'images.channel.genai': 'gemini 接口',\n 'images.channel.chat': 'chat 接口',\n 'images.save': '保存',\n 'images.saving': '正在保存…',\n 'images.saved': '已保存,工具已按新设置生效',\n 'images.dirty': '有未保存的改动',\n 'images.hint': '生图一次约 20-60 秒;不勾选的模型模型看不到也调不到。改完记得点保存。',\n 'images.failed': '图像生成设置失败:{message}',\n 'images.empty': '站点没有返回任何生图模型。',\n 'images.loading': '正在读取生图模型…',\n 'images.count': '{total} 个生图模型',\n 'images.picked': '已启用 {selected}',\n 'images.groupAria': '{model} 使用的分组',\n} satisfies Record<string, string>\n\n/** The dictionary key union. */\nexport type GroupKey = keyof typeof zh\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en = {\n 'provider.account': 'DeepSeek Account',\n 'trigger.fallback': 'Select model',\n 'trigger.loading': 'Loading models…',\n 'trigger.selectAria': 'Select model',\n 'trigger.aria': 'Select model, current {model}',\n 'trigger.ariaEffort': 'Select model, current {model}, reasoning effort {effort}',\n 'menu.aria': 'Model, group, and reasoning effort',\n 'menu.model': 'Model',\n 'menu.group': 'Group',\n 'menu.effort': 'Effort',\n 'effort.providerDefault': 'Default',\n 'status.loading': 'Refreshing model list…',\n 'error.action': 'Model operation failed: {message}',\n 'error.sessionInUse': 'This session is already in use, possibly by another running DSH instance (such as dsh web or the desktop app). Quit other running DSH instances and try again.',\n 'action.reload': 'Reload',\n 'warning.groupLoad': '{name} failed to load: {message}',\n 'search.placeholder': 'Search models…',\n 'search.clear': 'Clear search',\n 'search.empty': 'No matching models.',\n 'empty.models': 'No models available.',\n 'empty.groups': 'This model offers no other group.',\n 'empty.efforts': 'This model provides no reasoning effort levels.',\n 'account.nav': 'NearToken',\n 'account.title': 'NearToken account',\n 'account.site': 'Site',\n 'account.connect': 'Connect NearToken',\n 'account.connecting': 'Starting…',\n 'account.waiting': 'Authorization started. Confirm it in your browser.',\n 'account.userCode': 'Code',\n 'account.openBrowser': 'Open browser to confirm',\n 'account.expiresIn': 'This confirmation is valid for {minutes} minutes',\n 'account.cancel': 'Cancel',\n 'account.cancelling': 'Cancelling…',\n 'account.connected': 'Connected',\n 'account.disconnected': 'Not connected',\n 'account.group': 'Group',\n 'account.balance': 'Balance',\n 'account.used': 'Used',\n 'account.token': 'API token',\n 'account.signOut': 'Disconnect',\n 'account.signingOut': 'Disconnecting…',\n 'account.loading': 'Reading connection state…',\n 'account.failed': 'Failed: {message}',\n 'whitelist.title': 'Model whitelist',\n 'whitelist.intro': 'Check the models that should appear in the DSH model picker; unchecked models stay hidden. The list is stored in the plugin configuration and survives a restart.',\n 'whitelist.loading': 'Reading the model list…',\n 'whitelist.failed': 'Model whitelist failed: {message}',\n 'whitelist.search': 'Search models…',\n 'whitelist.noMatch': 'No matching models.',\n 'whitelist.empty': 'The site returned no models.',\n 'whitelist.count': '{total} models',\n 'whitelist.picked': '{selected} selected',\n 'card.expand': 'Expand',\n 'card.collapse': 'Collapse',\n 'whitelist.groupsCount': '{count} groups',\n 'whitelist.minRatio': 'from',\n 'whitelist.groupsTitle': 'Available groups',\n 'whitelist.selectAll': 'Check all',\n 'whitelist.clear': 'Clear',\n 'whitelist.reset': 'Show all',\n 'whitelist.saving': 'Saving…',\n 'whitelist.autoSaved': 'Saved; the model picker has been refreshed',\n 'whitelist.hint': 'Every change saves itself; unchecked models stay out of the picker. \"Show all\" clears the whitelist.',\n 'whitelist.keepOne': 'Keep at least one model; use \"Show all\" to offer everything again.',\n 'whitelist.cleared': 'Boxes cleared; checking a model saves the list you want.',\n 'images.title': 'Image generation',\n 'images.intro': 'Once on, the model can call the generate_image tool. Check the picture models you want and pick the group each one bills to.',\n 'images.enable': 'Enable the generate_image tool',\n 'images.channel.images': 'images endpoint',\n 'images.channel.genai': 'gemini endpoint',\n 'images.channel.chat': 'chat endpoint',\n 'images.save': 'Save',\n 'images.saving': 'Saving…',\n 'images.saved': 'Saved; the tool now runs with these settings',\n 'images.dirty': 'Unsaved changes',\n 'images.hint': 'One picture takes 20-60 seconds; an unchecked model is invisible to the model and cannot be called. Remember to save.',\n 'images.failed': 'Image generation settings failed: {message}',\n 'images.empty': 'The site returned no picture models.',\n 'images.loading': 'Reading the picture models…',\n 'images.count': '{total} picture models',\n 'images.picked': '{selected} enabled',\n 'images.groupAria': 'Group used by {model}',\n} satisfies Record<GroupKey, string>\n","/**\n * NearToken provider plugin, browser half. Registers two surfaces: the NearToken\n * settings page (sign in, account facts, sign out) and a replacement for the\n * composer's model seat at priority -1, so the slot's lowest-priority\n * registration renders and the shipped picker stays in place without drawing.\n *\n * The seat shares the SAME per-session directory the built-in picker uses\n * (`ctx.modelDirectories`), so selection state, pending markers, the /model\n * popup, and Session persistence are unaffected: this plugin only changes what\n * the control looks like and adds the group level on top of it.\n *\n * The seat's declared child ('conversation.input.model.label') is owned by the\n * shipped registration, so this one declares none and renders catalog names\n * directly.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: the carrier types and the ctx.modelDirectories / ctx.remote merges.\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the ui-conversation SlotMap merge (the input.model seat).\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-session/client'\nimport type { ModelSelection } from '@deepseek-ai/dsh-api-session-controller/types'\n// Type-only: pulls the settings shell's SlotMap merge ('settings.section').\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { createNearTokenApi } from './api.ts'\nimport { ModelGroupSelect } from './ModelGroupSelect.tsx'\nimport { NearTokenSection, type NearTokenSectionInjected } from './NearTokenSection.tsx'\nimport { en, zh, type GroupKey } from './locales.ts'\nimport type { ModelGroupSelectInjected } from './slots.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The replacement model seat's copy. */\n modelGroups: GroupKey\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'modelGroups'\n\n/** Required services: the slot registry, locale, sessions, and the directory service. */\nexport const inject = ['slots', 'locale', 'sessions', 'remote', 'remote.session']\n\n/**\n * Client plugin body: register the dictionaries, add the NearToken settings page,\n * then shadow the composer model seat over the shared model directory.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-neartoken-provider: dictionaries')\n // One carrier for the page's whole life: the registration closure hands the\n // same object back on every render, so the section's load effect runs once.\n const api = createNearTokenApi()\n const t = ctx.locale.bind(NS) as NearTokenSectionInjected['t']\n // The near-token page sits between the account page (-10) and the general\n // page (0): both answer \"who am I signed in as\".\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'neartoken',\n order: -5,\n label: () => t('account.nav'),\n locale: NS,\n inject: (): NearTokenSectionInjected => ({ api, t }),\n }, NearTokenSection))\n\n ctx.inject(['slots', 'modelDirectories'], (scope: ClientContext) => {\n const models = scope.modelDirectories\n const sessions = scope.sessions\n scope.slots.inject('conversation.input.model', () => scope.slots.register({\n name: 'conversation.input.model',\n // Shipped seat registers at the default priority 0; lower renders.\n priority: -1,\n locale: NS,\n inject: (sessionId): ModelGroupSelectInjected => {\n const directory = models.directoryFor(sessionId)\n const available = sessions.subagentAddress(sessionId) === undefined\n return {\n available,\n directory: directory.store,\n load: () => {\n if (available) directory.load().catch(() => { /* surfaced on the store */ })\n },\n select: (selection: ModelSelection) => available\n ? directory.select(selection)\n : Promise.resolve(undefined),\n }\n },\n }, ModelGroupSelect))\n })\n}\n"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -657,11 +657,19 @@ function isImageModel(model, endpoints) {
657
657
  }
658
658
  /**
659
659
  * Which request shape one image model speaks.
660
+ *
661
+ * The Gemini family declares `gemini` and a compatible `openai` surface; the
662
+ * native one answers the picture as a structured `inlineData` part, where the
663
+ * compatible one wraps it in assistant text as a data URL. Native measured 74 s
664
+ * against chat's 110 s for the same model and prompt, and it does not depend on
665
+ * a gateway conversion, so it is the route when the site declares it.
660
666
  * @param endpoints - the surfaces the site declares for the model.
661
- * @returns `images` for a model the catalog marks `image-generation`, `chat` otherwise.
667
+ * @returns `images` for an `image-generation` model, `genai` for a Gemini one, `chat` otherwise.
662
668
  */
663
669
  function imageChannel(endpoints) {
664
- return endpoints?.includes("image-generation") === true ? "images" : "chat";
670
+ if (endpoints?.includes("image-generation") === true) return "images";
671
+ if (endpoints?.includes("gemini") === true) return "genai";
672
+ return "chat";
665
673
  }
666
674
  /** The request members only the images endpoint understands. */
667
675
  const IMAGES_ONLY_PARAMETERS = [
@@ -683,7 +691,7 @@ function assertChannelParameters(channel, request) {
683
691
  if (channel === "images") return;
684
692
  const unsupported = IMAGES_ONLY_PARAMETERS.filter((name) => request[name] !== void 0);
685
693
  if (unsupported.length === 0) return;
686
- throw new Error(`${unsupported.join(", ")} can only be sent to an image-generation model; ${request.model} answers chat completions, so drop ${unsupported.length === 1 ? "it" : "them"} or enable a model such as gpt-image-2.5-flare for these settings`);
694
+ throw new Error(`${unsupported.join(", ")} can only be sent to an image-generation model; ${request.model} answers ${channel === "genai" ? "Gemini generateContent" : "chat completions"}, so drop ${unsupported.length === 1 ? "it" : "them"} or enable a model such as gpt-image-2.5-flare for these settings`);
687
695
  }
688
696
  /** An inline picture inside a chat answer. */
689
697
  const DATA_URL = /data:image\/(png|jpeg|webp|gif);base64,([A-Za-z0-9+/=]+)/i;
@@ -716,6 +724,23 @@ function extractImageReply(body) {
716
724
  const reply = replyFromMessage(message);
717
725
  if (reply !== void 0) return reply;
718
726
  }
727
+ for (const candidate of Array.isArray(root.candidates) ? root.candidates : []) {
728
+ if (typeof candidate !== "object" || candidate === null) continue;
729
+ const content = candidate.content;
730
+ if (typeof content !== "object" || content === null) continue;
731
+ const parts = content.parts;
732
+ if (!Array.isArray(parts)) continue;
733
+ for (const part of parts) {
734
+ if (typeof part !== "object" || part === null) continue;
735
+ const inline = part.inlineData ?? part.inline_data;
736
+ if (typeof inline !== "object" || inline === null) continue;
737
+ const data = inline.data;
738
+ if (typeof data === "string" && data.length > 0) return {
739
+ kind: "base64",
740
+ data
741
+ };
742
+ }
743
+ }
719
744
  }
720
745
  /**
721
746
  * Read one chat message as a picture: its text may embed a data URL or link it.
@@ -865,12 +890,14 @@ var NearTokenImageClient = class {
865
890
  * @returns the encoded picture.
866
891
  */
867
892
  async attempt(request) {
868
- const response = await request.send(`${this.deps.baseURL()}/v1/${request.channel === "images" ? "images/generations" : "chat/completions"}`, {
893
+ const pictures = request.images ?? [];
894
+ const path = request.channel === "images" ? "/v1/images/generations" : request.channel === "genai" ? `/v1beta/models/${request.model}:generateContent` : "/v1/chat/completions";
895
+ const response = await request.send(`${this.deps.baseURL()}${path}`, {
869
896
  method: "POST",
870
897
  headers: {
871
898
  ...attributionHeaders(),
872
899
  "content-type": "application/json",
873
- authorization: `Bearer ${request.key}`,
900
+ ...request.channel === "genai" ? { "x-goog-api-key": request.key } : { authorization: `Bearer ${request.key}` },
874
901
  ...request.route?.groupRef === void 0 ? {} : { "x-neartoken-group": request.route.groupRef }
875
902
  },
876
903
  body: JSON.stringify(request.channel === "images" ? {
@@ -880,17 +907,23 @@ var NearTokenImageClient = class {
880
907
  ...request.size === void 0 ? {} : { size: request.size },
881
908
  ...request.quality === void 0 ? {} : { quality: request.quality },
882
909
  ...request.background === void 0 ? {} : { background: request.background },
883
- ...request.images === void 0 || request.images.length === 0 ? {} : { image: [...request.images] }
884
- } : {
910
+ ...pictures.length === 0 ? {} : { image: pictures.map((picture) => `data:${picture.mediaType};base64,${picture.data}`) }
911
+ } : request.channel === "genai" ? { contents: [{
912
+ role: "user",
913
+ parts: [{ text: request.prompt }, ...pictures.map((picture) => ({ inlineData: {
914
+ mimeType: picture.mediaType,
915
+ data: picture.data
916
+ } }))]
917
+ }] } : {
885
918
  model: request.model,
886
919
  messages: [{
887
920
  role: "user",
888
- content: request.images === void 0 || request.images.length === 0 ? request.prompt : [{
921
+ content: pictures.length === 0 ? request.prompt : [{
889
922
  type: "text",
890
923
  text: request.prompt
891
- }, ...request.images.map((url) => ({
924
+ }, ...pictures.map((picture) => ({
892
925
  type: "image_url",
893
- image_url: { url }
926
+ image_url: { url: `data:${picture.mediaType};base64,${picture.data}` }
894
927
  }))]
895
928
  }],
896
929
  stream: false
@@ -1152,7 +1185,7 @@ async function resolveOptions(ctx, exec) {
1152
1185
  * @param ctx - a context carrying `fs`.
1153
1186
  * @param exec - the current tool execution.
1154
1187
  * @param paths - model-supplied file paths.
1155
- * @returns one data URL per picture.
1188
+ * @returns one payload per picture.
1156
1189
  * @throws {Error} when a path cannot be read as a supported image.
1157
1190
  */
1158
1191
  async function readReferences(ctx, exec, paths) {
@@ -1161,7 +1194,7 @@ async function readReferences(ctx, exec, paths) {
1161
1194
  const fs = ctx.get("fs");
1162
1195
  if (fs === void 0) throw new Error("cannot read reference images: no filesystem service is mounted");
1163
1196
  const options = await resolveOptions(ctx, exec);
1164
- const urls = [];
1197
+ const pictures = [];
1165
1198
  for (const requested of paths) {
1166
1199
  const target = await fs.resolve(requested, options);
1167
1200
  const info = await fs.stat(target, exec.signal);
@@ -1170,9 +1203,12 @@ async function readReferences(ctx, exec, paths) {
1170
1203
  const bytes = await fs.readBytes(target, exec.signal, MAX_REFERENCE_BYTES);
1171
1204
  const mediaType = sniffImageMediaType(bytes);
1172
1205
  if (mediaType === void 0) throw new Error(`cannot use "${target.displayPath}" as a reference image: not a PNG/JPEG/WebP/GIF file`);
1173
- urls.push(`data:${mediaType};base64,${Buffer.from(bytes).toString("base64")}`);
1206
+ pictures.push({
1207
+ mediaType,
1208
+ data: Buffer.from(bytes).toString("base64")
1209
+ });
1174
1210
  }
1175
- return urls;
1211
+ return pictures;
1176
1212
  }
1177
1213
  /**
1178
1214
  * Write a generated picture beside the transcript copy.
@@ -74,6 +74,7 @@ export declare const zh: {
74
74
  'images.intro': string;
75
75
  'images.enable': string;
76
76
  'images.channel.images': string;
77
+ 'images.channel.genai': string;
77
78
  'images.channel.chat': string;
78
79
  'images.save': string;
79
80
  'images.saving': string;
@@ -160,6 +161,7 @@ export declare const en: {
160
161
  'images.intro': string;
161
162
  'images.enable': string;
162
163
  'images.channel.images': string;
164
+ 'images.channel.genai': string;
163
165
  'images.channel.chat': string;
164
166
  'images.save': string;
165
167
  'images.saving': string;
@@ -14,7 +14,7 @@
14
14
  import type { ImageMediaType } from '@deepseek-ai/dsh-attachment';
15
15
  import type { NearTokenRoute } from './pricing.ts';
16
16
  /** How one image model is asked for a picture. */
17
- export type ImageChannel = 'images' | 'chat';
17
+ export type ImageChannel = 'images' | 'genai' | 'chat';
18
18
  /**
19
19
  * Whether a catalog route is a picture generator.
20
20
  * @param model - the bare model name.
@@ -24,10 +24,23 @@ export type ImageChannel = 'images' | 'chat';
24
24
  export declare function isImageModel(model: string, endpoints?: readonly string[]): boolean;
25
25
  /**
26
26
  * Which request shape one image model speaks.
27
+ *
28
+ * The Gemini family declares `gemini` and a compatible `openai` surface; the
29
+ * native one answers the picture as a structured `inlineData` part, where the
30
+ * compatible one wraps it in assistant text as a data URL. Native measured 74 s
31
+ * against chat's 110 s for the same model and prompt, and it does not depend on
32
+ * a gateway conversion, so it is the route when the site declares it.
27
33
  * @param endpoints - the surfaces the site declares for the model.
28
- * @returns `images` for a model the catalog marks `image-generation`, `chat` otherwise.
34
+ * @returns `images` for an `image-generation` model, `genai` for a Gemini one, `chat` otherwise.
29
35
  */
30
36
  export declare function imageChannel(endpoints?: readonly string[]): ImageChannel;
37
+ /** One reference picture, in the form every channel can encode for itself. */
38
+ export interface ImagePayload {
39
+ /** Media type the bytes were verified as. */
40
+ readonly mediaType: string;
41
+ /** Base64 payload without a data-URL prefix. */
42
+ readonly data: string;
43
+ }
31
44
  /** One picture the site answered with, before its bytes exist. */
32
45
  export type ImageReply = {
33
46
  readonly kind: 'base64';
@@ -94,8 +107,8 @@ export declare class NearTokenImageClient {
94
107
  readonly size?: string;
95
108
  readonly quality?: string;
96
109
  readonly background?: string;
97
- /** Reference pictures as data URLs, in the order the caller gave them. */
98
- readonly images?: readonly string[];
110
+ /** Reference pictures, in the order the caller gave them. */
111
+ readonly images?: readonly ImagePayload[];
99
112
  readonly signal?: AbortSignal;
100
113
  }): Promise<NearTokenGeneratedImage>;
101
114
  /**
@@ -101,8 +101,11 @@ export type BeginAuthorizationOutcome = {
101
101
  readonly status: 'failed';
102
102
  readonly message: string;
103
103
  };
104
- /** Which request shape one picture model speaks: the images endpoint or a chat completion. */
105
- export type NearTokenImageChannel = 'images' | 'chat';
104
+ /**
105
+ * Which request shape one picture model speaks: the images endpoint, Gemini's
106
+ * own generateContent, or a chat completion.
107
+ */
108
+ export type NearTokenImageChannel = 'images' | 'genai' | 'chat';
106
109
  /** One picture model the image-generation setting can enable. */
107
110
  export interface NearTokenImageModelEntry {
108
111
  /** Bare model name, as the site's API takes it. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-neartoken",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },