Web Component Communication Protocol
The LangCrew Web Component Communication Protocol defines how web clients communicate with LangCrew agents using Server-Sent Events (SSE) for real-time streaming communication.
1. Transport Protocol
Section titled “1. Transport Protocol”Streaming Transport (SSE)
Section titled “Streaming Transport (SSE)”- Client calls the send message API
- Server sends event streams through SSE (Server-Sent Events) connection
2. Message Definition
Section titled “2. Message Definition”2.1 Message Structure
Section titled “2.1 Message Structure”User Input
Section titled “User Input”{ "id": "uuid", "role": "user", "type": "text", "content": "User message content", "detail": { "knowledgeIds": [1, 2, 3], "tools": [1, 2, 3], "files": [{ "name": "file1.pdf", "type": "pdf", "url": "" }] }, "timestamp": 1748438204041}Session Messages
Section titled “Session Messages”Session Init
{ "id": "uuid", "role": "assistant", "type": "session_init", "content": "", "detail": { "session_id": "xxxxxx", "title": "xxxxx" }, "timestamp": 1748438204041}Finish Reason
{ "id": "uuid", "role": "assistant", "type": "finish_reason", "content": "Task completion message", "detail": { "status": "completed", "reason": "" }, "timestamp": 1748438204041}Resource Messages
Section titled “Resource Messages”Text (also used for result delivery)
{ "id": "uuid", "role": "assistant", "type": "text", "content": "Analysis results", "detail": { "streaming": false, "attachments": [] }, "timestamp": 1748438204041}Image (currently unused)
{ "id": "uuid", "role": "assistant", "type": "image", "content": "Image description text", "detail": { "url": "https://example.com/image.jpg", "width": 800, "height": 600 }, "timestamp": 1748438204041}Audio (currently unused)
{ "id": "uuid", "role": "assistant", "type": "audio", "content": "Audio description text", "detail": { "url": "https://example.com/audio.mp3", "duration": 120 }, "timestamp": 1748438204041}Video (currently unused)
{ "id": "uuid", "role": "assistant", "type": "video", "content": "Video description text", "detail": { "url": "https://example.com/video.mp4", "duration": 180, "thumbnail": "https://example.com/thumbnail.jpg" }, "timestamp": 1748438204041}Plan Messages
Section titled “Plan Messages”Plan Generation
{ "id": "uuid", "role": "assistant", "type": "plan", "content": "Analysis plan overview", "detail": { "steps": [{ "id": "step1", "title": "Step 1: Search Information", "description": "Use search tools to find relevant materials", "started_at": 1748438204041, "status": "pending" }, { "id": "step2", "title": "Step 2: Analyze Data", "description": "Analyze collected data", "started_at": null, "status": "pending" }], "created_at": 1748438204041 }, "timestamp": 1748438204041}Plan Update
{ "id": "uuid", "role": "assistant", "type": "plan_update", "content": "Plan update description", "detail": { "action": "update", "steps": [{ "id": "step1", "title": "Step 2: Modified new step", "description": "Adjust plan based on latest situation", "started_at": 1748438204041, "status": "success" }] }, "timestamp": 1748438204041}Tool Call Messages
Section titled “Tool Call Messages”Tool Call Start
{ "id": "uuid", "role": "assistant", "type": "tool_call", "content": "Click xxx to browse xxx content", "detail": { "run_id": "xxxxxxxx", "tool": "search", "status": "pending", "action": "Browsing", "action_content": "/home/user/document.html", "param": { "param1": {}, "param2": "xxxxxx" } }, "timestamp": 1748438204041}Tool Call End
{ "id": "uuid", "role": "assistant", "type": "tool_result", "content": "", "detail": { "run_id": "xxxxxxxx", "tool": "terminal", "status": "success", "result": { "content": "xxxxxx", "additional_kwargs": {}, "response_metadata": "xxxxxx" } }, "timestamp": 1748438204041}HITL Messages
Section titled “HITL Messages”HITL Standard Message
When this message is received, there is no subsequent finish_reason, requiring special handling as end of round with user in finished state
{ "id": "uuid", "role": "assistant", "type": "human_input", "content": "Your created content can be deployed as a static website, confirm deployment?", "detail": { "options": ["Agree", "Reject"], "result": { "question": "Your created content can be deployed as a static website, confirm deployment?" }, "session_id": "xxxxxx" }, "timestamp": 1748438204041}Status Messages
Section titled “Status Messages”(Will flash on page, current message disappears when new message arrives)
{ "id": "uuid", "role": "assistant", "type": "live_status", "content": "Searching", "detail": { "expires_in": 5000 }, "timestamp": 1748438204041}Error Messages
Section titled “Error Messages”{ "id": "uuid", "role": "assistant", "type": "error", "content": "Specific error message", "detail": {}, "timestamp": 1748438204041}2.2 Tool Types
Section titled “2.2 Tool Types”For superagent use, continuously expanding…:
- terminal: Terminal operations
- file: File operations
- search: Search operations
- browser: Browser operations
- html: Web page operations
2.3 Roles
Section titled “2.3 Roles”- user: User
- assistant: AI assistant
3. Complete Flow
Section titled “3. Complete Flow”- User initiates message
- Agent streaming response:
- Start message: title, session_id and other key information
- Plan message: Contains specific execution plan (if there are two steps, all pending)
- Plan update message: step 1 running
- Multiple execute messages: Multiple execution messages (text, tool call, status messages, etc.)
- Plan update message: step 1 success
- Plan update message: step 2 running (can be sent together with step1 success above)
- Multiple execute messages: Multiple execution messages (text, tool call, status messages, etc.)
- Plan update message: step 2 success
- Final return message to user: text with attachment
- End message: finish_reason
- Special messages: error messages, user_input (hitl)
4. Authentication
Section titled “4. Authentication”No built-in authentication. Users can add custom authentication middleware:
from langcrew.web import create_serverfrom fastapi import HTTPException, Dependsfrom fastapi.security import HTTPBearer
security = HTTPBearer()
async def verify_token(credentials = Depends(security)): # Add your authentication logic here if not is_valid_token(credentials.credentials): raise HTTPException(status_code=401, detail="Invalid token") return credentials
server = create_server(crew)
@server.app.post("/api/v1/chat")async def protected_chat(request: dict, token = Depends(verify_token)): # Your protected chat logic pass5. API Reference
Section titled “5. API Reference”Send Message /api/v1/chat
Section titled “Send Message /api/v1/chat”Request:
{ "message": "User message", "session_id": "xxxxx", "interrupt_data": {}}Parameters:
message(required): User’s message contentsession_id(optional): Session identifier for conversation continuity. If not provided or empty, a new session will be automatically created as a 16-character hexadecimal string (e.g.,abc123def456789a)interrupt_data(optional): Additional data for resuming interrupted conversations
Response: Streaming return of StreamMessage (see message definitions above)
Stop Chat /api/v1/chat/stop
Section titled “Stop Chat /api/v1/chat/stop”Request:
{ "session_id": "xxxxx"}Response:
{ "success": true, "session_id": "xxxx"}Usage Examples
Section titled “Usage Examples”Basic Chat Flow
Section titled “Basic Chat Flow”import requestsimport json
# Start new conversation (no session_id provided)response = requests.post('/api/v1/chat', json={ "message": "Hello, can you help me analyze this document?"})
# Handle streaming responsefor line in response.iter_lines(): if line: message = json.loads(line) print(f"Received: {message['type']} - {message['content']}")
# Extract session_id from session_init message if message['type'] == 'session_init': session_id = message['detail']['session_id'] print(f"New session created: {session_id}")Continue Existing Conversation
Section titled “Continue Existing Conversation”# Continue existing conversation with session_idresponse = requests.post('/api/v1/chat', json={ "message": "Can you provide more details?", "session_id": "abc123def456789a" # Use existing session})
# Handle streaming responsefor line in response.iter_lines(): if line: message = json.loads(line) print(f"Received: {message['type']} - {message['content']}")Handle HITL Messages
Section titled “Handle HITL Messages”# When receiving human_input messageif message['type'] == 'human_input': user_choice = input(message['content'])
# Send user response requests.post('/api/v1/chat', json={ "session_id": message['detail']['session_id'], "message": user_choice, "interrupt_data": message['detail'] })