Skip to main content
GlobalStorage is a thread-safe dictionary shared by all tools and middlewares during a single agent run. Use it to pass data between tool calls, track counters, or give middlewares access to information collected by tools.

Using global storage in tools

Add global_storage: GlobalStorage to your tool’s function signature. The framework injects it automatically at call time. Tools that don’t declare the parameter are unaffected.
from nexau.archs.main_sub.agent_context import GlobalStorage

def my_tool(param: str, global_storage: GlobalStorage) -> dict:
    # Read a value
    call_count = global_storage.get("call_count", 0)

    # Write a value
    global_storage.set("call_count", call_count + 1)

    # Update multiple keys at once
    global_storage.update({
        "last_tool": "my_tool",
        "last_param": param,
    })

    return {"result": f"call #{call_count + 1}"}
For concurrent access, lock the key you’re modifying:
with global_storage.lock_key("counter"):
    current = global_storage.get("counter", 0)
    global_storage.set("counter", current + 1)

# Lock multiple keys at once (sorted internally to prevent deadlocks)
with global_storage.lock_multiple("key1", "key2"):
    val1 = global_storage.get("key1", 0)
    val2 = global_storage.get("key2", 0)
    global_storage.set("key1", val1 + 1)
    global_storage.set("key2", val2 + 1)

Using global storage in middlewares

Access global storage from any middleware through the agent context:
from nexau.archs.main_sub.execution.hooks import Middleware, HookResult
from nexau.archs.main_sub.agent_context import get_context

class TrackingMiddleware(Middleware):
    def after_tool(self, hook_input):
        ctx = get_context()
        if ctx and hasattr(ctx, "global_storage"):
            storage = ctx.global_storage
            recent = storage.get("recent_tool_calls", [])
            recent.append(hook_input.tool_name)
            storage.set("recent_tool_calls", recent[-10:])  # keep last 10
        return HookResult.no_changes()

API reference

# Read / write
storage.get(key, default=None)   # get a value, with optional default
storage.set(key, value)          # set a value
storage.update({"k1": v1, ...})  # set multiple values
storage.delete(key)              # delete a key, returns bool
storage.keys()                   # list all keys
storage.items()                  # list all (key, value) pairs
storage.clear()                  # remove everything

# Locking
with storage.lock_key("my_key"):           # exclusive access to one key
    ...

with storage.lock_multiple("k1", "k2"):   # exclusive access to multiple keys
    ...

Common use cases

Cross-tool state

Track which tools have run, pass results from one tool to the next, or maintain a running count across the session.

Tracer / analytics access

A middleware sets up a tracer at the start of the run and stores it in global storage. Tools retrieve it by key to emit spans without any direct dependency on the middleware.

Deduplication

Record processed IDs so a tool can skip work it already did in the same run.

Shared configuration

Store runtime flags or user preferences once in before_agent and read them anywhere without threading them through every function signature.
Global storage is scoped to a single agent.run() call. It is not persisted across separate runs or sessions. For cross-run persistence, use the session manager or an external store.