docs(memory-provider): threading contract names spawn_context_thread and the sidecar/config primitives
The developer guide showed the exact bare threading.Thread pattern the previous commits removed from six in-tree providers; an external plugin copying it loses the profile ContextVar under multiplex. Point it at agent.memory_provider.spawn_context_thread and the canonical JSON/config writers.
This commit is contained in:
@@ -297,9 +297,11 @@ hooks:
|
||||
|
||||
## Threading Contract
|
||||
|
||||
**`sync_turn()` MUST be non-blocking.** If your backend has latency (API calls, LLM processing), run the work in a daemon thread:
|
||||
**`sync_turn()` MUST be non-blocking.** If your backend has latency (API calls, LLM processing), run the work in a daemon thread — spawned with `agent.memory_provider.spawn_context_thread`, never a bare `threading.Thread`. Profile isolation (the active `HERMES_HOME`, the per-turn secret scope) lives in `contextvars`, and a plain thread starts with an empty context: under multiplexed profiles it would silently write into the *default* profile's store, and `get_secret()` fails closed there.
|
||||
|
||||
```python
|
||||
from agent.memory_provider import spawn_context_thread
|
||||
|
||||
def sync_turn(self, user_content, assistant_content, *, session_id="", messages=None):
|
||||
def _sync():
|
||||
try:
|
||||
@@ -309,10 +311,12 @@ def sync_turn(self, user_content, assistant_content, *, session_id="", messages=
|
||||
|
||||
if self._sync_thread and self._sync_thread.is_alive():
|
||||
self._sync_thread.join(timeout=5.0)
|
||||
self._sync_thread = threading.Thread(target=_sync, daemon=True)
|
||||
self._sync_thread = spawn_context_thread(_sync, name="myprovider-sync")
|
||||
self._sync_thread.start()
|
||||
```
|
||||
|
||||
The same applies to prefetch and writer threads. Small JSON config sidecars (`$HERMES_HOME/<provider>.json`) are read with `utils.read_json_or_empty` and written with `utils.atomic_json_write`; anything under `config.yaml` goes through `hermes_cli.config.save_config(..., merge_existing=True)`.
|
||||
|
||||
`messages` is optional OpenAI-style conversation context as of the completed
|
||||
turn. When present, it includes user/assistant messages, assistant tool calls,
|
||||
and tool result messages. Providers that do not need raw turn context can omit
|
||||
|
||||
Reference in New Issue
Block a user