Repository navigation
Releases
Releases · a2ui-project/a2ui
A2UI CLI v0.3.0
-
Breaking: Requires
a2ui_core^0.7.0(a2ui_cliexposesa2ui_core
types in its public API). -
Added
a2ui lint(LintCommand,lintCatalog,CatalogLintFinding, andLintSeverity) to validate catalog JSON schemas against deterministic protocol rules with JSON Pointer locations, including v1.0 Unicode UAX 31 identifiers, component and function discriminators, the reservedSurfacecomponent name, v1.0requiresUserActivationcaller constraints, and redundantComponentCommonorFunctionCommonwrapping (#3831).
a2ui-core 0.6.0
- BREAKING CHANGE: (v1_0) Component validation
(PayloadValidator.validate_component, andMessageProcessorfor calls into
another catalog) rejects a call to a function whoseallowedCallersis
agentOnlyin a property binding, a check or an action, since only an
agent'scallRendererFunctionmay call one. The error matches the one
DataContextreports when such a call is evaluated. v0.9 catalogs are not
affected.PayloadValidator.validate_functionchecks only the envelope of a
call nested in an argument, as component validation does, since the call
runs in the catalog it names. Recommended migration: bind only
rendererOnlyorrendererOrAgentfunctions in components.
InternalCallRendererFunctionOpis exported froma2ui.core.processing, and
validate_reserved_directivesfroma2ui.core.resolution
(#3534,
#4008). - BREAKING CHANGE: Basic catalog
regexfunction (v0_9andv1_0) now validates patterns against the A2UI portable regex subset (ECMAScriptPatternin Unicode mode with no flags), enforces the 4-rule static ReDoS safety guard (PATTERN_TOO_LONGat 256 code points,NESTED_QUANTIFIER,OVERLAPPING_ALTERNATION, andADJACENT_OVERLAP), translates patterns to Pythonrewith exact ECMAScript character class and anchor semantics (\A,\Z, ASCII\d/\w/\b/\B, and\uXXXX/\UXXXXXXXXbracket classes), raisesA2uiExpressionErrorwith the rejection token on invalid or unsafe patterns, and returnsFalse/{"valid": False}without raising when the input value exceeds 4,096 Unicode code points. Recommended migration: rewrite patterns that use lookbehind, backreferences, named groups,\p{...}, inline flags, or nested/overlapping unbounded quantifiers to the portable subset. Exportsparse_regex_subset,check_regex_safety,analyze_regex,translate_to_python,compile_guarded,regex_test,RegexNode,RegexRejection,RegexAnalysisResult,RegexSyntaxError,MAX_REGEX_PATTERN_CODE_POINTS, andMAX_REGEX_VALUE_CODE_POINTSfroma2ui.coreanda2ui.core.common(#3854). - BREAKING CHANGE: (v1_0) The basic catalog
TextFieldrequiresvalue,
as the other input components do, so aTextFieldwithout one fails
validation instead of accepting input that never reaches the data model.
Recommended migration: bindvalueto a data model path, such as
{"@path": "/form/email"}. The path does not have to exist yet
(#3830, #3868). - BREAKING CHANGE:
DynamicBooleanproperties and function arguments now
coerce any resolved value to a boolean according to the protocol
specification: booleans are kept as is,ValidationResultobjects coerce to
valid, strings coerce toTrueonly when case-insensitively equal to
"true"(andFalsefor"false"and all other strings), numbers coerce to
value != 0(NaNisFalse), andNone, absent values, other objects,
and arrays coerce toFalse. Recommended migration: pass explicit booleans,
non-zero/zero numbers,"true"/"false"strings, orValidationResult
dicts rather than relying on Python truthiness orNonepass-through
(#3850). - BREAKING CHANGE: On every protocol version, a function call whose
nested argument call fails no longer runs withNonefor that argument: it
fails too, and the argument's error is reported once. Recommended migration:
handle a missing value inside the nested function instead of relying on the
enclosing one to receiveNone.
(#3415,
#3536,
#3740) - BREAKING CHANGE: Action errors are classified the same way in every
kind of action. A local function that ran and raised isEXECUTION_ERROR,
in an event action'scontextanduserMessageas well as in
action.functionCall; previously the event values reported
EXPRESSION_ERROR. A refused call (missing user activation,agentOnly,
invalid arguments) isEXPRESSION_ERROReverywhere; previously a
functionCallaction refused for user activation reported
EXECUTION_ERROR.GenericBinderruns a function call action through
DataContext.resolve_action, so these codes andrequires_user_activation
apply there, and its closure returns the result's current value.
Recommended migration: treatEXECUTION_ERRORas a function failure and
EXPRESSION_ERRORas a refused or malformed call.
(#3415,
#3536,
#3740) - (v1_0) The common types
IndexSystemFunctionschema declares"returnType": "number", like catalog functions do (#3725, #4025). - (v0_9) Restore
list_style(listStyle) property to basic catalogListcomponent schema (#3956). - (v1_0) The basic catalog
regexfunction'spatterndescription now names
the A2UI regex dialect and its safety limits
(#3820). - (v1_0) Function calls inside
${...}template expressions offormatString
now inherit thecatalogIdthat the enclosingformatStringcall resolved
to, even when the surface defines a different defaultcatalogId, while
preserving reserved@-prefixed system calls such as${@index()}as
catalogless.DataContext.active_catalog_idexposes the catalog ID of the
currently executing function call
(#3727). - Add
RpcHandler.cancel_surface_callsto cancel pending outbound agent
function calls withRpcErrorCode.CANCELLED. DataModelnow defensively copiesinitial_dataand values passed toset(), preventing subsequent caller mutation of input dicts or lists from silently mutating internal state, andPayloadValidatornow validates component type names against UAX 31 identifier syntax on v1.0+ surfaces.- (v1_0)
Catalog.from_json()now rejects function definitions that set
requiresUserActivation: truewhenallowedCallersis not'rendererOnly'
(such as'agentOnly'or'rendererOrAgent') by raisingA2uiCatalogError,
matching the v1.0 catalog definition schema
(#3840). MessageProcessorwrites an inlinecreateSurface.dataModelas one
DataModel.setper top-level key (/<escaped_key>, escaping~as~0and
/as~1per RFC 6901) before applying inlinecreateSurface.components
(#3857).- (v1_0) A function call whose function the renderer does not implement
(undeclared in the catalog the call resolves to, or declared schema-only) is
sent to the agent withcallAgentFunction, as the specification's fallback
routing defines, for bindings, check rules,action.functionCalland
action.event.MessageProcessorenables it on v1.0 surfaces that have an
outbound_listener. The call names its resolved catalog, and a schema-only
function's arguments are validated once they resolve and sent with the
schema's defaults. A call is not sent, and reportsEXPRESSION_ERROR, when
its function isagentOnly, needs user activation the evaluation lacks, has
arguments with no JSON form, or is read by a one-shotresolve_dynamic_valuecall, which never sends but may return the answer the surface already holds for the same call.formatStringtemplate parts and the arguments of an agent'scallRendererFunctionnever use the agent: an unimplemented function there is anEXPRESSION_ERROR(template parts, which render empty) or anEXECUTION_ERRORresponse (callRendererFunction). While the answer is
pending the value isNone(a signal withpeek=False), and a pending
check rule doesn't fail. Event action values resolve in order, and the first
failure stops the action. Identical binding calls share one request and a
cached answer; action calls never do. Evaluate on the event loop that owns
the surface: off the loop, a call that would have to be sent fails at once.
AddsSurfaceModel.agent_function_caller,SurfaceModel.settled_agent_answer,
SurfaceModel.call_agent_function,SurfaceModel.disposed,
DataContext.is_user_activated,MessageProcessor.dispose,
RpcHandler.cancel_surface_calls,AgentFunctionCalland
AgentFunctionCaller.
(#3415,
#3536,
#3740) deleteSurfacecancels the surface's pending agent calls withCANCELLED,
andMessageProcessor.dispose()disposes every surface and cancels all
pending calls. Cancelled calls report no error.
(#3415,
#3536,
#3740)- (v1_0) Add
AgentFunction,AgentFunctionContextandAgentFunctionHandler
(exported froma2ui.core) for catalog functions that run on the agent:
AgentFunction(...)for arendererOnlyfunction defined in code,
AgentFunction.from_api(...)to bind a catalog declaration, and
with_handler.Catalog.copy_with(agent_functions=...)adds them, and
Catalog.agent_functionsandCatalog.renderer_functionslist them. An
agent function's local$defsmay not define a name differently from ...
a2ui-agent-sdk 0.11.0
- BREAKING CHANGE: (v1_0)
validate_payloadandRendererState.apply
check eachcallRendererFunctionagainst the catalogs instead of running
it, and reject one the renderer would refuse: a surface that doesn't exist
when the call arrives, a catalog that isn't active, a function the catalog
doesn't declare, arendererOnlyfunction (the default) or one that
requires user activation, arguments that don't match the function's schema,
and a nested call the renderer can't make (to anagentOnlyfunction or one
that requires user activation, malformed, or naming no catalog on a surface
without a default one), a nested@indexcall (the arguments are resolved
outside any list template), and a malformed data binding (an@paththat
isn't a string, or a field other than@path). Each refusal has the code
INVALID_FUNCTION_CALL. A nested call that names no catalog is checked
against the default catalog of the surface the call names. They also reject
anagentOnlyfunction bound into a component. Recommended migration:
declare the functions an agent calls withallowedCallersset to
agentOnlyorrendererOrAgentin the catalog the call names
(#3534,
#4008). - BREAKING CHANGE:
PromptGenerator.generate()is now final and returns
assemble_instructions(self), whichSkillGenerator.generate_skill()also
uses, so a monolithic skill for a format's own catalogs holds its prompt
snippet. APromptGeneratorsubclass now implements the abstractcatalogs
property and the three hooks (generate_base_rules,
generate_catalog_instructions,generate_examples) instead of overriding
generate(); built-in snippets are unchanged.
#3568 - BREAKING CHANGE:
ExpressPromptGenerator,DirectJsonPromptGenerator,
ElementalPromptGeneratorandAtomPromptGeneratorare no longer exported
froma2ui.inference_formatsor their format packages. Reach a format's
generator throughInferenceFormat.prompt_generator, and subclass
PromptGeneratorto write a format of your own.
#3568 - BREAKING CHANGE: (v1_0) The
TextFieldbuilder in
a2ui.builder.v1_0.catalogs.basicrequiresvalue, following the basic
catalog. Recommended migration: passvalue, such as
value=DataBinding(path="/form/email"). The path does not have to exist yet
(#3830,
#3868). - (v1_0) Express compiles, decompiles and prompts the protocol's system
functions, which no catalog defines:@index()and@index(offset=1)
compile to{"@call": "@index", ...}without acatalogId, the decompiler
writes such calls back as@index(...), and the v1.0 Express prompt lists
@index(offset?). Before v1.0,@index()is a validation error
(#3725, #4025). RendererFunctionCalls.callchecks its arguments in a fixed order shared
with the TypeScript and Dart SDKs. An emptyfunction_call_idis now
refused withINVALID_FUNCTION_CALLinstead of replaced by a generated
one, and so are anamethat isn't a UAX #31 identifier or starts with
@, andargsthat aren't a mapping with identifier keys and JSON values
(no NaN or infinity).timeoutanddefault_timeoutmust be finite
positive numbers (not bools); onlydefault_timeout=Noneturns the limit
off. (#3939)RendererFunctionCallstakes optionalcatalogs. With them,callraises
UNKNOWN_FUNCTIONfor a catalog they lack or a name that isn't one of its
renderer functions (agent functions included), and
INVALID_FUNCTION_CALLfor arendererOnlyfunction or one that requires
user activation, before anything is registered. Two catalogs with one ID
raiseA2uiCatalogError.
(#3939)- Add
RendererFunctionCallstoa2ui.rpc, which sends v1.0
callRendererFunctionmessages for one conversation and settles each call's
future from the renderer'srendererFunctionResponse, with timeouts (30
seconds by default),max_pendinganddispose(). Itsresolvemethod is
theon_renderer_function_responsecallback of
RendererToAgentMessageProcessor: it returnsTruewhen it settles (or, for
a malformed response, fails) a pending call andFalseotherwise, so the
processor declines responses to calls it didn't make.is_pendingtells
whether a response answers one of its calls.agent_development.mddescribes it
(#3535). - Export
read_jsonfroma2ui.inference_formats.direct_json, which reads a
complete JSON document the way the Direct JSON parser does: it accepts
trailing commas and raw line breaks in strings, and straightens curly quotes.
ExportJSON_PAYLOAD_START_REfroma2ui.parser, the pattern a
BlockLexerfor JSON blocks passes aspayload_start_patternto recover a
block whose open tag is missing.
#3790 - Add
agent_callable_functionstoa2ui.utilsto return the functions on v1.0+ catalogs that an agent may invoke viacallRendererFunction(#3864, #3880). ExpressCompilerandExpressResponseStreamnow raiseExpressValidationErrorfor a check list passed to a component whose catalog schema declares nochecksproperty, and emit anupdateComponentsmessage for a component scope that defines norootinstead of raisingExpressUndefinedRootError(#3099, #3880). A statement holding an out-of-range number literal such as1e999now raisesExpressParseErrorinstead of being dropped from the compiled block.- Add
buffer_incomplete_componentstoDirectJsonParser,DirectJsonFormat, andDirectJsonFormatFactoryso callers can hold streamingupdateComponentsentries until each component object closes (#3880). - The Express prompt generator (
ExpressFormat.prompt_generator.generate_base_rules()) now includes the standalone renderer function call rule in v1.0 whencallRendererFunctionis allowed and the active catalogs define at least one agent-callable function, listing onlyagent_callable_functions(catalogs)and numbering multi-catalog rules sequentially (#3864, #3880). - Prompt snippets (
PromptGenerator.generate()and
prompt_snippet) follow one layout across formats and SDKs: the base rules,
then the catalog instructions, then the examples under### Examples:
followed by a blank line. The## Workflow Description:heading before the
base rules (and Atom's## Instructions:) is gone; add your own heading
around the snippet if you want one. A Direct JSON snippet puts the protocol
schemas in one schema block after the rules and each catalog schema in a
schema block of its own, andgenerate_catalog_instructions()with no
catalog returns one block per catalog.a2ui.constants.EXAMPLES_HEADINGholds
the examples heading. #3567 - Add A2UI Protocol v1.0 support to
@macroandMacroExpander:- Synthesize v1.0 schemas (
componentconst discriminators,ChildandExtensions$refs,Annotatedfield descriptions,oneOfunions, typeddict[str, V]additionalProperties, and nested Pydantic sub-models such asTabItem,ChoicePickerOption,IconNameSvgPath, andActionEvent) and coerce v1.0 wire directives (@path,@call,ActionwithuserMessage,CheckRule,DynamicChildList,AccessibilityAttributes, typeddict[str, V]maps, and nested sub-models). - Add
MacroExpander.transform_catalogs(catalogs),protocol_version, andon_error="passthrough" | "raise", enforce single-version invariants and UAX #31 / reserved'Surface'macro name checks, and closetransform_to_transportover registeredbase_catalogsby rewriting pure macro-sidecarcreateSurface.catalogIddefaults and stamping unique owningcatalogIds onto unannotated lowered primitives. - Export
Extensionsfroma2ui.builder.v1_0and supportclass MyCatalogNode(ComponentBuilderNode, catalog_id=...)alongside field-defaultcatalog_idoverrides while preserving wire aliases (#3776, #3778).
- Synthesize v1.0 schemas (
- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages, each following the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. #3721
MacroExpander.transform_to_transportno longer passes component envelope
fields (accessibility,catalogId,metadata) to macro functions unless
declared as parameters, and merges undeclaredaccessibilityand v1.0
metadataonto the expanded root component without copying the macro
invocation'scatalogIdonto emitted primitives
(#3626,
#3777).MacroExpanderaccepts optionalcatalog_idandbase_catalogsparameters
(plusregister_catalog) and tracks surface default catalogs across
createSurface/deleteSurface(or a per-callsurface_catalogsmapping on
transform_to_transport) to scope macro expansion...
a2ui-adk 0.3.0
a2ui_rpc_callbacktakesrenderer_calls, a provider of the session's
RendererFunctionCallssuch asA2uiRendererCallsStore.get, andcatalogs
becomes optional (pass one or both). The callback processes each message
with aRendererToAgentMessageProcessorwhose
on_renderer_function_responseisRendererFunctionCalls.resolve, and
answers the request without running the agent only when every message is
handled. A response to a call the session didn't make, such as one the
model wrote, is declined and goes to the agent. Responses that answer
pending calls always settle them, even in a request that goes to the agent,
and a malformed one fails the call it names. It needs thea2a
extra. #3535- Add
a2ui_rpc_interceptor, anA2aAgentExecutorinterceptor that ends a
taskcompletedwhen its request held onlycallAgentFunctionand
rendererFunctionResponsemessages and ADK would end itworkingbecause
there was nothing to send back. Other final states are left as they are. It
needs thea2aextra.
#3535 - Add
A2uiRendererCallsStore, which keeps aRendererFunctionCallsfor each
session.getreturns the session's instance, creating it on first use, and
is therenderer_callsprovider ofa2ui_rpc_callback.removedisposes a
session's instance, which fails its pending calls.
#3535 - Add
a2ui_rpc_callback, which returns abefore_agent_callbackthat
answers the renderer's A2UI v1.0callAgentFunctionmessages without
running the agent. When the user content holds only such calls, it builds a
RendererToAgentMessageProcessorfrom the agent's catalogs (or from the
catalogs a provider returns per context, such as the session's
A2uiRequestProcessor.active_catalogs), and returns the
agentFunctionResponsereplies as the agent's response, which
A2aAgentExecutorsends as A2UI parts. It reads and writes the parts with
ADK's own A2A part converters. Any other content, including the renderer's
action,errorandrendererFunctionResponsemessages, goes to the agent.
It needs thea2aextra.
#3795 SendA2uiToClientToolsetremoves thecallAgentFunctionand
agentFunctionResponsemessages from the contents sent to the model; the
session's events keep them. Addexclude_a2ui_rpc_from_prompt, a
before_model_callbackthat does the same for agents without the toolset.
It needs thea2aextra.
#3795- Package dependencies updated to require
a2ui-agent-sdk>0.10.0and
a2ui-a2a>0.2.0(for thea2aextra).
Published to PyPI: a2ui-adk 0.3.0
pip install a2ui-adk==0.3.0a2ui-a2a 0.3.0
- Add
get_a2ui_messages, which returns the A2UI messages in an A2A message's
A2UI parts, andcreate_a2ui_parts, which wraps A2UI messages, such as the
replies ofRendererToAgentMessageProcessor, as A2UI parts. Models are
serialized asto_message_dictsserializes them, with only the fields that
were set, so anagentFunctionResponsekeeps avalueofNone, and a
model's defaultversionis written for v0.9 and later.
#3795 - Add
extract_a2ui_json_to_partsto extract text and<a2ui-json>blocks into
A2A parts without requiring aCatalogorParser. A block that is unclosed,
is not JSON, or is not a JSON object or array of objects is logged and
skipped. A block whose open tag is missing starts at the first line that
opens a JSON array or object. Requires ana2ui-agent-sdkrelease later than
0.10.0.
#3790
Published to PyPI: a2ui-a2a 0.3.0
pip install a2ui-a2a==0.3.0Documentation Media Assets (Do Not Delete)
Immutable, content-addressed media assets referenced by docs/site/assets-manifest.json.
a2ui-core 0.5.0
- BREAKING CHANGE:
DataContextrefuses a function whoseallowed_callers
isagentOnly, before running it, so a binding, check or function call
action that calls one reports anEXPRESSION_ERRORinstead of running it, as
the v1.0 specification requires.RpcHandlerstill runs such a function for
an agent'scallRendererFunction. Recommended migration: set
allowed_callerstorendererOrAgenton a function both the renderer and
the agent call (#3483,
#3773). - From v0.9, a component its catalog declares with no
ComponentIdor
ChildListproperty has no child references. Previously any of its string
properties that named a component on the surface, such as anIconnamed
mailinside theRowwhose id ismail, was read as one, so a valid
surface could fail topology checks as a cycle. A property declared as a plain
string is read as text, as the protocol's catalog rules require. v0.8
catalogs, and components a catalog does not declare, still infer references
from property names and values. - BREAKING CHANGE: Unify the v1.0 protocol version wire value on
'1.0'
(without a'v'prefix) across message envelopes, capability objects, and
catalog documents (ProtocolVersion.V1_0.valueis now'1.0'), while
continuing to accept'v1.0'inCatalog.from_json.
Catalog.protocol_versionis typed asProtocolVersion | str.
#3097,
#3726 - BREAKING CHANGE:
validate_composition_constraintsand
SurfaceComponentsModel.validate_components_updateapply the"Surface"
allowedParentsrule only to the surface's root component (root_id,
"root"by default), even when another component also references it, and
check every parent of a component that has several, not only the last one
in surface order. A non-root component that nothing references is no longer
checked against"Surface"; the topology checks report it as an orphan, or
allow it. This matches the specification and the TypeScript, Dart and Swift
SDKs, and changes which payloads are accepted.
(#3354,
#3360) - BREAKING CHANGE: A
MessageProcessorwithout avalidation_config, as a
renderer has by default, checks eachupdateComponentsagainst the
allowedParentsandallowedChildrenrules of its catalogs, as the
TypeScript and Dart SDKs do. Before, it checked nothing, so a payload
that breaks those rules is now rejected. The check is skipped when no catalog
of the surface's components declares such rules.
#3360 - Add extension metadata APIs across
SurfaceModel(metadata,extensions,on_metadata_changed,set_extension,remove_extension, anddispatch_action(..., metadata=...)),ComponentModel(metadata,extensions,on_metadata_changed,set_extension,remove_extension),ComponentNode(metadataandon_metadata_changed),ComponentContextandGenericBinder(metadata,extensions, and optionalmetadataon bound action closures), andComponentApi(metadataparsed and serialized inCatalog.from_json()andCatalog.to_json()). FixMessageProcessorto store componentmetadataonComponentModel.metadataoutsideComponentModel.propertiesand validate UAX 31 extension keys on component creation as well as updates, and fix Pydantic code generation to emit a distinctActionMetadatawrapper model instead of colliding withExtensions(#3103, #3468, #3560, #3708, #3757). - A function defined without an argument schema (
FunctionApior
FunctionImplementationwithoutschema) takes any args, as one given
schema={}does:validation_schemaandresolved_function_schemagive
{}for it rather thanNone.Catalog.to_jsonwrites theargsof either
as{"type": "object", "additionalProperties": true}, so a catalog read back
withCatalog.from_jsonaccepts any args for it too.to_jsonused to write
{"type": "object"}forschema={}, whichfrom_jsonreads as taking no
args.to_jsonno longer raisesTypeErrorfor a catalog that holds such a
function, and neither do the paths that call it:link_catalogs, and so a
MessageProcessorof two or more catalogs, andget_renderer_capabilities
with v1.0 inline catalogs. - (v1_0)
DataContextreads aValidationResultdict that a function argument
resolves to by itsvalidboolean wherever the function's argument schema
types that argument asDynamicBoolean, as the specification defines the
type. This applies to everyDynamicBooleanargument, in built-in and
custom catalogs, soformatNumber'sgroupingand a custom function's
boolean parameters now read a failing validation asFalserather than as
a truthy dict;and,orandnotalready did. Catalogs below v1.0, whose
validation functions return booleans, are unchanged.
#3653 - Add
map_error_to_renderer_message,extract_envelope_error_context, andErrorEnvelopeContexttoa2ui.core.processingand thea2ui.corepublic facade, along withSurfaceGroupModel.on_errorandMessageProcessor.process_messages_with_errorsfor emitting and collecting structured wire-format renderer error messages. #3580 - Add
NodeResolver,ComponentNode, andNodeStatetoa2ui.core.resolutionand thea2ui.corepublic facade for reactive surface node-graph resolution, template expansion, and placeholder/cycle tracking. #3580 - (v1_0) Support
@-prefixed system function calls (such as${@index()}) inExpressionParserstring interpolation templates, and preserveValidationResult.messageon path-boundCheckRuleconditions inGenericBinderwhile overriding function default messages on evaluated checks. #3583 - BREAKING CHANGE: Cross-catalog
$refresolution across peer catalogs is
removed.Catalog.peer_catalogs,Catalog.with_peer_catalogsand
link_catalogsare gone,inline_local_refsno longer takes apeers
argument, andMessageProcessorno longer links the catalogs passed to it.
A catalog resolves$refs only against its own document and the protocol's
common_types.json.Catalog.from_jsonraisesA2uiCatalogErrorfor a
v1.0 catalog with a$refto any other document, such as
basic_catalog.json#/components/Textor an absolute catalog URI, and never
fetches it; v0.8 and v0.9 catalogs load as before. Recommended migration:
bundle referenced components, properties and functions into each catalog so
it is standalone.
#3232,
#3575 - Add
Catalog.derive, which builds a catalog with a newcatalog_idfrom
the namedcomponentsandfunctionsof an existing one and new entries,
with theinstructionsit is given, and does not keep the source's$id,
title, description or instructions.
#3597 - (v1_0) Relaxed v1.0
CatalogDefinitionschema rules to permit non-object
catalog$defs(such as primitive, enum, or union design tokens), property
$refs to#/$defs/..., and arbitrary vendor/metadata extension keys on
components and functions. Factoredweightin the v1.0 basic catalog into
#/$defs/Weight(annotated withCatalogDef), inlining leaf catalog$defs
into component schemas inCatalog.from_jsonand
Catalog.resolved_component_schemawhile restoring#/$defs/...references
inCatalog.to_json()andCatalog.validation_schema
(#2724). - Schema validation never fetches a
$refover the network. A$refto a
document that is not available locally fails validation with an
unresolvable-reference error instead of being downloaded
(#3554). - (v1_0) The
createSurfacedescription no longer says that a surface's
components and data must come in later messages. They can be sent inline in
createSurfaceor in laterupdateComponentsandupdateDataModelmessages.
#3678 SchemaValidator.evolveno longer raisesTypeError(_registry) for a
subschema that declares its own$schema, and keeps the validator's
registry.to_protocol_versionis exported from thea2ui.corepublic facade.- Under a
ValidationConfigthat allows dangling references, and orphans or a
missing root, as an agent mirroring a renderer's surfaces uses,
MessageProcessorchecks eachupdateComponentsagainst the components it
changes rather than copying the surface and walking its whole graph. A
surface that arrives in many small messages now takes time in proportion to
its size rather than its square. The checks and the errors they raise are
unchanged: composition constraints, the root when it is required, and
self-references, cycles and depth. Other configs check the whole surface as
before. SurfaceComponentsModel.components_update_appliedreports that a batch
validate_components_updatepassed has been applied, so that the next check
can start from what that check found.MessageProcessorcalls it.- `SurfaceComponentsModel.insert_component(ind...
a2ui-agent-sdk 0.10.0
- Add incremental streaming support for the Express inference format via
ExpressResponseStream(ExpressFormat.supports_streamingandExpressParser.supports_streamingnow returnTrue).ExpressFormatFactory,ExpressFormat, andExpressParseracceptprogressive_keys(defaulting toDEFAULT_EXPRESS_PROGRESSIVE_KEYS = frozenset({"text"})) to heal unclosed string literals in matching component properties and data path assignments as chunks arrive, while gating initialcreateSurfaceemission onroot = ...for new surfaces, emitting deltaupdateComponentsand per-pathupdateDataModelmessages on subsequent chunks, and holding statements with unresolved value variables until defined (#2896). - BREAKING CHANGE: Use
'1.0'(without a'v'prefix) as theversion
field on v1.0 protocol messages and capabilities in inference format
compilers, parsers, decompilers, builders (a2ui.builder.v1_0),
RendererState,resolve_catalogs, and prompt examples.
#3097,
#3726 - BREAKING CHANGE: The
a2ui.extensions.file_resolvemodule
(FileResolver,FileResolverSecurityErrorandResolvedFileConverter) is
removed, and the package no longer depends onhttpx. File pointers are not
part of the A2UI protocol, so resolving them is left to the agent.
#3731 - Add
ComponentBuilderNode.metadata,ComponentBuilderNode.with_extension(namespace, value), andset_surface_extensions(messages, *, surface_id=..., extensions=...)ina2ui.builder.v1_0with UAX 31 extension key validation, and support the reservedextensions=keyword argument onsurface(...)and component calls in v1.0 A2UI Express (ExpressCompilerandExpressParser.decompile) (#3708, #3757). - BREAKING: In Express (
ExpressCompiler), data path assignments ($/... = ...) in surface-updating scopes (scopes that do not create a surface withrootor carryupdate=true) now emit one targetedupdateDataModelmessage per assigned path at its JSON Pointerpathinstead of folding all assignments into a single rootupdateDataModelwithpath: "/"(which overwrote the entire surface data model on the renderer). Surface-creating scopes continue to fold data path assignments into a single root data model and now support list element traversal, canonical numeric-segment list auto-vivification, and full root replacement via$/ = {...}(#3677). - BREAKING CHANGE: When
ResponseStream.feedorcloseraises an
A2uiError, itspartial_resultsholds the parts the call made ready before
the failure, as forparse_response, and they stay applied to the stream's
RendererState. Before, a chunk that finished a block and then failed in the
next one raised without those parts and rolled them back. Recommended
migration: showerror.partial_resultsbefore ending the stream. #3597 - BREAKING CHANGE:
ResponseStreamis generic in the parts it returns
(ResponseStream[ResponsePart]by default,ResponseStream[StreamPart]for
a stream that reads past rejected blocks) and has an abstractis_in_block
property, so a subclass must implement it and an annotation must name the
part type. #3597 - BREAKING CHANGE:
DirectJsonPromptGenerator.generate_base_rules()now
returns the workflow rules followed by the protocol schemas (agent-to-renderer
and pruned common types) and acceptsallowed_messages, while
generate_catalog_instructions()returns only the catalog schemas and drops
allowed_messages(#3526).
Direct JSON catalog skills generated bySkillGeneratornow require
a2ui-coreto be loaded alongside them, and callers combining
generate_base_rules()withschema_to_prompt()(such as
SendA2uiToClientToolsetusers) should useDEFAULT_WORKFLOW_RULESinstead.
#3559 open_streamtakesafter_rejected_block="continue"to read past a
rejected block. The stream then returns anErrorPartin its place, skips
the rest of the block, and reads the text and blocks after it; the messages
the block emitted before it was rejected stay in the state. A block still
open when the response ends is returned as anErrorParttoo. By default the
first rejected block still ends the stream. #3597- Add
ResponseStream.is_in_block, which tells whether the response read so
far ends inside a block, so a client that joins the chunks of a paused and
resumed response can tell whether a space between them could break a block.
#3597 - Introduce typesafe fluent builder package for A2UI Protocol v1.0 (
a2ui.builder.v1_0),
re-exporting v1.0 common types (DataBinding,FunctionCall,
AccessibilityAttributes,ActionEvent, andCheckRule) from
a2ui.core.schema.v1_0, defining builder models (ComponentBuilderNodewith
catalog_id,accessibility, andextensions,Action, and
DynamicChildList), and generating the v1.0 basic catalog components (Button
with child slot,TextFieldwithplaceholder,Sliderwithsteps, and
VideowithposterUrl)
(#3070). - BREAKING:
SkillandSkillSetraiseA2uiValidationError(aValueError) for afilenamethat is absolute or has an empty,.or..segment, which they used to accept; the check runs on construction, on assignment, and inSkillSet.add.SkillSet.export_to_directorynow removes only the directory that holds each skill file (for examplesrc/skills/nestedforsrc/skills/nested/SKILL.md) instead of the first path segment (src), removes a symlink or file at that path instead of following it, and raises before touching anything when a skill directory's parent is a symlink out of the output directory. - BREAKING CHANGE:
parse_and_fixand thea2ui.parser.payload_fixer
module are removed. Nothing in the SDK used them any more: each inference
format's parser repairs the model's output, and the Direct JSON parser's
reader accepts trailing commas, unescaped control characters, smart quotes
used as JSON delimiters and a single message outside an array. Unlike
parse_and_fix, it keeps typographic quotes inside string values, so valid
JSON such as"Willkommen im „Café Central“"is no longer rejected
(#2934). To read a Direct
JSON block, useDirectJsonParser(catalogs).compile(text)or
A2uiRequestProcessor.parse_response.
#3632 - BREAKING CHANGE: Cross-catalog
$refresolution across peer catalogs is
removed.resolve_catalogs,validate_payload,RendererState, and the
Direct JSON and Express formats no longer link the catalogs they are given,
so a catalog's$refs resolve only against its own document and the
protocol'scommon_types.json. Loading a v1.0 catalog with a$refto any
other document raisesA2uiCatalogError. Recommended migration: bundle
referenced components, properties and functions into each catalog so it is
standalone.
#3232,
#3575 - The Express compiler accepts
userMessage=andcontext=keyword arguments onEvent(...), compilinguserMessageto the v1.0event.userMessagefield, and raisesExpressValidationErrorforuserMessagebefore v1.0 and for any keywordEventdoes not define, where it used to drop them. A function call in an action slot nested inside a list item or object property (such asitems: [{label, action: openUrl(...)}]) is now compiled as afunctionCallaction.ExpressDecompilerwritesuserMessage=back (#3598). - The Express compiler keeps a map literal as written, quoted keys or not, when
one of its keys shares a name with an Express construct (variable,path,
call,check,skipped); before, such a map was read as a variable
reference, data binding, function call or check, and lost its data
(#3410). In v1.0 and
later, only@pathmarks a data binding when the compiler checks a property
that does not admit one, so a plainpathkey is data. A_anywhere but in
place of an argument now raisesExpressValidationError. - The Express compiler finds a data binding inside a map literal given to a
property that does not admit one even when the map has keys namedevent,
functionCallor@call, and raisesExpressForbiddenDatabindingError. - A map literal with a
catalogIdkey among the arguments of an Express check
holds the check's options: any other key in it, or two such maps naming
different catalogs, raisesExpressValidationError. Before, only a map with
a singlecatalogIdstring was read as options, and any other was passed to
the check as an argument. A nullcatalogIdin such a map raises
ExpressValidationErrorrather than being ignored. - Only a
$pathgiven to an Express component'svalue, directly or through
variables, is passed to the component's checks. A map literal shaped like a
data binding is data and is not. - An Express variable whose value refers back to it, directly or through other
variables, raisesExpressValidationErrorrather thanRecursionError. - The Express d...
a2ui-adk 0.2.0
- BREAKING CHANGE:
GenAIFileResolveris removed, along with the
FileResolverit extended ina2ui-agent-sdk.
#3731 - BREAKING CHANGE:
SendA2uiToClientToolset(a2ui_enabled, a2ui_processor)
takes the request'sA2uiRequestProcessor, or anA2uiProcessorProvider
that returns it per context, instead of catalogs and examples. The processor
holds the catalogs, the example turns, the inference format and, for a canvas
agent, the boundRendererState.A2uiCatalogsProviderand
A2uiExamplesProviderare removed; markdown examples are no longer accepted,
so pass example turns toA2uiGeneratororA2uiRequestProcessor. To
migrate, putgenerator.create_processor(capabilities)in an
A2uiProcessorStoreand passA2uiProcessorStore.getas the
provider. A canvas agent binds itsRendererStateto the processor it puts
there.
#3299 - BREAKING CHANGE: The tool reads its argument, renamed from
a2ui_jsonto
a2ui_payload, in the processor's inference format (Express by default)
instead of always reading JSON. It compiles the payload with the format's
parser, no longer withparse_and_fix, validates it against the processor's
bound state or, without one, withvalidate_payload, and still returns A2UI
JSON messages for the part converter. The prompt it adds comes from the
format's prompt generator, and it skips each section (rules, catalogs,
examples) that the agent's system instruction already holds, such as when the
instruction includesprocessor.prompt_snippet.
#3299 - BREAKING CHANGE:
A2uiPartConvertertakes the processor, plus the
keyword argumentsbypass_tool_checkandfallback_text, instead of
catalogs,parser,versionandstate. It reads text-based A2UI with the
processor's parser and checks it against the processor's bound state, as a
response that shows new UI when there is none, so a response that updates a
surface it does not create is then rejected and logged. Each part is labeled
with its message's protocol version.
#3299 - BREAKING CHANGE:
A2uiEventConvertertakes the request's processor, or
a provider that returns it or None, in the required keyword argument
a2ui_processor, instead of reading catalogs from session state. Its
catalogs_keyargument and thesystem:a2ui_catalogskey are removed. When
the processor's format can stream, it opens oneResponseStreamper
response, feeds it each partial ADK event, and closes it on the final event.
A response is keyed by its invocation and its event's branch or author, so
the sub-agents of aParallelAgentdon't share a stream. A stream that gets
no event forstream_idle_timeoutseconds (600 by default), as when a run is
cancelled, is dropped.
#3299 A2uiProcessorStorekeeps each session's request processor in memory, since
ADK's persistent session services save state as JSON and can't hold one. Its
getandis_enabledmethods are providers forSendA2uiToClientToolset
andA2uiEventConverter.
#3299SendA2uiToClientToolsetandA2uiEventConverterlog a warning when they
get one processor for every request with aRendererStatebound to it,
since every conversation would share that state.
#3299A2uiEventConverternow streams responses in the defaultExpressFormat
incrementally as statements and progressive strings arrive, rather than waiting
for the closing</a2ui>tag.
#3712- Tool and parse errors, which may quote the A2UI payload, are logged by type
at warning level and in full only at debug level.
#3299 - Add
A2uiInstruction, an ADK instruction provider for an agent that writes
A2UI in its text response. It appends the processor'sprompt_snippetto
the agent's own instruction. ADK reads{name}session state templates out
of a string instruction, and the A2UI prompt holds braces that are not state
keys, such as the${expression}in the basic catalog, so a string
instruction failed withKeyError: "Context variable not found: 'expression'."
underadk runandadk web. As a provider,A2uiInstructionis used as
it is, while the agent's own instruction keeps its templates.
#3763 SendA2uiToClientToolsetno longer adds the prompt's rules and catalog
schemas a second time when the system instruction already holds the
processor's wholeprompt_snippetin the Direct JSON format, whose snippet
lays the schemas out in one block rather than per section.
#3763
Published to PyPI: a2ui-adk 0.2.0
pip install a2ui-adk==0.2.0a2ui-a2a 0.2.0
create_a2ui_partlabels a part with the message's ownversionfield when
noversionis passed, so a v0.9.1 or v1.0 message gets the current A2UI MIME
type. #3299parse_content_to_partslogs a parse error, which may quote the response,
by type at warning level and in full only at debug level.
#3299
Published to PyPI: a2ui-a2a 0.2.0
pip install a2ui-a2a==0.2.0