Write thread events for taskless communication runs
recordThreadEvent used to drop the event whenever `envelope.taskId` was null, so communication wakes produced nothing in the thread view even while the agent actively replied to peers. Taskless runs now write into a per-agent general thread (`ensureAgentCommunicationThread`), so the UI surfaces peer conversations alongside task activity. Peer-authored user turns inside the transcript used to be labelled with the recipient's id — pi erases the sender once the message is projected. A new `inboundCorrelations` map on `RuntimeBridge` pins each pi-message timestamp to its source `agent_messages` row at injection time, so the thread-event writer can recover the real author id and `senderKind` on `message_end`. prepareRun projections (no `message_end` fires for priorMessages) write their thread event directly as the projection lands so they are not silently lost.
This commit is contained in:
1 parent
1959d218d9
commit
1b8e6d384a
3 files changed
+250
-41
No files matched your search
@@ -35,6 +35,42 @@ export function ensureTaskThread(db: AppDatabase, taskId: string, companyId: str
|
||||
});
|
||||
}
|
||||
|
||||
export function findAgentCommunicationThread(db: AppDatabase, agentId: string, companyId: string) {
|
||||
const existing = db.listThreads({
|
||||
companyId,
|
||||
type: "general" as ThreadType,
|
||||
relatedEntityType: "agent",
|
||||
relatedEntityId: agentId,
|
||||
limit: 1,
|
||||
});
|
||||
return existing[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns (or creates) the single "general" thread that accumulates an
|
||||
* agent's taskless communication activity. Task runs already write into
|
||||
* a task-scoped thread; taskless communication runs would otherwise drop
|
||||
* their conversation events on the floor, leaving the thread view blank
|
||||
* even while the agent actively replies to peers.
|
||||
*/
|
||||
export function ensureAgentCommunicationThread(
|
||||
db: AppDatabase,
|
||||
agentId: string,
|
||||
companyId: string,
|
||||
agentLabel: string,
|
||||
) {
|
||||
const existing = findAgentCommunicationThread(db, agentId, companyId);
|
||||
if (existing) return existing;
|
||||
|
||||
return db.createThread({
|
||||
companyId,
|
||||
title: `${agentLabel} · communication`,
|
||||
type: "general" as ThreadType,
|
||||
relatedEntityType: "agent",
|
||||
relatedEntityId: agentId,
|
||||
});
|
||||
}
|
||||
|
||||
export function findApprovalThread(db: AppDatabase, approvalId: string, companyId: string) {
|
||||
const existing = db.listThreads({
|
||||
companyId,
|
||||
|
||||
Reference in new issue
Block a user