All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
update_payload_by_doc_idmethod on theBaseStorageBackendProtocol for in-place chunk-payload rewrites. Lets callers update per-document metadata without re-embedding: chunk text and vectors are unchanged, only the JSON payload fields are merged in place.SqliteVecBackendimplements it via a singleUPDATE chunks SET payload = ?per chunk filtered byjson_extract(payload, '$.doc_id').QdrantBackendimplements it viaset_payload(points=Filter(... doc_id ...)). Built-in payload keys (text,source,doc_id) are never overwritten — the caller passes only the metadata dict. Required by the studio's post-upload metadata editor so the KB chunk count stays stable across edits.
Agent._run_loopnow uses awhileloop so mutations tomax_stepsinsidebefore_iteration_callbackactually extend the run. Previouslyrange(self.max_steps)was evaluated once at loop start, making runtime extension a no-op.
- Observability primitives:
emit,set_hook,on_step,ObservabilityContext, and a typed event vocabulary (LLMCallEvent, EmbeddingEvent, RAGEvent, MCPEvent, GuardrailEvent, AgentStepEvent, OrchestratorEvent, PipelineStepEvent) for structured event emission from core call sites. Agent.run(delegated_to=...)parameter for caller correlation acrossOrchestratorsub-agents. Sub-agent events carry the delegating agent's name in their payload.total_billable_tokensfield onAgent.run()result. Resolves the previous ambiguity in theprompt + completion + reasoningmath:reasoning_tokensis a subset ofcompletion_tokensand is not additive.observability.print_hook()helper for examples and ad-hoc debugging.RecordingHookpytest fixture intests/conftest.py.CONTRIBUTING.mdandSECURITY.mdat the repo root, covering setup, test commands, pre-PR checklist, commit format, supported versions, the reporting process, and a 90-day disclosure timeline.LICENSE(MIT) and thisCHANGELOG.md.CLAUDE.mdagent instructions andissues/tracker at the repo root.mypyandpytest-covadded to thedevdependency group for CI type-checking and coverage reporting.- GitHub Actions CI workflow (
.github/workflows/ci.yaml) running ruff, mypy, and unit tests on every push tomainand on pull requests. - CI workflow extended with
gitleaks(full-history secret scan, runs first to fail fast),bandit(Python security scan), anddeptry(declared-dep audit, scoped to library + tests).banditanddeptryadded to thedevgroup viauv add.
- Renamed package from
llm-frameworktohoidfor first PyPI publish. All import paths change fromfrom llm_framework.Xtofrom hoid.X. Install becomesuv pip install hoid[std]. The MCPclientInfo.namesent to servers is now"hoid". The PyPI distribution ishoid; consumers pinning the old GitHub Release URL must switch topip install hoid==X.Y.Z. AgentandOrchestratorno longer accept anon_eventcallback. Subscribe viahoid.observability.set_hook()(global) or the per-instanceon_stepparameter.Orchestrator.delegate()no longer mutates sub-agent state at call time. Sub-agent events carrydelegated_toin the payload instead.Agent.run()docstring now documents the token accounting contract explicitly:completion_tokensis OpenAI-compatible (includes reasoning);total_billable_tokensis the actual bill.- All example scripts and integration tests migrated from the
on_event=...pattern to the new hook pattern. - Observability primitives moved from
hoid.observabilitytohoid.core.observability; the old path remains as a silent backward-compat re-export. - The internal
AgentEventTypedDict was removed fromcore/agent.py. The agent loop now constructsAgentStepEventdirectly via a private helper, eliminating the dual event representation. pyproject.tomlnow declaresclassifiers,keywords, and a[project.urls]block (Homepage, Documentation, Issues) so the package renders correctly on PyPI.
hoid.tools.*andhoid.mcp_servers.*. The reference tool implementations and MCP-server entry-point scripts now live inexamples/tools/andexamples/mcp_servers/. Theknowledge-serverandmemory-serverconsole scripts moved to theexamplesproject — run them viacd examples && uv run <server>. The[server]extra was removed (uvicornis no longer a library dependency; it ships transitively viaexamples/).
- Token accounting no longer double-counts
reasoning_tokensas a separate billable quantity. Consumers readingprompt_tokens + completion_tokens + reasoning_tokenswere being charged twice for reasoning tokens; the newtotal_billable_tokensfield gives the correct sum. - Lazy
import dataclassesinsideobservability._attach_ctxhoisted to the module-level imports.