openfox 2.0.0-beta.1 → 2.0.0-beta.11

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 (49) hide show
  1. package/dist/agent-defaults/code-reviewer.agent.md +2 -1
  2. package/dist/{chat-handler-IVIWOR3D.js → chat-handler-NMJCOCCB.js} +14 -27
  3. package/dist/{chunk-ZLUBZ4K4.js → chunk-4RLDN2LL.js} +222 -106
  4. package/dist/{chunk-CEZNMLOO.js → chunk-7TTEGAO6.js} +12 -13
  5. package/dist/chunk-BU56QFHW.js +315 -0
  6. package/dist/{chunk-FQLK5GL5.js → chunk-BVHFMAVN.js} +1 -1
  7. package/dist/{chunk-RF2JGDSS.js → chunk-DMH6JVPF.js} +13 -10
  8. package/dist/{chunk-ALH4KM2Y.js → chunk-EQQDA4D3.js} +2967 -3248
  9. package/dist/{chunk-QFSSKIQ3.js → chunk-EXYMWI7A.js} +4 -4
  10. package/dist/{chunk-NNEHZT3V.js → chunk-EZUR7OEP.js} +11 -3
  11. package/dist/{chunk-NONI4CRP.js → chunk-ITWVFGFV.js} +5 -61
  12. package/dist/{chunk-4U4CSRBE.js → chunk-LCRJWUW7.js} +6 -6
  13. package/dist/{chunk-XKR3HCAL.js → chunk-NSBYORD5.js} +177 -34
  14. package/dist/{chunk-PSJIT5LZ.js → chunk-RFNEDBVO.js} +4 -4
  15. package/dist/chunk-RI6GAMNP.js +13 -0
  16. package/dist/{chunk-HHAJ3QF6.js → chunk-UKTPL5ZG.js} +16 -28
  17. package/dist/{chunk-HGAMIPFO.js → chunk-VIIRNJDT.js} +39 -178
  18. package/dist/cli/dev.js +1 -1
  19. package/dist/cli/index.js +1 -1
  20. package/dist/compactor-TDNRM3A7.js +9 -0
  21. package/dist/{config-YU7NYZYG.js → config-TDVA7MQN.js} +9 -8
  22. package/dist/{events-OHJWCI3S.js → events-UGTGGFG3.js} +8 -7
  23. package/dist/{folding-U6UHQAS5.js → folding-YOCGTZYH.js} +2 -2
  24. package/dist/{orchestrator-7ZXM4J22.js → orchestrator-75L5UGDU.js} +18 -22
  25. package/dist/package.json +1 -1
  26. package/dist/{processor-TKBJLQ2N.js → processor-GHESQ2YV.js} +8 -9
  27. package/dist/{protocol-BQ12Aw5J.d.ts → protocol-B9R1CUvt.d.ts} +14 -39
  28. package/dist/{protocol-K62EPEGS.js → protocol-CN24IKQN.js} +3 -5
  29. package/dist/{provider-HTJEB3ON.js → provider-BGH4MBLH.js} +25 -10
  30. package/dist/{serve-5KA6SSSP.js → serve-I6T7V62Z.js} +25 -26
  31. package/dist/server/index.d.ts +1 -6
  32. package/dist/server/index.js +15 -16
  33. package/dist/{settings-VRAOAPLA.js → settings-6XX56F3F.js} +2 -2
  34. package/dist/shared/index.d.ts +2 -2
  35. package/dist/shared/index.js +1 -1
  36. package/dist/{tools-Z7X4HXZN.js → tools-D3WWIOQD.js} +11 -13
  37. package/dist/web/assets/{index-BY8EbT5Z.css → index-CSOB8dwI.css} +1 -1
  38. package/dist/web/assets/index-tJDr1ODC.js +299 -0
  39. package/dist/web/index.html +2 -2
  40. package/dist/web/sw.js +1 -1
  41. package/dist/workflow-defaults/default.workflow.json +9 -4
  42. package/package.json +1 -1
  43. package/dist/auto-compaction-UIWTO3H5.js +0 -27
  44. package/dist/chunk-CGZHLM3K.js +0 -70
  45. package/dist/chunk-SZKEGZIB.js +0 -140
  46. package/dist/chunk-UFY4I643.js +0 -332
  47. package/dist/runtime-config-NPSPMRDA.js +0 -9
  48. package/dist/vision-fallback-3MIZZ6NQ.js +0 -22
  49. package/dist/web/assets/index-CqOJgw7l.js +0 -299
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createServerMessage,
3
3
  isClientMessage
4
- } from "./chunk-FQLK5GL5.js";
4
+ } from "./chunk-BVHFMAVN.js";
5
5
 
6
6
  // src/server/ws/protocol.ts
7
7
  function enrichMessagesWithToolResults(messages) {
@@ -94,8 +94,14 @@ function createChatTodoMessage(todos) {
94
94
  function createChatProgressMessage(message, phase) {
95
95
  return createServerMessage("chat.progress", { message, ...phase ? { phase } : {} });
96
96
  }
97
- function createChatFormatRetryMessage(attempt, maxAttempts) {
98
- return createServerMessage("chat.format_retry", { attempt, maxAttempts });
97
+ function createChatFormatRetryMessage(attempt, maxAttempts, pattern, field, matchedContent) {
98
+ return createServerMessage("chat.format_retry", {
99
+ attempt,
100
+ maxAttempts,
101
+ ...pattern !== void 0 ? { pattern } : {},
102
+ ...field !== void 0 ? { field } : {},
103
+ ...matchedContent !== void 0 ? { matchedContent } : {}
104
+ });
99
105
  }
100
106
  function createChatMessageMessage(message) {
101
107
  return createServerMessage("chat.message", { message });
@@ -120,9 +126,6 @@ function createChatPathConfirmationMessage(callId, tool, paths, workdir, reason)
120
126
  function createChatAskUserMessage(callId, question) {
121
127
  return createServerMessage("chat.ask_user", { callId, question });
122
128
  }
123
- function createChatVisionFallbackMessage(payload) {
124
- return createServerMessage("chat.vision_fallback", payload);
125
- }
126
129
  function createModeChangedMessage(mode, auto, reason) {
127
130
  return createServerMessage("mode.changed", { mode, auto, ...reason ? { reason } : {} });
128
131
  }
@@ -198,9 +201,6 @@ function storedEventToServerMessage(event) {
198
201
  if (data.stats) {
199
202
  updates.stats = data.stats;
200
203
  }
201
- if (data.promptContext) {
202
- updates.promptContext = data.promptContext;
203
- }
204
204
  return createChatMessageUpdatedMessage(data.messageId, updates);
205
205
  }
206
206
  case "tool.preparing": {
@@ -283,9 +283,9 @@ function storedEventToServerMessage(event) {
283
283
  const data = event.data;
284
284
  return createChatAskUserMessage(data.callId, data.question);
285
285
  }
286
- case "format.retry": {
286
+ case "pattern.retry": {
287
287
  const data = event.data;
288
- return createChatFormatRetryMessage(data.attempt, data.maxAttempts);
288
+ return createChatFormatRetryMessage(data.attempt, data.maxAttempts, data.pattern, data.field, data.matchedContent);
289
289
  }
290
290
  case "turn.snapshot":
291
291
  case "context.compacted":
@@ -320,7 +320,6 @@ export {
320
320
  createChatErrorMessage,
321
321
  createChatPathConfirmationMessage,
322
322
  createChatAskUserMessage,
323
- createChatVisionFallbackMessage,
324
323
  createModeChangedMessage,
325
324
  createPhaseChangedMessage,
326
325
  createCriteriaUpdatedMessage,
@@ -334,4 +333,4 @@ export {
334
333
  createQueueStateMessage,
335
334
  storedEventToServerMessage
336
335
  };
337
- //# sourceMappingURL=chunk-CEZNMLOO.js.map
336
+ //# sourceMappingURL=chunk-7TTEGAO6.js.map
@@ -0,0 +1,315 @@
1
+ import {
2
+ PathAccessDeniedError,
3
+ TurnMetrics,
4
+ WORKFLOW_KICKOFF_PROMPT,
5
+ assembleAgentRequest,
6
+ buildAgentReminder,
7
+ buildAgentSmallReminder,
8
+ createAssemblyResult,
9
+ createChatDoneEvent,
10
+ createMessageStartEvent,
11
+ findAgentById,
12
+ getAllInstructions,
13
+ getConversationMessages,
14
+ getEnabledSkillMetadata,
15
+ getSubAgents,
16
+ getToolRegistryForAgent,
17
+ loadAllAgentsDefault,
18
+ processEventsForConversation,
19
+ runTopLevelAgentLoop
20
+ } from "./chunk-EQQDA4D3.js";
21
+ import {
22
+ getCurrentContextWindowId,
23
+ getCurrentWindowMessageOptions,
24
+ getEventStore,
25
+ getRuntimeConfig
26
+ } from "./chunk-NSBYORD5.js";
27
+ import {
28
+ buildSnapshotFromSessionState
29
+ } from "./chunk-ITWVFGFV.js";
30
+ import {
31
+ logger
32
+ } from "./chunk-K44MW7JJ.js";
33
+ import {
34
+ getGlobalConfigDir
35
+ } from "./chunk-CQGTEGKL.js";
36
+
37
+ // src/server/chat/dynamic-context.ts
38
+ import { createHash } from "crypto";
39
+ function computeDynamicContextHash(instructionContent, skills) {
40
+ const dynamicInputs = JSON.stringify({
41
+ instructions: instructionContent,
42
+ skills: skills.map((s) => s.id).sort()
43
+ });
44
+ return createHash("sha256").update(dynamicInputs).digest("hex");
45
+ }
46
+
47
+ // src/server/chat/orchestrator.ts
48
+ async function buildRetryPatterns() {
49
+ const { getSetting, SETTINGS_KEYS } = await import("./settings-6XX56F3F.js");
50
+ const raw = getSetting(SETTINGS_KEYS.RETRY_PATTERNS);
51
+ if (!raw) {
52
+ const oldXmlProtection = getSetting("llm.disableXmlProtection");
53
+ if (oldXmlProtection !== null) {
54
+ const disabled = oldXmlProtection === "true";
55
+ return {
56
+ retryPatterns: disabled ? [] : [{ field: "both", pattern: "<(tool_call|function=|/tool_call|parameter=)", action: "retry", active: true }],
57
+ maxRetriesPerTurn: 10
58
+ };
59
+ }
60
+ return { retryPatterns: [], maxRetriesPerTurn: 10 };
61
+ }
62
+ try {
63
+ const parsed = JSON.parse(raw);
64
+ return {
65
+ retryPatterns: Array.isArray(parsed.patterns) ? parsed.patterns : [],
66
+ maxRetriesPerTurn: typeof parsed.maxRetriesPerTurn === "number" ? parsed.maxRetriesPerTurn : 10
67
+ };
68
+ } catch {
69
+ return { retryPatterns: [], maxRetriesPerTurn: 10 };
70
+ }
71
+ }
72
+ function buildGetConversationMessages(sessionId, llmClient, append) {
73
+ return async () => {
74
+ const processedEvents = await processEventsForConversation(sessionId, llmClient, (event) => append(event));
75
+ return getConversationMessages({ type: "toplevel", sessionId }, { events: processedEvents });
76
+ };
77
+ }
78
+ function resolveStatsIdentity(options) {
79
+ const model = options.llmClient.getModel();
80
+ if (options.statsIdentity) {
81
+ return {
82
+ ...options.statsIdentity,
83
+ model
84
+ };
85
+ }
86
+ return {
87
+ providerId: `provider:${model}`,
88
+ providerName: "Unknown Provider",
89
+ backend: "unknown",
90
+ model
91
+ };
92
+ }
93
+ async function runChatTurn(options) {
94
+ const { sessionManager, sessionId } = options;
95
+ const eventStore = getEventStore();
96
+ const statsIdentity = resolveStatsIdentity(options);
97
+ const session = sessionManager.requireSession(sessionId);
98
+ const mode = session.mode;
99
+ logger.debug("Starting chat turn", { sessionId, mode });
100
+ sessionManager.setRunning(sessionId, true);
101
+ const append = (event) => eventStore.append(sessionId, event);
102
+ const turnMetrics = new TurnMetrics();
103
+ try {
104
+ await runAgentTurn(options, turnMetrics, mode, append);
105
+ const snapshot = buildSnapshot(sessionManager, sessionId, turnMetrics.buildStats(statsIdentity, mode));
106
+ const snapshotEvent = eventStore.append(sessionId, { type: "turn.snapshot", data: snapshot });
107
+ const deletedCount = eventStore.cleanupOldEvents(sessionId);
108
+ if (deletedCount > 0) {
109
+ logger.debug("Cleaned up old events after snapshot", { sessionId, deletedCount, snapshotSeq: snapshotEvent.seq });
110
+ }
111
+ } catch (error) {
112
+ if (error instanceof PathAccessDeniedError) {
113
+ const errorMsgId2 = crypto.randomUUID();
114
+ const reasonText = error.reason === "sensitive_file" ? "sensitive files that may contain secrets" : error.reason === "both" ? "files outside the project and sensitive files" : "files outside the project directory";
115
+ eventStore.append(sessionId, {
116
+ type: "chat.error",
117
+ data: {
118
+ error: `User denied access to ${reasonText}.`,
119
+ recoverable: false
120
+ }
121
+ });
122
+ eventStore.append(
123
+ sessionId,
124
+ createMessageStartEvent(
125
+ errorMsgId2,
126
+ "user",
127
+ `Access denied: ${error.paths.join(", ")}. If you need this file, explain why and ask the user for permission.`,
128
+ {
129
+ ...getCurrentWindowMessageOptions(sessionId) ?? {},
130
+ isSystemGenerated: true,
131
+ messageKind: "correction"
132
+ }
133
+ )
134
+ );
135
+ eventStore.append(sessionId, createChatDoneEvent(errorMsgId2, "error"));
136
+ return;
137
+ }
138
+ if (error instanceof Error && error.message === "Aborted") {
139
+ const snapshot = buildSnapshot(sessionManager, sessionId, turnMetrics.buildStats(statsIdentity, mode));
140
+ eventStore.append(sessionId, { type: "turn.snapshot", data: snapshot });
141
+ return;
142
+ }
143
+ logger.error("Chat turn error", { sessionId, mode, error });
144
+ const errorMsgId = crypto.randomUUID();
145
+ eventStore.append(sessionId, {
146
+ type: "chat.error",
147
+ data: {
148
+ error: error instanceof Error ? error.message : "Unknown error",
149
+ recoverable: false
150
+ }
151
+ });
152
+ eventStore.append(
153
+ sessionId,
154
+ createMessageStartEvent(
155
+ errorMsgId,
156
+ "user",
157
+ `Error: ${error instanceof Error ? error.message : "Unknown error"}`,
158
+ {
159
+ ...getCurrentWindowMessageOptions(sessionId) ?? {},
160
+ isSystemGenerated: true,
161
+ messageKind: "correction"
162
+ }
163
+ )
164
+ );
165
+ eventStore.append(sessionId, createChatDoneEvent(errorMsgId, "error"));
166
+ } finally {
167
+ eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
168
+ }
169
+ }
170
+ function injectAgentReminder(sessionId, agentDef) {
171
+ const eventStore = getEventStore();
172
+ const currentWindowId = getCurrentContextWindowId(sessionId);
173
+ let latestAgentName;
174
+ const events = eventStore.getAllEvents(sessionId);
175
+ for (let i = events.length - 1; i >= 0; i--) {
176
+ const event = events[i];
177
+ if (event.type === "message.start") {
178
+ const data = event.data;
179
+ if (data.isSystemGenerated && data.metadata?.type === "agent" && (data.contextWindowId === currentWindowId || !currentWindowId && !data.contextWindowId)) {
180
+ latestAgentName = data.metadata.name;
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ const currentAgentName = agentDef.metadata.name ?? agentDef.metadata.id;
186
+ const isSmallReminder = latestAgentName === currentAgentName;
187
+ const content = isSmallReminder ? buildAgentSmallReminder(currentAgentName) : buildAgentReminder(agentDef);
188
+ const reminderMsgId = crypto.randomUUID();
189
+ const currentWindowMessageOptions = currentWindowId ? { contextWindowId: currentWindowId } : void 0;
190
+ eventStore.append(sessionId, {
191
+ type: "message.start",
192
+ data: {
193
+ messageId: reminderMsgId,
194
+ role: "user",
195
+ content,
196
+ ...currentWindowMessageOptions ?? {},
197
+ isSystemGenerated: true,
198
+ messageKind: "auto-prompt",
199
+ metadata: {
200
+ type: "agent",
201
+ name: currentAgentName,
202
+ color: agentDef.metadata.color ?? "#6b7280",
203
+ kind: isSmallReminder ? "reminder" : "definition"
204
+ }
205
+ }
206
+ });
207
+ eventStore.append(sessionId, {
208
+ type: "message.done",
209
+ data: { messageId: reminderMsgId }
210
+ });
211
+ }
212
+ async function runAgentTurn(options, turnMetrics, agentId, append, callbacks) {
213
+ const statsIdentity = resolveStatsIdentity(options);
214
+ const allAgents = await loadAllAgentsDefault();
215
+ const agentDef = findAgentById(agentId, allAgents) ?? findAgentById("planner", allAgents);
216
+ injectAgentReminder(options.sessionId, agentDef);
217
+ const subAgentDefs = getSubAgents(allAgents);
218
+ const { content: instructionContent } = await getAllInstructions(
219
+ options.sessionManager.requireSession(options.sessionId).workdir,
220
+ options.sessionManager.requireSession(options.sessionId).projectId
221
+ );
222
+ const runtimeConfig = getRuntimeConfig();
223
+ const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
224
+ const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
225
+ return runTopLevelAgentLoop(
226
+ {
227
+ mode: agentId,
228
+ append,
229
+ ...await buildRetryPatterns(),
230
+ sessionManager: options.sessionManager,
231
+ sessionId: options.sessionId,
232
+ llmClient: options.llmClient,
233
+ statsIdentity,
234
+ signal: options.signal,
235
+ onMessage: options.onMessage,
236
+ assembleRequest: (input) => {
237
+ const cached = options.sessionManager.getCachedPrompt(options.sessionId);
238
+ if (cached) {
239
+ const currentHash = computeDynamicContextHash(instructionContent ?? "", skills);
240
+ if (cached.hash !== currentHash) {
241
+ options.sessionManager.setDynamicContextChanged(options.sessionId, true);
242
+ }
243
+ return createAssemblyResult({
244
+ systemPrompt: cached.systemPrompt,
245
+ messages: input.messages,
246
+ injectedFiles: input.injectedFiles,
247
+ requestTools: input.promptTools,
248
+ toolChoice: input.toolChoice,
249
+ disableThinking: false
250
+ });
251
+ }
252
+ const result = assembleAgentRequest({
253
+ ...input,
254
+ agentDef,
255
+ subAgentDefs,
256
+ modelName: options.llmClient.getModel()
257
+ });
258
+ const hash = computeDynamicContextHash(instructionContent ?? "", skills);
259
+ options.sessionManager.setCachedPrompt(options.sessionId, result.systemPrompt, hash);
260
+ return result;
261
+ },
262
+ getToolRegistry: () => getToolRegistryForAgent(agentDef),
263
+ getConversationMessages: buildGetConversationMessages(options.sessionId, options.llmClient, append),
264
+ injectAgentReminder: () => injectAgentReminder(options.sessionId, agentDef),
265
+ ...callbacks?.injectKickoff ? { injectKickoff: callbacks.injectKickoff } : {},
266
+ ...callbacks?.onToolExecuted ? { onToolExecuted: callbacks.onToolExecuted } : {}
267
+ },
268
+ turnMetrics
269
+ );
270
+ }
271
+ function injectWorkflowKickoffIfNeeded(sessionManager, sessionId, eventStore) {
272
+ const session = sessionManager.requireSession(sessionId);
273
+ const currentWindowMessageOptions = getCurrentContextWindowId(sessionId) ? { contextWindowId: getCurrentContextWindowId(sessionId) } : void 0;
274
+ const events = eventStore.getEvents(sessionId);
275
+ const hasKickoff = events.some((e) => {
276
+ if (e.type !== "message.start") return false;
277
+ const data = e.data;
278
+ return data.messageKind === "auto-prompt" && data.content?.includes("fulfil the");
279
+ });
280
+ if (!hasKickoff) {
281
+ const kickoffMsgId = crypto.randomUUID();
282
+ const kickoffContent = WORKFLOW_KICKOFF_PROMPT(session.criteria.length);
283
+ eventStore.append(
284
+ sessionId,
285
+ createMessageStartEvent(kickoffMsgId, "user", kickoffContent, {
286
+ ...currentWindowMessageOptions ?? {},
287
+ isSystemGenerated: true,
288
+ messageKind: "auto-prompt",
289
+ metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
290
+ })
291
+ );
292
+ eventStore.append(sessionId, { type: "message.done", data: { messageId: kickoffMsgId } });
293
+ }
294
+ }
295
+ function buildSnapshot(sessionManager, sessionId, _lastStats) {
296
+ const eventStore = getEventStore();
297
+ const session = sessionManager.requireSession(sessionId);
298
+ const events = eventStore.getEvents(sessionId);
299
+ const latestSeq = eventStore.getLatestSeq(sessionId) ?? 0;
300
+ const cachedPrompt = sessionManager.getCachedPrompt(sessionId);
301
+ return buildSnapshotFromSessionState({
302
+ session,
303
+ events,
304
+ latestSeq,
305
+ ...cachedPrompt ? { cachedSystemPrompt: cachedPrompt.systemPrompt, dynamicContextHash: cachedPrompt.hash } : {}
306
+ });
307
+ }
308
+
309
+ export {
310
+ computeDynamicContextHash,
311
+ runChatTurn,
312
+ runAgentTurn,
313
+ injectWorkflowKickoffIfNeeded
314
+ };
315
+ //# sourceMappingURL=chunk-BU56QFHW.js.map
@@ -26,4 +26,4 @@ export {
26
26
  isClientMessage,
27
27
  isServerMessage
28
28
  };
29
- //# sourceMappingURL=chunk-FQLK5GL5.js.map
29
+ //# sourceMappingURL=chunk-BVHFMAVN.js.map
@@ -2,11 +2,14 @@ import {
2
2
  clearModelCache,
3
3
  createLLMClient,
4
4
  detectModel
5
- } from "./chunk-HHAJ3QF6.js";
5
+ } from "./chunk-UKTPL5ZG.js";
6
6
  import {
7
+ buildModelsUrl,
7
8
  detectBackend,
8
- getModelProfile
9
- } from "./chunk-HGAMIPFO.js";
9
+ ensureVersionPrefix,
10
+ getModelProfile,
11
+ stripVersionPrefix
12
+ } from "./chunk-VIIRNJDT.js";
10
13
  import {
11
14
  logger
12
15
  } from "./chunk-K44MW7JJ.js";
@@ -67,7 +70,7 @@ function mergeModelsWithUserOverrides(backendModels, userModels) {
67
70
  return updatedModels;
68
71
  }
69
72
  async function fetchAvailableModelsFromBackend(baseUrl, apiKey) {
70
- const url = baseUrl.includes("/v1") ? `${baseUrl}/models` : `${baseUrl}/v1/models`;
73
+ const url = buildModelsUrl(baseUrl);
71
74
  const models = await fetchModelsFromBackend(url, apiKey);
72
75
  return models.map((m) => m.id);
73
76
  }
@@ -78,7 +81,7 @@ async function fetchModelsWithContext(baseUrl, apiKey, backend) {
78
81
  return fetchOllamaModelsWithContext(baseUrl, apiKey);
79
82
  }
80
83
  const isOpenCodeGo = baseUrl.includes("opencode.ai/zen/go");
81
- const url = isOpenCodeGo ? baseUrl.replace("/zen/go", "/zen").replace(/\/v1$/, "") + "/v1/models" : baseUrl.includes("/v1") ? `${baseUrl}/models` : `${baseUrl}/v1/models`;
84
+ const url = isOpenCodeGo ? buildModelsUrl(baseUrl.replace("/zen/go", "/zen")) : buildModelsUrl(baseUrl);
82
85
  logger.info("Fetching models via /v1/models", { url });
83
86
  const models = await fetchModelsFromBackend(url, apiKey);
84
87
  if (models.length === 0) return [];
@@ -177,7 +180,7 @@ function createProviderManager(config) {
177
180
  ...config,
178
181
  llm: {
179
182
  ...config.llm,
180
- baseUrl: provider.url.includes("/v1") ? provider.url : `${provider.url}/v1`,
183
+ baseUrl: ensureVersionPrefix(provider.url),
181
184
  model,
182
185
  backend: provider.backend,
183
186
  ...provider.apiKey && { apiKey: provider.apiKey }
@@ -235,7 +238,7 @@ function createProviderManager(config) {
235
238
  const providerConfig = createConfigForProvider(provider, targetModel);
236
239
  const newClient = createLLMClient(providerConfig);
237
240
  try {
238
- const url = provider.url.includes("/v1") ? provider.url.replace("/v1", "") : provider.url;
241
+ const url = stripVersionPrefix(provider.url);
239
242
  clearModelCache(url);
240
243
  const backend = provider.backend;
241
244
  logger.info("activateProvider fetching models", { providerId, providerName: provider.name, url, backend });
@@ -355,7 +358,7 @@ function createProviderManager(config) {
355
358
  if (provider.models && provider.models.length > 0) {
356
359
  return provider.models;
357
360
  }
358
- const url = provider.url.includes("/v1") ? provider.url.replace("/v1", "") : provider.url;
361
+ const url = stripVersionPrefix(provider.url);
359
362
  const backend = provider.backend;
360
363
  return fetchModelsWithContext(url, provider.apiKey, backend);
361
364
  },
@@ -466,7 +469,7 @@ function createProviderManager(config) {
466
469
  if (!provider) {
467
470
  return { success: false, error: "Provider not found" };
468
471
  }
469
- const url = provider.url.includes("/v1") ? provider.url.replace("/v1", "") : provider.url;
472
+ const url = stripVersionPrefix(provider.url);
470
473
  const backend = provider.backend;
471
474
  logger.info("refreshProviderModels fetching models", { providerId, providerName: provider.name, url, backend });
472
475
  const modelsWithContext = await fetchModelsWithContext(url, provider.apiKey, backend);
@@ -511,4 +514,4 @@ export {
511
514
  parseDefaultModelSelection,
512
515
  createProviderManager
513
516
  };
514
- //# sourceMappingURL=chunk-RF2JGDSS.js.map
517
+ //# sourceMappingURL=chunk-DMH6JVPF.js.map