@hasna/assistants 1.1.17 → 1.1.19
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/.assistants/feedback/605c7efa-fc58-4128-9473-e3886866c8aa.json +11 -0
- package/dist/.assistants/feedback/c7275051-b842-43ce-9bce-20c17467f8c0.json +11 -0
- package/dist/.assistants/schedules/0f585da2-b4e5-4967-8283-633ff8cefabb.json +22 -0
- package/dist/index.js +308 -98
- package/dist/index.js.map +14 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25784,6 +25784,60 @@ var init_executor3 = __esm(async () => {
|
|
|
25784
25784
|
MAX_SHELL_OUTPUT_LENGTH = 64 * 1024;
|
|
25785
25785
|
});
|
|
25786
25786
|
|
|
25787
|
+
// packages/core/src/channels/mentions.ts
|
|
25788
|
+
function parseMentions(content) {
|
|
25789
|
+
const mentions = [];
|
|
25790
|
+
const quotedRegex = /@"([^"]+)"/g;
|
|
25791
|
+
let match;
|
|
25792
|
+
while ((match = quotedRegex.exec(content)) !== null) {
|
|
25793
|
+
const name = match[1].trim();
|
|
25794
|
+
if (name && !mentions.includes(name)) {
|
|
25795
|
+
mentions.push(name);
|
|
25796
|
+
}
|
|
25797
|
+
}
|
|
25798
|
+
const simpleRegex = /@([a-zA-Z0-9_-]+)/g;
|
|
25799
|
+
while ((match = simpleRegex.exec(content)) !== null) {
|
|
25800
|
+
const name = match[1];
|
|
25801
|
+
if (!mentions.includes(name)) {
|
|
25802
|
+
mentions.push(name);
|
|
25803
|
+
}
|
|
25804
|
+
}
|
|
25805
|
+
return mentions;
|
|
25806
|
+
}
|
|
25807
|
+
function resolveNameToKnown(mentionName, knownNames) {
|
|
25808
|
+
const lower = mentionName.toLowerCase();
|
|
25809
|
+
const exact = knownNames.find((k) => k.name.toLowerCase() === lower);
|
|
25810
|
+
if (exact)
|
|
25811
|
+
return exact;
|
|
25812
|
+
const prefix = knownNames.find((k) => k.name.toLowerCase().startsWith(lower));
|
|
25813
|
+
if (prefix)
|
|
25814
|
+
return prefix;
|
|
25815
|
+
const word = knownNames.find((k) => k.name.toLowerCase().split(/\s+/).some((w) => w === lower));
|
|
25816
|
+
if (word)
|
|
25817
|
+
return word;
|
|
25818
|
+
return null;
|
|
25819
|
+
}
|
|
25820
|
+
function resolveMentions(names, members) {
|
|
25821
|
+
const resolved = [];
|
|
25822
|
+
for (const name of names) {
|
|
25823
|
+
const lower = name.toLowerCase();
|
|
25824
|
+
const member = members.find((m) => m.assistantName.toLowerCase() === lower);
|
|
25825
|
+
if (member) {
|
|
25826
|
+
resolved.push({
|
|
25827
|
+
name,
|
|
25828
|
+
memberId: member.assistantId,
|
|
25829
|
+
memberType: member.memberType
|
|
25830
|
+
});
|
|
25831
|
+
}
|
|
25832
|
+
}
|
|
25833
|
+
return resolved;
|
|
25834
|
+
}
|
|
25835
|
+
function getMentionedMemberIds(content, members) {
|
|
25836
|
+
const names = parseMentions(content);
|
|
25837
|
+
const resolved = resolveMentions(names, members);
|
|
25838
|
+
return resolved.map((r) => r.memberId);
|
|
25839
|
+
}
|
|
25840
|
+
|
|
25787
25841
|
// packages/core/src/scheduler/format.ts
|
|
25788
25842
|
function formatRelativeTime(timestamp, now2 = Date.now()) {
|
|
25789
25843
|
if (!timestamp)
|
|
@@ -67267,6 +67321,12 @@ class SwarmCoordinator {
|
|
|
67267
67321
|
}
|
|
67268
67322
|
const config = { ...this.config, ...input.config };
|
|
67269
67323
|
this.config = config;
|
|
67324
|
+
if (!Number.isFinite(config.maxConcurrent) || config.maxConcurrent < 1) {
|
|
67325
|
+
this.streamText(`
|
|
67326
|
+
\u26A0\uFE0F Invalid swarm config: maxConcurrent=${config.maxConcurrent}. Using 1.
|
|
67327
|
+
`);
|
|
67328
|
+
this.config.maxConcurrent = 1;
|
|
67329
|
+
}
|
|
67270
67330
|
this.validateToolLists(config);
|
|
67271
67331
|
const swarmId = generateId();
|
|
67272
67332
|
this.state = {
|
|
@@ -68234,7 +68294,12 @@ class TaskGraphScheduler {
|
|
|
68234
68294
|
stopped = false;
|
|
68235
68295
|
constructor(graph, options = {}) {
|
|
68236
68296
|
this.graph = graph;
|
|
68237
|
-
|
|
68297
|
+
const merged = { ...DEFAULT_SCHEDULER_OPTIONS, ...options };
|
|
68298
|
+
const maxConcurrent = Number.isFinite(merged.maxConcurrent) ? merged.maxConcurrent : DEFAULT_SCHEDULER_OPTIONS.maxConcurrent;
|
|
68299
|
+
this.options = {
|
|
68300
|
+
...merged,
|
|
68301
|
+
maxConcurrent: Math.max(1, maxConcurrent)
|
|
68302
|
+
};
|
|
68238
68303
|
}
|
|
68239
68304
|
async execute(executor2) {
|
|
68240
68305
|
const results = new Map;
|
|
@@ -74461,15 +74526,28 @@ Configure the external source with the URL and secret above.
|
|
|
74461
74526
|
if (activePerson && result.success) {
|
|
74462
74527
|
const agentPool = context.getChannelAgentPool?.();
|
|
74463
74528
|
const members = manager.getMembers(channel);
|
|
74529
|
+
const currentAssistantId = context.getAssistantManager?.()?.getActive?.()?.id;
|
|
74464
74530
|
if (agentPool && members.length > 0) {
|
|
74465
|
-
const currentAssistantId = context.getAssistantManager?.()?.getActive?.()?.id;
|
|
74466
74531
|
agentPool.triggerResponses(channel, activePerson.name, message, members, currentAssistantId || undefined);
|
|
74467
74532
|
}
|
|
74533
|
+
const mentions = parseMentions(message);
|
|
74534
|
+
if (mentions.length > 0) {
|
|
74535
|
+
const assistantMembers = members.filter((m) => m.memberType === "assistant");
|
|
74536
|
+
const knownNames = assistantMembers.map((m) => ({ id: m.assistantId, name: m.assistantName }));
|
|
74537
|
+
const resolved = mentions.map((m) => resolveNameToKnown(m, knownNames)).filter(Boolean);
|
|
74538
|
+
if (resolved.length > 0) {
|
|
74539
|
+
if (!resolved.some((r) => r.id === currentAssistantId)) {
|
|
74540
|
+
return { handled: true };
|
|
74541
|
+
}
|
|
74542
|
+
} else {
|
|
74543
|
+
return { handled: true };
|
|
74544
|
+
}
|
|
74545
|
+
}
|
|
74468
74546
|
return {
|
|
74469
74547
|
handled: false,
|
|
74470
74548
|
prompt: `[Channel Message] ${activePerson.name} posted in #${channel}: "${message}"
|
|
74471
74549
|
|
|
74472
|
-
Respond in #${channel} using channel_send. Be helpful and conversational.`
|
|
74550
|
+
You are in a group channel with other assistants and people. Respond in #${channel} using channel_send. Be helpful and conversational. You may reference or build on what other assistants have said.`
|
|
74473
74551
|
};
|
|
74474
74552
|
}
|
|
74475
74553
|
return { handled: true };
|
|
@@ -79324,7 +79402,7 @@ ${repoUrl}/issues/new
|
|
|
79324
79402
|
context.setProjectContext(projectContext);
|
|
79325
79403
|
}
|
|
79326
79404
|
}
|
|
79327
|
-
var VERSION = "1.1.
|
|
79405
|
+
var VERSION = "1.1.19";
|
|
79328
79406
|
var init_builtin = __esm(async () => {
|
|
79329
79407
|
init_src2();
|
|
79330
79408
|
init_store();
|
|
@@ -172747,11 +172825,12 @@ class ChannelStore {
|
|
|
172747
172825
|
sendMessage(channelId, senderId, senderName, content) {
|
|
172748
172826
|
const id = generateMessageId2();
|
|
172749
172827
|
const now2 = new Date().toISOString();
|
|
172750
|
-
|
|
172751
|
-
|
|
172752
|
-
|
|
172753
|
-
|
|
172754
|
-
|
|
172828
|
+
this.db.transaction(() => {
|
|
172829
|
+
this.db.prepare(`INSERT INTO channel_messages (id, channel_id, sender_id, sender_name, content, created_at)
|
|
172830
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(id, channelId, senderId, senderName, content, now2);
|
|
172831
|
+
this.db.prepare("UPDATE channels SET updated_at = ? WHERE id = ?").run(now2, channelId);
|
|
172832
|
+
this.db.prepare("UPDATE channel_members SET last_read_at = ? WHERE channel_id = ? AND assistant_id = ?").run(now2, channelId, senderId);
|
|
172833
|
+
});
|
|
172755
172834
|
return id;
|
|
172756
172835
|
}
|
|
172757
172836
|
getMessages(channelId, options) {
|
|
@@ -172898,6 +172977,9 @@ class ChannelsManager {
|
|
|
172898
172977
|
this.config = options.config;
|
|
172899
172978
|
this.store = new ChannelStore;
|
|
172900
172979
|
}
|
|
172980
|
+
getStore() {
|
|
172981
|
+
return this.store;
|
|
172982
|
+
}
|
|
172901
172983
|
createChannel(name2, description) {
|
|
172902
172984
|
return this.store.createChannel(name2, description || null, this.assistantId, this.assistantName);
|
|
172903
172985
|
}
|
|
@@ -173527,101 +173609,99 @@ var init_client4 = __esm(async () => {
|
|
|
173527
173609
|
]);
|
|
173528
173610
|
});
|
|
173529
173611
|
|
|
173530
|
-
// packages/core/src/channels/mentions.ts
|
|
173531
|
-
function parseMentions(content) {
|
|
173532
|
-
const mentions = [];
|
|
173533
|
-
const quotedRegex = /@"([^"]+)"/g;
|
|
173534
|
-
let match;
|
|
173535
|
-
while ((match = quotedRegex.exec(content)) !== null) {
|
|
173536
|
-
const name2 = match[1].trim();
|
|
173537
|
-
if (name2 && !mentions.includes(name2)) {
|
|
173538
|
-
mentions.push(name2);
|
|
173539
|
-
}
|
|
173540
|
-
}
|
|
173541
|
-
const simpleRegex = /@([a-zA-Z0-9_-]+)/g;
|
|
173542
|
-
while ((match = simpleRegex.exec(content)) !== null) {
|
|
173543
|
-
const name2 = match[1];
|
|
173544
|
-
if (!mentions.includes(name2)) {
|
|
173545
|
-
mentions.push(name2);
|
|
173546
|
-
}
|
|
173547
|
-
}
|
|
173548
|
-
return mentions;
|
|
173549
|
-
}
|
|
173550
|
-
function resolveNameToKnown(mentionName, knownNames) {
|
|
173551
|
-
const lower = mentionName.toLowerCase();
|
|
173552
|
-
const exact = knownNames.find((k7) => k7.name.toLowerCase() === lower);
|
|
173553
|
-
if (exact)
|
|
173554
|
-
return exact;
|
|
173555
|
-
const prefix2 = knownNames.find((k7) => k7.name.toLowerCase().startsWith(lower));
|
|
173556
|
-
if (prefix2)
|
|
173557
|
-
return prefix2;
|
|
173558
|
-
const word = knownNames.find((k7) => k7.name.toLowerCase().split(/\s+/).some((w6) => w6 === lower));
|
|
173559
|
-
if (word)
|
|
173560
|
-
return word;
|
|
173561
|
-
return null;
|
|
173562
|
-
}
|
|
173563
|
-
function resolveMentions(names, members) {
|
|
173564
|
-
const resolved = [];
|
|
173565
|
-
for (const name2 of names) {
|
|
173566
|
-
const lower = name2.toLowerCase();
|
|
173567
|
-
const member = members.find((m5) => m5.assistantName.toLowerCase() === lower);
|
|
173568
|
-
if (member) {
|
|
173569
|
-
resolved.push({
|
|
173570
|
-
name: name2,
|
|
173571
|
-
memberId: member.assistantId,
|
|
173572
|
-
memberType: member.memberType
|
|
173573
|
-
});
|
|
173574
|
-
}
|
|
173575
|
-
}
|
|
173576
|
-
return resolved;
|
|
173577
|
-
}
|
|
173578
|
-
function getMentionedMemberIds(content, members) {
|
|
173579
|
-
const names = parseMentions(content);
|
|
173580
|
-
const resolved = resolveMentions(names, members);
|
|
173581
|
-
return resolved.map((r6) => r6.memberId);
|
|
173582
|
-
}
|
|
173583
|
-
|
|
173584
173612
|
// packages/core/src/channels/agent-pool.ts
|
|
173585
173613
|
class ChannelAgentPool {
|
|
173586
173614
|
agents = new Map;
|
|
173587
173615
|
cwd;
|
|
173588
|
-
|
|
173616
|
+
getChannelsManager;
|
|
173617
|
+
responding = false;
|
|
173618
|
+
maxRounds = 2;
|
|
173619
|
+
constructor(cwd, getChannelsManager) {
|
|
173589
173620
|
this.cwd = cwd;
|
|
173621
|
+
this.getChannelsManager = getChannelsManager;
|
|
173590
173622
|
}
|
|
173591
173623
|
async triggerResponses(channelName, personName, message, channelMembers, excludeAssistantId) {
|
|
173592
|
-
|
|
173593
|
-
|
|
173594
|
-
|
|
173595
|
-
|
|
173596
|
-
|
|
173597
|
-
|
|
173598
|
-
|
|
173599
|
-
|
|
173600
|
-
|
|
173601
|
-
|
|
173602
|
-
|
|
173603
|
-
|
|
173604
|
-
|
|
173605
|
-
|
|
173624
|
+
if (this.responding)
|
|
173625
|
+
return;
|
|
173626
|
+
this.responding = true;
|
|
173627
|
+
try {
|
|
173628
|
+
const assistantMembers = channelMembers.filter((m5) => m5.memberType === "assistant");
|
|
173629
|
+
if (assistantMembers.length === 0)
|
|
173630
|
+
return;
|
|
173631
|
+
let targetMembers = assistantMembers;
|
|
173632
|
+
const mentions = parseMentions(message);
|
|
173633
|
+
if (mentions.length > 0) {
|
|
173634
|
+
const knownNames = assistantMembers.map((m5) => ({
|
|
173635
|
+
id: m5.assistantId,
|
|
173636
|
+
name: m5.assistantName
|
|
173637
|
+
}));
|
|
173638
|
+
const resolved = mentions.map((m5) => resolveNameToKnown(m5, knownNames)).filter(Boolean);
|
|
173639
|
+
if (resolved.length > 0) {
|
|
173640
|
+
const resolvedIds = new Set(resolved.map((r6) => r6.id));
|
|
173641
|
+
targetMembers = assistantMembers.filter((m5) => resolvedIds.has(m5.assistantId));
|
|
173642
|
+
} else {
|
|
173643
|
+
return;
|
|
173644
|
+
}
|
|
173606
173645
|
}
|
|
173646
|
+
if (excludeAssistantId) {
|
|
173647
|
+
targetMembers = targetMembers.filter((m5) => m5.assistantId !== excludeAssistantId);
|
|
173648
|
+
}
|
|
173649
|
+
if (targetMembers.length === 0)
|
|
173650
|
+
return;
|
|
173651
|
+
const prompt = `[Channel Message] ${personName} posted in #${channelName}: "${message}"
|
|
173652
|
+
|
|
173653
|
+
You are in a group channel with other assistants and people. Respond in #${channelName} using channel_send. Be helpful and conversational. You may reference or build on what other assistants have said.`;
|
|
173654
|
+
await this.executeRound(channelName, targetMembers, prompt, excludeAssistantId);
|
|
173655
|
+
for (let round = 2;round <= this.maxRounds; round++) {
|
|
173656
|
+
await new Promise((r6) => setTimeout(r6, 1000));
|
|
173657
|
+
const followUpMembers = this.getAgentsWithUnread(channelName, targetMembers, excludeAssistantId);
|
|
173658
|
+
if (followUpMembers.length === 0)
|
|
173659
|
+
break;
|
|
173660
|
+
const followUpPrompt = `[Channel Update] New messages appeared in #${channelName}. Read them with channel_read and respond if you have something valuable to add. If the conversation is complete or you have nothing meaningful to contribute, simply say nothing (do not use channel_send).`;
|
|
173661
|
+
await this.executeRound(channelName, followUpMembers, followUpPrompt, excludeAssistantId);
|
|
173662
|
+
}
|
|
173663
|
+
} finally {
|
|
173664
|
+
this.responding = false;
|
|
173607
173665
|
}
|
|
173608
|
-
|
|
173609
|
-
|
|
173610
|
-
|
|
173611
|
-
if (
|
|
173666
|
+
}
|
|
173667
|
+
async executeRound(channelName, members, prompt, excludeAssistantId) {
|
|
173668
|
+
let roundMembers = excludeAssistantId ? members.filter((m5) => m5.assistantId !== excludeAssistantId) : members;
|
|
173669
|
+
if (roundMembers.length === 0)
|
|
173612
173670
|
return;
|
|
173613
|
-
const
|
|
173614
|
-
|
|
173615
|
-
|
|
173616
|
-
const sends = targetMembers.map(async (member) => {
|
|
173671
|
+
const shuffled = this.shuffleArray([...roundMembers]);
|
|
173672
|
+
for (let i5 = 0;i5 < shuffled.length; i5++) {
|
|
173673
|
+
const member = shuffled[i5];
|
|
173617
173674
|
try {
|
|
173618
173675
|
const client = await this.getOrCreateClient(member.assistantId);
|
|
173619
173676
|
await client.send(prompt);
|
|
173620
173677
|
} catch (error3) {
|
|
173621
|
-
console.error(`ChannelAgentPool: Failed
|
|
173678
|
+
console.error(`ChannelAgentPool: Failed for ${member.assistantName}:`, error3);
|
|
173679
|
+
}
|
|
173680
|
+
if (i5 < shuffled.length - 1) {
|
|
173681
|
+
await new Promise((r6) => setTimeout(r6, 500 + Math.floor(Math.random() * 1500)));
|
|
173622
173682
|
}
|
|
173683
|
+
}
|
|
173684
|
+
}
|
|
173685
|
+
getAgentsWithUnread(channelName, members, excludeId) {
|
|
173686
|
+
const manager = this.getChannelsManager?.();
|
|
173687
|
+
if (!manager)
|
|
173688
|
+
return [];
|
|
173689
|
+
const channel = manager.getChannel(channelName);
|
|
173690
|
+
if (!channel)
|
|
173691
|
+
return [];
|
|
173692
|
+
return members.filter((m5) => {
|
|
173693
|
+
if (m5.assistantId === excludeId)
|
|
173694
|
+
return false;
|
|
173695
|
+
const unread = manager.getStore().getUnreadMessages(channel.id, m5.assistantId);
|
|
173696
|
+
return unread.length > 0;
|
|
173623
173697
|
});
|
|
173624
|
-
|
|
173698
|
+
}
|
|
173699
|
+
shuffleArray(array) {
|
|
173700
|
+
for (let i5 = array.length - 1;i5 > 0; i5--) {
|
|
173701
|
+
const j7 = Math.floor(Math.random() * (i5 + 1));
|
|
173702
|
+
[array[i5], array[j7]] = [array[j7], array[i5]];
|
|
173703
|
+
}
|
|
173704
|
+
return array;
|
|
173625
173705
|
}
|
|
173626
173706
|
async getOrCreateClient(assistantId) {
|
|
173627
173707
|
const existing = this.agents.get(assistantId);
|
|
@@ -182645,6 +182725,7 @@ class AssistantLoop {
|
|
|
182645
182725
|
isRunning = false;
|
|
182646
182726
|
shouldStop = false;
|
|
182647
182727
|
cumulativeTurns = 0;
|
|
182728
|
+
emittedTerminalChunk = false;
|
|
182648
182729
|
toolAbortController = null;
|
|
182649
182730
|
systemPrompt = null;
|
|
182650
182731
|
connectorDiscovery = null;
|
|
@@ -182907,7 +182988,7 @@ class AssistantLoop {
|
|
|
182907
182988
|
const assistantName = assistant?.name || "assistant";
|
|
182908
182989
|
this.channelsManager = createChannelsManager(assistantId, assistantName, this.config.channels);
|
|
182909
182990
|
registerChannelTools(this.toolRegistry, () => this.channelsManager);
|
|
182910
|
-
this.channelAgentPool = new ChannelAgentPool(this.cwd);
|
|
182991
|
+
this.channelAgentPool = new ChannelAgentPool(this.cwd, () => this.channelsManager);
|
|
182911
182992
|
}
|
|
182912
182993
|
try {
|
|
182913
182994
|
this.peopleManager = await createPeopleManager();
|
|
@@ -183265,6 +183346,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
183265
183346
|
throw new Error("Assistant not initialized. Call initialize() first.");
|
|
183266
183347
|
}
|
|
183267
183348
|
this.isRunning = true;
|
|
183349
|
+
this.emittedTerminalChunk = false;
|
|
183268
183350
|
this.setHeartbeatState("processing");
|
|
183269
183351
|
this.shouldStop = false;
|
|
183270
183352
|
this.cumulativeTurns = 0;
|
|
@@ -183289,6 +183371,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
183289
183371
|
if (explicitToolResult) {
|
|
183290
183372
|
this.pendingMemoryContext = null;
|
|
183291
183373
|
this.pendingContextInjection = null;
|
|
183374
|
+
this.ensureTerminalChunk();
|
|
183292
183375
|
return explicitToolResult;
|
|
183293
183376
|
}
|
|
183294
183377
|
if (userMessage.startsWith("/")) {
|
|
@@ -183326,6 +183409,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
183326
183409
|
panelValue: `session:${payload}`
|
|
183327
183410
|
});
|
|
183328
183411
|
}
|
|
183412
|
+
this.ensureTerminalChunk();
|
|
183329
183413
|
return { ok: true, summary: `Handled ${userMessage}` };
|
|
183330
183414
|
}
|
|
183331
183415
|
if (commandResult.prompt) {
|
|
@@ -183336,6 +183420,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
183336
183420
|
if (handled) {
|
|
183337
183421
|
this.pendingMemoryContext = null;
|
|
183338
183422
|
this.pendingContextInjection = null;
|
|
183423
|
+
this.ensureTerminalChunk();
|
|
183339
183424
|
return { ok: true, summary: `Executed ${userMessage}` };
|
|
183340
183425
|
}
|
|
183341
183426
|
} else {
|
|
@@ -183350,6 +183435,7 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
183350
183435
|
panelValue: commandResult.panelValue
|
|
183351
183436
|
});
|
|
183352
183437
|
}
|
|
183438
|
+
this.ensureTerminalChunk();
|
|
183353
183439
|
return { ok: true, summary: `Handled ${userMessage}` };
|
|
183354
183440
|
}
|
|
183355
183441
|
if (commandResult.prompt) {
|
|
@@ -184196,7 +184282,15 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
184196
184282
|
}
|
|
184197
184283
|
return true;
|
|
184198
184284
|
}
|
|
184285
|
+
ensureTerminalChunk() {
|
|
184286
|
+
if (!this.emittedTerminalChunk) {
|
|
184287
|
+
this.emit({ type: "done" });
|
|
184288
|
+
}
|
|
184289
|
+
}
|
|
184199
184290
|
emit(chunk) {
|
|
184291
|
+
if (chunk.type === "done" || chunk.type === "error") {
|
|
184292
|
+
this.emittedTerminalChunk = true;
|
|
184293
|
+
}
|
|
184200
184294
|
this.onChunk?.(chunk);
|
|
184201
184295
|
}
|
|
184202
184296
|
async emitNotification(params) {
|
|
@@ -206275,6 +206369,8 @@ await init_src3();
|
|
|
206275
206369
|
|
|
206276
206370
|
// packages/terminal/src/hooks/useSafeInput.ts
|
|
206277
206371
|
var import_react27 = __toESM(require_react(), 1);
|
|
206372
|
+
var rawModeUsers = 0;
|
|
206373
|
+
var rawModeEnabled = false;
|
|
206278
206374
|
function parseKeypress2(s6) {
|
|
206279
206375
|
const key = { name: "", ctrl: false, shift: false, meta: false, option: false, sequence: s6 };
|
|
206280
206376
|
if (s6 === "\r" || s6 === `
|
|
@@ -206321,9 +206417,17 @@ function useSafeInput(handler, options = {}) {
|
|
|
206321
206417
|
import_react27.useEffect(() => {
|
|
206322
206418
|
if (!isRawModeSupported || !setRawMode)
|
|
206323
206419
|
return;
|
|
206324
|
-
|
|
206420
|
+
rawModeUsers += 1;
|
|
206421
|
+
if (!rawModeEnabled) {
|
|
206422
|
+
setRawMode(true);
|
|
206423
|
+
rawModeEnabled = true;
|
|
206424
|
+
}
|
|
206325
206425
|
return () => {
|
|
206326
|
-
|
|
206426
|
+
rawModeUsers = Math.max(0, rawModeUsers - 1);
|
|
206427
|
+
if (rawModeEnabled && rawModeUsers === 0) {
|
|
206428
|
+
setRawMode(false);
|
|
206429
|
+
rawModeEnabled = false;
|
|
206430
|
+
}
|
|
206327
206431
|
};
|
|
206328
206432
|
}, [isRawModeSupported, setRawMode]);
|
|
206329
206433
|
import_react27.useEffect(() => {
|
|
@@ -219183,6 +219287,11 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219183
219287
|
const [createName, setCreateName] = import_react46.useState("");
|
|
219184
219288
|
const [createDesc, setCreateDesc] = import_react46.useState("");
|
|
219185
219289
|
const [chatInput, setChatInput] = import_react46.useState("");
|
|
219290
|
+
const lastSubmitTimeRef = import_react46.useRef(0);
|
|
219291
|
+
const [mentionActive, setMentionActive] = import_react46.useState(false);
|
|
219292
|
+
const [mentionQuery, setMentionQuery] = import_react46.useState("");
|
|
219293
|
+
const [mentionIndex, setMentionIndex] = import_react46.useState(0);
|
|
219294
|
+
const [chatMembers, setChatMembers] = import_react46.useState([]);
|
|
219186
219295
|
const [inviteName, setInviteName] = import_react46.useState("");
|
|
219187
219296
|
const loadChannels = () => {
|
|
219188
219297
|
try {
|
|
@@ -219202,6 +219311,7 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219202
219311
|
setSelectedChannel(ch2);
|
|
219203
219312
|
const result = manager.readMessages(ch2.id, 50);
|
|
219204
219313
|
setMessages(result?.messages || []);
|
|
219314
|
+
setChatMembers(manager.getMembers(ch2.id));
|
|
219205
219315
|
setMode("chat");
|
|
219206
219316
|
}
|
|
219207
219317
|
};
|
|
@@ -219213,7 +219323,68 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219213
219323
|
setMode("members");
|
|
219214
219324
|
}
|
|
219215
219325
|
};
|
|
219326
|
+
const mentionCandidates = import_react46.useMemo(() => {
|
|
219327
|
+
if (!mentionActive)
|
|
219328
|
+
return [];
|
|
219329
|
+
const q7 = mentionQuery.toLowerCase();
|
|
219330
|
+
return chatMembers.filter((m5) => m5.assistantName.toLowerCase().includes(q7));
|
|
219331
|
+
}, [mentionActive, mentionQuery, chatMembers]);
|
|
219332
|
+
const handleChatInputChange = (value) => {
|
|
219333
|
+
const prev = chatInput;
|
|
219334
|
+
setChatInput(value);
|
|
219335
|
+
if (value.length === prev.length + 1 && value[value.length - 1] === "@" && !mentionActive) {
|
|
219336
|
+
setMentionActive(true);
|
|
219337
|
+
setMentionQuery("");
|
|
219338
|
+
setMentionIndex(0);
|
|
219339
|
+
return;
|
|
219340
|
+
}
|
|
219341
|
+
if (mentionActive) {
|
|
219342
|
+
const lastAt = value.lastIndexOf("@");
|
|
219343
|
+
if (lastAt >= 0) {
|
|
219344
|
+
const afterAt = value.slice(lastAt + 1);
|
|
219345
|
+
if (lastAt > prev.lastIndexOf("@") + prev.slice(prev.lastIndexOf("@") + 1).length + 1) {
|
|
219346
|
+
setMentionActive(false);
|
|
219347
|
+
} else {
|
|
219348
|
+
setMentionQuery(afterAt);
|
|
219349
|
+
setMentionIndex(0);
|
|
219350
|
+
}
|
|
219351
|
+
} else {
|
|
219352
|
+
setMentionActive(false);
|
|
219353
|
+
}
|
|
219354
|
+
}
|
|
219355
|
+
};
|
|
219356
|
+
const insertMention = (memberName) => {
|
|
219357
|
+
const lastAt = chatInput.lastIndexOf("@");
|
|
219358
|
+
if (lastAt >= 0) {
|
|
219359
|
+
const before = chatInput.slice(0, lastAt);
|
|
219360
|
+
const needsQuotes = memberName.includes(" ");
|
|
219361
|
+
const mention = needsQuotes ? `@"${memberName}" ` : `@${memberName} `;
|
|
219362
|
+
setChatInput(before + mention);
|
|
219363
|
+
}
|
|
219364
|
+
setMentionActive(false);
|
|
219365
|
+
setMentionQuery("");
|
|
219366
|
+
setMentionIndex(0);
|
|
219367
|
+
};
|
|
219216
219368
|
useSafeInput((input, key) => {
|
|
219369
|
+
if (mentionActive && mode === "chat") {
|
|
219370
|
+
if (key.escape) {
|
|
219371
|
+
setMentionActive(false);
|
|
219372
|
+
setMentionQuery("");
|
|
219373
|
+
return;
|
|
219374
|
+
}
|
|
219375
|
+
if (key.upArrow) {
|
|
219376
|
+
setMentionIndex((prev) => Math.max(0, prev - 1));
|
|
219377
|
+
return;
|
|
219378
|
+
}
|
|
219379
|
+
if (key.downArrow) {
|
|
219380
|
+
setMentionIndex((prev) => Math.min(mentionCandidates.length - 1, prev + 1));
|
|
219381
|
+
return;
|
|
219382
|
+
}
|
|
219383
|
+
if (key.tab && mentionCandidates.length > 0) {
|
|
219384
|
+
insertMention(mentionCandidates[mentionIndex].assistantName);
|
|
219385
|
+
return;
|
|
219386
|
+
}
|
|
219387
|
+
}
|
|
219217
219388
|
const isTextEntry = mode === "create-name" || mode === "create-desc" || mode === "invite" || mode === "chat";
|
|
219218
219389
|
if (key.escape || input === "q" && !isTextEntry) {
|
|
219219
219390
|
if (key.escape && mode === "list" || input === "q" && mode === "list") {
|
|
@@ -219222,6 +219393,7 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219222
219393
|
setMode("list");
|
|
219223
219394
|
setSelectedChannel(null);
|
|
219224
219395
|
setStatusMessage(null);
|
|
219396
|
+
setMentionActive(false);
|
|
219225
219397
|
}
|
|
219226
219398
|
return;
|
|
219227
219399
|
}
|
|
@@ -219307,7 +219479,7 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219307
219479
|
}, undefined, false, undefined, this),
|
|
219308
219480
|
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
|
|
219309
219481
|
color: "gray",
|
|
219310
|
-
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"
|
|
219482
|
+
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"
|
|
219311
219483
|
}, undefined, false, undefined, this)
|
|
219312
219484
|
]
|
|
219313
219485
|
}, undefined, true, undefined, this);
|
|
@@ -219449,13 +219621,18 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219449
219621
|
}, undefined, false, undefined, this),
|
|
219450
219622
|
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(build_default2, {
|
|
219451
219623
|
value: chatInput,
|
|
219452
|
-
onChange:
|
|
219624
|
+
onChange: handleChatInputChange,
|
|
219453
219625
|
onSubmit: () => {
|
|
219454
219626
|
if (chatInput.trim()) {
|
|
219627
|
+
const now2 = Date.now();
|
|
219628
|
+
if (now2 - lastSubmitTimeRef.current < 500)
|
|
219629
|
+
return;
|
|
219630
|
+
lastSubmitTimeRef.current = now2;
|
|
219455
219631
|
const msg = chatInput.trim();
|
|
219456
219632
|
const result = activePersonId && activePersonName ? manager.sendAs(selectedChannel.id, msg, activePersonId, activePersonName) : manager.send(selectedChannel.id, msg);
|
|
219457
219633
|
if (result.success) {
|
|
219458
219634
|
setChatInput("");
|
|
219635
|
+
setMentionActive(false);
|
|
219459
219636
|
const updated = manager.readMessages(selectedChannel.id, 50);
|
|
219460
219637
|
setMessages(updated?.messages || []);
|
|
219461
219638
|
if (activePersonId && activePersonName && onPersonMessage && selectedChannel) {
|
|
@@ -219485,9 +219662,40 @@ function ChannelsPanel({ manager, onClose, activePersonId, activePersonName, onP
|
|
|
219485
219662
|
}
|
|
219486
219663
|
}
|
|
219487
219664
|
},
|
|
219488
|
-
placeholder: "Type a message..."
|
|
219665
|
+
placeholder: "Type a message... (@ to mention)"
|
|
219489
219666
|
}, undefined, false, undefined, this)
|
|
219490
219667
|
]
|
|
219668
|
+
}, undefined, true, undefined, this),
|
|
219669
|
+
mentionActive && mentionCandidates.length > 0 && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
|
|
219670
|
+
flexDirection: "column",
|
|
219671
|
+
paddingX: 1,
|
|
219672
|
+
borderStyle: "single",
|
|
219673
|
+
borderColor: "yellow",
|
|
219674
|
+
marginTop: 0,
|
|
219675
|
+
children: [
|
|
219676
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
|
|
219677
|
+
color: "yellow",
|
|
219678
|
+
bold: true,
|
|
219679
|
+
children: "Members (Tab to select, Esc to dismiss)"
|
|
219680
|
+
}, undefined, false, undefined, this),
|
|
219681
|
+
mentionCandidates.slice(0, 8).map((m5, i5) => /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
|
|
219682
|
+
children: [
|
|
219683
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
|
|
219684
|
+
color: i5 === mentionIndex ? "blue" : undefined,
|
|
219685
|
+
children: i5 === mentionIndex ? "\u25B8 " : " "
|
|
219686
|
+
}, undefined, false, undefined, this),
|
|
219687
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
|
|
219688
|
+
bold: i5 === mentionIndex,
|
|
219689
|
+
color: i5 === mentionIndex ? "blue" : undefined,
|
|
219690
|
+
children: m5.assistantName
|
|
219691
|
+
}, undefined, false, undefined, this),
|
|
219692
|
+
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
|
|
219693
|
+
color: "gray",
|
|
219694
|
+
children: m5.memberType === "person" ? " [person]" : " [assistant]"
|
|
219695
|
+
}, undefined, false, undefined, this)
|
|
219696
|
+
]
|
|
219697
|
+
}, m5.assistantId, true, undefined, this))
|
|
219698
|
+
]
|
|
219491
219699
|
}, undefined, true, undefined, this)
|
|
219492
219700
|
]
|
|
219493
219701
|
}, undefined, true, undefined, this);
|
|
@@ -233699,18 +233907,20 @@ When done, report the result.`);
|
|
|
233699
233907
|
const isActiveMember = activeAssistantId && members.some((m5) => m5.assistantId === activeAssistantId && m5.memberType === "assistant");
|
|
233700
233908
|
const mentions = parseMentions(message);
|
|
233701
233909
|
let activeAssistantTargeted = true;
|
|
233702
|
-
if (mentions.length > 0
|
|
233910
|
+
if (mentions.length > 0) {
|
|
233703
233911
|
const assistantMembers = members.filter((m5) => m5.memberType === "assistant");
|
|
233704
233912
|
const knownNames = assistantMembers.map((m5) => ({ id: m5.assistantId, name: m5.assistantName }));
|
|
233705
233913
|
const resolved = mentions.map((m5) => resolveNameToKnown(m5, knownNames)).filter(Boolean);
|
|
233706
233914
|
if (resolved.length > 0) {
|
|
233707
233915
|
activeAssistantTargeted = resolved.some((r6) => r6.id === activeAssistantId);
|
|
233916
|
+
} else {
|
|
233917
|
+
activeAssistantTargeted = false;
|
|
233708
233918
|
}
|
|
233709
233919
|
}
|
|
233710
233920
|
if (isActiveMember && activeAssistantTargeted) {
|
|
233711
233921
|
const prompt = `[Channel Message] ${personName} posted in #${channelName}: "${message}"
|
|
233712
233922
|
|
|
233713
|
-
Respond in #${channelName} using channel_send. Be helpful and conversational.`;
|
|
233923
|
+
You are in a group channel with other assistants and people. Respond in #${channelName} using channel_send. Be helpful and conversational. You may reference or build on what other assistants have said.`;
|
|
233714
233924
|
activeSession?.client.send(prompt);
|
|
233715
233925
|
}
|
|
233716
233926
|
}
|
|
@@ -234504,7 +234714,7 @@ Interactive Mode:
|
|
|
234504
234714
|
// packages/terminal/src/index.tsx
|
|
234505
234715
|
var jsx_dev_runtime44 = __toESM(require_jsx_dev_runtime(), 1);
|
|
234506
234716
|
setRuntime(bunRuntime);
|
|
234507
|
-
var VERSION4 = "1.1.
|
|
234717
|
+
var VERSION4 = "1.1.19";
|
|
234508
234718
|
var SYNC_START = "\x1B[?2026h";
|
|
234509
234719
|
var SYNC_END = "\x1B[?2026l";
|
|
234510
234720
|
function enableSynchronizedOutput() {
|
|
@@ -234644,4 +234854,4 @@ export {
|
|
|
234644
234854
|
main
|
|
234645
234855
|
};
|
|
234646
234856
|
|
|
234647
|
-
//# debugId=
|
|
234857
|
+
//# debugId=BA4928B11FA139C964756E2164756E21
|