Bind communication wakes to concrete inbox rows

Replace the worker's generic `"Continue."` default with a dispatch-time
`initialUserTurn` that is resolved per trigger. Message and peer-request
wakes now enumerate the actual unread messages (id, sender, channel,
subject, reply-to) so the agent's first user turn carries the entities
it is expected to act on, instead of idling into a status summary.

Drop the system-prompt `heartbeatFallbackSection`: its "respond with a
brief status summary" line fought the wake-reason block above it and
was the main reason communication wakes degraded into self-narration.
The wake-reason section plus the bound initial user turn now cover
every case that section was carrying.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-19 14:43:57 -04:00
1 parent e917c614c9
commit 271c6cfec8
7 files changed
+152 -14

No files matched your search

+2 -2
View File
@@ -6,8 +6,6 @@ export interface RunJob {
companyId: string;
/** Null for heartbeat runs with no assigned task. Must stay aligned with EnqueueRunPayload. */
taskId: string | null;
taskTitle: string;
taskDescription: string;
agentId: string;
agentName: string;
connectorId: string;
@@ -21,6 +19,8 @@ export interface RunJob {
trigger: string | null;
taskSessionId: string;
executionMode: "ai_ceo" | "ai_cofounder";
/** Seed user turn that kicks off the pi agent loop. Never empty. */
initialUserTurn: string;
}
/**
+4 -4
View File
@@ -182,10 +182,10 @@ export class WorkerRunner {
});
try {
const userMessage = job.taskTitle
? `${job.taskTitle}\n\n${job.taskDescription ?? ""}`.trim()
: (job.taskDescription ?? "");
const promptContent = userMessage.length > 0 ? userMessage : "Continue.";
const promptContent = job.initialUserTurn.trim();
if (promptContent.length === 0) {
throw new Error(`Run ${job.runId} has an empty initial user turn.`);
}
const promptMessage: AgentMessage = {
role: "user",
content: [{ type: "text", text: promptContent }],