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
@@ -51,7 +51,8 @@ export interface RuntimeMessageInjectorDeps {
|
||||
interface PendingSteer {
|
||||
recipientAgentId: string;
|
||||
companyId: string;
|
||||
messageId: string;
|
||||
runId: string;
|
||||
message: AgentMessageRecord;
|
||||
timer: ReturnType<typeof setTimeout>;
|
||||
}
|
||||
|
||||
@@ -116,7 +117,8 @@ export class RuntimeMessageInjector {
|
||||
this.pending.set(correlationId, {
|
||||
recipientAgentId,
|
||||
companyId,
|
||||
messageId: message.id,
|
||||
runId: ctx.runId,
|
||||
message,
|
||||
timer,
|
||||
});
|
||||
return true;
|
||||
@@ -145,17 +147,24 @@ export class RuntimeMessageInjector {
|
||||
|
||||
if (accepted) {
|
||||
try {
|
||||
this.deps.db.markAgentInboxDelivered(entry.recipientAgentId, [entry.messageId]);
|
||||
this.deps.runtimeBridge.registerInboundInjection(entry.runId, entry.message);
|
||||
} catch (error) {
|
||||
this.deps.logger.warn(
|
||||
`[injector] markAgentInboxDelivered failed for ${entry.messageId}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
`[injector] registerInboundInjection failed for ${entry.message.id}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
try {
|
||||
this.deps.db.markAgentInboxDelivered(entry.recipientAgentId, [entry.message.id]);
|
||||
} catch (error) {
|
||||
this.deps.logger.warn(
|
||||
`[injector] markAgentInboxDelivered failed for ${entry.message.id}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.deps.logger.warn(
|
||||
`[injector] steer rejected (${source}) for message ${entry.messageId} to agent ${entry.recipientAgentId}; falling back to wake + inbox projection`,
|
||||
`[injector] steer rejected (${source}) for message ${entry.message.id} to agent ${entry.recipientAgentId}; falling back to wake + inbox projection`,
|
||||
);
|
||||
|
||||
const wake = this.deps.getWakeAgent();
|
||||
|
||||
Reference in new issue
Block a user