AI Application
First, let's understand the following concepts:
lzc-cliis the scaffolding used to develop LazyCat LCMD applications. Withlzc-cli, you can quickly package, install, debug, and release applications.- The package generated by
lzc-cliuses thelpkformat, the application format of the LCMD ecosystem. - The LazyCat AI Browser supports plugin installation for both
PCandAndroidplatforms.
AI 应用 refers to applications built on top of LCMD applications by importing an AIApp resource. These applications follow the same download and installation process as regular LCMD applications, with the following key differences:
- Supports AI service integration: After installation, the app automatically deploys the matching device model's AI service onto the AI Pod.
- Supports AI Browser plugin integration: After installation, the AI Browser automatically loads the corresponding plugin.
- Supports defining AI Browser shortcuts and dependencies: Configuration for shortcuts, upstream services, and storage aliases is defined in the resource via
config/aipod.yml.
Resource Import Declaration
LCMD applications import AIApp resources through lzc-manifest.yml, using its import_resources declaration:
import_resources:
- kind: aipodAfter the platform installs an application, the AIApp resource is expanded to the following runtime directory:
/lzcapp/run/resources/aipod/<package-id>/Among them, <package-id> is the application package ID. The platform reads the AI Pod configuration, service compose file, browser plugin, and fallback metadata from this directory.
Resource Directory Structure
The recommended AIApp resource directory structure is as follows:
aipod/
├── package.yml
├── lzc-manifest.yml
├── icon.png
├── config/
│ └── aipod.yml
├── agxorin/
│ └── docker-compose.yml
├── thor/
│ └── docker-compose.yml
└── extensions/
├── desktop.zip
└── android.crxField Description:
config/aipod.yml: AI Pod configuration file, without outeraipod:.agxorin/docker-compose.yml: Service definition for AGX Orin and default Jetson devices.thor/docker-compose.yml: Service definition for Thor devices.extensions/*.zip|*.crx: AI browser plugin file, supporting one or more.package.yml,lzc-manifest.yml,icon.png: fallback sources for metadata and icons.
When compatible with old packages, the platform will still recognize the following legacy paths:
ai-pod-service/docker-compose.yml: legacy service definition. Used only as fallback when the compose file is missing under the device model directory.browser-extensions/extension.zip: legacy browser plugin. Used only as fallback when the plugin underextensions/is missing.
config/aipod.yml
config/aipod.yml contains only the AI Pod configuration itself, without an outer aipod:. For example:
shortcut:
disable: false
title: ComfyUI
url: /_lzc/aipod_backend/startup/gate/cloud.lazycat.aipod.comfyui?redirect=https%3A%2F%2Fcomfyui-ai
favicon: /icon.png
locales:
en:
shortcut:
title: ComfyUI
depends_on_others:
- ollama-ai
depends_on_hosts:
- comfyui-ai
storage_alias:
models: /ssd/modelsshortcut
AI applications installed in the LCMD are displayed by default in the AI Browser shortcut. This can be disabled via shortcut.disable, or the shortcut's title, entry URL, and icon can be overridden:
shortcut.disable: Whether to hide the shortcut, default isfalse.shortcut.title: Shortcut title.shortcut.url: Shortcut entry URL. It is recommended to use the platform startup gate for long initialization services.shortcut.favicon: Shortcut icon URL.
locales
locales is used to configure multi-language metadata. The platform selects appropriate titles, descriptions, or shortcut fields based on the browser's language setting, falling back to default configurations if missing.
depends_on_others
depends_on_others declares the other AI hosts that the current AI application depends on. The platform considers these dependencies during entry and startup checks.
depends_on_hosts
depends_on_hosts declares the AI hosts that the current AI application itself needs to check. Typically, this is filled with the Host(...) value exposed via Traefik in the compose file. storage_alias
storage_alias Declare storage aliases used in the service to enable the platform to mount models, caches, or user data to stable paths.
Add AI Services
AI services are described via the docker-compose.yml in the resource. The platform selects the service directory based on device model:
- Thor devices prefer
thor/docker-compose.yml. - Other devices default to
agxorin/docker-compose.yml. - If the model-specific directory is missing, fallback to the legacy
ai-pod-service/docker-compose.yml.
If agxorin, thor, and legacy services coexist, the AI host exposed to the AI browser must remain consistent across devices to prevent the same application from generating different access addresses on different devices.
Service Access Rules
Services within the AI Pod use traefik combined with Host forwarding rules. Compose files must include resolvable Traefik Host(...) labels and have host values ending with -ai.
services:
comfyui:
image: registry.lazycat.cloud/demo/comfyui:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.${LZC_SERVICE_ID}-comfyui.rule=Host(`comfyui-ai`)"
networks:
default:
external: true
name: traefik-shared-networkRule Description:
- The value in
Host(...)is the AI host that the microservice and AI Browser use to access this service. - Only services joined in
traefik-shared-networkcan be managed by Traefik. - The AI host must be exposed consistently across multiple device directories' compose files.
- Long initialization services must configure
healthcheck, using container health status to control the ready state. The platform's installation progress and startup loading will reuse this status.
For more usage of traefik, see Host Rule.
Info
The docker in the AI Pod defaults to nvidia-runtime. The container can directly use gpus without explicitly configuring gpus. For more details, click here.
Service Environment Variables
The following environment variables are provided by the AI Pod when the service runs:
Data Persistence Path
- Definition:
/ssd/lzc-ai-agent/data/<service_id> - Environment Variable:
LZC_AGENT_DATA_DIR - Example:
/ssd/lzc-ai-agent/data/cloud.lazycat.aipod.ai
ymlservices: ollama: volumes: - ${LZC_AGENT_DATA_DIR}/data:/root/.ollama- Definition:
Data Caching Path
- Definition:
/ssd/lzc-ai-agent/cache/<service_id> - Environment Variable:
LZC_AGENT_CACHE_DIR - Example:
/ssd/lzc-ai-agent/cache/cloud.lazycat.aipod.ai
ymlservices: ollama: volumes: - ${LZC_AGENT_CACHE_DIR}/cache:/root/.cache- Definition:
Service ID
Definition: The value of
<appId>minus.Environment variable:
LZC_SERVICE_IDExample:
cloudlazycataipodfishspeechymlservices: ollama: labels: - "traefik.http.routers.${LZC_SERVICE_ID}-ollama.rule=Host(`ollama-ai`)"
Add AI Browser Plugin
The AI browser plugin is placed in the resource directory under extensions/, supporting zip and crx:
extensions/
├── desktop.zip
└── android.crxzip For browser-compatible plugin formats. If the plugin is developed using wxt, it can be directly packaged as a zip file; alternatively, the plugin directory can be manually zipped.
When supporting legacy packages, the platform will still read browser-extensions/extension.zip as a fallback.
Metadata and Icon Fallback
The platform prioritizes reading config/aipod.yml from the resource. If missing metadata such as title, description, or icon is found, the following fallback order is applied:
package.ymllzc-manifest.ymlicon.png
If metadata is present in both the LCMD application manifest and the AIApp resource, the AI Browser displays the resource configuration.
Startup Entry and Loading
It is no longer recommended to include a built-in caddy within each AI application for health checks during long initialization of AI services. Instead, it is recommended to reuse the startup gate provided by the platform.
/_lzc/aipod_backend/startup/gate/:appid?redirect=<url>Quick access to directly enter gate
If the application entry point is an AI host, you can directly access the gate via the shortcut:
shortcut:
title: ComfyUI
url: /_lzc/aipod_backend/startup/gate/cloud.lazycat.aipod.comfyui?redirect=https%3A%2F%2Fcomfyui-aiRule Description:
:appidis the AI application package ID.redirectis the target URL to redirect to after the service becomes ready, which must be URL encoded and is typically the AI host or microservice page address exposed by compose.- Static frontend can directly use the LCMD platform routing.
- API or model service access routes through Traefik upstream.
- Reuse platform capabilities for loading, health checks, and failure alerts; no need to implement these repeatedly for each application.
Static Frontend Integration with Startup Gate
If the AI application itself has an LCMD static frontend, follow the approach in cloud.lazycat.aipod.imgtrans: use lzc-manifest.yml and application.injects to intercept page requests. Users then enter the platform startup loading phase before any frontend page; once the service is ready, they return to the original page with deep links and query parameters preserved.
application:
subdomain: imgtrans
injects:
- id: aipod-startup-gate
'on': request
auth_required: false
when:
- /*
unless:
- /api/*
- /debug/backend/*
- /assets/*
- /favicon.ico
- /icon.png
- /robots.txt
- /manifest.json
- /_lzc/*
do:
- src: >
const appid = "cloud.lazycat.aipod.imgtrans";
const cookieName = "aipod_startup_ready_" +
appid.replace(/[^A-Za-z0-9]/g, "_");
const cookies = String(ctx.headers.get("Cookie") || "");
if (cookies.split(";").map((item) => item.trim()).some((item) =>
item === cookieName + "=1")) {
return;
}
const boxDomain = String(ctx.request.host || "").replace(/^[^.]+\./,
"");
const query = ctx.request.raw_query ? "?" + ctx.request.raw_query :
"";
const redirect = "https://" + ctx.request.host + ctx.request.path +
query;
const location = "https://" + boxDomain +
"/_lzc/aipod_backend/startup/gate/" + encodeURIComponent(appid) +
"?redirect=" + encodeURIComponent(redirect);
ctx.response.send(307, "", { location });
routes:
- /=file:///lzcapp/pkg/content/dist
upstreams:
- location: /api/
backend: http://backend:3000
disable_trim_location: true
public_path:
- /debug/backend/
- /api/Key points of this example:
when: /*intercepts all page entry points,unlessallows access to APIs, debugging interfaces, static resources, icons, and/_lzc/*internal platform paths, to prevent resource requests and the gate itself from being repeatedly redirected.appidmust be filled with the current AI application package ID; the startup gate will use it to query the installation and service ready status.- After the gate becomes ready, it writes a value to the
aipod_startup_ready_<appid>cookie. The inject module first checks this cookie; if ready, it directly allows the request, avoiding the loading state on every page open. boxDomainderives the host by removing the first subdomain segment from the current host, e.g., fromimgtrans.13gxg.heiyu.spaceto obtain13gxg.heiyu.space.redirectpreserves the user's original access address and query parameters, and passes them to the gate viaencodeURIComponent. After the service becomes ready, the platform redirects back to this original address.- Static frontend files continue to be exposed via
routes, while application-specific APIs are forwarded viaupstreams. The startup gate only handles ready/loading states and does not replace business routing.
In the AIApp resource, dependencies can be declared, and the platform will include these dependencies in the ready check:
shortcut:
disable: false
depends_on_others:
- trans
- ocrAccess a Service on a Specific AI Pod
When there are multiple AI Pods, access can be achieved via f-{算力舱的序列号}-{服务名称}-ai.{微服名称}.heiyu.space. For example:
https://f-1420225016421-dozzle-ai.catdog.heiyu.space