waypoi 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/.github/instructions/ui.instructions.md +42 -0
  2. package/.github/workflows/ci.yml +35 -0
  3. package/.github/workflows/publish.yml +71 -0
  4. package/.github/workflows/release.yml +48 -0
  5. package/.playwright-mcp/console-2026-04-04T01-41-10-746Z.log +2 -0
  6. package/.playwright-mcp/console-2026-04-04T01-41-28-799Z.log +3 -0
  7. package/.playwright-mcp/console-2026-04-05T02-26-51-909Z.log +76 -0
  8. package/.playwright-mcp/page-2026-04-04T01-41-10-816Z.yml +1 -0
  9. package/.playwright-mcp/page-2026-04-04T01-41-29-141Z.yml +77 -0
  10. package/.playwright-mcp/page-2026-04-04T01-41-42-633Z.yml +190 -0
  11. package/.playwright-mcp/page-2026-04-04T01-42-03-929Z.yml +262 -0
  12. package/.playwright-mcp/page-2026-04-04T02-12-54-813Z.yml +6 -0
  13. package/.playwright-mcp/page-2026-04-04T02-14-58-600Z.yml +190 -0
  14. package/.playwright-mcp/page-2026-04-04T02-15-03-923Z.yml +190 -0
  15. package/.playwright-mcp/page-2026-04-04T02-15-07-426Z.yml +190 -0
  16. package/.playwright-mcp/page-2026-04-04T02-15-25-729Z.yml +262 -0
  17. package/.playwright-mcp/page-2026-04-04T02-16-22-984Z.yml +262 -0
  18. package/.playwright-mcp/page-2026-04-04T02-17-00-599Z.yml +190 -0
  19. package/.playwright-mcp/page-2026-04-04T02-17-50-874Z.yml +190 -0
  20. package/.playwright-mcp/page-2026-04-05T02-26-55-570Z.yml +6 -0
  21. package/AGENTS.md +48 -0
  22. package/CHANGELOG.md +131 -0
  23. package/README.md +552 -0
  24. package/assets/agent-mode.png +0 -0
  25. package/assets/categorize.png +0 -0
  26. package/assets/dashboard.png +0 -0
  27. package/assets/endpoint-proxy.png +0 -0
  28. package/assets/icon.png +0 -0
  29. package/assets/mcp-generate-image.png +0 -0
  30. package/assets/mcp-understand-image.png +0 -0
  31. package/assets/peek-token-flow.png +0 -0
  32. package/assets/playground.png +0 -0
  33. package/assets/sankey.png +0 -0
  34. package/cli/index.ts +2805 -0
  35. package/cli/legacyRewrite.ts +108 -0
  36. package/cli/modelRef.ts +24 -0
  37. package/dist/cli/index.js +2536 -0
  38. package/dist/cli/legacyRewrite.js +92 -0
  39. package/dist/cli/modelRef.js +20 -0
  40. package/dist/src/benchmark/artifacts.js +131 -0
  41. package/dist/src/benchmark/capabilityClassifier.js +81 -0
  42. package/dist/src/benchmark/capabilityStore.js +144 -0
  43. package/dist/src/benchmark/config.js +238 -0
  44. package/dist/src/benchmark/gates.js +118 -0
  45. package/dist/src/benchmark/jobs.js +252 -0
  46. package/dist/src/benchmark/runner.js +1847 -0
  47. package/dist/src/benchmark/schema.js +353 -0
  48. package/dist/src/benchmark/suites.js +314 -0
  49. package/dist/src/benchmark/tinyQaDataset.js +422 -0
  50. package/dist/src/benchmark/types.js +25 -0
  51. package/dist/src/config.js +47 -0
  52. package/dist/src/index.js +178 -0
  53. package/dist/src/mcp/client.js +215 -0
  54. package/dist/src/mcp/discovery.js +226 -0
  55. package/dist/src/mcp/policy.js +65 -0
  56. package/dist/src/mcp/registry.js +129 -0
  57. package/dist/src/mcp/service.js +460 -0
  58. package/dist/src/middleware/auth.js +179 -0
  59. package/dist/src/middleware/requestCapture.js +192 -0
  60. package/dist/src/middleware/requestStats.js +118 -0
  61. package/dist/src/pools/builder.js +132 -0
  62. package/dist/src/pools/repository.js +69 -0
  63. package/dist/src/pools/scheduler.js +360 -0
  64. package/dist/src/pools/types.js +2 -0
  65. package/dist/src/protocols/adapters/dashscope.js +267 -0
  66. package/dist/src/protocols/adapters/inferenceV2.js +346 -0
  67. package/dist/src/protocols/adapters/openai.js +27 -0
  68. package/dist/src/protocols/registry.js +99 -0
  69. package/dist/src/protocols/types.js +2 -0
  70. package/dist/src/providers/health.js +153 -0
  71. package/dist/src/providers/importer.js +289 -0
  72. package/dist/src/providers/modelRegistry.js +313 -0
  73. package/dist/src/providers/repository.js +361 -0
  74. package/dist/src/providers/types.js +2 -0
  75. package/dist/src/routes/admin.js +531 -0
  76. package/dist/src/routes/audio.js +295 -0
  77. package/dist/src/routes/chat.js +240 -0
  78. package/dist/src/routes/embeddings.js +157 -0
  79. package/dist/src/routes/images.js +288 -0
  80. package/dist/src/routes/mcp.js +256 -0
  81. package/dist/src/routes/mcpService.js +100 -0
  82. package/dist/src/routes/models.js +48 -0
  83. package/dist/src/routes/responses.js +711 -0
  84. package/dist/src/routes/sessions.js +450 -0
  85. package/dist/src/routes/stats.js +270 -0
  86. package/dist/src/routes/ui.js +97 -0
  87. package/dist/src/routes/videos.js +107 -0
  88. package/dist/src/routing/router.js +338 -0
  89. package/dist/src/services/imageGeneration.js +280 -0
  90. package/dist/src/services/imageUnderstanding.js +352 -0
  91. package/dist/src/services/videoGeneration.js +79 -0
  92. package/dist/src/storage/captureRepository.js +1591 -0
  93. package/dist/src/storage/files.js +157 -0
  94. package/dist/src/storage/imageCache.js +346 -0
  95. package/dist/src/storage/repositories.js +388 -0
  96. package/dist/src/storage/sessionRepository.js +370 -0
  97. package/dist/src/storage/statsRepository.js +204 -0
  98. package/dist/src/transport/httpClient.js +126 -0
  99. package/dist/src/types.js +2 -0
  100. package/dist/src/utils/messageMedia.js +285 -0
  101. package/dist/src/utils/modelCapabilities.js +108 -0
  102. package/dist/src/utils/modelDiscovery.js +170 -0
  103. package/dist/src/version.js +5 -0
  104. package/dist/src/workers/captureRetention.js +25 -0
  105. package/dist/src/workers/configWatcher.js +91 -0
  106. package/dist/src/workers/healthChecker.js +21 -0
  107. package/dist/src/workers/statsRotation.js +41 -0
  108. package/docs/LLM/output_schema.md +312 -0
  109. package/docs/benchmark.md +208 -0
  110. package/docs/mcp-guidelines.md +125 -0
  111. package/docs/mcp-service.md +178 -0
  112. package/docs/opencode.md +86 -0
  113. package/docs/providers.md +79 -0
  114. package/examples/benchmark.config.yaml +28 -0
  115. package/examples/providers/alibaba-dashscope.yaml +88 -0
  116. package/examples/providers/alibaba-llm.yaml +64 -0
  117. package/examples/providers/alibaba-registry.yaml +7 -0
  118. package/examples/providers/inference-v2-ray.yaml +29 -0
  119. package/examples/scenarios/assets/omni-call-sample.wav +0 -0
  120. package/examples/scenarios/custom.jsonl +5 -0
  121. package/examples/scenarios/custom.yaml +40 -0
  122. package/model-form-v2.png +0 -0
  123. package/package.json +66 -0
  124. package/provider-form-v2.png +0 -0
  125. package/provider-form.png +0 -0
  126. package/scripts/manual-test.sh +11 -0
  127. package/scripts/version-from-git.js +23 -0
  128. package/src/benchmark/artifacts.ts +149 -0
  129. package/src/benchmark/capabilityClassifier.ts +99 -0
  130. package/src/benchmark/capabilityStore.ts +174 -0
  131. package/src/benchmark/config.ts +337 -0
  132. package/src/benchmark/gates.ts +164 -0
  133. package/src/benchmark/jobs.ts +312 -0
  134. package/src/benchmark/runner.ts +2519 -0
  135. package/src/benchmark/schema.ts +443 -0
  136. package/src/benchmark/suites.ts +323 -0
  137. package/src/benchmark/tinyQaDataset.ts +428 -0
  138. package/src/benchmark/types.ts +442 -0
  139. package/src/config.ts +44 -0
  140. package/src/index.ts +195 -0
  141. package/src/mcp/client.ts +305 -0
  142. package/src/mcp/discovery.ts +266 -0
  143. package/src/mcp/policy.ts +105 -0
  144. package/src/mcp/registry.ts +164 -0
  145. package/src/mcp/service.ts +611 -0
  146. package/src/middleware/auth.ts +251 -0
  147. package/src/middleware/requestCapture.ts +245 -0
  148. package/src/middleware/requestStats.ts +163 -0
  149. package/src/pools/builder.ts +159 -0
  150. package/src/pools/repository.ts +71 -0
  151. package/src/pools/scheduler.ts +425 -0
  152. package/src/pools/types.ts +117 -0
  153. package/src/protocols/adapters/dashscope.ts +335 -0
  154. package/src/protocols/adapters/inferenceV2.ts +428 -0
  155. package/src/protocols/adapters/openai.ts +32 -0
  156. package/src/protocols/registry.ts +117 -0
  157. package/src/protocols/types.ts +81 -0
  158. package/src/providers/health.ts +207 -0
  159. package/src/providers/importer.ts +402 -0
  160. package/src/providers/modelRegistry.ts +415 -0
  161. package/src/providers/repository.ts +439 -0
  162. package/src/providers/types.ts +113 -0
  163. package/src/routes/admin.ts +666 -0
  164. package/src/routes/audio.ts +372 -0
  165. package/src/routes/chat.ts +301 -0
  166. package/src/routes/embeddings.ts +197 -0
  167. package/src/routes/images.ts +356 -0
  168. package/src/routes/mcp.ts +320 -0
  169. package/src/routes/mcpService.ts +114 -0
  170. package/src/routes/models.ts +50 -0
  171. package/src/routes/responses.ts +872 -0
  172. package/src/routes/sessions.ts +558 -0
  173. package/src/routes/stats.ts +312 -0
  174. package/src/routes/ui.ts +96 -0
  175. package/src/routes/videos.ts +132 -0
  176. package/src/routing/router.ts +501 -0
  177. package/src/services/imageGeneration.ts +396 -0
  178. package/src/services/imageUnderstanding.ts +449 -0
  179. package/src/services/videoGeneration.ts +127 -0
  180. package/src/storage/captureRepository.ts +1835 -0
  181. package/src/storage/files.ts +178 -0
  182. package/src/storage/imageCache.ts +405 -0
  183. package/src/storage/repositories.ts +494 -0
  184. package/src/storage/sessionRepository.ts +419 -0
  185. package/src/storage/statsRepository.ts +238 -0
  186. package/src/transport/httpClient.ts +145 -0
  187. package/src/types.ts +322 -0
  188. package/src/utils/messageMedia.ts +293 -0
  189. package/src/utils/modelCapabilities.ts +161 -0
  190. package/src/utils/modelDiscovery.ts +203 -0
  191. package/src/workers/captureRetention.ts +25 -0
  192. package/src/workers/configWatcher.ts +115 -0
  193. package/src/workers/healthChecker.ts +22 -0
  194. package/src/workers/statsRotation.ts +49 -0
  195. package/tests/benchmarkAdminRoutes.test.ts +82 -0
  196. package/tests/benchmarkBasics.test.ts +116 -0
  197. package/tests/captureAdminRoutes.test.ts +420 -0
  198. package/tests/captureRepository.test.ts +797 -0
  199. package/tests/cliLegacyRewrite.test.ts +45 -0
  200. package/tests/imageGeneration.service.test.ts +107 -0
  201. package/tests/imageUnderstanding.service.test.ts +123 -0
  202. package/tests/mcpPolicy.test.ts +105 -0
  203. package/tests/mcpService.test.ts +1245 -0
  204. package/tests/modelRef.test.ts +23 -0
  205. package/tests/modelsRoutes.test.ts +154 -0
  206. package/tests/sessionMediaCache.test.ts +167 -0
  207. package/tests/statsRoutes.test.ts +323 -0
  208. package/tsconfig.json +15 -0
  209. package/ui/index.html +16 -0
  210. package/ui/package-lock.json +8521 -0
  211. package/ui/package.json +52 -0
  212. package/ui/postcss.config.js +6 -0
  213. package/ui/public/assets/apple-touch-icon.png +0 -0
  214. package/ui/public/assets/favicon-16.png +0 -0
  215. package/ui/public/assets/favicon-32.png +0 -0
  216. package/ui/public/assets/icon-192.png +0 -0
  217. package/ui/public/assets/icon-512.png +0 -0
  218. package/ui/src/App.tsx +27 -0
  219. package/ui/src/api/client.ts +1503 -0
  220. package/ui/src/components/EndpointUsageGuide.tsx +361 -0
  221. package/ui/src/components/Layout.tsx +124 -0
  222. package/ui/src/components/MessageContent.tsx +365 -0
  223. package/ui/src/components/ToolCallMessage.tsx +179 -0
  224. package/ui/src/components/ToolPicker.tsx +442 -0
  225. package/ui/src/components/messageContentParser.test.ts +41 -0
  226. package/ui/src/components/messageContentParser.ts +73 -0
  227. package/ui/src/components/thinkingPreview.test.ts +27 -0
  228. package/ui/src/components/thinkingPreview.ts +15 -0
  229. package/ui/src/components/toMermaidSankey.test.ts +78 -0
  230. package/ui/src/components/toMermaidSankey.ts +56 -0
  231. package/ui/src/components/ui/button.tsx +58 -0
  232. package/ui/src/components/ui/input.tsx +21 -0
  233. package/ui/src/components/ui/textarea.tsx +21 -0
  234. package/ui/src/lib/utils.ts +6 -0
  235. package/ui/src/main.tsx +9 -0
  236. package/ui/src/pages/AgentPlayground.tsx +2010 -0
  237. package/ui/src/pages/Benchmark.tsx +988 -0
  238. package/ui/src/pages/Dashboard.tsx +581 -0
  239. package/ui/src/pages/Peek.tsx +962 -0
  240. package/ui/src/pages/Settings.tsx +2013 -0
  241. package/ui/src/pages/agentPlaygroundPayload.test.ts +109 -0
  242. package/ui/src/pages/agentPlaygroundPayload.ts +97 -0
  243. package/ui/src/pages/agentThinkingContent.test.ts +50 -0
  244. package/ui/src/pages/agentThinkingContent.ts +57 -0
  245. package/ui/src/pages/dashboardTokenUsage.test.ts +66 -0
  246. package/ui/src/pages/dashboardTokenUsage.ts +36 -0
  247. package/ui/src/pages/imageUpload.test.ts +39 -0
  248. package/ui/src/pages/imageUpload.ts +71 -0
  249. package/ui/src/pages/peekFilters.test.ts +29 -0
  250. package/ui/src/pages/peekFilters.ts +13 -0
  251. package/ui/src/pages/peekMedia.test.ts +58 -0
  252. package/ui/src/pages/peekMedia.ts +148 -0
  253. package/ui/src/pages/sessionAutoTitle.test.ts +128 -0
  254. package/ui/src/pages/sessionAutoTitle.ts +106 -0
  255. package/ui/src/stores/settings.ts +58 -0
  256. package/ui/src/styles/globals.css +223 -0
  257. package/ui/src/vite-env.d.ts +8 -0
  258. package/ui/tailwind.config.js +106 -0
  259. package/ui/tsconfig.json +32 -0
  260. package/ui/vite.config.ts +37 -0
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canonicalProviderModelId = canonicalProviderModelId;
4
+ exports.loadProviderStore = loadProviderStore;
5
+ exports.saveProviderStore = saveProviderStore;
6
+ exports.listProviders = listProviders;
7
+ exports.getProviderById = getProviderById;
8
+ exports.setProviderEnabled = setProviderEnabled;
9
+ exports.upsertProviders = upsertProviders;
10
+ exports.upsertProvider = upsertProvider;
11
+ exports.updateProvider = updateProvider;
12
+ exports.deleteProvider = deleteProvider;
13
+ exports.listProviderModels = listProviderModels;
14
+ exports.getProviderModel = getProviderModel;
15
+ exports.resolveProviderModelRef = resolveProviderModelRef;
16
+ exports.upsertProviderModel = upsertProviderModel;
17
+ exports.updateProviderModel = updateProviderModel;
18
+ exports.deleteProviderModel = deleteProviderModel;
19
+ exports.setProviderModelEnabled = setProviderModelEnabled;
20
+ exports.setProviderModelApiKey = setProviderModelApiKey;
21
+ exports.setProviderModelInsecureTls = setProviderModelInsecureTls;
22
+ exports.getEffectiveModelInsecureTls = getEffectiveModelInsecureTls;
23
+ exports.normalizeDomainSuffixes = normalizeDomainSuffixes;
24
+ const files_1 = require("../storage/files");
25
+ const CURRENT_VERSION = 3;
26
+ function defaultStore() {
27
+ return {
28
+ version: CURRENT_VERSION,
29
+ updatedAt: new Date().toISOString(),
30
+ providers: [],
31
+ };
32
+ }
33
+ function canonicalProviderModelId(providerId, modelId) {
34
+ return `${providerId}/${modelId}`;
35
+ }
36
+ async function loadProviderStore(paths) {
37
+ const store = await (0, files_1.readJsonFile)(paths.providersPath, defaultStore());
38
+ if (!Array.isArray(store.providers)) {
39
+ return defaultStore();
40
+ }
41
+ const providers = store.providers.map(normalizeProviderRecord);
42
+ return {
43
+ version: Number.isFinite(store.version) ? store.version : CURRENT_VERSION,
44
+ updatedAt: typeof store.updatedAt === "string" ? store.updatedAt : new Date().toISOString(),
45
+ providers,
46
+ };
47
+ }
48
+ async function saveProviderStore(paths, providers) {
49
+ const next = {
50
+ version: CURRENT_VERSION,
51
+ updatedAt: new Date().toISOString(),
52
+ providers: providers.map(normalizeProviderRecord),
53
+ };
54
+ await (0, files_1.writeJsonFile)(paths.providersPath, next);
55
+ }
56
+ async function listProviders(paths) {
57
+ const store = await loadProviderStore(paths);
58
+ return [...store.providers].sort((a, b) => a.id.localeCompare(b.id));
59
+ }
60
+ async function getProviderById(paths, providerId) {
61
+ const providers = await listProviders(paths);
62
+ return providers.find((provider) => provider.id === providerId) ?? null;
63
+ }
64
+ async function setProviderEnabled(paths, providerId, enabled) {
65
+ const store = await loadProviderStore(paths);
66
+ const index = store.providers.findIndex((provider) => provider.id === providerId);
67
+ if (index === -1) {
68
+ return null;
69
+ }
70
+ const updated = {
71
+ ...store.providers[index],
72
+ enabled,
73
+ };
74
+ store.providers[index] = normalizeProviderRecord(updated);
75
+ await saveProviderStore(paths, store.providers);
76
+ return store.providers[index];
77
+ }
78
+ async function upsertProviders(paths, providers) {
79
+ const existing = await loadProviderStore(paths);
80
+ const byId = new Map(existing.providers.map((provider) => [provider.id, normalizeProviderRecord(provider)]));
81
+ for (const provider of providers) {
82
+ const normalized = normalizeProviderRecord(provider);
83
+ const prev = byId.get(provider.id);
84
+ if (!prev) {
85
+ byId.set(provider.id, normalized);
86
+ continue;
87
+ }
88
+ const mergedByModelId = new Map(prev.models.map((model) => [model.providerModelId, model]));
89
+ for (const model of normalized.models) {
90
+ const previousModel = mergedByModelId.get(model.providerModelId);
91
+ mergedByModelId.set(model.providerModelId, normalizeProviderModelRecord({
92
+ ...model,
93
+ enabled: previousModel?.enabled ?? model.enabled,
94
+ apiKey: model.apiKey ?? previousModel?.apiKey,
95
+ aliases: model.aliases?.length ? model.aliases : previousModel?.aliases,
96
+ }));
97
+ }
98
+ byId.set(provider.id, normalizeProviderRecord({
99
+ ...normalized,
100
+ enabled: prev.enabled,
101
+ apiKey: normalized.apiKey ?? prev.apiKey,
102
+ insecureTls: provider.insecureTls ?? prev.insecureTls,
103
+ autoInsecureTlsDomains: provider.autoInsecureTlsDomains ?? prev.autoInsecureTlsDomains,
104
+ models: Array.from(mergedByModelId.values()),
105
+ }));
106
+ }
107
+ await saveProviderStore(paths, Array.from(byId.values()));
108
+ }
109
+ async function upsertProvider(paths, provider) {
110
+ const existing = await loadProviderStore(paths);
111
+ const index = existing.providers.findIndex((entry) => entry.id === provider.id);
112
+ if (index === -1) {
113
+ const normalized = normalizeProviderRecord(provider);
114
+ existing.providers.push(normalized);
115
+ await saveProviderStore(paths, existing.providers);
116
+ return normalized;
117
+ }
118
+ const prev = normalizeProviderRecord(existing.providers[index]);
119
+ const next = normalizeProviderRecord({
120
+ ...provider,
121
+ enabled: prev.enabled,
122
+ apiKey: provider.apiKey ?? prev.apiKey,
123
+ insecureTls: provider.insecureTls ?? prev.insecureTls,
124
+ autoInsecureTlsDomains: provider.autoInsecureTlsDomains ?? prev.autoInsecureTlsDomains,
125
+ });
126
+ existing.providers[index] = next;
127
+ await saveProviderStore(paths, existing.providers);
128
+ return next;
129
+ }
130
+ async function updateProvider(paths, providerId, patch) {
131
+ const store = await loadProviderStore(paths);
132
+ const index = store.providers.findIndex((provider) => provider.id === providerId);
133
+ if (index === -1) {
134
+ return null;
135
+ }
136
+ const current = normalizeProviderRecord(store.providers[index]);
137
+ const updated = normalizeProviderRecord({
138
+ ...current,
139
+ ...patch,
140
+ id: providerId,
141
+ models: patch.models ?? current.models,
142
+ });
143
+ store.providers[index] = updated;
144
+ await saveProviderStore(paths, store.providers);
145
+ return updated;
146
+ }
147
+ async function deleteProvider(paths, providerId) {
148
+ const store = await loadProviderStore(paths);
149
+ const index = store.providers.findIndex((provider) => provider.id === providerId);
150
+ if (index === -1) {
151
+ return null;
152
+ }
153
+ const [removed] = store.providers.splice(index, 1);
154
+ await saveProviderStore(paths, store.providers);
155
+ return normalizeProviderRecord(removed);
156
+ }
157
+ async function listProviderModels(paths, providerId) {
158
+ const provider = await getProviderById(paths, providerId);
159
+ if (!provider) {
160
+ return null;
161
+ }
162
+ return [...provider.models].sort((a, b) => a.modelId.localeCompare(b.modelId));
163
+ }
164
+ async function getProviderModel(paths, providerId, modelRef) {
165
+ const resolved = await resolveProviderModelRef(paths, providerId, modelRef);
166
+ if (!resolved) {
167
+ return null;
168
+ }
169
+ return resolved.model;
170
+ }
171
+ async function resolveProviderModelRef(paths, providerId, modelRef) {
172
+ const provider = await getProviderById(paths, providerId);
173
+ if (!provider) {
174
+ return null;
175
+ }
176
+ const normalizedRef = modelRef.trim();
177
+ const candidates = provider.models
178
+ .map((model, modelIndex) => ({ model, modelIndex }))
179
+ .filter(({ model }) => {
180
+ if (model.providerModelId === normalizedRef) {
181
+ return true;
182
+ }
183
+ if (canonicalProviderModelId(providerId, model.modelId) === normalizedRef) {
184
+ return true;
185
+ }
186
+ if (model.modelId === normalizedRef) {
187
+ return true;
188
+ }
189
+ return Boolean(model.aliases?.includes(normalizedRef));
190
+ });
191
+ if (candidates.length !== 1) {
192
+ return null;
193
+ }
194
+ return {
195
+ provider,
196
+ model: candidates[0].model,
197
+ modelIndex: candidates[0].modelIndex,
198
+ };
199
+ }
200
+ async function upsertProviderModel(paths, providerId, model) {
201
+ const store = await loadProviderStore(paths);
202
+ const providerIndex = store.providers.findIndex((provider) => provider.id === providerId);
203
+ if (providerIndex === -1) {
204
+ return null;
205
+ }
206
+ const provider = normalizeProviderRecord(store.providers[providerIndex]);
207
+ const normalizedModel = normalizeProviderModelRecord({
208
+ ...model,
209
+ providerId,
210
+ });
211
+ const modelIndex = provider.models.findIndex((entry) => entry.providerModelId === normalizedModel.providerModelId);
212
+ if (modelIndex === -1) {
213
+ provider.models.push(normalizedModel);
214
+ store.providers[providerIndex] = provider;
215
+ await saveProviderStore(paths, store.providers);
216
+ return { provider, created: true };
217
+ }
218
+ provider.models[modelIndex] = {
219
+ ...provider.models[modelIndex],
220
+ ...normalizedModel,
221
+ providerId,
222
+ };
223
+ store.providers[providerIndex] = provider;
224
+ await saveProviderStore(paths, store.providers);
225
+ return { provider, created: false };
226
+ }
227
+ async function updateProviderModel(paths, providerId, modelRef, patch) {
228
+ const store = await loadProviderStore(paths);
229
+ const providerIndex = store.providers.findIndex((provider) => provider.id === providerId);
230
+ if (providerIndex === -1) {
231
+ return null;
232
+ }
233
+ const provider = normalizeProviderRecord(store.providers[providerIndex]);
234
+ const matchingIndexes = provider.models.flatMap((model, index) => {
235
+ if (model.providerModelId === modelRef) {
236
+ return [index];
237
+ }
238
+ if (model.modelId === modelRef) {
239
+ return [index];
240
+ }
241
+ if (model.aliases?.includes(modelRef)) {
242
+ return [index];
243
+ }
244
+ return [];
245
+ });
246
+ if (matchingIndexes.length !== 1) {
247
+ return null;
248
+ }
249
+ const modelIndex = matchingIndexes[0];
250
+ const updated = normalizeProviderModelRecord({
251
+ ...provider.models[modelIndex],
252
+ ...patch,
253
+ providerId,
254
+ });
255
+ provider.models[modelIndex] = updated;
256
+ store.providers[providerIndex] = provider;
257
+ await saveProviderStore(paths, store.providers);
258
+ return updated;
259
+ }
260
+ async function deleteProviderModel(paths, providerId, modelRef) {
261
+ const store = await loadProviderStore(paths);
262
+ const providerIndex = store.providers.findIndex((provider) => provider.id === providerId);
263
+ if (providerIndex === -1) {
264
+ return null;
265
+ }
266
+ const provider = normalizeProviderRecord(store.providers[providerIndex]);
267
+ const matchingIndexes = provider.models.flatMap((model, index) => {
268
+ if (model.providerModelId === modelRef) {
269
+ return [index];
270
+ }
271
+ if (model.modelId === modelRef) {
272
+ return [index];
273
+ }
274
+ if (model.aliases?.includes(modelRef)) {
275
+ return [index];
276
+ }
277
+ return [];
278
+ });
279
+ if (matchingIndexes.length !== 1) {
280
+ return null;
281
+ }
282
+ const modelIndex = matchingIndexes[0];
283
+ const [removed] = provider.models.splice(modelIndex, 1);
284
+ store.providers[providerIndex] = provider;
285
+ await saveProviderStore(paths, store.providers);
286
+ return removed;
287
+ }
288
+ async function setProviderModelEnabled(paths, providerId, modelRef, enabled) {
289
+ return updateProviderModel(paths, providerId, modelRef, { enabled });
290
+ }
291
+ async function setProviderModelApiKey(paths, providerId, modelRef, apiKey) {
292
+ return updateProviderModel(paths, providerId, modelRef, { apiKey });
293
+ }
294
+ async function setProviderModelInsecureTls(paths, providerId, modelRef, insecureTls) {
295
+ return updateProviderModel(paths, providerId, modelRef, { insecureTls });
296
+ }
297
+ function getEffectiveModelInsecureTls(provider, model) {
298
+ return model.insecureTls ?? provider.insecureTls ?? false;
299
+ }
300
+ function normalizeProviderRecord(provider) {
301
+ const models = Array.isArray(provider.models) ? provider.models.map((model) => normalizeProviderModelRecord({
302
+ ...model,
303
+ providerId: provider.id,
304
+ })) : [];
305
+ return {
306
+ ...provider,
307
+ id: provider.id,
308
+ insecureTls: provider.insecureTls === true,
309
+ autoInsecureTlsDomains: normalizeDomainSuffixes(provider.autoInsecureTlsDomains),
310
+ models,
311
+ };
312
+ }
313
+ function normalizeProviderModelRecord(model) {
314
+ const aliases = normalizeAliases(model.aliases);
315
+ const providerId = model.providerId;
316
+ const modelId = model.modelId.trim();
317
+ return {
318
+ ...model,
319
+ providerId,
320
+ modelId,
321
+ providerModelId: model.providerModelId || canonicalProviderModelId(providerId, modelId),
322
+ aliases,
323
+ enabled: model.enabled ?? true,
324
+ };
325
+ }
326
+ function normalizeAliases(aliases) {
327
+ if (!Array.isArray(aliases)) {
328
+ return [];
329
+ }
330
+ const dedup = new Set();
331
+ for (const alias of aliases) {
332
+ const normalized = alias.trim();
333
+ if (normalized) {
334
+ dedup.add(normalized);
335
+ }
336
+ }
337
+ return Array.from(dedup);
338
+ }
339
+ function normalizeDomainSuffixes(domains) {
340
+ if (!Array.isArray(domains)) {
341
+ return [];
342
+ }
343
+ const dedup = new Set();
344
+ for (const domain of domains) {
345
+ let normalized = domain.trim().toLowerCase();
346
+ if (!normalized) {
347
+ continue;
348
+ }
349
+ if (normalized.startsWith("*.")) {
350
+ normalized = normalized.slice(2);
351
+ }
352
+ if (normalized.startsWith(".")) {
353
+ normalized = normalized.slice(1);
354
+ }
355
+ if (!normalized) {
356
+ continue;
357
+ }
358
+ dedup.add(normalized);
359
+ }
360
+ return Array.from(dedup);
361
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });