@nuvin/nuvin-core 1.7.0 → 1.7.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.
package/dist/VERSION CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "1.7.0",
3
- "commit": "4c993c8"
2
+ "version": "1.7.2",
3
+ "commit": "9570da1"
4
4
  }
package/dist/index.d.ts CHANGED
@@ -2059,12 +2059,15 @@ type ModelInfo = {
2059
2059
  id: string;
2060
2060
  name?: string;
2061
2061
  limits?: ModelLimits;
2062
- [key: string]: unknown;
2062
+ [key: string]: string | number | ModelLimits | undefined | unknown;
2063
+ };
2064
+ type RawModelResponse = {
2065
+ [key: string]: string | number | undefined | unknown;
2063
2066
  };
2064
- type RawModelResponse = Record<string, unknown>;
2065
2067
  declare function normalizeModelLimits(provider: string, model: RawModelResponse): ModelLimits | null;
2066
2068
  declare function getFallbackLimits(provider: string, model: string): ModelLimits | null;
2067
2069
  declare function normalizeModelInfo(provider: string, model: RawModelResponse): ModelInfo;
2070
+ declare function deduplicateModels(models: ModelInfo[]): ModelInfo[];
2068
2071
 
2069
2072
  type GithubOptions = {
2070
2073
  apiKey?: string;
@@ -2213,6 +2216,9 @@ declare class MCPToolPort implements ToolPort {
2213
2216
  executeToolCalls(calls: ToolInvocation[], _context?: Record<string, unknown>, maxConcurrent?: number, signal?: AbortSignal): Promise<ToolExecutionResult[]>;
2214
2217
  }
2215
2218
 
2219
+ /**
2220
+ * @deprecated Use MCPServerConfig from nuvin-cli/config/types.ts instead
2221
+ */
2216
2222
  type MCPServerConfig = {
2217
2223
  command?: string;
2218
2224
  args?: string[];
@@ -2222,11 +2228,14 @@ type MCPServerConfig = {
2222
2228
  headers?: Record<string, string>;
2223
2229
  prefix?: string;
2224
2230
  timeoutMs?: number;
2231
+ enabled?: boolean;
2225
2232
  };
2233
+ /**
2234
+ * @deprecated MCP config is now part of main CLI config under mcp.servers
2235
+ */
2226
2236
  type MCPConfig = {
2227
2237
  mcpServers: Record<string, MCPServerConfig>;
2228
2238
  };
2229
- declare function loadMCPConfig(filePath?: string): Promise<MCPConfig | null>;
2230
2239
 
2231
2240
  declare class PersistingConsoleEventPort implements EventPort {
2232
2241
  private memory;
@@ -2246,4 +2255,4 @@ declare function resolveBackspaces(s: string): string;
2246
2255
  declare function stripAnsiAndControls(s: string): string;
2247
2256
  declare function canonicalizeTerminalPaste(raw: string): string;
2248
2257
 
2249
- export { AGENT_CREATOR_SYSTEM_PROMPT, AbortError, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignErrorResult, type AssignParams, type AssignResult, type AssignSuccessResult$1 as AssignSuccessResult, type AssignTaskArgs, type AssignTaskMetadata, type BaseLLMOptions, type BashErrorResult, type BashParams, type BashResult, type BashSuccessResult$1 as BashSuccessResult, BashTool, type BashToolArgs, type BashToolMetadata, type CommandMetadata, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DEFAULT_RETRY_CONFIG, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationMetadata, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, type DirEntry, type DirLsArgs, type DirLsMetadata, type DirLsParams, type DirLsResult, type DirLsSuccessResult$1 as DirLsSuccessResult, type ErrorMetadata, ErrorReason, type ExecResult, type ExecResultError, type ExecResultSuccess, type FileEditArgs, type FileEditMetadata, type FileEditResult, type FileEditSuccessResult$1 as FileEditSuccessResult, type FileMetadata, type FileNewArgs, type FileNewMetadata, type FileNewParams, type FileNewResult, type FileNewSuccessResult$1 as FileNewSuccessResult, type FileReadArgs, type FileReadErrorResult, type FileReadMetadata, type FileReadParams, type FileReadResult, type FileReadSuccessResult$1 as FileReadSuccessResult, type FolderTreeOptions, type FunctionTool, GithubLLM, InMemoryMemory, InMemoryMetadata, InMemoryMetricsPort, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type LineRangeMetadata, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, type MetricsChangeHandler, type MetricsPort, type MetricsSnapshot, type ModelInfo, type ModelLimits, NoopMetricsPort, NoopReminders, type OrchestratorAwareToolPort, type ParseResult, PersistedMemory, PersistingConsoleEventPort, type RetryConfig, RetryTransport, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, type SubAgentState, type SubAgentToolCall, SystemClock, type TodoWriteArgs, type TodoWriteMetadata, type TodoWriteResult, type TodoWriteSuccessResult$1 as TodoWriteSuccessResult, type ToolApprovalDecision, type ToolArguments, type ToolCall, type ToolCallValidation, type ToolErrorMetadata, type ToolExecutionContext, type ToolExecutionResult, type ToolMetadataMap, type ToolName, type ToolParameterMap, type ToolPort, ToolRegistry, type ToolValidator, type TypedToolInvocation, type UsageData, type UserAttachment, type UserMessagePayload, type ValidationResult, type WebFetchArgs, type WebFetchMetadata, type WebFetchParams, type WebFetchResult, type WebFetchSuccessResult$1 as WebFetchSuccessResult, type WebSearchArgs, type WebSearchMetadata, type WebSearchParams, type WebSearchResult, type WebSearchSuccessResult$1 as WebSearchSuccessResult, type WebSearchToolResult, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, convertToolCall, convertToolCalls, createEmptySnapshot, createLLM, err, generateFolderTree, getAvailableProviders, getFallbackLimits, getProviderLabel, isAssignResult, isAssignSuccess, isAssignTaskArgs, isBashResult, isBashSuccess, isBashToolArgs, isDirLsArgs, isDirLsResult, isDirLsSuccess, isError, isFileEditArgs, isFileEditResult, isFileEditSuccess, isFileNewArgs, isFileNewResult, isFileNewSuccess, isFileReadArgs, isFileReadResult, isFileReadSuccess, isJsonResult, isRetryableError, isRetryableStatusCode, isSuccess, isSuccessJson, isSuccessText, isTextResult, isTodoWriteArgs, isTodoWriteResult, isTodoWriteSuccess, isWebFetchArgs, isWebFetchResult, isWebFetchSuccess, isWebSearchArgs, isWebSearchResult, isWebSearchSuccess, loadMCPConfig, normalizeModelInfo, normalizeModelLimits, normalizeNewlines, okJson, okText, parseJSON, parseSubAgentToolCallArguments, parseToolArguments, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels, toolValidators };
2258
+ export { AGENT_CREATOR_SYSTEM_PROMPT, AbortError, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignErrorResult, type AssignParams, type AssignResult, type AssignSuccessResult$1 as AssignSuccessResult, type AssignTaskArgs, type AssignTaskMetadata, type BaseLLMOptions, type BashErrorResult, type BashParams, type BashResult, type BashSuccessResult$1 as BashSuccessResult, BashTool, type BashToolArgs, type BashToolMetadata, type CommandMetadata, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DEFAULT_RETRY_CONFIG, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationMetadata, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, type DirEntry, type DirLsArgs, type DirLsMetadata, type DirLsParams, type DirLsResult, type DirLsSuccessResult$1 as DirLsSuccessResult, type ErrorMetadata, ErrorReason, type ExecResult, type ExecResultError, type ExecResultSuccess, type FileEditArgs, type FileEditMetadata, type FileEditResult, type FileEditSuccessResult$1 as FileEditSuccessResult, type FileMetadata, type FileNewArgs, type FileNewMetadata, type FileNewParams, type FileNewResult, type FileNewSuccessResult$1 as FileNewSuccessResult, type FileReadArgs, type FileReadErrorResult, type FileReadMetadata, type FileReadParams, type FileReadResult, type FileReadSuccessResult$1 as FileReadSuccessResult, type FolderTreeOptions, type FunctionTool, GithubLLM, InMemoryMemory, InMemoryMetadata, InMemoryMetricsPort, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type LineRangeMetadata, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, type MetricsChangeHandler, type MetricsPort, type MetricsSnapshot, type ModelInfo, type ModelLimits, NoopMetricsPort, NoopReminders, type OrchestratorAwareToolPort, type ParseResult, PersistedMemory, PersistingConsoleEventPort, type RetryConfig, RetryTransport, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, type SubAgentState, type SubAgentToolCall, SystemClock, type TodoWriteArgs, type TodoWriteMetadata, type TodoWriteResult, type TodoWriteSuccessResult$1 as TodoWriteSuccessResult, type ToolApprovalDecision, type ToolArguments, type ToolCall, type ToolCallValidation, type ToolErrorMetadata, type ToolExecutionContext, type ToolExecutionResult, type ToolMetadataMap, type ToolName, type ToolParameterMap, type ToolPort, ToolRegistry, type ToolValidator, type TypedToolInvocation, type UsageData, type UserAttachment, type UserMessagePayload, type ValidationResult, type WebFetchArgs, type WebFetchMetadata, type WebFetchParams, type WebFetchResult, type WebFetchSuccessResult$1 as WebFetchSuccessResult, type WebSearchArgs, type WebSearchMetadata, type WebSearchParams, type WebSearchResult, type WebSearchSuccessResult$1 as WebSearchSuccessResult, type WebSearchToolResult, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, convertToolCall, convertToolCalls, createEmptySnapshot, createLLM, deduplicateModels, err, generateFolderTree, getAvailableProviders, getFallbackLimits, getProviderLabel, isAssignResult, isAssignSuccess, isAssignTaskArgs, isBashResult, isBashSuccess, isBashToolArgs, isDirLsArgs, isDirLsResult, isDirLsSuccess, isError, isFileEditArgs, isFileEditResult, isFileEditSuccess, isFileNewArgs, isFileNewResult, isFileNewSuccess, isFileReadArgs, isFileReadResult, isFileReadSuccess, isJsonResult, isRetryableError, isRetryableStatusCode, isSuccess, isSuccessJson, isSuccessText, isTextResult, isTodoWriteArgs, isTodoWriteResult, isTodoWriteSuccess, isWebFetchArgs, isWebFetchResult, isWebFetchSuccess, isWebSearchArgs, isWebSearchResult, isWebSearchSuccess, normalizeModelInfo, normalizeModelLimits, normalizeNewlines, okJson, okText, parseJSON, parseSubAgentToolCallArguments, parseToolArguments, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels, toolValidators };
package/dist/index.js CHANGED
@@ -268,9 +268,9 @@ var JsonFileMemoryPersistence = class {
268
268
  }
269
269
  async load() {
270
270
  try {
271
- const fs10 = await import("fs");
272
- if (!fs10.existsSync(this.filename)) return {};
273
- const text = fs10.readFileSync(this.filename, "utf-8");
271
+ const fs9 = await import("fs");
272
+ if (!fs9.existsSync(this.filename)) return {};
273
+ const text = fs9.readFileSync(this.filename, "utf-8");
274
274
  const data = JSON.parse(text);
275
275
  return typeof data === "object" && data ? data : {};
276
276
  } catch {
@@ -280,13 +280,13 @@ var JsonFileMemoryPersistence = class {
280
280
  }
281
281
  async save(snapshot) {
282
282
  try {
283
- const fs10 = await import("fs");
284
- const path9 = await import("path");
285
- const dir = path9.dirname(this.filename);
286
- if (dir && dir !== "." && !fs10.existsSync(dir)) {
287
- fs10.mkdirSync(dir, { recursive: true });
283
+ const fs9 = await import("fs");
284
+ const path8 = await import("path");
285
+ const dir = path8.dirname(this.filename);
286
+ if (dir && dir !== "." && !fs9.existsSync(dir)) {
287
+ fs9.mkdirSync(dir, { recursive: true });
288
288
  }
289
- fs10.writeFileSync(this.filename, JSON.stringify(snapshot, null, 2), "utf-8");
289
+ fs9.writeFileSync(this.filename, JSON.stringify(snapshot, null, 2), "utf-8");
290
290
  } catch (err2) {
291
291
  console.warn(`Failed to save memory to ${this.filename}`, err2);
292
292
  }
@@ -1361,8 +1361,8 @@ var AgentOrchestrator = class {
1361
1361
  }
1362
1362
  async waitForToolApproval(toolCalls, conversationId, messageId) {
1363
1363
  const approvalId = this.ids.uuid();
1364
- return new Promise((resolve6, reject) => {
1365
- this.pendingApprovals.set(approvalId, { resolve: resolve6, reject });
1364
+ return new Promise((resolve5, reject) => {
1365
+ this.pendingApprovals.set(approvalId, { resolve: resolve5, reject });
1366
1366
  this.events?.emit({
1367
1367
  type: AgentEventTypes.ToolApprovalRequired,
1368
1368
  conversationId,
@@ -3344,14 +3344,14 @@ var AgentRegistry = class {
3344
3344
  * Load agents from both persistence and files
3345
3345
  */
3346
3346
  async loadAgents() {
3347
- const promises2 = [];
3347
+ const promises = [];
3348
3348
  if (this.persistence) {
3349
- promises2.push(this.loadFromPersistence());
3349
+ promises.push(this.loadFromPersistence());
3350
3350
  }
3351
3351
  if (this.filePersistence) {
3352
- promises2.push(this.loadFromFiles());
3352
+ promises.push(this.loadFromFiles());
3353
3353
  }
3354
- await Promise.all(promises2);
3354
+ await Promise.all(promises);
3355
3355
  }
3356
3356
  /**
3357
3357
  * Wait for all agents to finish loading
@@ -4917,21 +4917,21 @@ var NetworkLogger = class {
4917
4917
  async appendToLogFile(entry) {
4918
4918
  if (!this.opts.persistFile) return;
4919
4919
  try {
4920
- const fs10 = await import("fs/promises");
4921
- const path9 = await import("path");
4920
+ const fs9 = await import("fs/promises");
4921
+ const path8 = await import("path");
4922
4922
  const file = this.opts.persistFile;
4923
- const dir = path9.dirname(file);
4923
+ const dir = path8.dirname(file);
4924
4924
  if (dir && dir !== ".") {
4925
4925
  try {
4926
- await fs10.mkdir(dir, { recursive: true });
4926
+ await fs9.mkdir(dir, { recursive: true });
4927
4927
  } catch {
4928
4928
  }
4929
4929
  }
4930
4930
  const logLine = this.formatLogEntry(entry);
4931
- await fs10.appendFile(file, `${logLine}
4931
+ await fs9.appendFile(file, `${logLine}
4932
4932
  `, "utf-8");
4933
4933
  if (this.opts.maxFileSize) {
4934
- const stats = await fs10.stat(file);
4934
+ const stats = await fs9.stat(file);
4935
4935
  if (stats.size > this.opts.maxFileSize) {
4936
4936
  await this.rotateLogFile(file);
4937
4937
  }
@@ -4951,9 +4951,9 @@ var NetworkLogger = class {
4951
4951
  }
4952
4952
  async rotateLogFile(file) {
4953
4953
  try {
4954
- const fs10 = await import("fs/promises");
4954
+ const fs9 = await import("fs/promises");
4955
4955
  const rotatedFile = `${file}.${Date.now()}`;
4956
- await fs10.rename(file, rotatedFile);
4956
+ await fs9.rename(file, rotatedFile);
4957
4957
  } catch {
4958
4958
  }
4959
4959
  }
@@ -5180,12 +5180,12 @@ var GithubAuthTransport = class {
5180
5180
  this.dynamicApiUrl = data.endpoints.api;
5181
5181
  }
5182
5182
  }
5183
- buildFullUrl(path9) {
5184
- if (path9.startsWith("/")) {
5183
+ buildFullUrl(path8) {
5184
+ if (path8.startsWith("/")) {
5185
5185
  const apiUrl = this.dynamicApiUrl ?? this.baseUrl;
5186
- return `${apiUrl}${path9}`;
5186
+ return `${apiUrl}${path8}`;
5187
5187
  }
5188
- return path9;
5188
+ return path8;
5189
5189
  }
5190
5190
  hasVisionPayload(body) {
5191
5191
  if (!body || typeof body !== "object") return false;
@@ -5354,12 +5354,12 @@ var AbortError = class _AbortError extends Error {
5354
5354
  }
5355
5355
  };
5356
5356
  var sleep = (ms, signal) => {
5357
- return new Promise((resolve6, reject) => {
5357
+ return new Promise((resolve5, reject) => {
5358
5358
  if (signal?.aborted) {
5359
5359
  reject(new AbortError("Operation aborted"));
5360
5360
  return;
5361
5361
  }
5362
- const timeout = setTimeout(resolve6, ms);
5362
+ const timeout = setTimeout(resolve5, ms);
5363
5363
  signal?.addEventListener(
5364
5364
  "abort",
5365
5365
  () => {
@@ -5539,11 +5539,11 @@ var AnthropicAuthTransport = class {
5539
5539
  this.refreshPromise = null;
5540
5540
  }
5541
5541
  }
5542
- buildFullUrl(path9) {
5543
- if (path9.startsWith("/")) {
5544
- return `${this.baseUrl}${path9}`;
5542
+ buildFullUrl(path8) {
5543
+ if (path8.startsWith("/")) {
5544
+ return `${this.baseUrl}${path8}`;
5545
5545
  }
5546
- return path9;
5546
+ return path8;
5547
5547
  }
5548
5548
  makeAuthHeaders(headers) {
5549
5549
  const base = {
@@ -5650,11 +5650,11 @@ var BaseBearerAuthTransport = class {
5650
5650
  this.version = version;
5651
5651
  this.customHeaders = customHeaders;
5652
5652
  }
5653
- buildFullUrl(path9) {
5654
- if (path9.startsWith("/")) {
5655
- return `${this.baseUrl}${path9}`;
5653
+ buildFullUrl(path8) {
5654
+ if (path8.startsWith("/")) {
5655
+ return `${this.baseUrl}${path8}`;
5656
5656
  }
5657
- return path9;
5657
+ return path8;
5658
5658
  }
5659
5659
  makeAuthHeaders(headers) {
5660
5660
  const base = headers ? { ...headers } : {};
@@ -5808,6 +5808,15 @@ function normalizeModelInfo(provider, model) {
5808
5808
  ...limits ? { limits } : {}
5809
5809
  };
5810
5810
  }
5811
+ function deduplicateModels(models) {
5812
+ const uniqueModels = /* @__PURE__ */ new Map();
5813
+ for (const model of models) {
5814
+ if (!uniqueModels.has(model.id)) {
5815
+ uniqueModels.set(model.id, model);
5816
+ }
5817
+ }
5818
+ return Array.from(uniqueModels.values());
5819
+ }
5811
5820
 
5812
5821
  // src/llm-providers/llm-github.ts
5813
5822
  var GithubLLM = class extends BaseLLM {
@@ -5852,7 +5861,8 @@ var GithubLLM = class extends BaseLLM {
5852
5861
  throw new LLMError(text || `Failed to fetch models: ${res.status}`, res.status);
5853
5862
  }
5854
5863
  const body = await res.json();
5855
- return body.data.map((m) => normalizeModelInfo("github", m));
5864
+ const models = body.data.map((m) => normalizeModelInfo("github", m));
5865
+ return deduplicateModels(models);
5856
5866
  }
5857
5867
  handleError(error, model) {
5858
5868
  if (error instanceof LLMError) {
@@ -6289,7 +6299,8 @@ var AnthropicAISDKLLM = class {
6289
6299
  throw new LLMError(text || `Failed to fetch models: ${res.status}`, res.status);
6290
6300
  }
6291
6301
  const data = await res.json();
6292
- return data.data.map((model) => normalizeModelInfo("anthropic", model));
6302
+ const models = data.data.map((model) => normalizeModelInfo("anthropic", model));
6303
+ return deduplicateModels(models);
6293
6304
  } catch (error) {
6294
6305
  if (error instanceof LLMError) {
6295
6306
  throw error;
@@ -6399,10 +6410,11 @@ var GenericLLM = class extends BaseLLM {
6399
6410
  throw new Error("Provider does not support getModels");
6400
6411
  }
6401
6412
  if (Array.isArray(this.modelConfig)) {
6402
- return this.modelConfig.map((m) => {
6413
+ const models2 = this.modelConfig.map((m) => {
6403
6414
  const raw = typeof m === "string" ? { id: m } : m;
6404
6415
  return normalizeModelInfo(this.providerName, raw);
6405
6416
  });
6417
+ return deduplicateModels(models2);
6406
6418
  }
6407
6419
  if (typeof this.modelConfig === "string") {
6408
6420
  const transport2 = this.createTransport();
@@ -6412,7 +6424,8 @@ var GenericLLM = class extends BaseLLM {
6412
6424
  throw new Error(`Failed to fetch models: ${res2.status} ${text}`);
6413
6425
  }
6414
6426
  const data2 = await res2.json();
6415
- return data2.data.map((m) => normalizeModelInfo(this.providerName, m));
6427
+ const models2 = data2.data.map((m) => normalizeModelInfo(this.providerName, m));
6428
+ return deduplicateModels(models2);
6416
6429
  }
6417
6430
  const transport = this.createTransport();
6418
6431
  const res = await transport.get("/models", void 0, signal);
@@ -6421,7 +6434,8 @@ var GenericLLM = class extends BaseLLM {
6421
6434
  throw new Error(`Failed to fetch models: ${res.status} ${text}`);
6422
6435
  }
6423
6436
  const data = await res.json();
6424
- return data.data.map((m) => normalizeModelInfo(this.providerName, m));
6437
+ const models = data.data.map((m) => normalizeModelInfo(this.providerName, m));
6438
+ return deduplicateModels(models);
6425
6439
  }
6426
6440
  async generateCompletion(params, signal) {
6427
6441
  let enhancedParams = params;
@@ -6716,71 +6730,6 @@ var MCPToolPort = class {
6716
6730
  return results;
6717
6731
  }
6718
6732
  };
6719
-
6720
- // src/config.ts
6721
- import * as fs9 from "fs";
6722
- import * as path8 from "path";
6723
- import { parse as parseYaml } from "yaml";
6724
- async function loadMCPConfig(filePath = ".nuvin_mcp.json") {
6725
- try {
6726
- const resolvedPath = path8.resolve(filePath);
6727
- if (!fs9.existsSync(resolvedPath)) {
6728
- return null;
6729
- }
6730
- const raw = await fs9.promises.readFile(resolvedPath, "utf-8");
6731
- if (!raw.trim()) {
6732
- return null;
6733
- }
6734
- const ext = path8.extname(resolvedPath).toLowerCase();
6735
- let data;
6736
- if (ext === ".yaml" || ext === ".yml") {
6737
- data = parseYaml(raw);
6738
- } else {
6739
- data = JSON.parse(raw);
6740
- }
6741
- return normalizeMCPConfig(data);
6742
- } catch (error) {
6743
- console.warn(`Failed to load MCP config from ${filePath}:`, error);
6744
- return null;
6745
- }
6746
- }
6747
- function normalizeMCPConfig(raw) {
6748
- if (!raw || typeof raw !== "object") {
6749
- return null;
6750
- }
6751
- const asRecord = raw;
6752
- if (isValidConfig(asRecord)) {
6753
- const servers = asRecord.mcpServers;
6754
- if (servers && typeof servers === "object" && !Array.isArray(servers)) {
6755
- return { mcpServers: servers };
6756
- }
6757
- }
6758
- if ("config" in asRecord && asRecord.config && typeof asRecord.config === "object") {
6759
- const nested = asRecord.config;
6760
- if (isValidConfig(nested)) {
6761
- const servers = nested.mcpServers;
6762
- if (servers && typeof servers === "object" && !Array.isArray(servers)) {
6763
- return { mcpServers: servers };
6764
- }
6765
- }
6766
- }
6767
- return null;
6768
- }
6769
- function isValidConfig(value) {
6770
- if (!("mcpServers" in value)) {
6771
- return false;
6772
- }
6773
- const servers = value.mcpServers;
6774
- if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
6775
- return false;
6776
- }
6777
- for (const server of Object.values(servers)) {
6778
- if (!server || typeof server !== "object" || Array.isArray(server)) {
6779
- return false;
6780
- }
6781
- }
6782
- return true;
6783
- }
6784
6733
  export {
6785
6734
  AGENT_CREATOR_SYSTEM_PROMPT,
6786
6735
  AbortError,
@@ -6830,6 +6779,7 @@ export {
6830
6779
  convertToolCalls,
6831
6780
  createEmptySnapshot,
6832
6781
  createLLM,
6782
+ deduplicateModels,
6833
6783
  err,
6834
6784
  generateFolderTree,
6835
6785
  getAvailableProviders,
@@ -6870,7 +6820,6 @@ export {
6870
6820
  isWebSearchArgs,
6871
6821
  isWebSearchResult,
6872
6822
  isWebSearchSuccess,
6873
- loadMCPConfig,
6874
6823
  normalizeModelInfo,
6875
6824
  normalizeModelLimits,
6876
6825
  normalizeNewlines,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuvin/nuvin-core",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "main": "dist/index.js",