Web Chat
Status: no UI yet. The gateway exposes HTTP/WebSocket chat endpoints, but there is no web interface. A config + chat web UI is on the roadmap. The description below is the target design.
Use xops through a web browser interface.
Overview
The web channel provides:
- Real-time Chat - WebSocket-based instant messaging
- Streaming Responses - See answers as they're generated
- Local Access - No external dependencies
- API Access - REST endpoints for integration
Quick Start
Web chat is enabled by default. Start the gateway:
xops gateway start
Open your browser to:
http://localhost:18789
Configuration
Basic Setup
channels:
web:
enabled: true
port: 8080 # Web UI port (separate from gateway)
Gateway Port
The gateway server runs on its own port:
gateway:
bind: "127.0.0.1" # localhost only
port: 18789
API Endpoints
Health Check
curl http://localhost:18789/health
{
"status": "healthy",
"timestamp": "2025-01-26T12:00:00.000Z"
}
Send a Message
curl -X POST http://localhost:18789/chat \
-H "Content-Type: application/json" \
-d '{"message": "List pods in default namespace"}'
{
"conversationId": "abc123",
"response": "Here are the pods in the default namespace...",
"memoryUsed": true
}
Streaming Responses
curl -X POST http://localhost:18789/chat/stream \
-H "Content-Type: application/json" \
-d '{"message": "Explain Kubernetes networking"}'
Returns Server-Sent Events:
data: {"text": "Kubernetes "}
data: {"text": "networking "}
data: {"text": "consists of..."}
data: {"done": true, "conversationId": "abc123"}
Search Memory
curl -X POST http://localhost:18789/memory/search \
-H "Content-Type: application/json" \
-d '{"query": "Redis connection issues", "limit": 5}'
Get Status
curl http://localhost:18789/status
{
"status": "running",
"stats": {
"uptime": 3600000,
"messagesProcessed": 42,
"activeConversations": 3,
"memoryChunks": 156
},
"config": {
"engine": {
"runner": "goose",
"provider": "ollama",
"model": "qwen25-32k"
},
"channels": {
"telegram": true,
"slack": false,
"web": true
}
}
}
WebSocket Chat
Connect via WebSocket for real-time chat:
const ws = new WebSocket('ws://localhost:18789');
ws.onopen = () => {
console.log('Connected');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'connected':
console.log('Session ID:', data.conversationId);
break;
case 'start':
console.log('Response starting...');
break;
case 'chunk':
process.stdout.write(data.text);
break;
case 'done':
console.log('\nResponse complete');
break;
case 'error':
console.error('Error:', data.message);
break;
}
};
// Send a message
ws.send(JSON.stringify({
type: 'chat',
message: 'Hello!'
}));
Conversation Management
List Conversations
curl http://localhost:18789/conversations
{
"conversations": [
{
"id": "abc123",
"channel": "web",
"messageCount": 10,
"startedAt": "2025-01-26T10:00:00.000Z",
"lastActivity": "2025-01-26T12:00:00.000Z"
}
]
}
Delete Conversation
curl -X DELETE http://localhost:18789/conversations/abc123
Continue Conversation
Include conversationId to continue a conversation:
curl -X POST http://localhost:18789/chat \
-H "Content-Type: application/json" \
-d '{
"message": "What about the second option?",
"conversationId": "abc123"
}'
Network Access
Local Only (Default)
gateway:
bind: "127.0.0.1" # Only accessible from localhost
port: 18789
LAN Access
gateway:
bind: "0.0.0.0" # Accessible from any network interface
port: 18789
Security
When binding to 0.0.0.0, anyone on your network can access xops. Consider:
- Using a firewall
- Setting up authentication (coming soon)
- Using a VPN or tunnel
Remote Access via Tunnel
For secure remote access, use a tunnel:
gateway:
bind: "127.0.0.1"
port: 18789
tunnel:
provider: tailscale # or ngrok, cloudflare
See Self-Hosting for tunnel setup.
Integration Examples
Python Client
import requests
class xopsClient:
def __init__(self, base_url="http://localhost:18789"):
self.base_url = base_url
self.conversation_id = None
def chat(self, message):
response = requests.post(
f"{self.base_url}/chat",
json={
"message": message,
"conversationId": self.conversation_id
}
)
data = response.json()
self.conversation_id = data["conversationId"]
return data["response"]
# Usage
client = xopsClient()
print(client.chat("Hello!"))
print(client.chat("What pods are running?"))
Bash Script
#!/bin/bash
xops_chat() {
curl -s -X POST http://localhost:18789/chat \
-H "Content-Type: application/json" \
-d "{\"message\": \"$1\"}" | jq -r '.response'
}
# Usage
xops_chat "Check cluster health"
Node.js Client
const WebSocket = require('ws');
async function chat(message) {
return new Promise((resolve, reject) => {
const ws = new WebSocket('ws://localhost:18789');
let response = '';
ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.type === 'chunk') {
response += msg.text;
} else if (msg.type === 'done') {
ws.close();
resolve(response);
} else if (msg.type === 'error') {
ws.close();
reject(new Error(msg.message));
} else if (msg.type === 'connected') {
ws.send(JSON.stringify({ type: 'chat', message }));
}
});
});
}
// Usage
chat('List deployments').then(console.log);
Troubleshooting
"Connection refused"
Gateway is not running:
xops gateway start
"CORS error" in browser
Add your origin to allowed CORS:
# Currently configured for localhost:3000 and localhost:8080
# Custom CORS configuration coming soon
WebSocket disconnects
Check for:
- Network issues
- Gateway crashes (check logs)
- Idle timeout (reconnect automatically)
Next Steps
- Set up Telegram for mobile access
- Configure Memory for context
- Build a custom UI using the API