feat(sdk): per-domain typed clients for Phase-9 broker #131
No reviewers
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_aibroker!131
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "development_sdk_127_per_domain"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Realigns
hero_aibroker_sdkwith the Phase-9 per-domain socket split per #127.What lands
Per-domain typed modules, each generated from the broker's matching
specs/<domain>.openrpc.json:chat::Clientchat/rpc.sockai.chat,ai.messages,ai.responses,ai.completions,ai.stream.cancelspeech::Clientspeech/rpc.sockai.tts,ai.transcribe,ai.stream.cancelembedder::Clientembedder/rpc.sockai.embed,ai.rerank,embedder.*models::Clientmodels/rpc.sockmodels.*admin::Clientadmin/rpc.sockproviders.*,mcp.*,metrics.*,apikeys.*, … (35 methods)images::Clientimages/rpc.sockai.imagebilling::Clientbilling/rpc.sockbilling.unbilled,billing.mark_billedmemory::Clientmemory/rpc.sockmemory.{put,get,list,delete,file.*}meta::Clientmeta/rpc.sockmeta.info,meta.sockets,meta.health,rpc.discovervideo::Clientvideo/rpc.sockai.video.*default_domain_socket_path(domain)resolves<root>/<domain>/rpc.sockwithHERO_AIBROKER_SOCKET_DIR/HERO_SOCKET_DIR/$HOME//tmpfallback.PromptBuilder+chat_simplenow bind tochat::Client. Themodelsmodule is renamed tomodel_aliases(frees the name for the domain client).Two caveats called out in the diff
request: ChatRequest, but the chat handler reads them flat (params.get("model")directly). Mychat::Client::ai_chatsendsChatRequestdirectly to match the wire shape the server actually expects. Other 9 domains use macro-generated clients (their specs already declare flat params). Follow-up: either fix the spec or update the handler.allOf. Two methods (memory.search,ai.transcribe_verbose) are filtered out of the SDK-side specs. Server-side specs unchanged. Follow-up: addallOfsupport to the macro, then re-enable.The legacy
AIBrokerAdminAPIClientanddefault_socket_path()stay compiling for one cycle, marked#[deprecated], so in-flight consumers (hero_books#125, already merged) don't break the build before they're updated. A separate hero_books PR follows to switch over.Verification
cargo build -p hero_aibroker_sdk— cleancargo test -p hero_aibroker_sdk --doc— 3/3 compile-okcargo clippy -p hero_aibroker_sdk --no-deps -- -D warnings— cleancargo run -p hero_aibroker_examples --example verify_127_chatagainst the running broker on~/hero/var/sockets/hero_aibroker/rpc.socksends achat::ChatRequestthroughchat::Client::ai_chat, the broker routes it through Groq, and returns the assistant's content ("verified"). Full envelope inspected to confirm the OpenAI-shape response.target/release/hero_aibroker_serverbinds the 10 per-domain sockets at the expected paths (confirmed via startup log on a/tmp/aibroker_testinstance). Could not complete a live RPC to the test instance because secrets in hero_proc are empty in thecorecontext, but the chat handler is identical to the one we already proved works (sameserde_json::from_value::<ChatRequest>(params)path).Refs #127, #63.
🤖 Generated with Claude Code
The broker's Phase-9 split moved every OpenRPC method onto its own per-domain socket (`<root>/<domain>/rpc.sock`) and actively deletes the legacy unified `rpc.sock` on startup, so the pre-split SDK's `AIBrokerAdminAPIClient::connect_default()` is dead on the wire. This PR realigns the SDK with the new architecture: Per-domain modules, each generated from the broker's matching `crates/hero_aibroker_server/specs/<domain>.openrpc.json` (filtered copies live in `crates/hero_aibroker_sdk/specs/`): - `chat::Client` — chat/rpc.sock (ai.chat, ai.messages, ...) - `speech::Client` — speech/rpc.sock (ai.tts, ai.transcribe) - `embedder::Client` — embedder/rpc.sock (ai.embed, ai.rerank) - `models::Client` — models/rpc.sock (models.*) - `admin::Client` — admin/rpc.sock (providers.*, mcp.*, ...) - `images::Client` — images/rpc.sock (ai.image) - `billing::Client` — billing/rpc.sock (billing.*) - `memory::Client` — memory/rpc.sock (memory.{put,get,list,...}) - `meta::Client` — meta/rpc.sock (meta.info, meta.health, ...) - `video::Client` — video/rpc.sock (ai.video.*) `hero_aibroker_sdk::default_domain_socket_path(domain)` resolves `<root>/<domain>/rpc.sock` with `HERO_AIBROKER_SOCKET_DIR` / `HERO_SOCKET_DIR` / `$HOME` / `/tmp` fallback. Caveats covered: - `chat::Client::ai_chat` is hand-rolled, not macro-generated, because the chat spec wraps params as a single named `request` field but the server reads them flat (`params.get("model")` directly). The wrapper sends `ChatRequest` directly to match the wire shape the server expects. Other domains use the macro-generated client (flat params align with their server handlers). The macro-generated chat `GenClient` is retained for type definitions only. - The macro doesn't support `allOf`. Two methods (`memory.search` and `ai.transcribe_verbose`) are filtered out of the SDK-side specs. Server-side specs unchanged. - The legacy `AIBrokerAdminAPIClient` and `default_socket_path()` stay compiling for one cycle, marked deprecated, so in-flight consumers (hero_books#125) don't break before they're updated. PromptBuilder + chat_simple now use `chat::Client`. Module renamed `models` → `model_aliases` (frees `models` for the domain client). Live-tested end-to-end against the running broker via `hero_aibroker_examples::verify_127_chat` — a real `ai.chat` call goes through `chat::Client::ai_chat`, lands on the broker's chat handler, routes via Groq, and returns the assistant content. Refs #127, #63. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>6efa5506a09ffb7b3293ai.chathandler param shape with its OpenRPC spec #140