# Synqed Workspace Guide 🚀

A comprehensive guide to multi-agent collaboration with **Workspace** and **OrchestratedWorkspace**.

---

## Table of Contents
- [Overview](#overview)
- [Quick Start](#quick-start)
- [Workspace vs OrchestratedWorkspace](#workspace-vs-orchestratedworkspace)
- [Basic Workspace](#basic-workspace)
- [Orchestrated Workspace](#orchestrated-workspace)
- [Collaboration Modes](#collaboration-modes)
- [Real-World Examples](#real-world-examples)
- [API Reference](#api-reference)
- [Best Practices](#best-practices)

---

## Overview

Synqed provides two powerful tools for multi-agent collaboration:

| Feature | **Workspace** | **OrchestratedWorkspace** |
|---------|--------------|---------------------------|
| **Purpose** | Basic collaborative environment | Intelligent task orchestration |
| **Setup** | Manual agent coordination | Automatic task decomposition |
| **Agent Selection** | You choose which agents to use | LLM selects best agents per subtask |
| **Task Planning** | You define the workflow | LLM breaks tasks into subtasks |
| **Collaboration** | Agents work in parallel | Multi-phase structured collaboration |
| **Best For** | Simple coordination, direct control | Complex tasks, intelligent routing |

---

## Quick Start

### Installation

```bash
pip install synqed anthropic python-dotenv
```

### Environment Setup

Create a `.env` file:

```bash
ANTHROPIC_API_KEY='your-api-key-here'
```

### 30-Second Example

```python
import synqed
import asyncio
from synqed import CollaborationMode

async def main():
    # Create agents
    writer = synqed.Agent(name="Writer", description="Creative writer", 
                         skills=["writing"], executor=your_logic_func)
    editor = synqed.Agent(name="Editor", description="Content editor",
                         skills=["editing"], executor=your_logic_func)
    
    # Start servers
    writer_server = synqed.AgentServer(writer, port=8001)
    editor_server = synqed.AgentServer(editor, port=8002)
    await writer_server.start_background()
    await editor_server.start_background()
    
    # Create orchestrator
    orchestrator = synqed.Orchestrator(
        provider=synqed.LLMProvider.ANTHROPIC,
        api_key="your-key",
        model="claude-sonnet-4-5"
    )
    
    # Create orchestrated workspace
    workspace = synqed.OrchestratedWorkspace(
        orchestrator=orchestrator,
        enable_agent_discussion=True,
        collaboration_mode=CollaborationMode.COLLABORATIVE,
        display_messages=True
    )
    
    # Register agents
    workspace.register_agent(writer)
    workspace.register_agent(editor)
    
    # Execute task - watch agents collaborate!
    result = await workspace.execute_task(
        "Write a short story about AI, then edit it for clarity"
    )
    
    print(f"Final Result: {result.final_result}")

asyncio.run(main())
```

---

## Workspace vs OrchestratedWorkspace

### When to Use **Workspace**

✅ You want **direct control** over agent interactions  
✅ Simple tasks with clear delegation  
✅ You know which agents should do what  
✅ Need a basic collaboration sandbox  

**Example Use Case:** Three agents collaborating on a shared document where you explicitly assign roles.

### When to Use **OrchestratedWorkspace**

✅ Complex tasks that need **automatic decomposition**  
✅ You want the **LLM to plan** the workflow  
✅ Need **structured multi-phase collaboration**  
✅ Want agents to have **intelligent discussions**  
✅ Tasks with dependencies and subtasks  

**Example Use Case:** "Research microservices, write implementation code, and create documentation" - let the orchestrator break this down and assign subtasks intelligently.

---

## Basic Workspace

### Core Concept

`Workspace` is a **collaborative sandbox** where agents can:
- Share files and artifacts
- Send messages to each other
- Track progress together
- Maintain shared state

### Basic Example

```python
import synqed
import asyncio

async def main():
    # Create workspace
    workspace = synqed.Workspace(
        name="Recipe Planning",
        description="Plan meals and create shopping lists",
        display_messages=True  # Real-time colored output
    )
    
    # Add agents
    workspace.add_agent(recipe_agent)
    workspace.add_agent(shopping_agent)
    workspace.add_agent(nutrition_agent)
    
    # Start workspace
    await workspace.start()
    
    # Collaborate - all agents work in parallel
    result = await workspace.collaborate(
        "Plan a week of healthy dinners and create a shopping list"
    )
    
    # Get artifacts created during collaboration
    artifacts = workspace.get_artifacts()
    for artifact in artifacts:
        print(f"Artifact: {artifact.name}")
        print(f"Content: {artifact.content}")
    
    # Get conversation history
    messages = workspace.get_messages()
    
    # Clean up
    await workspace.close()

asyncio.run(main())
```

### Workspace Features

#### 1. Direct Messaging

```python
# Send message to specific agent
response = await workspace.send_message_to_agent(
    participant_id="agent-123",
    message="Can you review this recipe?"
)

# Broadcast to all agents
responses = await workspace.broadcast_message(
    "Team meeting at 3pm!"
)
```

#### 2. Artifact Management

```python
# Add artifact
artifact_id = workspace.add_artifact(
    name="shopping_list.txt",
    artifact_type="file",
    content="Eggs, Milk, Bread",
    created_by="shopping_agent"
)

# Get artifacts
all_artifacts = workspace.get_artifacts()
file_artifacts = workspace.get_artifacts(artifact_type="file")
```

#### 3. Shared State

```python
# Set shared data
workspace.set_shared_state("budget", 100)
workspace.set_shared_state("dietary_restrictions", ["vegetarian"])

# Get shared data
budget = workspace.get_shared_state("budget")
all_state = workspace.get_all_shared_state()
```

#### 4. Message Callbacks

```python
async def on_new_message(message):
    print(f"{message.sender_name}: {message.content}")

# Register callback
workspace.on_message(on_new_message)
```

---

## Orchestrated Workspace

### Core Concept

`OrchestratedWorkspace` is an **intelligent project manager** that:
1. **Analyzes** your complex task
2. **Breaks it down** into subtasks
3. **Selects** the best agents for each subtask
4. **Coordinates** multi-phase collaboration
5. **Synthesizes** the final result

### Complete Example

```python
import synqed
import asyncio
from synqed import CollaborationMode

async def main():
    # Step 1: Create orchestrator
    orchestrator = synqed.Orchestrator(
        provider=synqed.LLMProvider.ANTHROPIC,
        api_key="your-api-key",
        model="claude-sonnet-4-5",
        temperature=0.7
    )
    
    # Step 2: Create orchestrated workspace
    orchestrated = synqed.OrchestratedWorkspace(
        orchestrator=orchestrator,
        enable_agent_discussion=True,      # Multi-turn conversations
        collaboration_mode=CollaborationMode.ADVERSARIAL,  # Force conflict → synthesis
        display_messages=True,             # Watch in real-time
        workspace_persistence=True,        # Save workspace state
        max_parallel_subtasks=3            # Max parallel execution
    )
    
    # Step 3: Register specialized agents
    orchestrated.register_agent(research_agent)  # Good at research
    orchestrated.register_agent(coding_agent)    # Good at writing code
    orchestrated.register_agent(writing_agent)   # Good at documentation
    orchestrated.register_agent(review_agent)    # Good at quality checks
    
    # Step 4: Execute complex task
    result = await orchestrated.execute_task(
        """Research best practices for microservices architecture,
        write implementation code in Python, create comprehensive
        documentation, and provide a security review."""
    )
    
    # Step 5: Check results
    if result.success:
        print(f"✅ Success!")
        print(f"\nFinal Result:\n{result.final_result}")
        
        # See how task was broken down
        print(f"\nSubtasks executed: {len(result.plan.subtasks)}")
        for subtask in result.plan.subtasks:
            print(f"  - {subtask.description} → {subtask.assigned_agent_name}")
        
        # Individual subtask results
        for subtask_id, subtask_result in result.subtask_results.items():
            print(f"\n{subtask_id}: {subtask_result[:200]}...")
        
        # Full conversation history
        print(f"\nTotal messages: {len(result.workspace_messages)}")
    else:
        print(f"❌ Failed: {result.error}")

asyncio.run(main())
```

### How It Works

The `OrchestratedWorkspace` follows a **structured workflow**:

```
1. PLANNING PHASE
   └─ LLM analyzes task
   └─ Breaks into subtasks
   └─ Assigns to best agents
   └─ Determines dependencies

2. WORKSPACE SETUP
   └─ Creates temporary workspace
   └─ Adds required agents
   └─ Sets up shared context

3. EXECUTION PHASES (if enable_agent_discussion=True)
   
   Phase A: PROPOSAL
   └─ Each agent proposes their approach
   
   Phase B: DISCUSSION
   └─ Agents review each other's proposals
   └─ Provide feedback/critique
   
   Phase C: REFINEMENT
   └─ Agents refine based on feedback
   └─ Produce final deliverables
   
   Phase D: SYNTHESIS
   └─ LLM combines all results
   └─ Creates cohesive final answer

4. CLEANUP
   └─ Stores artifacts
   └─ Exports workspace (if enabled)
   └─ Returns result
```

---

## Collaboration Modes

### 🤝 COLLABORATIVE (Supportive)

**Best for:** Teams building on each other's ideas

**How it works:**
- Agents propose approaches
- Give **supportive, constructive** feedback
- Build synergy and find common ground
- Refine work collaboratively

**Example:**
```python
workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    collaboration_mode=CollaborationMode.COLLABORATIVE
)
```

**Use when:** You want harmonious teamwork, consensus-building, and agents that complement each other.

---

### ⚔️ ADVERSARIAL (Force Conflict)

**Best for:** Critical decisions, robust solutions, avoiding groupthink

**How it works:**
1. Each agent proposes **uncompromising** approach optimized for their specialty
2. All agents **identify flaws, risks, and false assumptions** in others' proposals
3. Each agent **defends** their approach against critiques
4. **Synthesis:** Conflicting perspectives collide → recombine → produce superior solution

**Example:**
```python
workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    collaboration_mode=CollaborationMode.ADVERSARIAL  # Battle-tested results
)
```

**Use when:** You need robust solutions, want to surface hidden problems early, or are making critical architecture decisions.

**Why it works:** Forces diversity of thought, prevents premature consensus, identifies edge cases through conflict.

---

### 🔷 INDEPENDENT (No Interaction)

**Best for:** Parallel tasks that don't need coordination

**How it works:**
- Agents execute subtasks in parallel
- No discussion or feedback
- Fast, independent execution

**Example:**
```python
workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    enable_agent_discussion=False  # Independent mode
)
```

**Use when:** Subtasks are truly independent, speed is critical, or agents don't need to coordinate.

---

## Real-World Examples

### Example 1: Basic Workspace - Recipe Team

```python
async def recipe_collaboration():
    workspace = synqed.Workspace(
        name="Recipe Team",
        display_messages=True
    )
    
    workspace.add_agent(chef_agent)
    workspace.add_agent(nutritionist_agent)
    workspace.add_agent(shopper_agent)
    
    await workspace.start()
    
    # All agents work together
    result = await workspace.collaborate(
        "Create a healthy, budget-friendly dinner for 4"
    )
    
    # Get the shopping list artifact
    shopping_lists = workspace.get_artifacts(artifact_type="shopping_list")
    
    await workspace.close()
    return result
```

### Example 2: Orchestrated - Software Development

```python
async def software_project():
    orchestrated = synqed.OrchestratedWorkspace(
        orchestrator=orchestrator,
        collaboration_mode=CollaborationMode.ADVERSARIAL
    )
    
    orchestrated.register_agent(architect_agent)
    orchestrated.register_agent(backend_dev_agent)
    orchestrated.register_agent(frontend_dev_agent)
    orchestrated.register_agent(qa_agent)
    orchestrated.register_agent(security_agent)
    
    result = await orchestrated.execute_task(
        """Design and implement a REST API for user authentication.
        Include security best practices, comprehensive tests, and documentation."""
    )
    
    # The orchestrator automatically:
    # 1. Has architect design the API
    # 2. Has backend dev implement it
    # 3. Has security agent review
    # 4. Has QA write tests
    # 5. Has frontend dev create usage docs
    # 6. Synthesizes everything into final deliverable
    
    return result
```

### Example 3: Orchestrated - Research Report

```python
async def research_report():
    orchestrated = synqed.OrchestratedWorkspace(
        orchestrator=orchestrator,
        collaboration_mode=CollaborationMode.COLLABORATIVE,
        display_messages=True
    )
    
    orchestrated.register_agent(researcher_agent)
    orchestrated.register_agent(writer_agent)
    orchestrated.register_agent(editor_agent)
    orchestrated.register_agent(fact_checker_agent)
    
    result = await orchestrated.execute_task(
        """Research the impact of AI on healthcare, write a comprehensive
        report with citations, ensure factual accuracy, and edit for publication."""
    )
    
    # Orchestrator plans:
    # Subtask 1: Research (researcher_agent)
    # Subtask 2: Write draft (writer_agent) - depends on Subtask 1
    # Subtask 3: Fact check (fact_checker_agent) - depends on Subtask 2
    # Subtask 4: Edit (editor_agent) - depends on Subtask 3
    
    return result
```

---

## API Reference

### Workspace

#### Constructor

```python
workspace = synqed.Workspace(
    name: str,                          # Workspace name
    description: str,                   # Description of purpose
    workspace_id: str = None,          # Optional custom ID
    workspace_dir: Path = None,        # Optional custom directory
    auto_cleanup: bool = True,         # Clean up on close
    enable_persistence: bool = False,  # Save state to disk
    max_messages: int = 1000,          # Max messages to retain
    message_retention_hours: int = 24, # Message retention time
    display_messages: bool = True      # Real-time display
)
```

#### Methods

```python
# Agent management
workspace.add_agent(agent, agent_url=None, role="agent", metadata=None)
workspace.remove_agent(participant_id)
workspace.list_participants()

# Lifecycle
await workspace.start()
await workspace.pause()
await workspace.resume()
await workspace.complete()
await workspace.close()

# Collaboration
await workspace.collaborate(task, orchestrator=None, timeout=300.0)
await workspace.send_message_to_agent(participant_id, message)
await workspace.broadcast_message(message, sender_id="system", sender_name="System")

# Artifacts
workspace.add_artifact(name, artifact_type, content, created_by, metadata=None)
workspace.get_artifact(artifact_id)
workspace.get_artifacts(artifact_type=None, created_by=None)

# State
workspace.set_shared_state(key, value)
workspace.get_shared_state(key, default=None)
workspace.get_all_shared_state()

# Messages
workspace.get_messages(message_type=None, sender_id=None, limit=None)
workspace.on_message(callback)

# Export
await workspace.export_workspace(export_path=None)
```

### OrchestratedWorkspace

#### Constructor

```python
orchestrated = synqed.OrchestratedWorkspace(
    orchestrator: Orchestrator,                      # Required: orchestrator instance
    enable_agent_discussion: bool = True,           # Multi-turn collaboration
    collaboration_mode: CollaborationMode = ADVERSARIAL,  # Collaboration style
    workspace_persistence: bool = False,            # Save workspace state
    max_parallel_subtasks: int = 3,                # Parallel execution limit
    message_callback: Callable = None,              # Custom message handler
    display_messages: bool = False,                 # Built-in display
    display_verbose: bool = False                   # Verbose output
)
```

#### Methods

```python
# Agent registration
orchestrated.register_agent(agent)

# Execution
result = await orchestrated.execute_task(
    task: str,
    context: dict = None,
    workspace_name: str = None
)
```

#### ExecutionResult

```python
result.success          # bool: Whether execution succeeded
result.final_result     # str: Synthesized final answer
result.plan             # ExecutionPlan: Task breakdown
result.subtask_results  # dict: Individual subtask results
result.workspace_messages  # list: Full message history
result.workspace_id     # str: Workspace ID
result.error           # str: Error message if failed
result.metadata        # dict: Additional metadata
```

---

## Best Practices

### ✅ DO

1. **Use OrchestratedWorkspace for complex tasks**
   - Let the LLM handle planning and coordination
   - Leverage structured collaboration phases

2. **Enable display_messages during development**
   - Watch agents communicate in real-time
   - Debug collaboration issues

3. **Choose the right collaboration mode**
   - ADVERSARIAL for critical decisions
   - COLLABORATIVE for creative teamwork
   - INDEPENDENT for parallel tasks

4. **Register agents with clear skills**
   - Helps orchestrator make smart assignments
   - Improves task decomposition quality

5. **Use workspace artifacts**
   - Store intermediate results
   - Share data between agents

### ❌ DON'T

1. **Don't use OrchestratedWorkspace for simple tasks**
   - Overhead of planning isn't worth it
   - Use basic Workspace or direct Agent calls

2. **Don't forget to close workspaces**
   - Always `await workspace.close()`
   - Or use async context manager

3. **Don't mix too many unrelated agents**
   - Register only relevant agents
   - Quality over quantity

4. **Don't ignore the execution plan**
   - Review `result.plan` to understand decisions
   - Learn how LLM broke down your task

---

## Troubleshooting

### Agents not collaborating

**Problem:** Agents work independently instead of discussing

**Solution:** 
```python
# Ensure discussion is enabled
workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    enable_agent_discussion=True  # ← Make sure this is True
)
```

### Task decomposition is poor

**Problem:** LLM creates bad subtasks

**Solution:**
- Make sure agents have clear, descriptive skills
- Provide better task descriptions
- Add context to `execute_task(task, context={...})`

### Too slow

**Problem:** Execution takes too long

**Solution:**
```python
# Increase parallelism
workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    max_parallel_subtasks=5,  # Increase from default 3
    enable_agent_discussion=False  # Or disable discussion
)
```

### Messages not displaying

**Problem:** Not seeing real-time output

**Solution:**
```python
workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    display_messages=True  # ← Enable this
)
```

---

## Advanced: Custom Message Callbacks

```python
def my_callback(msg_dict):
    """Custom handler for workspace messages"""
    sender = msg_dict.get('sender_name')
    content = msg_dict.get('content')
    msg_type = msg_dict.get('message_type')
    
    # Log to file
    with open('collab.log', 'a') as f:
        f.write(f"[{msg_type}] {sender}: {content}\n")
    
    # Send to monitoring service
    # monitoring.track_agent_activity(msg_dict)

workspace = synqed.OrchestratedWorkspace(
    orchestrator=orchestrator,
    message_callback=my_callback
)
```

---

## Next Steps

1. **Try the examples:** Start with `workspace.py` in the examples folder
2. **Experiment with modes:** Compare ADVERSARIAL vs COLLABORATIVE
3. **Build your agents:** Create specialized agents for your domain
4. **Scale up:** Add more agents for complex workflows

---

## Additional Resources

- 📚 [Full API Documentation](../docs/)
- 💡 [More Examples](../examples/)
- 🐛 [Report Issues](https://github.com/your-repo/issues)
- 💬 [Community Discord](https://discord.gg/your-invite)

---

**Happy Collaborating! 🎉**

