Inject chat thread context into agent task prompts
When a task_run is triggered by a chat @mention, the agent now receives the full thread transcript (up to 20 messages) in its prompt so it understands what it is replying to and can use the correct thread_id.
This commit is contained in:
1 parent
44f31b49fb
commit
477a0dff4a
1 file changed
+42
@@ -89,6 +89,11 @@ interface TaskRunIsolation {
|
|||||||
secretScopeJson: string;
|
secretScopeJson: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ChatContextBlock {
|
||||||
|
threadId: string;
|
||||||
|
transcript: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface RunRow {
|
interface RunRow {
|
||||||
task_id: string;
|
task_id: string;
|
||||||
agent_id: string;
|
agent_id: string;
|
||||||
@@ -170,6 +175,7 @@ export class TaskExecutionService {
|
|||||||
taskGoalId: task.goal_id,
|
taskGoalId: task.goal_id,
|
||||||
workspace: workspace ? { id: workspace.id, localPath: workspace.local_path } : null,
|
workspace: workspace ? { id: workspace.id, localPath: workspace.local_path } : null,
|
||||||
};
|
};
|
||||||
|
const chatContext = this.loadChatContext(orgId, isolation);
|
||||||
const result = await runAgentLoop(
|
const result = await runAgentLoop(
|
||||||
{ providers: this.providers, tools: { db: this.db, organization: this.organization, chat: this.chat } },
|
{ providers: this.providers, tools: { db: this.db, organization: this.organization, chat: this.chat } },
|
||||||
{
|
{
|
||||||
@@ -189,6 +195,7 @@ export class TaskExecutionService {
|
|||||||
isManager: !agent.manager_agent_id,
|
isManager: !agent.manager_agent_id,
|
||||||
hasReports: this.agentHasReports(orgId, agent.id),
|
hasReports: this.agentHasReports(orgId, agent.id),
|
||||||
managerName: this.agentName(orgId, agent.manager_agent_id),
|
managerName: this.agentName(orgId, agent.manager_agent_id),
|
||||||
|
chatContext,
|
||||||
}),
|
}),
|
||||||
toolContext,
|
toolContext,
|
||||||
},
|
},
|
||||||
@@ -381,6 +388,31 @@ export class TaskExecutionService {
|
|||||||
return runId;
|
return runId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadChatContext(orgId: string, isolation: TaskRunIsolation): ChatContextBlock | null {
|
||||||
|
let scope: { sourceMessageId?: string; sourceThreadId?: string };
|
||||||
|
try {
|
||||||
|
scope = JSON.parse(isolation.secretScopeJson);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!scope.sourceThreadId) return null;
|
||||||
|
const messages = this.db.prepare(`
|
||||||
|
select m.body_md, m.sender_type, m.sender_id,
|
||||||
|
coalesce(a.name, e.display_name, m.sender_type) as sender_name
|
||||||
|
from chat_messages m
|
||||||
|
left join agents a on a.id = m.sender_id and m.sender_type = 'agent'
|
||||||
|
left join employees e on e.id = m.sender_id and m.sender_type = 'employee'
|
||||||
|
where m.thread_id = ? and m.org_id = ?
|
||||||
|
order by m.created_at asc
|
||||||
|
limit 20
|
||||||
|
`).all(scope.sourceThreadId, orgId) as Array<{ body_md: string; sender_type: string; sender_name: string }>;
|
||||||
|
if (messages.length === 0) return null;
|
||||||
|
return {
|
||||||
|
threadId: scope.sourceThreadId,
|
||||||
|
transcript: messages.map((m) => `[${m.sender_name}]: ${m.body_md}`).join("\n"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private agentHasReports(orgId: string, agentId: string): boolean {
|
private agentHasReports(orgId: string, agentId: string): boolean {
|
||||||
const row = this.db.prepare("select 1 from agents where org_id = ? and manager_agent_id = ? and lifecycle = 'active' limit 1")
|
const row = this.db.prepare("select 1 from agents where org_id = ? and manager_agent_id = ? and lifecycle = 'active' limit 1")
|
||||||
.get(orgId, agentId);
|
.get(orgId, agentId);
|
||||||
@@ -500,6 +532,7 @@ function buildTaskPrompt(input: {
|
|||||||
isManager: boolean;
|
isManager: boolean;
|
||||||
hasReports: boolean;
|
hasReports: boolean;
|
||||||
managerName: string | null;
|
managerName: string | null;
|
||||||
|
chatContext: ChatContextBlock | null;
|
||||||
}): string {
|
}): string {
|
||||||
const lines = [
|
const lines = [
|
||||||
"Execute this AgentCompany task.",
|
"Execute this AgentCompany task.",
|
||||||
@@ -539,6 +572,15 @@ function buildTaskPrompt(input: {
|
|||||||
`Skill revisions: ${input.skillRuntimeSnapshot.source_revision_ids}`,
|
`Skill revisions: ${input.skillRuntimeSnapshot.source_revision_ids}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (input.chatContext) {
|
||||||
|
lines.push(
|
||||||
|
"",
|
||||||
|
"Chat thread you are replying to:",
|
||||||
|
input.chatContext.transcript,
|
||||||
|
"",
|
||||||
|
`Reply in this thread by passing thread_id="${input.chatContext.threadId}" to send_message.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (input.isManager && !input.hasReports) {
|
if (input.isManager && !input.hasReports) {
|
||||||
lines.push(
|
lines.push(
|
||||||
"",
|
"",
|
||||||
|
|||||||
Reference in new issue
Block a user