cendor-sdk 1.0.0
First public release on PyPI — the governed agent loop, multi-agent orchestration, ecosystem
interop, and production hardening + governed eval, consolidated with the gap-analysis remediation,
retrieval (RAG), and rolling memory. Requires cendor-core>=1.3 (Hugging Face detection).
Fixed
- Tool calling on Gemini & Bedrock (P0) —
build_kwargsdropped assistanttool_callsand all
toolresults, so multi-turn tool loops silently broke on those providers. Added
_canonical_to_gemini/_canonical_to_bedrock(functionCall/functionResponse; toolUse/toolResult),
mirroring the Anthropic translator, with round-trip tests.
Added — gap-analysis remediation (see plan/SDK_FIT_GAP_ANALYSIS.md)
- Provider param passthrough —
Agent.extramerges arbitrary request kwargs (tool_choice,
reasoning_effort,top_p,stop,seed,response_format,extra_body, …) into every call. - o-series temperature guard — the OpenAI provider omits
temperatureforo1/o3/o4models
(which reject it) instead of erroring. - Robust structured output — an
output_typenow derives a JSON Schema used via each provider's
native structured-output feature: OpenAIjson_schema, Ollamaformat, Geminiresponse_schema;
Anthropic/Bedrock/Responses embed the schema in the JSON nudge. Dataclass / Pydantic / dict. - Streaming —
run.stream(agent, input)/run.astream(...)yieldTextDelta/ToolCallEvent
/ToolResultEventand a terminalRunComplete(result). Native reassembly for the OpenAI family +
Ollama (tool-call deltas included); whole-response fallback for the rest. Single-agent. - Multimodal input — message
contentmay be a parts list (text+image_url); OpenAI-family
passes it through, Anthropic/Gemini translate to image blocks (base64/url), Bedrock keeps the text. - Unpriced-model cost governance —
register_model_price(model, input=…, output=…)registers a
rate so cost/USD budgets bind on HF/Azure-deployment/Foundry-Local/custom ids;configure
(on_unpriced="raise") re-exported. - Embeddings —
embed(model, inputs)/aembed(...)return vectors and emit a governed
LLMCall(tokens/cost/audit captured) for OpenAI-family providers — RAG calls become first-class. - RAG seam —
VectorIndex(a dependency-free in-memory cosine index overembed()) +
Agent(retriever=…), which injects retrieved context as a system message before the call
("always-on" RAG). Bring your own embedder viaembedder=, or plug a real vector DB as a
retriever. The SDK governs retrieval; it does not store your vectors. - Summarizing memory —
SummarizingSession(model=… | summarizer=…, max_messages=…, keep_recent=…)folds old turns into a durable summary note when a conversation grows, keeping
recent turns verbatim so memory stays bounded but the gist persists (beyondcontext_budget
trimming).llm_summarizer(model)builds a governed summarizer; pass any callable for offline
summaries. - Multi-agent checkpointing —
run([...], checkpoint=…)persists the trajectory per turn/segment
and resumes a crashed team run. - MCP prompts —
load_mcp_prompts(session)+get_mcp_prompt(session, name, args)(renders to
canonical messages);load_mcp_resourcesnow exported too. - Concurrent tool execution — a turn's multiple tool calls run via
asyncio.gatherin async runs. max_turnssignal —Result.incompleteisTruewhen a run ends with no final answer.- Nested tool params — tool schema generation expands nested dataclass / Pydantic parameters.
- Richer OTel spans —
span_treenow records latency, finish reason, reasoning tokens, and tool
argument names. - Eval judge —
EvalCase.judgeadds a pluggable semantic / LLM-judge scorer.
Added
- Hugging Face provider (
provider="huggingface"/"hf", extra[huggingface]) — wraps
huggingface_hub.InferenceClient.chat_completion(OpenAI-shaped response, so request formatting
and normalization are reused). Token viaapi_key=orHF_TOKEN/HUGGINGFACEHUB_API_TOKEN;
base_url=targets a dedicated Inference Endpoint;HF_PROVIDERroutes through a specific
inference provider.cendor-core'sinstrumentnow detectschat_completionstructurally and
attributes theLLMCalltohuggingface, so budgets/guard/audit apply. - Azure AI Foundry provider (
provider="azure"/"azure_openai"/"foundry", extra
[azure]) — connects to Foundry deployments via the standardopenaiSDK on the
/openai/v1/endpoint, per Microsoft's current guidance (theAzureOpenAIclient and
azure-ai-inferenceare being retired).modelis the Foundry deployment name;base_url
(orAZURE_OPENAI_ENDPOINT) is normalized to the v1 route;api_keyfalls back to
AZURE_OPENAI_API_KEY/AZURE_INFERENCE_CREDENTIAL. Entra ID via a bearer-tokenapi_keyor a
bring-your-ownclient=. Seedocs/sdk.md→ Connecting to Hugging Face & Azure AI Foundry. - Azure Foundry Responses API (
provider="azure_responses"/"foundry_responses") — drives
the OpenAI Responses API over a Foundry endpoint for OpenAI-family deployments; same Foundry-aware
construction asprovider="azure"(Chat Completions). - Foundry Local provider (
provider="foundry_local"/"foundry-local", extra
[foundry-local]) — Microsoft's on-device runtime over its local OpenAI-compatible REST server
(the local counterpart to Ollama). Endpoint viabase_url=orFOUNDRY_LOCAL_ENDPOINT(e.g.
foundry_local.FoundryLocalManager(alias).endpoint); no key required.modelis the resolved
Foundry Local model id. - Examples:
examples/foundry_agent.py(Azure Foundry + Foundry Local) and
examples/huggingface_agent.py, both offline.
Consolidation & docs (Phases 1–4)
Consolidates Phases 1–4 into a stable, documented release (plan §12): the governed agent loop,
multi-agent orchestration, ecosystem interop, and production hardening + governed eval — complete,
provider-agnostic, local-first, and tested offline.
- Full docs pass:
docs/index.mdlinks every page and lists the public API surface; the two-door
framing (libraries primary, SDK secondary) is consistent across the README and docs. - Marked
Development Status :: 5 - Production/Stable. - Verification:
uv run pytestgreen (91 tests, no network),ruff check/ruff formatclean,
mypy clean, namespace-guard clean,import cendor.sdkworks.