Data Assets: Frontend
This guide will walk you through the creation of Data Assets containing frontend code for an Human Machine Interface (HMI). The frontend Data Assets can be used by a HMI service.
To create a Data Asset which contains frontend code, four major ingredients are necessary:
- Asset Files: Your actual content (HTML, CSS, JS).
- Manifest File (
.textproto): Metadata that describes your Asset. - Bazel Build File (
BUILD.bazel): Instructions for how to build and package the Asset. - Build and Install the Asset: The command to compile everything.
Development setup
This guide requires a project with the Intrinsic SDK. Follow the guide on how to set up the development environment if you haven't already.
Bazel workspace
You will need a Bazel workspace to create a Data Asset. The workspace can be
created at the root of the project using inctl.
You can skip this step if you already have a MODULE.bazel file in your project.
inctl bazel init --sdk_repository https://github.com/intrinsic-ai/sdk.git --sdk_version latest
Organize your project files
First, create a dedicated folder for your new Data Asset. A common convention is to place the static files (like HTML, CSS and JavaScript) inside a dist subdirectory.
All the code for building the Data Asset can be found on the sdk-examples repo.
Your directory structure should look like this:
your_asset_name/
├── dist/
│ ├── index.html
│ ├── your_file.css
│ └── your_file.js
├── BUILD.bazel
└── your_asset_name.textproto
For example, using the HMI example with the hello_world Asset:
frontend_1/
├── dist/
│ ├── hello_world.html
│ ├── hello_world.css
│ └── hello_world.js
├── BUILD.bazel
└── hello_world.textproto
Create the manifest file (.textproto)
The manifest file provides metadata about your Data Asset. It informs users of the Data Asset’s name and ID, while detailing all included files.
Create a file named your_asset_name.textproto.
This file defines a DataManifest message.
metadata: Contains display information.id: A unique identifier for your Asset. Thepackageandnamecombination must be unique. Thepackageis typically predefined for your organization (see Asset packages).display_name: The human-readable name shown in the UI.
data: A map that links a unique key (e.g.,"hello_world.html") to a reference (the actual file path, e.g.,"dist/hello_world.html").
Here is the template based on the HMI example:
# proto-file: intrinsic/assets/data/proto/v1/data_manifest.proto
# proto-message: DataManifest
metadata {
id {
package: "ai.intrinsic" # Or your own package name
name: "hello_world" # The unique name of your Asset
}
display_name: "hello_world" # Name shown in the UI
vendor {
display_name: "Intrinsic" # Or your company/team name
}
}
data {
[type.googleapis.com/intrinsic_proto.data.v1.ReferencedDataStruct] {
fields {
key: "hello_world.html"
value {
referenced_data_value: {
reference: "dist/hello_world.html"
}
}
}
fields {
key: "hello_world.css"
value {
referenced_data_value: {
reference: "dist/hello_world.css"
}
}
}
fields {
key: "hello_world.js"
value {
referenced_data_value: {
reference: "dist/hello_world.js"
}
}
}
}
}
Create the Bazel build file (BUILD.bazel)
Next, create the BUILD.bazel file in the root of your Asset directory. This file uses the intrinsic_data rule to define how to package your Asset.
name: The name of the Bazel target (e.g.,"hello_world_data").data: A list of all your Asset files. The paths are relative to theBUILD.bazelfile.manifest: The path to your.textprotomanifest file.deps: Required dependencies for the build rule. This is usually standard and doesn't need to be changed.
Here is the BUILD.bazel file based on your example:
# Load the rule needed to build the Data Asset
load("@ai_intrinsic_sdks//intrinsic/assets/data/build_defs:data.bzl", "intrinsic_data")
# Define the Data Asset target
intrinsic_data(
# The name for this build target
name = "hello_world_data",
# List all the files to be included in the Asset
data = [
"dist/hello_world.css",
"dist/hello_world.html",
"dist/hello_world.js",
],
# Point to the manifest file that describes the Asset
manifest = "hello_world.textproto",
# Standard dependency, usually does not change
deps = [
"@ai_intrinsic_sdks//intrinsic/assets/data/proto/v1:referenced_data_struct_proto",
],
)
Build and install the Data Asset with Bazel
Use a build rule (e.g. in Bazel) to define your Data Asset, which packages your static files into a versioned bundle.
Run the Bazel build command from your workspace root.
The command structure is bazel build //path/to/your/asset:target_name.
For your hello_world example located in the sdk-examples directory, the command would be:
bazel build //data_assets/platform_http_server/frontend_{x}:{intrinsic_data_name}
For example, bazel build //data_assets/platform_http_server/frontend:hello_world_data.
Then, use inctl asset install with the local bundle file to install the Data Asset into your running solution. This makes the files available on the local filesystem.
inctl asset install bazel-bin/data_assets/platform_http_server/frontend_x/{intrinsic_data_name}.bundle.tar --solution YOUR_SOLUTION_ID
For example, inctl asset install bazel-bin/data_assets/platform_http_server/frontend/hello_world_data.bundle.tar --solution 1a23456b-78c9-0123-4de5-6f7g89h01i23_BRANCH
NOTE: There is an example of a service that uses those Data Assets. Follow the guide here.