kyvvu changelog¶
All notable changes to the Kyvvu Python client (kyvvu) are documented in this file.
Versions before 0.11.0 were early development releases with frequent breaking changes. The changelog starts from the current beta.
[1.0.0] - 2026-10-30¶
-
Changed: depends on
kyvvu-templates>=1.0.0,<2.0.0, which now ships the behaviour templates the engine no longer exports. -
Changed: the
kyvvucommand now ships in the Apache-2.0kyvvu-clidistribution. Install it separately; the client no longer installs a console script or exposes aserveextra. - Changed:
Kyvvu.register_agent()now delegates registration transport, retries and caching toPlatformClientand evaluates the profile accepted by the platform, including an owner assigned in its response. -
Removed: the client's
_registration_cache.pyand duplicate HTTP transport,__min_api_version__,SDK_API_VERSION,KV_SKIP_API_VERSION_CHECK, andKyvvuIncompatibleAPIError. Platform engine and policy schema compatibility checks remain. -
Changed: the Apache-2.0 baseline manifests, profiles, and loader now ship in the
kyvvu-baselinedependency. Existingkyvvu.baselineimports remain available as re-exports. -
Breaking: 1.0. Requires
kyvvu-engine>=1.0.0,<2.0.0and a platform at 1.0.0 or newer: the steps carryhash, which API 0.22 refuses with 422. ClassifiedDevelopment Status :: 5 - Production/Stable. -
Breaking: requires Python 3.11 or newer (
requires-python = ">=3.11"), withkyvvu-engine1.0. The 3.10 classifier is gone. On 3.10, pip keeps resolving the newest 0.x release. -
Changed: traces sent to the platform carry
seqandhashon every step: the engine computes the hash chain and the platform verifies it. Nothing changes in the client's own API.
[0.23.0] - 2026-10-17¶
-
Fixed:
kyvvu doctorwith both a CLI session and an agent API key checks both, on the Credential line, and fails when the key is rejected; a valid session used to show✓beside✗ Policies … (401). The key is checked where an agent started here would use it. Policies names the URL it fetched from and, on a 401/403, namesKV_API_KEYas the fix; when that URL differs from the CLI session's, Policies and Trace sink say so and suggest--api-url/KV_API_URL(Trace sink warns). The probe runner's own stderr notices are silenced, so nothing precedes the report. -
Fixed: the manifest CLI could not be used end to end.
kyvvu list-assignmentshas anIDcolumn andkyvvu assign-manifestprints the new assignment id, which is whatkyvvu unassign-manifest --assignment-idtakes. A refused request prints the platform's reason on one line,Error (409 manifest_already_assigned): Manifest '...' is already assigned ..., and exits 1, instead of the raw JSON body followed byFailed to assign manifest: 1(a catch-all interceptedtyper.Exit, which is not aSystemExit). Every CLI command reports platform errors in that shape.--agent-idonassign-manifest,list-assignmentsandlist-policiestakes the agent key as well as theagent_…id; a key used to answer404 Agent not found. -
Fixed:
kyvvu doctorverifies the declaredkyvvu-enginerange withoutpackaging, which the SDK does not depend on: a clean install now prints✓ Versions … (satisfies <1.0.0,>=0.13.0)instead of• Versions … not verified (packaging not installed). The built-in comparison covers the>=X,<Yrelease-number ranges the SDK declares and abstains (falling back topackaging, else "not verified") on anything else. -
Fixed: with
KV_POLICY_FILEset,kyvvu doctor's trace-sink hint claimed that withKV_API_KEYand an agent key setautowould resolve to the platform, even withKV_API_KEYset. It now saysautofollows the local policy file, and names only what is actually missing. -
Fixed: a plain
kyvvu tryprinted two "path ... resolved on none of the trial steps" warnings (the typo hint) aboutproperties.target.trust, which the bundled demo path leaves out on purpose. The warning now appears only when you supply the policies (--manifest), where a missing path may be a misspelling of yours; the bundled baseline's paths are never reported, including under--stepsalone. -
Fixed: two threads reaching
Kyvvu.runnerfirst at the same time each built a runner, the second replacing the first; a task started on the replaced one was unknown to the one that stayed, so its next step raisedTaskStateError: task ... is not open. The lazy construction is now locked. -
Changed: the bundled
eu-ai-act-minimalbaseline is 1.1.0. "AI-generated content must be marked before delivery" no longer demands astep.gateimmediately before everystep.model-- before the content exists -- and so no longer warns on every model call. It now fires on delivery: an outboundstep.messagePOST, or astep.resourcePOST withproperties.target.trust: external, in a task that holds a completedstep.model, warns unless astep.gatewas recorded after the most recent model step. The citation is corrected to Article 50(2).kyvvu tryand thekyvvu initscaffold gain a delivery step,send_reply(step.messagePOST), between the model call andrun_script, and now go allow, allow, warn, block: the warn lands on the delivery (content marking, Art. 50(2), and chatbot disclosure, Art. 50(1)) rather than on the model call, and the block is still OWASP ASI05 on the ungatedstep.exec. -
Added:
Kyvvu.registration_result, theEvalResultof the lastregister_agent()policy evaluation, set on the fresh, cached and stale-cache paths and on a block (the exception's ownresult). A call that fails before evaluating clears it. A warn outcome used to reach onlywarnings.warnand the incident sink, andregister_agent()returns the platform's response, so a caller had no way to read which registration policies warned. -
Added: a manifest assigned to a running agent applies without calling
register_agent()again. When a policy refresh changes the agent'sagent_registrationpolicies, the registration last sent is evaluated again: warnings file a registration incident, and a blocking violation makes every following step raiseKyvvuBlockedErrornaming the policy until a later refresh lets the registration pass.kv.policy_status()reports it asregistration_blocked/registration_blocked_by. - Breaking: identifiers have a grammar (see
docs/concepts/tasks.md, "Identifier rules"). Atask_idpassed tostart_task(),resume_task(),end_task(),idle_task(),error_task()oradd_step(), and anaction_idorstep_namepassed toadd_step(), outside its rule raisesKyvvuValidationErrornaming the field and the rule, before anything is recorded. An explicitly passedtask_idis refused, never mapped; an empty string is no longer treated as "omitted". - Changed: names and ids that come from code or a framework are made to
comply instead of raising:
@kv.stepfunction names, template-rendered task-boundary names (context["name"], crew and chain names) and framework tool names have control characters replaced by U+FFFD and are cut to 255 characters; a framework task or run id outside the grammar is mapped tox-plus 32 hex digits of its SHA-256 (deterministic), with the raw task id kept asproperties.raw.task_id. NewKyvvu.capture_step_name(),Kyvvu.compliant_task_id()andKyvvu.compliant_action_id()for adapters. -
Fixed:
kyvvu tryrecords a blocked step as a blocked step, as a real run does, so a rule withcount_attemptssees the same history in a trial.record_blocked_step()coerces the error message to I-JSON. -
Breaking: A write into a task this client does not have open now raises
KyvvuConfigErrorinstead of starting a second record of the task numbered from 1. This coversadd_step(),end_task(),idle_task(),@kv.step(including a context still naming a task that another context ended), andFrameworkAdapter.emit_step(). A step completion arriving after its task closed is dropped with a warning, never raised: a framework completion, and an@kv.stepcompletion, failure or block record when the task closed while the step ran (the function itself calledend_task(), or another context closed the task while an async step awaited).start_task()refuses an id that is already open.add_step()with a task boundary kind now has the matching lifecycle effect (task.startopens the task,task.end/task.errorclose and flush it). In 1.0 a task cannot be continued after it ends or from another process; atask_idmust never be reused. -
Changed: Captured values are coerced to I-JSON, which the engine now requires, so recording never fails the host's call: decorated arguments and return values,
add_step()input/output, and framework callback payloads and template-extracted properties, and the exception text a failed or blocked step records. Tuples and sets become lists, datetimes ISO strings,Decimal/UUIDstrings, NaN/Infinity the strings"NaN"/"Infinity"/"-Infinity", integers beyond 2^53-1 strings, bytes a"<bytes len=N>"marker, non-string keysstr(key), pydantic models theirmodel_dump(), anything else itsrepr. Explicitadd_step()propertiesandmetaare not coerced (policies read them): a non-I-JSON value raisesKyvvuValidationErrornaming its path.FrameworkAdapter.emit_task_start()takesproperties=;Kyvvu.capture_value()/capture_payload()expose the coercion to integrations. -
Breaking: A context without a selected task no longer resumes the client's only open task. Call
kv.resume_task(task_id)in that context, or passtask_id=to programmatic step and task methods. Framework tool callbacks retain their adapter task context. -
Breaking: Framework tool callbacks now record
POSTby default. Declare reads withKyvvu(read_only_tools=[...]);write_toolsexplicitly classifies writes. Tools carryingdata.*ortarget.trustrequire one of these declarations. -
Removed: The inherited
policy_hmac_secretsetting and HMAC policy verification. Ed25519 signing is planned for a future release. -
Breaking: Decorated gates record
properties.kindandoutput.decision; a normal return passes, whileGateDeniedor a crash denies. Manual gates needoutput={"decision": "pass"}to satisfy the bundled baseline. Ship this SDK and the matching engine before the platform serves updated gate policies. -
Removed: The inherited cross-execution rate-limit rule is no longer available. Policies naming it fail to load as an unknown rule.
-
Breaking: Exported trace steps carry the per-task ordinal as
seqin place ofstep, and a recordedBehaviorexposes it as.seq. -
Breaking: The behaviour field is
kindand its enum isActionKind; the retired field and enum names are rejected. Policy kind parameters aretarget_kinds,trigger_kinds,forbidden_kind,forbidden_kinds,required_kind,taint_kind, andforbidden_predecessor_kinds; old parameter names are rejected. A step policy'sfieldneeds a complete path such asinput.recipientorproperties.message.recipient(that is,input.<name>orproperties.<name>); bare data field names are rejected. -
Breaking: SDK model calls omit the verb. Passing
Verb.POSTto astep.modeldecorator now raises. Policies matchingPOSTwithout a step-type filter no longer match model calls; selectstep.modelexplicitly. ExistingPOSTlog rows remain as history.
[0.22.1] - 2026-10-01¶
Fixed¶
- A policy block raised from
on_chain_startor the root'son_chain_endleft the task open (LangChain, LangGraph). A block normally leaves the task to the framework's error callback, but a block on the firststep.message(raised out ofon_chain_start, so the run never starts) or on the final one (raised after the run finished) is followed by no error callback. The handler now closes the task astask.erroritself; before, it stayed open until the sweeper evicted it an hour later.
Added¶
KyvvuCrewAIListener.blocked_exception: theKyvvuBlockedErrorthat tripped the circuit breaker, for a caller to re-raise afterkickoff()(CrewAI's event bus swallows it).blocked_reasonstill gives the message.
[0.22.0] - 2026-10-01¶
Breaking. Requires the matching kyvvu-engine release. Several integration
defaults changed; read the breaking list before upgrading.
Breaking changes¶
- The
templateargument is a sentinel, andNonemeans no template. The default iskyvvu.default_template("the built-in, orKV_TEMPLATE_LOCATION"). ABehaviorTemplateyou pass replaces the built-in and governs both the steps and the task boundaries the integration opens; nothing falls through to the built-in. The template is checked at construction and must cover every boundary: all fourtask.*types forKyvvu, andon_chain_start/on_chain_end/on_agent_finish/on_chain_error(LangChain, LangGraph) or the threecrew_kickoff_*events (CrewAI).template=Noneis accepted byKyvvufor@kv.stepandadd_step, refused bystart_task, and refused by the callback handlers. function_nameandfunction_name_patternare removed. One name key,name/name_pattern, on every surface.step_nameis an output field, never a match key. Templates are validated strictly at load (see the engine).scope:is gone from manifests and policies and policy load failures raisePolicyLoadError.kv.dropped_policies,PolicyStatus.droppedandPolicyLoadState.all_droppedare removed; four load states remain.kyvvu try,doctorandserveexit non-zero on an unloadable set.KV_ENVIRONMENTworks throughKyvvu(...)and the default isproduction. Precedence is the argument, thenKV_ENVIRONMENT, thenproduction(the SDK used to default todevelopment). SetKV_ENVIRONMENT=developmentfor local work; thekyvvu initscaffold does.kyvvu tryprints the environment it evaluated as.- A policy block no longer ends the task on any surface. The
decorator and the framework adapters used to close the task on a block. Every
surface now records the blocked step, raises
KyvvuBlockedError, and leaves the task open; callerror_task(),end_task(), or record an approval gate and retry.error_task()on a closed task raisesKyvvuConfigError. - A decorated
step.gatepasses unless it raisesGateDenied. The decorator template no longer hard-codesguard.result = "pass"; the decorator recordspasson a normal return andfailonGateDenied(new, exported fromkyvvu, not aKyvvuBlockedError). A gate function that only returns a denial records a pass: deny by raising. - Callback handlers own their task. They raise
KyvvuConfigErrorif a task is already active and close only tasks they opened. Do not wrap a handler inkv.start_task(). @kv.stepon a tool a handler is running raises, because the call would be recorded twice. Decorated helpers andadd_stepinside a tool are fine.domain_allowlistrequirestarget_step_types; regexes usere.search;risk_classificationmeans "this class or above";cross_execution_rate_limitis refused at load (engine changes). The bundled decorator template now leavestarget.hostout when a function has nourlargument (| omit_empty).
Added¶
kyvvu template show <name>prints a built-in template (decorator,langchain,langgraph,crewai) from the package data, to copy and edit.- An unmatched callback event is recorded as
step.unknown. - Asynchronous reporting. Incident reports and trace flushes are
queued and sent by a worker thread;
kv.flush(timeout)andkv.report_status(); settingsKV_REPORT_QUEUE_SIZE(1000) andKV_REPORT_EXIT_FLUSH_SECONDS(2). The stdout, file and callback sinks stay inline. - A
kyvvu[serve]extra. It is not on PyPI until this release is published; until then installpip install kyvvu "kyvvu-engine[serve]".
Changed¶
kyvvu try's closing text follows the outcome of the gate replay and it prints the environment.- The CrewAI
ImportErrornamespip install "crewai>=1.15.21,<2"; there is nokyvvu[crewai]extra.
[0.19.0] - 2026-08-27¶
Breaking. Follows kyvvu-engine 0.10.0 in restoring the task.*
action-type namespace. Requires kyvvu-engine>=0.10.0.
Breaking changes¶
- The four task-lifecycle step types return to the
task.*namespace:step.task_start→task.start,step.task_end→task.end,step.task_error→task.error,step.task_idle→task.idle, with theStepTypemembers renamed to match. All four built-in templates (decorator,crewai,langchain,langgraph) are updated. A custom.btmplstill naming the old spelling must be updated. - Task-boundary markers no longer carry an
output.start_task,end_task,error_task, the blocked-start path, and_flush_task_errorused to recordoutput={"status": ...}on a lifecycle marker. Per the AAG spec a marker carries noinputand nooutput— that absence is what lets a consumer read a step with nooutputas an intended action rather than waiting for a result that never comes. The status and error text now live underproperties.task. - A template that does not cover a task-boundary type now raises
KyvvuConfigErrorinstead of silently synthesizing a fallback behavior. The fallback cost the caller the template's property extraction and changed the resolvedstep_name, with no log line — the framework adapters warned on an unmatched context, but the decorator path did not.
Added¶
kv.idle_task(), and atask_idlerule in the decorator template. The engine has always handledtask.idle, but the SDK had no way to emit it and the decorator template had no rule for it, so every idle marker fell through to the silent fallback. The task stays open: memory persists across the idle period and the next action signals resumption, soidle_task()does not end the task or clear the active-task context.StepType.task_idleis now in the decorator's task-step set, with both the sync and async handlers wired.
[0.11.0] - 2026-04-28¶
First tracked release. Establishes the public API surface and the two integration patterns (decorator, LangChain).
Breaking changes from earlier versions¶
- Constructor:
agent_keyandrisk_classificationare now parameters onKyvvu(), notregister_agent(). Passing them toregister_agent()raisesTypeError. - LangChain handler:
KyvvuLangChainHandleris now a pure adapter that accepts an already-constructedKyvvuinstance. The old pattern (KyvvuLangChainHandler(api_key=..., agent_key=...)) no longer works. UseKyvvu()+register_agent()+KyvvuLangChainHandler(kv). kv.enrich(): Removed as instance/static method. Use the module-levelfrom kyvvu import enrichor inline the dict.capture_outputkwarg: Removed from@kv.step(). Thetask_enddecorator now flushes automatically.- Task lifecycle:
start_task()replacesbegin_task(). Callingstart_task()twice on the same task withoutend_task()raisesKyvvuConfigError.
Added¶
Kyvvuclass with two identity-acquisition paths: constructor (agent_id) or registration (register_agent()).- Programmatic task API:
start_task(),resume_task(),end_task(),error_task(). @kv.stepdecorator integration viaFrameworkAdapterbase class.KyvvuLangChainHandlercallback handler (pure adapter pattern).- YAML behaviour templates with first-match-wins rule evaluation.
- Built-in templates:
decorator.template.yaml,langchain.template.yaml. BehaviorTemplate.from_builtin()andBehaviorTemplate.from_path().KV_TEMPLATE_LOCATIONenv var for custom templates.- CLI:
kyvvu auth,kyvvu agents,kyvvu policies,kyvvu config,kyvvu init,kyvvu serve. - Exception hierarchy:
KyvvuError,KyvvuAPIError,KyvvuBlockedError,KyvvuConfigError,KyvvuKeyRevokedError,KyvvuRateLimitError,KyvvuTimeoutError,KyvvuValidationError. - 351 tests across decorator, LangChain, templates, CLI, and core.