@nuvin/nuvin-core 1.1.1 → 1.1.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.1.1",
3
- "commit": "6744c77"
2
+ "version": "1.1.2",
3
+ "commit": "76be190"
4
4
  }
package/dist/index.d.ts CHANGED
@@ -19,6 +19,11 @@ type AgentTemplate = {
19
19
  shareContext?: boolean;
20
20
  metadata?: Record<string, unknown>;
21
21
  };
22
+ /**
23
+ * CompleteAgent is an AgentTemplate with all required fields populated
24
+ * Used for registered agents that have gone through applyDefaults()
25
+ */
26
+ type CompleteAgent = Required<Pick<AgentTemplate, 'id' | 'name' | 'description' | 'systemPrompt' | 'tools' | 'temperature' | 'maxTokens'>> & Pick<AgentTemplate, 'provider' | 'model' | 'topP' | 'timeoutMs' | 'shareContext' | 'metadata'>;
22
27
  /**
23
28
  * Specialist Agent Configuration (Internal - used by AgentManager)
24
29
  */
@@ -135,7 +140,7 @@ declare class AgentRegistry {
135
140
  */
136
141
  applyDefaults(partial: Partial<AgentTemplate> & {
137
142
  systemPrompt: string;
138
- }): AgentTemplate;
143
+ }): CompleteAgent;
139
144
  /**
140
145
  * Load agents from memory persistence
141
146
  */
@@ -161,7 +166,7 @@ declare class AgentRegistry {
161
166
  /**
162
167
  * Save agent to file
163
168
  */
164
- saveToFile(agent: AgentTemplate): Promise<void>;
169
+ saveToFile(agent: CompleteAgent): Promise<void>;
165
170
  /**
166
171
  * Delete agent from file
167
172
  */
@@ -177,11 +182,11 @@ declare class AgentRegistry {
177
182
  /**
178
183
  * Get an agent template by ID
179
184
  */
180
- get(agentId: string): AgentTemplate | undefined;
185
+ get(agentId: string): CompleteAgent | undefined;
181
186
  /**
182
187
  * List all registered agent templates
183
188
  */
184
- list(): AgentTemplate[];
189
+ list(): CompleteAgent[];
185
190
  /**
186
191
  * Check if an agent exists
187
192
  */
@@ -922,7 +927,7 @@ declare class DefaultSpecialistAgentFactory implements SpecialistAgentFactory {
922
927
  systemContextProvider?: SystemContextProvider;
923
928
  agentListProvider?: AgentListProvider;
924
929
  idGenerator?: IdGenerator;
925
- });
930
+ } | undefined);
926
931
  create(input: SpecialistAgentFactoryInput): SpecialistAgentConfig;
927
932
  }
928
933
 
@@ -938,7 +943,7 @@ declare class AgentManager {
938
943
  private llmResolver;
939
944
  private activeAgents;
940
945
  private eventCollectors;
941
- constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory, eventCallback?: (event: AgentEvent) => void, configResolver?: () => Partial<AgentConfig>);
946
+ constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory | undefined, eventCallback?: ((event: AgentEvent) => void) | undefined, configResolver?: (() => Partial<AgentConfig>) | undefined);
942
947
  /**
943
948
  * Create and execute a specialist agent for a specific task
944
949
  */
@@ -970,7 +975,7 @@ declare class AgentManagerCommandRunner implements AgentCommandRunner {
970
975
  private readonly delegatingTools;
971
976
  private readonly llmFactory?;
972
977
  private readonly configResolver?;
973
- constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory, configResolver?: () => Partial<AgentConfig>);
978
+ constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory | undefined, configResolver?: (() => Partial<AgentConfig>) | undefined);
974
979
  run(config: Parameters<AgentManager['executeTask']>[0], context?: ToolExecutionContext): Promise<SpecialistAgentResult>;
975
980
  }
976
981
 
@@ -995,7 +1000,7 @@ declare class DefaultDelegationResultFormatter implements DelegationResultFormat
995
1000
  status: "success" | "error" | "timeout";
996
1001
  executionTimeMs: number;
997
1002
  toolCallsExecuted: number;
998
- tokensUsed: number;
1003
+ tokensUsed: number | undefined;
999
1004
  };
1000
1005
  };
1001
1006
  formatError(error: unknown): string;
@@ -1157,9 +1162,9 @@ declare class GithubAuthTransport implements HttpTransport {
1157
1162
  }
1158
1163
 
1159
1164
  declare class LLMError extends Error {
1160
- readonly statusCode?: number;
1165
+ readonly statusCode?: number | undefined;
1161
1166
  readonly isRetryable: boolean;
1162
- constructor(message: string, statusCode?: number, isRetryable?: boolean, cause?: unknown);
1167
+ constructor(message: string, statusCode?: number | undefined, isRetryable?: boolean, cause?: unknown);
1163
1168
  }
1164
1169
  declare abstract class BaseLLM implements LLMPort {
1165
1170
  protected transport: HttpTransport | null;
@@ -1328,6 +1333,7 @@ declare function loadMCPConfig(filePath?: string): Promise<MCPConfig | null>;
1328
1333
  declare class PersistingConsoleEventPort implements EventPort {
1329
1334
  private memory;
1330
1335
  private maxPerConversation;
1336
+ private writeQueue;
1331
1337
  constructor(opts?: {
1332
1338
  memory?: MemoryPort<AgentEvent>;
1333
1339
  filename?: string;
@@ -1342,4 +1348,4 @@ declare function resolveBackspaces(s: string): string;
1342
1348
  declare function stripAnsiAndControls(s: string): string;
1343
1349
  declare function canonicalizeTerminalPaste(raw: string): string;
1344
1350
 
1345
- export { AGENT_CREATOR_SYSTEM_PROMPT, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignParams, BashTool, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, ErrorReason, type FolderTreeOptions, GithubLLM, InMemoryMemory, InMemoryMetadata, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, NoopReminders, type OrchestratorAwareToolPort, PersistedMemory, PersistingConsoleEventPort, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, SystemClock, type ToolApprovalDecision, type ToolCall, type ToolExecutionResult, type ToolPort, ToolRegistry, type UserAttachment, type UserMessagePayload, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, createLLM, generateFolderTree, getAvailableProviders, loadMCPConfig, normalizeNewlines, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels };
1351
+ export { AGENT_CREATOR_SYSTEM_PROMPT, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignParams, BashTool, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, ErrorReason, type FolderTreeOptions, GithubLLM, InMemoryMemory, InMemoryMetadata, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, NoopReminders, type OrchestratorAwareToolPort, PersistedMemory, PersistingConsoleEventPort, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, SystemClock, type ToolApprovalDecision, type ToolCall, type ToolExecutionResult, type ToolPort, ToolRegistry, type UserAttachment, type UserMessagePayload, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, createLLM, generateFolderTree, getAvailableProviders, loadMCPConfig, normalizeNewlines, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels };
package/dist/index.js CHANGED
@@ -2384,8 +2384,12 @@ var BashTool = class {
2384
2384
  }
2385
2385
  arr.push(chunk);
2386
2386
  };
2387
- child.stdout.on("data", (d) => capPush(stdout, d));
2388
- child.stderr.on("data", (d) => capPush(stderr, d));
2387
+ if (child.stdout) {
2388
+ child.stdout.on("data", (d) => capPush(stdout, d));
2389
+ }
2390
+ if (child.stderr) {
2391
+ child.stderr.on("data", (d) => capPush(stderr, d));
2392
+ }
2389
2393
  const exit = new Promise((res) => {
2390
2394
  child.on("close", (code, signal2) => res({ code, signal: signal2 }));
2391
2395
  });
@@ -2643,8 +2647,10 @@ var AgentRegistry = class {
2643
2647
  this.filePersistence = options?.filePersistence;
2644
2648
  for (const agent of defaultAgents) {
2645
2649
  const complete = this.applyDefaults(agent);
2646
- this.agents.set(complete.id, complete);
2647
- this.defaultAgentIds.add(complete.id);
2650
+ if (complete.id) {
2651
+ this.agents.set(complete.id, complete);
2652
+ this.defaultAgentIds.add(complete.id);
2653
+ }
2648
2654
  }
2649
2655
  this.loadingPromise = this.loadAgents();
2650
2656
  }
@@ -2726,7 +2732,7 @@ var AgentRegistry = class {
2726
2732
  for (const agent of loadedAgents) {
2727
2733
  if (this.validateTemplate(agent)) {
2728
2734
  const complete = this.applyDefaults(agent);
2729
- if (!this.defaultAgentIds.has(complete.id)) {
2735
+ if (complete.id && !this.defaultAgentIds.has(complete.id)) {
2730
2736
  this.agents.set(complete.id, complete);
2731
2737
  }
2732
2738
  }
@@ -2775,9 +2781,6 @@ var AgentRegistry = class {
2775
2781
  if (!this.filePersistence) {
2776
2782
  throw new Error("File persistence not configured");
2777
2783
  }
2778
- if (!agent.id) {
2779
- throw new Error("Cannot save agent without ID");
2780
- }
2781
2784
  if (this.defaultAgentIds.has(agent.id)) {
2782
2785
  throw new Error(`Cannot save default agent "${agent.id}" to file`);
2783
2786
  }
@@ -2999,8 +3002,8 @@ var AgentManager = class {
2999
3002
  this.llmFactory = llmFactory;
3000
3003
  this.eventCallback = eventCallback;
3001
3004
  this.configResolver = configResolver;
3002
- if (llmFactory) {
3003
- this.llmResolver = new LLMResolver(llmFactory);
3005
+ if (this.llmFactory) {
3006
+ this.llmResolver = new LLMResolver(this.llmFactory);
3004
3007
  }
3005
3008
  }
3006
3009
  llmResolver = null;
@@ -3178,7 +3181,9 @@ var AgentManager = class {
3178
3181
  */
3179
3182
  resolveLLM(config) {
3180
3183
  if (!this.llmResolver) {
3181
- throw new Error("AgentManager requires LLMFactory to create sub-agents. Please provide llmFactory in constructor.");
3184
+ throw new Error(
3185
+ "AgentManager requires LLMFactory to create sub-agents. Please provide llmFactory in constructor."
3186
+ );
3182
3187
  }
3183
3188
  return this.llmResolver.resolve(config);
3184
3189
  }
@@ -3411,9 +3416,7 @@ var ToolRegistry = class {
3411
3416
  const delegationService = factory.create({
3412
3417
  agentRegistry: this.agentRegistry,
3413
3418
  commandRunner,
3414
- agentListProvider: () => this.agentRegistry.list().filter(
3415
- (agent) => typeof agent.id === "string" && typeof agent.name === "string" && typeof agent.description === "string"
3416
- ).map((agent) => ({
3419
+ agentListProvider: () => this.agentRegistry.list().map((agent) => ({
3417
3420
  id: agent.id,
3418
3421
  name: agent.name,
3419
3422
  description: agent.description
@@ -3685,9 +3688,7 @@ var AgentFilePersistence = class {
3685
3688
  fs8.unlinkSync(filePath);
3686
3689
  }
3687
3690
  } catch (error) {
3688
- throw new Error(
3689
- `Failed to delete agent ${agentId}: ${error instanceof Error ? error.message : String(error)}`
3690
- );
3691
+ throw new Error(`Failed to delete agent ${agentId}: ${error instanceof Error ? error.message : String(error)}`);
3691
3692
  }
3692
3693
  }
3693
3694
  /**
@@ -3927,7 +3928,7 @@ var BaseLLM = class {
3927
3928
  }
3928
3929
  for (const ch of choices) {
3929
3930
  const delta = ch.delta ?? ch.message ?? {};
3930
- const textDelta = delta.content || delta.reasoning;
3931
+ const textDelta = delta.content ?? void 0;
3931
3932
  if (typeof textDelta === "string" && textDelta.length > 0) {
3932
3933
  if (content === "") {
3933
3934
  const trimmedDelta = textDelta.replace(/^\n+/, "");
@@ -4393,7 +4394,7 @@ var GithubAuthTransport = class {
4393
4394
  if (!Array.isArray(messages.messages)) return false;
4394
4395
  return messages.messages.some((msg) => isVisionMessage(msg));
4395
4396
  }
4396
- makeAuthHeaders(url, headers, body) {
4397
+ makeAuthHeaders(headers, body) {
4397
4398
  const base = headers ? { ...headers } : {};
4398
4399
  if (this.apiKey) base.Authorization = `Bearer ${this.apiKey}`;
4399
4400
  base["editor-version"] = base["editor-version"] || "vscode/1.104.2";
@@ -4431,11 +4432,11 @@ var GithubAuthTransport = class {
4431
4432
  await this.exchangeToken(signal);
4432
4433
  }
4433
4434
  const fullUrl = this.buildFullUrl(url);
4434
- let res = await this.inner.get(fullUrl, this.makeAuthHeaders(fullUrl, headers), signal);
4435
+ let res = await this.inner.get(fullUrl, this.makeAuthHeaders(headers), signal);
4435
4436
  if (res.status === 401 && this.accessToken) {
4436
4437
  await this.exchangeToken(signal);
4437
4438
  const retryUrl = this.buildFullUrl(url);
4438
- res = await this.inner.get(retryUrl, this.makeAuthHeaders(retryUrl, headers), signal);
4439
+ res = await this.inner.get(retryUrl, this.makeAuthHeaders(headers), signal);
4439
4440
  }
4440
4441
  return res;
4441
4442
  }
@@ -4444,11 +4445,11 @@ var GithubAuthTransport = class {
4444
4445
  await this.exchangeToken(signal);
4445
4446
  }
4446
4447
  const fullUrl = this.buildFullUrl(url);
4447
- let res = await this.inner.postJson(fullUrl, body, this.makeAuthHeaders(fullUrl, headers, body), signal);
4448
+ let res = await this.inner.postJson(fullUrl, body, this.makeAuthHeaders(headers, body), signal);
4448
4449
  if (res.status === 401 && this.accessToken) {
4449
4450
  await this.exchangeToken(signal);
4450
4451
  const retryUrl = this.buildFullUrl(url);
4451
- res = await this.inner.postJson(retryUrl, body, this.makeAuthHeaders(retryUrl, headers, body), signal);
4452
+ res = await this.inner.postJson(retryUrl, body, this.makeAuthHeaders(headers, body), signal);
4452
4453
  }
4453
4454
  return res;
4454
4455
  }
@@ -4457,12 +4458,12 @@ var GithubAuthTransport = class {
4457
4458
  await this.exchangeToken(signal);
4458
4459
  }
4459
4460
  const fullUrl = this.buildFullUrl(url);
4460
- const hdrs = this.makeAuthHeaders(fullUrl, { Accept: "text/event-stream", ...headers || {} }, body);
4461
+ const hdrs = this.makeAuthHeaders({ Accept: "text/event-stream", ...headers || {} }, body);
4461
4462
  let res = await this.inner.postStream(fullUrl, body, hdrs, signal);
4462
4463
  if (res.status === 401 && this.accessToken) {
4463
4464
  await this.exchangeToken(signal);
4464
4465
  const retryUrl = this.buildFullUrl(url);
4465
- res = await this.inner.postStream(retryUrl, body, this.makeAuthHeaders(retryUrl, hdrs, body), signal);
4466
+ res = await this.inner.postStream(retryUrl, body, this.makeAuthHeaders(hdrs, body), signal);
4466
4467
  }
4467
4468
  return res;
4468
4469
  }
@@ -4601,9 +4602,11 @@ var AnthropicAISDKLLM = class {
4601
4602
  }
4602
4603
  updateCredentials(result) {
4603
4604
  if (result.type === "success" && result.access && result.refresh && result.expires) {
4604
- this.opts.oauth.access = result.access;
4605
- this.opts.oauth.refresh = result.refresh;
4606
- this.opts.oauth.expires = result.expires;
4605
+ if (this.opts.oauth) {
4606
+ this.opts.oauth.access = result.access;
4607
+ this.opts.oauth.refresh = result.refresh;
4608
+ this.opts.oauth.expires = result.expires;
4609
+ }
4607
4610
  this.opts.onTokenUpdate?.({
4608
4611
  access: result.access,
4609
4612
  refresh: result.refresh,
@@ -5405,7 +5408,7 @@ function normalizeMCPConfig(raw) {
5405
5408
  return { mcpServers: servers };
5406
5409
  }
5407
5410
  }
5408
- if (asRecord.config && typeof asRecord.config === "object") {
5411
+ if ("config" in asRecord && asRecord.config && typeof asRecord.config === "object") {
5409
5412
  const nested = asRecord.config;
5410
5413
  if (isValidConfig(nested)) {
5411
5414
  const servers = nested.mcpServers;
@@ -5434,23 +5437,26 @@ function isValidConfig(value) {
5434
5437
 
5435
5438
  // events.ts
5436
5439
  var PersistingConsoleEventPort = class {
5437
- // private console = new ConsoleEventPort();
5438
5440
  memory;
5439
5441
  maxPerConversation;
5442
+ writeQueue = Promise.resolve();
5440
5443
  constructor(opts) {
5441
5444
  this.memory = opts?.memory ?? new PersistedMemory(new JsonFileMemoryPersistence(opts?.filename || "events.json"));
5442
5445
  this.maxPerConversation = opts?.maxPerConversation ?? 500;
5443
5446
  }
5444
5447
  async emit(event) {
5445
- try {
5446
- const key = event?.conversationId ?? "default";
5447
- const existing = await this.memory.get(key);
5448
- const next = [...existing, { ...event }];
5449
- const max = this.maxPerConversation;
5450
- const trimmed = max > 0 && next.length > max ? next.slice(next.length - max) : next;
5451
- await this.memory.set(key, trimmed);
5452
- } catch {
5453
- }
5448
+ this.writeQueue = this.writeQueue.then(async () => {
5449
+ try {
5450
+ const key = event?.conversationId ?? "default";
5451
+ const existing = await this.memory.get(key);
5452
+ const next = [...existing, { ...event }];
5453
+ const max = this.maxPerConversation;
5454
+ const trimmed = max > 0 && next.length > max ? next.slice(next.length - max) : next;
5455
+ await this.memory.set(key, trimmed);
5456
+ } catch {
5457
+ }
5458
+ });
5459
+ return this.writeQueue;
5454
5460
  }
5455
5461
  };
5456
5462
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuvin/nuvin-core",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "main": "dist/index.js",