# Context and Scoped Variables

[Tools](./tools.md) in Wasot can share data through a context system that supports both global and scoped variables. For the full API reference, see [The Context](./the_context.md).

## Global Context

Global variables persist throughout the entire document processing:

```python
@tool("document")
def document_tool(event: BlockStartedEvent):
    # Set a global variable - available everywhere
    event.context.put("doc_name", "My Document")
    
@tool("paragraph")
def paragraph_tool(event: BlockStartedEvent):
    # Access the global variable
    name = event.context.get("doc_name")  # Returns "My Document"
```

## Scoped Variables

Scoped variables are tied to the document structure and have limited lifetime:

```python
@tool("section")
def section_tool(event: BlockStartedEvent):
    # Set a scoped variable - available to children and later siblings
    event.context.put_scoped("section_id", "section_1")
    
@tool("paragraph")
def paragraph_tool(event: BlockStartedEvent):
    # Can access parent's scoped variable
    section = event.context.get_scoped("section_id")
```

### Scope Rules

1. **Visibility**: Scoped variables are visible to:
   - All nested child blocks (deeper levels)
   - Later siblings at the same level
   - The block that created them

2. **Lifetime**: Scoped variables are cleared when:
   - Moving up to a shallower level in the document structure
   - The scope that created them is exited

3. **Inheritance**: Child scopes can access variables from parent scopes

## Implementation

The context system uses the [StackFrameCollector](./stack_frame_collector.md) to track document structure. Each level in the document hierarchy gets its own scope for variables:

- When entering a deeper level (child block), a new scope is pushed
- When returning to a shallower level, scopes are popped and their variables cleared
- Variables search proceeds from current scope up to the root

## Example

```wasot
.document           # depth=1, scope=0
.page 1             # depth=1, scope=0 (sibling, same scope)
..section A         # depth=2, scope=1 (child, new scope)
...paragraph        # depth=3, scope=2 (deeper child, new scope)
..section B         # depth=2, scope=1 (back to parent level)
.page 2             # depth=1, scope=0 (back to root level)
```

In this structure:
- Variables set in `document` are visible everywhere
- Variables set in `page 1` are visible to its sections and their children
- Variables set in `section A` are only visible to its paragraph
- When we reach `page 2`, all scoped variables from `page 1` and its children are cleared

## API Reference

```python
# Global variables
event.context.put(key: str, value: Any)        # Set global variable
event.context.get(key: str) -> Any             # Get global or scoped variable
event.context.items -> dict                    # All global variables

# Scoped variables  
event.context.put_scoped(key: str, value: Any) # Set scoped variable
event.context.get_scoped(key: str) -> Any      # Get scoped variable only
event.context.scoped_items -> dict             # All visible scoped variables
```

The `get()` method checks scoped variables first, then falls back to global variables, providing a unified interface for variable access.