Changelog
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.
Dates are the release tag’s date (sdk-v* in KumihoIO/kumiho-SDKs). Entries are
in descending version order, which is also descending date order.
../../RELEASE_NOTES.md is the release record: the same releases with the
narrative — why a change mattered and what you have to do about it. This file is
its terse companion. Entries belong in both.
[0.15.0] - 2026-10-29
Fixed
Item krefs in nested spaces and with dotted names (
kref://p/a/b/x.k,kref://p/s/my.file.v2.k) are looked up as the kref names them byget_item_by_kref,get_item_from_revision,get_bundle_by_kref,kumiho.get_item,kumiho.get_bundle,Project.get_item,Project.get_bundleandSpace.get_bundle: the parent path is everything before the last/, the item name everything before the last..get_bundle_by_krefre-fetches the bundle the kref names. It re-fetched under the text before the first dot (my.set.bundlecame back asmy.bundle).
Changed
Kref.get_kind()is the text after the last.(kref://p/s/my.file.v2.kis kindk, wasfile.v2.k).An item kref with no kind raises
ValueErrorbefore sending (kref://p/s.v1/xnames a space), and so does a kind that contains/(Project.get_item("x", "image/png")): kinds containing/are not valid.Requests built from a server-returned item kref whose space ends in whitespace, or that holds an empty trailing segment, keep the shape they had.
Added
parse_kref()andKrefParts— one parser for the kumiho-db kernel’s verdict and parts of a kref, andKrefParts.get_item_request()for theGetItemrequest. It never raises. The shared grammar and conformance corpus are inspec/kref/.
Upgrading
Code that derives an item name or kind from a kref:
get_kind()of a dotted item name changed; take the stored kind fromItem.kind, and the name without its kind fromparse_kref(uri).item_name. SeeRELEASE_NOTES.md.
[0.14.4] - 2026-10-29
Changed
The
mcpextra’s floor is raised frommcp>=1.10.0,<3tomcp>=1.21.1,<3. pydantic 2.14.0 removed the privatepydantic._internal._typing_extra.eval_type_backport, which every mcp from 1.2.0 through 1.21.0 imports atimport mcp; with the newest pydantic those releases fail withImportErrorandkumiho-mcpcannot start. mcp 1.21.1 dropped the import. The CI and publish floor legs now pinmcp==1.21.1. Installs pinned to mcp 1.10.0 through 1.21.0 will be upgraded.
Fixed
tool_memory_store_batchno longer loses the whole batch to one bad space hint. A hint the server refuses with INVALID_ARGUMENT (edge whitespace such as"alpha / beta", an empty segment such as"a//b") used to raise out of the per-capture space step and fail the call. It now becomes{"error": ...}for that capture alone and the other captures are written in the same batch. Every other failure there still raises, and hints that worked are sent unchanged: the batch path still does not slugify.
[0.14.3] - 2026-09-23
Changed
tool_memory_storebatches direct provenance revision reads in windows of eight before creating their edges. Multiple direct revision references usebatch_get_revisions; selectors, batch failures, and missing revisions retain the per-reference lookup fallback. Store calls without provenance are unchanged.
[0.14.2] - 2026-09-21
Added
memory_projectandmemory_revision_limitonkumiho.search()andClient.search()— additiveSearchrequest fields. A supporting server validates the named project (exact, non-deprecated, under the authenticated tenant) and attaches each leading hit’s current revision —published, elselatest— to the result.SearchResultgainsmemory_revisionandmemory_revision_resolved, and the returned page carriesmemory_project_validated.memory_revision_limit(default 100) is sent only whenmemory_projectis set.Client.close()— releases the client’s gRPC channel once every borrower is finished, so a pool that retires clients can close their channels.
Changed
tool_memory_retrieve(..., include_resolved_metadata=True)uses search packets for a query in search and latest mode withoutunroll_revisions. When the server acknowledgesmemory_project_validated, the separate project lookup is skipped, and only hits whose packet was not hydrated go through the 0.14.1 batch resolution. A hit the server resolved to no accessible revision is not fetched again. An older server ignores the new fields and sends no acknowledgement, so the project check and the batch path run as before; a missing project returns the same error either way. Ranking, metadata, type/space filters, latest ordering and the pattern fallback are unchanged.python/protois pinned to the kumiho-proto commit that adds theSearchfields, and the Python stubs are regenerated with the same protobuf 6.31.1 toolchain as 0.14.0.
Notes
Deploy a server that supports the packets before clients rely on them. Search and Evaluate stay separate in the memory layer: graph and sibling processing still runs between them, so evaluation never sees a partial candidate set.
[0.14.1] - 2026-09-21
Added
include_resolved_metadataontool_memory_retrieve— internal and opt-in; thekumiho_memory_retrieveMCP schema is unchanged. The response gainsresolved_metadata, keyed by the exact revision kref and limited to the final results, each entry carryingmetadata,created_atandtags, so the memory layer does not fetch the same revisions again.Batched tag resolution on that path. In-scope search hits are resolved with
batch_get_revisionsin chunks of at most 100 items:publishedfirst, thenlatestonly for items that have no published revision. It does not apply withunroll_revisions. If the batch call fails, the per-item resolution runs instead and batch attempts are suppressed for 60 seconds on that client.MCP annotations for six kumiho-memory tools:
kumiho_memory_record_experience,kumiho_memory_record_outcome,kumiho_memory_prepare_patterns,kumiho_memory_store_pattern,kumiho_memory_check_patternandkumiho_memory_validate_insight_response. The hosted connector’s tool allowlist is unchanged.
Notes
A caller that does not pass the flag gets the same ranking, filters and response shape as 0.14.0.
The batched path needs a server with the current-tag batch resolution fix.
[0.14.0] - 2026-09-19
Added
kumiho.evaluate(query, fragments, questions, ...)andClient.evaluate(...)— judge prepared text fragments against caller-supplied questions using a server-managed evaluation provider. It is a ranking step over candidates the caller already holds, not a search: it takes no kref and it never reads, writes or tags the graph. Keyword arguments areextra_context,mode("","batched","per_fragment"),rubric_version,timeout_msandallow_cache.timeout_mssets both the server’s deadline hint and this call’s gRPC deadline, the latter with a two-second margin so the server’s own answer — including a non-OK status — wins the race againstDEADLINE_EXCEEDED.Value types in
kumiho.evaluation, re-exported fromkumiho—EvaluationFragment,EvaluationQuestion,EvaluationResult,FragmentEvaluation,EvaluationUsage, theEvaluationAnswerunion and its membersNoulAnswer,ChoiceAnswerandScoreAnswer, all frozen dataclasses. Fragments and questions are accepted as these types or as plain mappings; both build the same request.EvaluationResult.by_id()keys the per-fragment results by the caller’s own fragment id.Fragment ids stay on this side of the wire. What leaves the server for the provider is the query,
extra_context, each question’s instructions and criteria, and each fragment’s text and metadata. Ids are replaced with the server’s own private labels, and the literal{fragment}placeholder ininstructionspasses through untouched for the server to render.Client-side validation stops an obviously bad call before it costs tokens: a non-empty query, non-empty unique fragment ids, a known question type, and no
__in a question id, which the server reserves for its per-fragment ids. Shape and size limits are left to the server, the only side that can judge them. Mode and question type are translated here rather than passed through, because a typo in either would otherwise reach the server as the zero value and silently change what the call does. Statuses are derived from the enum name in the other direction, so a status this SDK predates reports"unspecified"rather than raising.Evaluatein the generated Python stubs, regenerated from kumiho-proto with the same grpcio-tools 1.76.0 / protobuf 6.31.1 the checked-in gencode headers name.
Notes
Evaluation is a Kumiho Cloud feature on paid tiers. A self-hosted CE server does not implement the RPC and answers
UNIMPLEMENTED; a tenant without the entitlement getsPERMISSION_DENIED, or a"not_entitled"result when the server answers in-band. Both surface asgrpc.RpcError, the way every other RPC’s failures do.There is no MCP tool for
evaluate. The memory layer is its caller, not an end user.
[0.13.2] - 2026-09-18
Added
item_krefontool_memory_store, and"item_kref"per capture ontool_memory_store_batch— the memory this store revises, given as an item kref or a revision kref (selectors are stripped). A correction knows what it corrects, so nothing is inferred: the similarity search is skipped, the new revision is created on that item,space_path/space_hintno longer decide placement (the item’s own space does, and it is whatmetadata["space"]records), and the item’s existing bundle membership is left alone. An unresolvable kref is an error — never a fall back to stacking or to a new item. The result has the shape of a stacked store:stackedtrue andprevious_revision_krefpointing at the item’s published revision, or its latest one when it had never been published. Batch rows gainprevious_revision_krefon this path; they had no such field.The
publishedtag moves with the correction, and only then. When the named item already had a published revision, the caller’s tags are applied first andpublishedlast — the server freezes a published revision and rejects tags applied after it. An item with no published revision is not published. A failingpublishedcall is returned as an error on this path (it is the operation the caller asked for), while the default path keeps swallowing tag failures as before.item_krefis not in thekumiho_memory_storeMCP schema; kumiho-memory’s reflect is its caller.
Fixed
space_pathsleaked items from same-prefixed spaces. The server’scontext_filteris a plain string prefix, sospace_paths=["9miho"]returned project-root items whose name begins9miho-, and["work"]returned items fromwork-infra.tool_memory_retrievenow checks each result’s own space path-segment-wise against the requested contexts — on the search, bundle, listing and latest paths alike — keeping genuine sub-spaces and dropping the lookalikes. The same check guards the stacking search, so a store can no longer displace a published revision in a space the caller never addressed.mode="latest"could starve the item it exists to find. The walk treatedItem.modified_atas an upper bound on revision dates and stopped early oncelimitresults were newer than the next item’s bound. That is only sound if the bound holds for the items it never resolves — and a server whosemodified_atdoes not track revisions hides exactly those: an item below the stop point is never resolved, so it never disproves the bound, so it never comes back. There is no early stop now. The bounded window is unchanged: themax(limit * 4, 20)items with the newestmodified_at(falling back to itemcreated_at) are resolved, and the results are ordered by their revision’s owncreated_at.mode="first"could resolve the whole project. When thememory_typesfilter matched nothing, the listing fallback walked every scoped item at 1-2 RPCs each (2,157 resolutions measured). It is bounded by the samemax(limit * 4, 20)window as the other modes.Mode spellings with spaces or hyphens fell through to search.
modeis now lowercased, stripped, and runs of spaces and hyphens folded to_before the alias lookup, so"most recent"and"Most-Recent"select latest._most_recent_itemsdroppedtzinfoinstead of converting. It now uses the same_ordering_timestampnormalization as the other ordering paths, so mixed UTC offsets compare correctly.
Removed
An unreachable widen-to-the-whole-project fallback in
tool_memory_retrieve(not results and contexts != [project_name] and not spaces).contextsdiffers from[project_name]exactly whenspacesis non-empty, so the two conditions could never both hold. The scoped listing above it already covers the unscoped case.
Notes
Nothing is published on the store’s own initiative.
publishedmoves only when a caller names a specific item to revise and that item already had a published revision; the tag is carried forward onto the replacement, never created. A store with noitem_krefbehaves exactly as in 0.13.1, including the long-standingtags or ["published"]default for an untagged new memory.Downstream: kumiho-memory’s
kumiho_memory_reflectgains arevisescapture field that passesitem_krefthrough (separate PR). The hosted connector picks both up when its pins move.
[0.13.1] - 2026-09-17
Fixed
kumiho_memory_retrievemode="latest"behaved as search. The schema advertised it, buttool_memory_retrievehad no branch for it: with a query results came back relevance-ranked, and without one in item-creation order, so a memory updated by a newer stacked revision never moved forward. It now orders newest first by thecreated_atof the revision returned for each item. With a query, relevance search picks the candidates (the topmax(limit * 4, 20)hits) and date orders them;scoresare kept, unsorted. Without a query, items are walked bymodified_atwith an early stop and a cap of the same size on revision resolutions.space_paths,memory_types, bundles andunroll_revisionsare honoured."newest","recent"and"most_recent"are accepted as aliases.mode="first"ignored the query andspace_paths. It listed the whole project and returned its oldest item, although auto-detect selects it only when a query is present. It now searches the scope contexts with no cross-space fallback. With a query, it returns the oldest by itemcreated_atamong the topmax(limit * 4, 20)relevance hits that passmemory_types, falling back to the scoped listing as the other modes do. Without a query, it walks the scoped items oldest first as before. It still returns at most one result with the same keys. A revision-less item no longer satisfies amemory_typesfilter.spaces_usedwas never filled from search hits. The search loop readitem.space.path;Item.spaceis astr, and the swallowedAttributeErrorleft the list empty. Returned search hits now report their space in project-prefixed form ("CognitiveMemory/personal", or the project name for a root item), deduped. First mode reports the returned item’s space instead of the project name.
Added
created_atonmode="latest"results — a list aligned withrevision_krefs(ISO strings,nullwhen a revision has none). Other modes’ results are unchanged.Item.modified_at, from theItemResponsefield of the same name the SDK never read.Nonewhen the server does not report it.
Changed
The
kumiho_memory_retrievedescription and itsmodedescription now say what each mode does.
Notes
spaces_usedis a deduped list, not aligned withrevision_krefs. Clients that readspaces_used[i]as the i-th result’s space were relying on an accident: the list was empty for search hits. They should derive the space from each result’s kref. The openclaw client in kumiho-plugins is being fixed.
[0.13.0] - 2026-09-04
Added
kumiho.request_context—RequestContext,current_request(),request_context()andhosted_mode(). Acontextvars-carried per-request identity (tenant, user, token, session) for deployments where one process serves many tenants.asyncio.to_threadcopies the context, so it follows a request across the async/sync boundary without being threaded through every call site.RequestContext,current_requestandhosted_modeare re-exported fromkumiho; the context manager is reachable asfrom kumiho.request_context import request_contextor askumiho.use_request_context— re-exporting it under its own name would shadow the submodule, since a submodule and a package attribute share one namespace andimport kumiho.request_context as rcresolves throughgetattr, notsys.modules.create_mcp_server(profile=..., instructions=...)—profile="connector"exposes a curated 18-tool surface for the hosted Claude connector;Noneor"full"keeps today’s whole tool list, which is what the stdio plugin gets. Falls back toKUMIHO_MCP_TOOL_PROFILE. An unrecognized name raisesValueErrornaming the valid profiles rather than silently serving everything — a typo in a deployment’s environment would otherwise publish every destructive tool to a public connector.kumiho.mcp_server.TOOL_ANNOTATIONS— MCP tool annotations (title,readOnlyHint,destructiveHint,idempotentHint,openWorldHint) for all 63 tools, the kumiho-memory ones included. Applied on both the mcp 1.x decorator path and the 2.xon_*path, withTool.titleandToolAnnotationsdetected by introspection so an older SDK degrades to unannotated tools instead of failing to construct.kumiho.mcp_server.ToolNotInProfileError— raised bycall_toolwhen a client asks for a tool the active profile withholds, so the refusal reaches the client as a real MCP tool error (isError: true) rather than a successful result whose text merely contains the word “error”. Clients and models branch onisError; a refusal that reports success reads as “the call went through”. mcp 1.x turns the raise into an error result on its own, and the 2.x branch catches the type and builds the same one.kumiho.mcp_server.CONNECTOR_INSTRUCTIONS— the engage/reflect protocol as serverinstructions, returned in the MCPinitializeresult for the connector profile. A remote connector has no skill and no hooks, so this is the only channel the protocol has.KUMIHO_STACK_MIDDLE_BAND— set to0to run the revision-stacking gate in strong-only mode, where a capture stacks only when its score clears the 0.75 strong threshold and the lexical floor; the 0.55 type-match band is withheld. Default is unchanged (two-band). Everykumiho_memory_storeandkumiho_memory_store_batchresult also reportsstack_mode("two-band"or"strong-only") next tostack_score/stack_runner_up/stack_overlap, so per-tenant telemetry can say which gate produced the number.
Changed
The MCP server’s process-global caches are keyed by tenant.
_project_cache,_known_spaces,_bundle_cacheand_space_registry_cachewere keyed by project name alone. Two tenants routinely have a project calledCognitiveMemory, and the cached value is a live handle bound to one tenant’s client and credentials.Hosted mode never mutates
os.environ. Theauth_tokenargument tokumiho_search_items/kumiho_fulltext_searchused to be published intoKUMIHO_AUTH_TOKEN; hosted, that is a credential swap visible to every other in-flight request, and a persistent one. It is now ignored (with a warning) when a request context is active orKUMIHO_MCP_HOSTED=1. Unchanged locally.Hosted mode never reads
~/.kumiho._ensure_configured()raises instead of falling back toauto_configure_from_discovery()when no request-scoped client is bound: the fallback would serve the operator’s own graph to a remote caller. Local memory-artifact writes are likewise a no-op when hosted — the root is on the server’s shared disk and the recorded path resolves for nobody.
Notes
Hosted deployments run with
KUMIHO_STACK_MIDDLE_BAND=0. The two-band gate was calibrated on one corpus. A shared multi-tenant server has not measured its own score distribution, and a middle-band false positive moves thepublishedtag onto an unrelated item — which every recall path then resolves first, so the displaced memory disappears from the default retrieval surface without anything reporting it. Strong-only keeps stacking for near-duplicates and withholds the contested band until thestack_mode/stack_scoretelemetry says a tenant’s distribution supports turning it back on. The stdio plugin keeps the two-band default.The stdio plugin path is unchanged in behavior: the default
create_mcp_server()still exposes every tool, with the same names and schemas. Tools now additionally carrytitleandannotations, which the plugin benefits from as much as the directory does.Two annotations deliberately disagree with the connector plan’s §2.2 hint columns, because the tools disagree with them:
kumiho_memory_space_profilepersists versioned profile items unlessdry_runis set (so it is not read-only), andkumiho_memory_dream_stateapplies deprecation (so it is destructive).space_profilekeeps its place in the connector profile; only the honesty of its hints changed.kumiho_memory_dream_stateis annotated but withheld from the connector profile for v1. Its assessment pass needs an LLM key and hosted tenants are keyless (plan §1.10), so listing it would publish a tool that fails at call time — which directory review catches head-on, since it asks the submitter to confirm every listed tool has been run. The full profile still serves it.
[0.12.2] - 2026-09-02
Fixed
Revision stacking in
kumiho_memory_storenever fired. The 0.92 fuzzy threshold sat above the scorer’s ceiling: an item scores 0.72-0.83 against its own exact title, so no input could ever stack and every capture minted a new item. The gate is now a lexical-overlap floor (token Jaccard >= 0.17 over Latin words and CJK bigrams, refusing texts under 8 tokens) combined with two score bands (>= 0.75 alone, or >= 0.55 with matchingmemory_type), calibrated on 17 labelled pairs from a live graph that are pinned as tests. The search now uses title and summary, is capped at 180 characters with a title-only retry (long CJK queries hit Lucene’s 1024-clause limit), and logs failures at warning instead of debug.Dart
EdgeType.isValidrejected valid types. It checked membership in a seven-item list rather than the regex every other SDK uses, soSUPPORTS,PRODUCED_BYandMIGRATED_FROMreturned false. Constants added;isValidnow delegates toisValidEdgeType.
Added
stack_score,stack_runner_upandstack_overlapon everykumiho_memory_storeandkumiho_memory_store_batchresult, reported whether or not the capture stacked, so a caller can tell a broken search from a near-miss.The 21-file
python/tests/suite is now collected by CI (moved underpython/python/tests/), together with thekumiho-clitests; a layout guard fails the build if a test directory underpython/is not run by any job.
Removed
python/.github/workflows/: dead copies that GitHub never read and that documented a stale version gate.
[0.12.1] - 2026-09-02
Added
SUPPORTSis reachable fromkumiho_create_edge— the tool’sedge_typeenum listed 8 of the 10EdgeTypemembers. The enum is enforced byjsonschema.validatein the MCP dispatcher, so the omitted types could not be written through this tool at all, even thoughEdgeTypedefines them,__init__re-exports them,validate_edge_typeaccepts them, and the proto field is a plain string.SUPERSEDESandSUPPORTSare now listed inkumiho.__all__, matching the aliases that were already defined.
Changed
The
kumiho_create_edgedescription and the MCP docs now state the direction of each type rather than naming only the four creative-provenance ones.
Notes
SUPERSEDESis deliberately still withheld from both edge tools. Belief revision is a protocol rather than a lone edge: its producers also demote the superseded revision and ripple grounding staleness to dependents. A bare edge write performs only part of that, so explicit belief revision belongs in the memory layer.kumiho_delete_edgekeeps the vocabulary it shipped with, since edge deletion has no repair path.
[0.12.0] - 2026-08-13
Added
Creative Project lifecycle APIs — Projects now expose metadata, archived listing and restoration, deletion-impact analysis, deletion guards, external reference resolution, Item moves, and snapshot-bound permanent deletion.
Space metadata support — Space creation and metadata updates can carry application-defined display labels without changing canonical identity.
Additive hard-delete RPC —
hard_delete_project()uses the new confirmation and impact-snapshot contract while the establisheddelete_project(project_id, force=False)signature remains available.
Changed
Generated protobuf and gRPC bindings now target the Project lifecycle contract shipped by kumiho-server 1.7.0.
Archived canonical Project names are reserved for identity-safe restoration. Creating another Project with the same canonical name returns a conflict.
[0.11.0] - 2026-08-01
Added
mcp 2.x support —
kumiho[mcp]now runs on both mcp 1.x and mcp 2.x. mcp 2.0.0 removed the low-levelServerhandler decorators and replaced them withon_*constructor keywords; the six handlers are registered through whichever shape the installed SDK provides, selected by capability detection rather than a version number so editable installs, forks and vendored copies resolve correctly. Capabilities, wire format and tool behavior are identical on both majors.Tool input validation on the 2.x path — mcp 1.x validated tool arguments against each tool’s
inputSchemabefore dispatch and mcp 2.0’s low-level path does not, so the SDK now performs that check itself. A schema-violating call is still rejected withInput validation error: ...rather than reaching the handler.
Fixed
kumiho[mcp]installed a server that could not start. Themcpextra declaredmcp>=1.0.0with no upper bound, so once mcp 2.0.0 published, every fresh install resolved to it andcreate_mcp_server()raisedAttributeError: 'Server' object has no attribute 'list_tools'at construction (KumihoIO/kumiho-SDKs#145).resources/readhad never worked, on any version: the handler assumed astrURI but MCP passes a pydanticAnyUrl, so every read raisedAttributeErroron its first line (#146). Resource bodies now also keep their declaredapplication/jsoncontent type instead of being served astext/plain, and the project name is percent-decoded — mcp 1.x escapes non-ASCII when anAnyUrlis stringified and mcp 2.x does not, so without decoding a Hangul or spaced project name resolved on one major only.serverInfo.versionreported the mcp SDK’s version as kumiho’s under mcp 1.x, and would have reported an empty string under 2.0 (#147). It now reports kumiho’s own version.
Changed
The
mcpextra is now bounded at both ends:mcp>=1.10.0,<3. The floor is the oldest release where every assumption in the code actually holds —mcp.server.lowlevel.helper_typeslanded in 1.3.0 and thecall_tooldecorator’svalidate_inputin 1.10.0, below which the 1.x path would silently skip tool-argument validation. Installs pinned below mcp 1.10.0 will be upgraded. CI now runs the suite against the declared floor and both majors, so a future major bump fails the build rather than reaching users.jsonschemais declared directly in themcpextra, since the SDK now imports it rather than relying on it transitively.
[0.10.8] - 2026-07-15
Fixed
MCP server orphan hardening —
kumiho.mcp_servernow exits when its launching ancestor chain dies: event-driven on Windows (a watchdog thread blocks on the ancestor process handles viaWaitForMultipleObjects), ppid-reparent polling on POSIX. On Windows, MCP clients restart sessions by terminating the launcher process, which does not kill its children — and because a venv’sScripts\python.exeis a redirector stub that runs the base interpreter as a separate child, the real server is a grandchild or deeper, so the whole contiguous python-named ancestor chain plus the client is watched, not just the direct parent. The strandedpython -m kumiho.mcp_serverprocesses previously accumulated without bound (KumihoIO/kumiho-plugins#25). Additionally,main()now hard-exits once the stdio transport closes, so lingering non-daemon threads (thread pools, gRPC channels) can never keep a dead server alive. Opt out withKUMIHO_MCP_DISABLE_ORPHAN_WATCHDOG=1.
[0.10.7] - 2026-07-15
Added
tool_memory_store_batch— the bulk counterpart oftool_memory_storefor the MCP write path. N captures land in onebatch_create_revisionstransaction (removing the neo4j relationship-group deadlock that per-capture concurrency triggers, and collapsing the heaviest create/revision writes) while preserving every per-capture semantic of the single path: credential screening, space resolution, fuzzy-stack,event_date/metadata, tags,topicbundle, andDERIVED_FROMedges (tag/bundle/edge stay per-item — the server has no batch RPC for them).kumiho_memory_reflectroutes ≥2-capture writes through it; a single capture keeps the byte-identical per-capture path.
[0.10.6] - 2026-07-15
Added
Batch revision creation —
batch_create_revisions(revisions, idempotency_prefix=...)writes up to 200 captures (item + revision + optional artifacts) in a single server transaction, returning positional(results, failures). Missing items are auto-created from each row’sitem_kref; rows targeting the same item stack in order (last becomeslatest); per-row artifacts can mark one"default": Trueso the chain resolves straight from the item kref; a stableidempotency_prefixmakes re-submission a safe no-op. Requires kumiho-server >= 1.6.3.
[0.10.5] - 2026-07-11
Added
kumiho._text.slugify()— one canonical slug helper shared by the SDK and kumiho-memory, so a fix (Unicode handling in particular) cannot land in one copy and silently miss another.\wis Unicode-aware, so Hangul, CJK and Cyrillic names slug to themselves rather than to the empty string, matching the kref path segments the server accepts. Optionalhash_on_truncateappends a short digest of the full normalized string so two long names sharing a prefix keep distinct slugs.MCP space registry — the MCP server records space aliases and resolves space hints against a short-lived per-project registry of existing space paths, with stem matching, so a near-miss space name resolves to the existing space instead of creating a near-duplicate.
[0.10.4] - 2026-07-03
Fixed
memory_typenever round-tripped — the server reserves thetypemetadata key, which made thememory_typesfilter dead code (#21).Interactive login prompt inside headless processes — the SDK could open a login prompt in a process with no console, hanging the MCP server indefinitely (#22). Both fixed in #23.
[0.10.3] - 2026-07-03
Fixed
Memory-retrieve RPC storm (#20) —
searchnow retries shallow wheninclude_revision_metadata=Truereturns nothing, and the pattern-fallback and bundle-expansion loops are bounded atlimit * 2. This removes the ~185s MCP timeout on unscoped recall against large cloud projects.
[0.10.2] - 2026-07-03
Fixed
__version__drift left over from 0.10.1 —kumiho/__init__.pywas never bumped whenpyproject.tomlwent to 0.10.1, so the published wheel’s metadata correctly said 0.10.1 whilekumiho.__version__still read"0.10.0"at runtime.
Added
tests/test_version.pyassertskumiho.__version__matchespyproject.toml, so this class of drift fails a test instead of silently shipping again.
[0.10.1] - 2026-07-03
Fixed
tool_memory_storenever applied tags — it called a nonexistent module-levelkumiho.tag_revision(...)instead of therevision.tag(...)method, and a bareexceptswallowed the failure. No tag, including the defaultpublishedtag, was ever actually applied through this path, which broke Dream State’s published-revision deprecation protection for every consumer relying on the default store backend.
[0.10.0] - 2026-06-17
Added
Full-text fuzzy search —
search(query, ...)returns ranked items (SearchResultwithitem,score,matched_in), with automatic typo tolerance.Semantic revision scoring —
score_revisions(query, revision_krefs)scores revisions against a query using server-side embeddings and/or fulltext.Batch revision fetch —
batch_get_revisions(revision_krefs=..., item_krefs=..., tag=...)fetches many revisions in a single call, returning(revisions, not_found).By-kref accessors —
get_artifact_by_kref(),get_bundle_by_kref(), andclient.get_item_from_revision().
Changed
The advanced
event_stream()parameters (cursor,consumer_group,from_beginning) andget_event_capabilities()are now generally available.The C++ and Dart SDKs now have full feature parity with the Python SDK.
[0.9.24] - 2026-04-17
Fixed
Unicode kref path segments —
Krefrejected non-ASCII letters in path segments even though the server accepts them, so a Hangul or CJK space or item name could not be addressed from the SDK.
[0.9.23] - 2026-04-17
Changed
gRPC reliability hardening — a per-RPC default deadline, so a call can no longer hang indefinitely against an unresponsive gateway.
Recall defaults to summarized mode, and summarized recall skips sibling unrolling.
[0.9.22] - 2026-04-02
Fixed
tool_memory_retrieveaccepts amemory_typesparameter, which the tool schema had omitted.
[0.9.21] - 2026-04-02
Added
kumiho_batch_get_revisionsMCP tool — exposes the SDK’s batch revision fetch to MCP clients, replacing N serialget_revisioncalls.
[0.9.20] - 2026-03-15
Fixed
Dream State consolidation returned data the ingest path could not use. The consolidation and Dream State responses are now shaped correctly for ingest, and the OpenAI response object is parsed as JSON rather than passed through as an object.
[0.9.19] - 2026-03-10
Added
Per-call
auth_tokenon the search tools, enabling cross-project search without rebuilding the client.
[0.9.18] - 2026-03-10
Fixed
assistant_textremoved fromrequiredin thekumiho_memory_storeschema; it was never mandatory to the handler, so the schema rejected valid calls.
[0.9.17] - 2026-03-09
Added
TransientRetryInterceptor— retries transient gRPC failures, so a gateway restart no longer surfaces as a hard error to the caller.
[0.9.16] - 2026-03-08
Fixed
Dream State replaced its event-stream collection with a revision query, decoupled its collection window from the gRPC deadline, and handles
DEADLINE_EXCEEDEDgracefully instead of aborting the pass.
[0.9.15] - 2026-03-07
Fixed
The chat tool handlers respect the client’s
projectparameter, and the replay tier gate was removed.
[0.4.0] - 2025-12-03
Added
Event streaming cursor support:
Event.cursorattribute for resumable streamingEventCapabilities API:
get_event_capabilities()to query tier-based streaming featuresNew event_stream() parameters:
cursor: Resume from last position (Creator+ tiers, Coming Soon)consumer_group: Load-balanced consumption (Enterprise tier, Coming Soon)from_beginning: Replay entire buffer (Creator+ tiers, Coming Soon)
Tier capability documentation with Coming Soon markers
Changed
Updated event streaming documentation with tier matrix
Event object now includes
cursorattribute (None for Free tier)
Notes
Creator tier and above streaming features are planned but not yet deployed
Free tier provides real-time streaming without persistence
[0.3.0] - 2024-XX-XX
Added
Comprehensive Google-style docstrings for all public APIs
Sphinx documentation with ReadTheDocs theme
get_artifact()top-level function for fetching artifacts by Krefget_artifact_by_kref()method in Client classType hints throughout the codebase
Changed
Updated
pyproject.tomlwith full PyPI metadataImproved error messages with more context
Fixed
Kref parsing for artifact URIs with special characters
[0.2.0] - 2024-XX-XX
Added
Event streaming support with
stream_events()Link traversal for lineage tracking
Batch operations for multiple artifacts
Changed
Switched to context-variable-based client management
Improved connection pooling for gRPC channels
[0.1.0] - 2024-XX-XX
Added
Initial release
Core entity classes: Project, Space, Item, Revision, Artifact, Edge
Kref URI parsing and generation
Discovery-based authentication
CLI authentication tool (
kumiho-auth)