- deny quotes.re_run_ai (wipes every quote item); orders.cancel and delivery_notes.cancel/combine always ask; orders.archive is a read tool - classifyToolCall escalates writes that touch email/contact fields to confirm, with a reason stored on the pending tool use - system prompt: real cancel tools, SAST date - bridge rejects @collection./@request. filter references and path-shaped ids - agent: blank-text responses become the placeholder, duplicate pending ids answered once, clearer "result unavailable" wording - catalogue test checks the policy against the real MCP tool list Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
/**
|
|
* Shared Giellie types (server + client). Message blocks follow the
|
|
* Anthropic content-block shape but are kept loose (`Block`) because
|
|
* MiniMax also returns `thinking` blocks that must round-trip untouched.
|
|
*/
|
|
export type Block = { type: string; [key: string]: unknown };
|
|
|
|
/** Synthetic tool_result text when a tool_use has no recorded result. */
|
|
export const RESULT_UNAVAILABLE_TEXT =
|
|
"Result unavailable — this action may or may not have executed. Verify the current state (read the record) before retrying.";
|
|
|
|
export interface StoredMessage {
|
|
role: "user" | "assistant";
|
|
content: Block[];
|
|
ts: string;
|
|
}
|
|
|
|
export interface PendingToolUse {
|
|
id: string;
|
|
/** Dotted MCP name, e.g. `orders.update`. */
|
|
name: string;
|
|
input: Record<string, unknown>;
|
|
/** Sends, cancels/merges and contact-detail changes — the trust toggle never auto-approves these. */
|
|
confirmAlways: boolean;
|
|
/** Why this always asks (badge text). Absent on rows saved before it existed. */
|
|
confirmReason?: string;
|
|
}
|
|
|
|
export interface PendingAction {
|
|
tool_uses: PendingToolUse[];
|
|
/** tool_result blocks already produced this turn (read tools). */
|
|
completed: Block[];
|
|
/** Every tool_use id of the assistant turn, in original order. */
|
|
order: string[];
|
|
}
|
|
|
|
/**
|
|
* Identifies which pending approval a decision is for. Client and server
|
|
* compare it so a stale tab cannot approve a newer, different request.
|
|
*/
|
|
export function pendingFingerprint(p: PendingAction): string {
|
|
return p.order.join(",");
|
|
}
|
|
|
|
export interface GielieChatSummary {
|
|
id: string;
|
|
title: string;
|
|
updated: string;
|
|
}
|
|
|
|
export interface GielieChat extends GielieChatSummary {
|
|
messages: StoredMessage[];
|
|
pending_action: PendingAction | null;
|
|
attachments: string[];
|
|
}
|