<p align="center">
  <img src="https://gitlab.com/pyninja/aiengineering/agentbyte/-/raw/v0.7.0/logo/agent-byte-avatar-low.png" alt="Agentbyte" width="200"/>
</p>

# Agentbyte

Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.

Current release: **0.7.0**

Repository: [gitlab.com/pyninja/aiengineering/agentbyte](https://gitlab.com/pyninja/aiengineering/agentbyte)

## What's New in 0.7.0

**MicroWebUI streaming polish + bundled SSE skill**

- Switched `agentbyte.microwebui` streaming to FastAPI's native SSE support with `EventSourceResponse` and `ServerSentEvent`, while preserving the existing frontend wire contract.
- Refined the bundled `microwebui` frontend with a scrollable chat window and a lightweight live "thinking" trace during streamed runs.
- Added a new bundled Copilot skill, `agentbyte-fastapi-sse-streaming`, covering FastAPI SSE setup and copy-ready `curl` examples for `/chat/stream`.
- Expanded the Chapter 8 web study topics to explain browser-generated `session_id` / `user_id` flow, session-list filtering, and the manual-SSE to native-SSE migration.

## What's New in 0.6.1

**Study topic documentation polish**

- Improved ASCII diagrams in web study topics with clearer visual hierarchy and flow using box-drawing characters.

## What's New in 0.6.0

**MicroWebUI + Chapter 8 demo promotion**

- Added `agentbyte.microwebui` with a small built-in `serve(entities=[...], port=...)` interface for lightweight agent demos.
- Promoted the working Chapter 8 FastAPI + SSE example into the reusable `microwebui` module instead of keeping it only as an `examples/app/` prototype.
- Added a bundled vanilla HTML frontend for `microwebui` with agent discovery, in-memory sessions, stored event history reload, and a live debug panel.
- Added a one-file launcher example, `examples/microwebui_agents.py`, showing the picoagents-style flow of defining agents locally and passing them to `serve(...)`.
- Fixed `microwebui` packaging so the bundled frontend ships correctly in the installable wheel without duplicate archive entries.

## What's New in 0.5.0

**Workflow Runtime — Spec 08 complete (8 sub-specs)**

- **Human-in-the-loop suspend/resume:** Any workflow step can call `context.request_input()` or `context.request_approval()` to suspend execution and surface a pending request to the caller. Resume by passing `responses=` to `WorkflowRunner.run()` — typed coercion is automatic.
- **Checkpoint-aware suspend:** Suspended workflows auto-save a checkpoint, and step-level `on_checkpoint_save()` / `on_checkpoint_restore()` hooks let steps persist private runtime state across restarts. Pending requests survive process boundaries.
- **`SubWorkflowStep`:** Compose child workflows as first-class steps in a parent workflow. Each invocation runs an isolated child instance; `input_mapper` / `output_mapper` hooks adapt data at the boundary; nested suspend/resume propagates through the parent transparently.
- **`WorkflowAgent` / `workflow.as_agent()`:** Expose any workflow as a `BaseAgent`-compatible agent for use inside orchestrators. Supports `full`, `last_result`, and `custom` memory modes. Suspended workflows return `finish_reason="suspended"` with pending-request metadata.
- **Staged state semantics:** Opt in with `WorkflowConfig(state_mode="staged")` to get wave-based state commits — parallel branches write to local buffers and commit atomically after each execution wave. Choose `FAIL` (default) or `LAST_WRITE_WINS` conflict resolution.
- **Structured workflow events:** `WorkflowEventOrigin` tags (`FRAMEWORK` / `STEP`) on every event. `WorkflowErrorDetails` carries error type, message, traceback, and identifiers on failure events. All events serialise cleanly via `model_dump(mode="json")`.
- **Declarative schema:** `workflow_to_schema(wf)` serialises any live workflow to a `WorkflowSchema` (Pydantic, JSON round-trippable). `WorkflowLoader.from_json()` / `from_dict()` / `from_yaml()` reconstruct fully data-driven workflows. `WorkflowStepRegistry` injects code-bound callables at load time.

## What's New in 0.4.8

- Added `RetryPolicy` as a public Pydantic v2 model exported from `agentbyte.llm`. Define a policy once and share it across multiple clients.
- Unified retry logic: `RetryMixin` replaces six duplicated retry method implementations across the four provider clients with a single shared implementation.
- All four client constructors and all Azure auth factories now accept `retry_policy=` directly.
- Provider config serialization now uses a nested `retry_policy` object instead of three flat scalar fields.
- `RetryPolicy` validation rejects negative `max_retries`, negative delays, and inverted delay bounds.

## What's New in 0.4.7

- Reorganised `agentbyte.llm` into provider packages: `agentbyte.llm.openai` and `agentbyte.llm.azure`. All existing flat `agentbyte.llm.*` imports continue to work via compatibility shims.
- Added shared `_retry_observability` helper — single retry record shape used by all provider clients.
- Provider-owned retry observability: `ChatCompletionResult.metadata["retry_observability"]` and `EmbeddingResult.metadata["retry_observability"]` populated on retries; absent when no retries occurred. Covers OpenAI and Azure chat and embedding clients.
- Updated concept notebooks and study docs to reflect the new layout and dual observability ownership model.

## What's New in 0.4.5

- Added a new `agentbyte.presets` package with provider-aware `build_chat_client()` plus default `get_*` builders for agents, orchestrators, and workflows.
- Added a review-gated plan-based preset flow so reviewer feedback now triggers writer revision loops until explicit `APPROVED`.
- Added the `notebooks/usecases/08.1-default-presets.ipynb` use-case notebook to demonstrate preset agents, orchestrators, workflows, and streaming.

## What's New in 0.4.4

- Corrected the release after `v0.4.3` published `0.4.2` artifacts in CI.
- Added a mandatory release guardrail to clean `dist/`, rebuild, and verify artifact filenames before tagging.

## What's New in 0.4.3

- Added a new `agentbyte-plan-based-orchestration` Copilot skill for Chapter 7.5 plan-based orchestration.
- Updated the `agentbyte-llm-client` skill to document `EmbeddingResult.embedding` versus `EmbeddingResult.embeddings`.

## What's New in 0.4.2

- Rebased the WebUI source frontend on the picoagents frontend snapshot copied into `src/agentbyte/webui/frontend/`.
- Added the packaged picoagents-style `agent_framework_devui` assets under `src/agentbyte/webui/` for parity/reference work.
- Fixed wheel packaging so the bundled WebUI assets are included once, unblocking PyPI publish.

## What's New in 0.4.1

- Extended `EmbeddingResult` with a single-vector `embedding` field while preserving `embeddings`, `usage`, `model`, and `metadata`.
- Updated OpenAI and Azure embedding clients so single-input calls are easier to consume without losing batch compatibility.
- Added and validated focused embedding client coverage for the new dual-field result contract.

## What's New in 0.4.0

- Added multi-agent orchestration foundations with `BaseOrchestrator`.
- Added `RoundRobinOrchestrator`, `AIOrchestrator`, and `PlanBasedOrchestrator`.
- Added a full termination system for autonomous orchestration flows.
- Added plan-based orchestration examples, tests, and study/tutorial docs.
- Expanded OpenTelemetry coverage across agents, workflows, and orchestration roots with aggregate usage summaries.
- Added a packaged Chapter 8 WebUI with FastAPI + SSE, session handling, discovery, and a browser UI for agents, workflows, and orchestrators.

## What's New in 0.3.5

- Added first-class async embeddings clients in `agentbyte.llm` for OpenAI and Azure OpenAI.
- Added separate single/batch embedding methods:
  - `create(input_text: str) -> list[float]`
  - `create_batch(input_texts: list[str]) -> list[list[float]]`
- Added Azure embedding deployment setting support:
  `AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME`.

## What's New in 0.3.2

- **Python baseline lowered:** package runtime requirement is now **Python 3.11+**.
- CI release pipeline now builds/tests/publishes with Python 3.11.

## What's New in 0.3.1

- **Interactive CLI wizard:** running `agentbyte` with no arguments launches a guided numbered menu — choose a command, then choose a provider (`github-copilot` / `claude`), then confirm before any files are written.
- Non-interactive path (`agentbyte create-skills --provider=github-copilot`) is fully preserved for scripting and CI.

## What's New in 0.3.0

- **Breaking:** `BaseAgent` no longer stores context. `self.context`, `reset_context()`, `clear_messages()`, `window_messages()`, and `reset()` are removed. `Agent.__init__` no longer accepts a `context=` kwarg.
- `Agent.run(task=None, context=None, ...)` and `Agent.run_stream(task=None, context=None, ...)` accept a per-call `AgentContext`. A fresh context is created automatically when `None`.
- `AgentResponse.context` returns the fully-populated working context to the caller — enables clean multi-turn patterns without agent-side state.
- `AgentAsTool.execute()` and `execute_stream()` thread the caller-supplied context through to the underlying agent.
- Notebooks, study docs (`topic_agents.md`, `topic_approval.md`), and OTel span guide (`topic_otel_spans.md`) updated to the caller-owned context pattern.

See [CHANGELOG.md](CHANGELOG.md) for the complete release history.

## Current Capabilities

- Agent execution loop with `run()` and `run_stream()` APIs.
- Tooling system (function tools + core tools + memory tool).
- Middleware chain for request/response/error handling.
- Built-in middleware: logging, security, rate limiting, approval, telemetry.
- Memory abstractions: list memory, file memory, context injection.
- OpenAI and Azure OpenAI model client support.
- OpenTelemetry-first tracing with model-call and task-level usage telemetry.
- Multi-agent orchestration: `RoundRobinOrchestrator`, `AIOrchestrator`, `HandoffOrchestrator`, `PlanBasedOrchestrator` with composable termination conditions.
- **Workflow runtime:** typed step graphs (`FunctionStep`, `EchoStep`, `HttpStep`, `TransformStep`, `AgentStep`, `SubWorkflowStep`) with conditional routing, parallel execution, checkpoint/resume, human-in-the-loop suspend/resume, staged state semantics, structured streaming events, and declarative JSON/YAML schema serialisation.

## Observability-First Telemetry

Agentbyte exposes two complementary telemetry layers:

- **Per-call middleware spans** (`chat ...`, `tool ...`) for model/tool-level diagnostics.
- **Task-level root span attributes** (`agent ...`) for final aggregated usage and outcome.

Enable telemetry:

```bash
export AGENTBYTE_ENABLE_OTEL=true
```

Per-call span attributes emitted by `OTelMiddleware`:

- `gen_ai.usage.input_tokens`, `gen_ai.usage.output_tokens`, `gen_ai.usage.total_tokens`
- `gen_ai.usage.cost_estimate_usd`
- `gen_ai.response.finish_reason`
- `gen_ai.request.model`
- `gen_ai.tool.name`, `gen_ai.tool.success`

## Degugging Traces without UI
details can be found in the [OTel spans guide](docs/study/topic_otel_spans.md#debugging-traces-without-ui).

Practical interpretation:

- `chat gpt-4.1-mini` spans show **per-call** usage/cost/finish reason.
- `agent <name>` span shows **final accumulated** usage and final task outcome.

## Installation

Python requirement: **3.11+**

```bash
uv sync --all-groups
```

Optional extras:

```bash
uv sync --extra openai
uv sync --extra azureopenai
uv sync --extra otel
uv sync --extra webui
```

### Install in another project (pip / uv add)

Use extras to enable provider + telemetry support:

```bash
pip install "agentbyte[azureopenai,otel]"
```

```bash
uv add "agentbyte[azureopenai,otel]"
```

For the browser WebUI:

```bash
pip install "agentbyte[webui]"
# or
uv add "agentbyte[webui]"
```

Install all optional features:

```bash
pip install "agentbyte[all]"
# or
uv add "agentbyte[all]"
```

Note: the Azure extra is `azureopenai`.

## Quick Start

```python
from agentbyte.agents import Agent
from agentbyte.middleware import LoggingMiddleware

# model_client = OpenAIChatCompletionClient(...) or AzureOpenAIChatCompletionClient(...)

def quick_faq_lookup(topic: str) -> str:
    faq = {
        "middleware": "Middleware handles cross-cutting runtime concerns.",
        "memory": "Memory helps agents keep useful context across interactions.",
    }
    return faq.get(topic.lower(), "No FAQ found.")

agent = Agent(
    name="helpful-assistant",
    description="Helpful assistant with middleware",
    instructions="Answer clearly and use tools when needed.",
    model_client=model_client,
    tools=[quick_faq_lookup],
    middlewares=[LoggingMiddleware()],
)
```

## Run The WebUI

### Option 1: Run the included demo app

This is the easiest way to see the WebUI working end to end with:
- one demo agent
- one demo workflow
- one demo orchestrator

Step 1. Install the WebUI extra:

```bash
uv sync --extra webui
```

Step 2. Start the demo app:

```bash
uv run python examples/webui/basic_webui.py
```

Step 3. Open the browser:

```text
http://127.0.0.1:8080
```

If auto-open is enabled in your environment, the browser may open automatically.

### Option 2: Run the WebUI against your current project directory

Use this when you want Agentbyte to scan a directory for exported `agent`, `workflow`, or `orchestrator` objects.

Important: discovery is convention-based. The scanned directory must contain Python modules that expose top-level variables literally named `agent`, `workflow`, or `orchestrator`. If you point `--dir` at a folder that does not export those names, the UI will load but show `No entities found`.

Step 1. Install the WebUI extra:

```bash
uv sync --extra webui
```

Step 2. Launch the WebUI and scan the current directory:

```bash
uv run agentbyte webui --dir .
```

Step 3. Open the browser:

```text
http://127.0.0.1:8080
```

Useful variants:

```bash
uv run agentbyte webui --dir . --port 8080 --host 127.0.0.1 --no-open
uv run agentbyte webui --dir examples --port 8090
```

For this repository, the most reliable first-run path is still the bundled demo:

```bash
uv run python examples/webui/basic_webui.py
```

Use `agentbyte webui --dir ...` when you have a directory of exportable demo modules, for example:

```python
# my_entities.py
agent = ...
workflow = ...
orchestrator = ...
```

### Option 3: Run it programmatically

Use this when you want to serve in-memory entities directly from Python.

```python
from agentbyte.webui import serve

serve(entities=[agent], port=8080, auto_open=True)
```

### Quick Troubleshooting

If the app does not start:

```bash
uv sync --extra webui
```

If port `8080` is already in use:

```bash
uv run agentbyte webui --dir . --port 8090
```

If you do not want the browser to open automatically:

```bash
uv run agentbyte webui --dir . --no-open
```

## Project Layout

```
src/agentbyte/
  agents/
  llm/
  memory/
  middleware/
  tools/
  messages.py
  context.py
  types.py
```

## Development

```bash
uv run ruff check src tests
uv run pytest tests -v
```

## License

MIT — see [LICENSE](LICENSE).

## References

- [Designing Multi-Agent Systems](https://github.com/victordibia/designing-multiagent-systems/tree/main)
- [Microsoft Agent Framework](https://github.com/microsoft/agent-framework)
