VeztaVezta
Architecture

Agent Chat

In-app AI chat agent — SSE streaming, DeepSeek models, MCP-shaped tool layer, safety guards, and conversation store

Vezta ships an in-app conversational agent (src/modules/agent/) that answers questions about markets, portfolios, and signals and — behind explicit confirmation and safety guards — can place and manage trades. It streams responses over SSE, calls an MCP-shaped tool layer, and persists conversations in Postgres.

Request Lifecycle

The client POSTs a message to POST /api/v1/agent/chat and consumes the reply as Server-Sent Events from GET /api/v1/agent/chat/:requestId/stream. POST /api/v1/agent/chat/resume re-attaches to an interrupted stream (for example after the user answers a confirmation card).

Queue Split (worker-ai)

When FF_AGENT_QUEUE_SPLIT=true, the chat loop runs on the dedicated worker-ai container (WORKER_DOMAIN=ai) over three BullMQ queues:

QueueRole
agent-requestRuns a new chat turn (plan → tool calls → stream)
agent-resumeResumes a turn after a tool / confirmation gate
agent-summarizeRolling conversation summarization for long threads

Events flow back to the API's SSE connection over a Redis-Streams substrate (AgentStreamBus), so the browser stays connected to the API container while work happens on the worker. Set FF_AGENT_QUEUE_SPLIT=false to run the loop in-process on the API container (fallback). A companion research-request queue (also on the ai domain) backs the heavier research pipeline.

Models

The agent uses DeepSeek via an OpenAI-compatible client (llm/llm-client.service.ts). The base URL and API key are supplied by environment variable (DEEPSEEK_BASE_URL, DEEPSEEK_API_KEY) — never hardcoded. Model tiers are registered in model-registry.service.ts; GET /api/v1/agent/models lists the models available to the client.

Tool Layer

Tools live in tools/handlers/ and are registered through ToolRegistryService in an MCP-shaped schema (tool-schemas.generator.ts). Handlers span read and guarded write categories:

  • Read / analysis: market, market-filter, search, events, calendar, leaderboard, tracker, watchlist, wallet-list, portfolio, aggregated-portfolio, analytics, ai-predictions, signals, arbitrage, chart, rewards, referral, notification, alerts, research, web, memory, backtest, analyst, assumptions, account-identity, account-settings.
  • Guarded write / action: trade, batch-trade, batch-cancel, batch-close, combo, copy-trade, strategy-create, strategy, funds-account, funds-wallet, share, pnl-card.

Free-text market references are resolved to concrete markets via market-resolver.service.ts.

Safety Layer

Every action tool passes through safety/ before execution:

GuardResponsibility
InjectionDetectorServiceDetects prompt-injection in tool inputs / retrieved content
ActionGuardServiceGates state-changing tools (trades, cancels) behind policy checks
FundsLeavingGuardServiceExtra scrutiny on anything that moves funds off-platform
PreconditionTrackerServiceEnsures required preconditions (balance, approvals, confirmations) hold
RateLimiterServicePer-domain rate limits (chat, search, research)

Conversation Store

Conversations persist across turns:

ModelPurpose
AgentConversationOne thread per user, with title + rolling summary
AgentMessageUser / assistant messages (AgentMessageStatus)
AgentToolCallPer-tool invocation record (AgentToolCallStatus)
AgentTradeMemoryRemembered trade context for follow-ups
AgentUserPreferencePer-user agent preferences

conversation/summarizer.service.ts compacts long threads; conversation-title.service.ts auto-titles; markdown-exporter.ts backs GET /agent/conversations/:id/export.

Endpoints

MethodPathPurpose
POST/api/v1/agent/chatStart a chat turn
GET/api/v1/agent/chat/:requestId/streamSSE stream of the turn
POST/api/v1/agent/chat/resumeResume an interrupted stream
GET/api/v1/agent/modelsList available models
GET / DELETE/api/v1/agent/preferences[/:id]Manage agent preferences
GET / DELETE / PATCH/api/v1/agent/conversations[/:id]List / delete / rename conversations
GET/api/v1/agent/conversations/:id/messagesFetch thread messages
GET/api/v1/agent/conversations/:id/exportExport thread as Markdown
POST/api/v1/agent/messages/:id/feedbackThumbs up / down on a reply
POST/api/v1/agent/transcribeVoice → text for voice input

A companion research module (ResearchController, /api/v1/research) runs a heavier structured probability-estimation pipeline over markets, sharing the same event bus and web-search primitives as the agent. See the Research API for its endpoints.

On this page