Skip to main content

Module host

Module host 

Source
Expand description

§The host API (VAPP-91)

What a surface needs from its host, the same on all four platforms (packages/exponential-ui/catalog/host.json): the router turning server messages into ops, the wire decoders (JSONL, SSE, A2UI-over-MCP), the function / URL / media policy, binding sources, catalog negotiation and declarative app packages. A line-by-line port of the TypeScript reference (packages/exponential-ui/src/host/) over serde_json::Value; every output is JSON-equal to it, locked by fixtures/host-*.json. The I/O (transports, the runtime host) stays on each platform; the Swift and Kotlin painters reach this module through exponential-ui-ffi.

Re-exports§

pub use decoders::decode_jsonl;
pub use decoders::mcp_action_call;
pub use decoders::messages_from_mcp_result;
pub use decoders::DecodeIssue;
pub use decoders::Decoded;
pub use decoders::JsonlDecoder;
pub use decoders::SseDecoder;
pub use package::available_extensions;
pub use package::client_capabilities;
pub use package::merge_data;
pub use package::package_sources;
pub use package::source_allowed;
pub use package::supported_catalog_ids;
pub use package::template_messages;
pub use package::validate_package;
pub use package::validate_package_with;
pub use package::version_satisfies;
pub use package::AvailableExtension;
pub use package::PackageIssue;
pub use package::PACKAGE_FORMAT_VERSION;
pub use policy::combine_decisions;
pub use policy::decide_function;
pub use policy::decide_url;
pub use policy::image_dimensions;
pub use policy::image_frames;
pub use policy::image_header;
pub use policy::is_builtin_function;
pub use policy::is_private_host;
pub use policy::media_image_check;
pub use policy::ImageHeader;
pub use policy::matches_pattern;
pub use policy::media_image_within_limits;
pub use policy::media_request;
pub use policy::media_within_limits;
pub use policy::package_policy;
pub use policy::svg_dimensions;
pub use policy::safe_href;
pub use policy::FunctionDecision;
pub use policy::FunctionPolicy;
pub use policy::MediaOptions;
pub use policy::MediaRequest;
pub use policy::MediaRule;
pub use policy::UrlDecision;
pub use policy::UrlPolicy;
pub use policy::BUILTIN_FUNCTIONS;
pub use router::normalize_path;
pub use router::HostRouter;
pub use router::SurfaceInfo;
pub use record_store::parse_records_source;
pub use record_store::RecordsFilter;
pub use record_store::RecordsQuery;
pub use record_store::RECORDS_FUNCTIONS;
pub use record_store::RECORDS_RESERVED_PARAMS;
pub use record_store::RECORDS_SCHEME;
pub use records::is_record_kind;
pub use records::validate_record;
pub use records::validate_record_schema;
pub use records::RECORD_FIELD_TYPES;
pub use records::RECORD_FORMATS;
pub use records::RECORD_RESERVED_KEYS;
pub use signature::canonical_json;
pub use signature::package_file_signed_bytes;
pub use signature::AUTHOR_KEY_PREFIX;
pub use signature::AUTHOR_NAME_MAX;
pub use signature::PACKAGE_FILE_SIGNATURE_ALG;
pub use signature::PACKAGE_FILE_SIGNATURE_CONTEXT;
pub use sources::parse_source;
pub use sources::source_with_params;
pub use sources::ParsedSource;
pub use tools::tool_call;
pub use tools::validate_tools;
pub use tools::ToolCall;
pub use tools::ToolConsentRow;
pub use tools::TOOL_KINDS;
pub use contract::*;

Modules§

contract
The host API contract (catalog/host.json) as constants, plus the client messages every platform host sends (tests/host_fixtures.rs gates the constants against the JSON).
decoders
The wire decoders every transport adapter shares (pure, incremental, fixture-locked in fixtures/host-transport.json): A2UI JSONL over a byte stream, Server-Sent Events, and the A2UI-over-MCP carrier.
package
Catalog negotiation and declarative app packages (VAPP-82: a manifest + A2UI templates + bindings, data never code).
policy
The policy rules every host applies before a client function, a URL open or a media load (catalog/host.json functions / urls / media). Pure; fixtures/host-policy.json locks them on every platform.
record_store
VAPP-161: the format’s NEUTRAL records (docs/package-format.md “Records”). A surface reads a kind through the binding records:<kind>?query and writes through the host functions records.upsert / records.delete; the HOST provides the store. Only the pure query parse is mirrored here (parseRecordsSource of packages/exponential-ui/src/host/record-store.ts; the store and the value derivation stay on each host). fixtures/host-package.json recordsQuery replays it.
records
VAPP-122: an app’s RECORDS, its own data. The manifest declares every kind with a JSON Schema SUBSET (records: {<kind>: {schema}}); a host validates a record against it before it is stored. Mirrors packages/exponential-ui/src/host/records.ts line by line; fixtures/host-router.json records replays it.
router
The host router. Server messages in, ops out (catalog/host.json ops); the platform host performs them on its surfaces. Pure and synchronous, so fixtures/host-router.json locks the same behaviour on every platform.
signature
VAPP-161: the PACKAGE FILE’s signed bytes (docs/package-format.md “The package file”): a context line + the RFC 8785 canonical JSON of the whole file without signature. Mirrors canonicalJson + packageFileSignedBytes of packages/exponential-ui/src/host/signature.ts; the Ed25519 itself is the host’s own (no crypto here). fixtures/host-package.json canonical + signatures[].signedText replay it.
sources
Binding sources. A data model path can follow a host source (exp:issues?board=…): the host registers one resolver per scheme, the router emits a bind op, the resolver’s emits land at the path.
tools
VAPP-161: a package’s TOOLS (docs/package-format.md “Tools”): the MCP servers and scripts its functions call (tools.<id>.<name> for an MCP tool, tools.<id> for a script), each behind the consent card the host MUST show before the first call. Mirrors packages/exponential-ui/src/host/tools.ts line by line; fixtures/host-router.json (validation) and fixtures/host-package.json consent + toolCalls replay it.