pyharness-ai 0.6.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.
Files changed (45) hide show
  1. pyharness_ai-0.6.2/LICENSE +21 -0
  2. pyharness_ai-0.6.2/PKG-INFO +230 -0
  3. pyharness_ai-0.6.2/README.md +167 -0
  4. pyharness_ai-0.6.2/mcp_servers.json +27 -0
  5. pyharness_ai-0.6.2/pyproject.toml +96 -0
  6. pyharness_ai-0.6.2/src/pyharness/__init__.py +65 -0
  7. pyharness_ai-0.6.2/src/pyharness/cli.py +12 -0
  8. pyharness_ai-0.6.2/src/pyharness/context.py +177 -0
  9. pyharness_ai-0.6.2/src/pyharness/core.py +726 -0
  10. pyharness_ai-0.6.2/src/pyharness/plugins/__init__.py +5 -0
  11. pyharness_ai-0.6.2/src/pyharness/plugins/builtin.py +65 -0
  12. pyharness_ai-0.6.2/src/pyharness/plugins/cli/__init__.py +10 -0
  13. pyharness_ai-0.6.2/src/pyharness/plugins/cli/app.py +179 -0
  14. pyharness_ai-0.6.2/src/pyharness/plugins/cli/ui.py +50 -0
  15. pyharness_ai-0.6.2/src/pyharness/plugins/context_compaction.py +209 -0
  16. pyharness_ai-0.6.2/src/pyharness/plugins/embedding.py +109 -0
  17. pyharness_ai-0.6.2/src/pyharness/plugins/guard_approval.py +220 -0
  18. pyharness_ai-0.6.2/src/pyharness/plugins/llm/__init__.py +7 -0
  19. pyharness_ai-0.6.2/src/pyharness/plugins/llm/dummy.py +65 -0
  20. pyharness_ai-0.6.2/src/pyharness/plugins/llm/entry.py +120 -0
  21. pyharness_ai-0.6.2/src/pyharness/plugins/llm/http.py +185 -0
  22. pyharness_ai-0.6.2/src/pyharness/plugins/llm/provider.py +108 -0
  23. pyharness_ai-0.6.2/src/pyharness/plugins/mcp_client.py +269 -0
  24. pyharness_ai-0.6.2/src/pyharness/plugins/mcp_config.py +68 -0
  25. pyharness_ai-0.6.2/src/pyharness/plugins/mcp_transport.py +152 -0
  26. pyharness_ai-0.6.2/src/pyharness/plugins/session_store.py +555 -0
  27. pyharness_ai-0.6.2/src/pyharness/plugins/text_splitter.py +135 -0
  28. pyharness_ai-0.6.2/src/pyharness/plugins/tool_fs.py +240 -0
  29. pyharness_ai-0.6.2/src/pyharness/plugins/tool_hybrid_search.py +164 -0
  30. pyharness_ai-0.6.2/src/pyharness/plugins/tool_knowledge.py +274 -0
  31. pyharness_ai-0.6.2/src/pyharness/plugins/tool_subagent.py +195 -0
  32. pyharness_ai-0.6.2/src/pyharness/plugins/tool_web.py +253 -0
  33. pyharness_ai-0.6.2/src/pyharness/plugins/ui_cli.py +76 -0
  34. pyharness_ai-0.6.2/src/pyharness/plugins/ui_websocket.py +39 -0
  35. pyharness_ai-0.6.2/src/pyharness/plugins/vector_store.py +145 -0
  36. pyharness_ai-0.6.2/src/pyharness/plugins/web/__init__.py +18 -0
  37. pyharness_ai-0.6.2/src/pyharness/plugins/web/__main__.py +15 -0
  38. pyharness_ai-0.6.2/src/pyharness/plugins/web/app.py +172 -0
  39. pyharness_ai-0.6.2/src/pyharness/plugins/web_ui.py +361 -0
  40. pyharness_ai-0.6.2/src/pyharness/plugins/workflow.py +769 -0
  41. pyharness_ai-0.6.2/src/pyharness/schema.py +439 -0
  42. pyharness_ai-0.6.2/src/pyharness/specs.py +303 -0
  43. pyharness_ai-0.6.2/static/app.js +515 -0
  44. pyharness_ai-0.6.2/static/index.html +96 -0
  45. pyharness_ai-0.6.2/static/style.css +597 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 PyHarness
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,230 @@
1
+ Metadata-Version: 2.5
2
+ Name: pyharness-ai
3
+ Version: 0.6.2
4
+ Summary: PyHarness: Everything is a Plugin. A Python Agent Framework.
5
+ Project-URL: Homepage, https://github.com/pyharness/pyharness
6
+ Project-URL: Repository, https://github.com/pyharness/pyharness
7
+ Project-URL: Issues, https://github.com/pyharness/pyharness/issues
8
+ Author-email: PyHarness <contact@pyharness.io>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,framework,llm,mcp,plugin,rag,workflow
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: pluggy>=1.5
22
+ Requires-Dist: pydantic>=2.7
23
+ Provides-Extra: all
24
+ Requires-Dist: aiofiles>=23.0; extra == 'all'
25
+ Requires-Dist: aiosqlite>=0.20; extra == 'all'
26
+ Requires-Dist: beautifulsoup4>=4.12; extra == 'all'
27
+ Requires-Dist: fastapi>=0.110; extra == 'all'
28
+ Requires-Dist: httpx>=0.27; extra == 'all'
29
+ Requires-Dist: markdownify>=0.12; extra == 'all'
30
+ Requires-Dist: numpy>=1.26; extra == 'all'
31
+ Requires-Dist: rich>=13.7; extra == 'all'
32
+ Requires-Dist: typer>=0.12; extra == 'all'
33
+ Requires-Dist: uvicorn[standard]>=0.29; extra == 'all'
34
+ Requires-Dist: websockets>=12; extra == 'all'
35
+ Provides-Extra: cli
36
+ Requires-Dist: rich>=13.7; extra == 'cli'
37
+ Requires-Dist: typer>=0.12; extra == 'cli'
38
+ Provides-Extra: dev
39
+ Requires-Dist: aiofiles>=23.0; extra == 'dev'
40
+ Requires-Dist: fastapi[standard]>=0.110; extra == 'dev'
41
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
42
+ Requires-Dist: pytest>=8; extra == 'dev'
43
+ Requires-Dist: ruff>=0.5; extra == 'dev'
44
+ Requires-Dist: websockets>=12; extra == 'dev'
45
+ Provides-Extra: llm
46
+ Requires-Dist: httpx>=0.27; extra == 'llm'
47
+ Provides-Extra: mcp
48
+ Requires-Dist: httpx>=0.27; extra == 'mcp'
49
+ Provides-Extra: memory
50
+ Requires-Dist: aiosqlite>=0.20; extra == 'memory'
51
+ Provides-Extra: rag
52
+ Requires-Dist: numpy>=1.26; extra == 'rag'
53
+ Provides-Extra: server
54
+ Requires-Dist: aiofiles>=23.0; extra == 'server'
55
+ Requires-Dist: fastapi>=0.110; extra == 'server'
56
+ Requires-Dist: uvicorn[standard]>=0.29; extra == 'server'
57
+ Requires-Dist: websockets>=12; extra == 'server'
58
+ Provides-Extra: web
59
+ Requires-Dist: beautifulsoup4>=4.12; extra == 'web'
60
+ Requires-Dist: httpx>=0.27; extra == 'web'
61
+ Requires-Dist: markdownify>=0.12; extra == 'web'
62
+ Description-Content-Type: text/markdown
63
+
64
+ # PyHarness — Everything is a Plugin
65
+
66
+ [![PyPI version](https://badge.fury.io/py/pyharness.svg)](https://badge.fury.io/py/pyharness)
67
+ [![CI Status](https://github.com/pyharness/pyharness/actions/workflows/ci.yml/badge.svg)](https://github.com/pyharness/pyharness/actions/workflows/ci.yml)
68
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
69
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
70
+
71
+ > **万物皆插件。** 一个基于 pluggy + Pydantic V2 的极简 Python Agent 框架,对标 DeepSeek Harness。
72
+
73
+ ---
74
+
75
+ ## ✨ Features
76
+
77
+ | 特性 | 说明 |
78
+ |------|------|
79
+ | 🧩 **万物皆插件** | LLM 提供方、工具执行器、CLI、Web UI 全部通过 `@hookimpl` 注册,核心零依赖 |
80
+ | 🧠 **流式思考** | 支持 SSE 流式输出,实时展示 Agent 思考过程 |
81
+ | 📋 **Plan 编排** | LLM 生成结构化执行计划,拓扑排序 + TaskGroup 并行执行 |
82
+ | 🤖 **Subagent 并行** | 自动派生子 Agent,TaskGroup 并行执行,支持超时与重试 |
83
+ | 🔒 **Human-in-the-loop** | 异步审批机制,高危工具执行前人工确认 |
84
+ | 💾 **SQLite 持久化** | 会话状态 + FTS5 全文检索,重启后恢复执行 |
85
+ | 🌐 **Web UI** | FastAPI + WebSocket 实时推送,三栏式对话界面 |
86
+ | ⏪ **可逆状态** | Frozen Pydantic + `model_copy`,支持分支、回滚、多分支搜索 |
87
+
88
+ ---
89
+
90
+ ## 🚀 Quick Start
91
+
92
+ ```bash
93
+ # 安装(含全部可选依赖)
94
+ pip install pyharness[all]
95
+
96
+ # 配置 API Key
97
+ export DEEPSEEK_API_KEY="sk-..."
98
+
99
+ # 启动 Web UI
100
+ pyharness serve
101
+ # → 打开浏览器访问 http://127.0.0.1:3080
102
+ ```
103
+
104
+ ### CLI 模式
105
+
106
+ ```bash
107
+ # 单轮对话
108
+ pyharness run --provider http -m deepseek-chat -i "Hello"
109
+
110
+ # 流式 REPL
111
+ pyharness chat --provider http -m deepseek-chat
112
+
113
+ # 查看版本
114
+ pyharness version
115
+ ```
116
+
117
+ ### Python API
118
+
119
+ ```python
120
+ from pyharness import Harness, AgentConfig
121
+ from pyharness.plugins.llm import entry as llm
122
+
123
+ # 初始化 Harness(自动加载内置插件)
124
+ h = Harness()
125
+
126
+ # 配置 LLM 提供方
127
+ llm.use_http(
128
+ models=("deepseek-chat",),
129
+ base_url="https://api.deepseek.com/v1",
130
+ api_key="sk-...",
131
+ )
132
+
133
+ # 运行 Agent 会话
134
+ ctx = await h.run_session(
135
+ AgentConfig(name="demo", model="deepseek-chat"),
136
+ initial_text="用 Python 写一个快速排序",
137
+ )
138
+
139
+ # 流式输出
140
+ async for chunk in h.stream_session(
141
+ AgentConfig(name="demo", model="deepseek-chat"),
142
+ initial_text="用 Python 写一个快速排序",
143
+ ):
144
+ print(chunk.delta, end="")
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 🏗️ Architecture
150
+
151
+ ```mermaid
152
+ graph TD
153
+ subgraph Core["🧠 PyHarness Core"]
154
+ Harness["Harness<br/>(EventBus + Session Lifecycle)"]
155
+ Specs["AgentHooks<br/>(pluggy contract)"]
156
+ Schema["Pydantic V2 Schema<br/>(Frozen + model_copy)"]
157
+ end
158
+
159
+ subgraph Plugins["🔌 Plugins"]
160
+ LLM["LLM Provider<br/>(dummy / http / stream)"]
161
+ Tools["Tool Executors<br/>(python / fs / web)"]
162
+ CLI["CLI Plugin<br/>(typer + rich)"]
163
+ WebUI["Web UI Plugin<br/>(FastAPI + WebSocket)"]
164
+ Store["Session Store<br/>(SQLite + FTS5)"]
165
+ Guard["Guard Approval<br/>(human-in-the-loop)"]
166
+ Workflow["Workflow<br/>(Plan + Subagent)"]
167
+ end
168
+
169
+ Harness --> Specs
170
+ Harness --> Schema
171
+ Harness --> Plugins
172
+
173
+ style Core fill:#1a1a2e,color:#fff,stroke:#e94560,stroke-width:2px
174
+ style Plugins fill:#16213e,color:#fff,stroke:#0f3460,stroke-width:2px
175
+ ```
176
+
177
+ **设计哲学**:核心只做三件事 —— 事件总线 (`pluggy`)、上下文管理 (`contextvars`)、插件加载。所有领域能力(LLM、工具、UI)都通过插件注入。
178
+
179
+ ---
180
+
181
+ ## 🛠️ Built-in Plugins
182
+
183
+ | 插件 | 入口 | 说明 |
184
+ |------|------|------|
185
+ | `builtin` | `pyharness.plugins.builtin` | Echo 工具示例 |
186
+ | `llm` | `pyharness.plugins.llm.entry` | LLM 提供方:Dummy / HTTP (OpenAI 兼容) |
187
+ | `ui-cli` | `pyharness.plugins.ui_cli` | 终端 CLI:`pyharness chat` / `run` |
188
+ | `web` | `pyharness.plugins.web_ui` | Web UI:FastAPI REST + WebSocket |
189
+ | `memory` | `pyharness.plugins.session_store` | SQLite 持久化 + FTS5 全文检索 |
190
+ | `guard-approval` | `pyharness.plugins.guard_approval` | 异步人工审批 |
191
+ | `context-compaction` | `pyharness.plugins.context_compaction` | 上下文压缩 |
192
+ | `subagent` | `pyharness.plugins.tool_subagent` | 子 Agent 并行编排 |
193
+ | `workflow` | `pyharness.plugins.workflow` | Plan 拓扑调度 + 自动重试 |
194
+ | `fs` | `pyharness.plugins.tool_fs` | 文件系统工具 |
195
+ | `web` | `pyharness.plugins.tool_web` | 网页抓取工具 |
196
+
197
+ ---
198
+
199
+ ## 🧪 Testing
200
+
201
+ ```bash
202
+ # 安装开发依赖
203
+ pip install -e ".[dev]"
204
+
205
+ # 运行测试
206
+ pytest tests/ -v
207
+
208
+ # Lint
209
+ ruff check src/ tests/
210
+ ```
211
+
212
+ > **75 个测试全绿**,覆盖 Core、LLM、CLI、Web UI、Workflow、Session Store。
213
+
214
+ ---
215
+
216
+ ## 🤝 Contributing
217
+
218
+ Contributions are welcome! Please feel free to submit a Pull Request.
219
+
220
+ 1. Fork the repository
221
+ 2. Create your feature branch (`git checkout -b feat/amazing-feature`)
222
+ 3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
223
+ 4. Push to the branch (`git push origin feat/amazing-feature`)
224
+ 5. Open a Pull Request
225
+
226
+ ---
227
+
228
+ ## License
229
+
230
+ Distributed under the MIT License. See `LICENSE` for more information.
@@ -0,0 +1,167 @@
1
+ # PyHarness — Everything is a Plugin
2
+
3
+ [![PyPI version](https://badge.fury.io/py/pyharness.svg)](https://badge.fury.io/py/pyharness)
4
+ [![CI Status](https://github.com/pyharness/pyharness/actions/workflows/ci.yml/badge.svg)](https://github.com/pyharness/pyharness/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
7
+
8
+ > **万物皆插件。** 一个基于 pluggy + Pydantic V2 的极简 Python Agent 框架,对标 DeepSeek Harness。
9
+
10
+ ---
11
+
12
+ ## ✨ Features
13
+
14
+ | 特性 | 说明 |
15
+ |------|------|
16
+ | 🧩 **万物皆插件** | LLM 提供方、工具执行器、CLI、Web UI 全部通过 `@hookimpl` 注册,核心零依赖 |
17
+ | 🧠 **流式思考** | 支持 SSE 流式输出,实时展示 Agent 思考过程 |
18
+ | 📋 **Plan 编排** | LLM 生成结构化执行计划,拓扑排序 + TaskGroup 并行执行 |
19
+ | 🤖 **Subagent 并行** | 自动派生子 Agent,TaskGroup 并行执行,支持超时与重试 |
20
+ | 🔒 **Human-in-the-loop** | 异步审批机制,高危工具执行前人工确认 |
21
+ | 💾 **SQLite 持久化** | 会话状态 + FTS5 全文检索,重启后恢复执行 |
22
+ | 🌐 **Web UI** | FastAPI + WebSocket 实时推送,三栏式对话界面 |
23
+ | ⏪ **可逆状态** | Frozen Pydantic + `model_copy`,支持分支、回滚、多分支搜索 |
24
+
25
+ ---
26
+
27
+ ## 🚀 Quick Start
28
+
29
+ ```bash
30
+ # 安装(含全部可选依赖)
31
+ pip install pyharness[all]
32
+
33
+ # 配置 API Key
34
+ export DEEPSEEK_API_KEY="sk-..."
35
+
36
+ # 启动 Web UI
37
+ pyharness serve
38
+ # → 打开浏览器访问 http://127.0.0.1:3080
39
+ ```
40
+
41
+ ### CLI 模式
42
+
43
+ ```bash
44
+ # 单轮对话
45
+ pyharness run --provider http -m deepseek-chat -i "Hello"
46
+
47
+ # 流式 REPL
48
+ pyharness chat --provider http -m deepseek-chat
49
+
50
+ # 查看版本
51
+ pyharness version
52
+ ```
53
+
54
+ ### Python API
55
+
56
+ ```python
57
+ from pyharness import Harness, AgentConfig
58
+ from pyharness.plugins.llm import entry as llm
59
+
60
+ # 初始化 Harness(自动加载内置插件)
61
+ h = Harness()
62
+
63
+ # 配置 LLM 提供方
64
+ llm.use_http(
65
+ models=("deepseek-chat",),
66
+ base_url="https://api.deepseek.com/v1",
67
+ api_key="sk-...",
68
+ )
69
+
70
+ # 运行 Agent 会话
71
+ ctx = await h.run_session(
72
+ AgentConfig(name="demo", model="deepseek-chat"),
73
+ initial_text="用 Python 写一个快速排序",
74
+ )
75
+
76
+ # 流式输出
77
+ async for chunk in h.stream_session(
78
+ AgentConfig(name="demo", model="deepseek-chat"),
79
+ initial_text="用 Python 写一个快速排序",
80
+ ):
81
+ print(chunk.delta, end="")
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 🏗️ Architecture
87
+
88
+ ```mermaid
89
+ graph TD
90
+ subgraph Core["🧠 PyHarness Core"]
91
+ Harness["Harness<br/>(EventBus + Session Lifecycle)"]
92
+ Specs["AgentHooks<br/>(pluggy contract)"]
93
+ Schema["Pydantic V2 Schema<br/>(Frozen + model_copy)"]
94
+ end
95
+
96
+ subgraph Plugins["🔌 Plugins"]
97
+ LLM["LLM Provider<br/>(dummy / http / stream)"]
98
+ Tools["Tool Executors<br/>(python / fs / web)"]
99
+ CLI["CLI Plugin<br/>(typer + rich)"]
100
+ WebUI["Web UI Plugin<br/>(FastAPI + WebSocket)"]
101
+ Store["Session Store<br/>(SQLite + FTS5)"]
102
+ Guard["Guard Approval<br/>(human-in-the-loop)"]
103
+ Workflow["Workflow<br/>(Plan + Subagent)"]
104
+ end
105
+
106
+ Harness --> Specs
107
+ Harness --> Schema
108
+ Harness --> Plugins
109
+
110
+ style Core fill:#1a1a2e,color:#fff,stroke:#e94560,stroke-width:2px
111
+ style Plugins fill:#16213e,color:#fff,stroke:#0f3460,stroke-width:2px
112
+ ```
113
+
114
+ **设计哲学**:核心只做三件事 —— 事件总线 (`pluggy`)、上下文管理 (`contextvars`)、插件加载。所有领域能力(LLM、工具、UI)都通过插件注入。
115
+
116
+ ---
117
+
118
+ ## 🛠️ Built-in Plugins
119
+
120
+ | 插件 | 入口 | 说明 |
121
+ |------|------|------|
122
+ | `builtin` | `pyharness.plugins.builtin` | Echo 工具示例 |
123
+ | `llm` | `pyharness.plugins.llm.entry` | LLM 提供方:Dummy / HTTP (OpenAI 兼容) |
124
+ | `ui-cli` | `pyharness.plugins.ui_cli` | 终端 CLI:`pyharness chat` / `run` |
125
+ | `web` | `pyharness.plugins.web_ui` | Web UI:FastAPI REST + WebSocket |
126
+ | `memory` | `pyharness.plugins.session_store` | SQLite 持久化 + FTS5 全文检索 |
127
+ | `guard-approval` | `pyharness.plugins.guard_approval` | 异步人工审批 |
128
+ | `context-compaction` | `pyharness.plugins.context_compaction` | 上下文压缩 |
129
+ | `subagent` | `pyharness.plugins.tool_subagent` | 子 Agent 并行编排 |
130
+ | `workflow` | `pyharness.plugins.workflow` | Plan 拓扑调度 + 自动重试 |
131
+ | `fs` | `pyharness.plugins.tool_fs` | 文件系统工具 |
132
+ | `web` | `pyharness.plugins.tool_web` | 网页抓取工具 |
133
+
134
+ ---
135
+
136
+ ## 🧪 Testing
137
+
138
+ ```bash
139
+ # 安装开发依赖
140
+ pip install -e ".[dev]"
141
+
142
+ # 运行测试
143
+ pytest tests/ -v
144
+
145
+ # Lint
146
+ ruff check src/ tests/
147
+ ```
148
+
149
+ > **75 个测试全绿**,覆盖 Core、LLM、CLI、Web UI、Workflow、Session Store。
150
+
151
+ ---
152
+
153
+ ## 🤝 Contributing
154
+
155
+ Contributions are welcome! Please feel free to submit a Pull Request.
156
+
157
+ 1. Fork the repository
158
+ 2. Create your feature branch (`git checkout -b feat/amazing-feature`)
159
+ 3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
160
+ 4. Push to the branch (`git push origin feat/amazing-feature`)
161
+ 5. Open a Pull Request
162
+
163
+ ---
164
+
165
+ ## License
166
+
167
+ Distributed under the MIT License. See `LICENSE` for more information.
@@ -0,0 +1,27 @@
1
+ {
2
+ "mcpServers": {
3
+ "filesystem": {
4
+ "command": "npx",
5
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"],
6
+ "enabled": false
7
+ },
8
+ "github": {
9
+ "command": "npx",
10
+ "args": ["-y", "@modelcontextprotocol/server-github"],
11
+ "env": {
12
+ "GITHUB_TOKEN": ""
13
+ },
14
+ "enabled": false
15
+ },
16
+ "memory": {
17
+ "command": "npx",
18
+ "args": ["-y", "@modelcontextprotocol/server-memory"],
19
+ "enabled": false
20
+ },
21
+ "puppeteer": {
22
+ "command": "npx",
23
+ "args": ["-y", "@modelcontextprotocol/server-puppeteer"],
24
+ "enabled": false
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,96 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "pyharness-ai"
7
+ version = "0.6.2"
8
+ description = "PyHarness: Everything is a Plugin. A Python Agent Framework."
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.11"
12
+ authors = [
13
+ {name = "PyHarness", email = "contact@pyharness.io"},
14
+ ]
15
+ keywords = ["agent", "ai", "llm", "framework", "plugin", "mcp", "rag", "workflow"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ "Topic :: Software Development :: Libraries :: Application Frameworks",
25
+ ]
26
+ dependencies = ["pluggy>=1.5", "pydantic>=2.7"]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/pyharness/pyharness"
30
+ Repository = "https://github.com/pyharness/pyharness"
31
+ Issues = "https://github.com/pyharness/pyharness/issues"
32
+
33
+ [project.scripts]
34
+ pyharness = "pyharness.cli:app"
35
+
36
+ [project.optional-dependencies]
37
+ cli = ["typer>=0.12", "rich>=13.7"]
38
+ server = ["fastapi>=0.110", "uvicorn[standard]>=0.29", "websockets>=12", "aiofiles>=23.0"]
39
+ llm = ["httpx>=0.27"]
40
+ web = ["httpx>=0.27", "beautifulsoup4>=4.12", "markdownify>=0.12"]
41
+ memory = ["aiosqlite>=0.20"]
42
+ rag = ["numpy>=1.26"]
43
+ mcp = ["httpx>=0.27"]
44
+ dev = [
45
+ "pytest>=8",
46
+ "pytest-asyncio>=0.23",
47
+ "ruff>=0.5",
48
+ "fastapi[standard]>=0.110",
49
+ "websockets>=12",
50
+ "aiofiles>=23.0",
51
+ ]
52
+ all = [
53
+ "typer>=0.12",
54
+ "rich>=13.7",
55
+ "fastapi>=0.110",
56
+ "uvicorn[standard]>=0.29",
57
+ "websockets>=12",
58
+ "aiofiles>=23.0",
59
+ "httpx>=0.27",
60
+ "beautifulsoup4>=4.12",
61
+ "markdownify>=0.12",
62
+ "aiosqlite>=0.20",
63
+ "numpy>=1.26",
64
+ ]
65
+
66
+ # Everything is a plugin: plugins discover & register through this group.
67
+ [project.entry-points."pyharness.plugins"]
68
+ builtin = "pyharness.plugins.builtin"
69
+ llm = "pyharness.plugins.llm.entry"
70
+ context-compaction = "pyharness.plugins.context_compaction"
71
+ guard-approval = "pyharness.plugins.guard_approval"
72
+ ui-cli = "pyharness.plugins.ui_cli"
73
+ fs = "pyharness.plugins.tool_fs"
74
+ web = "pyharness.plugins.tool_web"
75
+ memory = "pyharness.plugins.session_store"
76
+ subagent = "pyharness.plugins.tool_subagent"
77
+ workflow = "pyharness.plugins.workflow"
78
+ mcp = "pyharness.plugins.mcp_client"
79
+
80
+ [tool.hatch.build.targets.wheel]
81
+ packages = ["src/pyharness"]
82
+
83
+ [tool.hatch.build.targets.sdist]
84
+ include = ["src/", "README.md", "LICENSE", "static/", "mcp_servers.json"]
85
+
86
+ [tool.pytest.ini_options]
87
+ asyncio_mode = "auto"
88
+ testpaths = ["tests"]
89
+ filterwarnings = ["ignore:.*starlette.testclient.*deprecated.*"]
90
+
91
+ [tool.ruff]
92
+ line-length = 120
93
+ target-version = "py311"
94
+
95
+ [tool.ruff.lint]
96
+ select = ["E", "F", "I", "UP"]
@@ -0,0 +1,65 @@
1
+ """PyHarness — Everything is a Plugin.
2
+
3
+ A thin-core agent harness. The engine owns only the Event Bus (pluggy),
4
+ Context Management (contextvars) and Plugin Loading; every domain capability
5
+ (LLM providers, tool executors, CLIs, Web UIs) arrives as a plugin via
6
+ ``@hookimpl``. State is schema-driven (pydantic v2) and reversible
7
+ (``model_copy(update=...)`` snapshots).
8
+ """
9
+
10
+ from pyharness.context import (
11
+ SessionContext,
12
+ current_context,
13
+ open_session,
14
+ require_context,
15
+ )
16
+ from pyharness.core import EventBus, Harness
17
+ from pyharness.schema import (
18
+ AgentConfig,
19
+ Event,
20
+ EventType,
21
+ HarnessConfig,
22
+ LLMRequest,
23
+ LLMResponse,
24
+ LLMStreamChunk,
25
+ Message,
26
+ Role,
27
+ StepStatus,
28
+ ToolArg,
29
+ ToolCall,
30
+ ToolResult,
31
+ ToolResultStatus,
32
+ ToolSpec,
33
+ WorkflowPlan,
34
+ WorkflowStep,
35
+ )
36
+ from pyharness.specs import AgentHooks
37
+
38
+ __version__ = "0.6.2"
39
+
40
+ __all__ = [
41
+ "AgentConfig",
42
+ "AgentHooks",
43
+ "Event",
44
+ "EventBus",
45
+ "EventType",
46
+ "Harness",
47
+ "HarnessConfig",
48
+ "LLMRequest",
49
+ "LLMResponse",
50
+ "LLMStreamChunk",
51
+ "Message",
52
+ "Role",
53
+ "SessionContext",
54
+ "StepStatus",
55
+ "ToolArg",
56
+ "ToolCall",
57
+ "ToolResult",
58
+ "ToolResultStatus",
59
+ "ToolSpec",
60
+ "WorkflowPlan",
61
+ "WorkflowStep",
62
+ "current_context",
63
+ "open_session",
64
+ "require_context",
65
+ ]
@@ -0,0 +1,12 @@
1
+ """PyHarness top-level CLI entry point.
2
+
3
+ Exposes the ``pyharness`` command as defined in ``pyproject.toml``
4
+ ``[project.scripts]``.
5
+
6
+ This thin wrapper delegates to the real Typer app implemented in
7
+ :mod:`pyharness.plugins.cli.app`.
8
+ """
9
+
10
+ from pyharness.plugins.cli.app import app
11
+
12
+ __all__ = ["app"]