@astralyn/pi 0.85.1 → 0.85.2

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.
Files changed (248) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cli.js +94 -91
  3. package/dist/core/agent-session.js +2 -2
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/background/history.d.ts.map +1 -1
  6. package/dist/core/background/history.js +6 -0
  7. package/dist/core/background/history.js.map +1 -1
  8. package/dist/core/background/presentation.d.ts.map +1 -1
  9. package/dist/core/background/presentation.js +41 -4
  10. package/dist/core/background/presentation.js.map +1 -1
  11. package/dist/core/background/service.d.ts +2 -2
  12. package/dist/core/background/service.d.ts.map +1 -1
  13. package/dist/core/background/service.js +38 -15
  14. package/dist/core/background/service.js.map +1 -1
  15. package/dist/core/background/types.d.ts +9 -0
  16. package/dist/core/background/types.d.ts.map +1 -1
  17. package/dist/core/background/types.js +4 -0
  18. package/dist/core/background/types.js.map +1 -1
  19. package/dist/core/compaction/compaction.d.ts +5 -12
  20. package/dist/core/compaction/compaction.d.ts.map +1 -1
  21. package/dist/core/compaction/compaction.js +11 -19
  22. package/dist/core/compaction/compaction.js.map +1 -1
  23. package/dist/core/compaction/settings.d.ts +27 -0
  24. package/dist/core/compaction/settings.d.ts.map +1 -0
  25. package/dist/core/compaction/settings.js +40 -0
  26. package/dist/core/compaction/settings.js.map +1 -0
  27. package/dist/core/keybindings.d.ts +15 -0
  28. package/dist/core/keybindings.d.ts.map +1 -1
  29. package/dist/core/keybindings.js +12 -0
  30. package/dist/core/keybindings.js.map +1 -1
  31. package/dist/core/model-config.d.ts +32 -10
  32. package/dist/core/model-config.d.ts.map +1 -1
  33. package/dist/core/model-config.js +38 -1
  34. package/dist/core/model-config.js.map +1 -1
  35. package/dist/core/model-runtime.d.ts +2 -0
  36. package/dist/core/model-runtime.d.ts.map +1 -1
  37. package/dist/core/model-runtime.js +4 -0
  38. package/dist/core/model-runtime.js.map +1 -1
  39. package/dist/core/settings-manager.d.ts +4 -7
  40. package/dist/core/settings-manager.d.ts.map +1 -1
  41. package/dist/core/settings-manager.js +7 -6
  42. package/dist/core/settings-manager.js.map +1 -1
  43. package/dist/core/tools/bash.js +1 -1
  44. package/dist/core/tools/bash.js.map +1 -1
  45. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  46. package/dist/core/tools/shell-execution.js +3 -1
  47. package/dist/core/tools/shell-execution.js.map +1 -1
  48. package/dist/extensions/background/manager.d.ts +8 -5
  49. package/dist/extensions/background/manager.d.ts.map +1 -1
  50. package/dist/extensions/background/manager.js +115 -39
  51. package/dist/extensions/background/manager.js.map +1 -1
  52. package/dist/extensions/background/task-view.d.ts +5 -0
  53. package/dist/extensions/background/task-view.d.ts.map +1 -1
  54. package/dist/extensions/background/task-view.js +4 -0
  55. package/dist/extensions/background/task-view.js.map +1 -1
  56. package/dist/extensions/btw/controller.d.ts +1 -1
  57. package/dist/extensions/btw/controller.d.ts.map +1 -1
  58. package/dist/extensions/btw/controller.js +4 -4
  59. package/dist/extensions/btw/controller.js.map +1 -1
  60. package/dist/extensions/btw/index.js +3 -3
  61. package/dist/extensions/btw/index.js.map +1 -1
  62. package/dist/extensions/index.js +2 -2
  63. package/dist/extensions/index.js.map +1 -1
  64. package/dist/extensions/provider/catalog.d.ts +57 -0
  65. package/dist/extensions/provider/catalog.d.ts.map +1 -0
  66. package/dist/extensions/provider/catalog.js +181 -0
  67. package/dist/extensions/provider/catalog.js.map +1 -0
  68. package/dist/extensions/provider/compat-fields.d.ts +25 -0
  69. package/dist/extensions/provider/compat-fields.d.ts.map +1 -0
  70. package/dist/extensions/provider/compat-fields.js +148 -0
  71. package/dist/extensions/provider/compat-fields.js.map +1 -0
  72. package/dist/extensions/provider/configuration.d.ts +8 -0
  73. package/dist/extensions/provider/configuration.d.ts.map +1 -0
  74. package/dist/extensions/provider/configuration.js +21 -0
  75. package/dist/extensions/provider/configuration.js.map +1 -0
  76. package/dist/extensions/provider/connection.d.ts +14 -0
  77. package/dist/extensions/provider/connection.d.ts.map +1 -0
  78. package/dist/extensions/provider/connection.js +86 -0
  79. package/dist/extensions/provider/connection.js.map +1 -0
  80. package/dist/extensions/provider/constants.d.ts +38 -0
  81. package/dist/extensions/provider/constants.d.ts.map +1 -0
  82. package/dist/extensions/provider/constants.js +75 -0
  83. package/dist/extensions/provider/constants.js.map +1 -0
  84. package/dist/extensions/provider/index.d.ts +4 -0
  85. package/dist/extensions/provider/index.d.ts.map +1 -0
  86. package/dist/extensions/provider/index.js +65 -0
  87. package/dist/extensions/provider/index.js.map +1 -0
  88. package/dist/extensions/provider/probe.d.ts +34 -0
  89. package/dist/extensions/provider/probe.d.ts.map +1 -0
  90. package/dist/extensions/provider/probe.js +178 -0
  91. package/dist/extensions/provider/probe.js.map +1 -0
  92. package/dist/extensions/provider/refresh.d.ts +30 -0
  93. package/dist/extensions/provider/refresh.d.ts.map +1 -0
  94. package/dist/extensions/provider/refresh.js +66 -0
  95. package/dist/extensions/provider/refresh.js.map +1 -0
  96. package/dist/extensions/provider/store.d.ts +131 -0
  97. package/dist/extensions/provider/store.d.ts.map +1 -0
  98. package/dist/extensions/provider/store.js +503 -0
  99. package/dist/extensions/provider/store.js.map +1 -0
  100. package/dist/extensions/provider/ui/app.d.ts +25 -0
  101. package/dist/extensions/provider/ui/app.d.ts.map +1 -0
  102. package/dist/extensions/provider/ui/app.js +153 -0
  103. package/dist/extensions/provider/ui/app.js.map +1 -0
  104. package/dist/extensions/provider/ui/builtin-data.d.ts +53 -0
  105. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -0
  106. package/dist/extensions/provider/ui/builtin-data.js +315 -0
  107. package/dist/extensions/provider/ui/builtin-data.js.map +1 -0
  108. package/dist/extensions/provider/ui/compat.d.ts +57 -0
  109. package/dist/extensions/provider/ui/compat.d.ts.map +1 -0
  110. package/dist/extensions/provider/ui/compat.js +427 -0
  111. package/dist/extensions/provider/ui/compat.js.map +1 -0
  112. package/dist/extensions/provider/ui/dialogs.d.ts +30 -0
  113. package/dist/extensions/provider/ui/dialogs.d.ts.map +1 -0
  114. package/dist/extensions/provider/ui/dialogs.js +89 -0
  115. package/dist/extensions/provider/ui/dialogs.js.map +1 -0
  116. package/dist/extensions/provider/ui/dictionary.d.ts +29 -0
  117. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -0
  118. package/dist/extensions/provider/ui/dictionary.js +385 -0
  119. package/dist/extensions/provider/ui/dictionary.js.map +1 -0
  120. package/dist/extensions/provider/ui/editor.d.ts +91 -0
  121. package/dist/extensions/provider/ui/editor.d.ts.map +1 -0
  122. package/dist/extensions/provider/ui/editor.js +667 -0
  123. package/dist/extensions/provider/ui/editor.js.map +1 -0
  124. package/dist/extensions/provider/ui/fetch-models.d.ts +39 -0
  125. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -0
  126. package/dist/extensions/provider/ui/fetch-models.js +320 -0
  127. package/dist/extensions/provider/ui/fetch-models.js.map +1 -0
  128. package/dist/extensions/provider/ui/model-fields.d.ts +43 -0
  129. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -0
  130. package/dist/extensions/provider/ui/model-fields.js +441 -0
  131. package/dist/extensions/provider/ui/model-fields.js.map +1 -0
  132. package/dist/extensions/provider/ui/model-options.d.ts +93 -0
  133. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -0
  134. package/dist/extensions/provider/ui/model-options.js +529 -0
  135. package/dist/extensions/provider/ui/model-options.js.map +1 -0
  136. package/dist/extensions/provider/ui/pane.d.ts +81 -0
  137. package/dist/extensions/provider/ui/pane.d.ts.map +1 -0
  138. package/dist/extensions/provider/ui/pane.js +3 -0
  139. package/dist/extensions/provider/ui/pane.js.map +1 -0
  140. package/dist/extensions/provider/ui/provider-fields.d.ts +60 -0
  141. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -0
  142. package/dist/extensions/provider/ui/provider-fields.js +326 -0
  143. package/dist/extensions/provider/ui/provider-fields.js.map +1 -0
  144. package/dist/extensions/provider/ui/provider-list.d.ts +34 -0
  145. package/dist/extensions/provider/ui/provider-list.d.ts.map +1 -0
  146. package/dist/extensions/provider/ui/provider-list.js +162 -0
  147. package/dist/extensions/provider/ui/provider-list.js.map +1 -0
  148. package/dist/extensions/provider/ui/session.d.ts +20 -0
  149. package/dist/extensions/provider/ui/session.d.ts.map +1 -0
  150. package/dist/extensions/provider/ui/session.js +52 -0
  151. package/dist/extensions/provider/ui/session.js.map +1 -0
  152. package/dist/extensions/provider/ui/thinking-map.d.ts +20 -0
  153. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -0
  154. package/dist/extensions/provider/ui/thinking-map.js +166 -0
  155. package/dist/extensions/provider/ui/thinking-map.js.map +1 -0
  156. package/dist/extensions/provider/ui/value-row.d.ts +88 -0
  157. package/dist/extensions/provider/ui/value-row.d.ts.map +1 -0
  158. package/dist/extensions/provider/ui/value-row.js +158 -0
  159. package/dist/extensions/provider/ui/value-row.js.map +1 -0
  160. package/dist/extensions/statusline/index.js +2 -2
  161. package/dist/extensions/statusline/index.js.map +1 -1
  162. package/dist/extensions/subagent/index.d.ts.map +1 -1
  163. package/dist/extensions/subagent/index.js +4 -2
  164. package/dist/extensions/subagent/index.js.map +1 -1
  165. package/dist/extensions/subagent/resolve.d.ts +5 -0
  166. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  167. package/dist/extensions/subagent/resolve.js +15 -7
  168. package/dist/extensions/subagent/resolve.js.map +1 -1
  169. package/dist/extensions/subagent/schema.d.ts +2 -0
  170. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  171. package/dist/extensions/subagent/schema.js +1 -0
  172. package/dist/extensions/subagent/schema.js.map +1 -1
  173. package/dist/modes/interactive/components/tool-execution.d.ts +10 -0
  174. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  175. package/dist/modes/interactive/components/tool-execution.js +20 -2
  176. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  177. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  178. package/dist/modes/interactive/interactive-mode.js +6 -1
  179. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  180. package/dist/rpc-entry.js +94 -91
  181. package/docs/bundled/README.md +1 -1
  182. package/docs/bundled/extensions/background.md +5 -5
  183. package/docs/bundled/extensions/provider.md +117 -0
  184. package/docs/bundled/extensions/statusline.md +1 -1
  185. package/docs/bundled/extensions/subagent.md +7 -3
  186. package/docs/compaction.md +16 -6
  187. package/docs/docs.json +2 -2
  188. package/docs/keybindings.md +3 -0
  189. package/docs/settings.md +11 -7
  190. package/npm-shrinkwrap.json +2 -2
  191. package/package.json +1 -1
  192. package/dist/extensions/router/constants.d.ts +0 -23
  193. package/dist/extensions/router/constants.d.ts.map +0 -1
  194. package/dist/extensions/router/constants.js +0 -30
  195. package/dist/extensions/router/constants.js.map +0 -1
  196. package/dist/extensions/router/dialog-host.d.ts +0 -60
  197. package/dist/extensions/router/dialog-host.d.ts.map +0 -1
  198. package/dist/extensions/router/dialog-host.js +0 -196
  199. package/dist/extensions/router/dialog-host.js.map +0 -1
  200. package/dist/extensions/router/dialog.d.ts +0 -45
  201. package/dist/extensions/router/dialog.d.ts.map +0 -1
  202. package/dist/extensions/router/dialog.js +0 -378
  203. package/dist/extensions/router/dialog.js.map +0 -1
  204. package/dist/extensions/router/identity.d.ts +0 -15
  205. package/dist/extensions/router/identity.d.ts.map +0 -1
  206. package/dist/extensions/router/identity.js +0 -173
  207. package/dist/extensions/router/identity.js.map +0 -1
  208. package/dist/extensions/router/index.d.ts +0 -15
  209. package/dist/extensions/router/index.d.ts.map +0 -1
  210. package/dist/extensions/router/index.js +0 -70
  211. package/dist/extensions/router/index.js.map +0 -1
  212. package/dist/extensions/router/presets.d.ts +0 -51
  213. package/dist/extensions/router/presets.d.ts.map +0 -1
  214. package/dist/extensions/router/presets.js +0 -108
  215. package/dist/extensions/router/presets.js.map +0 -1
  216. package/dist/extensions/router/probe.d.ts +0 -26
  217. package/dist/extensions/router/probe.d.ts.map +0 -1
  218. package/dist/extensions/router/probe.js +0 -216
  219. package/dist/extensions/router/probe.js.map +0 -1
  220. package/dist/extensions/router/register.d.ts +0 -12
  221. package/dist/extensions/router/register.d.ts.map +0 -1
  222. package/dist/extensions/router/register.js +0 -90
  223. package/dist/extensions/router/register.js.map +0 -1
  224. package/dist/extensions/router/state.d.ts +0 -20
  225. package/dist/extensions/router/state.d.ts.map +0 -1
  226. package/dist/extensions/router/state.js +0 -169
  227. package/dist/extensions/router/state.js.map +0 -1
  228. package/dist/extensions/router/store.d.ts +0 -12
  229. package/dist/extensions/router/store.d.ts.map +0 -1
  230. package/dist/extensions/router/store.js +0 -266
  231. package/dist/extensions/router/store.js.map +0 -1
  232. package/dist/extensions/router/stream.d.ts +0 -12
  233. package/dist/extensions/router/stream.d.ts.map +0 -1
  234. package/dist/extensions/router/stream.js +0 -233
  235. package/dist/extensions/router/stream.js.map +0 -1
  236. package/dist/extensions/router/transport.d.ts +0 -9
  237. package/dist/extensions/router/transport.d.ts.map +0 -1
  238. package/dist/extensions/router/transport.js +0 -81
  239. package/dist/extensions/router/transport.js.map +0 -1
  240. package/dist/extensions/router/types.d.ts +0 -39
  241. package/dist/extensions/router/types.d.ts.map +0 -1
  242. package/dist/extensions/router/types.js +0 -2
  243. package/dist/extensions/router/types.js.map +0 -1
  244. package/dist/extensions/router/ui.d.ts +0 -26
  245. package/dist/extensions/router/ui.d.ts.map +0 -1
  246. package/dist/extensions/router/ui.js +0 -897
  247. package/dist/extensions/router/ui.js.map +0 -1
  248. package/docs/bundled/extensions/router.md +0 -197
@@ -1 +0,0 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/extensions/router/ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /router interactive flows: list, add, edit, fetch, thinking map.\n *\n * Relay edits are live: confirmed inputs and every toggle persist immediately.\n * Searchable pickers follow Pi's native /model interaction pattern.\n */\n\nimport type { ProviderHeaders } from \"@earendil-works/pi-ai\";\nimport type { TUI } from \"@earendil-works/pi-tui\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { BorderedLoader } from \"../../modes/interactive/components/bordered-loader.ts\";\nimport { getModelSelectorSearchText } from \"../../modes/interactive/model-search.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { formatError, isValidRelayId, NO_UI_WARNING, ROUTER_THINKING_LEVELS, truncate } from \"./constants.ts\";\nimport {\n\tcreateModelChecklist,\n\tcreateSearchableSelector,\n\tcreateThinkingMapEditor,\n\ttype ModelChecklistItem,\n} from \"./dialog.ts\";\nimport {\n\tcreateNativeRouterDialogs,\n\ttype RouterDialogs,\n\tRouterTuiSession,\n\tRouterTuiSessionClosedError,\n} from \"./dialog-host.ts\";\nimport {\n\tcreateDefaultModelConfig,\n\tdisplayModelLabel,\n\tresolveModelConfig,\n\tresolveRouterThinkingMap,\n\tsummarizeThinkingMap,\n} from \"./presets.ts\";\nimport { type ProbeModel, probeRelayModels } from \"./probe.ts\";\nimport { applyRouterFile, initializeRouterState, registerOneRelay, unregisterOneRelay } from \"./register.ts\";\nimport { loadRouterFile, removeRelay, upsertRelay } from \"./store.ts\";\nimport type { RelayConfig, RelayModelConfig } from \"./types.ts\";\n\n/**\n * Serialize live relay mutations without forcing a model-registry refresh for\n * every checkbox press. Provider registration follows each snapshot; the\n * registry is refreshed once when the editor closes.\n */\nclass RelayAutoSaver {\n\tprivate chain: Promise<void> = Promise.resolve();\n\tprivate error: unknown;\n\tprivate needsRefresh = false;\n\tprivate readonly ctx: ExtensionCommandContext;\n\tprivate readonly pi: ExtensionAPI;\n\tprivate readonly relay: RelayConfig;\n\n\tconstructor(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig) {\n\t\tthis.ctx = ctx;\n\t\tthis.pi = pi;\n\t\tthis.relay = relay;\n\t}\n\n\tsave(): void {\n\t\tconst snapshot = structuredClone(this.relay);\n\t\tthis.needsRefresh = true;\n\t\tthis.chain = this.chain\n\t\t\t.catch(() => {})\n\t\t\t.then(async () => {\n\t\t\t\tawait upsertRelay(snapshot);\n\t\t\t\tregisterOneRelay(this.pi, snapshot);\n\t\t\t\tthis.error = undefined;\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tthis.error = error;\n\t\t\t});\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.chain;\n\t\tif (this.error !== undefined) {\n\t\t\tconst error = this.error;\n\t\t\tthis.error = undefined;\n\t\t\tthrow error;\n\t\t}\n\t\tif (this.needsRefresh) {\n\t\t\tthis.needsRefresh = false;\n\t\t\tawait this.ctx.modelRegistry.refresh();\n\t\t}\n\t}\n}\n\n/** Abort the catalog request if its internal page or the whole Router session is disposed. */\nclass RouterProbeLoader extends BorderedLoader {\n\treadonly probeSignal: AbortSignal;\n\tprivate readonly disposeController = new AbortController();\n\n\tconstructor(tui: TUI, theme: Theme, message: string) {\n\t\tsuper(tui, theme, message, { cancellable: true });\n\t\tthis.probeSignal = AbortSignal.any([this.signal, this.disposeController.signal]);\n\t}\n\n\toverride dispose(): void {\n\t\tthis.disposeController.abort();\n\t\tsuper.dispose();\n\t}\n}\n\nexport function isCurrentRouterModel(\n\tcurrent: { provider: string; id: string } | undefined,\n\trelayId: string,\n\tmodelId: string,\n): boolean {\n\treturn current?.provider === relayId && current.id === modelId;\n}\n\nexport async function runRouterCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(NO_UI_WARNING, \"warning\");\n\t\treturn;\n\t}\n\t// Initialize before any provider closure can capture request state, including first /router reload.\n\tawait initializeRouterState(pi);\n\tconst trimmed = args.trim().toLowerCase();\n\tif (trimmed === \"reload\") {\n\t\tconst file = await loadRouterFile();\n\t\tapplyRouterFile(pi, file);\n\t\tawait ctx.modelRegistry.refresh();\n\t\tctx.ui.notify(`Reloaded ${file.relays.length} relay(s).`, \"info\");\n\t\treturn;\n\t}\n\tif (ctx.mode === \"tui\") {\n\t\tawait runRouterTuiCommand(args, ctx, pi);\n\t\treturn;\n\t}\n\tawait runRouterDialogCommand(args, ctx, pi, createNativeRouterDialogs(ctx));\n}\n\nasync function runRouterTuiCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tlet failure: { error: unknown } | undefined;\n\tlet closedDuringTransition = false;\n\tawait ctx.ui.custom<void>((tui, theme, keybindings, done) => {\n\t\tconst session = new RouterTuiSession(tui, theme, keybindings, () => {\n\t\t\tclosedDuringTransition = true;\n\t\t\tdone();\n\t\t});\n\t\tvoid runRouterDialogCommand(args, ctx, pi, session).then(\n\t\t\t() => {\n\t\t\t\tif (!closedDuringTransition) done();\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (closedDuringTransition) {\n\t\t\t\t\tif (!(error instanceof RouterTuiSessionClosedError)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tctx.ui.notify(formatError(error), \"error\");\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// The command context may have gone stale after the modal closed.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfailure = { error };\n\t\t\t\tdone();\n\t\t\t},\n\t\t);\n\t\treturn session;\n\t});\n\tif (failure) throw failure.error;\n}\n\nasync function runRouterDialogCommand(\n\targs: string,\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n): Promise<void> {\n\tconst trimmed = args.trim().toLowerCase();\n\tif (!trimmed || trimmed === \"list\") {\n\t\tawait openMainMenu(ctx, pi, dialogs);\n\t\treturn;\n\t}\n\tif (trimmed === \"add\") {\n\t\tawait addRelayFlow(ctx, pi, dialogs);\n\t\treturn;\n\t}\n\t// Treat as relay id open.\n\tconst file = await loadRouterFile();\n\tconst exact = file.relays.find((relay) => relay.id.toLowerCase() === trimmed);\n\tif (exact) {\n\t\tawait editRelayFlow(ctx, pi, dialogs, exact);\n\t\treturn;\n\t}\n\tawait openMainMenu(ctx, pi, dialogs, args.trim());\n}\n\nasync function openMainMenu(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\tinitialQuery?: string,\n): Promise<void> {\n\tlet cursor: string | undefined;\n\tlet query = initialQuery;\n\twhile (true) {\n\t\tconst file = await loadRouterFile();\n\t\t// Relays first (primary content), actions at the bottom.\n\t\tconst items = [\n\t\t\t...file.relays.map((relay) => ({\n\t\t\t\tvalue: `relay:${relay.id}`,\n\t\t\t\tlabel: relay.id,\n\t\t\t\tdescription: `${relay.models.length} model${relay.models.length === 1 ? \"\" : \"s\"} · ${truncate(relay.baseUrl, 40)}`,\n\t\t\t\tsearchText: `${relay.id} ${relay.baseUrl}`,\n\t\t\t})),\n\t\t\t{\n\t\t\t\tvalue: \"action:add\",\n\t\t\t\tlabel: \"+ Add relay\",\n\t\t\t\tdescription: \"Name · base URL · API key · fetch models\",\n\t\t\t\tsearchText: \"add create new relay gateway\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:reload\",\n\t\t\t\tlabel: \"Reload from disk\",\n\t\t\t\tdescription: \"Re-register providers from router.json\",\n\t\t\t\tsearchText: \"reload refresh\",\n\t\t\t},\n\t\t];\n\n\t\tconst selected =\n\t\t\tdialogs.kind === \"tui\"\n\t\t\t\t? await dialogs.show(\n\t\t\t\t\t\tcreateSearchableSelector({\n\t\t\t\t\t\t\ttitle: \"API relays\",\n\t\t\t\t\t\t\tsubtitle:\n\t\t\t\t\t\t\t\tfile.relays.length === 0\n\t\t\t\t\t\t\t\t\t? \"No relays yet — add a base URL + API key.\"\n\t\t\t\t\t\t\t\t\t: `${file.relays.length} relay${file.relays.length === 1 ? \"\" : \"s\"} · Enter opens · Esc closes`,\n\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\tinitialValue: cursor,\n\t\t\t\t\t\t\tinitialQuery: query,\n\t\t\t\t\t\t\tmaxVisible: 10,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t: await selectRouterItem(\n\t\t\t\t\t\tdialogs,\n\t\t\t\t\t\t\"API relays\",\n\t\t\t\t\t\titems.map((item) => ({ value: item.value, label: item.label, description: item.description })),\n\t\t\t\t\t);\n\n\t\tquery = undefined;\n\t\tif (selected === undefined) return;\n\t\tcursor = selected;\n\n\t\tif (selected === \"action:add\") {\n\t\t\tconst id = await addRelayFlow(ctx, pi, dialogs);\n\t\t\tif (id) cursor = `relay:${id}`;\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected === \"action:reload\") {\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tapplyRouterFile(pi, latest);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Reloaded ${latest.relays.length} relay(s).`, \"info\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected.startsWith(\"relay:\")) {\n\t\t\tconst id = selected.slice(\"relay:\".length);\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tconst relay = latest.relays.find((entry) => entry.id === id);\n\t\t\tif (!relay) {\n\t\t\t\tctx.ui.notify(`Relay \"${id}\" not found.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait editRelayFlow(ctx, pi, dialogs, relay);\n\t\t}\n\t}\n}\n\nasync function addRelayFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n): Promise<string | undefined> {\n\tconst file = await loadRouterFile();\n\tconst existing = new Set(file.relays.map((relay) => relay.id));\n\n\tconst id = await promptText(ctx, dialogs, \"New relay · name (provider id)\", \"my-relay\", (value) => {\n\t\tconst trimmed = value.trim();\n\t\tif (!trimmed) return \"Name is required.\";\n\t\tif (!isValidRelayId(trimmed)) return \"Name cannot be empty or contain '/'.\";\n\t\tif (existing.has(trimmed)) return `Relay \"${trimmed}\" already exists.`;\n\t\treturn undefined;\n\t});\n\tif (id === undefined) return undefined;\n\n\tconst baseUrl = await promptText(\n\t\tctx,\n\t\tdialogs,\n\t\t`New relay · ${id.trim()} · base URL`,\n\t\t\"https://relay.example/v1\",\n\t\t(value) => {\n\t\t\tconst trimmed = value.trim();\n\t\t\tif (!trimmed) return \"Base URL is required.\";\n\t\t\ttry {\n\t\t\t\tconst url = new URL(trimmed);\n\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t\tif (url.username || url.password || url.hash) return \"Do not embed credentials or a fragment in the URL.\";\n\t\t\t} catch {\n\t\t\t\treturn \"Invalid URL.\";\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t);\n\tif (baseUrl === undefined) return undefined;\n\n\tconst apiKey = await promptText(\n\t\tctx,\n\t\tdialogs,\n\t\t`New relay · ${id.trim()} · API key`,\n\t\t\"sk-… or $RELAY_KEY\",\n\t\t(value) => {\n\t\t\tif (!value.trim()) return \"API key is required.\";\n\t\t\treturn undefined;\n\t\t},\n\t);\n\tif (apiKey === undefined) return undefined;\n\n\tconst relay: RelayConfig = {\n\t\tid: id.trim(),\n\t\tbaseUrl: baseUrl.trim().replace(/\\/+$/, \"\"),\n\t\tapiKey: apiKey.trim(),\n\t\tmodels: [],\n\t};\n\n\t// Connection fields are committed before the network step so cancelling or\n\t// failing catalog discovery never loses the relay the user just entered.\n\tawait persistRelay(ctx, pi, relay);\n\tawait fetchAndSelectModels(ctx, pi, dialogs, relay);\n\tif (relay.models.length === 0) {\n\t\tctx.ui.notify(`Relay \"${relay.id}\" has no models yet.`, \"warning\");\n\t}\n\treturn relay.id;\n}\n\n/**\n * Relay editor — flat menu. Every mutation writes router.json immediately.\n * Hierarchy: list → relay → (models list | connection field | fetch | remove).\n */\nasync function editRelayFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\tinitial: RelayConfig,\n): Promise<void> {\n\tconst relay = structuredClone(initial);\n\twhile (true) {\n\t\tconst modelSummary =\n\t\t\trelay.models.length === 0\n\t\t\t\t? \"none yet — fetch catalog\"\n\t\t\t\t: relay.models.length <= 3\n\t\t\t\t\t? relay.models.map((m) => displayModelLabel(m)).join(\", \")\n\t\t\t\t\t: `${relay.models.length} models · ${relay.models\n\t\t\t\t\t\t\t.slice(0, 2)\n\t\t\t\t\t\t\t.map((m) => displayModelLabel(m))\n\t\t\t\t\t\t\t.join(\", \")}…`;\n\n\t\tconst choice = await selectRouterItem(dialogs, `Relay · ${relay.id}`, [\n\t\t\t{\n\t\t\t\tvalue: \"models\",\n\t\t\t\tlabel: \"Models\",\n\t\t\t\tdescription: modelSummary,\n\t\t\t},\n\t\t\t{ value: \"baseUrl\", label: \"Base URL\", description: relay.baseUrl },\n\t\t\t{ value: \"apiKey\", label: \"API key\", description: maskKey(relay.apiKey) },\n\t\t\t{ value: \"catalog\", label: \"Catalog format\", description: relay.catalog ?? \"openai\" },\n\t\t\t{ value: \"providerName\", label: \"Provider display name\", description: relay.name ?? relay.id },\n\t\t\t{ value: \"remove\", label: \"Remove relay\", description: \"Delete from router.json\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relays\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\n\t\tif (choice === \"catalog\") {\n\t\t\tconst next = await selectRouterItem(dialogs, \"Catalog format\", [\n\t\t\t\t{ value: \"openai\", label: \"OpenAI\", description: \"GET /models · data[].id\" },\n\t\t\t\t{ value: \"codex\", label: \"Codex\", description: \"GET /models?client_version=… · models[].slug\" },\n\t\t\t]);\n\t\t\tif (next) {\n\t\t\t\trelay.catalog = next;\n\t\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (choice === \"providerName\") {\n\t\t\tconst next = await dialogs.input(\"Provider display name · empty uses id\", relay.name ?? \"\");\n\t\t\tif (next !== undefined) {\n\t\t\t\tif (next.trim()) relay.name = next.trim();\n\t\t\t\telse delete relay.name;\n\t\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (choice === \"baseUrl\") {\n\t\t\tconst next = await promptText(ctx, dialogs, `Relay · ${relay.id} · base URL`, relay.baseUrl, (value) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(value.trim());\n\t\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t\t\tif (url.username || url.password || url.hash)\n\t\t\t\t\t\treturn \"Do not embed credentials or a fragment in the URL.\";\n\t\t\t\t} catch {\n\t\t\t\t\treturn \"Invalid URL.\";\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t\tif (next === undefined) continue;\n\t\t\tconst normalized = next.trim().replace(/\\/+$/, \"\");\n\t\t\tif (normalized === relay.baseUrl) continue;\n\t\t\trelay.baseUrl = normalized;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"apiKey\") {\n\t\t\tconst next = await promptText(\n\t\t\t\tctx,\n\t\t\t\tdialogs,\n\t\t\t\t`Relay · ${relay.id} · API key`,\n\t\t\t\t\"Enter a new key · blank keeps the current value\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tif (!trimmed || trimmed === relay.apiKey) continue;\n\t\t\trelay.apiKey = trimmed;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"models\") {\n\t\t\t// Always open the models screen (fetch lives only here). Empty list still\n\t\t\t// shows Fetch so the path is Relay → Models → Fetch, not a top-level shortcut.\n\t\t\tawait manageModelsFlow(ctx, pi, dialogs, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"remove\") {\n\t\t\tif (ctx.model?.provider === relay.id) {\n\t\t\t\tctx.ui.notify(`Switch away from relay \"${relay.id}\" before removing it.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ok = await dialogs.confirm(`Remove relay \"${relay.id}\"?`, \"Models will disappear from /model.\");\n\t\t\tif (!ok) continue;\n\t\t\tawait removeRelay(relay.id);\n\t\t\tunregisterOneRelay(pi, relay.id);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Removed relay \"${relay.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * Models screen: searchable configured models plus fetch/manual-add actions.\n * Selecting a model opens its editor (name / thinking / remove).\n */\nasync function manageModelsFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tlet cursor: string | undefined;\n\twhile (true) {\n\t\tconst items: Array<{ value: string; label: string; description?: string; searchText?: string }> = [\n\t\t\t...relay.models.map((model) => {\n\t\t\t\tconst resolved = resolveModelConfig(model);\n\t\t\t\tconst label = displayModelLabel(resolved);\n\t\t\t\tconst thinking = summarizeThinkingMap(resolved.thinkingLevelMap);\n\t\t\t\tconst current = ctx.model?.provider === relay.id && ctx.model.id === model.id ? \" ✓\" : \"\";\n\t\t\t\treturn {\n\t\t\t\t\tvalue: `model:${model.id}`,\n\t\t\t\t\tlabel: `${model.id}${current}`,\n\t\t\t\t\tdescription: label !== model.id ? `${label} · ${thinking}` : thinking,\n\t\t\t\t\tsearchText: `${getModelSelectorSearchText({ id: model.id, provider: relay.id, name: resolved.name })} ${thinking}`,\n\t\t\t\t};\n\t\t\t}),\n\t\t\t{\n\t\t\t\tvalue: \"action:fetch\",\n\t\t\t\tlabel: \"Fetch catalog\",\n\t\t\t\tdescription:\n\t\t\t\t\trelay.models.length === 0\n\t\t\t\t\t\t? \"GET /models · select models\"\n\t\t\t\t\t\t: \"Refresh from server · keeps selected customizations\",\n\t\t\t\tsearchText: \"fetch catalog refresh models server\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:manual\",\n\t\t\t\tlabel: \"Add models manually\",\n\t\t\t\tdescription: \"Comma- or newline-separated model ids\",\n\t\t\t\tsearchText: \"add manual custom model ids\",\n\t\t\t},\n\t\t\t{ value: \"action:back\", label: \"Back\", description: \"Return to relay\", searchText: \"back return\" },\n\t\t];\n\n\t\tconst currentValue = `model:${ctx.model?.id}`;\n\t\tconst initialValue = cursor ?? (ctx.model?.provider === relay.id ? currentValue : undefined);\n\t\tconst choice = await selectRouterItem(dialogs, `Relay · ${relay.id} · models`, items, { initialValue });\n\t\tif (choice === undefined || choice === \"action:back\") return;\n\t\tcursor = choice;\n\n\t\tif (choice === \"action:fetch\") {\n\t\t\tawait fetchAndSelectModels(ctx, pi, dialogs, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"action:manual\") {\n\t\t\tconst additions = await manualModelEntry(ctx, dialogs);\n\t\t\tif (!additions) continue;\n\t\t\trelay.models = mergeAddedModels(relay.models, additions);\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice.startsWith(\"model:\")) {\n\t\t\tconst modelId = choice.slice(\"model:\".length);\n\t\t\tconst model = relay.models.find((entry) => entry.id === modelId);\n\t\t\tif (!model) continue;\n\t\t\tawait editModelFlow(ctx, pi, dialogs, relay, model);\n\t\t}\n\t}\n}\n\n/** Single-model editor: display name + thinking. Every confirmed change is live. */\nasync function editModelFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n\tmodel: RelayModelConfig,\n): Promise<void> {\n\twhile (true) {\n\t\tconst resolved = resolveModelConfig(model);\n\t\tconst nameDesc = resolved.name ? resolved.name : \"(empty · /model shows id)\";\n\t\tconst action = await selectRouterItem(dialogs, `Relay · ${relay.id} · ${model.id}`, [\n\t\t\t{ value: \"name\", label: \"Display name\", description: nameDesc },\n\t\t\t{\n\t\t\t\tvalue: \"thinking\",\n\t\t\t\tlabel: \"Thinking levels\",\n\t\t\t\tdescription: summarizeThinkingMap(resolved.thinkingLevelMap),\n\t\t\t},\n\t\t\t{ value: \"contextWindow\", label: \"Context window\", description: String(resolved.contextWindow) },\n\t\t\t{\n\t\t\t\tvalue: \"maxTokens\",\n\t\t\t\tlabel: \"Output tokens (local metadata, not wire cap)\",\n\t\t\t\tdescription: String(resolved.maxTokens),\n\t\t\t},\n\t\t\t{ value: \"reasoning\", label: \"Reasoning\", description: resolved.reasoning ? \"Enabled\" : \"Disabled\" },\n\t\t\t{\n\t\t\t\tvalue: \"image\",\n\t\t\t\tlabel: \"Image input\",\n\t\t\t\tdescription: resolved.input.includes(\"image\") ? \"Enabled\" : \"Disabled\",\n\t\t\t},\n\t\t\t{ value: \"codex\", label: \"Codex request settings\", description: \"Summary · verbosity · parallel tools\" },\n\t\t\t{ value: \"remove\", label: \"Remove model\", description: \"Delete this model from the relay\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to models\" },\n\t\t]);\n\t\tif (action === undefined || action === \"back\") return;\n\n\t\tif (action === \"contextWindow\" || action === \"maxTokens\") {\n\t\t\tconst next = await promptText(\n\t\t\t\tctx,\n\t\t\t\tdialogs,\n\t\t\t\taction === \"maxTokens\" ? \"Output tokens · local metadata, not wire cap\" : \"Context window\",\n\t\t\t\tString(resolved[action]),\n\t\t\t\t(value) => {\n\t\t\t\t\tconst number = Number(value);\n\t\t\t\t\tif (!Number.isSafeInteger(number) || number <= 0) return \"Use a safe positive integer.\";\n\t\t\t\t\tif (action === \"maxTokens\" ? number > resolved.contextWindow : number < resolved.maxTokens)\n\t\t\t\t\t\treturn \"Output tokens must not exceed context window.\";\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (next !== undefined) {\n\t\t\t\tmodel[action] = Number(next);\n\t\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (action === \"reasoning\" || action === \"image\") {\n\t\t\tif (action === \"reasoning\") model.reasoning = !resolved.reasoning;\n\t\t\telse model.input = resolved.input.includes(\"image\") ? [\"text\"] : [\"text\", \"image\"];\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\t\tif (action === \"codex\") {\n\t\t\tawait editCodexSettings(dialogs, model, () => persistRelay(ctx, pi, relay));\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"name\") {\n\t\t\tconst next = await promptText(\n\t\t\t\tctx,\n\t\t\t\tdialogs,\n\t\t\t\t`Display name · ${model.id} (empty = show id)`,\n\t\t\t\tresolved.name ?? \"\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tconst nextName = !trimmed || trimmed === model.id ? undefined : trimmed;\n\t\t\tconst prevName = model.name?.trim() && model.name.trim() !== model.id ? model.name.trim() : undefined;\n\t\t\tif (nextName === prevName) continue;\n\t\t\tif (nextName) model.name = nextName;\n\t\t\telse delete model.name;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"thinking\") {\n\t\t\tconst saver = new RelayAutoSaver(ctx, pi, relay);\n\t\t\tif (dialogs.kind === \"tui\") {\n\t\t\t\tawait dialogs.show(\n\t\t\t\t\tcreateThinkingMapEditor({\n\t\t\t\t\t\ttitle: `Thinking · ${relay.id} / ${model.id}`,\n\t\t\t\t\t\tmap: resolved.thinkingLevelMap,\n\t\t\t\t\t\tlevels: ROUTER_THINKING_LEVELS,\n\t\t\t\t\t\tonChange: (nextMap) => {\n\t\t\t\t\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\t\t\t\t\tsaver.save();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait editThinkingMapNative(dialogs, resolved.thinkingLevelMap, (nextMap) => {\n\t\t\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\t\t\tsaver.save();\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait saver.flush();\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"remove\") {\n\t\t\tif (isCurrentRouterModel(ctx.model, relay.id, model.id)) {\n\t\t\t\tctx.ui.notify(`Switch away from model \"${model.id}\" before removing it.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ok = await dialogs.confirm(\n\t\t\t\t`Remove model \"${model.id}\"?`,\n\t\t\t\t\"Its display name and thinking settings will be removed.\",\n\t\t\t);\n\t\t\tif (!ok) continue;\n\t\t\trelay.models = relay.models.filter((entry) => entry.id !== model.id);\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tctx.ui.notify(`Removed model \"${model.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nasync function editCodexSettings(\n\tdialogs: RouterDialogs,\n\tmodel: RelayModelConfig,\n\tsave: () => Promise<void>,\n): Promise<void> {\n\twhile (true) {\n\t\tconst field = await selectRouterItem(dialogs, \"Codex request settings\", [\n\t\t\t{ value: \"reasoningSummary\", label: \"Reasoning summary\", description: String(model.codex?.reasoningSummary) },\n\t\t\t{ value: \"verbosity\", label: \"Verbosity\", description: String(model.codex?.verbosity) },\n\t\t\t{\n\t\t\t\tvalue: \"parallelToolCalls\",\n\t\t\t\tlabel: \"Parallel tool calls\",\n\t\t\t\tdescription: String(model.codex?.parallelToolCalls),\n\t\t\t},\n\t\t]);\n\t\tif (!field) return;\n\t\tconst values =\n\t\t\tfield === \"reasoningSummary\"\n\t\t\t\t? [\"auto\", \"concise\", \"detailed\"]\n\t\t\t\t: field === \"verbosity\"\n\t\t\t\t\t? [\"low\", \"medium\", \"high\"]\n\t\t\t\t\t: [\"true\", \"false\"];\n\t\tconst choice = await selectRouterItem(dialogs, field, [\n\t\t\t{ value: \"inherit\", label: \"Inherit\" },\n\t\t\t...(field === \"parallelToolCalls\" ? [] : [{ value: \"omit\", label: \"Omit (null)\" }]),\n\t\t\t...values.map((value) => ({ value, label: value })),\n\t\t]);\n\t\tif (!choice) continue;\n\t\tmodel.codex ??= {};\n\t\tconst codex = model.codex;\n\t\tif (choice === \"inherit\") delete codex[field];\n\t\telse if (field === \"parallelToolCalls\") codex.parallelToolCalls = choice === \"true\";\n\t\telse if (field === \"reasoningSummary\")\n\t\t\tcodex.reasoningSummary = choice === \"omit\" ? null : (choice as \"auto\" | \"concise\" | \"detailed\");\n\t\telse codex.verbosity = choice === \"omit\" ? null : (choice as \"low\" | \"medium\" | \"high\");\n\t\tawait save();\n\t}\n}\n\nasync function editThinkingMapNative(\n\tdialogs: RouterDialogs,\n\tmap: RelayModelConfig[\"thinkingLevelMap\"],\n\tonChange: (map: RelayModelConfig[\"thinkingLevelMap\"]) => void,\n): Promise<void> {\n\tconst working = resolveRouterThinkingMap(map);\n\twhile (true) {\n\t\tconst choice = await selectRouterItem(dialogs, \"Edit thinking level\", [\n\t\t\t...ROUTER_THINKING_LEVELS.map((level) => ({\n\t\t\t\tvalue: level,\n\t\t\t\tlabel: level,\n\t\t\t\tdescription:\n\t\t\t\t\tworking[level] === null ? \"hidden\" : working[level] === undefined ? \"default\" : String(working[level]),\n\t\t\t})),\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Changes are live\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\t\tif (!ROUTER_THINKING_LEVELS.includes(choice as (typeof ROUTER_THINKING_LEVELS)[number])) continue;\n\t\tconst level = choice as (typeof ROUTER_THINKING_LEVELS)[number];\n\t\tconst mode = await selectRouterItem(dialogs, `${level} · mapping`, [\n\t\t\t{ value: \"inherit\", label: \"Inherit\", description: \"Pi default\" },\n\t\t\t{ value: \"target\", label: \"String target\", description: \"Provider effort\" },\n\t\t\t{ value: \"hidden\", label: \"Hidden\", description: \"null\" },\n\t\t]);\n\t\tif (mode === undefined) continue;\n\t\tif (mode === \"inherit\") delete working[level];\n\t\telse if (mode === \"hidden\") working[level] = null;\n\t\telse {\n\t\t\tconst target = await dialogs.input(`${level} · provider effort`, working[level] ?? level);\n\t\t\tif (!target?.trim()) continue;\n\t\t\tworking[level] = target.trim();\n\t\t}\n\t\tonChange({ ...working });\n\t}\n}\n\nasync function fetchAndSelectModels(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tconst connection = await resolveProbeConnection(relay, ctx);\n\tif (connection.error) {\n\t\tctx.ui.notify(connection.error, \"warning\");\n\t\tawait recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\treturn;\n\t}\n\n\tlet result: Awaited<ReturnType<typeof probeRelayModels>> | undefined;\n\twhile (true) {\n\t\tconst probeOptions = {\n\t\t\tbaseUrl: relay.baseUrl,\n\t\t\tapiKey: connection.apiKey,\n\t\t\theaders: connection.headers,\n\t\t\tcatalog: relay.catalog,\n\t\t};\n\t\tif (dialogs.kind === \"tui\") {\n\t\t\tresult = await dialogs.show<Awaited<ReturnType<typeof probeRelayModels>> | undefined>(\n\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\tconst loader = new RouterProbeLoader(tui, theme, `Fetching models · ${relay.id}`);\n\t\t\t\t\tlet settled = false;\n\t\t\t\t\tconst finish = (value: Awaited<ReturnType<typeof probeRelayModels>> | undefined) => {\n\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tloader.dispose();\n\t\t\t\t\t\tdone(value);\n\t\t\t\t\t};\n\t\t\t\t\tloader.onAbort = () => finish(undefined);\n\t\t\t\t\tvoid probeRelayModels({ ...probeOptions, signal: loader.probeSignal })\n\t\t\t\t\t\t.then(finish)\n\t\t\t\t\t\t.catch((error) => finish({ ok: false, error: formatError(error) }));\n\t\t\t\t\treturn loader;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tctx.ui.notify(`Fetching models from ${relay.baseUrl}…`, \"info\");\n\t\t\tresult = await probeRelayModels(probeOptions);\n\t\t}\n\n\t\tif (result === undefined) return;\n\t\tif (result.ok && result.models.length === 0) {\n\t\t\tctx.ui.notify(\"Server returned an empty model list.\", \"warning\");\n\t\t\tconst recovery = await selectRouterItem(dialogs, `Catalog empty · ${relay.id}`, [\n\t\t\t\t{ value: \"retry\", label: \"Retry\", description: \"Fetch /models again\" },\n\t\t\t\t{ value: \"manual\", label: \"Add models manually\", description: \"Enter model ids without a catalog\" },\n\t\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relay settings\" },\n\t\t\t]);\n\t\t\tif (recovery === \"retry\") continue;\n\t\t\tif (recovery === \"manual\") await recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\t\treturn;\n\t\t}\n\t\tif (result.ok) break;\n\n\t\tctx.ui.notify(`Fetch failed: ${result.error}`, \"error\");\n\t\tconst recovery = await selectRouterItem(dialogs, `Catalog unavailable · ${relay.id}`, [\n\t\t\t{ value: \"retry\", label: \"Retry\", description: \"Fetch /models again\" },\n\t\t\t{ value: \"manual\", label: \"Add models manually\", description: \"Enter model ids without a catalog\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relay settings\" },\n\t\t]);\n\t\tif (recovery === \"retry\") continue;\n\t\tif (recovery === \"manual\") await recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\treturn;\n\t}\n\n\tif (!result || !result.ok) return;\n\tif (result.truncated) ctx.ui.notify(\"Catalog truncated to 2,000 models.\", \"warning\");\n\n\tconst discovered = new Map(result.models.map((model) => [model.id, model]));\n\tconst activeModelId = ctx.model?.provider === relay.id ? ctx.model.id : undefined;\n\tconst catalog = mergeCatalogWithConfigured(relay.models, result.models, activeModelId);\n\tconst initiallySelected = new Set(relay.models.map((model) => model.id));\n\tif (activeModelId) initiallySelected.add(activeModelId);\n\tconst currentModelId = activeModelId;\n\tconst protectedIds = currentModelId ? new Set([currentModelId]) : undefined;\n\tconst preserved = new Map(relay.models.map((model) => [model.id, structuredClone(model)]));\n\tif (activeModelId && !preserved.has(activeModelId)) {\n\t\tpreserved.set(activeModelId, createDefaultModelConfig(activeModelId));\n\t}\n\tconst saver = new RelayAutoSaver(ctx, pi, relay);\n\tconst applySelection = (selectedIds: string[]) => {\n\t\tif (currentModelId && !selectedIds.includes(currentModelId)) {\n\t\t\tctx.ui.notify(`Switch away from model \"${currentModelId}\" before disabling it.`, \"warning\");\n\t\t\treturn;\n\t\t}\n\t\trelay.models = selectedIds.map((id) => {\n\t\t\tconst previous = preserved.get(id);\n\t\t\tif (previous) return structuredClone(previous);\n\t\t\tconst next = modelFromCatalog(discovered.get(id) ?? { id });\n\t\t\tpreserved.set(id, next);\n\t\t\treturn structuredClone(next);\n\t\t});\n\t\tsaver.save();\n\t};\n\n\tif (dialogs.kind === \"tui\") {\n\t\tconst choice = await dialogs.show(\n\t\t\tcreateModelChecklist({\n\t\t\t\ttitle: `Select models · ${relay.id}`,\n\t\t\t\tsubtitle: \"Space toggles immediately · Enter/Esc returns\",\n\t\t\t\tmodels: catalog,\n\t\t\t\tinitiallySelected,\n\t\t\t\tprotectedIds,\n\t\t\t\tonChange: applySelection,\n\t\t\t\tonProtectedToggle: (id) => ctx.ui.notify(`Switch away from model \"${id}\" before disabling it.`, \"warning\"),\n\t\t\t}),\n\t\t);\n\t\tif (choice.kind === \"close\") applySelectionIfChanged(relay, choice.selectedIds, applySelection);\n\t} else {\n\t\tconst ok = await dialogs.confirm(\n\t\t\t`Import ${result.models.length} models?`,\n\t\t\t\"Non-TUI mode imports the full catalog.\",\n\t\t);\n\t\tif (ok) applySelection([...new Set([...initiallySelected, ...result.models.map((model) => model.id)])]);\n\t}\n\tawait saver.flush();\n\tif (relay.models.length === 0) ctx.ui.notify(`No models enabled for \"${relay.id}\".`, \"warning\");\n}\n\nexport function modelFromCatalog(entry: ProbeModel): RelayModelConfig {\n\tconst model: RelayModelConfig = { ...createDefaultModelConfig(entry.id, entry.name), ...entry.metadata };\n\tmodel.maxTokens = Math.min(model.maxTokens!, model.contextWindow!);\n\treturn model;\n}\n\nasync function resolveProbeConnection(\n\trelay: RelayConfig,\n\tctx: ExtensionCommandContext,\n): Promise<{ apiKey?: string; headers?: ProviderHeaders; error?: string }> {\n\ttry {\n\t\t// Registered relays use Pi's canonical credential precedence and dynamic resolution.\n\t\t// A new, empty relay is not registered yet: use the bounded literal/env fallback below.\n\t\tconst resolved = relay.models.length > 0 ? await ctx.modelRegistry.getProviderAuth?.(relay.id) : undefined;\n\t\tconst key = resolved?.auth.apiKey ? { value: resolved.auth.apiKey } : resolveProbeApiKey(relay.apiKey);\n\t\tif (key.error) return { error: key.error };\n\t\tconst headers: ProviderHeaders = { ...resolved?.auth.headers };\n\t\tfor (const [name, raw] of Object.entries(relay.headers ?? {})) {\n\t\t\tif (Object.keys(headers).some((key) => key.toLowerCase() === name.toLowerCase())) continue;\n\t\t\tconst value = resolveProbeApiKey(raw);\n\t\t\tif (value.error)\n\t\t\t\treturn {\n\t\t\t\t\terror: `Cannot resolve catalog header ${name}. Configure a model first for Pi's dynamic auth resolution.`,\n\t\t\t\t};\n\t\t\theaders[name] = value.value ?? \"\";\n\t\t}\n\t\treturn { apiKey: key.value, headers };\n\t} catch {\n\t\treturn {\n\t\t\terror: \"Cannot resolve relay credentials for catalog discovery. Check provider authentication and configured values.\",\n\t\t};\n\t}\n}\n\nasync function manualModelEntry(\n\tctx: ExtensionCommandContext,\n\tdialogs: RouterDialogs,\n): Promise<RelayModelConfig[] | undefined> {\n\tconst value = await dialogs.input(\"Model IDs (comma-separated)\", \"gpt-5.6-sol, gpt-5.6-luna\");\n\tif (value === undefined) return undefined;\n\tconst ids = [\n\t\t...new Set(\n\t\t\tvalue\n\t\t\t\t.split(/[,\\r\\n]+/)\n\t\t\t\t.map((id) => id.trim())\n\t\t\t\t.filter(Boolean),\n\t\t),\n\t];\n\tif (ids.length === 0) {\n\t\tctx.ui.notify(\"Enter at least one model id.\", \"warning\");\n\t\treturn undefined;\n\t}\n\treturn ids.map((id) => createDefaultModelConfig(id));\n}\n\nasync function recoverWithManualModels(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tconst additions = await manualModelEntry(ctx, dialogs);\n\tif (!additions) return;\n\trelay.models = mergeAddedModels(relay.models, additions);\n\tawait persistRelay(ctx, pi, relay);\n}\n\nfunction mergeAddedModels(previous: RelayModelConfig[], additions: RelayModelConfig[]): RelayModelConfig[] {\n\tconst result = previous.map((model) => structuredClone(model));\n\tconst ids = new Set(result.map((model) => model.id));\n\tfor (const model of additions) {\n\t\tif (ids.has(model.id)) continue;\n\t\tids.add(model.id);\n\t\tresult.push(model);\n\t}\n\treturn result;\n}\n\nexport function mergeCatalogWithConfigured(\n\tconfigured: ReadonlyArray<RelayModelConfig>,\n\tcatalog: ReadonlyArray<{ id: string; name?: string }>,\n\tactiveModelId?: string,\n): ModelChecklistItem[] {\n\tconst items = new Map<string, ModelChecklistItem>();\n\tconst configuredById = new Map(configured.map((model) => [model.id, model]));\n\tfor (const model of catalog) {\n\t\tconst previous = configuredById.get(model.id);\n\t\titems.set(model.id, {\n\t\t\tid: model.id,\n\t\t\tname: previous?.name ?? model.name,\n\t\t});\n\t}\n\tfor (const model of configured) {\n\t\tif (!items.has(model.id)) {\n\t\t\titems.set(model.id, {\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name ?? model.id,\n\t\t\t\tunavailable: true,\n\t\t\t});\n\t\t}\n\t}\n\tif (activeModelId && !items.has(activeModelId)) {\n\t\titems.set(activeModelId, { id: activeModelId, name: activeModelId, unavailable: true });\n\t}\n\treturn [...items.values()].sort((left, right) => left.id.localeCompare(right.id));\n}\n\nfunction applySelectionIfChanged(\n\trelay: RelayConfig,\n\tselectedIds: ReadonlyArray<string>,\n\tapply: (ids: string[]) => void,\n): void {\n\tconst current = new Set(relay.models.map((model) => model.id));\n\tif (current.size === selectedIds.length && selectedIds.every((id) => current.has(id))) return;\n\tapply([...selectedIds]);\n}\n\nasync function persistRelay(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig): Promise<void> {\n\tawait initializeRouterState(pi);\n\tawait upsertRelay(relay);\n\tregisterOneRelay(pi, relay);\n\tawait ctx.modelRegistry.refresh();\n}\n\nasync function promptText(\n\tctx: ExtensionCommandContext,\n\tdialogs: RouterDialogs,\n\ttitle: string,\n\tplaceholder: string,\n\tvalidate?: (value: string) => string | undefined,\n): Promise<string | undefined> {\n\twhile (true) {\n\t\tconst value = await dialogs.input(title, placeholder);\n\t\tif (value === undefined) return undefined;\n\t\tconst error = validate?.(value);\n\t\tif (error) {\n\t\t\tctx.ui.notify(error, \"warning\");\n\t\t\tcontinue;\n\t\t}\n\t\treturn value;\n\t}\n}\n\nasync function selectRouterItem<T extends string>(\n\tdialogs: RouterDialogs,\n\ttitle: string,\n\titems: ReadonlyArray<{ value: T; label: string; description?: string; searchText?: string }>,\n\topts?: { initialValue?: T; initialQuery?: string; maxVisible?: number },\n): Promise<T | undefined> {\n\tif (dialogs.kind === \"tui\") {\n\t\treturn dialogs.show(\n\t\t\tcreateSearchableSelector({\n\t\t\t\ttitle,\n\t\t\t\titems,\n\t\t\t\tinitialValue: opts?.initialValue,\n\t\t\t\tinitialQuery: opts?.initialQuery,\n\t\t\t\tmaxVisible: opts?.maxVisible ?? Math.min(10, Math.max(1, items.length)),\n\t\t\t}),\n\t\t);\n\t}\n\tconst labels = items.map((item) => (item.description ? `${item.label} — ${item.description}` : item.label));\n\tconst selected = await dialogs.select(title, labels);\n\tif (selected === undefined) return undefined;\n\treturn items[labels.indexOf(selected)]?.value;\n}\n\nfunction maskKey(key: string): string {\n\tif (key.startsWith(\"$\") || key.startsWith(\"!\")) return key;\n\tif (key.length <= 8) return \"••••\";\n\treturn `${key.slice(0, 4)}…${key.slice(-4)}`;\n}\n\n/** Resolve only keys that can be safely used by the catalog probe. */\nexport function resolveProbeApiKey(apiKey: string): { value?: string; error?: string } {\n\tconst trimmed = apiKey.trim();\n\tif (!trimmed) return {};\n\tif (trimmed.startsWith(\"!\")) {\n\t\treturn { error: \"This API key uses a !command and cannot be resolved for catalog probing.\" };\n\t}\n\tconst envOnly = trimmed.match(/^\\$([A-Za-z_][A-Za-z0-9_]*)$/);\n\tconst braced = trimmed.match(/^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/);\n\tconst envName = envOnly?.[1] ?? braced?.[1];\n\tif (envName) {\n\t\tconst value = process.env[envName]?.trim();\n\t\treturn value ? { value } : { error: `Environment variable $${envName} is not set.` };\n\t}\n\tif (trimmed.includes(\"$\")) {\n\t\treturn { error: \"This API key contains interpolation and cannot be resolved for catalog probing.\" };\n\t}\n\treturn { value: trimmed };\n}\n"]}
@@ -1,197 +0,0 @@
1
- # `router` — Codex-style API relays
2
-
3
- `/router` connects Pi to OpenAI-compatible API relays — self-hosted gateways such as sub2api, CPA, or codex2api, and similar proxies — using a **Codex-shaped normal API-key Responses/SSE profile pinned to Codex 0.153.4**. This is a scoped request adaptation, not the full Codex client or a guarantee that a gateway cannot distinguish it from Codex.
4
-
5
- Configuration lives at `~/.pi/agent/router.json`. A separate `~/.pi/agent/router-client.json` persists a non-secret installation identity when `/router` is opened or configured relays load. These paths follow Pi's agent directory when overridden.
6
-
7
- Providers register at extension load through `pi.registerProvider` (config form + `streamSimple`), not through `models.json`. Following Pi's [custom-provider path](../../custom-provider.md) and [provider documentation](../../providers.md), the router wraps the public `openAIResponsesApi()` from `@earendil-works/pi-ai/compat`. **The published pi-ai adapter still owns message conversion, Responses streaming, SSE parsing, usage, and tool-call events.**
8
-
9
- ---
10
-
11
- ## Usage
12
-
13
- ```text
14
- /router Browse relays
15
- /router add Add a relay
16
- /router reload Re-register from disk
17
- /router <id> Open a relay
18
- ```
19
-
20
- ### UI map
21
-
22
- ```text
23
- API relays ← relays first; add / reload at bottom
24
- └─ Relay · {id} ← models · URL · key · catalog · provider name · remove
25
- └─ Models ← searchable model list + fetch / manual add
26
- └─ {model id} ← name · thinking map · context/output metadata
27
- reasoning · image input · Codex settings · remove
28
- ```
29
-
30
- Edits **auto-save** to `router.json` and re-register the provider. Text fields save when confirmed; catalog selections and completed thinking-map edits save immediately. There is no Save or Apply step, and Back never discards a completed change. `/router reload` applies a complete router header snapshot: deleting a relay's `headers` field (or setting it to `{}`) clears its previously registered router headers, including custom Authorization. Independently configured model headers and other Pi configuration layers still follow normal provider composition.
31
-
32
- TUI model search follows Pi's `/model` behavior: the search field is always visible, typing fuzzy-filters results, arrows wrap, Enter opens the highlighted item, and Esc goes back. Catalog checkboxes use Space to toggle live; Enter or Esc returns to the model list. The active model and its provider cannot be disabled or removed; switch with `/model` first. Interactive `/router` requires `ctx.hasUI`; without it, the command warns and does not open. In a UI host without the TUI checklist, catalog import instead asks to import the full catalog.
33
-
34
- ### Add flow and discovery
35
-
36
- 1. **Name** — provider id, such as `my-relay`; appears as `my-relay/gpt-5.6-sol` in `/model`.
37
- 2. **Base URL** — usually ends with `/v1`; requests append `/responses` or `/models`. Use HTTP(S) without embedded credentials or a fragment. Existing query parameters are preserved.
38
- 3. **API key** — for example, a literal `sk-…` or `$RELAY_KEY`.
39
- 4. The connection is saved immediately, before discovery. A failed or cancelled fetch does not lose it.
40
- 5. **Fetch models**, then select models; retry or enter model ids manually if discovery fails.
41
-
42
- The relay's **Catalog format** selects:
43
-
44
- | Format | Request | Expected JSON |
45
- |---|---|---|
46
- | `openai` (default) | `GET {baseUrl}/models` | `{ "data": [{ "id": "…", "name": "…" }] }` (`name` optional) |
47
- | `codex` | `GET {baseUrl}/models?client_version=0.153.4` | `{ "models": [{ "slug": "…", "display_name": "…" }] }` plus optional Codex metadata |
48
-
49
- Codex discovery replaces any existing `client_version` parameter while keeping unrelated parameters. Both formats request JSON with the Codex identity headers and a default Bearer key. Resolved custom Authorization headers override that default, including explicit runtime `null` removal. Successful bodies are bounded to 4 MiB, non-OK text is read up to 4 KiB and displayed up to 400 characters, discovery times out after 10 seconds, and the sorted, deduplicated list is limited to 2,000 models.
50
-
51
- For registered relays with models, discovery uses Pi's canonical provider-auth resolution, including resolved auth headers. A new empty relay is not registered yet: its fallback accepts only literal values, `$ENV_VAR`, or `${ENV_VAR}`. Unset variables, `!command` values, and mixed interpolation are not sent unresolved or anonymously. **Add a model manually first** to enable Pi's dynamic auth resolution, then fetch again. The same limited fallback applies to unresolved relay headers.
52
-
53
- Fetching does **not overwrite existing selected model configurations**. Configured models missing from the catalog remain listed as unavailable. Codex metadata is imported only for newly selected models: display name, context bounded by `max_context_window`, supported effort mappings (`none` maps to Pi `off`), reasoning capability, text/image input, and supported summary/verbosity defaults. `max_context_window` is not an output limit: importing metadata caps the local default output count to the resulting context window instead.
54
-
55
- ### New-model defaults and customization
56
-
57
- Manual additions and OpenAI catalog entries start with these defaults; Codex catalog metadata can refine them:
58
-
59
- | Field | Default |
60
- |---|---|
61
- | `name` | Omitted unless a custom/catalog label exists; `/model` otherwise shows the id |
62
- | `reasoning` | `true` |
63
- | `input` | `text` + `image` |
64
- | `contextWindow` | 272000 |
65
- | `maxTokens` | 128000 (local metadata only) |
66
- | `thinkingLevelMap` | `low`, `medium`, `high` mapped to themselves; `off`, `minimal`, `xhigh`, `max` set to `null` |
67
-
68
- Relay → **Models** → model lets you edit:
69
-
70
- - **Display name** — leave empty to show the id.
71
- - **Thinking levels** — all seven Pi levels (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`). Each can inherit Pi behavior (omit the key), map to an arbitrary non-empty provider effort string, or be hidden (`null`).
72
- - **Context window / Output tokens** — safe positive integer metadata, with explicit output no greater than context. An omitted output value is capped to the context window when defaults are resolved, so existing partial small-context entries remain valid. **`maxTokens` is local Pi metadata, not a server generation cap: the router removes `max_output_tokens` from the request.**
73
- - **Reasoning / Image input** — capability toggles; these do not discover server support.
74
- - **Codex request settings** — reasoning summary, verbosity, and parallel tool calls, as described below.
75
- - **Remove model** — confirmation required; switch away from the active model first.
76
-
77
- ---
78
-
79
- ## Config shape
80
-
81
- The format remains **version 1**, with additive optional fields. The file is strict JSON; unsupported fields are rejected. `api` is **not** a config field: provider and model registration automatically use `openai-responses`.
82
-
83
- ```json
84
- {
85
- "version": 1,
86
- "relays": [
87
- {
88
- "id": "my-relay",
89
- "name": "My relay",
90
- "baseUrl": "https://relay.example/v1",
91
- "apiKey": "$RELAY_KEY",
92
- "catalog": "openai",
93
- "headers": { "X-Relay-Tenant": "example" },
94
- "models": [
95
- {
96
- "id": "gpt-5.6-sol",
97
- "reasoning": true,
98
- "input": ["text", "image"],
99
- "contextWindow": 272000,
100
- "maxTokens": 128000,
101
- "thinkingLevelMap": {
102
- "off": null,
103
- "minimal": null,
104
- "low": "low",
105
- "medium": "medium",
106
- "high": "high",
107
- "xhigh": null,
108
- "max": null
109
- },
110
- "codex": {
111
- "reasoningSummary": "auto",
112
- "verbosity": null,
113
- "parallelToolCalls": true
114
- },
115
- "headers": { "X-Relay-Route": "standard" },
116
- "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
117
- }
118
- ]
119
- }
120
- ]
121
- }
122
- ```
123
-
124
- Relay `name`, `headers`, and `catalog` are optional. Model `name`, `headers`, `cost`, and `codex` are optional alongside the existing capability and thinking fields. Config headers have string values; nullable header removals are available through Pi's runtime header hooks/options, not this JSON schema. Cost defaults to zero for all four Pi cost categories (rates per million tokens); it is accounting metadata, not a relay pricing lookup. Headers and cost can be edited in the file; the UI does not expose editors for them.
125
-
126
- For header-only Bearer authentication, set `"apiKey": ""` and configure `headers.Authorization` in the file, for example `"Authorization": "Bearer $RELAY_KEY"` for a registered relay. Both catalog discovery and Responses requests accept resolved Authorization without a duplicate API key; the new/empty-relay discovery fallback still has the limited value-resolution rules above. When an API key and custom Authorization are both present, the header wins. Credential validation belongs to the public Responses adapter; missing credentials still fail without sending a Responses request, and runtime `null` header removals are not restored.
127
-
128
- | `codex` field | Supported values | When omitted |
129
- |---|---|---|
130
- | `reasoningSummary` | `"auto"`, `"concise"`, `"detailed"`, `null` | `auto` for reasoning models; otherwise omitted from the wire |
131
- | `verbosity` | `"low"`, `"medium"`, `"high"`, `null` | Omitted from the wire |
132
- | `parallelToolCalls` | `true`, `false` | `true` |
133
-
134
- For summary and verbosity, `null` explicitly omits the wire field. UI **Inherit** removes the setting and uses these defaults. Support comes from catalog metadata or explicit settings, not a guess based on the model id.
135
-
136
- There is no migration from older models-manager configs, and Pi updates do not overwrite `router.json`. **Behavior change:** explicit existing thinking maps, including `off` and `minimal`, are now preserved. Omitted maps/entries follow Pi's semantics instead of the old router behavior that forced five enabled levels and ignored `off`/`minimal`. In particular, omitted `xhigh`/`max` are not enabled by the router. The conservative three-level map above applies only to newly created models; existing maps are not rewritten.
137
-
138
- An empty model list means the provider is not registered and has no entries in `/model`.
139
-
140
- ## Request profile and lifecycle
141
-
142
- ### Identity and headers
143
-
144
- The default originator is `codex_cli_rs`. The source-derived user-agent format is:
145
-
146
- ```text
147
- codex_cli_rs/0.153.4 ({OS type} {OS version}; {architecture}) {terminal[/version]}
148
- ```
149
-
150
- OS and terminal identity are **approximations**, not a copy of Codex's entire detection stack. Windows uses Node's OS release and normalized architecture; macOS uses `sw_vers` when available; Linux covers common `/etc/os-release` distributions, not the complete Rust `os_info` fallback matrix. Terminal detection uses environment variables and sanitizes the resulting token. In particular, it does not query tmux's underlying client or spawn zellij.
151
-
152
- Defaults include `Accept: text/event-stream` and `Content-Type: application/json`. A final provider-scoped fetch boundary removes all `x-stainless-*`, `x-pi-*`, `x-session-affinity`, and underscore `session_id` headers after SDK assembly. Unrelated OpenAI SDK process defaults (`OPENAI_ORG_ID`, `OPENAI_PROJECT_ID`, and header names in `OPENAI_CUSTOM_HEADERS`) are suppressed unless explicitly configured for the relay. It does not restore removed/null user-agent, originator, content-type, or Accept defaults. Custom values supplied through Pi headers/options are otherwise respected, except that a present Accept on a Responses POST is normalized to `text/event-stream`; catalog GETs explicitly use `application/json`.
153
-
154
- ### Installation, session, and user-task state
155
-
156
- - `router-client.json` contains `{ "version": 1, "installationId": "…" }`. The UUID persists across extension reloads/processes and is not a credential. Initialization reads and creates it under a dedicated cross-process lock, waits up to about five seconds on contention, and publishes complete JSON from a same-directory temporary file. Concurrent initializers reuse the winning identity rather than reading a half-written file. An invalid existing identity file or an unresolved lock error produces a load error rather than silently replacing the identity; retry `/router reload` after resolving the error.
157
- - A window UUID lives for one extension runtime, not one HTTP request. A full extension `/reload` creates a new window identity; `/router reload` re-registers providers and clears turn state without recreating the runtime.
158
- - Pi's supplied session identity is used for both session and thread, and for `prompt_cache_key`. Nonempty printable ASCII ids up to **64 characters** without surrounding spaces are preserved. Longer or unsafe/non-ASCII ids (including surrounding spaces that HTTP headers would trim) become a stable SHA-256 hexadecimal digest across headers, client metadata, and the cache key; absent ids receive a fresh UUID. This changes the wire/cache identity of previously unbounded 65–256-character ids, but not persisted Pi sessions or normal UUID session ids. Long ids are hashed rather than truncated so shared prefixes do not collapse distinct sessions. Nested callers need their own session id.
159
- - Headers include `session-id`, `thread-id`, `x-client-request-id` (thread id), `x-codex-window-id`, and JSON `x-codex-turn-metadata`. Body `client_metadata` carries installation, session, thread, window, and user-task turn identifiers and turn-start time.
160
- - Turn scope is keyed by session, provider, base URL, model, and latest user message. A tool-loop continuation keeps the same turn id/start time. The first valid successful response `x-codex-turn-state` token is retained and sent on subsequent requests in that scope; tokens are opaque, printable, bounded to 8 KiB, and never persisted.
161
- - User-task start, session navigation/start (including `/tree`), model selection, shutdown, and provider re-registration clear turn scopes. This is not a fresh turn for each Pi tool-loop iteration.
162
-
163
- ### Payload and replay
164
-
165
- The router moves only the leading system/developer prompt to `instructions`; later developer messages stay ordered in input. It sets `store: false`, `stream: true`, `tools` (empty if absent), `tool_choice: "auto"`, configured parallel tools, `include: ["reasoning.encrypted_content"]`, the cache key, and client metadata. Summary follows the table above; adapter-provided effort mappings remain intact, with `persistent` translated to `disabled`. Verbosity is sent only when configured.
166
-
167
- Ordinary function tools explicitly send **`strict: false`**, matching Codex rather than relying on the Responses API's automatic strict-schema normalization when the field is omitted. The router enables the public adapter's strict-tool compatibility; pi-ai still owns schema serialization and preserves optional/nested parameters for ordinary tools. Explicit Pi JSON-schema constrained-sampling tools can still request `strict: true`, and user payload hooks may override the shaped tools. Those are deliberate customizations beyond the ordinary Codex tool profile.
168
-
169
- Normal Codex DTO exclusions are removed: `prompt_cache_retention`, `prompt_cache_options`, `max_output_tokens`, `temperature`, `top_p`, `user`, `metadata`, `truncation`, `context_management`, `safety_identifier`, and `stream_options`.
170
-
171
- Replay follows the 0.153.4 prefixed item-id rule, **not the old blanket removal of optional ids**: recognized item variants retain string ids with non-empty text on both sides of the first underscore; malformed unprefixed ids are omitted. Required semantic references such as `item_reference.id`, stable tool `call_id` joins, and encrypted reasoning content remain intact. Status fields on selected replay variants and output-text annotations are removed. Pi-ai still owns conversion, and switching model/provider can trigger its stricter tool-call normalization; the router does not work around that.
172
-
173
- ### HTTP retries versus Pi agent behavior
174
-
175
- The scoped HTTP transport defaults to **four retries** after the initial attempt for HTTP 5xx and recognized network errors, with 200 ms exponential backoff and 0.9–1.1 jitter. It does **not** retry HTTP 429. Caller `maxRetries` and `maxRetryDelayMs` options can alter this policy; aborts and non-replayable streaming request bodies are not retried. The adapter's own HTTP retry layer is disabled (`maxRetries: 0`) to avoid stacking policies. Successful response bodies/SSE remain with pi-ai.
176
-
177
- This is only the HTTP policy. **Outer Pi agent retries, tool execution, context management, and compaction remain Pi behavior**, not Codex stream recovery or the full Codex agent loop.
178
-
179
- ## Supported scope and remaining limits
180
-
181
- - Supported target: normal **API-key-authenticated Responses POSTs over SSE**, plus OpenAI/Codex catalog GETs. Auth remains Bearer API key and the endpoint is `{baseUrl}/responses`, not automatically the ChatGPT OAuth `/codex/responses` endpoint. No `OpenAI-Beta` default is added.
182
- - No Codex account identity, ChatGPT account headers, attestation, credential reading, WebSocket transport, zstd request compression, Responses Lite, or remote-compaction clone is implemented.
183
- - HTTP/TLS fingerprinting, complete Rust OS/terminal detection, Codex prompts/tools, and complete agent/retry behavior are outside this profile. Matching headers and selected payload fields does not make Pi indistinguishable from the official binary.
184
- - User `before_provider_request` hooks run after shaping and may replace/override the payload. `before_provider_headers` hooks and custom stream options can alter header values or behavior, subject to the final cleanup above. Such customizations affect fidelity to this documented profile.
185
- - Local HTTP receiver tests cover headers/payloads, multi-turn tools and encrypted reasoning, hooks, cancellation, and related state/transport/catalog/configuration behavior. A real Windows ConPTY check exercised model edits, `/reload`, `/tree`, and pending/settled/collapsed/expanded tool presentation with a synthetic loopback provider. **Official binary downloads from GitHub and npm timed out, and no target gateway has been verified.** This is source-guided adaptation with local coverage, not a successful official-binary differential capture or a claim of perfect relay compatibility.
186
-
187
- ### Pinned upstream sources
188
-
189
- The reference is the released **`rust-v0.153.4`**, commit **`3d2ee51ca2d5db578f328aa75e20aa22c0197c9a`**, not `main` or a moving latest-version URL:
190
-
191
- - [Codex 0.153.4 release](https://github.com/openai/codex/releases/tag/rust-v0.153.4)
192
- - [Commit-pinned source tree](https://github.com/openai/codex/tree/3d2ee51ca2d5db578f328aa75e20aa22c0197c9a/codex-rs) — client identity, Responses request/response types, terminal detection, and model catalog behavior.
193
- - [Function tool serialization](https://github.com/openai/codex/blob/3d2ee51ca2d5db578f328aa75e20aa22c0197c9a/codex-rs/tools/src/responses_api.rs) — explicit non-strict tool definitions.
194
- - [HTTP retry implementation](https://github.com/openai/codex/blob/3d2ee51ca2d5db578f328aa75e20aa22c0197c9a/codex-rs/codex-client/src/retry.rs)
195
- - [Provider defaults](https://github.com/openai/codex/blob/3d2ee51ca2d5db578f328aa75e20aa22c0197c9a/codex-rs/model-provider-info/src/lib.rs)
196
-
197
- These release-pinned references define the intended supported profile; the limits above describe where this implementation does not reproduce the upstream client.