mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Implements the hermes-agent HSP/1 sync CLIENT against the frozen wire
contract (~/src/specs/collective-wisdom/hsp-1-contract.md §8), tested
against an in-process mock HSP server.
tools/skills_sync_client.py (new, low-level; does NOT import the CLI):
* Full 64-hex sha256 content addressing + canonical JSON (§2.1/§2.5,
OI-5) — kept distinct from the truncated local content_hash namespace.
* HSPClient: capabilities/refs/objects GET, batch object upload
(multipart, raw bytes per §1/§4.2), CAS ref (§4.4) with 409->HSPConflict.
* Object building: skill dir -> blob/tree/commit; exec-bit preserved,
symlinks skipped, oversize (413) surfaced; profile-root category trees.
* push/pull + three-way merge (M1-C): reuses the origin/user/incoming
decision semantics of skills_sync.py; non-overlap -> merge commit +
retry CAS; true overlap -> refs/user/<owner>/conflict/<n> + surface.
* DEV-PHASE gate: sync is INERT unless the resolved Nous token carries
tool_gateway_admin===true (decoded from the bearer; server re-verifies).
* Auth reuses resolve_nous_runtime_credentials() (no refresh reimpl).
* maybe_push_skills / maybe_pull_skills gate-and-swallow entrypoints.
Opt-in (M1-D): tools/skill_usage.set_sync / is_sync_enabled — a `sync`
flag on the .usage.json sidecar; nothing syncs unless opted in. Only
agent-created/user-authored skills are eligible (bundled/hub excluded).
Hooks:
* Debounced push in skill_manage success block (after the write gate).
* Periodic pull at the two curator tick sites (gateway housekeeping loop
+ CLI startup).
CLI: hermes sync status|pull|push|now|enable|disable
(hermes_cli/subcommands/sync.py + cmd_sync in main.py).
Tests: tests/tools/test_skills_sync_client.py — 29 tests (addressing,
canonicalization, dev gate, opt-in, object building, merge decisions, and
e2e push/pull/idempotency/conflict against a stdlib mock HSP server).
|
||
|---|---|---|
| .. | ||
| assets | ||
| builtin_hooks | ||
| platforms | ||
| relay | ||
| __init__.py | ||
| authz_mixin.py | ||
| cgroup_cleanup.py | ||
| channel_directory.py | ||
| code_skew.py | ||
| config.py | ||
| cwd_placeholder.py | ||
| dead_targets.py | ||
| delivery.py | ||
| display_config.py | ||
| drain_control.py | ||
| hooks.py | ||
| kanban_watchers.py | ||
| memory_monitor.py | ||
| message_timestamps.py | ||
| mirror.py | ||
| pairing.py | ||
| platform_registry.py | ||
| profile_routing.py | ||
| readiness.py | ||
| response_filters.py | ||
| restart.py | ||
| restart_loop_guard.py | ||
| rich_sent_store.py | ||
| run.py | ||
| runtime_footer.py | ||
| scale_to_zero.py | ||
| session.py | ||
| session_context.py | ||
| shutdown_forensics.py | ||
| slash_access.py | ||
| slash_commands.py | ||
| status.py | ||
| status_phrases.py | ||
| sticker_cache.py | ||
| stream_consumer.py | ||
| stream_dispatch.py | ||
| stream_events.py | ||
| whatsapp_identity.py | ||