deepharness 0.1.0__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.
- deepharness-0.1.0/LICENSE +21 -0
- deepharness-0.1.0/PKG-INFO +194 -0
- deepharness-0.1.0/README.md +162 -0
- deepharness-0.1.0/deepharness/__init__.py +101 -0
- deepharness-0.1.0/deepharness/agent/__init__.py +33 -0
- deepharness-0.1.0/deepharness/agent/loop.py +414 -0
- deepharness-0.1.0/deepharness/agent/output.py +173 -0
- deepharness-0.1.0/deepharness/agent/state.py +248 -0
- deepharness-0.1.0/deepharness/agent/turn.py +131 -0
- deepharness-0.1.0/deepharness/errors.py +102 -0
- deepharness-0.1.0/deepharness/graph/__init__.py +14 -0
- deepharness-0.1.0/deepharness/graph/builder.py +186 -0
- deepharness-0.1.0/deepharness/graph/executor.py +128 -0
- deepharness-0.1.0/deepharness/graph/reducers.py +43 -0
- deepharness-0.1.0/deepharness/providers/__init__.py +51 -0
- deepharness-0.1.0/deepharness/providers/anthropic.py +293 -0
- deepharness-0.1.0/deepharness/providers/base.py +203 -0
- deepharness-0.1.0/deepharness/providers/client.py +121 -0
- deepharness-0.1.0/deepharness/providers/gateways.py +99 -0
- deepharness-0.1.0/deepharness/providers/gemini.py +232 -0
- deepharness-0.1.0/deepharness/providers/openai.py +281 -0
- deepharness-0.1.0/deepharness/providers/rest.py +189 -0
- deepharness-0.1.0/deepharness/providers/wire.py +79 -0
- deepharness-0.1.0/deepharness/py.typed +0 -0
- deepharness-0.1.0/deepharness/tools/__init__.py +3 -0
- deepharness-0.1.0/deepharness/tools/toolbox.py +248 -0
- deepharness-0.1.0/deepharness.egg-info/PKG-INFO +194 -0
- deepharness-0.1.0/deepharness.egg-info/SOURCES.txt +46 -0
- deepharness-0.1.0/deepharness.egg-info/dependency_links.txt +1 -0
- deepharness-0.1.0/deepharness.egg-info/requires.txt +10 -0
- deepharness-0.1.0/deepharness.egg-info/top_level.txt +1 -0
- deepharness-0.1.0/pyproject.toml +48 -0
- deepharness-0.1.0/setup.cfg +4 -0
- deepharness-0.1.0/tests/test_agent.py +713 -0
- deepharness-0.1.0/tests/test_approval.py +178 -0
- deepharness-0.1.0/tests/test_budget.py +70 -0
- deepharness-0.1.0/tests/test_client.py +91 -0
- deepharness-0.1.0/tests/test_ctx.py +133 -0
- deepharness-0.1.0/tests/test_executor.py +377 -0
- deepharness-0.1.0/tests/test_gateways.py +66 -0
- deepharness-0.1.0/tests/test_graph.py +175 -0
- deepharness-0.1.0/tests/test_message.py +67 -0
- deepharness-0.1.0/tests/test_output.py +195 -0
- deepharness-0.1.0/tests/test_providers.py +663 -0
- deepharness-0.1.0/tests/test_session.py +29 -0
- deepharness-0.1.0/tests/test_state.py +67 -0
- deepharness-0.1.0/tests/test_streaming.py +394 -0
- deepharness-0.1.0/tests/test_toolbox.py +201 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sayed Shaun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepharness
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Compose LLM agents into typed, concurrent workflows.
|
|
5
|
+
Author-email: Sayed Shaun <sayedshaun4@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sayedshaun/deepharness
|
|
8
|
+
Project-URL: Documentation, https://sayedshaun.github.io/deepharness/
|
|
9
|
+
Project-URL: Repository, https://github.com/sayedshaun/deepharness
|
|
10
|
+
Project-URL: Issues, https://github.com/sayedshaun/deepharness/issues
|
|
11
|
+
Keywords: agents,llm,workflow,graph,async
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: httpx
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff; extra == "dev"
|
|
28
|
+
Provides-Extra: docs
|
|
29
|
+
Requires-Dist: mkdocs; extra == "docs"
|
|
30
|
+
Requires-Dist: mkdocs-material; extra == "docs"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
<div align="center">
|
|
34
|
+
|
|
35
|
+
<img src="docs/assets/logo.svg" width="160" alt="DeepHarness logo">
|
|
36
|
+
|
|
37
|
+
# DeepHarness
|
|
38
|
+
|
|
39
|
+
**Compose LLM agents into typed, concurrent workflows.**
|
|
40
|
+
|
|
41
|
+
A lightweight framework for wiring plain Python functions — and the agents inside them — into a
|
|
42
|
+
graph that runs branches in parallel, routes on conditions, and threads one typed state
|
|
43
|
+
object through the whole thing.
|
|
44
|
+
|
|
45
|
+
[](https://www.python.org/) [](pyproject.toml) [](#quickstart) [](https://github.com/astral-sh/ruff) [](https://sayedshaun.github.io/deepharness/)
|
|
46
|
+
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Why DeepHarness
|
|
52
|
+
|
|
53
|
+
- **One dependency. That's it.** `httpx`. Providers talk to vendor REST APIs
|
|
54
|
+
directly — no vendor SDKs, no transitive dependency sprawl.
|
|
55
|
+
- **Your state is a dataclass.** Not an untyped dict. Your editor autocompletes it, your type
|
|
56
|
+
checker checks it.
|
|
57
|
+
- **Nodes are just functions.** Sync or async, decorated in place. No base class to inherit,
|
|
58
|
+
no runner object to construct.
|
|
59
|
+
- **Parallel by default.** Independent branches run concurrently via `asyncio`; sync functions
|
|
60
|
+
are offloaded to threads so a blocking call never stalls the event loop.
|
|
61
|
+
- **One provider interface, a dozen vendors.** `OpenAI`, `Anthropic`, `Gemini`, and OpenAI-compatible
|
|
62
|
+
gateways (`Groq`, `Together`, `Fireworks`, `DeepSeek`, `Mistral`, `Cerebras`, `OpenRouter`, `XAI`,
|
|
63
|
+
`Ollama`, `LMStudio`, `VLLM`) all share the same `LLM` interface.
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install deepharness
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or install from source:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install git+https://github.com/sayedshaun/deepharness.git
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Quickstart
|
|
78
|
+
|
|
79
|
+
An `Agent` runs a think/act loop against a model: ask for a response, dispatch any tool calls
|
|
80
|
+
it requests, repeat until the model answers with no tool calls.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from deepharness import Agent, Message, OpenAI, tool
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@tool
|
|
87
|
+
def get_weather(city: str) -> str:
|
|
88
|
+
"""Look up the current weather for a city."""
|
|
89
|
+
return f"It is 22°C and sunny in {city}."
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
agent = Agent(
|
|
93
|
+
OpenAI(model="gpt-4o-mini", api_key="sk-..."),
|
|
94
|
+
tools=[get_weather],
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
result = await agent.arun("Weather in Oslo?")
|
|
98
|
+
print(result.output)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
An `Agent` can itself be handed to another agent as a tool via `as_tool()`, so one agent can
|
|
102
|
+
delegate a task to another:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
researcher = Agent(OpenAI(model="gpt-4o-mini", api_key="sk-..."), name="researcher")
|
|
106
|
+
|
|
107
|
+
editor = Agent(
|
|
108
|
+
OpenAI(model="gpt-4o-mini", api_key="sk-..."),
|
|
109
|
+
name="editor",
|
|
110
|
+
tools=[researcher.as_tool(description="Look up facts on a topic.")],
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Graphs
|
|
115
|
+
|
|
116
|
+
For fixed, known-shape workflows — run these steps, some in parallel, then merge — wire plain
|
|
117
|
+
functions (or agents) into a `Graph` instead:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import asyncio
|
|
121
|
+
from dataclasses import dataclass
|
|
122
|
+
|
|
123
|
+
from deepharness import Graph
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass
|
|
127
|
+
class State:
|
|
128
|
+
sales: str = ""
|
|
129
|
+
churn: str = ""
|
|
130
|
+
summary: str = ""
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
graph = Graph(State)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@graph.add(start=True)
|
|
137
|
+
async def fetch_sales(state: State) -> State:
|
|
138
|
+
await asyncio.sleep(0.5)
|
|
139
|
+
state.sales = "Sales up 12% QoQ."
|
|
140
|
+
return state
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@graph.add(start=True)
|
|
144
|
+
async def fetch_churn(state: State) -> State:
|
|
145
|
+
await asyncio.sleep(0.3)
|
|
146
|
+
state.churn = "Churn down to 4%."
|
|
147
|
+
return state
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@graph.add(end=True)
|
|
151
|
+
def summarize(state: State) -> State:
|
|
152
|
+
state.summary = f"{state.sales} {state.churn}"
|
|
153
|
+
return state
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
graph.connect(fetch_sales, summarize)
|
|
157
|
+
graph.connect(fetch_churn, summarize)
|
|
158
|
+
|
|
159
|
+
executor = graph.build()
|
|
160
|
+
result = asyncio.run(executor.run(State()))
|
|
161
|
+
|
|
162
|
+
print(result.summary) # Sales up 12% QoQ. Churn down to 4%.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`fetch_sales` and `fetch_churn` both run in the first wave, concurrently. `summarize` waits
|
|
166
|
+
for both before running.
|
|
167
|
+
|
|
168
|
+
**Agent or Graph?** Reach for `as_tool()` when an LLM should decide at runtime whether and
|
|
169
|
+
which sub-agent to call. Reach for `Graph` when the workflow's shape — which steps, which run
|
|
170
|
+
in parallel, in what order — is known ahead of time.
|
|
171
|
+
|
|
172
|
+
See the **[full documentation](https://sayedshaun.github.io/deepharness/)** for graphs, agents,
|
|
173
|
+
tools, providers, and the API reference.
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pip install -e ".[dev]"
|
|
179
|
+
pytest -q
|
|
180
|
+
ruff format . && ruff check .
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Docs are built with [MkDocs Material](https://squidfunk.github.io/mkdocs-material/):
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
pip install -e ".[docs]"
|
|
187
|
+
mkdocs serve
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
<div align="center">
|
|
193
|
+
<sub>Simple, modular, typed, dependency-light.</sub>
|
|
194
|
+
</div>
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="docs/assets/logo.svg" width="160" alt="DeepHarness logo">
|
|
4
|
+
|
|
5
|
+
# DeepHarness
|
|
6
|
+
|
|
7
|
+
**Compose LLM agents into typed, concurrent workflows.**
|
|
8
|
+
|
|
9
|
+
A lightweight framework for wiring plain Python functions — and the agents inside them — into a
|
|
10
|
+
graph that runs branches in parallel, routes on conditions, and threads one typed state
|
|
11
|
+
object through the whole thing.
|
|
12
|
+
|
|
13
|
+
[](https://www.python.org/) [](pyproject.toml) [](#quickstart) [](https://github.com/astral-sh/ruff) [](https://sayedshaun.github.io/deepharness/)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Why DeepHarness
|
|
20
|
+
|
|
21
|
+
- **One dependency. That's it.** `httpx`. Providers talk to vendor REST APIs
|
|
22
|
+
directly — no vendor SDKs, no transitive dependency sprawl.
|
|
23
|
+
- **Your state is a dataclass.** Not an untyped dict. Your editor autocompletes it, your type
|
|
24
|
+
checker checks it.
|
|
25
|
+
- **Nodes are just functions.** Sync or async, decorated in place. No base class to inherit,
|
|
26
|
+
no runner object to construct.
|
|
27
|
+
- **Parallel by default.** Independent branches run concurrently via `asyncio`; sync functions
|
|
28
|
+
are offloaded to threads so a blocking call never stalls the event loop.
|
|
29
|
+
- **One provider interface, a dozen vendors.** `OpenAI`, `Anthropic`, `Gemini`, and OpenAI-compatible
|
|
30
|
+
gateways (`Groq`, `Together`, `Fireworks`, `DeepSeek`, `Mistral`, `Cerebras`, `OpenRouter`, `XAI`,
|
|
31
|
+
`Ollama`, `LMStudio`, `VLLM`) all share the same `LLM` interface.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install deepharness
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or install from source:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install git+https://github.com/sayedshaun/deepharness.git
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quickstart
|
|
46
|
+
|
|
47
|
+
An `Agent` runs a think/act loop against a model: ask for a response, dispatch any tool calls
|
|
48
|
+
it requests, repeat until the model answers with no tool calls.
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from deepharness import Agent, Message, OpenAI, tool
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@tool
|
|
55
|
+
def get_weather(city: str) -> str:
|
|
56
|
+
"""Look up the current weather for a city."""
|
|
57
|
+
return f"It is 22°C and sunny in {city}."
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
agent = Agent(
|
|
61
|
+
OpenAI(model="gpt-4o-mini", api_key="sk-..."),
|
|
62
|
+
tools=[get_weather],
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
result = await agent.arun("Weather in Oslo?")
|
|
66
|
+
print(result.output)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
An `Agent` can itself be handed to another agent as a tool via `as_tool()`, so one agent can
|
|
70
|
+
delegate a task to another:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
researcher = Agent(OpenAI(model="gpt-4o-mini", api_key="sk-..."), name="researcher")
|
|
74
|
+
|
|
75
|
+
editor = Agent(
|
|
76
|
+
OpenAI(model="gpt-4o-mini", api_key="sk-..."),
|
|
77
|
+
name="editor",
|
|
78
|
+
tools=[researcher.as_tool(description="Look up facts on a topic.")],
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Graphs
|
|
83
|
+
|
|
84
|
+
For fixed, known-shape workflows — run these steps, some in parallel, then merge — wire plain
|
|
85
|
+
functions (or agents) into a `Graph` instead:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import asyncio
|
|
89
|
+
from dataclasses import dataclass
|
|
90
|
+
|
|
91
|
+
from deepharness import Graph
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class State:
|
|
96
|
+
sales: str = ""
|
|
97
|
+
churn: str = ""
|
|
98
|
+
summary: str = ""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
graph = Graph(State)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@graph.add(start=True)
|
|
105
|
+
async def fetch_sales(state: State) -> State:
|
|
106
|
+
await asyncio.sleep(0.5)
|
|
107
|
+
state.sales = "Sales up 12% QoQ."
|
|
108
|
+
return state
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@graph.add(start=True)
|
|
112
|
+
async def fetch_churn(state: State) -> State:
|
|
113
|
+
await asyncio.sleep(0.3)
|
|
114
|
+
state.churn = "Churn down to 4%."
|
|
115
|
+
return state
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@graph.add(end=True)
|
|
119
|
+
def summarize(state: State) -> State:
|
|
120
|
+
state.summary = f"{state.sales} {state.churn}"
|
|
121
|
+
return state
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
graph.connect(fetch_sales, summarize)
|
|
125
|
+
graph.connect(fetch_churn, summarize)
|
|
126
|
+
|
|
127
|
+
executor = graph.build()
|
|
128
|
+
result = asyncio.run(executor.run(State()))
|
|
129
|
+
|
|
130
|
+
print(result.summary) # Sales up 12% QoQ. Churn down to 4%.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`fetch_sales` and `fetch_churn` both run in the first wave, concurrently. `summarize` waits
|
|
134
|
+
for both before running.
|
|
135
|
+
|
|
136
|
+
**Agent or Graph?** Reach for `as_tool()` when an LLM should decide at runtime whether and
|
|
137
|
+
which sub-agent to call. Reach for `Graph` when the workflow's shape — which steps, which run
|
|
138
|
+
in parallel, in what order — is known ahead of time.
|
|
139
|
+
|
|
140
|
+
See the **[full documentation](https://sayedshaun.github.io/deepharness/)** for graphs, agents,
|
|
141
|
+
tools, providers, and the API reference.
|
|
142
|
+
|
|
143
|
+
## Development
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
pip install -e ".[dev]"
|
|
147
|
+
pytest -q
|
|
148
|
+
ruff format . && ruff check .
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Docs are built with [MkDocs Material](https://squidfunk.github.io/mkdocs-material/):
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pip install -e ".[docs]"
|
|
155
|
+
mkdocs serve
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
<div align="center">
|
|
161
|
+
<sub>Simple, modular, typed, dependency-light.</sub>
|
|
162
|
+
</div>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from deepharness.agent import (
|
|
2
|
+
FINAL_TOOL,
|
|
3
|
+
Agent,
|
|
4
|
+
AgentState,
|
|
5
|
+
Budget,
|
|
6
|
+
Ctx,
|
|
7
|
+
Finished,
|
|
8
|
+
Message,
|
|
9
|
+
PendingHumanInput,
|
|
10
|
+
StopReason,
|
|
11
|
+
TokenBudgetExceeded,
|
|
12
|
+
Toolbox,
|
|
13
|
+
ToolSpec,
|
|
14
|
+
load_session,
|
|
15
|
+
save_session,
|
|
16
|
+
tool,
|
|
17
|
+
)
|
|
18
|
+
from deepharness.errors import (
|
|
19
|
+
ConfigurationError,
|
|
20
|
+
DeepHarnessError,
|
|
21
|
+
HumanInputRequired,
|
|
22
|
+
ProviderError,
|
|
23
|
+
ToolNotFoundError,
|
|
24
|
+
)
|
|
25
|
+
from deepharness.graph import (
|
|
26
|
+
ConcurrentUpdateError,
|
|
27
|
+
ExecutionError,
|
|
28
|
+
Executor,
|
|
29
|
+
Graph,
|
|
30
|
+
NodeSpec,
|
|
31
|
+
StepLimitExceeded,
|
|
32
|
+
concat,
|
|
33
|
+
merge_dicts,
|
|
34
|
+
)
|
|
35
|
+
from deepharness.providers import (
|
|
36
|
+
VLLM,
|
|
37
|
+
XAI,
|
|
38
|
+
Anthropic,
|
|
39
|
+
Cerebras,
|
|
40
|
+
Completed,
|
|
41
|
+
DeepSeek,
|
|
42
|
+
Fireworks,
|
|
43
|
+
Gemini,
|
|
44
|
+
Groq,
|
|
45
|
+
LMStudio,
|
|
46
|
+
Mistral,
|
|
47
|
+
Ollama,
|
|
48
|
+
OpenAI,
|
|
49
|
+
OpenRouter,
|
|
50
|
+
TextDelta,
|
|
51
|
+
Together,
|
|
52
|
+
TokenUsage,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
__all__ = [
|
|
56
|
+
"FINAL_TOOL",
|
|
57
|
+
"VLLM",
|
|
58
|
+
"XAI",
|
|
59
|
+
"Agent",
|
|
60
|
+
"AgentState",
|
|
61
|
+
"Anthropic",
|
|
62
|
+
"Budget",
|
|
63
|
+
"Cerebras",
|
|
64
|
+
"Completed",
|
|
65
|
+
"ConcurrentUpdateError",
|
|
66
|
+
"ConfigurationError",
|
|
67
|
+
"Ctx",
|
|
68
|
+
"DeepHarnessError",
|
|
69
|
+
"DeepSeek",
|
|
70
|
+
"ExecutionError",
|
|
71
|
+
"Executor",
|
|
72
|
+
"Finished",
|
|
73
|
+
"Fireworks",
|
|
74
|
+
"Gemini",
|
|
75
|
+
"Graph",
|
|
76
|
+
"Groq",
|
|
77
|
+
"HumanInputRequired",
|
|
78
|
+
"LMStudio",
|
|
79
|
+
"Message",
|
|
80
|
+
"Mistral",
|
|
81
|
+
"NodeSpec",
|
|
82
|
+
"Ollama",
|
|
83
|
+
"OpenAI",
|
|
84
|
+
"OpenRouter",
|
|
85
|
+
"PendingHumanInput",
|
|
86
|
+
"ProviderError",
|
|
87
|
+
"StepLimitExceeded",
|
|
88
|
+
"StopReason",
|
|
89
|
+
"TextDelta",
|
|
90
|
+
"Together",
|
|
91
|
+
"TokenBudgetExceeded",
|
|
92
|
+
"TokenUsage",
|
|
93
|
+
"ToolNotFoundError",
|
|
94
|
+
"ToolSpec",
|
|
95
|
+
"Toolbox",
|
|
96
|
+
"concat",
|
|
97
|
+
"load_session",
|
|
98
|
+
"merge_dicts",
|
|
99
|
+
"save_session",
|
|
100
|
+
"tool",
|
|
101
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from ..tools.toolbox import Ctx, Toolbox, ToolSpec, tool
|
|
2
|
+
from .loop import Agent, TokenBudgetExceeded
|
|
3
|
+
from .output import FINAL_TOOL
|
|
4
|
+
from .state import (
|
|
5
|
+
AgentState,
|
|
6
|
+
Budget,
|
|
7
|
+
Finished,
|
|
8
|
+
Message,
|
|
9
|
+
PendingHumanInput,
|
|
10
|
+
StopReason,
|
|
11
|
+
as_dict,
|
|
12
|
+
load_session,
|
|
13
|
+
save_session,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"FINAL_TOOL",
|
|
18
|
+
"Agent",
|
|
19
|
+
"AgentState",
|
|
20
|
+
"Budget",
|
|
21
|
+
"Ctx",
|
|
22
|
+
"Finished",
|
|
23
|
+
"Message",
|
|
24
|
+
"PendingHumanInput",
|
|
25
|
+
"StopReason",
|
|
26
|
+
"TokenBudgetExceeded",
|
|
27
|
+
"ToolSpec",
|
|
28
|
+
"Toolbox",
|
|
29
|
+
"as_dict",
|
|
30
|
+
"load_session",
|
|
31
|
+
"save_session",
|
|
32
|
+
"tool",
|
|
33
|
+
]
|