91 lines
2.8 KiB
Markdown
91 lines
2.8 KiB
Markdown
#region AgentChat.DataModel [C:3] [TYPE ADR] [SEMANTICS data-model,agent-chat,final]
|
|
@BRIEF Final data model — structured JSON metadata, PostgreSQL checkpointer, dual-identity RBAC, no custom WebSocket types.
|
|
|
|
## 1. Streaming Metadata Protocol
|
|
|
|
Each `event.data` is a `ChatMessage` with optional structured `metadata`:
|
|
|
|
```typescript
|
|
interface StreamMetadata {
|
|
type?: "stream_token" | "tool_start" | "tool_end" | "tool_error"
|
|
| "confirm_required" | "confirm_resolved" | "error";
|
|
token?: string;
|
|
tool?: string;
|
|
input?: Record<string, unknown>;
|
|
output?: Record<string, unknown>;
|
|
error?: string;
|
|
prompt?: string;
|
|
thread_id?: string;
|
|
result?: "confirmed" | "denied";
|
|
code?: string;
|
|
detail?: string;
|
|
}
|
|
```
|
|
|
|
No `agent-ws.ts`. No custom WebSocket types. No emoji prefix parsing.
|
|
|
|
## 2. SQLAlchemy
|
|
|
|
Tables: `agent_conversations`, `agent_messages`. Legacy `assistant_messages` preserved.
|
|
|
|
## 3. Pydantic Schemas
|
|
|
|
`ConversationItem`, `ConversationListResponse`, `MessageItem`, `HistoryResponse`, `DeleteResponse`.
|
|
|
|
## 4. TypeScript DTOs
|
|
|
|
`frontend/src/types/agent.ts` — matches Pydantic schemas. Includes `StreamMetadata`.
|
|
|
|
## 4a. Frontend Screen-State Derivations
|
|
|
|
`AgentChatModel` owns operator-only derived state. These fields are not persisted and do not cross the API boundary:
|
|
|
|
```typescript
|
|
type AgentProcessStepState = "done" | "active" | "blocked" | "idle";
|
|
|
|
interface AgentProcessStep {
|
|
id: "context" | "reasoning" | "tools" | "confirmation" | "result";
|
|
label: string;
|
|
state: AgentProcessStepState;
|
|
}
|
|
```
|
|
|
|
Derived state:
|
|
|
|
- `hasSilentStream`: `streaming` with no token, no tool call, no confirmation/checkpoint.
|
|
- `userFacingStatusTitle` / `userFacingStatusDetail`: operator-readable status copy.
|
|
- `processSteps`: UI process strip; currently inferred from stream/tool/confirmation/error state.
|
|
- `cleanVisibleMessageText(rawText)`: strips hidden runtime/prefetch/upload context before rendering or retrying.
|
|
|
|
## 5. PostgreSQL Checkpointer
|
|
|
|
LangGraph checkpointer: `langgraph-checkpoint-postgres`. Thread ID = conversation_id. Survives container restarts. Same PostgreSQL instance as FastAPI.
|
|
|
|
## 6. Dual Identity RBAC
|
|
|
|
```
|
|
Authorization: Bearer {service_jwt}
|
|
X-User-JWT: {user_jwt}
|
|
```
|
|
|
|
Audit: `{service_actor: "agent", user_actor: user_id}`.
|
|
|
|
## 7. Hidden Runtime Context
|
|
|
|
The backend may prepend hidden runtime context to the LLM-facing message. This is not a persisted message field.
|
|
|
|
```text
|
|
[RUNTIME CONTEXT]
|
|
Current datetime: <ISO>
|
|
Environment: <env_id>
|
|
Rules: interpret now/start/duration from current datetime...
|
|
Dashboards: compact bounded prefetch...
|
|
[/RUNTIME CONTEXT]
|
|
|
|
<visible user text>
|
|
```
|
|
|
|
Persistence invariant: `agent_messages.text`, title generation input, and frontend-rendered user bubbles use the visible user text only.
|
|
|
|
#endregion AgentChat.DataModel
|