soothe-daemon 0.5.6__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.
- soothe_daemon-0.5.6/.gitignore +218 -0
- soothe_daemon-0.5.6/PKG-INFO +75 -0
- soothe_daemon-0.5.6/README.md +34 -0
- soothe_daemon-0.5.6/pyproject.toml +105 -0
- soothe_daemon-0.5.6/src/soothe_daemon/README.md +122 -0
- soothe_daemon-0.5.6/src/soothe_daemon/__init__.py +9 -0
- soothe_daemon-0.5.6/src/soothe_daemon/__main__.py +6 -0
- soothe_daemon-0.5.6/src/soothe_daemon/_handlers.py +288 -0
- soothe_daemon-0.5.6/src/soothe_daemon/_rpc_handlers.py +406 -0
- soothe_daemon-0.5.6/src/soothe_daemon/bootstrap_env.py +35 -0
- soothe_daemon-0.5.6/src/soothe_daemon/cli/__init__.py +1 -0
- soothe_daemon-0.5.6/src/soothe_daemon/cli/daemon_main.py +355 -0
- soothe_daemon-0.5.6/src/soothe_daemon/client_session.py +369 -0
- soothe_daemon-0.5.6/src/soothe_daemon/config/__init__.py +29 -0
- soothe_daemon-0.5.6/src/soothe_daemon/config/env.py +23 -0
- soothe_daemon-0.5.6/src/soothe_daemon/config/models.py +252 -0
- soothe_daemon-0.5.6/src/soothe_daemon/config/settings.py +167 -0
- soothe_daemon-0.5.6/src/soothe_daemon/entrypoint.py +121 -0
- soothe_daemon-0.5.6/src/soothe_daemon/event_bus.py +273 -0
- soothe_daemon-0.5.6/src/soothe_daemon/event_size_stats.py +166 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/__init__.py +50 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checker.py +243 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/__init__.py +3 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/config_check.py +196 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/daemon_check.py +673 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/embedding_warmup_check.py +92 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/external_apis_check.py +177 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/mcp_check.py +118 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/observability_check.py +162 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/persistence_check.py +242 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/protocols_check.py +66 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/providers_check.py +143 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/checks/vector_stores_check.py +156 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/formatters.py +194 -0
- soothe_daemon-0.5.6/src/soothe_daemon/health/models.py +133 -0
- soothe_daemon-0.5.6/src/soothe_daemon/image_understanding.py +177 -0
- soothe_daemon-0.5.6/src/soothe_daemon/logging.py +90 -0
- soothe_daemon-0.5.6/src/soothe_daemon/loop_isolation.py +177 -0
- soothe_daemon-0.5.6/src/soothe_daemon/message_router.py +1486 -0
- soothe_daemon-0.5.6/src/soothe_daemon/paths.py +23 -0
- soothe_daemon-0.5.6/src/soothe_daemon/protocol_v2.py +154 -0
- soothe_daemon-0.5.6/src/soothe_daemon/query_engine.py +816 -0
- soothe_daemon-0.5.6/src/soothe_daemon/reattachment_handler.py +122 -0
- soothe_daemon-0.5.6/src/soothe_daemon/runner/__init__.py +10 -0
- soothe_daemon-0.5.6/src/soothe_daemon/runner/factory.py +93 -0
- soothe_daemon-0.5.6/src/soothe_daemon/runner/pool_runner.py +1500 -0
- soothe_daemon-0.5.6/src/soothe_daemon/runner/ray_actor.py +59 -0
- soothe_daemon-0.5.6/src/soothe_daemon/runner/ray_runner.py +98 -0
- soothe_daemon-0.5.6/src/soothe_daemon/server.py +1086 -0
- soothe_daemon-0.5.6/src/soothe_daemon/singleton.py +67 -0
- soothe_daemon-0.5.6/src/soothe_daemon/thread_state.py +125 -0
- soothe_daemon-0.5.6/src/soothe_daemon/transport_manager.py +214 -0
- soothe_daemon-0.5.6/src/soothe_daemon/transports/__init__.py +5 -0
- soothe_daemon-0.5.6/src/soothe_daemon/transports/base.py +141 -0
- soothe_daemon-0.5.6/src/soothe_daemon/transports/http_rest.py +490 -0
- soothe_daemon-0.5.6/src/soothe_daemon/transports/websocket.py +326 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV — lockfile is committed for reproducible installs (Docker `uv sync --frozen`, CI).
|
|
98
|
+
.uv/
|
|
99
|
+
|
|
100
|
+
# poetry
|
|
101
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
102
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
103
|
+
# commonly ignored for libraries.
|
|
104
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
105
|
+
#poetry.lock
|
|
106
|
+
#poetry.toml
|
|
107
|
+
|
|
108
|
+
# pdm
|
|
109
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
110
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
111
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
112
|
+
#pdm.lock
|
|
113
|
+
#pdm.toml
|
|
114
|
+
.pdm-python
|
|
115
|
+
.pdm-build/
|
|
116
|
+
|
|
117
|
+
# pixi
|
|
118
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
119
|
+
#pixi.lock
|
|
120
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
121
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
122
|
+
.pixi
|
|
123
|
+
|
|
124
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
125
|
+
__pypackages__/
|
|
126
|
+
|
|
127
|
+
# Celery stuff
|
|
128
|
+
celerybeat-schedule
|
|
129
|
+
celerybeat.pid
|
|
130
|
+
|
|
131
|
+
# SageMath parsed files
|
|
132
|
+
*.sage.py
|
|
133
|
+
|
|
134
|
+
# Environments
|
|
135
|
+
.env
|
|
136
|
+
.envrc
|
|
137
|
+
.venv
|
|
138
|
+
env/
|
|
139
|
+
venv/
|
|
140
|
+
ENV/
|
|
141
|
+
env.bak/
|
|
142
|
+
venv.bak/
|
|
143
|
+
|
|
144
|
+
# Spyder project settings
|
|
145
|
+
.spyderproject
|
|
146
|
+
.spyproject
|
|
147
|
+
|
|
148
|
+
# Rope project settings
|
|
149
|
+
.ropeproject
|
|
150
|
+
|
|
151
|
+
# mkdocs documentation
|
|
152
|
+
/site
|
|
153
|
+
|
|
154
|
+
# mypy
|
|
155
|
+
.mypy_cache/
|
|
156
|
+
.dmypy.json
|
|
157
|
+
dmypy.json
|
|
158
|
+
|
|
159
|
+
# Pyre type checker
|
|
160
|
+
.pyre/
|
|
161
|
+
|
|
162
|
+
# pytype static type analyzer
|
|
163
|
+
.pytype/
|
|
164
|
+
|
|
165
|
+
# Cython debug symbols
|
|
166
|
+
cython_debug/
|
|
167
|
+
|
|
168
|
+
# PyCharm
|
|
169
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
170
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
171
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
172
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
173
|
+
#.idea/
|
|
174
|
+
|
|
175
|
+
# Abstra
|
|
176
|
+
# Abstra is an AI-powered process automation framework.
|
|
177
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
178
|
+
# Learn more at https://abstra.io/docs
|
|
179
|
+
.abstra/
|
|
180
|
+
|
|
181
|
+
# Visual Studio Code
|
|
182
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
183
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
184
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
185
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
186
|
+
# .vscode/
|
|
187
|
+
|
|
188
|
+
# Ruff stuff:
|
|
189
|
+
.ruff_cache/
|
|
190
|
+
|
|
191
|
+
# PyPI configuration file
|
|
192
|
+
.pypirc
|
|
193
|
+
|
|
194
|
+
# Cursor
|
|
195
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
196
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
197
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
198
|
+
.cursorignore
|
|
199
|
+
.cursorindexingignore
|
|
200
|
+
|
|
201
|
+
# Marimo
|
|
202
|
+
marimo/_static/
|
|
203
|
+
marimo/_lsp/
|
|
204
|
+
__marimo__/
|
|
205
|
+
|
|
206
|
+
.python-version
|
|
207
|
+
thirdparty/
|
|
208
|
+
.cursor/
|
|
209
|
+
large_tool_results/
|
|
210
|
+
plot_*
|
|
211
|
+
.claude/
|
|
212
|
+
.DS_Store
|
|
213
|
+
|
|
214
|
+
checkpoint.json
|
|
215
|
+
manifest.json
|
|
216
|
+
_bmad
|
|
217
|
+
__MACOSX
|
|
218
|
+
.qoder
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: soothe-daemon
|
|
3
|
+
Version: 0.5.6
|
|
4
|
+
Summary: Soothe daemon server - long-running agent runtime with WebSocket/HTTP transports
|
|
5
|
+
Project-URL: Homepage, https://github.com/OpenSoothe/soothe
|
|
6
|
+
Project-URL: Documentation, https://soothe.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/OpenSoothe/soothe
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: agent,ai,daemon,llm,server,soothe,websocket
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: <4.0,>=3.11
|
|
21
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
22
|
+
Requires-Dist: fastapi>=0.104.0
|
|
23
|
+
Requires-Dist: psutil>=5.9.0
|
|
24
|
+
Requires-Dist: pydantic-settings<3.0.0,>=2.0.0
|
|
25
|
+
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
26
|
+
Requires-Dist: pyyaml<7.0.0,>=6.0.0
|
|
27
|
+
Requires-Dist: requests>=2.32.3
|
|
28
|
+
Requires-Dist: soothe-sdk<1.0.0,>=0.5.0
|
|
29
|
+
Requires-Dist: soothe<1.0.0,>=0.5.0
|
|
30
|
+
Requires-Dist: typer<1.0.0,>=0.9.0
|
|
31
|
+
Requires-Dist: uvicorn[standard]>=0.24.0
|
|
32
|
+
Requires-Dist: websockets>=12.0
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.12.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: soothe-cli>=0.5.0; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# soothe-daemon
|
|
43
|
+
|
|
44
|
+
Soothe daemon server — long-running agent runtime with WebSocket/HTTP transports.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install soothe-daemon
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For full runtime, also install the agent core and CLI:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install soothe soothe-daemon soothe-cli
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
soothed start --foreground
|
|
62
|
+
soothed status
|
|
63
|
+
soothed doctor
|
|
64
|
+
soothed stop
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Configuration
|
|
68
|
+
|
|
69
|
+
- `~/.soothe/config/config.yml` — Agent config (`SootheConfig`)
|
|
70
|
+
- `~/.soothe/config/daemon_config.yml` — Daemon config (`SootheDaemonConfig`)
|
|
71
|
+
|
|
72
|
+
## Dependencies
|
|
73
|
+
|
|
74
|
+
- `soothe>=0.5.0` — In-process agent core
|
|
75
|
+
- `soothe-sdk>=0.5.0` — WebSocket protocol
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# soothe-daemon
|
|
2
|
+
|
|
3
|
+
Soothe daemon server — long-running agent runtime with WebSocket/HTTP transports.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install soothe-daemon
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For full runtime, also install the agent core and CLI:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install soothe soothe-daemon soothe-cli
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
soothed start --foreground
|
|
21
|
+
soothed status
|
|
22
|
+
soothed doctor
|
|
23
|
+
soothed stop
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
- `~/.soothe/config/config.yml` — Agent config (`SootheConfig`)
|
|
29
|
+
- `~/.soothe/config/daemon_config.yml` — Daemon config (`SootheDaemonConfig`)
|
|
30
|
+
|
|
31
|
+
## Dependencies
|
|
32
|
+
|
|
33
|
+
- `soothe>=0.5.0` — In-process agent core
|
|
34
|
+
- `soothe-sdk>=0.5.0` — WebSocket protocol
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "soothe-daemon"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Soothe daemon server - long-running agent runtime with WebSocket/HTTP transports"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.11,<4.0"
|
|
12
|
+
keywords = ["soothe", "daemon", "server", "websocket", "agent", "ai", "llm"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"soothe>=0.5.0,<1.0.0", # in-proc agent core (PyPI)
|
|
27
|
+
"soothe-sdk>=0.5.0,<1.0.0", # WebSocket protocol (PyPI)
|
|
28
|
+
"aiohttp>=3.9.0",
|
|
29
|
+
"fastapi>=0.104.0",
|
|
30
|
+
"psutil>=5.9.0",
|
|
31
|
+
"pydantic>=2.0.0,<3.0.0",
|
|
32
|
+
"pydantic-settings>=2.0.0,<3.0.0",
|
|
33
|
+
"pyyaml>=6.0.0,<7.0.0",
|
|
34
|
+
"requests>=2.32.3",
|
|
35
|
+
"typer>=0.9.0,<1.0.0",
|
|
36
|
+
"uvicorn[standard]>=0.24.0",
|
|
37
|
+
"websockets>=12.0",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
dev = [
|
|
42
|
+
"pytest>=8.0.0",
|
|
43
|
+
"pytest-asyncio>=1.3.0",
|
|
44
|
+
"pytest-cov",
|
|
45
|
+
"ruff>=0.12.0",
|
|
46
|
+
"mypy>=1.0.0",
|
|
47
|
+
"soothe-cli>=0.5.0", # For CLI integration tests (PyPI)
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.scripts]
|
|
51
|
+
soothed = "soothe_daemon.cli.daemon_main:app"
|
|
52
|
+
|
|
53
|
+
[project.urls]
|
|
54
|
+
Homepage = "https://github.com/OpenSoothe/soothe"
|
|
55
|
+
Documentation = "https://soothe.readthedocs.io"
|
|
56
|
+
Repository = "https://github.com/OpenSoothe/soothe"
|
|
57
|
+
|
|
58
|
+
[tool.hatch.build.targets.wheel]
|
|
59
|
+
packages = ["src/soothe_daemon"]
|
|
60
|
+
|
|
61
|
+
[tool.hatch.build.targets.sdist]
|
|
62
|
+
include = ["src/soothe_daemon/"]
|
|
63
|
+
exclude = [
|
|
64
|
+
"**/__pycache__",
|
|
65
|
+
"**/*.pyc",
|
|
66
|
+
"**/*.pyo",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[tool.ruff]
|
|
70
|
+
line-length = 100
|
|
71
|
+
target-version = "py311"
|
|
72
|
+
|
|
73
|
+
[tool.ruff.lint]
|
|
74
|
+
select = ["E", "F", "I", "N", "W", "UP"]
|
|
75
|
+
ignore = ["E501"]
|
|
76
|
+
|
|
77
|
+
[tool.ruff.lint.per-file-ignores]
|
|
78
|
+
"src/soothe_daemon/cli/daemon_main.py" = ["E402"]
|
|
79
|
+
|
|
80
|
+
[tool.ruff.format]
|
|
81
|
+
docstring-code-format = true
|
|
82
|
+
|
|
83
|
+
[tool.hatch.version]
|
|
84
|
+
path = "../../VERSION"
|
|
85
|
+
pattern = "^(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+)$"
|
|
86
|
+
|
|
87
|
+
[tool.mypy]
|
|
88
|
+
python_version = "3.12"
|
|
89
|
+
warn_return_any = true
|
|
90
|
+
warn_unused_configs = true
|
|
91
|
+
disallow_untyped_defs = true
|
|
92
|
+
|
|
93
|
+
[tool.pytest.ini_options]
|
|
94
|
+
asyncio_mode = "auto"
|
|
95
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
96
|
+
testpaths = ["tests"]
|
|
97
|
+
python_files = ["test_*.py"]
|
|
98
|
+
python_classes = ["Test*"]
|
|
99
|
+
python_functions = ["test_*"]
|
|
100
|
+
addopts = "-v --strict-markers"
|
|
101
|
+
markers = [
|
|
102
|
+
"asyncio: mark test as async",
|
|
103
|
+
"integration: mark test as integration test",
|
|
104
|
+
"slow: long-running or stress tests",
|
|
105
|
+
]
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# soothe.daemon
|
|
2
|
+
|
|
3
|
+
Long-running background process that serves the Soothe agent over multiple
|
|
4
|
+
transports. Acts as a **transport adapter** around `SootheRunner` — it does
|
|
5
|
+
not re-implement orchestration logic.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Relationship to `soothe.core`
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌──────────────────────────────────────────┐
|
|
13
|
+
│ TUI / CLI client │
|
|
14
|
+
└───────────────┬──────────────────────────┘
|
|
15
|
+
│ WebSocket / HTTP REST
|
|
16
|
+
┌───────────────▼──────────────────────────┐
|
|
17
|
+
│ soothe.daemon │
|
|
18
|
+
│ │
|
|
19
|
+
│ SootheDaemon process lifecycle │
|
|
20
|
+
│ TransportManager multi-transport │
|
|
21
|
+
│ MessageRouter JSON → runner API │
|
|
22
|
+
│ QueryEngine streaming + cancel│
|
|
23
|
+
│ ThreadStateRegistry per-thread state │
|
|
24
|
+
└───────────────┬──────────────────────────┘
|
|
25
|
+
│ constructs / calls
|
|
26
|
+
┌───────────────▼──────────────────────────┐
|
|
27
|
+
│ soothe.core.runner.SootheRunner │
|
|
28
|
+
│ (orchestration, protocols, streaming) │
|
|
29
|
+
└──────────────────────────────────────────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`SootheDaemon` holds a single `SootheRunner` instance and delegates all
|
|
33
|
+
query execution to it via public APIs (`astream`, thread helpers). The
|
|
34
|
+
daemon **never** duplicates protocol, memory, or planning logic.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Directory map
|
|
39
|
+
|
|
40
|
+
| File / Package | Responsibility |
|
|
41
|
+
|----------------|----------------|
|
|
42
|
+
| `server.py` | `SootheDaemon` — process lifecycle, WebSocket server, Unix socket |
|
|
43
|
+
| `entrypoint.py` | `run_daemon()` — CLI entry point, signal handling |
|
|
44
|
+
| `transport_manager.py` | Manages multiple transport servers (WebSocket, HTTP REST) |
|
|
45
|
+
| `transports/` | `WebSocketTransport`, `HttpRestTransport`, `TransportServer` base |
|
|
46
|
+
| `message_router.py` | Routes incoming JSON messages to runner public APIs |
|
|
47
|
+
| `query_engine.py` | `QueryEngine` — streams a single query, owns cancel / ownership |
|
|
48
|
+
| `thread_state.py` | `ThreadStateRegistry` — per-thread draft, history, logger |
|
|
49
|
+
| `client_session.py` | Tracks connected client metadata and event filtering |
|
|
50
|
+
| `event_bus.py` | In-process pub/sub for broadcasting events to all clients |
|
|
51
|
+
| `protocol.py` / `protocol_v2.py` | Wire-format encode/decode helpers |
|
|
52
|
+
| `websocket_client.py` | `WebSocketClient` — for CLI commands that talk to the daemon |
|
|
53
|
+
| `singleton.py` | Single-instance enforcement |
|
|
54
|
+
| `paths.py` | `pid_path()`, `socket_path()` — canonical filesystem paths |
|
|
55
|
+
| `health/` | `HealthChecker` and per-category check implementations |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## health/ subpackage
|
|
60
|
+
|
|
61
|
+
Health checks verify all Soothe components including daemon socket,
|
|
62
|
+
persistence, providers, protocols, and external APIs.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
daemon/health/
|
|
66
|
+
├── __init__.py # HealthChecker, format_* exports
|
|
67
|
+
├── checker.py # HealthChecker orchestrator
|
|
68
|
+
├── models.py # CheckResult, CategoryResult, HealthReport
|
|
69
|
+
├── formatters.py # format_text, format_markdown, format_json
|
|
70
|
+
└── checks/
|
|
71
|
+
├── config_check.py
|
|
72
|
+
├── daemon_check.py # uses soothe_daemon.paths (pid_path, socket_path)
|
|
73
|
+
├── persistence_check.py
|
|
74
|
+
├── protocols_check.py
|
|
75
|
+
├── providers_check.py
|
|
76
|
+
├── vector_stores_check.py
|
|
77
|
+
├── mcp_check.py
|
|
78
|
+
├── external_apis_check.py
|
|
79
|
+
└── observability_check.py
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Health checks live here (not in `core`) because they legitimately depend
|
|
83
|
+
on daemon-layer paths (`pid_path`, `socket_path`) and daemon connectivity.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Boundary rules
|
|
88
|
+
|
|
89
|
+
| Direction | Rule |
|
|
90
|
+
|-----------|------|
|
|
91
|
+
| `daemon` → `core` | OK — daemon composes `SootheRunner` |
|
|
92
|
+
| `daemon` → `soothe.logging` | OK |
|
|
93
|
+
| `daemon` → `config` | OK |
|
|
94
|
+
| `daemon` → `ux` | **Forbidden** |
|
|
95
|
+
| `daemon.health` → `daemon.paths` | OK — intra-daemon import |
|
|
96
|
+
| Orchestration logic in daemon | **Forbidden** — belongs in `core` |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Key types
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from soothe_daemon import SootheDaemon # main daemon class
|
|
104
|
+
from soothe_daemon import WebSocketClient # client for CLI ↔ daemon
|
|
105
|
+
from soothe_daemon import run_daemon # entrypoint
|
|
106
|
+
from soothe_daemon import pid_path # ~/.soothe/soothe.pid
|
|
107
|
+
from soothe_daemon import socket_path # ~/.soothe/soothe.sock
|
|
108
|
+
from soothe_daemon.health import HealthChecker
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Message flow
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Client connects (WebSocket / HTTP)
|
|
117
|
+
→ TransportManager routes connection to handler
|
|
118
|
+
→ MessageRouter.handle(msg) dispatches by msg["type"]
|
|
119
|
+
→ QueryEngine.stream(runner, query, thread_id, ...)
|
|
120
|
+
→ runner.astream(...) yields (namespace, mode, data)
|
|
121
|
+
→ events broadcast via EventBus to all clients
|
|
122
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Soothe daemon subpackage - background agent runner with WebSocket IPC."""
|
|
2
|
+
|
|
3
|
+
from soothe_sdk.client import WebSocketClient
|
|
4
|
+
|
|
5
|
+
from soothe_daemon.entrypoint import run_daemon
|
|
6
|
+
from soothe_daemon.paths import pid_path, socket_path
|
|
7
|
+
from soothe_daemon.server import SootheDaemon
|
|
8
|
+
|
|
9
|
+
__all__ = ["SootheDaemon", "WebSocketClient", "pid_path", "run_daemon", "socket_path"]
|