Q11: deleted messages and withdrawn commands never reach the model

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 03:47:57 -04:00
1 parent 31ab919334
commit 22632a4695
8 files changed
+91 -28

No files matched your search

+5 -20
View File
@@ -150,10 +150,13 @@ export class ChatAgentWakeService {
const targetId = this.requireAgentMention(mentions);
const agent = this.requireRunnableAgent(input.orgId, targetId, "Slash command /agent");
const workspace = this.workspaceForAgent(input.orgId, agent.workspace_id);
const from = this.principalName(input.orgId, input.senderType, input.senderId);
const space = this.spaceRow(input.orgId, input.spaceId);
const direct = space.space_type === "direct";
const taskId = this.organization.createTask({
orgId: input.orgId,
title: this.taskTitle(agent.name, slash),
description: this.taskDescription(input, slash, messageId, threadId),
title: direct ? `Reply to ${from}` : `Reply to ${from} in #${space.name}`,
description: this.mentionTaskDescription(from, space.name, direct),
status: TASK_STATUS.BACKLOG,
assigneeAgentId: agent.id,
risk: RISK_LEVEL.LOW,
@@ -290,12 +293,6 @@ export class ChatAgentWakeService {
`).run("agent", agentId, "thinking", slash.args.trim().slice(0, 160), now);
}
private taskTitle(agentName: string, slash: SlashInvocation): string {
const details = slash.args.replace(/^@[^\s]+\s*/, "").trim();
const title = details || `reply as ${agentName}`;
return `Chat mention: ${title.length > 64 ? `${title.slice(0, 61)}...` : title}`;
}
private mentionTaskDescription(from: string, channel: string, direct: boolean): string {
const where = direct
? `${from} messaged you directly; their full message is in the thread below.`
@@ -328,16 +325,4 @@ export class ChatAgentWakeService {
if (!row) throw new Error("Chat space was not found.");
return row;
}
private taskDescription(input: SendMessageInput, slash: SlashInvocation, messageId: string, threadId: string): string {
return [
`Chat command: /agent ${slash.args.trim()}`,
`Source message: ${messageId}`,
`Source thread: ${threadId}`,
`Source space: ${input.spaceId}`,
`Sender: ${input.senderType}${input.senderId ? `:${input.senderId}` : ""}`,
"",
"Reply in the source thread with send_message and pass the thread_id above.",
].join("\n");
}
}
+5 -4
View File
@@ -30,15 +30,16 @@ export function loadChatWakeContext(db: DatabaseSync, orgId: string, agentId: st
if (!thread) throw new Error(`Chat wake thread ${scope.sourceThreadId} no longer exists.`);
const lastReplyAt = (db.prepare(`
select coalesce(max(created_at), '') as at from chat_messages
where thread_id = ? and org_id = ? and sender_type = 'agent' and sender_id = ?
where thread_id = ? and org_id = ? and sender_type = 'agent' and sender_id = ? and deleted_at is null
`).get(scope.sourceThreadId, orgId, agentId) as { at: string }).at;
const isFresh = `not (m.sender_type = 'agent' and m.sender_id = ?) and (m.created_at > ? or coalesce(m.edited_at, '') > ?)`;
const inThread = "m.thread_id = ? and m.org_id = ? and m.deleted_at is null";
const args = [scope.sourceThreadId, orgId, agentId, lastReplyAt, lastReplyAt];
const fresh = db.prepare(`${MESSAGE_SELECT} where m.thread_id = ? and m.org_id = ? and ${isFresh} order by m.created_at asc`)
const fresh = db.prepare(`${MESSAGE_SELECT} where ${inThread} and ${isFresh} order by m.created_at asc`)
.all(...args) as unknown as ThreadMessageRow[];
const history = (db.prepare(`${MESSAGE_SELECT} where m.thread_id = ? and m.org_id = ? and not (${isFresh}) order by m.created_at desc limit ?`)
const history = (db.prepare(`${MESSAGE_SELECT} where ${inThread} and not (${isFresh}) order by m.created_at desc limit ?`)
.all(...args, HISTORY_LIMIT) as unknown as ThreadMessageRow[]).reverse();
const historyTotal = (db.prepare(`select count(*) as n from chat_messages m where m.thread_id = ? and m.org_id = ? and not (${isFresh})`)
const historyTotal = (db.prepare(`select count(*) as n from chat_messages m where ${inThread} and not (${isFresh})`)
.get(...args) as { n: number }).n;
if (fresh.length === 0 && history.length === 0) return null;
const omitted = historyTotal - history.length;