Systematic rename of all semantic anchors (#region, [DEF], @RELATION) across 1400+ files — backend Python, frontend Svelte/TS, specs, docs: - Flat anchors become Namespace.Module.Entity - @RELATION references updated to match new anchor paths - Zero business logic changes
4.4 KiB
#region Spec.AgentChatContext.DataModel [C:3] [TYPE ADR] [SEMANTICS data-model,agent-chat,schema] @defgroup DataModel Data structures for 035-agent-chat-context — frontend TypeScript DTOs and backend Python counterparts. @RATIONALE Updated for Path B (/agent page), Gradio payload safety, two-layer RBAC, and permission_denied event type.
1. UIContext — Navigation Context Payload
Source
Derived from URL query parameters on /agent page entry. Static for visit duration. EnvId syncable via updateActiveEnv.
TypeScript (frontend/src/lib/models/AgentChatTypes.ts)
export interface UIContext {
objectType: "dashboard" | "dataset" | "migration" | null;
objectId: string | null;
objectName: string | null; // max 256 chars
envId: string | null; // synced with EnvSelector via updateActiveEnv
route: string; // source page route (e.g. "/dashboards/42")
contextVersion: number; // currently 1
}
Python validation (backend/src/agent/_context.py — NEW)
# UIContext validation rules:
# objectType: must be one of ("dashboard","dataset","migration",None)
# objectId: must be numeric string or None
# objectName: max 256 chars
# envId: string or None
# route: string, max 512 chars
# contextVersion: positive integer ≤ 1
# Max payload size: 4 KB (413 Payload Too Large if exceeded)
2. ConfirmMetadataV2 — SSE confirm_required Event
{
"metadata": {
"type": "confirm_required",
"thread_id": "uuid",
"tool_name": "deploy_dashboard",
"tool_args": {"env_id": "prod", "dashboard_id": 42},
"risk": "write",
"risk_level": "guarded",
"dangerous": false,
"env_context": "prod",
"prompt": "⚠️ Изменение данных в production",
"requires_confirmation": true
}
}
Env resolution rule (canonical):
tool_args.env_id(tool-targeted environment)- Submit-time
envIdparameter (position 5 in Gradio args) UIContext.envId(from URL params)null(no environment)
Env normalization: env_id containing "prod"/"production" → "prod"; "stag"/"test" → "staging"; "dev"/"local" → "dev". Unknown values → null.
3. PermissionDeniedMetadata — SSE permission_denied Event (NEW)
{
"metadata": {
"type": "permission_denied",
"tool_name": "deploy_dashboard",
"required_role": "admin",
"user_role": "analyst",
"alternatives": [
{"action": "get_health_summary", "prompt": "Запросить отчёт о состоянии дашборда"}
]
}
}
Distinct from confirm_required: This event BYPASSES HITL checkpoint. Frontend renders permission-denied card with «Закрыть» button — no confirm. Emitted at invocation-time guard (AgentChat.ToolFilter.InvocationGuard).
4. New SSE Event Types
| Event | When | Fields |
|---|---|---|
permission_denied |
Tool invocation rejected by RBAC guard | tool_name, required_role, user_role, alternatives |
tool_retry |
Read-only tool auto-retrying | tool, attempt, max_attempts |
tool_timeout |
Tool exceeded 30s timeout | tool, timeout_seconds, is_write_tool, retryable |
tool_timeout (extended)
{"metadata":{"type":"tool_timeout","tool":"superset_explore_database","timeout_seconds":30,"is_write_tool":false,"retryable":true}}
For write tools (is_write_tool=true): retryable=false, frontend shows "Operation status unknown — check Superset" (no retry button).
5. AgentChatModel — New Atoms (v2)
// ADD to AgentChatModel class:
uiContext: UIContext | null = $state(null);
dangerousCountdown: number = $state(0);
dangerousCountdownActive: boolean = $state(false);
_activeEnvId: string | null = $state(null);
permissionAlternatives: Array<{ action: string; prompt: string }> | null = $state(null);
// ADD derived:
isProdContext: boolean = $derived(...);
showProdWarning: boolean = $derived(...);
contextPillLabel: string = $derived(...);
// updateActiveEnv now syncs BOTH atoms:
updateActiveEnv(envId: string | null): void {
this._activeEnvId = envId;
if (this.uiContext) this.uiContext.envId = envId;
}
REMOVED: toolAffinity atom (debug data must come from backend SSE, not frontend reconstruction).
6. Existing DB Models — No Changes
No new tables, no schema migrations. Context not persisted in conversations.
#endregion Spec.AgentChatContext.DataModel