feat: add governed chat agent selection

This commit is contained in:
thanhnv
2026-07-08 22:19:51 +09:00
parent 06d8d31b16
commit 004afa73c9
18 changed files with 677 additions and 39 deletions
@@ -108,6 +108,19 @@ export interface ChatAnswer {
};
action?: { id: string; label: string; description: string } | null;
action_gate?: { outcome?: string; reason?: string; exit_code?: number };
agent_binding?: {
success: boolean;
decision: string;
reason: string;
agent_selected: string;
skill_selected: string;
delegation_level: number;
model_role?: string;
mode?: string;
tool_allowlist: string[];
requires_approval: boolean;
audit?: { record_hash?: string; head?: string; seq?: number };
};
actor: SettingsActor;
}
@@ -118,6 +131,19 @@ export interface ChatAction {
triggers: string[];
}
export interface ChatAgent {
id: string;
label: string;
mode: string;
model_role: string;
roles_allowed: string[];
skills_allowed: string[];
tool_allowlist: string[];
max_delegation_level: number;
requires_approval?: boolean;
allowed_for_role?: boolean;
}
export interface SettingsState {
actor: SettingsActor;
capabilities: {
@@ -164,10 +190,11 @@ export const api = {
post<{ proposal: any; audit_verify: { ok: boolean; output: string } }>('approvals/submit', body, actorHeaders(actor)),
decideApproval: (actor: SettingsActor, body: { id: string; decision: 'approve' | 'reject'; reason: string }) =>
post<{ proposal: any; applied: any; audit_verify: { ok: boolean; output: string } }>('approvals/decide', body, actorHeaders(actor)),
askChat: (actor: SettingsActor, body: { message: string; chatId?: string }) =>
askChat: (actor: SettingsActor, body: { message: string; chatId?: string; agentId?: string; skillId?: string; delegationLevel?: number }) =>
post<ChatAnswer>('chat/ask', body, actorHeaders(actor)),
verifyChatAudit: () => get<{ ok: boolean; output: string }>('chat/audit/verify'),
chatActions: (actor: SettingsActor) => getWithHeaders<{ success: boolean; actions: ChatAction[] }>('chat/actions', actorHeaders(actor)),
chatAgents: (actor: SettingsActor) => getWithHeaders<{ success: boolean; agents: ChatAgent[] }>('chat/agents', actorHeaders(actor)),
};
// Health is raw (not enveloped) + carries HTTP status.