openfox 2.0.24 → 2.0.25

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 (45) hide show
  1. package/dist/auto-config-FZFXOEEG.js +169 -0
  2. package/dist/backend-AGXWAU7A.js +9 -0
  3. package/dist/{chat-handler-4ATHDLH4.js → chat-handler-XH3QUXIC.js} +28 -47
  4. package/dist/{chunk-XJ4SUDL7.js → chunk-2ELCWCO3.js} +32 -241
  5. package/dist/{chunk-QK6TYNUN.js → chunk-64NCACBV.js} +6 -6
  6. package/dist/{chunk-GI24G4OW.js → chunk-AYJTMZVU.js} +79 -59
  7. package/dist/{chunk-YVF3BLQS.js → chunk-GZOYGODG.js} +36 -22
  8. package/dist/chunk-HNCM3D7Y.js +28 -0
  9. package/dist/chunk-IEDE6VK4.js +124 -0
  10. package/dist/chunk-J2GP3J3X.js +97 -0
  11. package/dist/{chunk-INRKWEOH.js → chunk-L5FBH2YX.js} +116 -65
  12. package/dist/{chunk-4EDH3ZXL.js → chunk-LP5RXQW5.js} +3 -3
  13. package/dist/chunk-M3RB4IF6.js +114 -0
  14. package/dist/chunk-V4IE7HJY.js +175 -0
  15. package/dist/{chunk-MDRNKI7D.js → chunk-WCPFR6ZP.js} +55 -48
  16. package/dist/{chunk-CDIYCGCO.js → chunk-WEXW7ZXJ.js} +2 -2
  17. package/dist/{chunk-RYHCYZQ7.js → chunk-Y6STCE5Z.js} +26 -24
  18. package/dist/{chunk-YUHODMKY.js → chunk-YGSBVKFU.js} +11 -5
  19. package/dist/chunk-Z4FMBCJO.js +52 -0
  20. package/dist/chunk-ZJ4FP6RS.js +200 -0
  21. package/dist/cli/dev.js +1 -1
  22. package/dist/cli/index.js +1 -1
  23. package/dist/client-725U6BTX.js +13 -0
  24. package/dist/client-pure-5NOTSIRK.js +19 -0
  25. package/dist/{compactor-SEZEZSML.js → compactor-JMGSZ4DQ.js} +7 -4
  26. package/dist/http-client-SIPAW7IM.js +8 -0
  27. package/dist/{orchestrator-MFN7COWT.js → orchestrator-FRFKYO77.js} +16 -13
  28. package/dist/package.json +1 -1
  29. package/dist/{processor-W2ZSJVOJ.js → processor-YAMVUA7K.js} +30 -55
  30. package/dist/profiles-Q36ELWQF.js +9 -0
  31. package/dist/{provider-IMW3ITB7.js → provider-KB7GB2O2.js} +15 -9
  32. package/dist/provider-manager-5VAVOKHC.js +22 -0
  33. package/dist/{serve-ABSUHKT3.js → serve-XBIN2DEU.js} +23 -17
  34. package/dist/server/index.d.ts +9 -1
  35. package/dist/server/index.js +19 -13
  36. package/dist/{server-7EAYI7T4.js → server-VXOP7JUX.js} +18 -12
  37. package/dist/{tools-7CKTYL2G.js → tools-JDYXXX2N.js} +11 -8
  38. package/dist/url-utils-QWAHP54Q.js +15 -0
  39. package/dist/web/assets/{index-CkUCxzzC.css → index-BLOGpuPE.css} +1 -1
  40. package/dist/web/assets/{index-Bi5R_oF2.js → index-CtG8oo36.js} +66 -66
  41. package/dist/web/index.html +2 -2
  42. package/dist/web/sw.js +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-UUFEE7VR.js +0 -505
  45. package/dist/provider-manager-DNBMBP4D.js +0 -16
@@ -21,7 +21,7 @@ import {
21
21
  tokenFromPassword,
22
22
  verifyPassword,
23
23
  workflowExists
24
- } from "./chunk-RYHCYZQ7.js";
24
+ } from "./chunk-Y6STCE5Z.js";
25
25
  import {
26
26
  agentExists,
27
27
  createToolRegistry,
@@ -61,15 +61,7 @@ import {
61
61
  setMcpTools,
62
62
  setNotifyMcpServersChanged,
63
63
  skillExists
64
- } from "./chunk-MDRNKI7D.js";
65
- import {
66
- getProject
67
- } from "./chunk-O4TED6AJ.js";
68
- import {
69
- ALWAYS_ALLOWED,
70
- ALWAYS_ALLOWED_FOR_SUBAGENTS,
71
- TOP_LEVEL_ONLY_TOOLS
72
- } from "./chunk-YUHODMKY.js";
64
+ } from "./chunk-WCPFR6ZP.js";
73
65
  import {
74
66
  getPathSeparator,
75
67
  isAbsolutePath
@@ -77,6 +69,20 @@ import {
77
69
  import {
78
70
  createMcpTools
79
71
  } from "./chunk-NWO6GRYE.js";
72
+ import {
73
+ createContextStateMessage
74
+ } from "./chunk-F4PMNP7S.js";
75
+ import {
76
+ EventEmitter
77
+ } from "./chunk-EU3WWTFH.js";
78
+ import {
79
+ getProject
80
+ } from "./chunk-O4TED6AJ.js";
81
+ import {
82
+ ALWAYS_ALLOWED,
83
+ ALWAYS_ALLOWED_FOR_SUBAGENTS,
84
+ TOP_LEVEL_ONLY_TOOLS
85
+ } from "./chunk-YGSBVKFU.js";
80
86
  import {
81
87
  createSession,
82
88
  deleteSession,
@@ -102,40 +108,39 @@ import {
102
108
  updateSessionProvider,
103
109
  updateSessionRunning
104
110
  } from "./chunk-YBWY4DKY.js";
105
- import {
106
- createContextStateMessage
107
- } from "./chunk-F4PMNP7S.js";
108
- import {
109
- EventEmitter
110
- } from "./chunk-EU3WWTFH.js";
111
111
  import {
112
112
  initDatabase
113
113
  } from "./chunk-FBGWG4N6.js";
114
- import {
115
- createServerMessage
116
- } from "./chunk-YD6NDTKF.js";
117
- import {
118
- getGlobalConfigDir
119
- } from "./chunk-CQGTEGKL.js";
120
114
  import {
121
115
  createProviderManager,
122
116
  parseDefaultModelSelection
123
- } from "./chunk-YVF3BLQS.js";
117
+ } from "./chunk-GZOYGODG.js";
124
118
  import {
125
- SessionNotFoundError,
126
- buildModelsUrl,
127
119
  detectModel,
128
- ensureVersionPrefix,
129
120
  getLlmStatus
130
- } from "./chunk-XJ4SUDL7.js";
121
+ } from "./chunk-M3RB4IF6.js";
131
122
  import {
132
- getBackendDisplayName,
133
- getModelProfile
134
- } from "./chunk-UUFEE7VR.js";
123
+ getBackendDisplayName
124
+ } from "./chunk-Z4FMBCJO.js";
125
+ import {
126
+ buildModelsUrl
127
+ } from "./chunk-HNCM3D7Y.js";
128
+ import {
129
+ SessionNotFoundError
130
+ } from "./chunk-IEDE6VK4.js";
135
131
  import {
136
132
  logger,
137
133
  setLogLevel
138
134
  } from "./chunk-K44MW7JJ.js";
135
+ import {
136
+ createServerMessage
137
+ } from "./chunk-YD6NDTKF.js";
138
+ import {
139
+ getGlobalConfigDir
140
+ } from "./chunk-CQGTEGKL.js";
141
+ import {
142
+ getModelProfile
143
+ } from "./chunk-V4IE7HJY.js";
139
144
 
140
145
  // src/server/index.ts
141
146
  import express from "express";
@@ -3443,7 +3448,7 @@ import { Router as Router6 } from "express";
3443
3448
  import { spawn as spawn2 } from "child_process";
3444
3449
 
3445
3450
  // src/constants.ts
3446
- var VERSION = "2.0.24";
3451
+ var VERSION = "2.0.25";
3447
3452
 
3448
3453
  // src/server/routes/auto-update.ts
3449
3454
  var updateInProgress = false;
@@ -3623,7 +3628,7 @@ async function createServerHandle(config4) {
3623
3628
  setMcpTools(mcpTools);
3624
3629
  logger.info("MCP tools registered", { count: mcpTools.length });
3625
3630
  }
3626
- const { signalMcpReady } = await import("./server-7EAYI7T4.js");
3631
+ const { signalMcpReady } = await import("./server-VXOP7JUX.js");
3627
3632
  signalMcpReady();
3628
3633
  });
3629
3634
  const app = express();
@@ -3816,7 +3821,7 @@ async function createServerHandle(config4) {
3816
3821
  app.get("/api/sessions/:id", async (req, res) => {
3817
3822
  const { getEventStore: getEventStore2 } = await import("./events-JKPHAR5W.js");
3818
3823
  const { buildMessagesFromStoredEvents } = await import("./folding-PI67HWBR.js");
3819
- const { getPendingQuestionsForSession } = await import("./tools-7CKTYL2G.js");
3824
+ const { getPendingQuestionsForSession } = await import("./tools-JDYXXX2N.js");
3820
3825
  const session = sessionManager.getSession(req.params.id);
3821
3826
  if (!session) {
3822
3827
  return res.status(404).json({ error: "Session not found" });
@@ -3947,7 +3952,7 @@ async function createServerHandle(config4) {
3947
3952
  if (!callId || approved === void 0) {
3948
3953
  return res.status(400).json({ error: "callId and approved are required" });
3949
3954
  }
3950
- const { providePathConfirmation } = await import("./tools-7CKTYL2G.js");
3955
+ const { providePathConfirmation } = await import("./tools-JDYXXX2N.js");
3951
3956
  const result = providePathConfirmation(callId, approved, alwaysAllow);
3952
3957
  if (!result.found) {
3953
3958
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -3955,7 +3960,7 @@ async function createServerHandle(config4) {
3955
3960
  const { getEventStore: getEventStore2 } = await import("./events-JKPHAR5W.js");
3956
3961
  const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-PI67HWBR.js");
3957
3962
  const { createSessionStateMessage } = await import("./protocol-BKNLAEPJ.js");
3958
- const { getPendingQuestionsForSession } = await import("./tools-7CKTYL2G.js");
3963
+ const { getPendingQuestionsForSession } = await import("./tools-JDYXXX2N.js");
3959
3964
  const eventStore = getEventStore2();
3960
3965
  const events = eventStore.getEvents(sessionId);
3961
3966
  const messages = buildMessagesFromStoredEvents(events);
@@ -3976,7 +3981,7 @@ async function createServerHandle(config4) {
3976
3981
  if (!skip && typeof answer !== "string") {
3977
3982
  return res.status(400).json({ error: "answer is required when not skipping" });
3978
3983
  }
3979
- const { provideAnswer } = await import("./tools-7CKTYL2G.js");
3984
+ const { provideAnswer } = await import("./tools-JDYXXX2N.js");
3980
3985
  const found = provideAnswer(callId, answer ?? "", skip ?? false);
3981
3986
  if (!found) {
3982
3987
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -4012,8 +4017,8 @@ async function createServerHandle(config4) {
4012
4017
  if (!session) {
4013
4018
  return res.status(404).json({ error: "Session not found" });
4014
4019
  }
4015
- const { stopSessionExecution } = await import("./chat-handler-4ATHDLH4.js");
4016
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-7CKTYL2G.js");
4020
+ const { stopSessionExecution } = await import("./chat-handler-XH3QUXIC.js");
4021
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-JDYXXX2N.js");
4017
4022
  const queuedMessages = sessionManager.getQueueState(sessionId);
4018
4023
  sessionManager.clearMessageQueue(sessionId);
4019
4024
  stopSessionExecution(sessionId, sessionManager);
@@ -4220,7 +4225,7 @@ async function createServerHandle(config4) {
4220
4225
  const apiKey = req.query["apiKey"];
4221
4226
  if (!url) return res.status(400).json({ error: "url is required" });
4222
4227
  try {
4223
- const { fetchModelsWithContext } = await import("./provider-manager-DNBMBP4D.js");
4228
+ const { fetchModelsWithContext } = await import("./provider-manager-5VAVOKHC.js");
4224
4229
  const models = await fetchModelsWithContext(url, apiKey);
4225
4230
  if (models.length === 0) {
4226
4231
  return res.status(404).json({ error: `No models found at ${buildModelsUrl(url)}`, url });
@@ -4243,36 +4248,82 @@ async function createServerHandle(config4) {
4243
4248
  });
4244
4249
  }
4245
4250
  });
4251
+ app.post("/api/providers/auto-config", async (req, res) => {
4252
+ const { url, apiKey, backend, models } = req.body;
4253
+ if (!url) return res.status(400).json({ error: "url is required" });
4254
+ if (!models?.length) return res.status(400).json({ error: "models is required" });
4255
+ try {
4256
+ const { autoConfig } = await import("./auto-config-FZFXOEEG.js");
4257
+ const result = await autoConfig({
4258
+ url,
4259
+ ...apiKey ? { apiKey } : {},
4260
+ backend: backend || "unknown",
4261
+ models
4262
+ });
4263
+ res.json(result);
4264
+ } catch (error) {
4265
+ res.status(500).json({ error: error instanceof Error ? error.message : "Auto-config failed" });
4266
+ }
4267
+ });
4246
4268
  app.post("/api/providers/test-params", async (req, res) => {
4247
- const { url, model, params, apiKey, queryParams } = req.body;
4269
+ const { url, model, apiKey, backend, thinkingField, mode, modelConfig } = req.body;
4248
4270
  if (!url) return res.status(400).json({ error: "url is required" });
4249
4271
  if (!model) return res.status(400).json({ error: "model is required" });
4272
+ if (!mode) return res.status(400).json({ error: "mode is required" });
4250
4273
  try {
4251
- const headers = { "Content-Type": "application/json" };
4252
- if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
4253
- const hasQueryParams = queryParams && Object.keys(queryParams).length > 0;
4254
- const body = {
4274
+ const { getModelProfile: getModelProfile2 } = await import("./profiles-Q36ELWQF.js");
4275
+ const { getBackendCapabilities } = await import("./backend-AGXWAU7A.js");
4276
+ const { buildNonStreamingCreateParams } = await import("./client-pure-5NOTSIRK.js");
4277
+ const { OpenAIHttpClient } = await import("./http-client-SIPAW7IM.js");
4278
+ const { ensureVersionPrefix } = await import("./url-utils-QWAHP54Q.js");
4279
+ const profile = getModelProfile2(model);
4280
+ const capabilities = getBackendCapabilities(backend || "unknown");
4281
+ const modelSettings = {};
4282
+ if (modelConfig?.temperature !== void 0) modelSettings["temperature"] = modelConfig.temperature;
4283
+ if (modelConfig?.topP !== void 0) modelSettings["topP"] = modelConfig.topP;
4284
+ if (modelConfig?.topK !== void 0) modelSettings["topK"] = modelConfig.topK;
4285
+ if (modelConfig?.maxTokens !== void 0) modelSettings["maxTokens"] = modelConfig.maxTokens;
4286
+ if (modelConfig?.supportsVision !== void 0) modelSettings["supportsVision"] = modelConfig.supportsVision;
4287
+ const rawQP = mode === "thinking" ? modelConfig?.thinkingQueryParams : modelConfig?.nonThinkingQueryParams;
4288
+ if (rawQP) {
4289
+ modelSettings["queryParams"] = JSON.parse(rawQP);
4290
+ } else {
4291
+ const modeEnabled = mode === "thinking" ? modelConfig?.thinkingEnabled : modelConfig?.nonThinkingEnabled;
4292
+ if (modeEnabled) {
4293
+ modelSettings["chatTemplateKwargs"] = mode === "thinking" ? { enable_thinking: true } : { enable_thinking: false };
4294
+ }
4295
+ }
4296
+ let reasoningEffort;
4297
+ if (mode === "thinking" && modelConfig?.thinkingEnabled && modelConfig?.thinkingLevel) {
4298
+ reasoningEffort = modelConfig.thinkingLevel;
4299
+ }
4300
+ const hasModelSettings = Object.keys(modelSettings).length > 0;
4301
+ const { params } = await buildNonStreamingCreateParams({
4255
4302
  model,
4256
- messages: [{ role: "user", content: "say hi in one word" }],
4257
- max_tokens: 8e3,
4258
- ...hasQueryParams ? {} : params,
4259
- ...hasQueryParams ? queryParams : {}
4260
- };
4261
- const response = await fetch(`${ensureVersionPrefix(url)}/chat/completions`, {
4262
- method: "POST",
4263
- headers,
4264
- body: JSON.stringify(body),
4265
- signal: AbortSignal.timeout(15e3)
4303
+ request: {
4304
+ messages: [{ role: "user", content: "say hi in one word" }],
4305
+ tools: [],
4306
+ ...hasModelSettings ? { modelSettings } : {},
4307
+ ...reasoningEffort ? { reasoningEffort } : {}
4308
+ },
4309
+ profile,
4310
+ capabilities,
4311
+ ...thinkingField ? { thinkingField } : {}
4312
+ });
4313
+ const httpClient = new OpenAIHttpClient({
4314
+ baseURL: ensureVersionPrefix(url),
4315
+ apiKey: apiKey ?? "not-needed"
4316
+ });
4317
+ const response = await httpClient.createChatCompletion(params, { signal: AbortSignal.timeout(15e3) }, true);
4318
+ res.json({
4319
+ success: true,
4320
+ message: response.choices?.[0]?.message ?? {},
4321
+ raw: response.raw
4266
4322
  });
4267
- if (!response.ok) {
4268
- const errorBody = await response.text();
4269
- return res.status(400).json({ error: `API error (${response.status}): ${errorBody.slice(0, 2e3)}` });
4270
- }
4271
- const data = await response.json();
4272
- const message = data.choices?.[0]?.message ?? {};
4273
- res.json({ success: true, message, raw: JSON.stringify(data, null, 2).slice(0, 2e3) });
4274
4323
  } catch (error) {
4275
- res.status(400).json({ error: error instanceof Error ? error.message : "Request failed" });
4324
+ res.status(400).json({
4325
+ error: error instanceof Error ? error.message : "Test failed"
4326
+ });
4276
4327
  }
4277
4328
  });
4278
4329
  app.post("/api/providers", async (req, res) => {
@@ -4456,7 +4507,7 @@ async function createServerHandle(config4) {
4456
4507
  });
4457
4508
  async function rebuildMcpTools() {
4458
4509
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-B7QP6NLA.js");
4459
- const { setMcpTools: setMcpTools2 } = await import("./tools-7CKTYL2G.js");
4510
+ const { setMcpTools: setMcpTools2 } = await import("./tools-JDYXXX2N.js");
4460
4511
  const mcpTools = createMcpTools2(mcpManager);
4461
4512
  setMcpTools2(mcpTools);
4462
4513
  }
@@ -4768,7 +4819,7 @@ async function createServerHandle(config4) {
4768
4819
  const state = sessionManager.getContextState(sessionId);
4769
4820
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
4770
4821
  });
4771
- const { QueueProcessor } = await import("./processor-W2ZSJVOJ.js");
4822
+ const { QueueProcessor } = await import("./processor-YAMVUA7K.js");
4772
4823
  const queueProcessor = new QueueProcessor({
4773
4824
  sessionManager,
4774
4825
  providerManager,
@@ -4843,4 +4894,4 @@ export {
4843
4894
  createServerHandle,
4844
4895
  createServer
4845
4896
  };
4846
- //# sourceMappingURL=chunk-INRKWEOH.js.map
4897
+ //# sourceMappingURL=chunk-L5FBH2YX.js.map
@@ -152,7 +152,7 @@ async function runCli(options) {
152
152
  break;
153
153
  }
154
154
  case "provider": {
155
- const { runProviderCommand } = await import("./provider-IMW3ITB7.js");
155
+ const { runProviderCommand } = await import("./provider-KB7GB2O2.js");
156
156
  const [, subcommand] = positionals;
157
157
  await runProviderCommand(mode, subcommand);
158
158
  break;
@@ -196,7 +196,7 @@ async function runCli(options) {
196
196
  if (!configExists) {
197
197
  await runNetworkSetup(mode);
198
198
  }
199
- const { runServe } = await import("./serve-ABSUHKT3.js");
199
+ const { runServe } = await import("./serve-XBIN2DEU.js");
200
200
  const serveOptions = { mode };
201
201
  if (values.port) serveOptions.port = parseInt(values.port);
202
202
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -208,4 +208,4 @@ async function runCli(options) {
208
208
  export {
209
209
  runCli
210
210
  };
211
- //# sourceMappingURL=chunk-4EDH3ZXL.js.map
211
+ //# sourceMappingURL=chunk-LP5RXQW5.js.map
@@ -0,0 +1,114 @@
1
+ import {
2
+ buildModelsUrl,
3
+ stripVersionPrefix
4
+ } from "./chunk-HNCM3D7Y.js";
5
+ import {
6
+ logger
7
+ } from "./chunk-K44MW7JJ.js";
8
+
9
+ // src/server/llm/models.ts
10
+ var modelCache = /* @__PURE__ */ new Map();
11
+ var llmStatus = "unknown";
12
+ var lastActiveUrl = null;
13
+ var CACHE_TTL_MS = 3e4;
14
+ function getCacheKey(url) {
15
+ return stripVersionPrefix(url);
16
+ }
17
+ async function detectModel(llmBaseUrl, retries = 3, silent = false) {
18
+ const cacheKey = getCacheKey(llmBaseUrl);
19
+ const now = Date.now();
20
+ const cached = modelCache.get(cacheKey);
21
+ if (cached && now - cached.timestamp < CACHE_TTL_MS) {
22
+ lastActiveUrl = cacheKey;
23
+ llmStatus = "connected";
24
+ return cached.model;
25
+ }
26
+ const url = buildModelsUrl(llmBaseUrl);
27
+ for (let attempt = 1; attempt <= retries; attempt++) {
28
+ try {
29
+ if (silent) {
30
+ logger.debug("Fetching models from LLM server", { url, attempt });
31
+ }
32
+ const response = await fetch(url, {
33
+ signal: AbortSignal.timeout(1e4)
34
+ });
35
+ if (!response.ok) {
36
+ if (silent) {
37
+ logger.debug("Failed to fetch models from LLM server", { status: response.status, attempt });
38
+ } else {
39
+ logger.warn("Failed to fetch models from LLM server", { status: response.status, attempt });
40
+ }
41
+ if (attempt < retries) {
42
+ await new Promise((r) => setTimeout(r, 1e3 * attempt));
43
+ continue;
44
+ }
45
+ llmStatus = "disconnected";
46
+ return cached?.model ?? null;
47
+ }
48
+ const data = await response.json();
49
+ if (data.data && data.data.length > 0) {
50
+ const modelData = data.data[0];
51
+ const modelId = modelData.id;
52
+ modelCache.set(cacheKey, {
53
+ model: modelId,
54
+ modelInfo: modelData,
55
+ timestamp: now
56
+ });
57
+ lastActiveUrl = cacheKey;
58
+ llmStatus = "connected";
59
+ if (silent) {
60
+ logger.debug("Detected LLM model", {
61
+ model: modelId,
62
+ maxLen: modelData.max_model_len,
63
+ root: modelData.root
64
+ });
65
+ } else {
66
+ logger.info("Detected LLM model", {
67
+ model: modelId,
68
+ maxLen: modelData.max_model_len,
69
+ root: modelData.root
70
+ });
71
+ }
72
+ return modelId;
73
+ }
74
+ if (silent) {
75
+ logger.debug("LLM server returned empty models list");
76
+ } else {
77
+ logger.warn("LLM server returned empty models list");
78
+ }
79
+ llmStatus = "disconnected";
80
+ return null;
81
+ } catch (error) {
82
+ const errMsg = error instanceof Error ? error.message : String(error);
83
+ if (silent) {
84
+ logger.debug("Could not detect model from LLM server", { error: errMsg, attempt });
85
+ } else {
86
+ logger.warn("Could not detect model from LLM server", { error: errMsg, attempt });
87
+ }
88
+ if (attempt < retries) {
89
+ await new Promise((r) => setTimeout(r, 1e3 * attempt));
90
+ continue;
91
+ }
92
+ }
93
+ }
94
+ llmStatus = "disconnected";
95
+ return cached?.model ?? null;
96
+ }
97
+ function getLlmStatus() {
98
+ return llmStatus;
99
+ }
100
+ function clearModelCache(url) {
101
+ if (url) {
102
+ modelCache.delete(getCacheKey(url));
103
+ } else {
104
+ modelCache.clear();
105
+ }
106
+ llmStatus = "unknown";
107
+ }
108
+
109
+ export {
110
+ detectModel,
111
+ getLlmStatus,
112
+ clearModelCache
113
+ };
114
+ //# sourceMappingURL=chunk-M3RB4IF6.js.map
@@ -0,0 +1,175 @@
1
+ // src/server/llm/profiles.ts
2
+ var DEFAULT_PROFILE = {
3
+ name: "default",
4
+ temperature: 0.7,
5
+ topP: 0.9,
6
+ defaultMaxTokens: 4096,
7
+ supportsVision: true
8
+ };
9
+ var MOCK_PROFILE = {
10
+ name: "mock",
11
+ temperature: 0.7,
12
+ topP: 0.9,
13
+ defaultMaxTokens: 1024,
14
+ supportsVision: false
15
+ };
16
+ var MODEL_PROFILES = [
17
+ {
18
+ pattern: "mistral",
19
+ profile: {
20
+ name: "Mistral",
21
+ temperature: 0.7,
22
+ topP: 0.9,
23
+ defaultMaxTokens: 16384,
24
+ supportsVision: false
25
+ }
26
+ },
27
+ {
28
+ pattern: "qwen3-coder-next",
29
+ profile: {
30
+ name: "Qwen3-Coder-Next",
31
+ // Per Qwen docs: "temperature=1.0, top_p=0.95, top_k=40"
32
+ temperature: 1,
33
+ topP: 0.95,
34
+ topK: 40,
35
+ // "This model supports only non-thinking mode and does not generate <think></think> blocks"
36
+ defaultMaxTokens: 16384,
37
+ supportsVision: false
38
+ }
39
+ },
40
+ {
41
+ pattern: "qwen3",
42
+ profile: {
43
+ name: "Qwen3",
44
+ temperature: 0.7,
45
+ topP: 0.9,
46
+ defaultMaxTokens: 16384,
47
+ supportsVision: false
48
+ }
49
+ },
50
+ {
51
+ pattern: "qwen3-vl",
52
+ profile: {
53
+ name: "Qwen3-VL",
54
+ temperature: 0.7,
55
+ topP: 0.9,
56
+ defaultMaxTokens: 16384,
57
+ supportsVision: true
58
+ }
59
+ },
60
+ {
61
+ pattern: "deepseek",
62
+ profile: {
63
+ name: "DeepSeek",
64
+ temperature: 0.6,
65
+ topP: 0.95,
66
+ defaultMaxTokens: 16384,
67
+ supportsVision: false
68
+ }
69
+ },
70
+ {
71
+ pattern: "minimax-m2.5",
72
+ profile: {
73
+ name: "MiniMax-M2.5",
74
+ temperature: 1,
75
+ topP: 0.95,
76
+ topK: 40,
77
+ defaultMaxTokens: 16384,
78
+ supportsVision: false
79
+ }
80
+ },
81
+ {
82
+ pattern: "minimax-m2.7",
83
+ profile: {
84
+ name: "MiniMax-M2.7",
85
+ temperature: 1,
86
+ topP: 0.95,
87
+ topK: 40,
88
+ defaultMaxTokens: 16384,
89
+ supportsVision: false
90
+ }
91
+ },
92
+ {
93
+ pattern: "minimax",
94
+ profile: {
95
+ name: "MiniMax",
96
+ temperature: 1,
97
+ topP: 0.95,
98
+ topK: 40,
99
+ defaultMaxTokens: 16384,
100
+ supportsVision: false
101
+ }
102
+ },
103
+ {
104
+ pattern: "minimax-m3",
105
+ profile: {
106
+ name: "MiniMax-M3",
107
+ temperature: 1,
108
+ topP: 0.95,
109
+ topK: 40,
110
+ defaultMaxTokens: 16384,
111
+ supportsVision: true
112
+ }
113
+ },
114
+ {
115
+ pattern: "llava",
116
+ profile: {
117
+ name: "LLaVA",
118
+ temperature: 0.7,
119
+ topP: 0.9,
120
+ defaultMaxTokens: 16384,
121
+ supportsVision: true
122
+ }
123
+ },
124
+ {
125
+ pattern: "llama",
126
+ profile: {
127
+ name: "Llama",
128
+ temperature: 0.7,
129
+ topP: 0.9,
130
+ defaultMaxTokens: 16384,
131
+ supportsVision: false
132
+ }
133
+ },
134
+ {
135
+ pattern: "claude",
136
+ profile: {
137
+ name: "Claude",
138
+ temperature: 0.7,
139
+ topP: 0.9,
140
+ defaultMaxTokens: 16384,
141
+ supportsVision: false
142
+ }
143
+ },
144
+ {
145
+ pattern: "gemma-4",
146
+ profile: {
147
+ name: "Gemma 4",
148
+ temperature: 0.7,
149
+ topP: 0.9,
150
+ defaultMaxTokens: 16384,
151
+ supportsVision: true
152
+ }
153
+ }
154
+ ];
155
+ function getModelProfile(modelName) {
156
+ const lowerName = modelName.toLowerCase();
157
+ if (lowerName.includes("mock")) {
158
+ return MOCK_PROFILE;
159
+ }
160
+ for (const { pattern, profile } of MODEL_PROFILES) {
161
+ if (lowerName.includes(pattern.toLowerCase())) {
162
+ return profile;
163
+ }
164
+ }
165
+ return DEFAULT_PROFILE;
166
+ }
167
+ function modelSupportsVision(modelName) {
168
+ return getModelProfile(modelName).supportsVision;
169
+ }
170
+
171
+ export {
172
+ getModelProfile,
173
+ modelSupportsVision
174
+ };
175
+ //# sourceMappingURL=chunk-V4IE7HJY.js.map