@lightcone-ai/daemon 0.6.1 → 0.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -81,15 +81,16 @@ export class AgentManager {
81
81
 
82
82
  if (config.mysqlAccess) {
83
83
  const mysqlServerPath = new URL('../../mcp-servers/mysql/index.js', import.meta.url).pathname;
84
+ const agentEnv = config.envVars ?? {};
84
85
  mcpServers['mysql'] = {
85
86
  command: 'node',
86
87
  args: [mysqlServerPath],
87
88
  env: {
88
- DB_HOST: process.env.DB_HOST ?? '',
89
+ DB_HOST: process.env.DB_HOST ?? '',
89
90
  DB_PORT: process.env.DB_PORT ?? '3306',
90
91
  DB_USER: process.env.DB_USER ?? '',
91
92
  DB_PASSWORD: process.env.DB_PASSWORD ?? '',
92
- DB_NAME: process.env.DB_NAME ?? '',
93
+ DB_NAME: agentEnv.MYSQL_DB ?? process.env.DB_NAME ?? '',
93
94
  },
94
95
  };
95
96
  }
@@ -145,6 +146,17 @@ export class AgentManager {
145
146
  proc.on('exit', (code) => {
146
147
  console.log(`[AgentManager] Agent ${agentId} channel=${channelId ?? 'none'} exited (code=${code})`);
147
148
  this.agents.delete(key);
149
+
150
+ // If exited immediately with an error and had a session, retry without session (session file may not exist on this machine)
151
+ if (code !== 0 && config.sessionId && !this._retried?.has(key)) {
152
+ if (!this._retried) this._retried = new Set();
153
+ this._retried.add(key);
154
+ console.log(`[AgentManager] Retrying ${agentId} channel=${channelId} without session (session may not exist locally)`);
155
+ const retryConfig = { ...config, sessionId: null };
156
+ this._startAgent({ agentId, channelId, config: retryConfig }, connection);
157
+ return;
158
+ }
159
+
148
160
  connection.send({ type: 'agent:status', agentId, channelId, status: 'inactive' });
149
161
  connection.send({ type: 'agent:activity', agentId, channelId, activity: 'offline', detail: '', entries: [] });
150
162
  });
@@ -154,6 +166,9 @@ export class AgentManager {
154
166
 
155
167
  connection.send({ type: 'agent:status', agentId, channelId, status: 'active' });
156
168
  connection.send({ type: 'agent:activity', agentId, channelId, activity: 'online', detail: '', entries: [] });
169
+
170
+ // Flush any messages that arrived while the agent was starting
171
+ this._flushPending(key, connection);
157
172
  }
158
173
 
159
174
  _stopAgent(agentId, channelId, connection) {
@@ -165,12 +180,29 @@ export class AgentManager {
165
180
  // exit handler will report status
166
181
  }
167
182
 
168
- _deliverMessage({ agentId, channelId, seq, message }, connection) {
183
+ _deliverMessage(msg, connection) {
184
+ const { agentId, channelId, seq, message } = msg;
169
185
  const key = this._key(agentId, channelId);
170
186
  connection.send({ type: 'agent:deliver:ack', agentId, channelId, seq });
171
187
 
172
- if (!this.agents.has(key)) {
173
- console.warn(`[AgentManager] Agent ${agentId} channel=${channelId} not running, dropping seq=${seq}`);
188
+ if (!this.agents.has(key) && !this.starting.has(key)) {
189
+ // Agent not running queue the message and request config to spawn it
190
+ console.log(`[AgentManager] Agent ${agentId} channel=${channelId} not running, requesting start for seq=${seq}`);
191
+ if (!this._pendingMessages) this._pendingMessages = new Map();
192
+ const pending = this._pendingMessages.get(key) ?? [];
193
+ pending.push(msg);
194
+ this._pendingMessages.set(key, pending);
195
+ connection.send({ type: 'agent:request_start', agentId, channelId });
196
+ return;
197
+ }
198
+
199
+ if (this.starting.has(key)) {
200
+ // Spawn in progress — queue the message for delivery after start
201
+ console.log(`[AgentManager] Agent ${agentId} channel=${channelId} still starting, queuing seq=${seq}`);
202
+ if (!this._pendingMessages) this._pendingMessages = new Map();
203
+ const pending = this._pendingMessages.get(key) ?? [];
204
+ pending.push(msg);
205
+ this._pendingMessages.set(key, pending);
174
206
  return;
175
207
  }
176
208
 
@@ -179,6 +211,19 @@ export class AgentManager {
179
211
  this._write(key, text);
180
212
  }
181
213
 
214
+ _flushPending(key, connection) {
215
+ if (!this._pendingMessages) return;
216
+ const pending = this._pendingMessages.get(key);
217
+ if (!pending || pending.length === 0) return;
218
+ this._pendingMessages.delete(key);
219
+ for (const msg of pending) {
220
+ const { agentId, channelId, seq, message } = msg;
221
+ const text = `New message in ${message.channel_type === 'dm' ? `dm from` : `#${message.channel_name} from`} ${message.sender_name}: ${message.content}`;
222
+ console.log(`[AgentManager] Flushing queued seq=${seq} to agent ${agentId} channel=${channelId}`);
223
+ this._write(key, text);
224
+ }
225
+ }
226
+
182
227
  // Write a user message to the running Claude process via stdin
183
228
  _write(key, text) {
184
229
  const agent = this.agents.get(key);