# Workspace Engine Guide

## What is the Workspace Engine?

The **Workspace Engine** is the **intelligence layer** of Synq. It's a standalone component that enables structured multi-agent collaboration **without requiring orchestration or delegation**.

Think of it as:
- **Message-passing environment** with explicit turn-taking
- **Protocol enforcement** for structured collaboration patterns
- **Shared state management** for agent coordination
- **Lifecycle management** from init → execution → termination
- **Full observability** with logs, traces, and contribution scoring

## When to Use Workspace Engine vs Orchestrator

### Use Workspace Engine when:
- ✅ Agents need to **collaborate directly** within a structured environment
- ✅ You have a **specific scenario** (simulation, debate, review)
- ✅ You want **deterministic collaboration patterns** (debate, consensus, critique-and-revise)
- ✅ No task delegation needed - agents work together on one shared goal
- ✅ **Examples**: civilization simulators, committee meetings, design reviews, team planning

### Use Orchestrator when:
- ✅ You need **task decomposition** and **delegation** to specialized agents
- ✅ Complex tasks that break down into independent subtasks
- ✅ You want **automatic agent selection** based on skills
- ✅ **Examples**: "research X, design Y, implement Z" workflows

## Core Concepts

### 1. Structured Messages

Agents don't send loose natural language. They send **structured messages** with types:

```python
from synqed import StructuredMessageType

# Available message types
MessageType.SUGGESTION       # Agent proposes an idea
MessageType.OBSERVATION      # Agent shares a finding
MessageType.CRITIQUE         # Agent provides feedback
MessageType.VOTE             # Agent votes on a proposal
MessageType.PLAN_FRAGMENT    # Agent contributes to a plan
MessageType.FINAL_OUTPUT_PROPOSAL  # Agent proposes final answer
```

### 2. Collaboration Protocols

Protocols define **HOW agents collaborate**. They enforce phases, turn-taking, and termination rules.

#### **Critique-and-Revise Protocol**
Best for quality output through peer review.

```python
config = synqed.WorkspaceConfig(
    protocol_type=synqed.ProtocolType.CRITIQUE_AND_REVISE,
)
```

**Flow:**
1. **Proposal**: Each agent proposes their solution
2. **Critique**: Agents critique each other's proposals  
3. **Refinement**: Agents refine based on critiques
4. **Synthesis**: Best ideas combined

**Use when**: Design reviews, code reviews, proposal refinement

---

#### **Debate Protocol**
Best for finding the best single solution among competing alternatives.

```python
config = synqed.WorkspaceConfig(
    protocol_type=synqed.ProtocolType.DEBATE,
)
```

**Flow:**
1. **Proposal**: Agents propose competing solutions
2. **Discussion**: Agents argue for/against proposals
3. **Voting**: Agents vote on best proposal
4. **Finalization**: Winner selected and refined

**Use when**: Decision-making, evaluating alternatives, competitive scenarios

---

#### **Consensus Protocol**
Best for building shared understanding and collaborative solutions.

```python
config = synqed.WorkspaceConfig(
    protocol_type=synqed.ProtocolType.CONSENSUS,
)
```

**Flow:**
1. **Proposal**: Agents propose ideas
2. **Discussion**: Free-flowing discussion to find common ground
3. **Consensus Building**: Iterative convergence on shared solution
4. **Finalization**: Consensus documented

**Use when**: Team alignment, collaborative planning, shared vision building

### 3. Shared State Management

The workspace maintains:
- **Shared scratchpad**: All agents can read/write structured state
- **Private agent memories**: Each agent's observations and actions
- **Version control**: Track changes over time
- **Access control**: Who can modify what

```python
# Agents can interact with shared state
workspace.shared_state.set("resource_allocation", {
    "food": 40,
    "defense": 30,
    "research": 20,
    "trade": 10
}, agent_id="farmer")

# Read shared state
allocation = workspace.shared_state.get("resource_allocation")

# Private memory
workspace.shared_state.set_agent_memory(agent_id, "my_preference", "food_first")
```

### 4. Scheduler

The scheduler prevents chaos by enforcing:
- **Turn-taking rules** (who speaks when)
- **Fairness** (no single agent dominates)
- **Token limits** (prevent verbose agents)
- **Priority handling** (critical messages can interrupt)

### 5. Constraints

Constraints keep agents on-task:
- Token limits per message/round
- Role-specific instructions
- Forbidden topics
- Task relevance checks
- Automatic truncation of long messages

### 6. Observability

Full transparency into execution:
- **Message logs**: Every message with timestamps
- **Execution trace**: Phase transitions, rounds, events
- **Interaction graph**: Who talked to whom, about what
- **Contribution scores**: Participation, influence, quality metrics
- **Reasoning summary**: Key decisions and outcomes

## Basic Usage

### Step 1: Define Agents

```python
import synqed

# Define agent executors (can be LLMs, rule-based, or hybrid)
async def agent_executor(context: dict) -> str:
    # Agent receives full workspace context
    task = context["task"]
    role = context["agent_role"]
    messages = context["recent_messages"]
    shared_state = context["shared_state"]
    
    # Generate response (using LLM, rules, etc.)
    response = await call_your_llm(task, role, messages)
    return response

# Create agent info
agents = [
    synqed.AgentInfo(
        agent_id="agent1",
        agent_name="Agent One",
        role="Analyst",
        skills=["analysis", "research"],
        executor=agent_executor,
    ),
    synqed.AgentInfo(
        agent_id="agent2",
        agent_name="Agent Two",
        role="Designer",
        skills=["design", "creativity"],
        executor=agent_executor,
    ),
]
```

### Step 2: Configure Workspace

```python
config = synqed.WorkspaceConfig(
    name="My Workspace",
    description="Collaborative task solving",
    
    # Choose protocol
    protocol_type=synqed.ProtocolType.CRITIQUE_AND_REVISE,
    
    # Protocol settings
    protocol_config=synqed.ProtocolConfig(
        max_rounds=5,
        min_rounds=2,
        max_tokens_per_message=1000,
    ),
    
    # Constraints
    max_messages=100,
    max_total_tokens=10000,
    timeout_seconds=300,
)
```

### Step 3: Create and Run Workspace

```python
# Create workspace
workspace = synqed.WorkspaceEngine(config)

# Initialize with task
await workspace.initialize(
    task="Your collaborative task here",
    agents=agents,
    context={"additional": "context"},
)

# Run until completion
result = await workspace.run()

print(f"Result: {result}")
print(f"Success: {workspace.stats.success}")
```

### Step 4: Analyze Results

```python
# Get statistics
stats = workspace.stats.to_dict()
print(f"Rounds: {stats['total_rounds']}")
print(f"Messages: {stats['total_messages']}")
print(f"Duration: {stats['duration_seconds']}s")

# Get transcript
transcript = workspace.get_transcript()
print(transcript)

# Get messages by type
suggestions = workspace.get_messages(
    message_type=synqed.StructuredMessageType.SUGGESTION
)

# Get agent contributions
for agent_id, count in stats['messages_by_agent'].items():
    print(f"{agent_id}: {count} messages")
```

## Advanced Features

### Custom Constraints

```python
# Define agent-specific constraints
constraints = {
    "agent1": synqed.AgentConstraints(
        agent_id="agent1",
        max_tokens_per_message=500,
        forbidden_topics=["politics", "religion"],
        must_stay_on_task=True,
        allow_meta_discussion=False,
    ),
}

# Create constraint enforcer
enforcer = synqed.ConstraintEnforcer(
    workspace_rules=synqed.create_workspace_rules(strict=True),
    agent_constraints=constraints,
)
```

### Custom Protocols

You can create custom protocols by extending the `Protocol` base class:

```python
from synqed.protocols import Protocol, ProtocolPhase

class CustomProtocol(Protocol):
    def get_phases(self) -> list[ProtocolPhase]:
        return [
            ProtocolPhase.INITIALIZATION,
            # Your custom phases
            ProtocolPhase.COMPLETED,
        ]
    
    def get_next_speaker(self, agents, messages):
        # Your scheduling logic
        pass
    
    # Implement other required methods
```

### Observability & Analytics

```python
from synqed import ObservabilityCollector

# Create collector
collector = ObservabilityCollector(workspace.workspace_id)

# Collect data during execution
for message in workspace.messages:
    collector.record_message(message)

# Generate report
report = collector.export_full_report()

# Access specific metrics
print(f"Agent contributions: {report['contributions']}")
print(f"Interaction graph: {report['interaction_graph']}")
print(f"Reasoning summary: {report['reasoning_summary']}")
```

## Examples

See `examples/intro/workspace_engine_demo.py` for:
- **Civilization Simulator**: Village council resource allocation
- **Debate**: Should we build the dam?
- **Design Review**: Mobile app feature design

## Best Practices

1. **Choose the right protocol** for your use case
2. **Set appropriate constraints** to keep agents focused
3. **Monitor token usage** to control costs
4. **Use structured messages** for clarity and debuggability
5. **Analyze transcripts** to understand agent behavior
6. **Iterate on agent roles** to improve collaboration quality

## Comparison: Workspace Engine vs OrchestratedWorkspace

| Feature | WorkspaceEngine | OrchestratedWorkspace |
|---------|----------------|----------------------|
| **Purpose** | Structured collaboration | Task decomposition + delegation |
| **Orchestrator** | Not required | Required |
| **Task handling** | Single shared task | Breaks into subtasks |
| **Agent assignment** | All agents on one task | Agents assigned to subtasks |
| **Protocols** | Enforced (debate, consensus, etc) | Optional discussion phases |
| **Use case** | Simulations, debates, reviews | Complex multi-step workflows |

## Key Takeaway

**WorkspaceEngine is the substrate.** It provides the mechanics for true multi-agent collaboration:
- Not vibes, but explicit message-passing
- Not chaos, but protocol-enforced interaction
- Not loose chat, but structured communication
- Not opaque, but fully observable

This is what enables **emergent intelligence** that a single agent cannot achieve.

