feat(agents): Tier 2 — AGENTS.md + per-session picker

Six builtin defaults (Code Reviewer, Debugger, Refactorer, Architect,
Security Auditor, Prompt Builder) with no model field so session.model
wins. Project root AGENTS.md parsed on demand with mtime cache; when
present, only its agents are shown. sessions.agent_id resolves per turn
into effective system prompt, temperature, and a tool whitelist applied
in inference. AgentPicker mounts in the ChatInput toolbar; SettingsDrawer
agent surface deferred to Batch 7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-16 20:06:51 +00:00
parent 934f739ca1
commit 92bd3b1cdf
16 changed files with 984 additions and 35 deletions

View File

@@ -18,10 +18,13 @@ interface Props {
sessionId: string;
chatId: string;
projectId: string;
// Batch 9: optional, threaded down to ChatInput's agent picker.
agentId?: string | null;
onAgentChange?: (agentId: string | null) => void | Promise<void>;
sessionChats?: import('@/api/types').Chat[];
}
export function ChatPane({ sessionId, chatId, projectId, sessionChats }: Props) {
export function ChatPane({ sessionId, chatId, projectId, agentId, onAgentChange, sessionChats }: Props) {
const stream = useSessionStream(sessionId);
const lastErrorRef = useRef<string | null>(null);
const [queue, setQueue] = useState<string[]>([]);
@@ -167,7 +170,14 @@ export function ChatPane({ sessionId, chatId, projectId, sessionChats }: Props)
<div className="relative">
<ChatContextPopover stats={contextStats} />
<ChatInput disabled={false} projectId={projectId} onSend={handleSend} onForceSend={streaming ? handleForceSend : undefined} />
<ChatInput
disabled={false}
projectId={projectId}
agentId={agentId}
onAgentChange={onAgentChange}
onSend={handleSend}
onForceSend={streaming ? handleForceSend : undefined}
/>
</div>
</div>
);