AI and MCP
Phase H adds id_effect_ai — vendor-neutral LLM traits over Phase A HttpClient, with feature-gated vendors.
Language model trait
#![allow(unused)] fn main() { use id_effect_ai::{ChatRequest, LanguageModel, complete}; }
LanguageModel is a capability (LanguageModelService). Install MockLanguageModel in tests; wire OpenAI or Anthropic at the edge with provide_openai_language_model / provide_anthropic_language_model.
OpenAI and ChatGPT share one adapter (feature = "openai") — model IDs like gpt-4o select the model.
Streaming
complete_stream returns Stream<CompletionChunk, AiError, R> — token deltas map to chunks for sinks and UI bridges.
Anthropic Claude
feature = "anthropic" uses the Messages API (/v1/messages) with SSE streaming. System prompts map to the top-level system field.
Cursor Cloud Agents
feature = "cursor" exposes CursorAgentsClient — a separate capability from LanguageModel:
list_models()—GET /v1/modelscreate_agent(prompt)—POST /v1/agentssend_followup(agent_id, prompt)—POST /v1/agents/{id}/runswait_until_idle(agent_id, run_id)— poll until terminal status
Cursor uses HTTP Basic auth (CURSOR_API_KEY).
Configuration and secrets
Load keys via AiConfig::from_env(). API keys are Secret<String> from id_effect_config — never log .expose() output.
Transient HTTP failures (429/502/503/504) retry via Schedule in retry_transient_ai_http.
MCP server template
cargo run -p id_effect_ai --example mcp_server_template scaffolds a minimal MCP JSON-RPC loop over stdio using the same Effect + capability patterns.