This commit is contained in:
2026-09-23 17:25:09 +05:30
parent 8537b09f33
commit f3fe53d2ac
2 changed files with 246 additions and 8 deletions

View File

@@ -20,6 +20,26 @@ export interface AssistantStep {
scope?: string;
}
/** One line on an approval card: what is about to change, in checkable detail. */
export interface ProposalDetail {
label: string;
value: string;
}
/**
* A change Buddy has resolved and is waiting on a person for.
*
* Nothing has happened when this arrives. The `card` is signed by the server
* and opaque here — the console sends it back unchanged, and anything the
* browser altered stops it verifying.
*/
export interface Proposal {
summary: string;
details?: ProposalDetail[];
warning?: string;
card: string;
}
export interface AssistantAnswer {
reply: string;
used?: AssistantStep[];
@@ -32,6 +52,8 @@ export interface AssistantAnswer {
* spinner — but it must not be presented as the whole story.
*/
incomplete?: boolean;
/** Set when a change is resolved and waiting. One card, never a list. */
awaiting?: Proposal;
}
/**
@@ -64,3 +86,16 @@ export async function assistantAvailable(): Promise<boolean> {
export async function askAssistant(agent: string, question: string): Promise<AssistantAnswer> {
return api.post<AssistantAnswer>(`${WEB}/assistant/ask`, { agent, question });
}
/**
* Perform a change the person has agreed to.
*
* A separate call with no question in it, because it is a different act: the
* card names the action and the session names the person, and no model is
* consulted. The server re-checks both against the live database before writing
* — so this can legitimately fail with "somebody already approved that", which
* is an answer rather than an error.
*/
export async function approveAssistant(agent: string, card: string): Promise<AssistantAnswer> {
return api.post<AssistantAnswer>(`${WEB}/assistant/approve`, { agent, card });
}