Files
AgentCompany/src/main/prompt-builder/index.ts
T
2026-04-04 12:03:50 -04:00

162 lines
8.8 KiB
TypeScript

import type { AgentRecord, AgentMessageRecord, ApprovalRecord, DocumentRecord, ExecutionMode, GoalRecord, KnowledgeEntryRecord, MeetingRecord, ProjectRecord, SprintRecord, TaskRecord } from "@shared/types";
import type { AppLocale } from "@shared/locale";
import { buildSystemPrompt } from "./system-prompt";
export interface PromptContext {
agent: AgentRecord;
apiUrl: string;
apiKey: string;
runId: string;
task: TaskRecord | null;
companyName: string;
locale?: AppLocale;
/** Company execution mode: ai_ceo (fully autonomous) or ai_cofounder (human-reviewed) */
executionMode?: ExecutionMode;
goals: GoalRecord[];
projects: ProjectRecord[];
directReports: AgentRecord[];
chainOfCommand: AgentRecord[];
assignedTasks: TaskRecord[];
allAgents: AgentRecord[];
pendingApprovals: ApprovalRecord[];
tasksAwaitingReview: TaskRecord[];
wakeReason: string | null;
allTasks: TaskRecord[];
recentComments: Array<{ taskId: string; taskTitle: string; authorName: string; body: string; createdAt: string }>;
companyDescription: string;
socialAccounts: Array<{ id: string; platform: string; accountName: string; status: string; requireApproval: boolean }>;
recentMessages?: AgentMessageRecord[];
upcomingMeetings?: MeetingRecord[];
relevantKnowledge?: KnowledgeEntryRecord[];
activeSprint?: SprintRecord | null;
recentDocuments?: DocumentRecord[];
allConnectors?: Array<{ id: string; label: string; status: string; enabledModels?: string[] }>;
/** D-07: Handoff markdown from a rotated session, injected as context for the agent */
sessionHandoff?: string | null;
/** Names of skills injected into this agent's runtime environment */
skillNames?: string[];
/** Full skill entries with semantic metadata for capability manifest */
skillEntries?: Array<{ name: string; whenToUse: string; allowedTools: string[]; effort: string; contextMode: string }>;
/** All company documents for attachment content resolution in messages */
companyDocuments?: DocumentRecord[];
/** Company-wide skill catalog for capability-aware delegation. */
companySkillCatalog?: Array<{ name: string; slug: string; description: string | null }>;
/** Company workspaces visible to the current run. */
companyWorkspaces?: Array<{ name: string; localPath: string }>;
}
export function buildTaskPrompt(ctx: PromptContext): string {
const systemPrompt = buildSystemPrompt(ctx);
const parts: string[] = [systemPrompt];
if (ctx.wakeReason) {
const reasonMap: Record<string, string> = {
timer: `Regular heartbeat check-in. This is your periodic wake.
Action required:
1. Call GET /api/agents/me/standup to get your full briefing
2. Review all your assigned tasks and their statuses
3. Take action on the most important item: reviews > unblocking > new work
4. If nothing needs attention, post a brief status update on your current task`,
manual: `You were manually triggered by the human operator (Board).
Action required:
1. Check your assigned tasks for any new assignments or updated instructions
2. Check your messages for any direct communications
3. Execute any pending work with high priority — the Board is watching`,
assignment: `You have been assigned a new task.
Action required:
1. GET /api/companies/${ctx.agent.companyId}/issues?assigneeAgentId=${ctx.agent.id}&status=todo to find your new assignment
2. Review the task title, description, and any existing comments
3. POST /api/issues/{issueId}/checkout to claim the task
4. Begin working on it immediately according to your Operating Instructions`,
goal_activated: `A goal you own has been activated.
Action required:
1. GET /api/companies/${ctx.agent.companyId}/goals to find the newly activated goal
2. Decompose the goal into projects (POST /api/companies/${ctx.agent.companyId}/projects)
3. Break projects into actionable tasks and assign to your team
4. Leave a planning comment on each task explaining the approach`,
approval_resolved: `An approval you requested has been decided.
Action required:
1. GET /api/companies/${ctx.agent.companyId}/approvals?requestedByAgentId=${ctx.agent.id} to check the result
2. If APPROVED: proceed with the action you were waiting on (hiring, credential access, etc.)
3. If DENIED or REVISION_REQUESTED: read the feedback, adjust your approach, and resubmit if appropriate
4. Update the related task with the outcome`,
subtask_completed: `A subtask you delegated has been completed or moved to review.
Action required:
1. Check tasks with status "in_review" from your reports
2. Read ALL comments on the completed subtask (GET /api/issues/{issueId}/comments)
3. Review the work quality against the acceptance criteria you set
4. If acceptable: PATCH /api/issues/{issueId} with status "done" and an approving comment
5. If changes needed: PATCH /api/issues/{issueId} with status "in_progress" and specific feedback
6. Check if the parent task can now progress`,
comment: `A new comment has been posted on one of your tasks.
Action required:
1. Check your recent comments in the briefing above
2. If someone asked you a question: respond via POST /api/issues/{issueId}/comments
3. If your manager left feedback: address it and update the task
4. If it's a status update from a collaborator: acknowledge and adjust your work if needed`,
report_blocked: `One of your reports is blocked and needs your help.
Action required:
1. GET /api/companies/${ctx.agent.companyId}/issues?status=blocked to find blocked tasks under your reports
2. Read the blocker comments to understand what they need
3. Take action to unblock them:
- If they need credentials: create a secret_access approval via POST /api/companies/${ctx.agent.companyId}/approvals
- If they need cross-department help: send a message to the relevant department lead
- If they need clarification: post a comment with clear direction
4. After unblocking, wake the agent: POST /api/agents/{agentId}/wake with reason "blocker resolved"`,
report_failed: `A run by one of your reports has failed.
Action required:
1. Check your reports' task statuses for failed or stalled items
2. Investigate: read the task comments and any error information
3. Decide on next steps:
- If the task should be retried: set status back to "todo" with a comment explaining what to do differently
- If the task should be reassigned: change the assigneeAgentId to another capable report
- If the task is no longer needed: set status to "cancelled" with explanation
4. Wake the relevant agent to take action`,
message: `You received a direct message from another agent.
Action required:
1. GET /api/companies/${ctx.agent.companyId}/messages?unreadOnly=true to read your new messages
2. Read each message and understand what is being asked
3. Respond to each message using the exact sender and message IDs returned by the API:
- For direct messages, POST /api/companies/${ctx.agent.companyId}/messages with channel="direct", toAgentId set to the original message's fromAgentId, and parentMessageId set to that message's id
- If the sender is Board, the toAgentId is "__board__"
4. Mark messages as read: POST /api/companies/${ctx.agent.companyId}/messages/{messageId}/read
5. If the message requires you to take action on a task, do so`,
peer_request: `A peer agent has requested your attention.
Action required:
1. Check your messages: GET /api/companies/${ctx.agent.companyId}/messages?unreadOnly=true
2. Check for any new task assignments from outside your usual chain
3. Read and respond to the peer's request using the sender's fromAgentId and message id from the API response
4. If cross-department collaboration is needed, coordinate via messages and tasks`,
};
const explanation = reasonMap[ctx.wakeReason] ?? `Trigger: ${ctx.wakeReason}\nAction required: Check your standup briefing and messages for context on why you were woken.`;
parts.push(`\n# Wake Reason\n${explanation}\n`);
}
parts.push(`\n# Time Awareness
Consider what phase of operations the company is in and prioritize accordingly:
- Early in a sprint cycle → planning, task breakdown, delegation
- Mid-sprint → execution, unblocking, progress updates
- Late sprint → reviews, quality checks, retrospective preparation
- End of month → status reports, budget reviews, performance check-ins
- End of quarter → strategy reviews, goal setting, performance evaluations
`);
if (ctx.task) {
parts.push(`\n---\n\nYour immediate task:\n\nTitle: ${ctx.task.title}\nDescription: ${ctx.task.description || "No additional description."}\nPriority: ${ctx.task.priority}\n\nPlease execute this task according to your operating instructions.`);
} else {
parts.push(`\n---\n\nYou have been woken for a heartbeat check. Review your assigned tasks and active goals, then take appropriate action. If there's nothing to do, respond with a brief status summary.`);
}
return parts.join("");
}