commit 2c9f28137747c2dce15110b1345cfd7b99578d3a Author: Horus AI Date: Fri Mar 20 20:49:15 2026 +0100 AI Tele-Center - Initial commit 🏛️👁️ Features: - Egyptian agent faces module - Meeting room concept - Client portal spec - AnveVoice integration docs Built: March 2026 diff --git a/ANVEVOICE_INTEGRATION.md b/ANVEVOICE_INTEGRATION.md new file mode 100644 index 0000000..4225f91 --- /dev/null +++ b/ANVEVOICE_INTEGRATION.md @@ -0,0 +1,33 @@ +# AnveVoice Integration 🎙️ + +## What is AnveVoice? +AI voice assistant for websites - handles calls, chat, lead capture. + +## Why AnveVoice? +- ✅ Phone calls built-in +- ✅ 22+ languages +- ✅ Lead capture automatic +- ✅ Analytics dashboard +- ✅ Embed widget ready + +## Setup +1. Get API key: https://anvevoice.com/developer +2. Configure in OpenClaw +3. Create bot for each agent + +## Agent Integration +Each Egyptian agent can have an AnveVoice bot: +- **Cleopatra** → Sales voice bot +- **Anubis** → Outreach voice bot +- **Ptah** → Support voice bot + +## Pricing +| Plan | Price | +|------|-------| +| Free | ₹0 | +| Growth | ₹2,999/mo | +| Scale | ₹9,999/mo | + +## Docs +- Dashboard: https://anvevoice.com/dashboard +- API: https://anvevoice.com/developer diff --git a/README.md b/README.md new file mode 100644 index 0000000..d1a0101 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# AI Tele-Center 🏛️👁️ + +A 3D virtual office for AI agents with Egyptian-themed avatars. + +## Vision +- Watch AI agents work in real-time in a 3D office +- Egyptian god-themed agents (Horus, Cleopatra, Anubis, Thoth, Ptah, Seshat, Sekhmet, Maat) +- Meeting rooms for standups and scrum +- Client portal to watch their hired agents work + +## Features +- 🏛️ 3D virtual office (built on Claw3D) +- 👁️ Egyptian-themed AI agents +- 📋 Standup meetings +- 💬 Real-time chat with agents +- 📊 Task pipeline +- 👥 Client portal + +## Tech Stack +- Claw3D (3D office) +- OpenClaw (agent runtime) +- React Three Fiber (3D rendering) +- TypeScript + +## Egyptian Agents +| Agent | Role | Head | +|-------|------|------| +| Horus | Orchestrator | Falcon | +| Cleopatra | Voice/Sales | Queen | +| Anubis | Outreach | Jackal | +| Thoth | Research | Ibis | +| Ptah | Dev/Ops | Mummy | +| Seshat | Content | Scribe | +| Sekhmet | Trading | Lioness | +| Maat | QA | Feather | + +## Status +🚧 In Development - Egyptian faces module ready + +## Links +- Claw3D: https://github.com/iamlukethedev/Claw3D +- AnveVoice (voice widget): https://anvevoice.com +- OpenClaw: https://github.com/openclaw/openclaw + +--- +Built by Horus AI for HostPioneers © 2026 diff --git a/SPEC.md b/SPEC.md new file mode 100644 index 0000000..d7aaccb --- /dev/null +++ b/SPEC.md @@ -0,0 +1,59 @@ +# AI Tele-Center Specification + +## Overview +3D virtual office where AI agents work and clients can watch them. + +## Architecture +``` +┌─────────────────────────────────────┐ +│ AI TELE-CENTER │ +├─────────────────────────────────────┤ +│ 3D Office (Claw3D) │ +│ ├── Reception │ +│ ├── Agent Desks │ +│ ├── Meeting Room │ +│ └── Break Room │ +├─────────────────────────────────────┤ +│ Egyptian Agents │ +│ ├── Horus (Orchestrator) │ +│ ├── Cleopatra (Voice) │ +│ ├── Anubis (Outreach) │ +│ └── ... │ +├─────────────────────────────────────┤ +│ Client Portal │ +│ ├── Watch Agent │ +│ ├── Assign Tasks │ +│ └── View Metrics │ +└─────────────────────────────────────┘ +``` + +## Agent Types +- **Horus** 👁️ - Master Orchestrator, sees all +- **Cleopatra** 👑 - Voice AI, speaks to customers +- **Anubis** 🐕 - Lead generation, cold outreach +- **Thoth** 🐦 - Research, strategy +- **Ptah** 🔨 - Development, deployment +- **Seshat** 📝 - Content, SEO, documentation +- **Sekhmet** 🦁 - Trading, risk management +- **Maat** ⚖️ - Quality assurance + +## Meeting Room +- Daily standups at 9 AM +- Sprint planning +- Retrospectives +- Agent collaboration + +## Client Portal +- See ONLY their hired agent(s) +- Real-time activity feed +- Task assignment +- Performance metrics +- Chat with agent + +## TODO +- [ ] Integrate Egyptian faces into Claw3D +- [ ] Build meeting room +- [ ] Connect to OpenClaw runtime +- [ ] Build client portal +- [ ] Add AnveVoice for phone/SMS +- [ ] Test with real agents diff --git a/src/egyptianFaces.tsx b/src/egyptianFaces.tsx new file mode 100644 index 0000000..0a0a24e --- /dev/null +++ b/src/egyptianFaces.tsx @@ -0,0 +1,391 @@ +/** + * Egyptian Agent Faces for Claw3D 🏛️👁️ + * Custom canvas-drawn Egyptian god heads for each AI agent + */ + +export type EgyptianAgentType = + | 'horus' + | 'cleopatra' + | 'anubis' + | 'thoth' + | 'ptah' + | 'seshat' + | 'sekhmet' + | 'maat'; + +interface EgyptianFaceConfig { + name: string; + skinColor: string; + accentColor: string; + eyeColor: string; + crownColor: string; + specialFeature: string; +} + +export const EGYPTIAN_AGENTS: Record = { + horus: { + name: 'Horus', + skinColor: '#DAA520', + accentColor: '#1E90FF', + eyeColor: '#FFD700', + crownColor: '#FFFFFF', + specialFeature: 'falcon' + }, + cleopatra: { + name: 'Cleopatra', + skinColor: '#CD853F', + accentColor: '#9B59B6', + eyeColor: '#000000', + crownColor: '#FFD700', + specialFeature: 'queen' + }, + anubis: { + name: 'Anubis', + skinColor: '#1a1a1a', + accentColor: '#FFD700', + eyeColor: '#FFD700', + crownColor: '#1a1a1a', + specialFeature: 'jackal' + }, + thoth: { + name: 'Thoth', + skinColor: '#FFFFFF', + accentColor: '#40E0D0', + eyeColor: '#000000', + crownColor: '#40E0D0', + specialFeature: 'ibis' + }, + ptah: { + name: 'Ptah', + skinColor: '#F5DEB3', + accentColor: '#FFD700', + eyeColor: '#000000', + crownColor: '#F5DEB3', + specialFeature: 'mummy' + }, + seshat: { + name: 'Seshat', + skinColor: '#DEB887', + accentColor: '#228B22', + eyeColor: '#000000', + crownColor: '#228B22', + specialFeature: 'scribe' + }, + sekhmet: { + name: 'Sekhmet', + skinColor: '#D2691E', + accentColor: '#B22222', + eyeColor: '#FFD700', + crownColor: '#B22222', + specialFeature: 'lioness' + }, + maat: { + name: 'Maat', + skinColor: '#FFE4C4', + accentColor: '#40E0D0', + eyeColor: '#000000', + crownColor: '#FFFFFF', + specialFeature: 'feather' + } +}; + +export function drawEgyptianFace( + ctx: CanvasRenderingContext2D, + agentType: EgyptianAgentType, + x: number, + y: number, + size: number +) { + const config = EGYPTIAN_AGENTS[agentType]; + ctx.save(); + ctx.translate(x, y); + + switch (agentType) { + case 'horus': drawHorusFace(ctx, size, config); break; + case 'cleopatra': drawCleopatraFace(ctx, size, config); break; + case 'anubis': drawAnubisFace(ctx, size, config); break; + case 'thoth': drawThothFace(ctx, size, config); break; + case 'ptah': drawPtahFace(ctx, size, config); break; + case 'seshat': drawSeshatFace(ctx, size, config); break; + case 'sekhmet': drawSekhmetFace(ctx, size, config); break; + case 'maat': drawMaatFace(ctx, size, config); break; + } + + ctx.restore(); +} + +function drawHorusFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 32 * s, 24 * s, 28 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(32 * s, 28 * s, 14 * s, 8 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#000000'; + ctx.beginPath(); + ctx.ellipse(34 * s, 28 * s, 5 * s, 5 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.strokeStyle = '#000000'; + ctx.lineWidth = 2 * s; + ctx.beginPath(); + ctx.moveTo(18 * s, 28 * s); + ctx.lineTo(8 * s, 24 * s); + ctx.moveTo(46 * s, 28 * s); + ctx.lineTo(56 * s, 28 * s); + ctx.stroke(); + ctx.fillStyle = '#FFD700'; + ctx.beginPath(); + ctx.moveTo(32 * s, 32 * s); + ctx.lineTo(38 * s, 38 * s); + ctx.lineTo(32 * s, 40 * s); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = config.crownColor; + ctx.beginPath(); + ctx.moveTo(12 * s, 8 * s); + ctx.lineTo(20 * s, 0 * s); + ctx.lineTo(32 * s, 8 * s); + ctx.lineTo(44 * s, 0 * s); + ctx.lineTo(52 * s, 8 * s); + ctx.lineTo(52 * s, 16 * s); + ctx.lineTo(12 * s, 16 * s); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = config.accentColor; + ctx.fillRect(14 * s, 8 * s, 36 * s, 4 * s); +} + +function drawCleopatraFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 34 * s, 20 * s, 24 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(24 * s, 28 * s, 8 * s, 5 * s, -0.2, 0, Math.PI * 2); + ctx.fill(); + ctx.beginPath(); + ctx.ellipse(40 * s, 28 * s, 8 * s, 5 * s, 0.2, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.eyeColor; + ctx.beginPath(); + ctx.arc(25 * s, 28 * s, 3 * s, 0, Math.PI * 2); + ctx.arc(41 * s, 28 * s, 3 * s, 0, Math.PI * 2); + ctx.fill(); + ctx.strokeStyle = '#000000'; + ctx.lineWidth = 1.5 * s; + ctx.beginPath(); + ctx.moveTo(16 * s, 26 * s); + ctx.lineTo(10 * s, 24 * s); + ctx.moveTo(48 * s, 26 * s); + ctx.lineTo(54 * s, 24 * s); + ctx.stroke(); + ctx.fillStyle = '#8B4513'; + ctx.beginPath(); + ctx.ellipse(32 * s, 44 * s, 6 * s, 3 * s, 0, 0, Math.PI); + ctx.fill(); + ctx.fillStyle = config.crownColor; + ctx.fillRect(14 * s, 4 * s, 36 * s, 12 * s); + ctx.fillStyle = '#00FF00'; + ctx.beginPath(); + ctx.ellipse(32 * s, 2 * s, 4 * s, 6 * s, 0, 0, Math.PI * 2); + ctx.fill(); +} + +function drawAnubisFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 36 * s, 18 * s, 22 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(24 * s, 38 * s); + ctx.lineTo(8 * s, 42 * s); + ctx.lineTo(24 * s, 46 * s); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = config.eyeColor; + ctx.beginPath(); + ctx.arc(26 * s, 30 * s, 5 * s, 0, Math.PI * 2); + ctx.arc(38 * s, 30 * s, 5 * s, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = 'rgba(255, 215, 0, 0.3)'; + ctx.beginPath(); + ctx.arc(26 * s, 30 * s, 8 * s, 0, Math.PI * 2); + ctx.arc(38 * s, 30 * s, 8 * s, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.moveTo(18 * s, 20 * s); + ctx.lineTo(14 * s, 4 * s); + ctx.lineTo(24 * s, 16 * s); + ctx.closePath(); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(46 * s, 20 * s); + ctx.lineTo(50 * s, 4 * s); + ctx.lineTo(40 * s, 16 * s); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = config.accentColor; + ctx.fillRect(18 * s, 50 * s, 28 * s, 6 * s); +} + +function drawThothFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 32 * s, 18 * s, 20 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#000000'; + ctx.beginPath(); + ctx.moveTo(32 * s, 34 * s); + ctx.quadraticCurveTo(50 * s, 36 * s, 58 * s, 30 * s); + ctx.quadraticCurveTo(50 * s, 38 * s, 32 * s, 38 * s); + ctx.fill(); + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(24 * s, 26 * s, 6 * s, 4 * s, 0, 0, Math.PI * 2); + ctx.ellipse(40 * s, 26 * s, 6 * s, 4 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.strokeStyle = '#000000'; + ctx.lineWidth = 1 * s; + ctx.beginPath(); + ctx.moveTo(18 * s, 26 * s); + ctx.lineTo(10 * s, 24 * s); + ctx.moveTo(46 * s, 26 * s); + ctx.lineTo(54 * s, 24 * s); + ctx.stroke(); + ctx.fillStyle = config.accentColor; + ctx.beginPath(); + ctx.arc(32 * s, 8 * s, 8 * s, Math.PI, 0); + ctx.fill(); +} + +function drawPtahFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 32 * s, 20 * s, 24 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.strokeStyle = '#DEB887'; + ctx.lineWidth = 3 * s; + for (let i = 0; i < 6; i++) { + ctx.beginPath(); + ctx.moveTo(12 * s, (20 + i * 8) * s); + ctx.lineTo(52 * s, (20 + i * 8) * s); + ctx.stroke(); + } + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(24 * s, 28 * s, 6 * s, 4 * s, 0, 0, Math.PI * 2); + ctx.ellipse(40 * s, 28 * s, 6 * s, 4 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.accentColor; + ctx.beginPath(); + ctx.arc(24 * s, 28 * s, 2 * s, 0, Math.PI * 2); + ctx.arc(40 * s, 28 * s, 2 * s, 0, Math.PI * 2); + ctx.fill(); +} + +function drawSeshatFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 34 * s, 18 * s, 22 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(24 * s, 30 * s, 6 * s, 4 * s, 0, 0, Math.PI * 2); + ctx.ellipse(40 * s, 30 * s, 6 * s, 4 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#000000'; + ctx.beginPath(); + ctx.arc(25 * s, 30 * s, 2 * s, 0, Math.PI * 2); + ctx.arc(41 * s, 30 * s, 2 * s, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.crownColor; + const cx = 32 * s, cy = 8 * s, spikes = 7, outerR = 6 * s, innerR = 3 * s; + let rot = Math.PI / 2 * 3; + ctx.beginPath(); + ctx.moveTo(cx, cy - outerR); + for (let i = 0; i < spikes; i++) { + ctx.lineTo(cx + Math.cos(rot) * outerR, cy + Math.sin(rot) * outerR); + rot += Math.PI / spikes; + ctx.lineTo(cx + Math.cos(rot) * innerR, cy + Math.sin(rot) * innerR); + rot += Math.PI / spikes; + } + ctx.lineTo(cx, cy - outerR); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = '#000000'; + ctx.fillRect(48 * s, 36 * s, 8 * s, 20 * s); +} + +function drawSekhmetFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 34 * s, 22 * s, 24 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.accentColor; + for (let i = 0; i < 12; i++) { + const angle = (i / 12) * Math.PI * 2; + ctx.beginPath(); + ctx.arc(32 * s + Math.cos(angle) * 26 * s, 34 * s + Math.sin(angle) * 28 * s, 6 * s, 0, Math.PI * 2); + ctx.fill(); + } + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(24 * s, 28 * s, 7 * s, 5 * s, 0, 0, Math.PI * 2); + ctx.ellipse(40 * s, 28 * s, 7 * s, 5 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.eyeColor; + ctx.beginPath(); + ctx.arc(25 * s, 28 * s, 3 * s, 0, Math.PI * 2); + ctx.arc(41 * s, 28 * s, 3 * s, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.accentColor; + ctx.beginPath(); + ctx.moveTo(10 * s, 16 * s); + ctx.lineTo(32 * s, 4 * s); + ctx.lineTo(54 * s, 16 * s); + ctx.lineTo(54 * s, 24 * s); + ctx.lineTo(10 * s, 24 * s); + ctx.closePath(); + ctx.fill(); +} + +function drawMaatFace(ctx: CanvasRenderingContext2D, size: number, config: EgyptianFaceConfig) { + const s = size / 64; + ctx.fillStyle = config.skinColor; + ctx.beginPath(); + ctx.ellipse(32 * s, 36 * s, 18 * s, 20 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#FFFFFF'; + ctx.beginPath(); + ctx.ellipse(24 * s, 32 * s, 5 * s, 3 * s, 0, 0, Math.PI * 2); + ctx.ellipse(40 * s, 32 * s, 5 * s, 3 * s, 0, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = '#000000'; + ctx.beginPath(); + ctx.arc(24 * s, 32 * s, 2 * s, 0, Math.PI * 2); + ctx.arc(40 * s, 32 * s, 2 * s, 0, Math.PI * 2); + ctx.fill(); + ctx.fillStyle = config.crownColor; + ctx.beginPath(); + ctx.moveTo(32 * s, 0 * s); + ctx.quadraticCurveTo(40 * s, 8 * s, 32 * s, 20 * s); + ctx.quadraticCurveTo(24 * s, 8 * s, 32 * s, 0 * s); + ctx.fill(); + ctx.strokeStyle = config.accentColor; + ctx.lineWidth = 1 * s; + ctx.beginPath(); + ctx.moveTo(32 * s, 4 * s); + ctx.lineTo(32 * s, 16 * s); + ctx.stroke(); +} diff --git a/src/meetingRoom.ts b/src/meetingRoom.ts new file mode 100644 index 0000000..86cf6e8 --- /dev/null +++ b/src/meetingRoom.ts @@ -0,0 +1,27 @@ +/** + * Egyptian Meeting Room for Claw3D 🏛️📋 + */ + +export interface MeetingParticipant { + agentId: string; + agentName: string; + agentType: string; + status: 'speaking' | 'listening' | 'away'; + currentTask?: string; +} + +export const MEETING_ROOM_CONFIG = { + roomName: "🏛️ Temple of Teams", + seats: 9, + features: ['standup_board', 'task_pipeline', 'sprint_timer', 'chat_panel'] +}; + +export function createStandupMessage(participants: MeetingParticipant[]): string { + let msg = `# 🏛️ Daily Standup - ${new Date().toLocaleDateString()}\n\n`; + participants.forEach(p => { + const icon = p.status === 'speaking' ? '🎤' : p.status === 'away' ? '🚶' : '👂'; + msg += `## ${icon} ${p.agentName}\n`; + msg += `**Task:** ${p.currentTask || 'Waiting...'}\n\n`; + }); + return msg; +}