feat: add governed chat console

This commit is contained in:
thanhnv
2026-07-08 21:14:40 +09:00
parent 3be9970c15
commit 5561bcf864
28 changed files with 2023 additions and 43 deletions
@@ -78,6 +78,46 @@ export interface CommandCenterState extends Freshness {
ticker: Array<{ at: string | null; kind: string; text: string; status: string }>;
}
export interface ChatSource {
path: string;
title?: string;
line?: number;
excerpt?: string;
score: number;
hash?: string;
preview?: string;
envelope?: CommandEnvelope;
}
export interface ChatAnswer {
success: boolean;
mode: 'READ_ONLY' | 'OPERATOR' | 'BLOCK' | 'NOT_SUPPORTED' | string;
risk: string;
decision: 'ANSWERED' | 'ACTION_COMPLETED' | 'ACTION_FAILED' | 'REQUIRES_APPROVAL' | 'DENIED' | 'NOT_SUPPORTED' | string;
answer: string;
sources: ChatSource[];
certified: boolean;
audit: { hash?: string; record_hash?: string; head?: string; seq?: number; path?: string };
audit_verify: { ok: boolean; output: string };
router: {
reason?: string;
matched_rules?: string[];
gates?: string[];
side_effect_allowed?: boolean;
needs_approval?: boolean;
};
action?: { id: string; label: string; description: string } | null;
action_gate?: { outcome?: string; reason?: string; exit_code?: number };
actor: SettingsActor;
}
export interface ChatAction {
id: string;
label: string;
description: string;
triggers: string[];
}
export interface SettingsState {
actor: SettingsActor;
capabilities: {
@@ -124,6 +164,10 @@ 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 }) =>
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)),
};
// Health is raw (not enveloped) + carries HTTP status.