Skip to content

feat: add ai-skill and ai-memory hive CLI commands#287

Merged
maximelb merged 3 commits into
cli-v2from
feat/ai-skill-and-ai-memory
May 3, 2026
Merged

feat: add ai-skill and ai-memory hive CLI commands#287
maximelb merged 3 commits into
cli-v2from
feat/ai-skill-and-ai-memory

Conversation

@maximelb
Copy link
Copy Markdown
Contributor

@maximelb maximelb commented May 3, 2026

Summary

Mirrors the two new typed hives that landed in legion_config_hive:

  • ai_skill — Claude Code skill definitions (master, refractionPOINT/legion_config_hive#282).
  • ai_memory — per-agent memory store with a server-side partial-merge hook (branch feat/ai-memory-hive, refractionPOINT/legion_config_hive 5c15eb9).

ai-skill

A straight hive shortcut on top of make_hive_group (list, get, set, delete, enable, disable). No special semantics — the validator on the server enforces the SKILL.md schema.

ai-memory (partial-merge mechanism baked in)

The ai_memory hive's PreIngest hook merges incoming memories map keys into the stored record on a per-key basis: keys present in the request replace or drop (when the value is JSON null) their counterpart, while keys absent from the request are preserved untouched. Per the task brief, that mechanism is baked into the CLI tool: every ai-memory sub-command takes both --key (the hive record / agent identifier) and --memory-name (required) so write operations are always targeted at one entry.

  • ai-memory set --key A --memory-name X sends {memories: {X: content}} only — no GET round-trip, no etag race window.
  • ai-memory delete --key A --memory-name X --confirm sends {memories: {X: null}} so the merge hook drops just that one entry.
  • ai-memory delete-record --key A --confirm removes the whole agent record (regular DELETE verb, not the merge path).
  • ai-memory get --key A --memory-name X returns the single memory's content; list returns the per-record memory map; list-records enumerates every agent.

The shape lives in a dedicated AiMemory SDK class (limacharlie/sdk/ai_memory.py) so the merge convention isn't re-derived in every CLI module.

Plumbing

  • Configs.ALL_HIVES, _KNOWN_HIVE_TYPES, sync flag map, sync help text, hive list-types docs, NEW_CLI.md hive table.
  • New --hive-ai-skill / --hive-ai-memory flags on sync pull / sync push.
  • Lazy-loading regression snapshot updated.

Test plan

  • pytest tests/unit/test_sdk_ai_memory.py tests/unit/test_cli_ai_skill_memory.py -v (27 new tests; partial-merge payload shape pinned for both set and delete).
  • pytest tests/unit/test_cli_command_map_lint.py tests/unit/test_cli_lazy_loading_regression.py tests/unit/test_sdk_configs.py tests/unit/test_sdk_hive.py tests/unit/test_cli_commands.py -q (1061 passed).
  • Smoke-test setgetdelete round-trip against a real org once the upstream ai_memory hive is on master.

🤖 Generated with Claude Code

maximelb and others added 2 commits May 2, 2026 20:48
Mirrors the two new typed hives added in legion_config_hive: ai_skill
(Claude Code skill definitions) and ai_memory (per-agent memory store
with a server-side partial-merge hook).

ai-skill is a straight hive shortcut on top of make_hive_group: list,
get, set, delete, enable, disable.

ai-memory is custom because its hook lets Set on a single memory name
update only that one entry while every other memory on the record is
preserved by the server. The new AiMemory SDK class bakes that
mechanism in: set/delete take a required --memory-name and send
{memories: {name: content|null}} only — no GET-then-PUT round trip,
no etag race window. delete-record removes the whole agent record
through the regular DELETE verb.

Both hive names are also added to Configs.ALL_HIVES, the sync flag
map (--hive-ai-skill, --hive-ai-memory), the hive list-types output,
and the lazy-loading regression snapshot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The /mtd endpoint serializes "data": {} into the response even though
the call is metadata-only. HiveRecord.from_raw kept the empty dict, so
a follow-up set() saw record.data != None and routed to /data with an
empty payload. Hives whose validator requires fields (ai_skill needs
content, ai_agent needs provider config, ...) then rejected the
disable/enable flow with "<field> is required".

Drop the envelope in get_metadata so set() routes back to /mtd, where
the validator-skip-on-metadata-only path applies and the round-trip
preserves the record's data on the server.

Surfaced testing the new ai-skill disable/enable shortcut against
white-sands; secret/lookup escaped the bug only because their
validators tolerate empty data.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@maximelb maximelb requested a review from dzimine-lc May 3, 2026 22:37
@maximelb maximelb marked this pull request as ready for review May 3, 2026 22:37
@maximelb
Copy link
Copy Markdown
Contributor Author

maximelb commented May 3, 2026

/gcbrun

The 5 failing tests mocked Client/Organization but never set a return
value for client.request(), so the SDK call returned a MagicMock that
the CLI's _output() then crashed on with
"Type is not JSON serializable: MagicMock".

Set request.return_value = {} on each so the CLI's serialization step
gets a real dict.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@maximelb maximelb merged commit f827559 into cli-v2 May 3, 2026
7 checks passed
@maximelb maximelb deleted the feat/ai-skill-and-ai-memory branch May 3, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant