Skip to content

Backend Architecture

RTC Agent consists of two Go services: the Main Server handles AI reasoning orchestration, context management, real-time communication, tool call scheduling, and object storage; the Admin-server is an independent management service providing administrator authentication, user management, and other functions, integrated with the Main Server via RFC 8693 Token Exchange.

LayerResponsibilityKey Modules
🌐 Access LayerProtocol adaptation, authentication & authorizationWebSocket Gateway, OAuth2 Handler, Token Exchange
📋 Use Case LayerBusiness orchestration, RPC processingSession / Message / Turn / RTC use cases
🤖 Domain LayerAI reasoning, state managementAgent Engine, Context Management, Memory System
💾 Infrastructure LayerData persistence, message passing, object storagePostgreSQL, Redis, Centrifuge, MinIO/S3
🔐 Admin-serverAdministrator authentication, user managementJWT signing (RS256/ES256/EdDSA), JWKS endpoint, Admin UI

Authentication System: The Main Server uses OAuth2 authorization code flow for end users; Admin-server uses email/password login for service administrators. Administrators obtain JWTs from Admin-server, which can be recognized by the Main Server via RFC 8693 Token Exchange. See Authentication Flow and HTTP API.

The Gateway is the entry point for frontend-backend communication, managing all WebSocket connections and RPC routing.

ResponsibilityDescription
Connection ManagementHandles WebSocket connection establishment, authentication, heartbeats, and disconnection
RPC RoutingDispatches the 17 RPC methods to their corresponding use case handlers
Event PushPushes events generated by the Agent to the frontend via Centrifuge
RTC RelayForwards AI tool call requests to the frontend and receives execution results

17 RPC Methods by Category:

CategoryMethods
Sessionv1.session.list, v1.session.get, v1.session.open, v1.session.close, v1.session.update, v1.session.fork, v1.session.compact
Messagev1.message.send, v1.message.list, v1.message.get
Turnv1.turn.list, v1.turn.get, v1.turn.stop
RTCv1.rtc.list, v1.rtc.get, v1.rtc.update_status, v1.rtc.submit_result

See WebSocket RPC.

The Agent engine is the core of AI reasoning — assembling prompts, calling the LLM, handling tool calls, and managing the reasoning loop.

CapabilityDescription
Reasoning LoopCall LLM → Process response → Tool call → Continue reasoning, until the final reply is generated
Built-in ToolsFile operations (ls/read/write/grep/find/script), sub-agent management (subAgent/listSubAgent/stopSubAgent), user interaction (askUser), goal management (goal), loop tasks (loop), etc.
Multimodal UnderstandingProcesses file attachments in user messages — images are loaded from OSS, preprocessed (EXIF correction, resizing, compression), and injected as base64 into LLM Vision; text files are UTF-8 validated, truncated if needed, XML-wrapped, and appended to Content (see below)
Streaming OutputPushes LLM output to the frontend in real-time
Error FeedbackAutomatically classifies errors when a Turn fails, generating structured ErrorContent messages pushed to the frontend (see below)
Sub-AgentsComplex tasks are automatically decomposed, with multiple specialized sub-agents working in parallel (see below)

When a Turn execution fails, the system automatically classifies the error and generates a structured error message, which the frontend can render as a user-friendly prompt with a retry button:

Error CategoryDescriptionTypical Scenario
apiAPI call errorsModel returns an error, rate limit
contextContext-relatedContext too long, compression fails
networkNetwork errorsConnection timeout, DNS failure
permissionPermission errorsAuthentication fails, session ownership mismatch
streamStream processing errorsSSE interrupted, stream parsing fails
systemSystem errorsInternal exception, database error
timeoutTimeout errorsReasoning timeout, tool execution timeout
toolTool call errorsTool doesn’t exist, parameter validation fails

💡 Rate limit protection: Each session can have at most 20 error messages per hour, preventing error storms. The debug.show_raw_errors configuration controls whether raw error details are exposed to the frontend.

See ErrorContent Protocol Definition.

When task complexity exceeds the capacity of a single reasoning pass, the Agent engine automatically decomposes the task and creates sub-agents for parallel processing:

  • Independent context: Each sub-agent has its own session and context, no interference
  • Parallel execution: Multiple sub-agents can call the LLM and tools simultaneously
  • Result aggregation: The main Agent collects results from all sub-agents and generates the final reply

Context management is responsible for building the complete prompt sent to the LLM, and automatically compressing it when conversations become too long.

When conversation length approaches the token limit, the system uses progressive compression:

StrategyTriggerCompression MethodCost
MicrocompactAfter tool callsCleans up earlier tool results, keeping only the most recent 5Zero
Auto CompactToken reaches thresholdLLM summarizes earlier conversations (9-part structured summary)One LLM call
Reactive CompactStill over limit after Auto CompactProgressive multi-level compression (3 levels, from zero cost to aggressive trimming)Zero ~ one LLM
Session Memory CompactWhen Auto Compact is triggeredDirectly uses Session Memory as summaryZero

💡 Performance optimization: Strategic Cache Breakpoints set cache breakpoints at key positions in the message list, improving LLM prompt cache hit rate from 0% to 75% after compression, reducing input cost by approximately 69%.

See Context Management.

A dual-layer memory architecture that gives AI both short-term and long-term memory.

Independently maintained per session, used for long-conversation context compression:

CategoryDescription
decisionDecisions and choices made by the user
contextBackground information for the current task
progressCompleted work and progress
issueEncountered problems and blockers
learningsLessons learned from the task
  • Capacity: Max 20 entries, approximately 12K tokens
  • Extraction: Dual-track — background Agent automatic extraction + Agent proactive saving
  • Usage: Source for Session Memory Compact summaries; 5 entries injected into context per conversation turn

Cross-session long-term memory, storing user preferences and historical facts:

CategoryDescription
userUser identity (role, expertise, preferences)
feedbackUser feedback on working style
projectOngoing projects, goals, constraints
referenceExternal resource pointers (URLs, docs, tickets)
  • Importance levels: low / medium / high / critical
  • Capacity: Max 1000 entries
  • Extraction: Agent proactive saving only
  • Retrieval: Keyword full-text search + importance weighting → top 5

See Memory System.

The RTC handler manages the full lifecycle of tool calls — from creating RTC records to saving checkpoints, pausing Turns, waiting for results, and resuming reasoning.

FeatureDescription
CheckpointSaves the current reasoning state to Redis, with a 24-hour TTL
Crash RecoveryCan recover from a checkpoint after server restart
Serial ExecutionRTC calls within the same session are strictly serialized to avoid file conflicts
100% DeliveryFrontend result submission retries indefinitely; idempotency is guaranteed

Different work modes have different confirmation strategies for tool calls:

Tool Typemanualeditplanautobypass
Read-only tools (ls/read/grep/find)✅ Auto✅ Auto✅ Auto✅ Auto✅ Auto
Write tools (write)⚠️ Confirm✅ Auto⚠️ Confirm✅ Auto✅ Auto
script tool⚠️ Confirm⚠️ Confirm⚠️ Confirm⚠️ Confirm✅ Auto

See Work Modes.

The OSS3 package provides S3-compatible object storage abstraction for managing user-uploaded file attachments (images, text, etc.).

rtc-oss3.Backend defines S3-compatible object storage operations:

Operation CategoryMethodsDescription
Basic OperationsPutObject / GetObject / DeleteObject / HeadObjectObject CRUD
Batch/RangeDeleteObjects / GetObjectRange / ListObjects / CopyObjectBatch delete, range download, list, copy
Multipart UploadCreateMultipartUpload / UploadPart / CompleteMultipartUpload / AbortMultipartUpload / ListPartsLarge file multipart upload
Presigned URLsPresignGet / PresignPutGenerate presigned URLs (server-side proxy upload/download)
LifecycleHealthCheck / CloseHealth check, resource cleanup

💡 The current implementation is a MinIO backend, but the interface design is compatible with all S3-protocol storage services including Alibaba Cloud OSS and AWS S3. Switching backends only requires changing the constructor—no business code modifications needed.

EndpointAuthenticationPurpose
POST /api/credentials/temporaryJWTSTS temporary credentials — clients obtain temporary S3 credentials for direct upload/download
POST /api/presigned-urlJWTPresigned URLs — server generates signed GET/PUT URLs with configurable expiry (default 1 hour, max 7 days)
PUT/GET/DELETE/HEAD /{bucket}/{key}SigV4 signatureS3-compatible API — clients use temporary credentials to directly manipulate objects
POST /{bucket}?deleteSigV4 signatureBatch delete objects
Multipart upload operationsSigV4 signatureLarge file multipart upload (?uploads, ?partNumber, ?uploadId)

💡 Two upload modes: (1) STS temporary credentials mode — clients obtain temporary AK/SK/Token, then use standard AWS SDK to directly operate S3; (2) Presigned URL mode — server generates signed URLs, clients PUT/GET directly without SDK.

File attachments (FileAttachment) in user messages undergo end-to-end processing before being injected into LLM context.

File TypeProcessing PipelineInjection Method
Image (JPEG/PNG/BMP/TIFF/SVG)OSS read → Magic bytes detection → EXIF auto-orientation → Resize to 2000x2000 bounding box → Multi-level JPEG compression (80→60→40→20) → base64 encoding (≤ 5MB)MultiContent Image part, directly understood by LLM Vision
TextOSS read → UTF-8 validation → Truncation if over limit (256KB, UTF-8 safe boundary)XML-wrapped <file_content name="..." type="...">, appended to Content
OtherSkipped (logged warning)—

💡 Parallel loading: Multiple file attachments are loaded in parallel using goroutines, reducing latency in multi-file scenarios. WebP/GIF formats are rejected due to decoding library limitations—users should convert to JPEG/PNG.

The Admin Dashboard is a single-page application (SPA) built with Ant Design Pro, served as static assets by the admin-server. Administrators access the dashboard via browser, authenticate with email and password, and manage users and system state.

FeatureDescription
Tech StackReact + Ant Design Pro + Umi routing
AuthenticationEmail/password login, Access Token + Refresh Token dual-token mechanism with auto-refresh
Token SecurityAccess Token stored in memory only (XSS prevention), Refresh Token via httpOnly cookie or secure storage
RTC Agent IntegrationAfter login, automatically mounts <rtc-agent> as a global floating widget using Token Exchange mode (admin JWT → RTC JWT)
DeploymentSPA static assets are embedded into admin-server binary at compile time, accessible via /admin/ path

💡 RTC Agent Widget: After admin login, RTC Agent floats above the dashboard as a global widget, allowing administrators to interact with AI directly from the admin interface. The widget uses Token Exchange mode to automatically exchange the admin-server JWT for a Main Server RTC JWT—no separate login required.

ChannelPurposeCharacteristics
TopicState change events (Session, Message, Turn, RTC)Persisted, offset tracking, offline recovery
LiveStreaming output intermediate chunksNon-persistent, Redis PUB/SUB, low latency, lossy
  • Brief disconnection (< 5 seconds): Missing events are automatically pushed after reconnection
  • Long disconnection: Client detects offset gap and proactively pulls history
  • Epoch change: After server restart, epoch changes; client resets offset and pulls full state

See Real-Time Communication.