clawlet 0.5.0 → 0.5.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/agent.ts +70 -70
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawlet",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "A lightweight AI based personal assistant.",
5
5
  "main": "src/cli.ts",
6
6
  "type": "module",
package/src/agent.ts CHANGED
@@ -289,86 +289,86 @@ export class Agent {
289
289
  if (!this.initialized) await this.init();
290
290
  this.processing = true;
291
291
 
292
- const queuedItem = await this.memory.queue.pop("main-session");
293
- if (!queuedItem) {
294
- this.processing = false;
295
- return;
296
- }
297
- const { text, label } = queuedItem;
292
+ while (true) {
293
+ const queuedItem = await this.memory.queue.pop("main-session");
294
+ if (!queuedItem) {
295
+ this.processing = false;
296
+ return;
297
+ }
298
+ const { text, label } = queuedItem;
298
299
 
299
- for (const out of this.outputAdapters) {
300
- out.onAgentStart(label);
301
- }
300
+ for (const out of this.outputAdapters) {
301
+ out.onAgentStart(label);
302
+ }
303
+
304
+ this.messages = await this.memory.compactHistory("main-session", this.model);
302
305
 
303
- this.messages = await this.memory.compactHistory("main-session", this.model);
304
-
305
- // Bootstrap: if bootstrapPrompt is set, run it instead of normal chat
306
- // until the required files (SOUL.md, IDENTITY.md, USER.md) are created
307
- const isFirstMessage = this.messages.length === 0;
308
- let input: string;
309
- if (this.bootstrapPrompt && isFirstMessage) {
310
- input = `[BOOTSTRAP MODE] The workspace is not yet set up.\n\n` +
311
- `${this.bootstrapPrompt}\n\n` +
312
- `Use fs.writeFile to create each file in the workspace when the user provides the information.\n\n` +
313
- `--- USER MESSAGE ---\n${text}`;
314
- } else if (this.bootstrapPrompt) {
315
- // Still in bootstrap mode (subsequent messages) — check if bootstrap is complete
316
- const workspaceDir = path.join(process.cwd(), 'workspace');
317
- const requiredFiles = ['SOUL.md', 'IDENTITY.md', 'USER.md'];
318
- let allExist = true;
319
- for (const file of requiredFiles) {
320
- try {
321
- await access(path.join(workspaceDir, file));
322
- } catch {
323
- allExist = false;
324
- break;
306
+ // Bootstrap: if bootstrapPrompt is set, run it instead of normal chat
307
+ // until the required files (SOUL.md, IDENTITY.md, USER.md) are created
308
+ const isFirstMessage = this.messages.length === 0;
309
+ let input: string;
310
+ if (this.bootstrapPrompt && isFirstMessage) {
311
+ input = `[BOOTSTRAP MODE] The workspace is not yet set up.\n\n` +
312
+ `${this.bootstrapPrompt}\n\n` +
313
+ `Use fs.writeFile to create each file in the workspace when the user provides the information.\n\n` +
314
+ `--- USER MESSAGE ---\n${text}`;
315
+ } else if (this.bootstrapPrompt) {
316
+ // Still in bootstrap mode (subsequent messages) — check if bootstrap is complete
317
+ const workspaceDir = path.join(process.cwd(), 'workspace');
318
+ const requiredFiles = ['SOUL.md', 'IDENTITY.md', 'USER.md'];
319
+ let allExist = true;
320
+ for (const file of requiredFiles) {
321
+ try {
322
+ await access(path.join(workspaceDir, file));
323
+ } catch {
324
+ allExist = false;
325
+ break;
326
+ }
325
327
  }
328
+ if (allExist) {
329
+ this.bootstrapPrompt = null;
330
+ console.log(` ✅ Bootstrap complete! SOUL.md, IDENTITY.md, and USER.md are now present.`);
331
+ }
332
+ input = text;
333
+ } else if (isFirstMessage) {
334
+ input = `[SYSTEM BOOT] This is a fresh session. Before responding to the user, you MUST execute the "Every Session" protocol from AGENTS.md NOW using your tools:\n` +
335
+ `1. Call fs.readFile for SOUL.md\n` +
336
+ `2. Call fs.readFile for USER.md\n` +
337
+ `3. Call fs.readFile for memory:${getTodayString()}.md (create it with fs.writeFile if it doesn't exist)\n` +
338
+ `4. Call fs.readFile for MEMORY.md\n` +
339
+ `Execute ALL of these tool calls first, then respond to the user's message below.\n\n` +
340
+ `--- USER MESSAGE ---\n${text}`;
341
+ } else {
342
+ input = text;
326
343
  }
327
- if (allExist) {
328
- this.bootstrapPrompt = null;
329
- console.log(` ✅ Bootstrap complete! SOUL.md, IDENTITY.md, and USER.md are now present.`);
330
- }
331
- input = text;
332
- } else if (isFirstMessage) {
333
- input = `[SYSTEM BOOT] This is a fresh session. Before responding to the user, you MUST execute the "Every Session" protocol from AGENTS.md NOW using your tools:\n` +
334
- `1. Call fs.readFile for SOUL.md\n` +
335
- `2. Call fs.readFile for USER.md\n` +
336
- `3. Call fs.readFile for memory:${getTodayString()}.md (create it with fs.writeFile if it doesn't exist)\n` +
337
- `4. Call fs.readFile for MEMORY.md\n` +
338
- `Execute ALL of these tool calls first, then respond to the user's message below.\n\n` +
339
- `--- USER MESSAGE ---\n${text}`;
340
- } else {
341
- input = text;
342
- }
343
344
 
344
- let fullResponse = "";
345
- try {
346
- const newMessages = await runAgent(input, this.memory, this.model, this.messages, this.tools, (chunk) => {
347
- fullResponse += chunk;
348
- for (const out of this.outputAdapters) {
349
- out.onResponseChunk(chunk);
345
+ let fullResponse = "";
346
+ try {
347
+ const newMessages = await runAgent(input, this.memory, this.model, this.messages, this.tools, (chunk) => {
348
+ fullResponse += chunk;
349
+ for (const out of this.outputAdapters) {
350
+ out.onResponseChunk(chunk);
351
+ }
352
+ });
353
+
354
+ for (const msg of newMessages) {
355
+ if (typeof msg.content !== "string") {
356
+ msg.content = msg.content.filter((part) => part.type !== 'reasoning');
357
+ }
358
+ await this.memory.history.push("main-session", msg);
350
359
  }
351
- });
352
360
 
353
- for (const msg of newMessages) {
354
- if (typeof msg.content !== "string") {
355
- msg.content = msg.content.filter((part) => part.type !== 'reasoning');
361
+ for (const out of this.outputAdapters) {
362
+ out.onResponseEnd(fullResponse);
356
363
  }
357
- await this.memory.history.push("main-session", msg);
358
- }
359
-
360
- for (const out of this.outputAdapters) {
361
- out.onResponseEnd(fullResponse);
362
- }
363
364
 
364
- // Compact history if it's grown past the threshold
365
- this.messages = await this.memory.compactHistory("main-session", this.model);
366
- } catch (error: any) {
367
- for (const out of this.outputAdapters) {
368
- out.onError(error);
365
+ // Compact history if it's grown past the threshold
366
+ this.messages = await this.memory.compactHistory("main-session", this.model);
367
+ } catch (error: any) {
368
+ for (const out of this.outputAdapters) {
369
+ out.onError(error);
370
+ }
369
371
  }
370
372
  }
371
-
372
- this.processing = false;
373
373
  }
374
374
  }