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