agentbyte 0.3.0__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentbyte-0.3.2/.github/skills/agentbyte-agent-as-tool/SKILL.md +41 -0
- agentbyte-0.3.2/.github/skills/agentbyte-dataset/SKILL.md +208 -0
- agentbyte-0.3.2/.github/skills/agentbyte-function-tools/SKILL.md +47 -0
- agentbyte-0.3.2/.github/skills/agentbyte-list-memory/SKILL.md +46 -0
- agentbyte-0.3.2/.github/skills/agentbyte-llm-client/SKILL.md +63 -0
- agentbyte-0.3.2/.github/skills/agentbyte-memory-tool/SKILL.md +39 -0
- agentbyte-0.3.2/.github/skills/agentbyte-middleware/SKILL.md +35 -0
- agentbyte-0.3.2/.github/skills/agentbyte-multi-turn-context/SKILL.md +34 -0
- agentbyte-0.3.2/.github/skills/agentbyte-otel-tracing/SKILL.md +42 -0
- agentbyte-0.3.2/.github/skills/agentbyte-simple-agent/SKILL.md +49 -0
- agentbyte-0.3.2/.github/skills/agentbyte-tool-approval/SKILL.md +41 -0
- agentbyte-0.3.2/.github/skills/skill-authoring/SKILL.md +82 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/.gitignore +2 -1
- {agentbyte-0.3.0 → agentbyte-0.3.2}/CHANGELOG.md +19 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/PKG-INFO +17 -4
- {agentbyte-0.3.0 → agentbyte-0.3.2}/README.md +14 -2
- {agentbyte-0.3.0 → agentbyte-0.3.2}/pyproject.toml +15 -2
- agentbyte-0.3.2/src/agentbyte/__about__.py +2 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/__init__.py +1 -6
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/agents/agent.py +0 -1
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/agents/agent_as_tool.py +0 -9
- agentbyte-0.3.2/src/agentbyte/cli/__init__.py +3 -0
- agentbyte-0.3.2/src/agentbyte/cli/main.py +263 -0
- agentbyte-0.3.2/src/agentbyte/component.py +148 -0
- agentbyte-0.3.2/src/agentbyte/dataset/__init__.py +104 -0
- agentbyte-0.3.2/src/agentbyte/dataset/base.py +225 -0
- agentbyte-0.3.2/src/agentbyte/dataset/json.py +120 -0
- agentbyte-0.3.2/src/agentbyte/dataset/loader.py +101 -0
- agentbyte-0.3.2/src/agentbyte/dataset/loaders.py +155 -0
- agentbyte-0.3.2/src/agentbyte/dataset/sqlite.py +413 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/azure_openai.py +47 -61
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/base.py +2 -1
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/openai.py +35 -52
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/settings.py +17 -106
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/tools/base.py +1 -2
- agentbyte-0.3.2/src/agentbyte/workflow/__init__.py +126 -0
- agentbyte-0.3.2/src/agentbyte/workflow/core/__init__.py +81 -0
- agentbyte-0.3.2/src/agentbyte/workflow/core/checkpoint.py +363 -0
- agentbyte-0.3.2/src/agentbyte/workflow/core/models.py +414 -0
- agentbyte-0.3.2/src/agentbyte/workflow/core/runner.py +674 -0
- agentbyte-0.3.2/src/agentbyte/workflow/core/workflow.py +454 -0
- agentbyte-0.3.2/src/agentbyte/workflow/defaults.py +98 -0
- agentbyte-0.3.2/src/agentbyte/workflow/schema_utils.py +35 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/__init__.py +21 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/agentbyte_agent.py +59 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/echo.py +62 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/function.py +42 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/http.py +77 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/step.py +140 -0
- agentbyte-0.3.2/src/agentbyte/workflow/steps/transform.py +48 -0
- agentbyte-0.3.2/src/agentbyte/workflow/visualizer.py +242 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_agent_as_tool.py +0 -15
- agentbyte-0.3.2/tests/cli/test_create_skills.py +219 -0
- agentbyte-0.3.2/tests/workflow/test_checkpoint.py +184 -0
- agentbyte-0.3.2/tests/workflow/test_workflow_class.py +485 -0
- agentbyte-0.3.2/tests/workflow/test_workflow_models.py +205 -0
- agentbyte-0.3.2/tests/workflow/test_workflow_runner.py +347 -0
- agentbyte-0.3.2/tests/workflow/test_workflow_steps.py +178 -0
- agentbyte-0.3.2/tests/workflow/test_workflow_visualizer.py +125 -0
- agentbyte-0.3.0/.github/copilot-instructions.md +0 -600
- agentbyte-0.3.0/.gitlab-ci.yml +0 -63
- agentbyte-0.3.0/.gitmodules +0 -3
- agentbyte-0.3.0/.python-version +0 -1
- agentbyte-0.3.0/docker/jaeger-compose.yml +0 -9
- agentbyte-0.3.0/docs/book-designing-multi-agent-system.md +0 -9167
- agentbyte-0.3.0/docs/implementation_plan.md +0 -435
- agentbyte-0.3.0/docs/progress.md +0 -81
- agentbyte-0.3.0/docs/study/topic_agents.md +0 -454
- agentbyte-0.3.0/docs/study/topic_approval.md +0 -228
- agentbyte-0.3.0/docs/study/topic_memory.md +0 -139
- agentbyte-0.3.0/docs/study/topic_middleware.md +0 -104
- agentbyte-0.3.0/docs/study/topic_model_client.md +0 -2464
- agentbyte-0.3.0/docs/study/topic_otel.md +0 -377
- agentbyte-0.3.0/docs/study/topic_otel_spans.md +0 -752
- agentbyte-0.3.0/docs/study/topic_tools.md +0 -1816
- agentbyte-0.3.0/docs/study_plan.md +0 -139
- agentbyte-0.3.0/examples/azure_openai_usage_example.py +0 -221
- agentbyte-0.3.0/examples/function_tool_example.py +0 -259
- agentbyte-0.3.0/examples/llm_client_dependency_injection.py +0 -474
- agentbyte-0.3.0/examples/memory/memory_usage_example.py +0 -239
- agentbyte-0.3.0/examples/message_types_example.py +0 -234
- agentbyte-0.3.0/examples/openai_client_example.py +0 -456
- agentbyte-0.3.0/examples/otel/agent_with_content_capture.py +0 -128
- agentbyte-0.3.0/examples/otel/agent_with_stream_telemetry.py +0 -157
- agentbyte-0.3.0/examples/otel/agent_with_telemetry.py +0 -145
- agentbyte-0.3.0/examples/otel/inspect_trace.py +0 -254
- agentbyte-0.3.0/examples/otel/inspect_traces.py +0 -179
- agentbyte-0.3.0/logo/agent-byte-avatar-low.png +0 -0
- agentbyte-0.3.0/notebooks/agent-knowledge-building.ipynb +0 -144
- agentbyte-0.3.0/notebooks/auth/00-Authentication-and-Identity-of-AI-clients.ipynb +0 -430
- agentbyte-0.3.0/notebooks/concepts/agent/01-tools-example.ipynb +0 -460
- agentbyte-0.3.0/notebooks/concepts/agent/02a-azure-openai-wrapper.ipynb +0 -688
- agentbyte-0.3.0/notebooks/concepts/agent/02b-openai-wrapper.ipynb +0 -489
- agentbyte-0.3.0/notebooks/concepts/agent/03a-simple-agent-no-tool.ipynb +0 -340
- agentbyte-0.3.0/notebooks/concepts/agent/03b-agent-with-tool.ipynb +0 -394
- agentbyte-0.3.0/notebooks/concepts/agent/03c-multi-tool-agent.ipynb +0 -464
- agentbyte-0.3.0/notebooks/concepts/agent/04-agent-with-context.ipynb +0 -851
- agentbyte-0.3.0/notebooks/concepts/agent/05a-agent-with-middleware.ipynb +0 -845
- agentbyte-0.3.0/notebooks/concepts/agent/05b-agent-with-otel-middleware.ipynb +0 -313
- agentbyte-0.3.0/notebooks/concepts/agent/06-agent-with-memory.ipynb +0 -468
- agentbyte-0.3.0/notebooks/concepts/agent/07-agent-as-tool-coordinator.ipynb +0 -718
- agentbyte-0.3.0/notebooks/concepts/agent/sample-data/contracts_asmd_seed_rows.json +0 -92
- agentbyte-0.3.0/notebooks/concepts/agent/sample-data/contracts_esmd_seed_rows.json +0 -112
- agentbyte-0.3.0/notebooks/usecases/04.1-multi-turn-agent.ipynb +0 -601
- agentbyte-0.3.0/notebooks/usecases/04.2-metadata-extraction-large-doc.ipynb +0 -652
- agentbyte-0.3.0/src/agentbyte/__about__.py +0 -2
- agentbyte-0.3.0/uv.lock +0 -1663
- {agentbyte-0.3.0 → agentbyte-0.3.2}/LICENSE +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/agents/__init__.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/agents/base.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/agents/types.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/cancellation_token.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/context.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/entity.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/__init__.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/auth.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/llm/types.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/memory/__init__.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/memory/base.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/messages.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/middleware/__init__.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/middleware/base.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/middleware/otel.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/session.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/tools/__init__.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/tools/core_tools.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/tools/decorator.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/tools/memory_tool.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/src/agentbyte/types.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_agent_basic.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_agent_event_types.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_agent_memory_integration.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_agent_middleware_integration.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_agent_stream_events.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/agents/test_tool_approval.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/llm/test_azure_client.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/llm/test_llm_types.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/llm/test_openai_client.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/memory/test_memory.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/middleware/test_middleware_chain.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/middleware/test_otel.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/test_cancellation_token.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/test_context.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/test_messages.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/test_package_api.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/test_session.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/test_types.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/tools/test_memory_tool.py +0 -0
- {agentbyte-0.3.0 → agentbyte-0.3.2}/tests/tools/test_tools.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-agent-as-tool
|
|
3
|
+
description: Guide for the Orchestrator-Specialist pattern. Use this to wrap an Agentbyte agent as a tool that can be executed by another coordinator agent.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when building complex agentic teams or delegated workflows.
|
|
7
|
+
|
|
8
|
+
## Pattern: AgentAsTool
|
|
9
|
+
```python
|
|
10
|
+
from agentbyte.agents import Agent
|
|
11
|
+
from agentbyte.agents.agent_as_tool import AgentAsTool
|
|
12
|
+
|
|
13
|
+
# 1. Define specialist agent
|
|
14
|
+
research_agent = Agent(
|
|
15
|
+
name="researcher",
|
|
16
|
+
description="Research-focused specialist that queries for data.",
|
|
17
|
+
instructions="Research the topic provided and return a summary.",
|
|
18
|
+
model_client=client
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# 2. Wrap as a tool
|
|
22
|
+
research_tool = AgentAsTool(research_agent)
|
|
23
|
+
|
|
24
|
+
# 3. Add to coordinator agent
|
|
25
|
+
coordinator = Agent(
|
|
26
|
+
name="manager",
|
|
27
|
+
description="Orchestrates task execution by delegating to researcher.",
|
|
28
|
+
model_client=client,
|
|
29
|
+
tools=[research_tool] # Coordinator sees researcher as a tool
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
response = await coordinator.run("Tell me about the history of solar panels.")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Key Benefits
|
|
36
|
+
- **Specialization:** Specialists have their own instructions, tools, and model client settings.
|
|
37
|
+
- **Isolation:** Coordinator only sees the task input/output, keeping context windows cleaner.
|
|
38
|
+
|
|
39
|
+
## Guardrails
|
|
40
|
+
- **Naming:** The name of the `AgentAsTool` must be unique in the coordinator's tool list.
|
|
41
|
+
- **Description:** Provide a very clear `description` for the specialist agent; that description is what the coordinator sees to decide when to invoke it.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-dataset
|
|
3
|
+
description: Guide for creating and using Agentbyte datasets with SQLite or JSON backends. Use this when asked to load datasets, create dataset structures, or work with schema-driven data loading.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when you need to:
|
|
7
|
+
- **Load** an existing dataset using `load_dataset()`
|
|
8
|
+
- **Create** a new dataset with config.json, schema.json, and data.json
|
|
9
|
+
- **Query** SQLite datasets with SQL or iterate JSON datasets
|
|
10
|
+
- **Display** dataset schemas in pretty or raw format
|
|
11
|
+
- **Work with** multiple data engines (SQLite for structured, JSON for semi-structured)
|
|
12
|
+
|
|
13
|
+
## Dataset Architecture
|
|
14
|
+
|
|
15
|
+
Agentbyte datasets are file-based and engine-agnostic. Each dataset lives in `data/samples/{category}/{name}/` with three files:
|
|
16
|
+
|
|
17
|
+
### File Structure
|
|
18
|
+
```
|
|
19
|
+
data/samples/{category}/{name}/
|
|
20
|
+
├── config.json # Engine, table name, in-memory flag, description
|
|
21
|
+
├── schema.json # Column definitions (name, type, SQL constraints)
|
|
22
|
+
└── data.json # Records only ({"records": [...]})
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Supported Engines
|
|
26
|
+
- **sqlite** (default): Structured data with SQL queries, strict schema, constraints
|
|
27
|
+
- **json**: Semi-structured data, flexible JSON format, inferred schema
|
|
28
|
+
- **Future**: duckdb, lance, qdrant
|
|
29
|
+
|
|
30
|
+
## Creating a Dataset
|
|
31
|
+
|
|
32
|
+
### 1. Create Directory
|
|
33
|
+
```python
|
|
34
|
+
from pathlib import Path
|
|
35
|
+
|
|
36
|
+
dataset_dir = Path("data/samples/mydata/mydataset")
|
|
37
|
+
dataset_dir.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Write config.json
|
|
41
|
+
Define engine, table name, and metadata:
|
|
42
|
+
```python
|
|
43
|
+
import json
|
|
44
|
+
|
|
45
|
+
config = {
|
|
46
|
+
"engine": "sqlite", # "sqlite" or "json"
|
|
47
|
+
"table_name": "my_table", # SQL table name (SQLite only)
|
|
48
|
+
"in_memory": True, # Use in-memory storage
|
|
49
|
+
"description": "My dataset" # Optional description
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
with open(dataset_dir / "config.json", "w") as f:
|
|
53
|
+
json.dump(config, f, indent=2)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. Write schema.json (SQLite Only)
|
|
57
|
+
List of column definitions with types and constraints:
|
|
58
|
+
```python
|
|
59
|
+
schema = [
|
|
60
|
+
{"name": "id", "type": "TEXT", "primary_key": True, "not_null": True},
|
|
61
|
+
{"name": "name", "type": "TEXT", "not_null": True},
|
|
62
|
+
{"name": "value", "type": "REAL"},
|
|
63
|
+
{"name": "status", "type": "TEXT"}
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
with open(dataset_dir / "schema.json", "w") as f:
|
|
67
|
+
json.dump(schema, f, indent=2)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**SQLite Column Constraints (all optional):**
|
|
71
|
+
- `primary_key` (bool): Is PRIMARY KEY
|
|
72
|
+
- `not_null` (bool): Is NOT NULL
|
|
73
|
+
- `unique` (bool): Is UNIQUE
|
|
74
|
+
- All other fields ignored for JSON datasets (schema is inferred from data)
|
|
75
|
+
|
|
76
|
+
### 4. Write data.json
|
|
77
|
+
Records only; schema is separate:
|
|
78
|
+
```python
|
|
79
|
+
data = {
|
|
80
|
+
"records": [
|
|
81
|
+
{"id": "001", "name": "Item 1", "value": 100.0, "status": "active"},
|
|
82
|
+
{"id": "002", "name": "Item 2", "value": 200.0, "status": "inactive"},
|
|
83
|
+
{"id": "003", "name": "Item 3", "value": 150.0, "status": "active"}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
with open(dataset_dir / "data.json", "w") as f:
|
|
88
|
+
json.dump(data, f, indent=2)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Using Datasets
|
|
92
|
+
|
|
93
|
+
### Load a Dataset
|
|
94
|
+
```python
|
|
95
|
+
from agentbyte.dataset import load_dataset
|
|
96
|
+
|
|
97
|
+
ds = load_dataset("category/name") # Returns SQLiteDataset or JSONDataset
|
|
98
|
+
print(ds.engine) # "sqlite" or "json"
|
|
99
|
+
print(ds.table_name) # Table/collection name
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Connect & Get Data
|
|
103
|
+
|
|
104
|
+
**SQLite Dataset:**
|
|
105
|
+
```python
|
|
106
|
+
conn = ds.connect() # Returns sqlite3.Connection
|
|
107
|
+
rows = conn.execute("SELECT * FROM my_table").fetchall()
|
|
108
|
+
for row in rows:
|
|
109
|
+
print(dict(row)) # Convert sqlite3.Row to dict
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**JSON Dataset:**
|
|
113
|
+
```python
|
|
114
|
+
data = ds.connect() # Returns dict with {"records": [...]}
|
|
115
|
+
for record in data.get("records", []):
|
|
116
|
+
print(record)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Display Schema
|
|
120
|
+
|
|
121
|
+
Both datasets support schema inspection:
|
|
122
|
+
```python
|
|
123
|
+
# Pretty format (default) - shows column names, types, constraints
|
|
124
|
+
ds.schema.show()
|
|
125
|
+
|
|
126
|
+
# Raw format - list of column dicts
|
|
127
|
+
from agentbyte.dataset import SchemaFormat
|
|
128
|
+
ds.schema.show(format=SchemaFormat.RAW)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**SQLite Only:** SqliteSchema has `.to_create_table_sql()` and `.get_column_names()` methods.
|
|
132
|
+
|
|
133
|
+
## Examples
|
|
134
|
+
|
|
135
|
+
### Example 1: Load & Query Existing SQLite Dataset
|
|
136
|
+
```python
|
|
137
|
+
from agentbyte.dataset import load_dataset
|
|
138
|
+
|
|
139
|
+
ds = load_dataset("contracts/asmd")
|
|
140
|
+
conn = ds.connect()
|
|
141
|
+
|
|
142
|
+
# Display schema
|
|
143
|
+
ds.schema.show()
|
|
144
|
+
|
|
145
|
+
# Query
|
|
146
|
+
active = conn.execute(
|
|
147
|
+
"SELECT id, name FROM contracts_asmd WHERE status='active'"
|
|
148
|
+
).fetchall()
|
|
149
|
+
|
|
150
|
+
for row in active:
|
|
151
|
+
print(dict(row))
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Example 2: Load & Iterate JSON Dataset
|
|
155
|
+
```python
|
|
156
|
+
ds = load_dataset("documents/wiki") # engine="json" in config
|
|
157
|
+
data = ds.connect() # dict with {"records": [...]}
|
|
158
|
+
|
|
159
|
+
for i, record in enumerate(data["records"], 1):
|
|
160
|
+
print(f"{i}. {record['title']}: {record['url']}")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Example 3: Create Dataset Programmatically
|
|
164
|
+
See "Creating a Dataset" section above for step-by-step code.
|
|
165
|
+
|
|
166
|
+
## Guardrails
|
|
167
|
+
|
|
168
|
+
- **Do** use relative paths from project root in `load_dataset()` (e.g., `"contracts/asmd"`, not full file paths).
|
|
169
|
+
- **Do** keep schema.json separate from data.json for clarity and reusability.
|
|
170
|
+
- **Do** use `dict(row)` to convert sqlite3.Row objects to dicts for JSON serialization.
|
|
171
|
+
- **Do** call `ds.connect()` only once; it caches the connection and schema on first call.
|
|
172
|
+
- **Don't** hard-code values in datasets (use config.json for metadata).
|
|
173
|
+
- **Don't** forget `.json` extensions for all three files.
|
|
174
|
+
- **Don't** put schema definitions inside data.json (separate files for clarity).
|
|
175
|
+
- **Don't** assume JSON datasets support SQL—use dict iteration instead.
|
|
176
|
+
|
|
177
|
+
## API Reference
|
|
178
|
+
|
|
179
|
+
### Factory Function
|
|
180
|
+
```python
|
|
181
|
+
load_dataset(dataset_id: str) -> BaseDataset
|
|
182
|
+
```
|
|
183
|
+
Loads dataset from `data/samples/{category}/{name}/`. Returns `SQLiteDataset` or `JSONDataset` based on config.engine.
|
|
184
|
+
|
|
185
|
+
### Classes (Generic)
|
|
186
|
+
- **Column**: name (str), type (str)
|
|
187
|
+
- **Schema**: columns (list[Column])
|
|
188
|
+
- **DataRecord**: id (str), data (Any), metadata (dict)
|
|
189
|
+
- **DatasetConfig**: engine (str), table_name (str), in_memory (bool), description (str)
|
|
190
|
+
- **SchemaFormat**: RAW or PRETTY enum for display formats
|
|
191
|
+
|
|
192
|
+
### Classes (SQLite-Specific)
|
|
193
|
+
- **SqliteColumn**: Extends Column; adds primary_key, not_null, unique; method `to_sql_def()`
|
|
194
|
+
- **SqliteSchema**: Extends Schema; methods `to_create_table_sql()`, `get_column_names()`, `show(format)`
|
|
195
|
+
- **SQLiteDataset**: Implements BaseDataset; properties: engine, table_name, schema, in_memory
|
|
196
|
+
|
|
197
|
+
### Classes (JSON-Specific)
|
|
198
|
+
- **JSONDataset**: Implements BaseDataset; properties: engine, table_name, schema (inferred)
|
|
199
|
+
|
|
200
|
+
## Troubleshooting
|
|
201
|
+
|
|
202
|
+
| Issue | Fix |
|
|
203
|
+
|-------|-----|
|
|
204
|
+
| `FileNotFoundError: Schema file not found` | Ensure `schema.json` exists in dataset directory |
|
|
205
|
+
| `FileNotFoundError: Data file not found` | Ensure `data.json` exists in dataset directory |
|
|
206
|
+
| `KeyError: 'records'` | data.json must have `{"records": [...]}` structure |
|
|
207
|
+
| `sqlite3.Row has no .dict() method` | Use `dict(row)` instead of `row.dict()` |
|
|
208
|
+
| Notebook paths fail in `load_dataset()` | Use relative paths from project root; notebook working directory is handled by loader |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-function-tools
|
|
3
|
+
description: Guide for creating Agentbyte FunctionTools from Python functions or using the @tool decorator. Use this when defining agent capabilities, configuring ToolResult objects, or setting tool ApprovalMode.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when defining tools that an Agentbyte agent can execute.
|
|
7
|
+
|
|
8
|
+
## Patterns
|
|
9
|
+
|
|
10
|
+
### 1. Using the `@tool` decorator (Recommended for simple functions)
|
|
11
|
+
```python
|
|
12
|
+
from agentbyte.tools import tool
|
|
13
|
+
|
|
14
|
+
@tool
|
|
15
|
+
def get_weather(city: str) -> str:
|
|
16
|
+
"""Get the current weather for a city."""
|
|
17
|
+
return f"Weather in {city}: 25°C, Sunny"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Manual `FunctionTool` wrapping
|
|
21
|
+
```python
|
|
22
|
+
from agentbyte.tools import FunctionTool, ApprovalMode
|
|
23
|
+
|
|
24
|
+
def calculate_tax(amount: float) -> float:
|
|
25
|
+
return amount * 0.15
|
|
26
|
+
|
|
27
|
+
# Manually wrapping with a description and approval mode
|
|
28
|
+
tax_tool = FunctionTool(
|
|
29
|
+
calculate_tax,
|
|
30
|
+
description="Calculate the 15% regional tax for a given amount.",
|
|
31
|
+
approval_mode=ApprovalMode.ALWAYS # Triggers explicit human-in-the-loop approval
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## ToolResult usage
|
|
36
|
+
Returning structured data from tools:
|
|
37
|
+
```python
|
|
38
|
+
from agentbyte.types import ToolResult
|
|
39
|
+
|
|
40
|
+
def complex_operation():
|
|
41
|
+
return ToolResult(content="Operation summary", metadata={"id": 123})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Guardrails
|
|
45
|
+
- **Docstrings:** Always provide clear docstrings for tool functions; these are sent to the LLM as the tool description.
|
|
46
|
+
- **Imports:** Import from `agentbyte.tools` or `agentbyte.types`.
|
|
47
|
+
- **Statelessness:** Tools should ideally be stateless or operate on resources provided via arguments.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-list-memory
|
|
3
|
+
description: Guide for adding persistent memory to Agentbyte agents using ListMemory. Use this when you want agents to store, retrieve, and learn from cross-interaction knowledge.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when implementing local, in-memory knowledge stores for agents.
|
|
7
|
+
|
|
8
|
+
## Pattern: ListMemory Usage
|
|
9
|
+
```python
|
|
10
|
+
from agentbyte.memory import ListMemory, MemoryContent
|
|
11
|
+
from agentbyte.agents import Agent
|
|
12
|
+
|
|
13
|
+
# 1. Initialize local memory
|
|
14
|
+
user_memory = ListMemory()
|
|
15
|
+
|
|
16
|
+
# 2. Pre-load knowledge (if needed)
|
|
17
|
+
user_memory.add(MemoryContent(content="The user likes coffee and uses Python 3.13."))
|
|
18
|
+
|
|
19
|
+
# 3. Attach to agent
|
|
20
|
+
agent = Agent(
|
|
21
|
+
name="concierge",
|
|
22
|
+
memory=user_memory,
|
|
23
|
+
...
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# 4. First turn: Agent 'learns' from the context
|
|
27
|
+
response = await agent.run("What is my favorite language?")
|
|
28
|
+
print(response.messages[-1].content) # "You use Python 3.13."
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Advanced Memory: OperationRecorder
|
|
32
|
+
To allow agents to **write** to their own memory during a run, add the recorder middleware:
|
|
33
|
+
```python
|
|
34
|
+
from agentbyte.middleware import OperationRecorderMiddleware
|
|
35
|
+
|
|
36
|
+
agent = Agent(
|
|
37
|
+
...,
|
|
38
|
+
memory=user_memory,
|
|
39
|
+
middlewares=[OperationRecorderMiddleware()]
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Guardrails
|
|
44
|
+
- **In-Memory:** `ListMemory` is not persisted to disk by default.
|
|
45
|
+
- **System Prompt:** Memory is automatically injected into the agent's system prompt instructions.
|
|
46
|
+
- **Context vs Memory:** `AgentContext` threads messages (short-term); `Memory` stores facts (long-term).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-llm-client
|
|
3
|
+
description: Guide for initializing Agentbyte agents with OpenAI and Azure OpenAI clients. Use this when asked to set up LLM clients, configure authentication (API keys, certificates, Managed Identity), or implement Dependency Injection for model clients.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when a user needs to initialize an `OpenAIChatCompletionClient` or `AzureOpenAIChatCompletionClient`, select an authentication path, or configure LLM parameters.
|
|
7
|
+
|
|
8
|
+
## Core Patterns
|
|
9
|
+
|
|
10
|
+
### 1. OpenAI Client Initialization
|
|
11
|
+
Canonical source: `notebooks/concepts/agent/02b-openai-wrapper.ipynb`
|
|
12
|
+
|
|
13
|
+
#### Method A: Env-based factory (Recommended for simple setup)
|
|
14
|
+
```python
|
|
15
|
+
from agentbyte.llm.openai import OpenAIChatCompletionClient
|
|
16
|
+
|
|
17
|
+
# Automatically reads OPENAI_API_KEY from environment
|
|
18
|
+
model_client = OpenAIChatCompletionClient.from_api_key(
|
|
19
|
+
model="gpt-4o",
|
|
20
|
+
config={"max_completion_tokens": 500}
|
|
21
|
+
)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
#### Method B: Direct Dependency Injection (For advanced SDK control)
|
|
25
|
+
```python
|
|
26
|
+
import os
|
|
27
|
+
from openai import AsyncOpenAI
|
|
28
|
+
from agentbyte.llm.openai import OpenAIChatCompletionClient
|
|
29
|
+
|
|
30
|
+
raw_client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"], timeout=30.0)
|
|
31
|
+
model_client = OpenAIChatCompletionClient(model="gpt-4o", client=raw_client)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Azure OpenAI Client Initialization
|
|
35
|
+
Canonical source: `notebooks/concepts/agent/02a-azure-openai-wrapper.ipynb`
|
|
36
|
+
|
|
37
|
+
#### Method A: Managed Identity (Recommended for Azure-hosted production)
|
|
38
|
+
```python
|
|
39
|
+
from agentbyte.llm.azure_openai import AzureOpenAIChatCompletionClient
|
|
40
|
+
|
|
41
|
+
model_client = AzureOpenAIChatCompletionClient.from_default_credential(
|
|
42
|
+
model="gpt-4o-mini"
|
|
43
|
+
)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### Method B: Certificate Auth (Service Principal)
|
|
47
|
+
```python
|
|
48
|
+
import os
|
|
49
|
+
from agentbyte.llm.azure_openai import AzureOpenAIChatCompletionClient
|
|
50
|
+
|
|
51
|
+
model_client = AzureOpenAIChatCompletionClient.from_certificate(
|
|
52
|
+
model="gpt-4o-mini",
|
|
53
|
+
tenant_id=os.environ["AZURE_TENANT_ID"],
|
|
54
|
+
client_id=os.environ["AZURE_CLIENT_ID"],
|
|
55
|
+
certificate_data=os.environ["AZURE_CERT_DATA"]
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Guardrails
|
|
60
|
+
- **Environment Loading:** Always use `load_dotenv(find_dotenv(), override=True)` before initializing clients in scripts or notebooks.
|
|
61
|
+
- **Client Reuse:** Prefer creating one `model_client` and passing it to multiple agents rather than re-initializing for every agent.
|
|
62
|
+
- **Factory vs. Constructor:** Use factory methods (`from_api_key`, `from_certificate`) for standard auth. Use the constructor only if you need to inject a custom-configured `AsyncOpenAI` or `AsyncAzureOpenAI` instance.
|
|
63
|
+
- **Config Dict:** LLM parameters like `temperature`, `max_completion_tokens`, or `seed` should be passed via the `config` dictionary.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-memory-tool
|
|
3
|
+
description: Guide for sandboxed file-system operations in Agentbyte memory. Use this when agents need to read, write, and modify files in a safe project environment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when your agent needs to persist structured data or documents in a sandbox.
|
|
7
|
+
|
|
8
|
+
## Pattern: MemoryTool and Backend
|
|
9
|
+
```python
|
|
10
|
+
from agentbyte.tools.memory_tool import MemoryTool, MemoryBackend
|
|
11
|
+
from agentbyte.agents import Agent
|
|
12
|
+
|
|
13
|
+
# 1. Initialize backend (sandboxed or direct)
|
|
14
|
+
backend = MemoryBackend(root_dir="agent_knowledge_base", sandbox=True)
|
|
15
|
+
|
|
16
|
+
# 2. Initialize the tool
|
|
17
|
+
memory_tool = MemoryTool(memory_backend=backend)
|
|
18
|
+
|
|
19
|
+
# 3. Register as a tool
|
|
20
|
+
agent = Agent(
|
|
21
|
+
name="knowledge-agent",
|
|
22
|
+
model_client=client,
|
|
23
|
+
tools=[memory_tool] # Agent gets 'create', 'view', 'str_replace', 'insert' commands
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
await agent.run("Create a file called 'notes.txt' with the text 'Hello World'.")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Available Operations
|
|
30
|
+
- `create`: Create a new file with initial content.
|
|
31
|
+
- `view`: Read part or all of a file.
|
|
32
|
+
- `str_replace`: Change exact strings within a file.
|
|
33
|
+
- `insert`: Add content at a specific line.
|
|
34
|
+
- `delete`: Remove a file or directory.
|
|
35
|
+
|
|
36
|
+
## Guardrails
|
|
37
|
+
- **Sandbox:** Always use `sandbox=True` for agent-facing file operations to prevent path transversal.
|
|
38
|
+
- **Root Dir:** Ensure the `root_dir` exists or the backend has permissions to create it.
|
|
39
|
+
- **Context:** `MemoryTool` is meant for long-term file storage, separate from conversation history.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-middleware
|
|
3
|
+
description: Guide for adding middleware chains to Agentbyte agents. Use this for logging, guardrails, PII redaction, usage tracking, or custom pre/post run logic.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when you need to intercept agent execution.
|
|
7
|
+
|
|
8
|
+
## Pattern: Custom Middleware
|
|
9
|
+
```python
|
|
10
|
+
from agentbyte.middleware import BaseMiddleware, MiddlewareContext
|
|
11
|
+
from agentbyte.messages import Message
|
|
12
|
+
|
|
13
|
+
class MyLogger(BaseMiddleware):
|
|
14
|
+
async def before_run(self, context: MiddlewareContext):
|
|
15
|
+
print(f"Starting agent: {context.agent_name}")
|
|
16
|
+
|
|
17
|
+
async def after_run(self, context: MiddlewareContext, response: list[Message]):
|
|
18
|
+
print(f"Finished agent: {context.agent_name}")
|
|
19
|
+
|
|
20
|
+
agent = Agent(
|
|
21
|
+
...,
|
|
22
|
+
middlewares=[MyLogger()]
|
|
23
|
+
)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Built-in Middlewares
|
|
27
|
+
- `LoggingMiddleware`: Outputs detailed step logic.
|
|
28
|
+
- `GuardrailMiddleware`: Enforces constraints on responses.
|
|
29
|
+
- `PIIRedactionMiddleware`: Automatically masks sensitive patterns.
|
|
30
|
+
- `RateLimitMiddleware`: Prevents LLM client flooding.
|
|
31
|
+
|
|
32
|
+
## Guardrails
|
|
33
|
+
- **Execution Order:** Middlewares execute in the list order.
|
|
34
|
+
- **Error Handling:** Use `on_error` implementation in the middleware to handle exceptions in the pipeline.
|
|
35
|
+
- **Context:** Use `MiddlewareContext` to pass information between `before_run` and `after_run`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-multi-turn-context
|
|
3
|
+
description: Guide for managing Agentbyte multi-turn conversations using a caller-owned AgentContext. Use this when implementing stateful chats, threading conversation history, or isolating user sessions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when building conversational agents that need to remember previous turns.
|
|
7
|
+
|
|
8
|
+
## Pattern: Context Threading
|
|
9
|
+
```python
|
|
10
|
+
from agentbyte.context import AgentContext
|
|
11
|
+
from agentbyte.agents import Agent
|
|
12
|
+
|
|
13
|
+
# 1. Create caller-owned context
|
|
14
|
+
session_context = AgentContext(metadata={"session_id": "user-123"})
|
|
15
|
+
|
|
16
|
+
agent = Agent(name="chat-bot", ...)
|
|
17
|
+
|
|
18
|
+
# 2. First Turn
|
|
19
|
+
response1 = await agent.run("Hi, I am Alex", context=session_context)
|
|
20
|
+
|
|
21
|
+
# 3. Second Turn (Re-pass the context from the response)
|
|
22
|
+
response2 = await agent.run("What is my name?", context=response1.context)
|
|
23
|
+
|
|
24
|
+
print(response2.messages[-1].content) # "Your name is Alex"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Key Attributes
|
|
28
|
+
- **`context.messages`**: Access the conversation history.
|
|
29
|
+
- **`context.metadata`**: Dictionary of custom data carried across turns.
|
|
30
|
+
|
|
31
|
+
## Guardrails
|
|
32
|
+
- **Stateless Agents:** Never store conversation history on the `Agent` object itself.
|
|
33
|
+
- **Context Ownership:** The application caller is responsible for persisting and passing the `AgentContext`.
|
|
34
|
+
- **Model Client vs Context:** `AgentContext` stores messages; `model_client` handles the LLM API calls.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-otel-tracing
|
|
3
|
+
description: Guide for enabling OpenTelemetry (OTel) instrumentation in Agentbyte. Use this when connecting agents to Jaeger, tracing LLM calls, or aggregating multi-turn token metrics.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill to add observability to your agents.
|
|
7
|
+
|
|
8
|
+
## Pattern 1: Automatic Instrumentation
|
|
9
|
+
```python
|
|
10
|
+
import os
|
|
11
|
+
# MUST occur before any agentbyte imports
|
|
12
|
+
os.environ["AGENTBYTE_ENABLE_OTEL"] = "true"
|
|
13
|
+
os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "http://localhost:4318"
|
|
14
|
+
os.environ["OTEL_SERVICE_NAME"] = "my-agent-service"
|
|
15
|
+
|
|
16
|
+
from agentbyte.middleware import auto_instrument
|
|
17
|
+
auto_instrument()
|
|
18
|
+
|
|
19
|
+
# Agents will now automatically create traces in Jaeger
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Pattern 2: Manual Instrumentation
|
|
23
|
+
```python
|
|
24
|
+
from agentbyte.middleware import OTelMiddleware
|
|
25
|
+
|
|
26
|
+
agent = Agent(
|
|
27
|
+
name="my-traced-agent",
|
|
28
|
+
...,
|
|
29
|
+
middlewares=[OTelMiddleware()]
|
|
30
|
+
)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Environment Config
|
|
34
|
+
| Variable | Purpose |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `AGENTBYTE_OTEL_CAPTURE_CONTENT` | Capture full message text in spans |
|
|
37
|
+
| `AGENTBYTE_OTEL_CAPTURE_USAGE` | Aggregate tokens, calls, and cost in root span |
|
|
38
|
+
|
|
39
|
+
## Guardrails
|
|
40
|
+
- **Import Order:** Ensure OTel environment variables are set before the first `agentbyte` import.
|
|
41
|
+
- **Jaeger:** Ensure your OTLP collector endpoint is active.
|
|
42
|
+
- **PII:** Be careful with `AGENTBYTE_OTEL_CAPTURE_CONTENT` in production environments.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-simple-agent
|
|
3
|
+
description: Guide for creating basic Agentbyte agents for simple reasoning, tool use, and structured output. Use this when starting an agent project or setting up agents for single reasoning turns without complex state.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill when initializing the core reasoning agent in Agentbyte.
|
|
7
|
+
|
|
8
|
+
## Patterns
|
|
9
|
+
|
|
10
|
+
### 1. Simple Reasoning Agent
|
|
11
|
+
```python
|
|
12
|
+
from agentbyte.agents import Agent
|
|
13
|
+
from agentbyte.llm.openai import OpenAIChatCompletionClient
|
|
14
|
+
|
|
15
|
+
client = OpenAIChatCompletionClient.from_api_key(model="gpt-4o-mini")
|
|
16
|
+
|
|
17
|
+
simple_agent = Agent(
|
|
18
|
+
name="concierge",
|
|
19
|
+
description="A helpful assistant that answers user questions clearly.",
|
|
20
|
+
instructions="You are a concierge. Be brief and professional.",
|
|
21
|
+
model_client=client
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
result = await simple_agent.run("What is the time in London?")
|
|
25
|
+
print(result.messages[-1].content)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Structured Output Agent (Pydantic)
|
|
29
|
+
```python
|
|
30
|
+
from pydantic import BaseModel
|
|
31
|
+
from agentbyte.agents import Agent
|
|
32
|
+
|
|
33
|
+
class ProductReview(BaseModel):
|
|
34
|
+
score: int
|
|
35
|
+
summary: str
|
|
36
|
+
|
|
37
|
+
review_agent = Agent(
|
|
38
|
+
name="reviewer",
|
|
39
|
+
description="Extracts structured reviews from customer feedback.",
|
|
40
|
+
instructions="Analyze the text and provide score (1-5) and summary.",
|
|
41
|
+
model_client=client,
|
|
42
|
+
output_format=ProductReview # Enforces Pydantic model response
|
|
43
|
+
)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Guardrails
|
|
47
|
+
- **Required Fields:** Always include `name`, `description`, and `instructions` in the `Agent` constructor.
|
|
48
|
+
- **Streaming:** Use `await agent.run_stream(...)` to access incremental message chunks.
|
|
49
|
+
- **Model Client:** Always pass a `model_client` (instantiated from `agentbyte.llm`).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentbyte-tool-approval
|
|
3
|
+
description: Guide for implementing Human-in-the-Loop workflows in Agentbyte. Use this for pausing execution on sensitive tool calls, inspecting pending requests, and resuming after approval.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use this skill for high-risk operations where you need manual oversight.
|
|
7
|
+
|
|
8
|
+
## Pattern: Approval Workflow
|
|
9
|
+
|
|
10
|
+
### 1. Set Approval Mode on the Tool
|
|
11
|
+
```python
|
|
12
|
+
from agentbyte.tools import FunctionTool, ApprovalMode
|
|
13
|
+
|
|
14
|
+
risky_tool = FunctionTool(
|
|
15
|
+
process_payment,
|
|
16
|
+
description="Processes sensitive payments.",
|
|
17
|
+
approval_mode=ApprovalMode.ALWAYS # Force pause
|
|
18
|
+
)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Handle the Pause in the Orchestrator
|
|
22
|
+
```python
|
|
23
|
+
response = await agent.run("Charge $50 to my account.", context=context)
|
|
24
|
+
|
|
25
|
+
if response.status == "approval_needed":
|
|
26
|
+
# 3. Inspect pending requests in the context
|
|
27
|
+
pending = context.pending_approval_requests[0]
|
|
28
|
+
print(f"Approving call to: {pending.tool_name}")
|
|
29
|
+
|
|
30
|
+
# 4. Approve and re-run
|
|
31
|
+
context.approve_tool(pending.call_id)
|
|
32
|
+
final_response = await agent.run(action=None, context=context)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Key Statuses
|
|
36
|
+
- **`response.status`**: Check for `"approval_needed"`.
|
|
37
|
+
- **`context.approve_tool(call_id)`**: Marks the tool call for execution.
|
|
38
|
+
|
|
39
|
+
## Guardrails
|
|
40
|
+
- **Context Threading:** You **must** pass the same `AgentContext` object between the first run and the approved run.
|
|
41
|
+
- **Metadata:** Use `context.pending_approval_requests` to see the actual tool parameters before deciding to approve.
|