fix(api): route group follow-ups to the waiting member bot
Group threads/followUp always steered to members[0], so a follow-up while a later member had waiting_input went to the wrong bot or started a fresh run on the first member instead of continuing the ask. Resolve the target bot like group sends: prefer waiting ask/takeover on any member, then the newest steerable active run, then @mentions, then the default first member. Extract followUpGroupThreadMessage and add regression tests. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
This commit is contained in:
parent
44d1bc7277
commit
f5265924ba
@ -180,6 +180,7 @@ import {
|
||||
shouldForwardPeerThreadEvent,
|
||||
} from "./thread-message-pages.js";
|
||||
import {
|
||||
followUpGroupThreadMessage,
|
||||
reactToThreadMessage,
|
||||
resolveThreadTarget,
|
||||
sendThreadMessage,
|
||||
@ -1543,79 +1544,8 @@ export function createRouter(deps: RouterDeps) {
|
||||
}
|
||||
return { ok: true as const };
|
||||
}
|
||||
const committed = await deps.prisma.$transaction(async (tx) => {
|
||||
await lockOwnedGroup(tx, context.actor, target.groupId);
|
||||
const group = await tx.chatGroup.findFirst({
|
||||
where: {
|
||||
id: target.groupId,
|
||||
archivedAt: null,
|
||||
thread: { id: target.threadId },
|
||||
},
|
||||
include: { members: { orderBy: { createdAt: "asc" } } },
|
||||
});
|
||||
const botId = group?.members[0]?.botId;
|
||||
if (!botId) throw new IsolationError();
|
||||
const blocks = [{ kind: "text" as const, text: input.text }];
|
||||
const message = await createThreadMessageInTransaction(tx, {
|
||||
threadId: target.threadId,
|
||||
role: "user",
|
||||
blocks,
|
||||
});
|
||||
const active = await tx.run.findFirst({
|
||||
where: {
|
||||
threadId: target.threadId,
|
||||
botId,
|
||||
status: { in: [...ACTIVE_RUN_STATUSES] },
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
let run: { id: string } | null = null;
|
||||
if (!active) {
|
||||
const task = await tx.task.create({
|
||||
data: {
|
||||
spaceId: context.actor.spaceId,
|
||||
botId,
|
||||
threadId: target.threadId,
|
||||
userId: context.actor.userId,
|
||||
prompt: input.text,
|
||||
status: "queued",
|
||||
},
|
||||
});
|
||||
run = await tx.run.create({
|
||||
data: {
|
||||
spaceId: context.actor.spaceId,
|
||||
botId,
|
||||
threadId: target.threadId,
|
||||
taskId: task.id,
|
||||
userId: context.actor.userId,
|
||||
status: "queued",
|
||||
trigger: "follow_up",
|
||||
sourceMessageId: message.id,
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
await tx.message.update({ where: { id: message.id }, data: { runId: run.id } });
|
||||
} else {
|
||||
await tx.steeringMessage.create({
|
||||
data: {
|
||||
messageId: message.id,
|
||||
botId,
|
||||
userId: context.actor.userId,
|
||||
runId: active.id,
|
||||
},
|
||||
});
|
||||
await tx.message.update({ where: { id: message.id }, data: { runId: active.id } });
|
||||
}
|
||||
const event = await appendEventInTransaction(tx, {
|
||||
spaceId: context.actor.spaceId,
|
||||
threadId: target.threadId,
|
||||
botId,
|
||||
type: "thread.message.created",
|
||||
runId: run?.id ?? active?.id,
|
||||
payload: { messageId: message.id, role: "user", blocks },
|
||||
});
|
||||
await touchGroupUpdatedAt(tx, target.groupId);
|
||||
return { runId: run?.id, eventSeq: event.seq };
|
||||
const committed = await followUpGroupThreadMessage(deps, context.actor, target, {
|
||||
text: input.text,
|
||||
});
|
||||
await deps.events.notify(target.threadId, committed.eventSeq).catch((error) => {
|
||||
getLogger().error("group follow-up realtime notification", error);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user