yepanywhere 0.6.0 → 0.6.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 (225) hide show
  1. package/bundled/@yep-anywhere/shared/dist/app-types.d.ts +25 -0
  2. package/bundled/@yep-anywhere/shared/dist/app-types.d.ts.map +1 -1
  3. package/bundled/@yep-anywhere/shared/dist/app-types.js.map +1 -1
  4. package/bundled/@yep-anywhere/shared/dist/codex-schema/session.d.ts +179 -14
  5. package/bundled/@yep-anywhere/shared/dist/codex-schema/session.d.ts.map +1 -1
  6. package/bundled/@yep-anywhere/shared/dist/codex-schema/session.js +89 -0
  7. package/bundled/@yep-anywhere/shared/dist/codex-schema/session.js.map +1 -1
  8. package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.d.ts +25 -0
  9. package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.d.ts.map +1 -0
  10. package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.js +52 -0
  11. package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.js.map +1 -0
  12. package/bundled/@yep-anywhere/shared/dist/codex-web-run.d.ts +46 -0
  13. package/bundled/@yep-anywhere/shared/dist/codex-web-run.d.ts.map +1 -0
  14. package/bundled/@yep-anywhere/shared/dist/codex-web-run.js +14 -0
  15. package/bundled/@yep-anywhere/shared/dist/codex-web-run.js.map +1 -0
  16. package/bundled/@yep-anywhere/shared/dist/git-status.d.ts +29 -6
  17. package/bundled/@yep-anywhere/shared/dist/git-status.d.ts.map +1 -1
  18. package/bundled/@yep-anywhere/shared/dist/git-status.js +1 -6
  19. package/bundled/@yep-anywhere/shared/dist/git-status.js.map +1 -1
  20. package/bundled/@yep-anywhere/shared/dist/index.d.ts +7 -2
  21. package/bundled/@yep-anywhere/shared/dist/index.d.ts.map +1 -1
  22. package/bundled/@yep-anywhere/shared/dist/index.js +2 -0
  23. package/bundled/@yep-anywhere/shared/dist/index.js.map +1 -1
  24. package/bundled/@yep-anywhere/shared/dist/server-capabilities.d.ts +248 -0
  25. package/bundled/@yep-anywhere/shared/dist/server-capabilities.d.ts.map +1 -0
  26. package/bundled/@yep-anywhere/shared/dist/server-capabilities.js +251 -0
  27. package/bundled/@yep-anywhere/shared/dist/server-capabilities.js.map +1 -0
  28. package/bundled/@yep-anywhere/shared/dist/tool-display-actions.d.ts +26 -0
  29. package/bundled/@yep-anywhere/shared/dist/tool-display-actions.d.ts.map +1 -0
  30. package/bundled/@yep-anywhere/shared/dist/tool-display-actions.js +9 -0
  31. package/bundled/@yep-anywhere/shared/dist/tool-display-actions.js.map +1 -0
  32. package/bundled/@yep-anywhere/shared/package.json +1 -1
  33. package/client-dist/assets/de-BNhVdIq4.js +6 -0
  34. package/client-dist/assets/es-Csn9n24J.js +6 -0
  35. package/client-dist/assets/fr-DKx4tSpo.js +6 -0
  36. package/client-dist/assets/index-1y2h7U7U.js +582 -0
  37. package/client-dist/assets/index-Cn_ZDP6u.css +1 -0
  38. package/client-dist/assets/ja-DAkhkwQZ.js +6 -0
  39. package/client-dist/assets/zh-CN-B7lY0cc6.js +6 -0
  40. package/client-dist/index.html +2 -2
  41. package/dist/app.d.ts.map +1 -1
  42. package/dist/app.js.map +1 -1
  43. package/dist/codex/codeModeExec.d.ts +30 -0
  44. package/dist/codex/codeModeExec.d.ts.map +1 -0
  45. package/dist/codex/codeModeExec.js +419 -0
  46. package/dist/codex/codeModeExec.js.map +1 -0
  47. package/dist/codex/displayActions.d.ts +48 -0
  48. package/dist/codex/displayActions.d.ts.map +1 -0
  49. package/dist/codex/displayActions.js +674 -0
  50. package/dist/codex/displayActions.js.map +1 -0
  51. package/dist/codex/normalization.d.ts +10 -7
  52. package/dist/codex/normalization.d.ts.map +1 -1
  53. package/dist/codex/normalization.js +179 -502
  54. package/dist/codex/normalization.js.map +1 -1
  55. package/dist/codex/webRun.d.ts +42 -0
  56. package/dist/codex/webRun.d.ts.map +1 -0
  57. package/dist/codex/webRun.js +199 -0
  58. package/dist/codex/webRun.js.map +1 -0
  59. package/dist/indexes/SessionIndexService.d.ts +1 -1
  60. package/dist/indexes/SessionIndexService.d.ts.map +1 -1
  61. package/dist/indexes/SessionIndexService.js +16 -4
  62. package/dist/indexes/SessionIndexService.js.map +1 -1
  63. package/dist/routes/git-status.d.ts.map +1 -1
  64. package/dist/routes/git-status.js +70 -0
  65. package/dist/routes/git-status.js.map +1 -1
  66. package/dist/routes/project-queue.d.ts.map +1 -1
  67. package/dist/routes/project-queue.js.map +1 -1
  68. package/dist/routes/public-shares.d.ts +1 -1
  69. package/dist/routes/public-shares.d.ts.map +1 -1
  70. package/dist/routes/public-shares.js +4 -6
  71. package/dist/routes/public-shares.js.map +1 -1
  72. package/dist/routes/session-metadata-patch.d.ts +24 -0
  73. package/dist/routes/session-metadata-patch.d.ts.map +1 -0
  74. package/dist/routes/session-metadata-patch.js +119 -0
  75. package/dist/routes/session-metadata-patch.js.map +1 -0
  76. package/dist/routes/session-project-routing.d.ts +25 -0
  77. package/dist/routes/session-project-routing.d.ts.map +1 -0
  78. package/dist/routes/session-project-routing.js +32 -0
  79. package/dist/routes/session-project-routing.js.map +1 -0
  80. package/dist/routes/session-provider-resolution.d.ts +28 -0
  81. package/dist/routes/session-provider-resolution.d.ts.map +1 -0
  82. package/dist/routes/session-provider-resolution.js +22 -0
  83. package/dist/routes/session-provider-resolution.js.map +1 -0
  84. package/dist/routes/session-queue-summaries.d.ts +21 -0
  85. package/dist/routes/session-queue-summaries.d.ts.map +1 -0
  86. package/dist/routes/session-queue-summaries.js +79 -0
  87. package/dist/routes/session-queue-summaries.js.map +1 -0
  88. package/dist/routes/session-recovered-queue.d.ts +43 -0
  89. package/dist/routes/session-recovered-queue.d.ts.map +1 -0
  90. package/dist/routes/session-recovered-queue.js +132 -0
  91. package/dist/routes/session-recovered-queue.js.map +1 -0
  92. package/dist/routes/session-thinking-options.d.ts +12 -0
  93. package/dist/routes/session-thinking-options.d.ts.map +1 -0
  94. package/dist/routes/session-thinking-options.js +7 -0
  95. package/dist/routes/session-thinking-options.js.map +1 -0
  96. package/dist/routes/sessions.d.ts.map +1 -1
  97. package/dist/routes/sessions.js +110 -409
  98. package/dist/routes/sessions.js.map +1 -1
  99. package/dist/routes/settings-parsers.d.ts +37 -0
  100. package/dist/routes/settings-parsers.d.ts.map +1 -0
  101. package/dist/routes/settings-parsers.js +896 -0
  102. package/dist/routes/settings-parsers.js.map +1 -0
  103. package/dist/routes/settings.d.ts.map +1 -1
  104. package/dist/routes/settings.js +4 -894
  105. package/dist/routes/settings.js.map +1 -1
  106. package/dist/routes/version.d.ts +0 -2
  107. package/dist/routes/version.d.ts.map +1 -1
  108. package/dist/routes/version.js +8 -10
  109. package/dist/routes/version.js.map +1 -1
  110. package/dist/sdk/cli-detection.d.ts +15 -1
  111. package/dist/sdk/cli-detection.d.ts.map +1 -1
  112. package/dist/sdk/cli-detection.js +159 -28
  113. package/dist/sdk/cli-detection.js.map +1 -1
  114. package/dist/sdk/messageQueue.d.ts +5 -0
  115. package/dist/sdk/messageQueue.d.ts.map +1 -1
  116. package/dist/sdk/messageQueue.js +21 -0
  117. package/dist/sdk/messageQueue.js.map +1 -1
  118. package/dist/sdk/providers/codex-model-catalog.d.ts +34 -0
  119. package/dist/sdk/providers/codex-model-catalog.d.ts.map +1 -0
  120. package/dist/sdk/providers/codex-model-catalog.js +378 -0
  121. package/dist/sdk/providers/codex-model-catalog.js.map +1 -0
  122. package/dist/sdk/providers/codex-notification-guards.d.ts +15 -0
  123. package/dist/sdk/providers/codex-notification-guards.d.ts.map +1 -0
  124. package/dist/sdk/providers/codex-notification-guards.js +159 -0
  125. package/dist/sdk/providers/codex-notification-guards.js.map +1 -0
  126. package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.d.ts +9 -0
  127. package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.d.ts.map +1 -0
  128. package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.js +3 -0
  129. package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.js.map +1 -0
  130. package/dist/sdk/providers/codex-protocol/generated/MultiAgentMode.d.ts +5 -5
  131. package/dist/sdk/providers/codex-protocol/generated/MultiAgentMode.d.ts.map +1 -1
  132. package/dist/sdk/providers/codex-protocol/generated/ResponseItem.d.ts +1 -0
  133. package/dist/sdk/providers/codex-protocol/generated/ResponseItem.d.ts.map +1 -1
  134. package/dist/sdk/providers/codex-protocol/generated/ThreadId.d.ts +5 -0
  135. package/dist/sdk/providers/codex-protocol/generated/ThreadId.d.ts.map +1 -1
  136. package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.d.ts +7 -0
  137. package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.d.ts.map +1 -0
  138. package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.js +3 -0
  139. package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.js.map +1 -0
  140. package/dist/sdk/providers/codex-protocol/generated/v2/AskForApproval.d.ts +1 -1
  141. package/dist/sdk/providers/codex-protocol/generated/v2/AskForApproval.d.ts.map +1 -1
  142. package/dist/sdk/providers/codex-protocol/generated/v2/CapabilityRootLocation.d.ts +3 -0
  143. package/dist/sdk/providers/codex-protocol/generated/v2/CapabilityRootLocation.d.ts.map +1 -1
  144. package/dist/sdk/providers/codex-protocol/generated/v2/CodexErrorInfo.d.ts +1 -1
  145. package/dist/sdk/providers/codex-protocol/generated/v2/CodexErrorInfo.d.ts.map +1 -1
  146. package/dist/sdk/providers/codex-protocol/generated/v2/McpToolCallAppContext.d.ts +3 -0
  147. package/dist/sdk/providers/codex-protocol/generated/v2/McpToolCallAppContext.d.ts.map +1 -1
  148. package/dist/sdk/providers/codex-protocol/generated/v2/Thread.d.ts +13 -0
  149. package/dist/sdk/providers/codex-protocol/generated/v2/Thread.d.ts.map +1 -1
  150. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.d.ts +5 -0
  151. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.d.ts.map +1 -0
  152. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.js +3 -0
  153. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.js.map +1 -0
  154. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadForkParams.d.ts +7 -0
  155. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadForkParams.d.ts.map +1 -1
  156. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.d.ts +2 -0
  157. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.d.ts.map +1 -0
  158. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.js +3 -0
  159. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.js.map +1 -0
  160. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadItem.d.ts +5 -13
  161. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadItem.d.ts.map +1 -1
  162. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadRollbackParams.d.ts +3 -0
  163. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadRollbackParams.d.ts.map +1 -1
  164. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadStartParams.d.ts +10 -0
  165. package/dist/sdk/providers/codex-protocol/generated/v2/ThreadStartParams.d.ts.map +1 -1
  166. package/dist/sdk/providers/codex-protocol/generated/v2/Turn.d.ts +3 -0
  167. package/dist/sdk/providers/codex-protocol/generated/v2/Turn.d.ts.map +1 -1
  168. package/dist/sdk/providers/codex-summary-helpers.d.ts +41 -0
  169. package/dist/sdk/providers/codex-summary-helpers.d.ts.map +1 -0
  170. package/dist/sdk/providers/codex-summary-helpers.js +207 -0
  171. package/dist/sdk/providers/codex-summary-helpers.js.map +1 -0
  172. package/dist/sdk/providers/codex.d.ts +0 -25
  173. package/dist/sdk/providers/codex.d.ts.map +1 -1
  174. package/dist/sdk/providers/codex.js +160 -703
  175. package/dist/sdk/providers/codex.js.map +1 -1
  176. package/dist/sdk/providers/opencode-models.d.ts +17 -0
  177. package/dist/sdk/providers/opencode-models.d.ts.map +1 -0
  178. package/dist/sdk/providers/opencode-models.js +83 -0
  179. package/dist/sdk/providers/opencode-models.js.map +1 -0
  180. package/dist/sdk/providers/opencode.d.ts +1 -9
  181. package/dist/sdk/providers/opencode.d.ts.map +1 -1
  182. package/dist/sdk/providers/opencode.js +1 -82
  183. package/dist/sdk/providers/opencode.js.map +1 -1
  184. package/dist/sdk/types.d.ts +3 -1
  185. package/dist/sdk/types.d.ts.map +1 -1
  186. package/dist/services/ProjectQueueService.d.ts.map +1 -1
  187. package/dist/services/ProjectQueueService.js +3 -1
  188. package/dist/services/ProjectQueueService.js.map +1 -1
  189. package/dist/sessions/claude-summary.d.ts.map +1 -1
  190. package/dist/sessions/claude-summary.js +13 -1
  191. package/dist/sessions/claude-summary.js.map +1 -1
  192. package/dist/sessions/codex-reader.d.ts +0 -2
  193. package/dist/sessions/codex-reader.d.ts.map +1 -1
  194. package/dist/sessions/codex-reader.js +46 -84
  195. package/dist/sessions/codex-reader.js.map +1 -1
  196. package/dist/sessions/codex-user-turn-provenance.d.ts +40 -0
  197. package/dist/sessions/codex-user-turn-provenance.d.ts.map +1 -0
  198. package/dist/sessions/codex-user-turn-provenance.js +165 -0
  199. package/dist/sessions/codex-user-turn-provenance.js.map +1 -0
  200. package/dist/sessions/normalization.d.ts.map +1 -1
  201. package/dist/sessions/normalization.js +80 -51
  202. package/dist/sessions/normalization.js.map +1 -1
  203. package/dist/sessions/pagination.d.ts +6 -0
  204. package/dist/sessions/pagination.d.ts.map +1 -1
  205. package/dist/sessions/pagination.js +42 -2
  206. package/dist/sessions/pagination.js.map +1 -1
  207. package/dist/subscriptions.d.ts.map +1 -1
  208. package/dist/subscriptions.js +1 -0
  209. package/dist/subscriptions.js.map +1 -1
  210. package/dist/supervisor/Process.d.ts +12 -0
  211. package/dist/supervisor/Process.d.ts.map +1 -1
  212. package/dist/supervisor/Process.js +178 -22
  213. package/dist/supervisor/Process.js.map +1 -1
  214. package/dist/supervisor/Supervisor.d.ts +5 -1
  215. package/dist/supervisor/Supervisor.d.ts.map +1 -1
  216. package/dist/supervisor/Supervisor.js +47 -0
  217. package/dist/supervisor/Supervisor.js.map +1 -1
  218. package/package.json +2 -2
  219. package/client-dist/assets/de-CHMDbVD5.js +0 -6
  220. package/client-dist/assets/es-CK8MPF_C.js +0 -6
  221. package/client-dist/assets/fr-49PXQiUL.js +0 -6
  222. package/client-dist/assets/index-B-09fVut.js +0 -557
  223. package/client-dist/assets/index-uJnfvD1f.css +0 -1
  224. package/client-dist/assets/ja-CrCGPmoH.js +0 -6
  225. package/client-dist/assets/zh-CN-AFJxv5ke.js +0 -6
@@ -1,903 +1,13 @@
1
1
  /**
2
2
  * Server settings API routes
3
3
  */
4
- import { ALL_PERMISSION_MODES, ALL_PROVIDERS, HELPER_SIDE_MODEL_CHEAPEST, HELPER_SIDE_MODEL_SAME_AS_MAIN, normalizeYaClientBaseUrl, normalizeYaClientBaseUrlFromShareViewerUrl, DEFAULT_CACHE_MISS_BILLING_SETTINGS, DEFAULT_PROJECT_QUEUE_QUIET_SECONDS, DEFAULT_PROMPT_CACHE_KEEPALIVE_INACTIVITY_MINUTES, MAX_PROJECT_QUEUE_QUIET_SECONDS, PROMPT_CACHE_KEEPALIVE_MODES, PROMPT_SUGGESTION_MODES, RECAP_MODES, clampRecapAfterSeconds, clampProjectQueueQuietSeconds, } from "../../bundled/@yep-anywhere/shared/dist/index.js";
4
+ import { DEFAULT_PROJECT_QUEUE_QUIET_SECONDS, DEFAULT_PROMPT_CACHE_KEEPALIVE_INACTIVITY_MINUTES, MAX_PROJECT_QUEUE_QUIET_SECONDS, PROMPT_CACHE_KEEPALIVE_MODES, clampProjectQueueQuietSeconds, normalizeYaClientBaseUrl, normalizeYaClientBaseUrlFromShareViewerUrl, } from "../../bundled/@yep-anywhere/shared/dist/index.js";
5
5
  import { Hono } from "hono";
6
- import { getFileAccessInfo, normalizeFileAccess, } from "../middleware/file-access.js";
6
+ import { getFileAccessInfo } from "../middleware/file-access.js";
7
7
  import { testSSHConnection } from "../sdk/remote-spawn.js";
8
- import { CODEX_UPDATE_POLICIES, DEFAULT_SERVER_SETTINGS, DEFAULT_SPEECH_AUDIO_RETENTION_MAX_AGE_DAYS, DEFAULT_SPEECH_AUDIO_RETENTION_MAX_BYTES, } from "../services/ServerSettingsService.js";
8
+ import { CODEX_UPDATE_POLICIES, DEFAULT_SERVER_SETTINGS, } from "../services/ServerSettingsService.js";
9
9
  import { isValidSshHostAlias, normalizeSshHostAlias, } from "../utils/sshHostAlias.js";
10
- const HELPER_TARGET_ID_PATTERN = /^[A-Za-z0-9._-]{1,64}$/;
11
- const MAX_HELPER_TARGETS = 20;
12
- const HELPER_TARGET_MODEL_DISCOVERY_TIMEOUT_MS = 5000;
13
- const SESSION_TOOLBAR_PRESENCE_CLIENT_DEFAULT_KEYS = [
14
- "modeSelector",
15
- "steerNow",
16
- "attachments",
17
- "slashMenu",
18
- "thinkingToggle",
19
- "renderMode",
20
- "microphone",
21
- "waveform",
22
- "shortcutsHelp",
23
- "contextUsage",
24
- "btw",
25
- "nudge",
26
- "sessionStatus",
27
- "projectQueue",
28
- ];
29
- const TOOLBAR_CONTROL_PRESENCES = [
30
- "hidden",
31
- "pin",
32
- "last",
33
- "mid",
34
- "first",
35
- ];
36
- const CLIENT_DEFAULT_KEYS = [
37
- "speech",
38
- "busyComposerDefaultAction",
39
- "collapsedComposerButton",
40
- "sessionToolbarPresence",
41
- "steerNowDefault",
42
- "patientQueueDefault",
43
- "projectQueueCtrlEnterEnabled",
44
- "compactAtContextPercent",
45
- ];
46
- const BUSY_COMPOSER_DEFAULT_ACTIONS = [
47
- "steer",
48
- "queue",
49
- ];
50
- const COLLAPSED_COMPOSER_BUTTON_PREFERENCES = [
51
- "primary",
52
- "alternate",
53
- "microphone",
54
- ];
55
- const SPEECH_CLIENT_DEFAULT_KEYS = [
56
- "voiceInputEnabled",
57
- "speechMethod",
58
- "speechSmartTurnSettings",
59
- "grokSpeechAudioSettings",
60
- ];
61
- const THINKING_MODES = [
62
- "off",
63
- "auto",
64
- "on",
65
- ];
66
- const EFFORT_LEVELS = [
67
- "low",
68
- "medium",
69
- "high",
70
- "xhigh",
71
- "max",
72
- ];
73
- const MAX_SPEECH_SMART_TURN_TIMEOUT_MS = 10000;
74
- function parseHostAliasList(rawHosts) {
75
- const hosts = [];
76
- for (const rawHost of rawHosts) {
77
- if (typeof rawHost !== "string")
78
- continue;
79
- const host = normalizeSshHostAlias(rawHost);
80
- if (!host)
81
- continue;
82
- if (!isValidSshHostAlias(host)) {
83
- return { hosts: [], invalidHost: host };
84
- }
85
- hosts.push(host);
86
- }
87
- return { hosts };
88
- }
89
- function normalizeOpenAiCompatibleBaseUrl(raw) {
90
- if (typeof raw !== "string")
91
- return null;
92
- const trimmed = raw.trim();
93
- if (!trimmed)
94
- return null;
95
- const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed)
96
- ? trimmed
97
- : `http://${trimmed}`;
98
- try {
99
- const url = new URL(withScheme);
100
- if (url.protocol !== "http:" && url.protocol !== "https:")
101
- return null;
102
- if (url.pathname === "" || url.pathname === "/") {
103
- url.pathname = "/v1";
104
- }
105
- const normalized = url.toString();
106
- return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
107
- }
108
- catch {
109
- return null;
110
- }
111
- }
112
- /**
113
- * Returns:
114
- * - `null` when the payload is invalid
115
- * - `undefined` when the setting should be cleared
116
- * - an array when valid helper targets should be saved
117
- */
118
- function parseHelperTargets(raw) {
119
- if (raw === undefined)
120
- return null;
121
- if (raw === null || raw === "")
122
- return undefined;
123
- if (!Array.isArray(raw) || raw.length > MAX_HELPER_TARGETS)
124
- return null;
125
- const seenIds = new Set();
126
- const parsed = [];
127
- for (const entry of raw) {
128
- if (!entry || typeof entry !== "object")
129
- return null;
130
- const input = entry;
131
- const id = typeof input.id === "string" ? input.id.trim() : "";
132
- const name = typeof input.name === "string" ? input.name.trim() : "";
133
- const baseUrl = normalizeOpenAiCompatibleBaseUrl(input.baseUrl);
134
- const model = typeof input.model === "string" ? input.model.trim() : "";
135
- if (!HELPER_TARGET_ID_PATTERN.test(id) ||
136
- seenIds.has(id) ||
137
- !name ||
138
- name.length > 80 ||
139
- input.kind !== "openai-compatible" ||
140
- !baseUrl ||
141
- model.length > 200) {
142
- return null;
143
- }
144
- seenIds.add(id);
145
- parsed.push({
146
- id,
147
- name,
148
- kind: "openai-compatible",
149
- baseUrl,
150
- ...(model ? { model } : {}),
151
- });
152
- }
153
- return parsed;
154
- }
155
- function isRecord(value) {
156
- return typeof value === "object" && value !== null;
157
- }
158
- function parseOptionalString(value, maxLength) {
159
- if (value === undefined || value === null || value === "")
160
- return undefined;
161
- if (typeof value !== "string")
162
- return null;
163
- return value.length > 0 ? value.slice(0, maxLength) : undefined;
164
- }
165
- function parseProviderSessionDefaults(raw) {
166
- if (raw === undefined || raw === null || raw === "")
167
- return undefined;
168
- if (!isRecord(raw))
169
- return null;
170
- const parsed = {};
171
- if ("model" in raw) {
172
- const model = parseOptionalString(raw.model, 200);
173
- if (model === null)
174
- return null;
175
- if (model)
176
- parsed.model = model;
177
- }
178
- if ("serviceTier" in raw) {
179
- const serviceTier = parseOptionalString(raw.serviceTier, 64);
180
- if (serviceTier === null)
181
- return null;
182
- if (serviceTier)
183
- parsed.serviceTier = serviceTier;
184
- }
185
- if ("thinkingMode" in raw) {
186
- if (raw.thinkingMode !== undefined &&
187
- raw.thinkingMode !== null &&
188
- raw.thinkingMode !== "" &&
189
- !THINKING_MODES.includes(raw.thinkingMode)) {
190
- return null;
191
- }
192
- if (typeof raw.thinkingMode === "string" && raw.thinkingMode.length > 0) {
193
- parsed.thinkingMode = raw.thinkingMode;
194
- }
195
- }
196
- if ("effortLevel" in raw) {
197
- if (raw.effortLevel !== undefined &&
198
- raw.effortLevel !== null &&
199
- raw.effortLevel !== "" &&
200
- !EFFORT_LEVELS.includes(raw.effortLevel)) {
201
- return null;
202
- }
203
- if (typeof raw.effortLevel === "string" && raw.effortLevel.length > 0) {
204
- parsed.effortLevel = raw.effortLevel;
205
- }
206
- }
207
- if ("helperSideModel" in raw) {
208
- const helperSideModel = parseOptionalString(raw.helperSideModel, 200);
209
- if (helperSideModel === null)
210
- return null;
211
- if (helperSideModel) {
212
- parsed.helperSideModel =
213
- helperSideModel === HELPER_SIDE_MODEL_SAME_AS_MAIN
214
- ? HELPER_SIDE_MODEL_SAME_AS_MAIN
215
- : helperSideModel === HELPER_SIDE_MODEL_CHEAPEST
216
- ? HELPER_SIDE_MODEL_CHEAPEST
217
- : helperSideModel;
218
- }
219
- }
220
- return Object.keys(parsed).length > 0 ? parsed : undefined;
221
- }
222
- const MAX_FILE_ACCESS_CUSTOM_ENTRIES = 100;
223
- const MAX_FILE_ACCESS_CUSTOM_LENGTH = 1024;
224
- /**
225
- * Returns:
226
- * - `null` when the payload is invalid
227
- * - `undefined` when the setting should be cleared (reset to secure defaults)
228
- * - a normalized object when valid
229
- */
230
- function parseFileAccess(raw) {
231
- if (raw === undefined)
232
- return null;
233
- if (raw === null || raw === "")
234
- return undefined;
235
- if (!isRecord(raw))
236
- return null;
237
- const allowedKeys = new Set([
238
- "projects",
239
- "uploads",
240
- "temp",
241
- "home",
242
- "custom",
243
- ]);
244
- for (const key of Object.keys(raw)) {
245
- if (!allowedKeys.has(key))
246
- return null;
247
- }
248
- for (const key of ["projects", "uploads", "temp", "home"]) {
249
- if (key in raw && typeof raw[key] !== "boolean")
250
- return null;
251
- }
252
- if ("custom" in raw) {
253
- if (!Array.isArray(raw.custom) ||
254
- raw.custom.length > MAX_FILE_ACCESS_CUSTOM_ENTRIES) {
255
- return null;
256
- }
257
- for (const entry of raw.custom) {
258
- if (typeof entry !== "string" ||
259
- entry.length > MAX_FILE_ACCESS_CUSTOM_LENGTH) {
260
- return null;
261
- }
262
- }
263
- }
264
- return normalizeFileAccess({
265
- projects: raw.projects,
266
- uploads: raw.uploads,
267
- temp: raw.temp,
268
- home: raw.home,
269
- custom: raw.custom ?? [],
270
- });
271
- }
272
- function parseOpenAiModelsResponse(raw) {
273
- if (!isRecord(raw) || !Array.isArray(raw.data))
274
- return null;
275
- const models = [];
276
- for (const entry of raw.data) {
277
- if (!isRecord(entry) || typeof entry.id !== "string" || !entry.id.trim()) {
278
- continue;
279
- }
280
- const metadata = isRecord(entry.metadata) ? entry.metadata : undefined;
281
- const rawContextWindow = typeof entry.max_model_len === "number"
282
- ? entry.max_model_len
283
- : typeof entry.maxModelLen === "number"
284
- ? entry.maxModelLen
285
- : typeof metadata?.max_model_len === "number"
286
- ? metadata.max_model_len
287
- : undefined;
288
- const contextWindow = rawContextWindow !== undefined && Number.isFinite(rawContextWindow)
289
- ? rawContextWindow
290
- : undefined;
291
- models.push({
292
- id: entry.id,
293
- name: entry.id,
294
- ...(contextWindow ? { contextWindow } : {}),
295
- });
296
- }
297
- return models;
298
- }
299
- function parseAgentContextHints(raw, current) {
300
- if (raw === undefined || raw === null)
301
- return {};
302
- if (!isRecord(raw))
303
- return null;
304
- const parsed = { ...current };
305
- if ("latexMathRendering" in raw) {
306
- if (typeof raw.latexMathRendering !== "boolean")
307
- return null;
308
- parsed.latexMathRendering = raw.latexMathRendering;
309
- }
310
- return parsed;
311
- }
312
- async function discoverOpenAiCompatibleModels(baseUrl) {
313
- const controller = new AbortController();
314
- const timeout = setTimeout(() => controller.abort(), HELPER_TARGET_MODEL_DISCOVERY_TIMEOUT_MS);
315
- try {
316
- const response = await fetch(`${baseUrl}/models`, {
317
- signal: controller.signal,
318
- });
319
- if (!response.ok)
320
- return null;
321
- return parseOpenAiModelsResponse(await response.json());
322
- }
323
- catch {
324
- return null;
325
- }
326
- finally {
327
- clearTimeout(timeout);
328
- }
329
- }
330
- /**
331
- * Returns:
332
- * - `null` when the payload is invalid
333
- * - `undefined` when the setting should be cleared
334
- * - an object when valid defaults should be saved
335
- */
336
- function parseNewSessionDefaults(raw) {
337
- if (raw === undefined)
338
- return null;
339
- if (raw === null || raw === "")
340
- return undefined;
341
- if (typeof raw !== "object")
342
- return null;
343
- const input = raw;
344
- const parsed = {};
345
- if ("provider" in input) {
346
- if (input.provider !== undefined &&
347
- input.provider !== null &&
348
- input.provider !== "" &&
349
- !ALL_PROVIDERS.includes(input.provider)) {
350
- return null;
351
- }
352
- if (typeof input.provider === "string" && input.provider.length > 0) {
353
- parsed.provider = input.provider;
354
- }
355
- }
356
- if ("model" in input) {
357
- const model = parseOptionalString(input.model, 200);
358
- if (model === null)
359
- return null;
360
- if (model)
361
- parsed.model = model;
362
- }
363
- if ("serviceTier" in input) {
364
- const serviceTier = parseOptionalString(input.serviceTier, 64);
365
- if (serviceTier === null)
366
- return null;
367
- if (serviceTier)
368
- parsed.serviceTier = serviceTier;
369
- }
370
- if ("permissionMode" in input) {
371
- if (input.permissionMode !== undefined &&
372
- input.permissionMode !== null &&
373
- input.permissionMode !== "" &&
374
- !ALL_PERMISSION_MODES.includes(input.permissionMode)) {
375
- return null;
376
- }
377
- if (typeof input.permissionMode === "string" &&
378
- input.permissionMode.length > 0) {
379
- parsed.permissionMode = input.permissionMode;
380
- }
381
- }
382
- if ("recapMode" in input) {
383
- if (input.recapMode !== undefined &&
384
- input.recapMode !== null &&
385
- input.recapMode !== "" &&
386
- !RECAP_MODES.includes(input.recapMode)) {
387
- return null;
388
- }
389
- if (typeof input.recapMode === "string" && input.recapMode.length > 0) {
390
- parsed.recapMode = input.recapMode;
391
- }
392
- }
393
- if ("recapAfterSeconds" in input) {
394
- if (input.recapAfterSeconds !== undefined &&
395
- input.recapAfterSeconds !== null &&
396
- input.recapAfterSeconds !== "" &&
397
- (typeof input.recapAfterSeconds !== "number" ||
398
- !Number.isFinite(input.recapAfterSeconds))) {
399
- return null;
400
- }
401
- if (typeof input.recapAfterSeconds === "number" &&
402
- Number.isFinite(input.recapAfterSeconds)) {
403
- parsed.recapAfterSeconds = clampRecapAfterSeconds(input.recapAfterSeconds);
404
- }
405
- }
406
- if ("promptSuggestionMode" in input) {
407
- if (input.promptSuggestionMode !== undefined &&
408
- input.promptSuggestionMode !== null &&
409
- input.promptSuggestionMode !== "" &&
410
- !PROMPT_SUGGESTION_MODES.includes(input.promptSuggestionMode)) {
411
- return null;
412
- }
413
- if (typeof input.promptSuggestionMode === "string" &&
414
- input.promptSuggestionMode.length > 0) {
415
- parsed.promptSuggestionMode =
416
- input.promptSuggestionMode;
417
- }
418
- }
419
- if ("providers" in input) {
420
- if (input.providers !== undefined &&
421
- input.providers !== null &&
422
- input.providers !== "" &&
423
- !isRecord(input.providers)) {
424
- return null;
425
- }
426
- if (isRecord(input.providers)) {
427
- const providers = {};
428
- for (const [providerName, rawDefaults] of Object.entries(input.providers)) {
429
- if (!ALL_PROVIDERS.includes(providerName)) {
430
- return null;
431
- }
432
- const parsedProviderDefaults = parseProviderSessionDefaults(rawDefaults);
433
- if (parsedProviderDefaults === null)
434
- return null;
435
- if (parsedProviderDefaults) {
436
- providers[providerName] = parsedProviderDefaults;
437
- }
438
- }
439
- if (Object.keys(providers).length > 0) {
440
- parsed.providers = providers;
441
- }
442
- }
443
- }
444
- return Object.keys(parsed).length > 0 ? parsed : undefined;
445
- }
446
- function parseSpeechSmartTurnClientDefault(raw) {
447
- if (!isRecord(raw))
448
- return null;
449
- if (typeof raw.enabled !== "boolean" ||
450
- typeof raw.threshold !== "number" ||
451
- typeof raw.timeoutMs !== "number" ||
452
- !Number.isFinite(raw.threshold) ||
453
- !Number.isFinite(raw.timeoutMs) ||
454
- raw.threshold < 0 ||
455
- raw.threshold > 1 ||
456
- raw.timeoutMs < 0 ||
457
- raw.timeoutMs > MAX_SPEECH_SMART_TURN_TIMEOUT_MS) {
458
- return null;
459
- }
460
- return {
461
- enabled: raw.enabled,
462
- threshold: raw.threshold,
463
- timeoutMs: Math.round(raw.timeoutMs),
464
- };
465
- }
466
- function parseGrokSpeechAudioClientDefault(raw) {
467
- if (!isRecord(raw))
468
- return null;
469
- if (raw.uplinkMode !== "pcm16" && raw.uplinkMode !== "browser-compressed") {
470
- return null;
471
- }
472
- return { uplinkMode: raw.uplinkMode };
473
- }
474
- function parseSessionToolbarPresenceClientDefaults(raw) {
475
- if (raw === undefined || raw === null || raw === "")
476
- return undefined;
477
- if (!isRecord(raw))
478
- return null;
479
- const allowedKeys = new Set(SESSION_TOOLBAR_PRESENCE_CLIENT_DEFAULT_KEYS);
480
- for (const key of Object.keys(raw)) {
481
- if (!allowedKeys.has(key))
482
- return null;
483
- }
484
- const allowedPresences = new Set(TOOLBAR_CONTROL_PRESENCES);
485
- const parsed = {};
486
- for (const key of SESSION_TOOLBAR_PRESENCE_CLIENT_DEFAULT_KEYS) {
487
- if (!(key in raw))
488
- continue;
489
- const value = raw[key];
490
- if (typeof value !== "string" || !allowedPresences.has(value))
491
- return null;
492
- parsed[key] = value;
493
- }
494
- return Object.keys(parsed).length > 0 ? parsed : null;
495
- }
496
- // Per-model compaction thresholds: each value is "compact at X% of that
497
- // model's context window". Reject non-numbers (the slider only ever sends
498
- // numbers), but treat out-of-range like the load path does — keep 1–99 and
499
- // drop anything else (including >= 100 = "off"). An empty result clears the
500
- // setting. The returned map is authoritative: the client always sends the
501
- // full map, so mergeClientDefaults replaces rather than per-model merges,
502
- // which is what makes turning a model "off" (dropping its key) take effect.
503
- function parseCompactAtContextPercent(raw) {
504
- if (raw === undefined || raw === null || raw === "")
505
- return undefined;
506
- if (!isRecord(raw))
507
- return null;
508
- const cleaned = {};
509
- for (const [modelId, value] of Object.entries(raw)) {
510
- if (typeof value !== "number" || !Number.isFinite(value))
511
- return null;
512
- const pct = Math.round(value);
513
- if (pct > 0 && pct < 100)
514
- cleaned[modelId] = pct;
515
- }
516
- return Object.keys(cleaned).length > 0 ? cleaned : undefined;
517
- }
518
- function parseClientDefaults(raw) {
519
- if (raw === undefined)
520
- return null;
521
- if (raw === null || raw === "")
522
- return undefined;
523
- if (!isRecord(raw))
524
- return null;
525
- const allowedKeys = new Set(CLIENT_DEFAULT_KEYS);
526
- for (const key of Object.keys(raw)) {
527
- if (!allowedKeys.has(key))
528
- return null;
529
- }
530
- if (Object.keys(raw).length === 0)
531
- return null;
532
- const parsed = {};
533
- if ("speech" in raw) {
534
- if (raw.speech === undefined || raw.speech === null || raw.speech === "") {
535
- parsed.speech = undefined;
536
- }
537
- else if (!isRecord(raw.speech)) {
538
- return null;
539
- }
540
- else {
541
- const allowedSpeechKeys = new Set(SPEECH_CLIENT_DEFAULT_KEYS);
542
- for (const key of Object.keys(raw.speech)) {
543
- if (!allowedSpeechKeys.has(key))
544
- return null;
545
- }
546
- const speech = {};
547
- if ("voiceInputEnabled" in raw.speech) {
548
- if (typeof raw.speech.voiceInputEnabled !== "boolean")
549
- return null;
550
- speech.voiceInputEnabled = raw.speech.voiceInputEnabled;
551
- }
552
- if ("speechMethod" in raw.speech) {
553
- if (typeof raw.speech.speechMethod !== "string" ||
554
- raw.speech.speechMethod.trim().length === 0) {
555
- return null;
556
- }
557
- speech.speechMethod = raw.speech.speechMethod.trim().slice(0, 120);
558
- }
559
- if ("speechSmartTurnSettings" in raw.speech) {
560
- const parsedSmartTurn = parseSpeechSmartTurnClientDefault(raw.speech.speechSmartTurnSettings);
561
- if (!parsedSmartTurn)
562
- return null;
563
- speech.speechSmartTurnSettings = parsedSmartTurn;
564
- }
565
- if ("grokSpeechAudioSettings" in raw.speech) {
566
- const parsedGrokAudio = parseGrokSpeechAudioClientDefault(raw.speech.grokSpeechAudioSettings);
567
- if (!parsedGrokAudio)
568
- return null;
569
- speech.grokSpeechAudioSettings = parsedGrokAudio;
570
- }
571
- if (Object.keys(speech).length === 0)
572
- return null;
573
- parsed.speech = speech;
574
- }
575
- }
576
- if ("busyComposerDefaultAction" in raw) {
577
- if (raw.busyComposerDefaultAction === undefined ||
578
- raw.busyComposerDefaultAction === null) {
579
- parsed.busyComposerDefaultAction = undefined;
580
- }
581
- else if (!BUSY_COMPOSER_DEFAULT_ACTIONS.includes(raw.busyComposerDefaultAction)) {
582
- return null;
583
- }
584
- else {
585
- parsed.busyComposerDefaultAction =
586
- raw.busyComposerDefaultAction;
587
- }
588
- }
589
- if ("collapsedComposerButton" in raw) {
590
- if (raw.collapsedComposerButton === undefined ||
591
- raw.collapsedComposerButton === null) {
592
- parsed.collapsedComposerButton = undefined;
593
- }
594
- else if (!COLLAPSED_COMPOSER_BUTTON_PREFERENCES.includes(raw.collapsedComposerButton)) {
595
- return null;
596
- }
597
- else {
598
- parsed.collapsedComposerButton =
599
- raw.collapsedComposerButton;
600
- }
601
- }
602
- if ("steerNowDefault" in raw) {
603
- if (raw.steerNowDefault === undefined || raw.steerNowDefault === null) {
604
- parsed.steerNowDefault = undefined;
605
- }
606
- else if (typeof raw.steerNowDefault !== "boolean") {
607
- return null;
608
- }
609
- else {
610
- parsed.steerNowDefault = raw.steerNowDefault;
611
- }
612
- }
613
- if ("patientQueueDefault" in raw) {
614
- if (raw.patientQueueDefault === undefined ||
615
- raw.patientQueueDefault === null) {
616
- parsed.patientQueueDefault = undefined;
617
- }
618
- else if (typeof raw.patientQueueDefault !== "boolean") {
619
- return null;
620
- }
621
- else {
622
- parsed.patientQueueDefault = raw.patientQueueDefault;
623
- }
624
- }
625
- if ("projectQueueCtrlEnterEnabled" in raw) {
626
- if (raw.projectQueueCtrlEnterEnabled === undefined ||
627
- raw.projectQueueCtrlEnterEnabled === null) {
628
- parsed.projectQueueCtrlEnterEnabled = undefined;
629
- }
630
- else if (typeof raw.projectQueueCtrlEnterEnabled !== "boolean") {
631
- return null;
632
- }
633
- else {
634
- parsed.projectQueueCtrlEnterEnabled = raw.projectQueueCtrlEnterEnabled;
635
- }
636
- }
637
- if ("sessionToolbarPresence" in raw) {
638
- const parsedPresence = parseSessionToolbarPresenceClientDefaults(raw.sessionToolbarPresence);
639
- if (parsedPresence === null)
640
- return null;
641
- parsed.sessionToolbarPresence = parsedPresence;
642
- }
643
- if ("compactAtContextPercent" in raw) {
644
- const parsedCompact = parseCompactAtContextPercent(raw.compactAtContextPercent);
645
- if (parsedCompact === null)
646
- return null;
647
- parsed.compactAtContextPercent = parsedCompact;
648
- }
649
- return Object.keys(parsed).length > 0 ? parsed : undefined;
650
- }
651
- function mergeClientDefaults(current, update) {
652
- if (!update)
653
- return undefined;
654
- const merged = { ...current };
655
- if ("speech" in update) {
656
- if (update.speech === undefined) {
657
- delete merged.speech;
658
- }
659
- else {
660
- merged.speech = {
661
- ...current?.speech,
662
- ...update.speech,
663
- };
664
- }
665
- }
666
- if ("busyComposerDefaultAction" in update) {
667
- if (update.busyComposerDefaultAction === undefined) {
668
- delete merged.busyComposerDefaultAction;
669
- }
670
- else {
671
- merged.busyComposerDefaultAction = update.busyComposerDefaultAction;
672
- }
673
- }
674
- if ("collapsedComposerButton" in update) {
675
- if (update.collapsedComposerButton === undefined) {
676
- delete merged.collapsedComposerButton;
677
- }
678
- else {
679
- merged.collapsedComposerButton = update.collapsedComposerButton;
680
- }
681
- }
682
- if ("steerNowDefault" in update) {
683
- if (update.steerNowDefault === undefined) {
684
- delete merged.steerNowDefault;
685
- }
686
- else {
687
- merged.steerNowDefault = update.steerNowDefault;
688
- }
689
- }
690
- if ("patientQueueDefault" in update) {
691
- if (update.patientQueueDefault === undefined) {
692
- delete merged.patientQueueDefault;
693
- }
694
- else {
695
- merged.patientQueueDefault = update.patientQueueDefault;
696
- }
697
- }
698
- if ("projectQueueCtrlEnterEnabled" in update) {
699
- if (update.projectQueueCtrlEnterEnabled === undefined) {
700
- delete merged.projectQueueCtrlEnterEnabled;
701
- }
702
- else {
703
- merged.projectQueueCtrlEnterEnabled = update.projectQueueCtrlEnterEnabled;
704
- }
705
- }
706
- if ("sessionToolbarPresence" in update) {
707
- if (update.sessionToolbarPresence === undefined) {
708
- delete merged.sessionToolbarPresence;
709
- }
710
- else {
711
- merged.sessionToolbarPresence = {
712
- ...current?.sessionToolbarPresence,
713
- ...update.sessionToolbarPresence,
714
- };
715
- }
716
- }
717
- if ("compactAtContextPercent" in update) {
718
- // Replace the whole map (not a per-model merge): the client always sends
719
- // the complete map, so a model dropped from it means "off" for that model.
720
- if (update.compactAtContextPercent === undefined) {
721
- delete merged.compactAtContextPercent;
722
- }
723
- else {
724
- merged.compactAtContextPercent = update.compactAtContextPercent;
725
- }
726
- }
727
- return Object.keys(merged).length > 0 ? merged : undefined;
728
- }
729
- function parseSpeechAudioRetention(raw) {
730
- if (raw === undefined || raw === null) {
731
- return DEFAULT_SERVER_SETTINGS.speechAudioRetention;
732
- }
733
- if (!isRecord(raw))
734
- return null;
735
- const enabled = typeof raw.enabled === "boolean"
736
- ? raw.enabled
737
- : DEFAULT_SERVER_SETTINGS.speechAudioRetention.enabled;
738
- const maxAgeDays = raw.maxAgeDays === undefined || raw.maxAgeDays === null
739
- ? DEFAULT_SPEECH_AUDIO_RETENTION_MAX_AGE_DAYS
740
- : raw.maxAgeDays;
741
- const maxBytes = raw.maxBytes === undefined || raw.maxBytes === null
742
- ? DEFAULT_SPEECH_AUDIO_RETENTION_MAX_BYTES
743
- : raw.maxBytes;
744
- if (typeof maxAgeDays !== "number" ||
745
- !Number.isInteger(maxAgeDays) ||
746
- maxAgeDays < 1 ||
747
- maxAgeDays > 3650) {
748
- return null;
749
- }
750
- if (typeof maxBytes !== "number" ||
751
- !Number.isInteger(maxBytes) ||
752
- maxBytes < 1024 * 1024 ||
753
- maxBytes > 100 * 1024 * 1024 * 1024) {
754
- return null;
755
- }
756
- return { enabled, maxAgeDays, maxBytes };
757
- }
758
- function parsePromptCacheKeepalive(raw) {
759
- if (raw === undefined)
760
- return null;
761
- if (raw === null || raw === "")
762
- return undefined;
763
- if (!isRecord(raw))
764
- return null;
765
- const rawProviders = raw.providers;
766
- if (rawProviders === undefined || rawProviders === null)
767
- return {};
768
- if (!isRecord(rawProviders))
769
- return null;
770
- const providers = {};
771
- for (const [providerName, rawProviderSetting] of Object.entries(rawProviders)) {
772
- if (!ALL_PROVIDERS.includes(providerName))
773
- return null;
774
- if (rawProviderSetting === undefined || rawProviderSetting === null) {
775
- continue;
776
- }
777
- if (!isRecord(rawProviderSetting))
778
- return null;
779
- const setting = {};
780
- if ("mode" in rawProviderSetting) {
781
- if (typeof rawProviderSetting.mode !== "string" ||
782
- !PROMPT_CACHE_KEEPALIVE_MODES.includes(rawProviderSetting.mode)) {
783
- return null;
784
- }
785
- setting.mode = rawProviderSetting.mode;
786
- }
787
- if ("inactivityMinutes" in rawProviderSetting) {
788
- const value = rawProviderSetting.inactivityMinutes;
789
- if (typeof value !== "number" ||
790
- !Number.isInteger(value) ||
791
- value < 1 ||
792
- value > 1440) {
793
- return null;
794
- }
795
- setting.inactivityMinutes = value;
796
- }
797
- if (Object.keys(setting).length > 0) {
798
- providers[providerName] = setting;
799
- }
800
- }
801
- return { providers };
802
- }
803
- function parseCacheMissBilling(raw) {
804
- if (raw === undefined)
805
- return null;
806
- if (raw === null || raw === "")
807
- return DEFAULT_CACHE_MISS_BILLING_SETTINGS;
808
- if (!isRecord(raw))
809
- return null;
810
- const parsed = {};
811
- if ("enabled" in raw) {
812
- if (raw.enabled === undefined || raw.enabled === null) {
813
- parsed.enabled = DEFAULT_CACHE_MISS_BILLING_SETTINGS.enabled;
814
- }
815
- else if (typeof raw.enabled !== "boolean") {
816
- return null;
817
- }
818
- else {
819
- parsed.enabled = raw.enabled;
820
- }
821
- }
822
- if ("showToasts" in raw) {
823
- if (raw.showToasts === undefined || raw.showToasts === null) {
824
- parsed.showToasts = DEFAULT_CACHE_MISS_BILLING_SETTINGS.showToasts;
825
- }
826
- else if (typeof raw.showToasts !== "boolean") {
827
- return null;
828
- }
829
- else {
830
- parsed.showToasts = raw.showToasts;
831
- }
832
- }
833
- if ("freshWindowMinutes" in raw) {
834
- if (raw.freshWindowMinutes === undefined ||
835
- raw.freshWindowMinutes === null) {
836
- parsed.freshWindowMinutes =
837
- DEFAULT_CACHE_MISS_BILLING_SETTINGS.freshWindowMinutes;
838
- }
839
- else if (typeof raw.freshWindowMinutes !== "number" ||
840
- !Number.isInteger(raw.freshWindowMinutes) ||
841
- raw.freshWindowMinutes < 1 ||
842
- raw.freshWindowMinutes > 1440) {
843
- return null;
844
- }
845
- else {
846
- parsed.freshWindowMinutes = raw.freshWindowMinutes;
847
- }
848
- }
849
- if ("providerFreshWindowMinutes" in raw) {
850
- if (raw.providerFreshWindowMinutes === undefined ||
851
- raw.providerFreshWindowMinutes === null) {
852
- parsed.providerFreshWindowMinutes =
853
- DEFAULT_CACHE_MISS_BILLING_SETTINGS.providerFreshWindowMinutes;
854
- }
855
- else if (!isRecord(raw.providerFreshWindowMinutes)) {
856
- return null;
857
- }
858
- else {
859
- const providerFreshWindowMinutes = {};
860
- for (const [providerName, value] of Object.entries(raw.providerFreshWindowMinutes)) {
861
- if (!ALL_PROVIDERS.includes(providerName)) {
862
- return null;
863
- }
864
- if (typeof value !== "number" ||
865
- !Number.isInteger(value) ||
866
- value < 1 ||
867
- value > 1440) {
868
- return null;
869
- }
870
- providerFreshWindowMinutes[providerName] = value;
871
- }
872
- parsed.providerFreshWindowMinutes = providerFreshWindowMinutes;
873
- }
874
- }
875
- if ("minimumInputTokens" in raw) {
876
- if (raw.minimumInputTokens === undefined ||
877
- raw.minimumInputTokens === null) {
878
- parsed.minimumInputTokens =
879
- DEFAULT_CACHE_MISS_BILLING_SETTINGS.minimumInputTokens;
880
- }
881
- else if (typeof raw.minimumInputTokens !== "number" ||
882
- !Number.isInteger(raw.minimumInputTokens) ||
883
- raw.minimumInputTokens < 1 ||
884
- raw.minimumInputTokens > 5_000_000) {
885
- return null;
886
- }
887
- else {
888
- parsed.minimumInputTokens = raw.minimumInputTokens;
889
- }
890
- }
891
- const result = {
892
- ...DEFAULT_CACHE_MISS_BILLING_SETTINGS,
893
- ...parsed,
894
- providerFreshWindowMinutes: {
895
- ...DEFAULT_CACHE_MISS_BILLING_SETTINGS.providerFreshWindowMinutes,
896
- ...parsed.providerFreshWindowMinutes,
897
- },
898
- };
899
- return result;
900
- }
10
+ import { discoverOpenAiCompatibleModels, mergeClientDefaults, normalizeOpenAiCompatibleBaseUrl, parseAgentContextHints, parseCacheMissBilling, parseClientDefaults, parseFileAccess, parseHelperTargets, parseHostAliasList, parseNewSessionDefaults, parsePromptCacheKeepalive, parseSpeechAudioRetention, } from "./settings-parsers.js";
901
11
  export function createSettingsRoutes(deps) {
902
12
  const app = new Hono();
903
13
  const { serverSettingsService, sessionMetadataService, onAllowedHostsChanged, onFileAccessChanged, onRemoteSessionPersistenceChanged, onOllamaUrlChanged, onOllamaSystemPromptChanged, onOllamaUseFullSystemPromptChanged, onGrokBuildUseXaiApiKeyChanged, publicShareService, } = deps;