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.
Files changed (56) hide show
  1. soothe_daemon-0.5.6/.gitignore +218 -0
  2. soothe_daemon-0.5.6/PKG-INFO +75 -0
  3. soothe_daemon-0.5.6/README.md +34 -0
  4. soothe_daemon-0.5.6/pyproject.toml +105 -0
  5. soothe_daemon-0.5.6/src/soothe_daemon/README.md +122 -0
  6. soothe_daemon-0.5.6/src/soothe_daemon/__init__.py +9 -0
  7. soothe_daemon-0.5.6/src/soothe_daemon/__main__.py +6 -0
  8. soothe_daemon-0.5.6/src/soothe_daemon/_handlers.py +288 -0
  9. soothe_daemon-0.5.6/src/soothe_daemon/_rpc_handlers.py +406 -0
  10. soothe_daemon-0.5.6/src/soothe_daemon/bootstrap_env.py +35 -0
  11. soothe_daemon-0.5.6/src/soothe_daemon/cli/__init__.py +1 -0
  12. soothe_daemon-0.5.6/src/soothe_daemon/cli/daemon_main.py +355 -0
  13. soothe_daemon-0.5.6/src/soothe_daemon/client_session.py +369 -0
  14. soothe_daemon-0.5.6/src/soothe_daemon/config/__init__.py +29 -0
  15. soothe_daemon-0.5.6/src/soothe_daemon/config/env.py +23 -0
  16. soothe_daemon-0.5.6/src/soothe_daemon/config/models.py +252 -0
  17. soothe_daemon-0.5.6/src/soothe_daemon/config/settings.py +167 -0
  18. soothe_daemon-0.5.6/src/soothe_daemon/entrypoint.py +121 -0
  19. soothe_daemon-0.5.6/src/soothe_daemon/event_bus.py +273 -0
  20. soothe_daemon-0.5.6/src/soothe_daemon/event_size_stats.py +166 -0
  21. soothe_daemon-0.5.6/src/soothe_daemon/health/__init__.py +50 -0
  22. soothe_daemon-0.5.6/src/soothe_daemon/health/checker.py +243 -0
  23. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/__init__.py +3 -0
  24. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/config_check.py +196 -0
  25. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/daemon_check.py +673 -0
  26. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/embedding_warmup_check.py +92 -0
  27. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/external_apis_check.py +177 -0
  28. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/mcp_check.py +118 -0
  29. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/observability_check.py +162 -0
  30. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/persistence_check.py +242 -0
  31. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/protocols_check.py +66 -0
  32. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/providers_check.py +143 -0
  33. soothe_daemon-0.5.6/src/soothe_daemon/health/checks/vector_stores_check.py +156 -0
  34. soothe_daemon-0.5.6/src/soothe_daemon/health/formatters.py +194 -0
  35. soothe_daemon-0.5.6/src/soothe_daemon/health/models.py +133 -0
  36. soothe_daemon-0.5.6/src/soothe_daemon/image_understanding.py +177 -0
  37. soothe_daemon-0.5.6/src/soothe_daemon/logging.py +90 -0
  38. soothe_daemon-0.5.6/src/soothe_daemon/loop_isolation.py +177 -0
  39. soothe_daemon-0.5.6/src/soothe_daemon/message_router.py +1486 -0
  40. soothe_daemon-0.5.6/src/soothe_daemon/paths.py +23 -0
  41. soothe_daemon-0.5.6/src/soothe_daemon/protocol_v2.py +154 -0
  42. soothe_daemon-0.5.6/src/soothe_daemon/query_engine.py +816 -0
  43. soothe_daemon-0.5.6/src/soothe_daemon/reattachment_handler.py +122 -0
  44. soothe_daemon-0.5.6/src/soothe_daemon/runner/__init__.py +10 -0
  45. soothe_daemon-0.5.6/src/soothe_daemon/runner/factory.py +93 -0
  46. soothe_daemon-0.5.6/src/soothe_daemon/runner/pool_runner.py +1500 -0
  47. soothe_daemon-0.5.6/src/soothe_daemon/runner/ray_actor.py +59 -0
  48. soothe_daemon-0.5.6/src/soothe_daemon/runner/ray_runner.py +98 -0
  49. soothe_daemon-0.5.6/src/soothe_daemon/server.py +1086 -0
  50. soothe_daemon-0.5.6/src/soothe_daemon/singleton.py +67 -0
  51. soothe_daemon-0.5.6/src/soothe_daemon/thread_state.py +125 -0
  52. soothe_daemon-0.5.6/src/soothe_daemon/transport_manager.py +214 -0
  53. soothe_daemon-0.5.6/src/soothe_daemon/transports/__init__.py +5 -0
  54. soothe_daemon-0.5.6/src/soothe_daemon/transports/base.py +141 -0
  55. soothe_daemon-0.5.6/src/soothe_daemon/transports/http_rest.py +490 -0
  56. 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"]
@@ -0,0 +1,6 @@
1
+ """Allow running the daemon as a module: python -m soothe_daemon."""
2
+
3
+ from soothe_daemon.entrypoint import main
4
+
5
+ if __name__ == "__main__":
6
+ main()