AI Tele-Center - Initial commit 🏛️👁️
Features: - Egyptian agent faces module - Meeting room concept - Client portal spec - AnveVoice integration docs Built: March 2026
This commit is contained in:
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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<EgyptianAgentType, EgyptianFaceConfig> = {
|
||||||
|
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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user