@hasna/assistants 1.1.16 → 1.1.18

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
@@ -74513,24 +74513,28 @@ Configure the external source with the URL and secret above.
74513
74513
  `);
74514
74514
  context.emit("done");
74515
74515
  if (activePerson && result.success) {
74516
+ const agentPool = context.getChannelAgentPool?.();
74517
+ const members = manager.getMembers(channel);
74518
+ const currentAssistantId = context.getAssistantManager?.()?.getActive?.()?.id;
74519
+ if (agentPool && members.length > 0) {
74520
+ agentPool.triggerResponses(channel, activePerson.name, message, members, currentAssistantId || undefined);
74521
+ }
74516
74522
  const mentions = parseMentions(message);
74517
- let mentionContext = "";
74518
74523
  if (mentions.length > 0) {
74519
- const assistantManager = context.getAssistantManager?.();
74520
- if (assistantManager) {
74521
- const assistants = assistantManager.listAssistants?.() || [];
74522
- const knownNames = assistants.map((a) => ({ id: a.id, name: a.name }));
74523
- const resolved = mentions.map((m) => resolveNameToKnown(m, knownNames)).filter(Boolean);
74524
- if (resolved.length > 0) {
74525
- mentionContext = `
74526
-
74527
- Note: ${activePerson.name} mentioned ${resolved.map((r) => r.name).join(", ")}. Respond as the mentioned assistant.`;
74524
+ const assistantMembers = members.filter((m) => m.memberType === "assistant");
74525
+ const knownNames = assistantMembers.map((m) => ({ id: m.assistantId, name: m.assistantName }));
74526
+ const resolved = mentions.map((m) => resolveNameToKnown(m, knownNames)).filter(Boolean);
74527
+ if (resolved.length > 0) {
74528
+ if (!resolved.some((r) => r.id === currentAssistantId)) {
74529
+ return { handled: true };
74528
74530
  }
74531
+ } else {
74532
+ return { handled: true };
74529
74533
  }
74530
74534
  }
74531
74535
  return {
74532
74536
  handled: false,
74533
- prompt: `[Channel Message] ${activePerson.name} posted in #${channel}: "${message}"${mentionContext}
74537
+ prompt: `[Channel Message] ${activePerson.name} posted in #${channel}: "${message}"
74534
74538
 
74535
74539
  Respond in #${channel} using channel_send. Be helpful and conversational.`
74536
74540
  };
@@ -79387,7 +79391,7 @@ ${repoUrl}/issues/new
79387
79391
  context.setProjectContext(projectContext);
79388
79392
  }
79389
79393
  }
79390
- var VERSION = "1.1.16";
79394
+ var VERSION = "1.1.18";
79391
79395
  var init_builtin = __esm(async () => {
79392
79396
  init_src2();
79393
79397
  init_store();
@@ -172760,7 +172764,7 @@ class ChannelStore {
172760
172764
  params.push(options.status);
172761
172765
  }
172762
172766
  }
172763
- query += " ORDER BY last_message_at DESC NULLS LAST, c.created_at DESC";
172767
+ query += " ORDER BY (last_message_at IS NULL) ASC, last_message_at DESC, c.created_at DESC";
172764
172768
  const stmt = this.db.prepare(query);
172765
172769
  const rows = stmt.all(...params);
172766
172770
  return rows.map((row) => ({
@@ -173166,6 +173170,498 @@ var init_manager6 = __esm(async () => {
173166
173170
  await init_store7();
173167
173171
  });
173168
173172
 
173173
+ // packages/core/src/client.ts
173174
+ class EmbeddedClient {
173175
+ assistantLoop;
173176
+ chunkCallbacks = [];
173177
+ errorCallbacks = [];
173178
+ initialized = false;
173179
+ logger;
173180
+ session;
173181
+ messages = [];
173182
+ messageIds = new Set;
173183
+ cwd;
173184
+ startedAt;
173185
+ initialMessages = null;
173186
+ assistantId = null;
173187
+ messageQueue = [];
173188
+ processingQueue = false;
173189
+ sawErrorChunk = false;
173190
+ constructor(cwd, options) {
173191
+ initAssistantsDir();
173192
+ const sessionId = options?.sessionId || generateId();
173193
+ this.logger = new Logger(sessionId);
173194
+ this.session = new SessionStorage(sessionId);
173195
+ this.cwd = cwd || process.cwd();
173196
+ this.startedAt = options?.startedAt || new Date().toISOString();
173197
+ this.initialMessages = options?.initialMessages || null;
173198
+ this.logger.info("Session started", { cwd: this.cwd });
173199
+ const createAssistant = options?.assistantFactory ?? ((opts) => new AssistantLoop(opts));
173200
+ this.assistantLoop = createAssistant({
173201
+ cwd: this.cwd,
173202
+ sessionId,
173203
+ assistantId: options?.assistantId,
173204
+ allowedTools: options?.allowedTools,
173205
+ extraSystemPrompt: options?.systemPrompt,
173206
+ model: options?.model,
173207
+ onChunk: (chunk) => {
173208
+ for (const callback of this.chunkCallbacks) {
173209
+ callback(chunk);
173210
+ }
173211
+ if (chunk.type === "error") {
173212
+ this.sawErrorChunk = true;
173213
+ }
173214
+ if (chunk.type === "done" || chunk.type === "error" || chunk.type === "stopped") {
173215
+ queueMicrotask(() => {
173216
+ this.drainQueue();
173217
+ });
173218
+ }
173219
+ },
173220
+ onToolStart: (toolCall) => {
173221
+ this.logger.info("Tool started", { tool: toolCall.name, input: toolCall.input });
173222
+ },
173223
+ onToolEnd: (toolCall, result) => {
173224
+ this.logger.info("Tool completed", {
173225
+ tool: toolCall.name,
173226
+ success: !result.isError,
173227
+ resultLength: result.content.length
173228
+ });
173229
+ }
173230
+ });
173231
+ }
173232
+ async initialize() {
173233
+ if (this.initialized)
173234
+ return;
173235
+ this.logger.info("Initializing assistant");
173236
+ await this.assistantLoop.initialize();
173237
+ if (typeof this.assistantLoop.getAssistantId === "function") {
173238
+ this.assistantId = this.assistantLoop.getAssistantId();
173239
+ if (this.assistantId) {
173240
+ this.session = new SessionStorage(this.session.getSessionId(), undefined, this.assistantId);
173241
+ }
173242
+ }
173243
+ if (this.initialMessages && this.initialMessages.length > 0) {
173244
+ const contextSeed = this.selectContextSeed(this.initialMessages);
173245
+ if (typeof this.assistantLoop.importContext === "function") {
173246
+ this.assistantLoop.importContext(contextSeed);
173247
+ } else {
173248
+ this.assistantLoop.getContext().import(contextSeed);
173249
+ }
173250
+ this.messages = [...this.initialMessages];
173251
+ this.messageIds = new Set(this.initialMessages.map((msg) => msg.id));
173252
+ }
173253
+ this.initialized = true;
173254
+ this.logger.info("Assistant initialized", {
173255
+ tools: this.assistantLoop.getTools().length,
173256
+ skills: this.assistantLoop.getSkills().length
173257
+ });
173258
+ }
173259
+ async send(message) {
173260
+ if (!this.initialized) {
173261
+ await this.initialize();
173262
+ }
173263
+ if (!message.trim()) {
173264
+ return;
173265
+ }
173266
+ this.messageQueue.push(message);
173267
+ if (this.assistantLoop.isProcessing() || this.processingQueue) {
173268
+ this.logger.info("Queuing message (assistant busy)", { message, queueLength: this.messageQueue.length });
173269
+ return;
173270
+ }
173271
+ await this.drainQueue();
173272
+ }
173273
+ async processMessage(message) {
173274
+ this.logger.info("User message", { message });
173275
+ this.sawErrorChunk = false;
173276
+ try {
173277
+ await this.assistantLoop.process(message);
173278
+ const context = this.assistantLoop.getContext();
173279
+ const contextMessages = context.getMessages();
173280
+ if (contextMessages.length > 0) {
173281
+ this.mergeMessages(contextMessages);
173282
+ const lastMessage = contextMessages.slice(-1)[0];
173283
+ if (lastMessage?.role === "assistant") {
173284
+ this.logger.info("Assistant response", {
173285
+ length: lastMessage.content.length,
173286
+ hasToolCalls: !!lastMessage.toolCalls?.length
173287
+ });
173288
+ }
173289
+ }
173290
+ this.saveSession();
173291
+ } catch (error3) {
173292
+ if (this.sawErrorChunk) {
173293
+ return;
173294
+ }
173295
+ const err = error3 instanceof Error ? error3 : new Error(String(error3));
173296
+ this.logger.error("Error processing message", { error: err.message });
173297
+ for (const callback of this.errorCallbacks) {
173298
+ callback(err);
173299
+ }
173300
+ }
173301
+ }
173302
+ async drainQueue() {
173303
+ if (this.processingQueue)
173304
+ return;
173305
+ this.processingQueue = true;
173306
+ try {
173307
+ while (this.messageQueue.length > 0 && !this.assistantLoop.isProcessing()) {
173308
+ const nextMessage = this.messageQueue.shift();
173309
+ if (nextMessage) {
173310
+ await this.processMessage(nextMessage);
173311
+ }
173312
+ }
173313
+ } finally {
173314
+ this.processingQueue = false;
173315
+ }
173316
+ }
173317
+ saveSession() {
173318
+ this.session.save({
173319
+ messages: this.messages,
173320
+ startedAt: this.startedAt,
173321
+ updatedAt: new Date().toISOString(),
173322
+ cwd: this.cwd
173323
+ });
173324
+ }
173325
+ onChunk(callback) {
173326
+ this.chunkCallbacks.push(callback);
173327
+ return () => {
173328
+ const index = this.chunkCallbacks.indexOf(callback);
173329
+ if (index !== -1)
173330
+ this.chunkCallbacks.splice(index, 1);
173331
+ };
173332
+ }
173333
+ onError(callback) {
173334
+ this.errorCallbacks.push(callback);
173335
+ return () => {
173336
+ const index = this.errorCallbacks.indexOf(callback);
173337
+ if (index !== -1)
173338
+ this.errorCallbacks.splice(index, 1);
173339
+ };
173340
+ }
173341
+ setAskUserHandler(handler) {
173342
+ if (typeof this.assistantLoop.setAskUserHandler === "function") {
173343
+ this.assistantLoop.setAskUserHandler(handler);
173344
+ }
173345
+ }
173346
+ async getTools() {
173347
+ if (!this.initialized) {
173348
+ await this.initialize();
173349
+ }
173350
+ return this.assistantLoop.getTools();
173351
+ }
173352
+ async getSkills() {
173353
+ if (!this.initialized) {
173354
+ await this.initialize();
173355
+ }
173356
+ return this.assistantLoop.getSkills();
173357
+ }
173358
+ async refreshSkills() {
173359
+ if (!this.initialized) {
173360
+ await this.initialize();
173361
+ }
173362
+ if (typeof this.assistantLoop.refreshSkills === "function") {
173363
+ await this.assistantLoop.refreshSkills();
173364
+ }
173365
+ return this.assistantLoop.getSkills();
173366
+ }
173367
+ getSkillLoader() {
173368
+ if (typeof this.assistantLoop.getSkillLoader === "function") {
173369
+ return this.assistantLoop.getSkillLoader();
173370
+ }
173371
+ return null;
173372
+ }
173373
+ stop() {
173374
+ this.logger.info("Processing stopped by user");
173375
+ this.assistantLoop.stop();
173376
+ }
173377
+ disconnect() {
173378
+ this.logger.info("Session ended");
173379
+ if (typeof this.assistantLoop.shutdown === "function") {
173380
+ this.assistantLoop.shutdown();
173381
+ }
173382
+ this.saveSession();
173383
+ this.chunkCallbacks.length = 0;
173384
+ this.errorCallbacks.length = 0;
173385
+ }
173386
+ isProcessing() {
173387
+ return this.assistantLoop.isProcessing();
173388
+ }
173389
+ getSessionId() {
173390
+ return this.session.getSessionId();
173391
+ }
173392
+ async getCommands() {
173393
+ if (!this.initialized) {
173394
+ await this.initialize();
173395
+ }
173396
+ return this.assistantLoop.getCommands();
173397
+ }
173398
+ getTokenUsage() {
173399
+ return this.assistantLoop.getTokenUsage();
173400
+ }
173401
+ getEnergyState() {
173402
+ if (typeof this.assistantLoop.getEnergyState === "function") {
173403
+ return this.assistantLoop.getEnergyState();
173404
+ }
173405
+ return null;
173406
+ }
173407
+ getVoiceState() {
173408
+ if (typeof this.assistantLoop.getVoiceState === "function") {
173409
+ return this.assistantLoop.getVoiceState();
173410
+ }
173411
+ return null;
173412
+ }
173413
+ getHeartbeatState() {
173414
+ if (typeof this.assistantLoop.getHeartbeatState === "function") {
173415
+ return this.assistantLoop.getHeartbeatState();
173416
+ }
173417
+ return null;
173418
+ }
173419
+ getIdentityInfo() {
173420
+ if (typeof this.assistantLoop.getIdentityInfo === "function") {
173421
+ return this.assistantLoop.getIdentityInfo();
173422
+ }
173423
+ return null;
173424
+ }
173425
+ getModel() {
173426
+ if (typeof this.assistantLoop.getModel === "function") {
173427
+ return this.assistantLoop.getModel();
173428
+ }
173429
+ return null;
173430
+ }
173431
+ getAssistantManager() {
173432
+ if (typeof this.assistantLoop.getAssistantManager === "function") {
173433
+ return this.assistantLoop.getAssistantManager();
173434
+ }
173435
+ return null;
173436
+ }
173437
+ getIdentityManager() {
173438
+ if (typeof this.assistantLoop.getIdentityManager === "function") {
173439
+ return this.assistantLoop.getIdentityManager();
173440
+ }
173441
+ return null;
173442
+ }
173443
+ getMemoryManager() {
173444
+ if (typeof this.assistantLoop.getMemoryManager === "function") {
173445
+ return this.assistantLoop.getMemoryManager();
173446
+ }
173447
+ return null;
173448
+ }
173449
+ async refreshIdentityContext() {
173450
+ if (typeof this.assistantLoop.refreshIdentityContext === "function") {
173451
+ await this.assistantLoop.refreshIdentityContext();
173452
+ }
173453
+ }
173454
+ getMessagesManager() {
173455
+ if (typeof this.assistantLoop.getMessagesManager === "function") {
173456
+ return this.assistantLoop.getMessagesManager();
173457
+ }
173458
+ return null;
173459
+ }
173460
+ getWebhooksManager() {
173461
+ if (typeof this.assistantLoop.getWebhooksManager === "function") {
173462
+ return this.assistantLoop.getWebhooksManager();
173463
+ }
173464
+ return null;
173465
+ }
173466
+ getChannelsManager() {
173467
+ if (typeof this.assistantLoop.getChannelsManager === "function") {
173468
+ return this.assistantLoop.getChannelsManager();
173469
+ }
173470
+ return null;
173471
+ }
173472
+ getChannelAgentPool() {
173473
+ if (typeof this.assistantLoop.getChannelAgentPool === "function") {
173474
+ return this.assistantLoop.getChannelAgentPool();
173475
+ }
173476
+ return null;
173477
+ }
173478
+ getPeopleManager() {
173479
+ if (typeof this.assistantLoop.getPeopleManager === "function") {
173480
+ return this.assistantLoop.getPeopleManager();
173481
+ }
173482
+ return null;
173483
+ }
173484
+ getTelephonyManager() {
173485
+ if (typeof this.assistantLoop.getTelephonyManager === "function") {
173486
+ return this.assistantLoop.getTelephonyManager();
173487
+ }
173488
+ return null;
173489
+ }
173490
+ getWalletManager() {
173491
+ if (typeof this.assistantLoop.getWalletManager === "function") {
173492
+ return this.assistantLoop.getWalletManager();
173493
+ }
173494
+ return null;
173495
+ }
173496
+ getSecretsManager() {
173497
+ if (typeof this.assistantLoop.getSecretsManager === "function") {
173498
+ return this.assistantLoop.getSecretsManager();
173499
+ }
173500
+ return null;
173501
+ }
173502
+ getInboxManager() {
173503
+ if (typeof this.assistantLoop.getInboxManager === "function") {
173504
+ return this.assistantLoop.getInboxManager();
173505
+ }
173506
+ return null;
173507
+ }
173508
+ getActiveProjectId() {
173509
+ if (typeof this.assistantLoop.getActiveProjectId === "function") {
173510
+ return this.assistantLoop.getActiveProjectId();
173511
+ }
173512
+ return null;
173513
+ }
173514
+ setActiveProjectId(projectId) {
173515
+ if (typeof this.assistantLoop.setActiveProjectId === "function") {
173516
+ this.assistantLoop.setActiveProjectId(projectId);
173517
+ }
173518
+ }
173519
+ getSwarmCoordinator() {
173520
+ if (typeof this.assistantLoop.getOrCreateSwarmCoordinator === "function") {
173521
+ return this.assistantLoop.getOrCreateSwarmCoordinator();
173522
+ }
173523
+ return null;
173524
+ }
173525
+ getAssistantLoop() {
173526
+ return this.assistantLoop;
173527
+ }
173528
+ addSystemMessage(content) {
173529
+ if (typeof this.assistantLoop.addSystemMessage === "function") {
173530
+ this.assistantLoop.addSystemMessage(content);
173531
+ } else {
173532
+ const context = this.assistantLoop.getContext();
173533
+ if (typeof context.addSystemMessage === "function") {
173534
+ context.addSystemMessage(content);
173535
+ }
173536
+ }
173537
+ }
173538
+ clearConversation() {
173539
+ this.assistantLoop.clearConversation();
173540
+ this.messages = [];
173541
+ this.messageIds.clear();
173542
+ this.logger.info("Conversation cleared");
173543
+ }
173544
+ getCwd() {
173545
+ return this.cwd;
173546
+ }
173547
+ getStartedAt() {
173548
+ return this.startedAt;
173549
+ }
173550
+ getMessages() {
173551
+ return [...this.messages];
173552
+ }
173553
+ getQueueLength() {
173554
+ return this.messageQueue.length;
173555
+ }
173556
+ clearQueue() {
173557
+ this.messageQueue = [];
173558
+ this.logger.info("Message queue cleared");
173559
+ }
173560
+ mergeMessages(contextMessages) {
173561
+ if (contextMessages.length === 0)
173562
+ return;
173563
+ if (this.messages.length === 0 && this.messageIds.size === 0) {
173564
+ this.messages = [...contextMessages];
173565
+ this.messageIds = new Set(contextMessages.map((msg) => msg.id));
173566
+ return;
173567
+ }
173568
+ for (const msg of contextMessages) {
173569
+ if (!this.messageIds.has(msg.id)) {
173570
+ this.messages.push(msg);
173571
+ this.messageIds.add(msg.id);
173572
+ }
173573
+ }
173574
+ }
173575
+ selectContextSeed(messages) {
173576
+ if (messages.length === 0)
173577
+ return [];
173578
+ const contextInfo = typeof this.assistantLoop.getContextInfo === "function" ? this.assistantLoop.getContextInfo() : null;
173579
+ const maxMessages = contextInfo?.config?.maxMessages ?? 100;
173580
+ if (messages.length <= maxMessages)
173581
+ return messages;
173582
+ let startIndex = messages.length - maxMessages;
173583
+ if (startIndex > 0 && messages[startIndex]?.toolResults && messages[startIndex - 1]) {
173584
+ startIndex -= 1;
173585
+ }
173586
+ return messages.slice(Math.max(0, startIndex));
173587
+ }
173588
+ }
173589
+ var init_client4 = __esm(async () => {
173590
+ init_src2();
173591
+ await __promiseAll([
173592
+ init_loop(),
173593
+ init_logger2()
173594
+ ]);
173595
+ });
173596
+
173597
+ // packages/core/src/channels/agent-pool.ts
173598
+ class ChannelAgentPool {
173599
+ agents = new Map;
173600
+ cwd;
173601
+ constructor(cwd) {
173602
+ this.cwd = cwd;
173603
+ }
173604
+ async triggerResponses(channelName, personName, message, channelMembers, excludeAssistantId) {
173605
+ const assistantMembers = channelMembers.filter((m5) => m5.memberType === "assistant");
173606
+ if (assistantMembers.length === 0)
173607
+ return;
173608
+ let targetMembers = assistantMembers;
173609
+ const mentions = parseMentions(message);
173610
+ if (mentions.length > 0) {
173611
+ const knownNames = assistantMembers.map((m5) => ({
173612
+ id: m5.assistantId,
173613
+ name: m5.assistantName
173614
+ }));
173615
+ const resolved = mentions.map((m5) => resolveNameToKnown(m5, knownNames)).filter(Boolean);
173616
+ if (resolved.length > 0) {
173617
+ const resolvedIds = new Set(resolved.map((r6) => r6.id));
173618
+ targetMembers = assistantMembers.filter((m5) => resolvedIds.has(m5.assistantId));
173619
+ } else {
173620
+ return;
173621
+ }
173622
+ }
173623
+ if (excludeAssistantId) {
173624
+ targetMembers = targetMembers.filter((m5) => m5.assistantId !== excludeAssistantId);
173625
+ }
173626
+ if (targetMembers.length === 0)
173627
+ return;
173628
+ const prompt = `[Channel Message] ${personName} posted in #${channelName}: "${message}"
173629
+
173630
+ Respond in #${channelName} using channel_send. Be helpful and conversational.`;
173631
+ const sends = targetMembers.map(async (member) => {
173632
+ try {
173633
+ const client = await this.getOrCreateClient(member.assistantId);
173634
+ await client.send(prompt);
173635
+ } catch (error3) {
173636
+ console.error(`ChannelAgentPool: Failed to trigger response for ${member.assistantName}:`, error3);
173637
+ }
173638
+ });
173639
+ await Promise.allSettled(sends);
173640
+ }
173641
+ async getOrCreateClient(assistantId) {
173642
+ const existing = this.agents.get(assistantId);
173643
+ if (existing)
173644
+ return existing;
173645
+ const client = new EmbeddedClient(this.cwd, {
173646
+ assistantId
173647
+ });
173648
+ await client.initialize();
173649
+ this.agents.set(assistantId, client);
173650
+ return client;
173651
+ }
173652
+ shutdown() {
173653
+ for (const [, client] of this.agents) {
173654
+ try {
173655
+ client.disconnect();
173656
+ } catch {}
173657
+ }
173658
+ this.agents.clear();
173659
+ }
173660
+ }
173661
+ var init_agent_pool = __esm(async () => {
173662
+ await init_client4();
173663
+ });
173664
+
173169
173665
  // packages/core/src/channels/tools.ts
173170
173666
  function createChannelToolExecutors(getChannelsManager) {
173171
173667
  return {
@@ -173459,6 +173955,7 @@ var init_channels = __esm(async () => {
173459
173955
  init_tools10();
173460
173956
  await __promiseAll([
173461
173957
  init_manager6(),
173958
+ init_agent_pool(),
173462
173959
  init_store7()
173463
173960
  ]);
173464
173961
  });
@@ -175529,424 +176026,6 @@ class SessionStore {
175529
176026
  }
175530
176027
  var init_store10 = () => {};
175531
176028
 
175532
- // packages/core/src/client.ts
175533
- class EmbeddedClient {
175534
- assistantLoop;
175535
- chunkCallbacks = [];
175536
- errorCallbacks = [];
175537
- initialized = false;
175538
- logger;
175539
- session;
175540
- messages = [];
175541
- messageIds = new Set;
175542
- cwd;
175543
- startedAt;
175544
- initialMessages = null;
175545
- assistantId = null;
175546
- messageQueue = [];
175547
- processingQueue = false;
175548
- sawErrorChunk = false;
175549
- constructor(cwd, options) {
175550
- initAssistantsDir();
175551
- const sessionId = options?.sessionId || generateId();
175552
- this.logger = new Logger(sessionId);
175553
- this.session = new SessionStorage(sessionId);
175554
- this.cwd = cwd || process.cwd();
175555
- this.startedAt = options?.startedAt || new Date().toISOString();
175556
- this.initialMessages = options?.initialMessages || null;
175557
- this.logger.info("Session started", { cwd: this.cwd });
175558
- const createAssistant = options?.assistantFactory ?? ((opts) => new AssistantLoop(opts));
175559
- this.assistantLoop = createAssistant({
175560
- cwd: this.cwd,
175561
- sessionId,
175562
- assistantId: options?.assistantId,
175563
- allowedTools: options?.allowedTools,
175564
- extraSystemPrompt: options?.systemPrompt,
175565
- model: options?.model,
175566
- onChunk: (chunk) => {
175567
- for (const callback of this.chunkCallbacks) {
175568
- callback(chunk);
175569
- }
175570
- if (chunk.type === "error") {
175571
- this.sawErrorChunk = true;
175572
- }
175573
- if (chunk.type === "done" || chunk.type === "error" || chunk.type === "stopped") {
175574
- queueMicrotask(() => {
175575
- this.drainQueue();
175576
- });
175577
- }
175578
- },
175579
- onToolStart: (toolCall) => {
175580
- this.logger.info("Tool started", { tool: toolCall.name, input: toolCall.input });
175581
- },
175582
- onToolEnd: (toolCall, result) => {
175583
- this.logger.info("Tool completed", {
175584
- tool: toolCall.name,
175585
- success: !result.isError,
175586
- resultLength: result.content.length
175587
- });
175588
- }
175589
- });
175590
- }
175591
- async initialize() {
175592
- if (this.initialized)
175593
- return;
175594
- this.logger.info("Initializing assistant");
175595
- await this.assistantLoop.initialize();
175596
- if (typeof this.assistantLoop.getAssistantId === "function") {
175597
- this.assistantId = this.assistantLoop.getAssistantId();
175598
- if (this.assistantId) {
175599
- this.session = new SessionStorage(this.session.getSessionId(), undefined, this.assistantId);
175600
- }
175601
- }
175602
- if (this.initialMessages && this.initialMessages.length > 0) {
175603
- const contextSeed = this.selectContextSeed(this.initialMessages);
175604
- if (typeof this.assistantLoop.importContext === "function") {
175605
- this.assistantLoop.importContext(contextSeed);
175606
- } else {
175607
- this.assistantLoop.getContext().import(contextSeed);
175608
- }
175609
- this.messages = [...this.initialMessages];
175610
- this.messageIds = new Set(this.initialMessages.map((msg) => msg.id));
175611
- }
175612
- this.initialized = true;
175613
- this.logger.info("Assistant initialized", {
175614
- tools: this.assistantLoop.getTools().length,
175615
- skills: this.assistantLoop.getSkills().length
175616
- });
175617
- }
175618
- async send(message) {
175619
- if (!this.initialized) {
175620
- await this.initialize();
175621
- }
175622
- if (!message.trim()) {
175623
- return;
175624
- }
175625
- this.messageQueue.push(message);
175626
- if (this.assistantLoop.isProcessing() || this.processingQueue) {
175627
- this.logger.info("Queuing message (assistant busy)", { message, queueLength: this.messageQueue.length });
175628
- return;
175629
- }
175630
- await this.drainQueue();
175631
- }
175632
- async processMessage(message) {
175633
- this.logger.info("User message", { message });
175634
- this.sawErrorChunk = false;
175635
- try {
175636
- await this.assistantLoop.process(message);
175637
- const context = this.assistantLoop.getContext();
175638
- const contextMessages = context.getMessages();
175639
- if (contextMessages.length > 0) {
175640
- this.mergeMessages(contextMessages);
175641
- const lastMessage = contextMessages.slice(-1)[0];
175642
- if (lastMessage?.role === "assistant") {
175643
- this.logger.info("Assistant response", {
175644
- length: lastMessage.content.length,
175645
- hasToolCalls: !!lastMessage.toolCalls?.length
175646
- });
175647
- }
175648
- }
175649
- this.saveSession();
175650
- } catch (error3) {
175651
- if (this.sawErrorChunk) {
175652
- return;
175653
- }
175654
- const err = error3 instanceof Error ? error3 : new Error(String(error3));
175655
- this.logger.error("Error processing message", { error: err.message });
175656
- for (const callback of this.errorCallbacks) {
175657
- callback(err);
175658
- }
175659
- }
175660
- }
175661
- async drainQueue() {
175662
- if (this.processingQueue)
175663
- return;
175664
- this.processingQueue = true;
175665
- try {
175666
- while (this.messageQueue.length > 0 && !this.assistantLoop.isProcessing()) {
175667
- const nextMessage = this.messageQueue.shift();
175668
- if (nextMessage) {
175669
- await this.processMessage(nextMessage);
175670
- }
175671
- }
175672
- } finally {
175673
- this.processingQueue = false;
175674
- }
175675
- }
175676
- saveSession() {
175677
- this.session.save({
175678
- messages: this.messages,
175679
- startedAt: this.startedAt,
175680
- updatedAt: new Date().toISOString(),
175681
- cwd: this.cwd
175682
- });
175683
- }
175684
- onChunk(callback) {
175685
- this.chunkCallbacks.push(callback);
175686
- return () => {
175687
- const index = this.chunkCallbacks.indexOf(callback);
175688
- if (index !== -1)
175689
- this.chunkCallbacks.splice(index, 1);
175690
- };
175691
- }
175692
- onError(callback) {
175693
- this.errorCallbacks.push(callback);
175694
- return () => {
175695
- const index = this.errorCallbacks.indexOf(callback);
175696
- if (index !== -1)
175697
- this.errorCallbacks.splice(index, 1);
175698
- };
175699
- }
175700
- setAskUserHandler(handler) {
175701
- if (typeof this.assistantLoop.setAskUserHandler === "function") {
175702
- this.assistantLoop.setAskUserHandler(handler);
175703
- }
175704
- }
175705
- async getTools() {
175706
- if (!this.initialized) {
175707
- await this.initialize();
175708
- }
175709
- return this.assistantLoop.getTools();
175710
- }
175711
- async getSkills() {
175712
- if (!this.initialized) {
175713
- await this.initialize();
175714
- }
175715
- return this.assistantLoop.getSkills();
175716
- }
175717
- async refreshSkills() {
175718
- if (!this.initialized) {
175719
- await this.initialize();
175720
- }
175721
- if (typeof this.assistantLoop.refreshSkills === "function") {
175722
- await this.assistantLoop.refreshSkills();
175723
- }
175724
- return this.assistantLoop.getSkills();
175725
- }
175726
- getSkillLoader() {
175727
- if (typeof this.assistantLoop.getSkillLoader === "function") {
175728
- return this.assistantLoop.getSkillLoader();
175729
- }
175730
- return null;
175731
- }
175732
- stop() {
175733
- this.logger.info("Processing stopped by user");
175734
- this.assistantLoop.stop();
175735
- }
175736
- disconnect() {
175737
- this.logger.info("Session ended");
175738
- if (typeof this.assistantLoop.shutdown === "function") {
175739
- this.assistantLoop.shutdown();
175740
- }
175741
- this.saveSession();
175742
- this.chunkCallbacks.length = 0;
175743
- this.errorCallbacks.length = 0;
175744
- }
175745
- isProcessing() {
175746
- return this.assistantLoop.isProcessing();
175747
- }
175748
- getSessionId() {
175749
- return this.session.getSessionId();
175750
- }
175751
- async getCommands() {
175752
- if (!this.initialized) {
175753
- await this.initialize();
175754
- }
175755
- return this.assistantLoop.getCommands();
175756
- }
175757
- getTokenUsage() {
175758
- return this.assistantLoop.getTokenUsage();
175759
- }
175760
- getEnergyState() {
175761
- if (typeof this.assistantLoop.getEnergyState === "function") {
175762
- return this.assistantLoop.getEnergyState();
175763
- }
175764
- return null;
175765
- }
175766
- getVoiceState() {
175767
- if (typeof this.assistantLoop.getVoiceState === "function") {
175768
- return this.assistantLoop.getVoiceState();
175769
- }
175770
- return null;
175771
- }
175772
- getHeartbeatState() {
175773
- if (typeof this.assistantLoop.getHeartbeatState === "function") {
175774
- return this.assistantLoop.getHeartbeatState();
175775
- }
175776
- return null;
175777
- }
175778
- getIdentityInfo() {
175779
- if (typeof this.assistantLoop.getIdentityInfo === "function") {
175780
- return this.assistantLoop.getIdentityInfo();
175781
- }
175782
- return null;
175783
- }
175784
- getModel() {
175785
- if (typeof this.assistantLoop.getModel === "function") {
175786
- return this.assistantLoop.getModel();
175787
- }
175788
- return null;
175789
- }
175790
- getAssistantManager() {
175791
- if (typeof this.assistantLoop.getAssistantManager === "function") {
175792
- return this.assistantLoop.getAssistantManager();
175793
- }
175794
- return null;
175795
- }
175796
- getIdentityManager() {
175797
- if (typeof this.assistantLoop.getIdentityManager === "function") {
175798
- return this.assistantLoop.getIdentityManager();
175799
- }
175800
- return null;
175801
- }
175802
- getMemoryManager() {
175803
- if (typeof this.assistantLoop.getMemoryManager === "function") {
175804
- return this.assistantLoop.getMemoryManager();
175805
- }
175806
- return null;
175807
- }
175808
- async refreshIdentityContext() {
175809
- if (typeof this.assistantLoop.refreshIdentityContext === "function") {
175810
- await this.assistantLoop.refreshIdentityContext();
175811
- }
175812
- }
175813
- getMessagesManager() {
175814
- if (typeof this.assistantLoop.getMessagesManager === "function") {
175815
- return this.assistantLoop.getMessagesManager();
175816
- }
175817
- return null;
175818
- }
175819
- getWebhooksManager() {
175820
- if (typeof this.assistantLoop.getWebhooksManager === "function") {
175821
- return this.assistantLoop.getWebhooksManager();
175822
- }
175823
- return null;
175824
- }
175825
- getChannelsManager() {
175826
- if (typeof this.assistantLoop.getChannelsManager === "function") {
175827
- return this.assistantLoop.getChannelsManager();
175828
- }
175829
- return null;
175830
- }
175831
- getPeopleManager() {
175832
- if (typeof this.assistantLoop.getPeopleManager === "function") {
175833
- return this.assistantLoop.getPeopleManager();
175834
- }
175835
- return null;
175836
- }
175837
- getTelephonyManager() {
175838
- if (typeof this.assistantLoop.getTelephonyManager === "function") {
175839
- return this.assistantLoop.getTelephonyManager();
175840
- }
175841
- return null;
175842
- }
175843
- getWalletManager() {
175844
- if (typeof this.assistantLoop.getWalletManager === "function") {
175845
- return this.assistantLoop.getWalletManager();
175846
- }
175847
- return null;
175848
- }
175849
- getSecretsManager() {
175850
- if (typeof this.assistantLoop.getSecretsManager === "function") {
175851
- return this.assistantLoop.getSecretsManager();
175852
- }
175853
- return null;
175854
- }
175855
- getInboxManager() {
175856
- if (typeof this.assistantLoop.getInboxManager === "function") {
175857
- return this.assistantLoop.getInboxManager();
175858
- }
175859
- return null;
175860
- }
175861
- getActiveProjectId() {
175862
- if (typeof this.assistantLoop.getActiveProjectId === "function") {
175863
- return this.assistantLoop.getActiveProjectId();
175864
- }
175865
- return null;
175866
- }
175867
- setActiveProjectId(projectId) {
175868
- if (typeof this.assistantLoop.setActiveProjectId === "function") {
175869
- this.assistantLoop.setActiveProjectId(projectId);
175870
- }
175871
- }
175872
- getSwarmCoordinator() {
175873
- if (typeof this.assistantLoop.getOrCreateSwarmCoordinator === "function") {
175874
- return this.assistantLoop.getOrCreateSwarmCoordinator();
175875
- }
175876
- return null;
175877
- }
175878
- getAssistantLoop() {
175879
- return this.assistantLoop;
175880
- }
175881
- addSystemMessage(content) {
175882
- if (typeof this.assistantLoop.addSystemMessage === "function") {
175883
- this.assistantLoop.addSystemMessage(content);
175884
- } else {
175885
- const context = this.assistantLoop.getContext();
175886
- if (typeof context.addSystemMessage === "function") {
175887
- context.addSystemMessage(content);
175888
- }
175889
- }
175890
- }
175891
- clearConversation() {
175892
- this.assistantLoop.clearConversation();
175893
- this.messages = [];
175894
- this.messageIds.clear();
175895
- this.logger.info("Conversation cleared");
175896
- }
175897
- getCwd() {
175898
- return this.cwd;
175899
- }
175900
- getStartedAt() {
175901
- return this.startedAt;
175902
- }
175903
- getMessages() {
175904
- return [...this.messages];
175905
- }
175906
- getQueueLength() {
175907
- return this.messageQueue.length;
175908
- }
175909
- clearQueue() {
175910
- this.messageQueue = [];
175911
- this.logger.info("Message queue cleared");
175912
- }
175913
- mergeMessages(contextMessages) {
175914
- if (contextMessages.length === 0)
175915
- return;
175916
- if (this.messages.length === 0 && this.messageIds.size === 0) {
175917
- this.messages = [...contextMessages];
175918
- this.messageIds = new Set(contextMessages.map((msg) => msg.id));
175919
- return;
175920
- }
175921
- for (const msg of contextMessages) {
175922
- if (!this.messageIds.has(msg.id)) {
175923
- this.messages.push(msg);
175924
- this.messageIds.add(msg.id);
175925
- }
175926
- }
175927
- }
175928
- selectContextSeed(messages) {
175929
- if (messages.length === 0)
175930
- return [];
175931
- const contextInfo = typeof this.assistantLoop.getContextInfo === "function" ? this.assistantLoop.getContextInfo() : null;
175932
- const maxMessages = contextInfo?.config?.maxMessages ?? 100;
175933
- if (messages.length <= maxMessages)
175934
- return messages;
175935
- let startIndex = messages.length - maxMessages;
175936
- if (startIndex > 0 && messages[startIndex]?.toolResults && messages[startIndex - 1]) {
175937
- startIndex -= 1;
175938
- }
175939
- return messages.slice(Math.max(0, startIndex));
175940
- }
175941
- }
175942
- var init_client4 = __esm(async () => {
175943
- init_src2();
175944
- await __promiseAll([
175945
- init_loop(),
175946
- init_logger2()
175947
- ]);
175948
- });
175949
-
175950
176029
  // packages/core/src/sessions/registry.ts
175951
176030
  class SessionRegistry {
175952
176031
  sessions = new Map;
@@ -180810,7 +180889,7 @@ class GlobalMemoryManager {
180810
180889
  const result = this.db.prepare(`
180811
180890
  DELETE FROM memories WHERE id IN (
180812
180891
  SELECT id FROM memories
180813
- ORDER BY importance ASC, accessed_at ASC NULLS FIRST, created_at ASC
180892
+ ORDER BY importance ASC, (accessed_at IS NOT NULL) ASC, accessed_at ASC, created_at ASC
180814
180893
  LIMIT ?
180815
180894
  )
180816
180895
  `).run(toRemove);
@@ -182581,6 +182660,7 @@ class AssistantLoop {
182581
182660
  isRunning = false;
182582
182661
  shouldStop = false;
182583
182662
  cumulativeTurns = 0;
182663
+ emittedTerminalChunk = false;
182584
182664
  toolAbortController = null;
182585
182665
  systemPrompt = null;
182586
182666
  connectorDiscovery = null;
@@ -182598,6 +182678,7 @@ class AssistantLoop {
182598
182678
  messagesManager = null;
182599
182679
  webhooksManager = null;
182600
182680
  channelsManager = null;
182681
+ channelAgentPool = null;
182601
182682
  peopleManager = null;
182602
182683
  telephonyManager = null;
182603
182684
  memoryManager = null;
@@ -182842,6 +182923,7 @@ class AssistantLoop {
182842
182923
  const assistantName = assistant?.name || "assistant";
182843
182924
  this.channelsManager = createChannelsManager(assistantId, assistantName, this.config.channels);
182844
182925
  registerChannelTools(this.toolRegistry, () => this.channelsManager);
182926
+ this.channelAgentPool = new ChannelAgentPool(this.cwd);
182845
182927
  }
182846
182928
  try {
182847
182929
  this.peopleManager = await createPeopleManager();
@@ -183199,6 +183281,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
183199
183281
  throw new Error("Assistant not initialized. Call initialize() first.");
183200
183282
  }
183201
183283
  this.isRunning = true;
183284
+ this.emittedTerminalChunk = false;
183202
183285
  this.setHeartbeatState("processing");
183203
183286
  this.shouldStop = false;
183204
183287
  this.cumulativeTurns = 0;
@@ -183223,6 +183306,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
183223
183306
  if (explicitToolResult) {
183224
183307
  this.pendingMemoryContext = null;
183225
183308
  this.pendingContextInjection = null;
183309
+ this.ensureTerminalChunk();
183226
183310
  return explicitToolResult;
183227
183311
  }
183228
183312
  if (userMessage.startsWith("/")) {
@@ -183260,6 +183344,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
183260
183344
  panelValue: `session:${payload}`
183261
183345
  });
183262
183346
  }
183347
+ this.ensureTerminalChunk();
183263
183348
  return { ok: true, summary: `Handled ${userMessage}` };
183264
183349
  }
183265
183350
  if (commandResult.prompt) {
@@ -183270,6 +183355,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
183270
183355
  if (handled) {
183271
183356
  this.pendingMemoryContext = null;
183272
183357
  this.pendingContextInjection = null;
183358
+ this.ensureTerminalChunk();
183273
183359
  return { ok: true, summary: `Executed ${userMessage}` };
183274
183360
  }
183275
183361
  } else {
@@ -183284,6 +183370,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
183284
183370
  panelValue: commandResult.panelValue
183285
183371
  });
183286
183372
  }
183373
+ this.ensureTerminalChunk();
183287
183374
  return { ok: true, summary: `Handled ${userMessage}` };
183288
183375
  }
183289
183376
  if (commandResult.prompt) {
@@ -183925,6 +184012,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
183925
184012
  getMessagesManager: () => this.messagesManager,
183926
184013
  getWebhooksManager: () => this.webhooksManager,
183927
184014
  getChannelsManager: () => this.channelsManager,
184015
+ getChannelAgentPool: () => this.channelAgentPool,
183928
184016
  getPeopleManager: () => this.peopleManager,
183929
184017
  getTelephonyManager: () => this.telephonyManager,
183930
184018
  getMemoryManager: () => this.memoryManager,
@@ -184129,7 +184217,15 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
184129
184217
  }
184130
184218
  return true;
184131
184219
  }
184220
+ ensureTerminalChunk() {
184221
+ if (!this.emittedTerminalChunk) {
184222
+ this.emit({ type: "done" });
184223
+ }
184224
+ }
184132
184225
  emit(chunk) {
184226
+ if (chunk.type === "done" || chunk.type === "error") {
184227
+ this.emittedTerminalChunk = true;
184228
+ }
184133
184229
  this.onChunk?.(chunk);
184134
184230
  }
184135
184231
  async emitNotification(params) {
@@ -184175,6 +184271,8 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
184175
184271
  this.voiceManager?.stopListening();
184176
184272
  this.messagesManager?.stopWatching();
184177
184273
  this.webhooksManager?.stopWatching();
184274
+ this.channelAgentPool?.shutdown();
184275
+ this.channelAgentPool = null;
184178
184276
  this.channelsManager?.close();
184179
184277
  this.channelsManager = null;
184180
184278
  this.telephonyManager?.close();
@@ -184256,6 +184354,9 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
184256
184354
  getChannelsManager() {
184257
184355
  return this.channelsManager;
184258
184356
  }
184357
+ getChannelAgentPool() {
184358
+ return this.channelAgentPool;
184359
+ }
184259
184360
  getPeopleManager() {
184260
184361
  return this.peopleManager;
184261
184362
  }
@@ -186932,6 +187033,7 @@ __export(exports_src2, {
186932
187033
  CommandExecutor: () => CommandExecutor,
186933
187034
  ChannelsManager: () => ChannelsManager,
186934
187035
  ChannelStore: () => ChannelStore,
187036
+ ChannelAgentPool: () => ChannelAgentPool,
186935
187037
  CapabilityStorage: () => CapabilityStorage,
186936
187038
  CapabilityEnforcer: () => CapabilityEnforcer,
186937
187039
  CallManager: () => CallManager,
@@ -206202,6 +206304,8 @@ await init_src3();
206202
206304
 
206203
206305
  // packages/terminal/src/hooks/useSafeInput.ts
206204
206306
  var import_react27 = __toESM(require_react(), 1);
206307
+ var rawModeUsers = 0;
206308
+ var rawModeEnabled = false;
206205
206309
  function parseKeypress2(s6) {
206206
206310
  const key = { name: "", ctrl: false, shift: false, meta: false, option: false, sequence: s6 };
206207
206311
  if (s6 === "\r" || s6 === `
@@ -206248,9 +206352,17 @@ function useSafeInput(handler, options = {}) {
206248
206352
  import_react27.useEffect(() => {
206249
206353
  if (!isRawModeSupported || !setRawMode)
206250
206354
  return;
206251
- setRawMode(true);
206355
+ rawModeUsers += 1;
206356
+ if (!rawModeEnabled) {
206357
+ setRawMode(true);
206358
+ rawModeEnabled = true;
206359
+ }
206252
206360
  return () => {
206253
- setRawMode(false);
206361
+ rawModeUsers = Math.max(0, rawModeUsers - 1);
206362
+ if (rawModeEnabled && rawModeUsers === 0) {
206363
+ setRawMode(false);
206364
+ rawModeEnabled = false;
206365
+ }
206254
206366
  };
206255
206367
  }, [isRawModeSupported, setRawMode]);
206256
206368
  import_react27.useEffect(() => {
@@ -206319,6 +206431,7 @@ var COMMANDS = [
206319
206431
  { name: "/memory", description: "show what AI remembers" },
206320
206432
  { name: "/context", description: "manage injected project context" },
206321
206433
  { name: "/hooks", description: "manage hooks (list, add, remove, test)" },
206434
+ { name: "/onboarding", description: "rerun onboarding setup" },
206322
206435
  { name: "/projects", description: "manage projects in this folder" },
206323
206436
  { name: "/plans", description: "manage project plans" },
206324
206437
  { name: "/schedules", description: "manage scheduled commands" },
@@ -219109,6 +219222,11 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219109
219222
  const [createName, setCreateName] = import_react46.useState("");
219110
219223
  const [createDesc, setCreateDesc] = import_react46.useState("");
219111
219224
  const [chatInput, setChatInput] = import_react46.useState("");
219225
+ const lastSubmitTimeRef = import_react46.useRef(0);
219226
+ const [mentionActive, setMentionActive] = import_react46.useState(false);
219227
+ const [mentionQuery, setMentionQuery] = import_react46.useState("");
219228
+ const [mentionIndex, setMentionIndex] = import_react46.useState(0);
219229
+ const [chatMembers, setChatMembers] = import_react46.useState([]);
219112
219230
  const [inviteName, setInviteName] = import_react46.useState("");
219113
219231
  const loadChannels = () => {
219114
219232
  try {
@@ -219128,6 +219246,7 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219128
219246
  setSelectedChannel(ch2);
219129
219247
  const result = manager.readMessages(ch2.id, 50);
219130
219248
  setMessages(result?.messages || []);
219249
+ setChatMembers(manager.getMembers(ch2.id));
219131
219250
  setMode("chat");
219132
219251
  }
219133
219252
  };
@@ -219139,7 +219258,68 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219139
219258
  setMode("members");
219140
219259
  }
219141
219260
  };
219261
+ const mentionCandidates = import_react46.useMemo(() => {
219262
+ if (!mentionActive)
219263
+ return [];
219264
+ const q7 = mentionQuery.toLowerCase();
219265
+ return chatMembers.filter((m5) => m5.assistantName.toLowerCase().includes(q7));
219266
+ }, [mentionActive, mentionQuery, chatMembers]);
219267
+ const handleChatInputChange = (value) => {
219268
+ const prev = chatInput;
219269
+ setChatInput(value);
219270
+ if (value.length === prev.length + 1 && value[value.length - 1] === "@" && !mentionActive) {
219271
+ setMentionActive(true);
219272
+ setMentionQuery("");
219273
+ setMentionIndex(0);
219274
+ return;
219275
+ }
219276
+ if (mentionActive) {
219277
+ const lastAt = value.lastIndexOf("@");
219278
+ if (lastAt >= 0) {
219279
+ const afterAt = value.slice(lastAt + 1);
219280
+ if (lastAt > prev.lastIndexOf("@") + prev.slice(prev.lastIndexOf("@") + 1).length + 1) {
219281
+ setMentionActive(false);
219282
+ } else {
219283
+ setMentionQuery(afterAt);
219284
+ setMentionIndex(0);
219285
+ }
219286
+ } else {
219287
+ setMentionActive(false);
219288
+ }
219289
+ }
219290
+ };
219291
+ const insertMention = (memberName) => {
219292
+ const lastAt = chatInput.lastIndexOf("@");
219293
+ if (lastAt >= 0) {
219294
+ const before = chatInput.slice(0, lastAt);
219295
+ const needsQuotes = memberName.includes(" ");
219296
+ const mention = needsQuotes ? `@"${memberName}" ` : `@${memberName} `;
219297
+ setChatInput(before + mention);
219298
+ }
219299
+ setMentionActive(false);
219300
+ setMentionQuery("");
219301
+ setMentionIndex(0);
219302
+ };
219142
219303
  useSafeInput((input, key) => {
219304
+ if (mentionActive && mode === "chat") {
219305
+ if (key.escape) {
219306
+ setMentionActive(false);
219307
+ setMentionQuery("");
219308
+ return;
219309
+ }
219310
+ if (key.upArrow) {
219311
+ setMentionIndex((prev) => Math.max(0, prev - 1));
219312
+ return;
219313
+ }
219314
+ if (key.downArrow) {
219315
+ setMentionIndex((prev) => Math.min(mentionCandidates.length - 1, prev + 1));
219316
+ return;
219317
+ }
219318
+ if (key.tab && mentionCandidates.length > 0) {
219319
+ insertMention(mentionCandidates[mentionIndex].assistantName);
219320
+ return;
219321
+ }
219322
+ }
219143
219323
  const isTextEntry = mode === "create-name" || mode === "create-desc" || mode === "invite" || mode === "chat";
219144
219324
  if (key.escape || input === "q" && !isTextEntry) {
219145
219325
  if (key.escape && mode === "list" || input === "q" && mode === "list") {
@@ -219148,6 +219328,7 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219148
219328
  setMode("list");
219149
219329
  setSelectedChannel(null);
219150
219330
  setStatusMessage(null);
219331
+ setMentionActive(false);
219151
219332
  }
219152
219333
  return;
219153
219334
  }
@@ -219233,7 +219414,7 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219233
219414
  }, undefined, false, undefined, this),
219234
219415
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
219235
219416
  color: "gray",
219236
- children: mode === "list" ? "q:close c:create enter:open m:members i:invite l:leave d:delete r:refresh" : mode === "chat" ? "esc:back (type to chat)" : mode === "members" ? "esc:back" : mode === "delete-confirm" ? "y:confirm n:cancel" : mode === "create-confirm" ? "y:confirm n:cancel" : "Enter to continue"
219417
+ children: mode === "list" ? "q:close c:create enter:open m:members i:invite l:leave d:delete r:refresh" : mode === "chat" ? "esc:back (type to chat, @ to mention)" : mode === "members" ? "esc:back" : mode === "delete-confirm" ? "y:confirm n:cancel" : mode === "create-confirm" ? "y:confirm n:cancel" : "Enter to continue"
219237
219418
  }, undefined, false, undefined, this)
219238
219419
  ]
219239
219420
  }, undefined, true, undefined, this);
@@ -219375,13 +219556,18 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219375
219556
  }, undefined, false, undefined, this),
219376
219557
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(build_default2, {
219377
219558
  value: chatInput,
219378
- onChange: setChatInput,
219559
+ onChange: handleChatInputChange,
219379
219560
  onSubmit: () => {
219380
219561
  if (chatInput.trim()) {
219562
+ const now2 = Date.now();
219563
+ if (now2 - lastSubmitTimeRef.current < 500)
219564
+ return;
219565
+ lastSubmitTimeRef.current = now2;
219381
219566
  const msg = chatInput.trim();
219382
219567
  const result = activePersonId && activePersonName ? manager.sendAs(selectedChannel.id, msg, activePersonId, activePersonName) : manager.send(selectedChannel.id, msg);
219383
219568
  if (result.success) {
219384
219569
  setChatInput("");
219570
+ setMentionActive(false);
219385
219571
  const updated = manager.readMessages(selectedChannel.id, 50);
219386
219572
  setMessages(updated?.messages || []);
219387
219573
  if (activePersonId && activePersonName && onPersonMessage && selectedChannel) {
@@ -219411,9 +219597,40 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
219411
219597
  }
219412
219598
  }
219413
219599
  },
219414
- placeholder: "Type a message..."
219600
+ placeholder: "Type a message... (@ to mention)"
219415
219601
  }, undefined, false, undefined, this)
219416
219602
  ]
219603
+ }, undefined, true, undefined, this),
219604
+ mentionActive && mentionCandidates.length > 0 && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
219605
+ flexDirection: "column",
219606
+ paddingX: 1,
219607
+ borderStyle: "single",
219608
+ borderColor: "yellow",
219609
+ marginTop: 0,
219610
+ children: [
219611
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
219612
+ color: "yellow",
219613
+ bold: true,
219614
+ children: "Members (Tab to select, Esc to dismiss)"
219615
+ }, undefined, false, undefined, this),
219616
+ mentionCandidates.slice(0, 8).map((m5, i5) => /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
219617
+ children: [
219618
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
219619
+ color: i5 === mentionIndex ? "blue" : undefined,
219620
+ children: i5 === mentionIndex ? "\u25B8 " : " "
219621
+ }, undefined, false, undefined, this),
219622
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
219623
+ bold: i5 === mentionIndex,
219624
+ color: i5 === mentionIndex ? "blue" : undefined,
219625
+ children: m5.assistantName
219626
+ }, undefined, false, undefined, this),
219627
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
219628
+ color: "gray",
219629
+ children: m5.memberType === "person" ? " [person]" : " [assistant]"
219630
+ }, undefined, false, undefined, this)
219631
+ ]
219632
+ }, m5.assistantId, true, undefined, this))
219633
+ ]
219417
219634
  }, undefined, true, undefined, this)
219418
219635
  ]
219419
219636
  }, undefined, true, undefined, this);
@@ -232120,6 +232337,10 @@ function App2({ cwd: cwd2, version: version3 }) {
232120
232337
  setShowIdentityPanel(true);
232121
232338
  return;
232122
232339
  }
232340
+ if (cmdName === "onboarding" && !cmdArgs) {
232341
+ setShowOnboardingPanel(true);
232342
+ return;
232343
+ }
232123
232344
  if (cmdName === "memory" && !cmdArgs) {
232124
232345
  setMemoryError(null);
232125
232346
  setShowMemoryPanel(true);
@@ -233613,23 +233834,30 @@ When done, report the result.`);
233613
233834
  activePersonName: activeSession?.client.getPeopleManager?.()?.getActivePerson?.()?.name || undefined,
233614
233835
  onPersonMessage: (channelName, personName, message) => {
233615
233836
  const members = channelsManager.getMembers(channelName);
233616
- const assistantMembers = members.filter((m5) => m5.memberType === "assistant").map((m5) => m5.assistantName);
233837
+ const agentPool = activeSession?.client.getChannelAgentPool?.();
233838
+ if (agentPool) {
233839
+ agentPool.triggerResponses(channelName, personName, message, members, activeSession?.assistantId || undefined);
233840
+ }
233841
+ const activeAssistantId = activeSession?.assistantId;
233842
+ const isActiveMember = activeAssistantId && members.some((m5) => m5.assistantId === activeAssistantId && m5.memberType === "assistant");
233617
233843
  const mentions = parseMentions(message);
233618
- let targetAssistants = assistantMembers;
233844
+ let activeAssistantTargeted = true;
233619
233845
  if (mentions.length > 0) {
233620
- const knownNames = assistantMembers.map((name2) => ({ id: name2, name: name2 }));
233621
- const resolved = mentions.map((m5) => resolveNameToKnown(m5, knownNames)).filter(Boolean).map((r6) => r6.name);
233846
+ const assistantMembers = members.filter((m5) => m5.memberType === "assistant");
233847
+ const knownNames = assistantMembers.map((m5) => ({ id: m5.assistantId, name: m5.assistantName }));
233848
+ const resolved = mentions.map((m5) => resolveNameToKnown(m5, knownNames)).filter(Boolean);
233622
233849
  if (resolved.length > 0) {
233623
- targetAssistants = resolved;
233850
+ activeAssistantTargeted = resolved.some((r6) => r6.id === activeAssistantId);
233851
+ } else {
233852
+ activeAssistantTargeted = false;
233624
233853
  }
233625
233854
  }
233626
- const assistantList = targetAssistants.length > 0 ? `Assistants in this channel: ${targetAssistants.join(", ")}.` : "";
233627
- const prompt = `[Channel Message] ${personName} posted in #${channelName}: "${message}"
233628
-
233629
- ${assistantList}
233855
+ if (isActiveMember && activeAssistantTargeted) {
233856
+ const prompt = `[Channel Message] ${personName} posted in #${channelName}: "${message}"
233630
233857
 
233631
233858
  Respond in #${channelName} using channel_send. Be helpful and conversational.`;
233632
- activeSession?.client.send(prompt);
233859
+ activeSession?.client.send(prompt);
233860
+ }
233633
233861
  }
233634
233862
  }, undefined, false, undefined, this);
233635
233863
  }
@@ -234421,7 +234649,7 @@ Interactive Mode:
234421
234649
  // packages/terminal/src/index.tsx
234422
234650
  var jsx_dev_runtime44 = __toESM(require_jsx_dev_runtime(), 1);
234423
234651
  setRuntime(bunRuntime);
234424
- var VERSION4 = "1.1.16";
234652
+ var VERSION4 = "1.1.18";
234425
234653
  var SYNC_START = "\x1B[?2026h";
234426
234654
  var SYNC_END = "\x1B[?2026l";
234427
234655
  function enableSynchronizedOutput() {
@@ -234561,4 +234789,4 @@ export {
234561
234789
  main
234562
234790
  };
234563
234791
 
234564
- //# debugId=16DA2E0FA4EFC84C64756E2164756E21
234792
+ //# debugId=C8555F61FD8AD49264756E2164756E21