wave-agent-sdk 0.0.7 → 0.0.8

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 (172) hide show
  1. package/dist/agent.d.ts +32 -20
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +202 -20
  4. package/dist/constants/events.d.ts +28 -0
  5. package/dist/constants/events.d.ts.map +1 -0
  6. package/dist/constants/events.js +27 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -0
  10. package/dist/managers/aiManager.d.ts +34 -1
  11. package/dist/managers/aiManager.d.ts.map +1 -1
  12. package/dist/managers/aiManager.js +243 -128
  13. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  14. package/dist/managers/backgroundBashManager.js +7 -6
  15. package/dist/managers/hookManager.d.ts +9 -4
  16. package/dist/managers/hookManager.d.ts.map +1 -1
  17. package/dist/managers/hookManager.js +62 -30
  18. package/dist/managers/liveConfigManager.d.ts +58 -0
  19. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  20. package/dist/managers/liveConfigManager.js +160 -0
  21. package/dist/managers/messageManager.d.ts +38 -13
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +163 -30
  24. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  25. package/dist/managers/slashCommandManager.js +4 -1
  26. package/dist/managers/subagentManager.d.ts +51 -0
  27. package/dist/managers/subagentManager.d.ts.map +1 -1
  28. package/dist/managers/subagentManager.js +189 -18
  29. package/dist/services/aiService.d.ts +13 -5
  30. package/dist/services/aiService.d.ts.map +1 -1
  31. package/dist/services/aiService.js +350 -74
  32. package/dist/services/configurationWatcher.d.ts +120 -0
  33. package/dist/services/configurationWatcher.d.ts.map +1 -0
  34. package/dist/services/configurationWatcher.js +439 -0
  35. package/dist/services/fileWatcher.d.ts +69 -0
  36. package/dist/services/fileWatcher.d.ts.map +1 -0
  37. package/dist/services/fileWatcher.js +213 -0
  38. package/dist/services/hook.d.ts +91 -9
  39. package/dist/services/hook.d.ts.map +1 -1
  40. package/dist/services/hook.js +393 -43
  41. package/dist/services/jsonlHandler.d.ts +62 -0
  42. package/dist/services/jsonlHandler.d.ts.map +1 -0
  43. package/dist/services/jsonlHandler.js +257 -0
  44. package/dist/services/memory.d.ts +9 -0
  45. package/dist/services/memory.d.ts.map +1 -1
  46. package/dist/services/memory.js +81 -12
  47. package/dist/services/memoryStore.d.ts +81 -0
  48. package/dist/services/memoryStore.d.ts.map +1 -0
  49. package/dist/services/memoryStore.js +200 -0
  50. package/dist/services/session.d.ts +64 -49
  51. package/dist/services/session.d.ts.map +1 -1
  52. package/dist/services/session.js +310 -132
  53. package/dist/tools/bashTool.d.ts.map +1 -1
  54. package/dist/tools/bashTool.js +5 -4
  55. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  56. package/dist/tools/deleteFileTool.js +2 -1
  57. package/dist/tools/editTool.d.ts.map +1 -1
  58. package/dist/tools/editTool.js +3 -2
  59. package/dist/tools/multiEditTool.d.ts.map +1 -1
  60. package/dist/tools/multiEditTool.js +4 -3
  61. package/dist/tools/readTool.d.ts.map +1 -1
  62. package/dist/tools/readTool.js +2 -1
  63. package/dist/tools/writeTool.d.ts.map +1 -1
  64. package/dist/tools/writeTool.js +5 -6
  65. package/dist/types/commands.d.ts +4 -0
  66. package/dist/types/commands.d.ts.map +1 -1
  67. package/dist/types/core.d.ts +35 -0
  68. package/dist/types/core.d.ts.map +1 -1
  69. package/dist/types/environment.d.ts +42 -0
  70. package/dist/types/environment.d.ts.map +1 -0
  71. package/dist/types/environment.js +21 -0
  72. package/dist/types/hooks.d.ts +8 -2
  73. package/dist/types/hooks.d.ts.map +1 -1
  74. package/dist/types/hooks.js +8 -2
  75. package/dist/types/index.d.ts +2 -0
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/dist/types/index.js +2 -0
  78. package/dist/types/memoryStore.d.ts +82 -0
  79. package/dist/types/memoryStore.d.ts.map +1 -0
  80. package/dist/types/memoryStore.js +7 -0
  81. package/dist/types/messaging.d.ts +14 -2
  82. package/dist/types/messaging.d.ts.map +1 -1
  83. package/dist/types/session.d.ts +20 -0
  84. package/dist/types/session.d.ts.map +1 -0
  85. package/dist/types/session.js +7 -0
  86. package/dist/utils/bashHistory.d.ts.map +1 -1
  87. package/dist/utils/bashHistory.js +27 -26
  88. package/dist/utils/cacheControlUtils.d.ts +121 -0
  89. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  90. package/dist/utils/cacheControlUtils.js +367 -0
  91. package/dist/utils/commandPathResolver.d.ts +52 -0
  92. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  93. package/dist/utils/commandPathResolver.js +145 -0
  94. package/dist/utils/configPaths.d.ts +85 -0
  95. package/dist/utils/configPaths.d.ts.map +1 -0
  96. package/dist/utils/configPaths.js +121 -0
  97. package/dist/utils/configResolver.d.ts +37 -10
  98. package/dist/utils/configResolver.d.ts.map +1 -1
  99. package/dist/utils/configResolver.js +127 -23
  100. package/dist/utils/constants.d.ts +1 -1
  101. package/dist/utils/constants.js +1 -1
  102. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  103. package/dist/utils/convertMessagesForAPI.js +7 -5
  104. package/dist/utils/customCommands.d.ts.map +1 -1
  105. package/dist/utils/customCommands.js +66 -21
  106. package/dist/utils/fileUtils.d.ts +15 -0
  107. package/dist/utils/fileUtils.d.ts.map +1 -0
  108. package/dist/utils/fileUtils.js +61 -0
  109. package/dist/utils/globalLogger.d.ts +102 -0
  110. package/dist/utils/globalLogger.d.ts.map +1 -0
  111. package/dist/utils/globalLogger.js +136 -0
  112. package/dist/utils/mcpUtils.d.ts.map +1 -1
  113. package/dist/utils/mcpUtils.js +25 -3
  114. package/dist/utils/messageOperations.d.ts +20 -8
  115. package/dist/utils/messageOperations.d.ts.map +1 -1
  116. package/dist/utils/messageOperations.js +25 -16
  117. package/dist/utils/pathEncoder.d.ts +104 -0
  118. package/dist/utils/pathEncoder.d.ts.map +1 -0
  119. package/dist/utils/pathEncoder.js +272 -0
  120. package/dist/utils/subagentParser.d.ts.map +1 -1
  121. package/dist/utils/subagentParser.js +2 -1
  122. package/dist/utils/tokenCalculation.d.ts +26 -0
  123. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  124. package/dist/utils/tokenCalculation.js +36 -0
  125. package/package.json +6 -3
  126. package/src/agent.ts +298 -34
  127. package/src/constants/events.ts +38 -0
  128. package/src/index.ts +2 -0
  129. package/src/managers/aiManager.ts +323 -170
  130. package/src/managers/backgroundBashManager.ts +7 -6
  131. package/src/managers/hookManager.ts +83 -40
  132. package/src/managers/liveConfigManager.ts +248 -0
  133. package/src/managers/messageManager.ts +230 -63
  134. package/src/managers/slashCommandManager.ts +4 -1
  135. package/src/managers/subagentManager.ts +283 -21
  136. package/src/services/aiService.ts +474 -83
  137. package/src/services/configurationWatcher.ts +622 -0
  138. package/src/services/fileWatcher.ts +301 -0
  139. package/src/services/hook.ts +538 -47
  140. package/src/services/jsonlHandler.ts +319 -0
  141. package/src/services/memory.ts +92 -12
  142. package/src/services/memoryStore.ts +279 -0
  143. package/src/services/session.ts +381 -157
  144. package/src/tools/bashTool.ts +5 -4
  145. package/src/tools/deleteFileTool.ts +2 -1
  146. package/src/tools/editTool.ts +3 -2
  147. package/src/tools/multiEditTool.ts +4 -3
  148. package/src/tools/readTool.ts +2 -1
  149. package/src/tools/writeTool.ts +7 -6
  150. package/src/types/commands.ts +6 -0
  151. package/src/types/core.ts +44 -0
  152. package/src/types/environment.ts +60 -0
  153. package/src/types/hooks.ts +21 -8
  154. package/src/types/index.ts +2 -0
  155. package/src/types/memoryStore.ts +94 -0
  156. package/src/types/messaging.ts +14 -2
  157. package/src/types/session.ts +25 -0
  158. package/src/utils/bashHistory.ts +27 -27
  159. package/src/utils/cacheControlUtils.ts +540 -0
  160. package/src/utils/commandPathResolver.ts +189 -0
  161. package/src/utils/configPaths.ts +163 -0
  162. package/src/utils/configResolver.ts +182 -22
  163. package/src/utils/constants.ts +1 -1
  164. package/src/utils/convertMessagesForAPI.ts +7 -5
  165. package/src/utils/customCommands.ts +90 -22
  166. package/src/utils/fileUtils.ts +65 -0
  167. package/src/utils/globalLogger.ts +145 -0
  168. package/src/utils/mcpUtils.ts +34 -3
  169. package/src/utils/messageOperations.ts +42 -20
  170. package/src/utils/pathEncoder.ts +379 -0
  171. package/src/utils/subagentParser.ts +2 -1
  172. package/src/utils/tokenCalculation.ts +43 -0
package/src/agent.ts CHANGED
@@ -4,7 +4,10 @@ import {
4
4
  } from "./managers/messageManager.js";
5
5
  import { AIManager } from "./managers/aiManager.js";
6
6
  import { ToolManager } from "./managers/toolManager.js";
7
- import { SubagentManager } from "./managers/subagentManager.js";
7
+ import {
8
+ SubagentManager,
9
+ type SubagentManagerCallbacks,
10
+ } from "./managers/subagentManager.js";
8
11
  import * as memory from "./services/memory.js";
9
12
  import { McpManager, type McpManagerCallbacks } from "./managers/mcpManager.js";
10
13
  import { BashManager } from "./managers/bashManager.js";
@@ -23,9 +26,15 @@ import type {
23
26
  Usage,
24
27
  } from "./types/index.js";
25
28
  import { HookManager } from "./managers/hookManager.js";
29
+ import { MemoryStoreService } from "./services/memoryStore.js";
30
+ import { initializeMemoryStore } from "./services/memory.js";
31
+ import { LiveConfigManager } from "./managers/liveConfigManager.js";
26
32
  import { configResolver } from "./utils/configResolver.js";
27
33
  import { configValidator } from "./utils/configValidator.js";
28
34
  import { SkillManager } from "./managers/skillManager.js";
35
+ import { loadSessionFromJsonl } from "./services/session.js";
36
+ import type { SubagentConfiguration } from "./utils/subagentParser.js";
37
+ import { setGlobalLogger } from "./utils/globalLogger.js";
29
38
 
30
39
  /**
31
40
  * Configuration options for Agent instances
@@ -52,20 +61,13 @@ export interface AgentOptions {
52
61
  workdir?: string;
53
62
  /**Optional custom system prompt - if provided, replaces default system prompt */
54
63
  systemPrompt?: string;
55
-
56
- // New: Session directory configuration
57
- /**
58
- * Optional custom directory for session file storage
59
- * @default join(homedir(), ".wave", "sessions")
60
- * @example "/path/to/custom/sessions"
61
- */
62
- sessionDir?: string;
63
64
  }
64
65
 
65
66
  export interface AgentCallbacks
66
67
  extends MessageManagerCallbacks,
67
68
  BackgroundBashManagerCallbacks,
68
- McpManagerCallbacks {}
69
+ McpManagerCallbacks,
70
+ SubagentManagerCallbacks {}
69
71
 
70
72
  export class Agent {
71
73
  private messageManager: MessageManager;
@@ -79,6 +81,8 @@ export class Agent {
79
81
  private subagentManager: SubagentManager; // Add subagent manager instance
80
82
  private slashCommandManager: SlashCommandManager; // Add slash command manager instance
81
83
  private hookManager: HookManager; // Add hooks manager instance
84
+ private memoryStore: MemoryStoreService; // Add memory store service
85
+ private liveConfigManager: LiveConfigManager; // Add live configuration manager
82
86
  private workdir: string; // Working directory
83
87
  private systemPrompt?: string; // Custom system prompt
84
88
  private _usages: Usage[] = []; // Usage tracking array
@@ -88,6 +92,13 @@ export class Agent {
88
92
  private modelConfig: ModelConfig;
89
93
  private tokenLimit: number;
90
94
 
95
+ // Original constructor values for preserving overrides during live updates
96
+ private readonly constructorApiKey?: string;
97
+ private readonly constructorBaseURL?: string;
98
+ private readonly constructorAgentModel?: string;
99
+ private readonly constructorFastModel?: string;
100
+ private readonly constructorTokenLimit?: number;
101
+
91
102
  /**
92
103
  * Agent constructor - handles configuration resolution and validation
93
104
  *
@@ -96,27 +107,35 @@ export class Agent {
96
107
  * Agent.create() to maintain API consistency.
97
108
  *
98
109
  * @param options - Configuration options for the Agent instance
99
- * @param options.sessionDir - Optional custom directory for session storage
100
110
  */
101
111
  private constructor(options: AgentOptions) {
102
- const {
103
- callbacks = {},
104
- logger,
105
- workdir,
106
- systemPrompt,
107
- sessionDir,
108
- } = options;
109
-
110
- // Resolve configuration from constructor args and environment variables
112
+ const { callbacks = {}, logger, workdir, systemPrompt } = options;
113
+
114
+ // Set working directory first so it can be used for configuration resolution
115
+ this.workdir = workdir || process.cwd();
116
+
117
+ // Store original constructor values for live config updates
118
+ this.constructorApiKey = options.apiKey;
119
+ this.constructorBaseURL = options.baseURL;
120
+ this.constructorAgentModel = options.agentModel;
121
+ this.constructorFastModel = options.fastModel;
122
+ this.constructorTokenLimit = options.tokenLimit;
123
+
124
+ // Resolve configuration from constructor args and environment variables with live config support
111
125
  const gatewayConfig = configResolver.resolveGatewayConfig(
112
126
  options.apiKey,
113
127
  options.baseURL,
128
+ this.workdir,
114
129
  );
115
130
  const modelConfig = configResolver.resolveModelConfig(
116
131
  options.agentModel,
117
132
  options.fastModel,
133
+ this.workdir,
134
+ );
135
+ const tokenLimit = configResolver.resolveTokenLimit(
136
+ options.tokenLimit,
137
+ this.workdir,
118
138
  );
119
- const tokenLimit = configResolver.resolveTokenLimit(options.tokenLimit);
120
139
 
121
140
  // Validate resolved configuration
122
141
  configValidator.validateGatewayConfig(gatewayConfig);
@@ -127,9 +146,11 @@ export class Agent {
127
146
  );
128
147
 
129
148
  this.logger = logger; // Save the passed logger
130
- this.workdir = workdir || process.cwd(); // Set working directory, default to current working directory
131
149
  this.systemPrompt = systemPrompt; // Save custom system prompt
132
150
 
151
+ // Set global logger for SDK-wide access
152
+ setGlobalLogger(logger || null);
153
+
133
154
  // Store resolved configuration
134
155
  this.gatewayConfig = gatewayConfig;
135
156
  this.modelConfig = modelConfig;
@@ -145,14 +166,59 @@ export class Agent {
145
166
  logger: this.logger,
146
167
  }); // Initialize tool registry, pass MCP manager
147
168
 
169
+ this.memoryStore = new MemoryStoreService(this.logger); // Initialize memory store service
170
+ initializeMemoryStore(this.memoryStore); // Initialize global memory store reference
148
171
  this.hookManager = new HookManager(this.workdir, undefined, this.logger); // Initialize hooks manager
172
+ this.liveConfigManager = new LiveConfigManager({
173
+ workdir: this.workdir,
174
+ logger: this.logger,
175
+ onConfigurationChanged: () => {
176
+ // Update Agent configuration (AIManager, SubagentManager)
177
+ this.updateConfiguration();
178
+
179
+ // Reload hook configuration
180
+ try {
181
+ this.hookManager.loadConfigurationFromSettings();
182
+ this.logger?.info(
183
+ "Live Config: Hook configuration reloaded successfully",
184
+ );
185
+ } catch (error) {
186
+ this.logger?.error(
187
+ `Live Config: Failed to reload hook configuration: ${(error as Error).message}`,
188
+ );
189
+ }
190
+ },
191
+ onMemoryStoreFileChanged: async (
192
+ filePath: string,
193
+ changeType: "add" | "change" | "unlink",
194
+ ) => {
195
+ try {
196
+ if (changeType === "unlink") {
197
+ // Handle file deletion gracefully
198
+ this.memoryStore.removeContent(filePath);
199
+ this.logger?.info(
200
+ "Live Config: Removed AGENTS.md from memory store due to file deletion",
201
+ );
202
+ } else {
203
+ // Update memory store content for add/change
204
+ await this.memoryStore.updateContent(filePath);
205
+ this.logger?.info(
206
+ "Live Config: Updated AGENTS.md content in memory store",
207
+ );
208
+ }
209
+ } catch (error) {
210
+ this.logger?.error(
211
+ `Live Config: Failed to update memory store: ${(error as Error).message}`,
212
+ );
213
+ }
214
+ },
215
+ }); // Initialize live configuration manager
149
216
 
150
217
  // Initialize MessageManager
151
218
  this.messageManager = new MessageManager({
152
219
  callbacks,
153
220
  workdir: this.workdir,
154
221
  logger: this.logger,
155
- sessionDir,
156
222
  });
157
223
 
158
224
  // Initialize subagent manager with all dependencies in constructor
@@ -161,10 +227,20 @@ export class Agent {
161
227
  workdir: this.workdir,
162
228
  parentToolManager: this.toolManager,
163
229
  parentMessageManager: this.messageManager,
230
+ callbacks: {
231
+ onSubagentUserMessageAdded: callbacks.onSubagentUserMessageAdded,
232
+ onSubagentAssistantMessageAdded:
233
+ callbacks.onSubagentAssistantMessageAdded,
234
+ onSubagentAssistantContentUpdated:
235
+ callbacks.onSubagentAssistantContentUpdated,
236
+ onSubagentToolBlockUpdated: callbacks.onSubagentToolBlockUpdated,
237
+ onSubagentMessagesChange: callbacks.onSubagentMessagesChange,
238
+ }, // Pass subagent callbacks for forwarding
164
239
  logger: this.logger,
165
240
  gatewayConfig,
166
241
  modelConfig,
167
242
  tokenLimit,
243
+ hookManager: this.hookManager,
168
244
  onUsageAdded: (usage) => this.addUsage(usage),
169
245
  });
170
246
 
@@ -257,6 +333,11 @@ export class Agent {
257
333
  return this.workdir;
258
334
  }
259
335
 
336
+ /** Get merged environment variables from Wave configuration */
337
+ public get environmentVars(): Record<string, string> | undefined {
338
+ return this.hookManager.getEnvironmentVars();
339
+ }
340
+
260
341
  /** Get AI loading status */
261
342
  public get isLoading(): boolean {
262
343
  return this.aiManager.isLoading;
@@ -303,9 +384,6 @@ export class Agent {
303
384
  * @param options - Configuration options for the Agent instance
304
385
  * @param options.apiKey - API key for the AI service (or set WAVE_API_KEY env var)
305
386
  * @param options.baseURL - Base URL for the AI service (or set WAVE_BASE_URL env var)
306
- * @param options.sessionDir - Optional custom directory for session file storage.
307
- * If not provided, defaults to ~/.wave/sessions/. Can be relative or absolute path.
308
- * Examples: "./app-sessions", "/var/myapp/sessions", "~/Documents/sessions"
309
387
  * @param options.callbacks - Optional callbacks for various Agent events
310
388
  * @param options.restoreSessionId - Optional session ID to restore from
311
389
  * @param options.continueLastSession - Whether to continue the last session automatically
@@ -317,18 +395,11 @@ export class Agent {
317
395
  *
318
396
  * @example
319
397
  * ```typescript
320
- * // Basic usage with default session directory
398
+ * // Basic usage
321
399
  * const agent = await Agent.create({
322
400
  * apiKey: 'your-api-key',
323
401
  * baseURL: 'https://api.example.com'
324
402
  * });
325
- *
326
- * // Custom session directory
327
- * const agent = await Agent.create({
328
- * apiKey: 'your-api-key',
329
- * baseURL: 'https://api.example.com',
330
- * sessionDir: './app-sessions'
331
- * });
332
403
  * ```
333
404
  */
334
405
  static async create(options: AgentOptions): Promise<Agent> {
@@ -386,6 +457,19 @@ export class Agent {
386
457
  // Don't throw error to prevent app startup failure
387
458
  }
388
459
 
460
+ // Initialize live configuration reload
461
+ try {
462
+ this.logger?.debug("Initializing live configuration reload...");
463
+ await this.liveConfigManager.initialize();
464
+ this.logger?.debug("Live configuration reload initialized successfully");
465
+ } catch (error) {
466
+ this.logger?.error(
467
+ "Failed to initialize live configuration reload:",
468
+ error,
469
+ );
470
+ // Don't throw error to prevent app startup failure - continue without live reload
471
+ }
472
+
389
473
  // Handle session restoration or set provided messages
390
474
  if (options?.messages) {
391
475
  // If messages are provided, use them directly (useful for testing)
@@ -400,6 +484,87 @@ export class Agent {
400
484
  );
401
485
  // Rebuild usage array from restored messages
402
486
  this.rebuildUsageFromMessages();
487
+
488
+ // After main session is restored, restore any associated subagent sessions
489
+ await this.restoreSubagentSessions();
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Restore subagent sessions associated with the current main session
495
+ * This method is called after the main session is restored to load any subagent sessions
496
+ */
497
+ private async restoreSubagentSessions(): Promise<void> {
498
+ try {
499
+ // Only attempt to restore subagent sessions if we have messages (session was restored)
500
+ if (this.messages.length === 0) {
501
+ return;
502
+ }
503
+
504
+ // Extract sessionId -> subagentId mapping from SubagentBlocks
505
+ const subagentBlockMap = new Map<
506
+ string,
507
+ { subagentId: string; configuration: SubagentConfiguration }
508
+ >(); // sessionId -> { subagentId, configuration }
509
+
510
+ for (const message of this.messages) {
511
+ if (message.role === "assistant" && message.blocks) {
512
+ for (const block of message.blocks) {
513
+ if (
514
+ block.type === "subagent" &&
515
+ block.sessionId &&
516
+ block.subagentId &&
517
+ block.configuration
518
+ ) {
519
+ subagentBlockMap.set(block.sessionId, {
520
+ subagentId: block.subagentId,
521
+ configuration: block.configuration,
522
+ });
523
+ }
524
+ }
525
+ }
526
+ }
527
+
528
+ if (subagentBlockMap.size === 0) {
529
+ return; // No subagent blocks found
530
+ }
531
+
532
+ // Load subagent sessions using sessionIds
533
+ const subagentSessions = [];
534
+ for (const [sessionId, blockData] of subagentBlockMap) {
535
+ try {
536
+ const sessionData = await loadSessionFromJsonl(
537
+ sessionId,
538
+ this.messageManager.getWorkdir(),
539
+ );
540
+ if (sessionData) {
541
+ subagentSessions.push({
542
+ sessionData,
543
+ subagentId: blockData.subagentId, // Use the subagentId from SubagentBlock
544
+ configuration: blockData.configuration, // Include configuration
545
+ });
546
+ }
547
+ } catch (error) {
548
+ this.logger?.warn(
549
+ `Failed to load subagent session ${sessionId}:`,
550
+ error,
551
+ );
552
+ }
553
+ }
554
+
555
+ if (subagentSessions.length > 0) {
556
+ this.logger?.debug(
557
+ `Found ${subagentSessions.length} subagent sessions to restore`,
558
+ );
559
+
560
+ // Restore subagent sessions through the SubagentManager
561
+ await this.subagentManager.restoreSubagentSessions(subagentSessions);
562
+
563
+ this.logger?.debug("Subagent sessions restored successfully");
564
+ }
565
+ } catch (error) {
566
+ this.logger?.warn("Failed to restore subagent sessions:", error);
567
+ // Don't throw error to prevent app startup failure
403
568
  }
404
569
  }
405
570
 
@@ -453,6 +618,22 @@ export class Agent {
453
618
  await this.mcpManager.cleanup();
454
619
  // Cleanup subagent manager
455
620
  this.subagentManager.cleanup();
621
+ // Cleanup live configuration reload
622
+ try {
623
+ await this.liveConfigManager.shutdown();
624
+ } catch (error) {
625
+ this.logger?.error(
626
+ "Error shutting down live configuration reload:",
627
+ error,
628
+ );
629
+ }
630
+ // Cleanup memory store
631
+ try {
632
+ this.memoryStore.clear();
633
+ this.logger?.debug("Memory store cleared successfully");
634
+ } catch (error) {
635
+ this.logger?.error("Error clearing memory store:", error);
636
+ }
456
637
  }
457
638
 
458
639
  public async sendMessage(
@@ -623,4 +804,87 @@ export class Agent {
623
804
  public getCustomCommands(): CustomSlashCommand[] {
624
805
  return this.slashCommandManager.getCustomCommands();
625
806
  }
807
+
808
+ // ========== Live Configuration Management ==========
809
+
810
+ /**
811
+ * Update Agent configuration from live settings.json changes
812
+ * This method refreshes all configuration-dependent components with new values
813
+ * Note: Constructor values still take precedence over live configuration
814
+ */
815
+ public updateConfiguration(): void {
816
+ try {
817
+ this.logger?.info(
818
+ "Live Config: Updating Agent configuration from live settings",
819
+ );
820
+
821
+ // Re-resolve configuration with current workdir, preserving constructor overrides
822
+ // We need to track what was explicitly provided in constructor vs. what should use live config
823
+ const newGatewayConfig = configResolver.resolveGatewayConfig(
824
+ this.constructorApiKey, // Preserve constructor override if provided
825
+ this.constructorBaseURL, // Preserve constructor override if provided
826
+ this.workdir,
827
+ );
828
+ const newModelConfig = configResolver.resolveModelConfig(
829
+ this.constructorAgentModel, // Preserve constructor override if provided
830
+ this.constructorFastModel, // Preserve constructor override if provided
831
+ this.workdir,
832
+ );
833
+ const newTokenLimit = configResolver.resolveTokenLimit(
834
+ this.constructorTokenLimit,
835
+ this.workdir,
836
+ );
837
+
838
+ // Validate new configuration
839
+ configValidator.validateGatewayConfig(newGatewayConfig);
840
+ configValidator.validateTokenLimit(newTokenLimit);
841
+ configValidator.validateModelConfig(
842
+ newModelConfig.agentModel,
843
+ newModelConfig.fastModel,
844
+ );
845
+
846
+ // Update stored configuration
847
+ this.gatewayConfig = newGatewayConfig;
848
+ this.modelConfig = newModelConfig;
849
+ this.tokenLimit = newTokenLimit;
850
+
851
+ // Update AIManager with new configuration
852
+ this.aiManager.updateConfiguration(
853
+ newGatewayConfig,
854
+ newModelConfig,
855
+ newTokenLimit,
856
+ );
857
+
858
+ // Update SubagentManager with new configuration
859
+ this.subagentManager.updateConfiguration(
860
+ newGatewayConfig,
861
+ newModelConfig,
862
+ newTokenLimit,
863
+ );
864
+
865
+ this.logger?.info(
866
+ `Live Config: Agent configuration updated successfully - model: ${newModelConfig.agentModel}, tokenLimit: ${newTokenLimit}`,
867
+ );
868
+ } catch (error) {
869
+ this.logger?.error(
870
+ `Live Config: Failed to update Agent configuration: ${(error as Error).message}`,
871
+ );
872
+ // Don't throw - continue with previous configuration
873
+ }
874
+ }
875
+
876
+ /**
877
+ * Get current Agent configuration for debugging
878
+ */
879
+ public getCurrentConfiguration(): {
880
+ gatewayConfig: GatewayConfig;
881
+ modelConfig: ModelConfig;
882
+ tokenLimit: number;
883
+ } {
884
+ return {
885
+ gatewayConfig: { ...this.gatewayConfig },
886
+ modelConfig: { ...this.modelConfig },
887
+ tokenLimit: this.tokenLimit,
888
+ };
889
+ }
626
890
  }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Event name constants to prevent typos and ensure consistency
3
+ *
4
+ * Using constants instead of magic strings prevents bugs like:
5
+ * - ConfigurationWatcher emitting 'configurationChange'
6
+ * - LiveConfigManager listening for 'configurationChanged'
7
+ *
8
+ * This pattern ensures compile-time validation of event names.
9
+ */
10
+
11
+ // Configuration Watcher Events
12
+ export const CONFIGURATION_EVENTS = {
13
+ CONFIGURATION_CHANGE: "configurationChange",
14
+ WATCHER_ERROR: "watcherError",
15
+ } as const;
16
+
17
+ // File Watcher Events
18
+ export const FILE_WATCHER_EVENTS = {
19
+ CHANGE: "change",
20
+ CREATE: "create",
21
+ DELETE: "delete",
22
+ RENAME: "rename",
23
+ } as const;
24
+
25
+ // Memory Store Events
26
+ export const MEMORY_STORE_EVENTS = {
27
+ FILE_ADDED: "fileAdded",
28
+ FILE_CHANGED: "fileChanged",
29
+ FILE_REMOVED: "fileRemoved",
30
+ } as const;
31
+
32
+ // Type exports for better TypeScript support
33
+ export type ConfigurationEventName =
34
+ (typeof CONFIGURATION_EVENTS)[keyof typeof CONFIGURATION_EVENTS];
35
+ export type FileWatcherEventName =
36
+ (typeof FILE_WATCHER_EVENTS)[keyof typeof FILE_WATCHER_EVENTS];
37
+ export type MemoryStoreEventName =
38
+ (typeof MEMORY_STORE_EVENTS)[keyof typeof MEMORY_STORE_EVENTS];
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./services/aiService.js";
3
3
  export * from "./services/memory.js";
4
4
  export * from "./services/session.js";
5
5
  export * from "./services/hook.js";
6
+ export * from "./services/jsonlHandler.js";
6
7
 
7
8
  // Export main agent
8
9
  export * from "./agent.js";
@@ -11,6 +12,7 @@ export * from "./agent.js";
11
12
  export * from "./utils/bashHistory.js";
12
13
  export * from "./utils/convertMessagesForAPI.js";
13
14
  export * from "./utils/fileFilter.js";
15
+ export * from "./utils/globalLogger.js";
14
16
  export * from "./utils/mcpUtils.js";
15
17
  export * from "./utils/messageOperations.js";
16
18
  export * from "./utils/path.js";