@nuvin/nuvin-core 0.1.0 → 1.0.1

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/index.js CHANGED
@@ -1251,9 +1251,8 @@ var SystemClock = class {
1251
1251
 
1252
1252
  // cost.ts
1253
1253
  var SimpleCost = class {
1254
- // Demo cost: $0.00 (undefined) to avoid implying pricing; could be extended
1255
- estimate(_model, _usage) {
1256
- return void 0;
1254
+ estimate(_model, usage) {
1255
+ return usage?.cost;
1257
1256
  }
1258
1257
  };
1259
1258
 
@@ -2620,7 +2619,6 @@ var AgentRegistry = class {
2620
2619
  maxTokens: partial.maxTokens ?? 4e3,
2621
2620
  provider: partial.provider,
2622
2621
  model: partial.model,
2623
- apiKey: partial.apiKey,
2624
2622
  topP: partial.topP,
2625
2623
  timeoutMs: partial.timeoutMs,
2626
2624
  shareContext: partial.shareContext,
@@ -2911,16 +2909,34 @@ var DefaultSpecialistAgentFactory = class {
2911
2909
  }
2912
2910
  };
2913
2911
 
2912
+ // delegation/LLMResolver.ts
2913
+ var LLMResolver = class {
2914
+ constructor(factory) {
2915
+ this.factory = factory;
2916
+ }
2917
+ resolve(config) {
2918
+ return this.factory.createLLM({
2919
+ provider: config.provider,
2920
+ model: config.model
2921
+ });
2922
+ }
2923
+ };
2924
+
2914
2925
  // agent-manager.ts
2915
2926
  var DEFAULT_TIMEOUT_MS = 3e5;
2916
2927
  var MAX_DELEGATION_DEPTH = 3;
2917
2928
  var AgentManager = class {
2918
- constructor(delegatingConfig, delegatingLLM, delegatingTools, eventCallback) {
2929
+ constructor(delegatingConfig, delegatingTools, llmFactory, eventCallback, configResolver) {
2919
2930
  this.delegatingConfig = delegatingConfig;
2920
- this.delegatingLLM = delegatingLLM;
2921
2931
  this.delegatingTools = delegatingTools;
2932
+ this.llmFactory = llmFactory;
2922
2933
  this.eventCallback = eventCallback;
2934
+ this.configResolver = configResolver;
2935
+ if (llmFactory) {
2936
+ this.llmResolver = new LLMResolver(llmFactory);
2937
+ }
2923
2938
  }
2939
+ llmResolver = null;
2924
2940
  activeAgents = /* @__PURE__ */ new Map();
2925
2941
  eventCollectors = /* @__PURE__ */ new Map();
2926
2942
  /**
@@ -2997,18 +3013,19 @@ var AgentManager = class {
2997
3013
  }
2998
3014
  }
2999
3015
  };
3016
+ const freshConfig = this.configResolver?.() ?? {};
3000
3017
  const specialistConfig = {
3001
3018
  id: agentId,
3002
3019
  systemPrompt: config.systemPrompt,
3003
3020
  temperature: config.temperature ?? this.delegatingConfig.temperature,
3004
3021
  topP: config.topP ?? this.delegatingConfig.topP,
3005
- model: config.model ?? this.delegatingConfig.model,
3022
+ model: config.model ?? freshConfig.model ?? this.delegatingConfig.model,
3006
3023
  maxTokens: config.maxTokens ?? this.delegatingConfig.maxTokens,
3007
3024
  enabledTools: config.tools,
3008
3025
  maxToolConcurrency: this.delegatingConfig.maxToolConcurrency,
3009
3026
  requireToolApproval: false,
3010
3027
  // Specialists run autonomously
3011
- reasoningEffort: this.delegatingConfig.reasoningEffort
3028
+ reasoningEffort: freshConfig.reasoningEffort ?? this.delegatingConfig.reasoningEffort
3012
3029
  };
3013
3030
  const llm = this.resolveLLM(config);
3014
3031
  const specialistOrchestrator = new AgentOrchestrator(specialistConfig, {
@@ -3090,13 +3107,13 @@ var AgentManager = class {
3090
3107
  }
3091
3108
  }
3092
3109
  /**
3093
- * Resolve which LLM to use (reuse delegating LLM or create new one)
3110
+ * Resolve which LLM to use - creates fresh LLM instance via factory
3094
3111
  */
3095
3112
  resolveLLM(config) {
3096
- if (!config.provider && !config.model) {
3097
- return this.delegatingLLM;
3113
+ if (!this.llmResolver) {
3114
+ throw new Error("AgentManager requires LLMFactory to create sub-agents. Please provide llmFactory in constructor.");
3098
3115
  }
3099
- return this.delegatingLLM;
3116
+ return this.llmResolver.resolve(config);
3100
3117
  }
3101
3118
  /**
3102
3119
  * Execute agent task with timeout
@@ -3145,19 +3162,21 @@ var AgentManager = class {
3145
3162
 
3146
3163
  // delegation/AgentManagerCommandRunner.ts
3147
3164
  var AgentManagerCommandRunner = class {
3148
- constructor(delegatingConfig, delegatingLLM, delegatingTools) {
3165
+ constructor(delegatingConfig, delegatingTools, llmFactory, configResolver) {
3149
3166
  this.delegatingConfig = delegatingConfig;
3150
- this.delegatingLLM = delegatingLLM;
3151
3167
  this.delegatingTools = delegatingTools;
3168
+ this.llmFactory = llmFactory;
3169
+ this.configResolver = configResolver;
3152
3170
  }
3153
3171
  async run(config, context) {
3154
3172
  const eventPort = context?.eventPort;
3155
3173
  const signal = context?.signal;
3156
3174
  const agentManager = new AgentManager(
3157
3175
  this.delegatingConfig,
3158
- this.delegatingLLM,
3159
3176
  this.delegatingTools,
3160
- eventPort ? (event) => eventPort.emit(event) : void 0
3177
+ this.llmFactory,
3178
+ eventPort ? (event) => eventPort.emit(event) : void 0,
3179
+ this.configResolver
3161
3180
  );
3162
3181
  return agentManager.executeTask(config, signal);
3163
3182
  }
@@ -3253,16 +3272,34 @@ var DefaultDelegationResultFormatter = class {
3253
3272
  }
3254
3273
  };
3255
3274
 
3275
+ // delegation/DelegationServiceFactory.ts
3276
+ var DelegationServiceFactory = class {
3277
+ create(config) {
3278
+ const specialistFactory = new DefaultSpecialistAgentFactory({
3279
+ agentListProvider: config.agentListProvider
3280
+ });
3281
+ return new DefaultDelegationService(
3282
+ config.agentRegistry,
3283
+ new DefaultDelegationPolicy(),
3284
+ specialistFactory,
3285
+ config.commandRunner,
3286
+ new DefaultDelegationResultFormatter()
3287
+ );
3288
+ }
3289
+ };
3290
+
3256
3291
  // tools.ts
3257
3292
  var ToolRegistry = class {
3258
3293
  tools = /* @__PURE__ */ new Map();
3259
3294
  toolsMemory;
3260
3295
  agentRegistry;
3296
+ delegationServiceFactory;
3261
3297
  assignTool;
3262
3298
  enabledAgentsConfig = {};
3263
3299
  constructor(opts) {
3264
3300
  this.toolsMemory = opts?.toolsMemory || new InMemoryMemory();
3265
3301
  this.agentRegistry = opts?.agentRegistry || new AgentRegistry();
3302
+ this.delegationServiceFactory = opts?.delegationServiceFactory;
3266
3303
  const todoStore = new TodoStore(opts?.todoMemory || new InMemoryMemory());
3267
3304
  const toolInstances = [
3268
3305
  new TodoWriteTool(todoStore),
@@ -3301,22 +3338,20 @@ var ToolRegistry = class {
3301
3338
  /**
3302
3339
  * Initialize AssignTool with orchestrator dependencies (lazy initialization)
3303
3340
  */
3304
- setOrchestrator(config, llm, tools) {
3305
- const delegationService = new DefaultDelegationService(
3306
- this.agentRegistry,
3307
- new DefaultDelegationPolicy(),
3308
- new DefaultSpecialistAgentFactory({
3309
- agentListProvider: () => this.agentRegistry.list().filter(
3310
- (agent) => typeof agent.id === "string" && typeof agent.name === "string" && typeof agent.description === "string"
3311
- ).map((agent) => ({
3312
- id: agent.id,
3313
- name: agent.name,
3314
- description: agent.description
3315
- }))
3316
- }),
3317
- new AgentManagerCommandRunner(config, llm, tools),
3318
- new DefaultDelegationResultFormatter()
3319
- );
3341
+ setOrchestrator(config, tools, llmFactory, configResolver) {
3342
+ const commandRunner = new AgentManagerCommandRunner(config, tools, llmFactory, configResolver);
3343
+ const factory = this.delegationServiceFactory ?? new DelegationServiceFactory();
3344
+ const delegationService = factory.create({
3345
+ agentRegistry: this.agentRegistry,
3346
+ commandRunner,
3347
+ agentListProvider: () => this.agentRegistry.list().filter(
3348
+ (agent) => typeof agent.id === "string" && typeof agent.name === "string" && typeof agent.description === "string"
3349
+ ).map((agent) => ({
3350
+ id: agent.id,
3351
+ name: agent.name,
3352
+ description: agent.description
3353
+ }))
3354
+ });
3320
3355
  delegationService.setEnabledAgents(this.enabledAgentsConfig);
3321
3356
  this.assignTool = new AssignTool(delegationService);
3322
3357
  this.tools.set("assign_task", this.assignTool);
@@ -3758,9 +3793,7 @@ var BaseLLM = class {
3758
3793
  }
3759
3794
  }
3760
3795
  }
3761
- const userAssistantMessages = messages.filter(
3762
- (msg) => msg.role === "user" || msg.role === "assistant"
3763
- );
3796
+ const userAssistantMessages = messages.filter((msg) => msg.role === "user" || msg.role === "assistant");
3764
3797
  const lastTwoIndices = [];
3765
3798
  if (userAssistantMessages.length >= 2) {
3766
3799
  for (let i = userAssistantMessages.length - 2; i < userAssistantMessages.length; i++) {
@@ -3803,7 +3836,8 @@ var BaseLLM = class {
3803
3836
  ...enhancedParams.usage && { usage: enhancedParams.usage }
3804
3837
  };
3805
3838
  if (enhancedParams.tools && enhancedParams.tools.length > 0) body.tools = enhancedParams.tools;
3806
- if (enhancedParams.tool_choice && enhancedParams.tools && enhancedParams.tools.length > 0) body.tool_choice = enhancedParams.tool_choice;
3839
+ if (enhancedParams.tool_choice && enhancedParams.tools && enhancedParams.tools.length > 0)
3840
+ body.tool_choice = enhancedParams.tool_choice;
3807
3841
  const res = await this.getTransport().postJson("/chat/completions", body, void 0, signal);
3808
3842
  if (!res.ok) {
3809
3843
  const text = await res.text();
@@ -3828,7 +3862,8 @@ var BaseLLM = class {
3828
3862
  ...enhancedParams.usage && { usage: enhancedParams.usage }
3829
3863
  };
3830
3864
  if (enhancedParams.tools && enhancedParams.tools.length > 0) body.tools = enhancedParams.tools;
3831
- if (enhancedParams.tool_choice && enhancedParams.tools && enhancedParams.tools.length > 0) body.tool_choice = enhancedParams.tool_choice;
3865
+ if (enhancedParams.tool_choice && enhancedParams.tools && enhancedParams.tools.length > 0)
3866
+ body.tool_choice = enhancedParams.tool_choice;
3832
3867
  const res = await this.getTransport().postStream(
3833
3868
  "/chat/completions",
3834
3869
  body,
@@ -3847,6 +3882,7 @@ var BaseLLM = class {
3847
3882
  let content = "";
3848
3883
  const mergedToolCalls = [];
3849
3884
  let usage;
3885
+ let lastFinishReason;
3850
3886
  const flushEvent = (rawEvent) => {
3851
3887
  const lines = rawEvent.split("\n");
3852
3888
  const dataLines = [];
@@ -3859,11 +3895,15 @@ var BaseLLM = class {
3859
3895
  try {
3860
3896
  const evt = JSON.parse(dataStr);
3861
3897
  const choices = Array.isArray(evt.choices) ? evt.choices : [];
3862
- const finishReason = choices.find((ch) => ch.finish_reason)?.finish_reason;
3863
- if (evt.usage) {
3864
- usage = normalizeUsage(evt.usage);
3865
- if (finishReason && handlers.onStreamFinish) {
3866
- handlers.onStreamFinish(finishReason, usage);
3898
+ const finishReason = choices.find((ch) => ch.finish_reason && ch.finish_reason !== null)?.finish_reason;
3899
+ if (finishReason) {
3900
+ lastFinishReason = finishReason;
3901
+ }
3902
+ const usageData = evt.usage || choices[0]?.usage;
3903
+ if (usageData) {
3904
+ usage = normalizeUsage(usageData);
3905
+ if (lastFinishReason && handlers.onStreamFinish) {
3906
+ handlers.onStreamFinish(lastFinishReason, usage);
3867
3907
  } else {
3868
3908
  handlers.onChunk?.("", usage);
3869
3909
  }
@@ -4411,91 +4451,15 @@ var GithubAuthTransport = class {
4411
4451
  }
4412
4452
  };
4413
4453
 
4414
- // transports/openrouter-transport.ts
4415
- var OpenRouterAuthTransport = class {
4416
- inner;
4417
- apiKey;
4418
- baseUrl;
4419
- constructor(inner, apiKey, baseUrl) {
4420
- this.inner = inner;
4421
- this.apiKey = apiKey;
4422
- this.baseUrl = baseUrl ?? "https://openrouter.ai/api/v1";
4423
- }
4424
- buildFullUrl(path9) {
4425
- if (path9.startsWith("/")) {
4426
- return `${this.baseUrl}${path9}`;
4427
- }
4428
- return path9;
4429
- }
4430
- makeAuthHeaders(headers) {
4431
- if (!this.apiKey || this.apiKey.trim() === "") {
4432
- throw new Error("API key missing");
4433
- }
4434
- const base = headers ? { ...headers } : {};
4435
- base["Authorization"] = `Bearer ${this.apiKey}`;
4436
- return base;
4437
- }
4438
- async get(url, headers, signal) {
4439
- const fullUrl = this.buildFullUrl(url);
4440
- return this.inner.get(fullUrl, this.makeAuthHeaders(headers), signal);
4441
- }
4442
- async postJson(url, body, headers, signal) {
4443
- const fullUrl = this.buildFullUrl(url);
4444
- return this.inner.postJson(fullUrl, body, this.makeAuthHeaders(headers), signal);
4445
- }
4446
- async postStream(url, body, headers, signal) {
4447
- const fullUrl = this.buildFullUrl(url);
4448
- return this.inner.postStream(fullUrl, body, this.makeAuthHeaders(headers), signal);
4449
- }
4450
- };
4451
-
4452
- // transports/deepinfra-transport.ts
4453
- var DeepInfraAuthTransport = class {
4454
+ // transports/base-bearer-auth-transport.ts
4455
+ var BaseBearerAuthTransport = class {
4454
4456
  inner;
4455
4457
  apiKey;
4456
4458
  baseUrl;
4457
4459
  constructor(inner, apiKey, baseUrl) {
4458
4460
  this.inner = inner;
4459
4461
  this.apiKey = apiKey;
4460
- this.baseUrl = baseUrl ?? "https://api.deepinfra.com/v1/openai";
4461
- }
4462
- buildFullUrl(path9) {
4463
- if (path9.startsWith("/")) {
4464
- return `${this.baseUrl}${path9}`;
4465
- }
4466
- return path9;
4467
- }
4468
- makeAuthHeaders(headers) {
4469
- if (!this.apiKey || this.apiKey.trim() === "") {
4470
- throw new Error("API key missing");
4471
- }
4472
- const base = headers ? { ...headers } : {};
4473
- base["Authorization"] = `Bearer ${this.apiKey}`;
4474
- return base;
4475
- }
4476
- async get(url, headers, signal) {
4477
- const fullUrl = this.buildFullUrl(url);
4478
- return this.inner.get(fullUrl, this.makeAuthHeaders(headers), signal);
4479
- }
4480
- async postJson(url, body, headers, signal) {
4481
- const fullUrl = this.buildFullUrl(url);
4482
- return this.inner.postJson(fullUrl, body, this.makeAuthHeaders(headers), signal);
4483
- }
4484
- async postStream(url, body, headers, signal) {
4485
- const fullUrl = this.buildFullUrl(url);
4486
- return this.inner.postStream(fullUrl, body, this.makeAuthHeaders(headers), signal);
4487
- }
4488
- };
4489
-
4490
- // transports/zai-transport.ts
4491
- var ZAIAuthTransport = class {
4492
- inner;
4493
- apiKey;
4494
- baseUrl;
4495
- constructor(inner, apiKey, baseUrl) {
4496
- this.inner = inner;
4497
- this.apiKey = apiKey;
4498
- this.baseUrl = baseUrl ?? "https://api.z.ai/api/coding/paas/v4";
4462
+ this.baseUrl = baseUrl ?? this.getDefaultBaseUrl();
4499
4463
  }
4500
4464
  buildFullUrl(path9) {
4501
4465
  if (path9.startsWith("/")) {
@@ -4525,105 +4489,23 @@ var ZAIAuthTransport = class {
4525
4489
  }
4526
4490
  };
4527
4491
 
4528
- // transports/anthropic-transport.ts
4529
- var AnthropicAuthTransport = class {
4530
- apiKey;
4531
- oauth;
4532
- baseUrl;
4533
- inner;
4534
- constructor(inner, opts = {}) {
4535
- this.inner = inner;
4536
- this.apiKey = opts.apiKey;
4537
- this.oauth = opts.oauth;
4538
- this.baseUrl = opts.baseUrl || "https://api.anthropic.com";
4492
+ // transports/simple-bearer-transport.ts
4493
+ var SimpleBearerAuthTransport = class extends BaseBearerAuthTransport {
4494
+ defaultUrl;
4495
+ constructor(inner, defaultBaseUrl, apiKey, baseUrl) {
4496
+ super(inner, apiKey, baseUrl ?? defaultBaseUrl);
4497
+ this.defaultUrl = defaultBaseUrl;
4539
4498
  }
4540
- async refreshOAuth(signal) {
4541
- if (!this.oauth?.refresh) return;
4542
- if (this.oauth.expires > Date.now()) return;
4543
- try {
4544
- const response = await fetch("https://console.anthropic.com/v1/oauth/token", {
4545
- method: "POST",
4546
- headers: {
4547
- "Content-Type": "application/json"
4548
- },
4549
- body: JSON.stringify({
4550
- grant_type: "refresh_token",
4551
- refresh_token: this.oauth.refresh,
4552
- client_id: "9d1c250a-e61b-44d9-88ed-5944d1962f5e"
4553
- }),
4554
- signal
4555
- });
4556
- if (!response.ok) {
4557
- throw new Error(`OAuth token refresh failed: ${response.status} ${response.statusText}`);
4558
- }
4559
- const data = await response.json();
4560
- this.oauth = {
4561
- type: "oauth",
4562
- access: data.access_token,
4563
- refresh: data.refresh_token || this.oauth.refresh,
4564
- expires: Date.now() + data.expires_in * 1e3
4565
- };
4566
- } catch (error) {
4567
- throw new Error(`Failed to refresh OAuth token: ${error instanceof Error ? error.message : String(error)}`);
4568
- }
4569
- }
4570
- buildFullUrl(path9) {
4571
- if (path9.startsWith("/")) {
4572
- return `${this.baseUrl}${path9}`;
4573
- }
4574
- return path9;
4575
- }
4576
- getAuthHeaders() {
4577
- const headers = {};
4578
- if (this.oauth) {
4579
- headers.authorization = `Bearer ${this.oauth.access}`;
4580
- } else if (this.apiKey) {
4581
- headers["x-api-key"] = this.apiKey;
4582
- } else {
4583
- throw new Error("No authentication credentials provided");
4584
- }
4585
- headers["anthropic-version"] = "2023-06-01";
4586
- headers["anthropic-beta"] = [
4587
- "claude-code-20250219",
4588
- "interleaved-thinking-2025-05-14",
4589
- "fine-grained-tool-streaming-2025-05-14"
4590
- ].join(",");
4591
- return headers;
4592
- }
4593
- async get(url, headers, signal) {
4594
- if (this.oauth) {
4595
- await this.refreshOAuth(signal);
4596
- }
4597
- const fullUrl = this.buildFullUrl(url);
4598
- const authHeaders = this.getAuthHeaders();
4599
- const mergedHeaders = { ...authHeaders, ...headers };
4600
- return this.inner.get(fullUrl, mergedHeaders, signal);
4601
- }
4602
- async postJson(url, body, headers, signal) {
4603
- if (this.oauth) {
4604
- await this.refreshOAuth(signal);
4605
- }
4606
- const fullUrl = this.buildFullUrl(url);
4607
- const authHeaders = this.getAuthHeaders();
4608
- const mergedHeaders = { ...authHeaders, ...headers };
4609
- return this.inner.postJson(fullUrl, body, mergedHeaders, signal);
4610
- }
4611
- async postStream(url, body, headers, signal) {
4612
- if (this.oauth) {
4613
- await this.refreshOAuth(signal);
4614
- }
4615
- const fullUrl = this.buildFullUrl(url);
4616
- const authHeaders = this.getAuthHeaders();
4617
- const mergedHeaders = { ...authHeaders, ...headers };
4618
- return this.inner.postStream(fullUrl, body, mergedHeaders, signal);
4619
- }
4620
- // Method to update OAuth credentials (useful for token refresh from config)
4621
- updateCredentials(opts) {
4622
- if (opts.apiKey) this.apiKey = opts.apiKey;
4623
- if (opts.oauth) this.oauth = opts.oauth;
4499
+ getDefaultBaseUrl() {
4500
+ return this.defaultUrl;
4624
4501
  }
4625
4502
  };
4626
4503
 
4504
+ // transports/transport-factory.ts
4505
+ function createTransport(_name, inner, defaultBaseUrl, apiKey, baseUrl) {
4506
+ return new SimpleBearerAuthTransport(inner, defaultBaseUrl, apiKey, baseUrl);
4507
+ }
4508
+
4627
4509
  // llm-providers/llm-github.ts
4628
4510
  var GithubLLM = class extends BaseLLM {
4629
4511
  opts;
@@ -4649,392 +4531,6 @@ var GithubLLM = class extends BaseLLM {
4649
4531
  }
4650
4532
  };
4651
4533
 
4652
- // llm-providers/llm-openrouter.ts
4653
- var OpenRouterLLM = class extends BaseLLM {
4654
- includeUsage;
4655
- constructor(opts = {}) {
4656
- const { enablePromptCaching = true, includeUsage = true, ...restOpts } = opts;
4657
- super("https://openrouter.ai/api/v1", { enablePromptCaching });
4658
- this.includeUsage = includeUsage;
4659
- this.opts = restOpts;
4660
- }
4661
- opts;
4662
- createTransport() {
4663
- const base = new FetchTransport({ persistFile: this.opts.httpLogFile });
4664
- return new OpenRouterAuthTransport(base, this.opts.apiKey, this.apiUrl);
4665
- }
4666
- async generateCompletion(params, signal) {
4667
- let enhancedParams = params;
4668
- if (this.includeUsage && !enhancedParams.usage) {
4669
- enhancedParams = { ...enhancedParams, usage: { include: true } };
4670
- }
4671
- return super.generateCompletion(enhancedParams, signal);
4672
- }
4673
- async streamCompletion(params, handlers, signal) {
4674
- let enhancedParams = params;
4675
- if (this.includeUsage && !enhancedParams.usage) {
4676
- enhancedParams = { ...enhancedParams, usage: { include: true } };
4677
- }
4678
- return super.streamCompletion(enhancedParams, handlers, signal);
4679
- }
4680
- async getModels(signal) {
4681
- const transport = this.createTransport();
4682
- const res = await transport.get("/models", void 0, signal);
4683
- if (!res.ok) {
4684
- const text = await res.text();
4685
- throw new Error(`Failed to fetch models: ${res.status} ${text}`);
4686
- }
4687
- const data = await res.json();
4688
- return data.data;
4689
- }
4690
- };
4691
-
4692
- // llm-providers/llm-deepinfra.ts
4693
- var DeepInfraLLM = class extends BaseLLM {
4694
- opts;
4695
- constructor(opts = {}) {
4696
- super(opts.apiUrl || "https://api.deepinfra.com/v1/openai");
4697
- this.opts = opts;
4698
- }
4699
- createTransport() {
4700
- const base = new FetchTransport({ persistFile: this.opts.httpLogFile });
4701
- return new DeepInfraAuthTransport(base, this.opts.apiKey || process.env.DEEPINFRA_API_KEY, this.opts.apiUrl);
4702
- }
4703
- async getModels(signal) {
4704
- const transport = this.createTransport();
4705
- const res = await transport.get("/models", void 0, signal);
4706
- if (!res.ok) {
4707
- const text = await res.text();
4708
- throw new Error(`Failed to fetch models: ${res.status} ${text}`);
4709
- }
4710
- const data = await res.json();
4711
- return data.data;
4712
- }
4713
- };
4714
-
4715
- // llm-providers/llm-zai.ts
4716
- var ZaiLLM = class extends BaseLLM {
4717
- opts;
4718
- constructor(opts = {}) {
4719
- super("https://api.z.ai/api/coding/paas/v4");
4720
- this.opts = opts;
4721
- }
4722
- createTransport() {
4723
- const base = new FetchTransport({
4724
- persistFile: this.opts.httpLogFile,
4725
- logLevel: "INFO",
4726
- enableConsoleLog: false,
4727
- maxFileSize: 5 * 1024 * 1024,
4728
- // 5MB before rotation
4729
- captureResponseBody: true
4730
- // Disable for better performance
4731
- });
4732
- return new ZAIAuthTransport(base, this.opts.apiKey, this.apiUrl);
4733
- }
4734
- };
4735
-
4736
- // llm-providers/llm-anthropic.ts
4737
- var AnthropicLLM = class {
4738
- transport = null;
4739
- opts;
4740
- apiUrl;
4741
- constructor(opts = {}) {
4742
- this.opts = opts;
4743
- this.apiUrl = opts.apiUrl || "https://api.anthropic.com";
4744
- }
4745
- getTransport() {
4746
- if (!this.transport) {
4747
- const base = new FetchTransport({
4748
- persistFile: this.opts.httpLogFile
4749
- });
4750
- this.transport = new AnthropicAuthTransport(base, {
4751
- apiKey: this.opts.apiKey,
4752
- oauth: this.opts.oauth,
4753
- baseUrl: this.apiUrl
4754
- });
4755
- }
4756
- return this.transport;
4757
- }
4758
- transformToAnthropicMessages(messages) {
4759
- const systemMessages = [];
4760
- const anthropicMessages = [];
4761
- for (const msg of messages) {
4762
- if (msg.role === "system") {
4763
- if (typeof msg.content === "string") {
4764
- systemMessages.push(msg.content);
4765
- } else if (Array.isArray(msg.content)) {
4766
- for (const part of msg.content) {
4767
- if (part.type === "text") {
4768
- systemMessages.push(part.text);
4769
- }
4770
- }
4771
- }
4772
- continue;
4773
- }
4774
- if (msg.role === "tool") {
4775
- const lastMsg = anthropicMessages[anthropicMessages.length - 1];
4776
- if (lastMsg && lastMsg.role === "user" && Array.isArray(lastMsg.content)) {
4777
- lastMsg.content.push({
4778
- type: "tool_result",
4779
- tool_use_id: msg.tool_call_id || "",
4780
- content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)
4781
- });
4782
- } else {
4783
- anthropicMessages.push({
4784
- role: "user",
4785
- content: [
4786
- {
4787
- type: "tool_result",
4788
- tool_use_id: msg.tool_call_id || "",
4789
- content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)
4790
- }
4791
- ]
4792
- });
4793
- }
4794
- continue;
4795
- }
4796
- const content = [];
4797
- if (typeof msg.content === "string" && msg.content) {
4798
- content.push({ type: "text", text: msg.content });
4799
- } else if (Array.isArray(msg.content)) {
4800
- for (const part of msg.content) {
4801
- if (part.type === "text") {
4802
- content.push({ type: "text", text: part.text });
4803
- } else if (part.type === "image_url") {
4804
- const url = part.image_url.url;
4805
- if (url.startsWith("data:")) {
4806
- const match = url.match(/^data:([^;]+);base64,(.+)$/);
4807
- if (match) {
4808
- content.push({
4809
- type: "image",
4810
- source: {
4811
- type: "base64",
4812
- media_type: match[1],
4813
- data: match[2]
4814
- }
4815
- });
4816
- }
4817
- }
4818
- }
4819
- }
4820
- }
4821
- if (msg.tool_calls) {
4822
- for (const toolCall of msg.tool_calls) {
4823
- content.push({
4824
- type: "tool_use",
4825
- id: toolCall.id,
4826
- name: toolCall.function.name,
4827
- input: JSON.parse(toolCall.function.arguments || "{}")
4828
- });
4829
- }
4830
- }
4831
- if (content.length > 0) {
4832
- anthropicMessages.push({
4833
- role: msg.role === "assistant" ? "assistant" : "user",
4834
- content: content.length === 1 && content[0].type === "text" ? content[0].text : content
4835
- });
4836
- }
4837
- }
4838
- const result = {
4839
- messages: anthropicMessages
4840
- };
4841
- if (systemMessages.length > 0) {
4842
- result.system = [
4843
- {
4844
- type: "text",
4845
- text: "You are Claude Code, Anthropic's official CLI for Claude."
4846
- },
4847
- { type: "text", text: systemMessages.join("\n\n") }
4848
- ];
4849
- }
4850
- return result;
4851
- }
4852
- transformTools(tools) {
4853
- if (!tools || tools.length === 0) return void 0;
4854
- return tools.map((tool) => ({
4855
- name: tool.function.name,
4856
- description: tool.function.description,
4857
- input_schema: tool.function.parameters
4858
- }));
4859
- }
4860
- transformToolChoice(toolChoice) {
4861
- if (!toolChoice || toolChoice === "auto") {
4862
- return { type: "auto" };
4863
- }
4864
- if (toolChoice === "none") {
4865
- return void 0;
4866
- }
4867
- if (typeof toolChoice === "object" && toolChoice.type === "function") {
4868
- return { type: "tool", name: toolChoice.function.name };
4869
- }
4870
- return { type: "auto" };
4871
- }
4872
- transformResponse(response) {
4873
- let content = "";
4874
- const tool_calls = [];
4875
- for (const block of response.content) {
4876
- if (block.type === "text") {
4877
- content += block.text;
4878
- } else if (block.type === "tool_use") {
4879
- tool_calls.push({
4880
- id: block.id,
4881
- type: "function",
4882
- function: {
4883
- name: block.name,
4884
- arguments: JSON.stringify(block.input)
4885
- }
4886
- });
4887
- }
4888
- }
4889
- const usage = {
4890
- prompt_tokens: response.usage.input_tokens,
4891
- completion_tokens: response.usage.output_tokens,
4892
- total_tokens: response.usage.input_tokens + response.usage.output_tokens
4893
- };
4894
- return {
4895
- content,
4896
- ...tool_calls.length > 0 ? { tool_calls } : {},
4897
- usage
4898
- };
4899
- }
4900
- async generateCompletion(params, signal) {
4901
- const { system, messages } = this.transformToAnthropicMessages(params.messages);
4902
- const tools = this.transformTools(params.tools);
4903
- const tool_choice = tools ? this.transformToolChoice(params.tool_choice) : void 0;
4904
- const body = {
4905
- model: params.model,
4906
- messages,
4907
- max_tokens: params.maxTokens ?? 10240,
4908
- temperature: params.temperature,
4909
- stream: false,
4910
- // ...(params.topP !== undefined && { top_p: params.topP }),
4911
- ...system && { system },
4912
- ...tools && { tools },
4913
- ...tool_choice && { tool_choice }
4914
- };
4915
- const res = await this.getTransport().postJson("/v1/messages", body, void 0, signal);
4916
- if (!res.ok) {
4917
- const text = await res.text();
4918
- throw new Error(text || `Anthropic API error ${res.status}`);
4919
- }
4920
- const data = await res.json();
4921
- return this.transformResponse(data);
4922
- }
4923
- async streamCompletion(params, handlers = {}, signal) {
4924
- const { system, messages } = this.transformToAnthropicMessages(params.messages);
4925
- const tools = this.transformTools(params.tools);
4926
- const tool_choice = tools ? this.transformToolChoice(params.tool_choice) : void 0;
4927
- const body = {
4928
- model: params.model,
4929
- messages,
4930
- max_tokens: params.maxTokens ?? 10240,
4931
- temperature: params.temperature,
4932
- stream: true,
4933
- // ...(params.topP !== undefined && { top_p: params.topP }),
4934
- ...system && { system },
4935
- ...tools && { tools },
4936
- ...tool_choice && { tool_choice }
4937
- };
4938
- const res = await this.getTransport().postStream("/v1/messages", body, { Accept: "text/event-stream" }, signal);
4939
- if (!res.ok) {
4940
- const text = await res.text();
4941
- throw new Error(text || `Anthropic stream error ${res.status}`);
4942
- }
4943
- const reader = res.body?.getReader();
4944
- if (!reader) return { content: "" };
4945
- const decoder = new TextDecoder("utf-8");
4946
- let buffer = "";
4947
- let content = "";
4948
- const toolCalls = /* @__PURE__ */ new Map();
4949
- let usage;
4950
- let inputTokens = 0;
4951
- let stopReason = null;
4952
- const processEvent = (eventData) => {
4953
- try {
4954
- const event = JSON.parse(eventData);
4955
- if (event.type === "message_start") {
4956
- if (event.message?.usage) {
4957
- inputTokens = event.message.usage.input_tokens || 0;
4958
- }
4959
- } else if (event.type === "content_block_start") {
4960
- const block = event.content_block;
4961
- if (block?.type === "tool_use" && "id" in block && "name" in block) {
4962
- toolCalls.set(event.index, {
4963
- id: String(block.id),
4964
- type: "function",
4965
- function: {
4966
- name: String(block.name) || "",
4967
- arguments: ""
4968
- }
4969
- });
4970
- }
4971
- } else if (event.type === "content_block_delta") {
4972
- if (event.delta.type === "text_delta") {
4973
- const textDelta = event.delta.text;
4974
- if (textDelta) {
4975
- content += textDelta;
4976
- handlers.onChunk?.(textDelta);
4977
- }
4978
- } else if (event.delta.type === "input_json_delta") {
4979
- const toolCall = toolCalls.get(event.index);
4980
- if (toolCall) {
4981
- toolCall.function.arguments += event.delta.partial_json;
4982
- handlers.onToolCallDelta?.(toolCall);
4983
- }
4984
- }
4985
- } else if (event.type === "message_delta") {
4986
- if (event.delta.stop_reason) {
4987
- stopReason = event.delta.stop_reason;
4988
- }
4989
- if (event.usage) {
4990
- usage = {
4991
- prompt_tokens: inputTokens,
4992
- completion_tokens: event.usage.output_tokens,
4993
- total_tokens: inputTokens + event.usage.output_tokens
4994
- };
4995
- }
4996
- } else if (event.type === "message_stop") {
4997
- if (handlers.onStreamFinish) {
4998
- handlers.onStreamFinish(stopReason || void 0, usage);
4999
- }
5000
- }
5001
- } catch (err2) {
5002
- }
5003
- };
5004
- while (true) {
5005
- const { value, done } = await reader.read();
5006
- if (done) break;
5007
- const chunk = decoder.decode(value, { stream: true });
5008
- buffer += chunk;
5009
- const lines = buffer.split("\n");
5010
- buffer = lines.pop() || "";
5011
- for (const line of lines) {
5012
- if (line.startsWith("data: ")) {
5013
- const data = line.slice(6).trim();
5014
- if (data && data !== "[DONE]") {
5015
- processEvent(data);
5016
- }
5017
- }
5018
- }
5019
- }
5020
- if (buffer.trim()) {
5021
- const line = buffer.trim();
5022
- if (line.startsWith("data: ")) {
5023
- const data = line.slice(6).trim();
5024
- if (data && data !== "[DONE]") {
5025
- processEvent(data);
5026
- }
5027
- }
5028
- }
5029
- const tool_calls = toolCalls.size > 0 ? Array.from(toolCalls.values()) : void 0;
5030
- return {
5031
- content,
5032
- ...tool_calls && { tool_calls },
5033
- ...usage && { usage }
5034
- };
5035
- }
5036
- };
5037
-
5038
4534
  // llm-providers/llm-anthropic-aisdk.ts
5039
4535
  import { createAnthropic } from "@ai-sdk/anthropic";
5040
4536
  import {
@@ -5479,6 +4975,125 @@ var AnthropicAISDKLLM = class {
5479
4975
  }
5480
4976
  };
5481
4977
 
4978
+ // llm-providers/llm-provider-config.json
4979
+ var llm_provider_config_default = {
4980
+ providers: [
4981
+ {
4982
+ name: "deepinfra",
4983
+ className: "DeepInfraLLM",
4984
+ baseUrl: "https://api.deepinfra.com/v1/openai",
4985
+ transportName: "deepinfra",
4986
+ features: {
4987
+ promptCaching: false,
4988
+ getModels: true
4989
+ }
4990
+ },
4991
+ {
4992
+ name: "openrouter",
4993
+ className: "OpenRouterLLM",
4994
+ baseUrl: "https://openrouter.ai/api/v1",
4995
+ transportName: "openrouter",
4996
+ features: {
4997
+ promptCaching: true,
4998
+ getModels: true,
4999
+ includeUsage: true
5000
+ }
5001
+ },
5002
+ {
5003
+ name: "zai",
5004
+ className: "ZaiLLM",
5005
+ baseUrl: "https://api.z.ai/api/coding/paas/v4",
5006
+ transportName: "zai",
5007
+ features: {
5008
+ promptCaching: false,
5009
+ getModels: false
5010
+ }
5011
+ },
5012
+ {
5013
+ name: "moonshot",
5014
+ className: "MoonshotLLM",
5015
+ baseUrl: "https://api.moonshot.ai/v1",
5016
+ transportName: "moonshot",
5017
+ features: {
5018
+ promptCaching: false,
5019
+ getModels: true
5020
+ }
5021
+ }
5022
+ ]
5023
+ };
5024
+
5025
+ // llm-providers/llm-factory.ts
5026
+ var providers = llm_provider_config_default.providers;
5027
+ var GenericLLM = class extends BaseLLM {
5028
+ opts;
5029
+ transportName;
5030
+ includeUsage;
5031
+ supportsModels;
5032
+ constructor(transportName, baseUrl, supportsModels, opts = {}) {
5033
+ const { enablePromptCaching = false, includeUsage = false, ...restOpts } = opts;
5034
+ super(opts.apiUrl || baseUrl, { enablePromptCaching });
5035
+ this.transportName = transportName;
5036
+ this.includeUsage = includeUsage;
5037
+ this.supportsModels = supportsModels;
5038
+ this.opts = restOpts;
5039
+ }
5040
+ createTransport() {
5041
+ const base = new FetchTransport({
5042
+ persistFile: this.opts.httpLogFile,
5043
+ logLevel: "INFO",
5044
+ enableConsoleLog: false,
5045
+ maxFileSize: 5 * 1024 * 1024,
5046
+ captureResponseBody: true
5047
+ });
5048
+ return createTransport(this.transportName, base, this.apiUrl, this.opts.apiKey, this.opts.apiUrl);
5049
+ }
5050
+ async getModels(signal) {
5051
+ if (!this.supportsModels) {
5052
+ throw new Error(`Provider ${this.transportName} does not support getModels`);
5053
+ }
5054
+ const transport = this.createTransport();
5055
+ const res = await transport.get("/models", void 0, signal);
5056
+ if (!res.ok) {
5057
+ const text = await res.text();
5058
+ throw new Error(`Failed to fetch models: ${res.status} ${text}`);
5059
+ }
5060
+ const data = await res.json();
5061
+ return data.data;
5062
+ }
5063
+ async generateCompletion(params, signal) {
5064
+ let enhancedParams = params;
5065
+ if (this.includeUsage && !enhancedParams.usage) {
5066
+ enhancedParams = { ...enhancedParams, usage: { include: true } };
5067
+ }
5068
+ return super.generateCompletion(enhancedParams, signal);
5069
+ }
5070
+ async streamCompletion(params, handlers, signal) {
5071
+ let enhancedParams = params;
5072
+ if (this.includeUsage && !enhancedParams.usage) {
5073
+ enhancedParams = { ...enhancedParams, usage: { include: true } };
5074
+ }
5075
+ return super.streamCompletion(enhancedParams, handlers, signal);
5076
+ }
5077
+ };
5078
+ function createLLM(providerName, options = {}) {
5079
+ const config = providers.find((p) => p.name.toLowerCase() === providerName.toLowerCase());
5080
+ if (!config) {
5081
+ throw new Error(`Unknown LLM provider: ${providerName}. Available: ${providers.map((p) => p.name).join(", ")}`);
5082
+ }
5083
+ return new GenericLLM(config.transportName, config.baseUrl, config.features.getModels ?? false, {
5084
+ ...options,
5085
+ enablePromptCaching: options.enablePromptCaching ?? config.features.promptCaching,
5086
+ includeUsage: options.includeUsage ?? config.features.includeUsage
5087
+ });
5088
+ }
5089
+ function getAvailableProviders() {
5090
+ return providers.map((p) => p.name);
5091
+ }
5092
+ function supportsGetModels(providerName) {
5093
+ const config = providers.find((p) => p.name.toLowerCase() === providerName.toLowerCase());
5094
+ return config?.features.getModels ?? false;
5095
+ }
5096
+
5482
5097
  // mcp/mcp-client.ts
5483
5098
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5484
5099
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
@@ -5779,27 +5394,26 @@ export {
5779
5394
  AgentOrchestrator,
5780
5395
  AgentRegistry,
5781
5396
  AnthropicAISDKLLM,
5782
- AnthropicLLM,
5783
5397
  BashTool,
5784
5398
  CompositeToolPort,
5785
5399
  ConversationContext,
5786
5400
  ConversationStore,
5787
5401
  CoreMCPClient,
5788
- DeepInfraLLM,
5789
5402
  DefaultDelegationPolicy,
5790
5403
  DefaultDelegationResultFormatter,
5791
5404
  DefaultDelegationService,
5792
5405
  DefaultSpecialistAgentFactory,
5406
+ DelegationServiceFactory,
5793
5407
  EchoLLM,
5794
5408
  GithubLLM,
5795
5409
  InMemoryMemory,
5796
5410
  InMemoryMetadata,
5797
5411
  JsonFileMemoryPersistence,
5798
5412
  LLMError,
5413
+ LLMResolver,
5799
5414
  MCPToolPort,
5800
5415
  MemoryPortMetadataAdapter,
5801
5416
  NoopReminders,
5802
- OpenRouterLLM,
5803
5417
  PersistedMemory,
5804
5418
  PersistingConsoleEventPort,
5805
5419
  RuntimeEnv,
@@ -5808,15 +5422,17 @@ export {
5808
5422
  SimpleId,
5809
5423
  SystemClock,
5810
5424
  ToolRegistry,
5811
- ZaiLLM,
5812
5425
  buildAgentCreationPrompt,
5813
5426
  buildInjectedSystem,
5814
5427
  canonicalizeTerminalPaste,
5428
+ createLLM,
5815
5429
  generateFolderTree,
5430
+ getAvailableProviders,
5816
5431
  loadMCPConfig,
5817
5432
  normalizeNewlines,
5818
5433
  renderTemplate,
5819
5434
  resolveBackspaces,
5820
5435
  resolveCarriageReturns,
5821
- stripAnsiAndControls
5436
+ stripAnsiAndControls,
5437
+ supportsGetModels
5822
5438
  };