Skip to content

Digital Human spec reference ​

Reference for the Digital Human spec.yaml: every field with its type, default and allowed values, the rules Halo checks, and the fields that have no effect.

A Digital Human is defined by its spec: its instructions, triggers, settings form, capabilities and dependencies. This page lists every field Halo accepts, the rules it checks, and the fields it accepts but never acts on.

Where the spec lives ​

You rarely start from an empty file:

  • Ask Halo. Describe the job in a conversation, and Halo writes and installs the spec for you. See Create a Digital Human.
  • Read or edit an existing one. Open the Digital Human, go to Capabilities and settings and switch to the YAML tab. It shows the full spec, checks your changes when you click Save, and Export saves it as a file.
  • Package it. A Digital Human package carries the spec as spec.yaml at its root. See DHP protocol.

You can also ask Halo to change an installed Digital Human, or send the changed top-level fields with PATCH /api/apps/:appId/spec.

A minimal spec ​

yaml
name: Weekly sales summary
version: "1.0.0"
author: example
description: Every Monday, sums up last week's orders and reports the totals.
type: automation
system_prompt: |
  You prepare the weekly sales summary.
  1. Read orders.csv in the workspace.
  2. Write the totals per product to report.md.
  3. Report the three biggest changes with report_to_user.
  Never delete or rewrite orders.csv.
subscriptions:
  - id: weekly
    source:
      type: schedule
      config:
        cron: "0 9 * * 1"

name, version, author, description, type and system_prompt are required for a Digital Human. When Halo's assistant creates one, it fills in version (1.0) and author (Halo) if you leave them out; a file you import must have them.

Rules Halo checks ​

Halo validates the spec when it is installed or changed, and rejects it with the field that failed:

  • cron must be a valid cron expression with a future run; every must look like 30m, 2h or 1d. A schedule needs one of the two.
  • Trigger ids must be unique, and a trigger's config_key must name a config_schema key.
  • A select setting needs at least one option.
  • browser_login[].url, store.homepage and store.repository must be URLs.

Fields Halo does not know are dropped without an error, so a typo in a field name silently does nothing. Compare a spec you wrote by hand with the tables below.

When Halo reads a spec.yaml file (Import, or POST /api/apps/import-spec), it also accepts a few older names: inputs for config_schema, required_mcps and required_skills for requires.mcps and requires.skills, input for config_key, and a trigger written as - type: schedule with its config beside it instead of under source. Write the current names in new specs.

Fields ​

Field paths use [] for list items and <…> for the keys of a map. A value in parentheses after a path, such as (schedule), means the field applies to that trigger type only.

Generated from the schema of Halo 3.0.4.

Top-level fields ​

FieldTypeRequiredDefault / valuesDescription
spec_versionstringNo= "1"Version of the spec format. Leave it out; Halo fills in "1".
namestring (non-empty)Yes—The name people see. For a skill it is also the folder name and the slash command, so a non-ASCII skill name is turned into an ASCII command name and the original is kept in display_name.
display_namestringNo—Name to show when name is not presentable, such as a skill named in Chinese. A matching i18n entry wins over it.
versionstring (version)Yes—Your version of the package, such as 1.0.0. A Store update must carry a higher version.
authorstring (non-empty)Yes—Who made it. When published, it becomes the namespace of the Store address, <author>/<name>. Optional for skills.
descriptionstring (non-empty)Yes—One or two sentences on what it does, shown in lists and the Store.
iconstringNo—An emoji or an image URL. Anything else falls back to the type icon; a Digital Human without an icon gets a generated avatar.
permissionsstring[]No—Capabilities to turn on at install: ai-browser, ai-terminal, email, im-push (on by default anyway), halo-api-ref (Operate Halo) and conversation-collab (Conversation Collaboration), both off by default. A spec can only add a capability; the user can still turn any of them off.
requires (see below)objectNo—MCP servers and skills it depends on.
config_schema (see below)object[]No—The settings form the user fills in at install and can change later. Every run and chat hands the Digital Human the current values by key, with defaults filled in.
store (see below)objectNo—Store listing details, used when the package is published or installed from a store.
i18n (see below)map<string, object>No—Translations of the name, description, settings form and login labels, keyed by language tag such as en or zh-CN.
typeliteralYesautomationKind of package: automation (a Digital Human), mcp, skill, or extension (reserved).
system_promptstring (non-empty)Yes—The Digital Human's instructions: its role, its steps, what it must never do and when to ask. Everything it does on its own follows from this text.
subscriptions (see below)object[]No—When it runs on its own. Leave it out for a Digital Human that only answers chats and messages from bots.
filters (see below)object[]No—No effect: accepted, but nothing reads it. Meant as rules that drop events before a run starts. Put such conditions in the system prompt instead.
memory_schema (see below)map<string, object>No—What the Digital Human should keep in its memory file between runs, such as processed ids or a last-run time. It guides the AI; nothing checks it.
output (see below)objectNo—No effect: accepted, but nothing reads it. Meant to configure notifications and output format. Ask for notifications in the system prompt instead: the Digital Human sends them through the notification channels set up in Settings.
escalation (see below)objectNo—How long its questions wait for an answer. The Digital Human can always stop and ask.
recommended_modelstringNo—Model to suggest. Shown as a hint where the user picks the model; it does not switch the model.
browser_login (see below)object[]No—Websites the user must be signed in to in the AI Browser before it can work. Halo asks the user to sign in; the Digital Human never sees the password.

requires ​

FieldTypeRequiredDefault / valuesDescription
mcpsobject[]No—MCP servers it uses. Runs get only the servers listed here, and a run doesn't start while one of them is not installed, turned off, waiting for sign-in or failing. A chat gets every server of its workspace and the global ones, except those marked enabled: false.
mcps[].idstring (non-empty)Yes—Id of an installed MCP server.
mcps[].reasonstringNo—Why it needs the server, shown next to the dependency.
mcps[].bundledbooleanNo—No effect: accepted, but nothing reads it. Meant to mark an MCP server shipped inside the package.
mcps[].enabledbooleanNo—false keeps the declaration but stops this Digital Human from using the server, in runs and in chat. The server itself stays on for everyone else.
skills(string | object)[]No—Skills to install together with it, as ids or objects. Every skill in its workspace or global scope is available to it anyway; this list only decides what gets installed.
skills[].idstring (non-empty)Yes—Skill id.
skills[].reasonstringNo—Why it needs the skill.
skills[].bundledbooleanNo—true when the skill ships inside the package under skills/<id>/ rather than coming from the Store.
skills[].filesstring[]No—For a bundled skill, its files relative to skills/<id>/, such as SKILL.md and index.js.

config_schema ​

FieldTypeRequiredDefault / valuesDescription
keystring (non-empty)Yes—Unique key of the setting.
labelstring (non-empty)Yes—Label shown on the form.
typeenumYesurl, text, string, number, select, boolean, emailInput control. text is multi-line, string single-line. There is no password or secret type, because the values are passed to the AI as plain text: for sites that need a login, use browser_login.
descriptionstringNo—Help text under the field.
requiredbooleanNo—Marks the field as required on the form.
defaultanyNo—Value filled in until the user changes it.
placeholderstringNo—Hint shown in an empty field.
optionsobject[]No—Choices of a select field, at least one.
options[].labelstring (non-empty)Yes—Text of the choice.
options[].valuestring | number | booleanYes—Value stored when it is chosen.

store ​

FieldTypeRequiredDefault / valuesDescription
slugstringNo—Store address of the package. Publishing sets it to <author>/<name> for you.
categorystringNo—Store category it is listed under.
tagsstring[]No= []Tags that help people find it in the Store.
localestringNo—Main language of the package, as a language tag such as zh-CN.
min_app_versionstringNo—Oldest Halo version it is meant for. The Store shows it; Halo does not block older versions.
licensestringNo—License, as an SPDX identifier such as MIT. Kept with the package.
homepagestring (URL)No—Project homepage. Kept with the package.
repositorystring (URL)No—Source repository. Kept with the package.

i18n ​

FieldTypeRequiredDefault / valuesDescription
<locale>.namestringNo—Translated name.
<locale>.descriptionstringNo—Translated description.
<locale>.config_schemamap<string, object>No—Translations of settings fields, keyed by the field key.
<locale>.config_schema.<key>.labelstringNo—Translated label.
<locale>.config_schema.<key>.descriptionstringNo—Translated help text.
<locale>.config_schema.<key>.placeholderstringNo—Translated placeholder.
<locale>.config_schema.<key>.optionsmap<string, string>No—Translated choice labels, keyed by the choice value.
<locale>.browser_loginmap<string, object>No—Translated login labels, keyed by the browser_login URL.
<locale>.browser_login.<key>.labelstringNo—Translated label.

subscriptions ​

FieldTypeRequiredDefault / valuesDescription
idstringNo—Id of this trigger, unique in the spec. Without one, triggers are numbered 0, 1, … in order.
sourceobjectYes—What starts a run.
source.typeenumYesschedule, file, webhook, webpage, rss, custom, wecomschedule, file and webhook start runs. webpage, rss, custom and wecom are accepted but nothing produces their events. Messages to a bot reach a Digital Human through its bot binding, not through a trigger.
source.config (schedule)objectYes—When to run: every or cron.
source.config.every (schedule)string (duration)No—Interval such as 30m, 2h or 1d (units s, m, h, d). If both every and cron are set, every wins.
source.config.cron (schedule)string (cron)No—Cron expression with 5 fields, or 6 with seconds first, such as 0 9 * * 1-5. It is checked when the spec is saved.
source.config.workday_calendar (schedule)booleanNo—true runs only on mainland China working days, including make-up workdays, and skips public holidays. Use it with a schedule that fires every day, not 1-5.
source.config (file)objectYes—Which file changes start a run.
source.config.pattern (file)stringNo—Glob matched against the changed file's path inside its own workspace, such as inbox/*.csv. It matches the same path in every workspace Halo watches, not only this one.
source.config.path (file)stringNo—Folder whose files count, matched as part of the absolute path. Halo does not limit a file trigger to the Digital Human's own workspace: changes in any workspace it watches (those open in the app and those of other file triggers) count. Set path to a folder inside this workspace to keep the trigger there.
source.config (webhook)objectYes—An HTTP endpoint at /hooks/<path> that other systems post JSON events to.
source.config.path (webhook)stringNo—Path after /hooks/. Use lower case and a path no other Digital Human uses.
source.config.secret (webhook)stringNo—Shared secret for the HMAC-SHA256 signature every request must carry. Without it, anyone who can reach Halo can start the Digital Human.
source.config (webpage)objectYes—No effect: no event source produces this trigger. Meant to watch a web page for changes. To check a page, use a schedule and let the Digital Human open it in the AI Browser.
source.config.watch (webpage)stringNo—No effect: no event source produces this trigger. What to watch on the page.
source.config.selector (webpage)stringNo—No effect: no event source produces this trigger. CSS selector to focus on.
source.config.url (webpage)stringNo—No effect: no event source produces this trigger. Page URL.
source.config (rss)objectYes—No effect: no event source produces this trigger. Meant to follow an RSS feed. Use a schedule that reads the feed instead.
source.config.url (rss)stringNo—No effect: no event source produces this trigger. Feed URL.
source.config (custom)map<string, any>Yes—No effect: no event source produces this trigger. Free-form settings for a custom event source. Halo has none built in.
source.config (wecom)objectYes—No effect: no event source produces this trigger. Meant for WeCom messages. To have a Digital Human answer a WeCom bot, bind the bot to it in Settings › Message Channels.
source.config.chatId (wecom)stringNo—No effect: no event source produces this trigger. Chat to listen to.
frequencyobjectNo—Meant as the range of intervals a user may pick. Halo does not enforce it.
frequency.defaultstring (duration)Yes—Suggested interval. It does not change when runs happen: set the schedule's every or cron for that.
frequency.minstring (duration)No—No effect: accepted, but nothing reads it. Meant as the shortest interval a user may pick.
frequency.maxstring (duration)No—No effect: accepted, but nothing reads it. Meant as the longest interval a user may pick.
config_keystringNo—No effect: accepted, but nothing reads it. Meant to feed a setting into the trigger. It must name an existing config_schema key, or the spec is rejected, but the value is never used.

filters ​

FieldTypeRequiredDefault / valuesDescription
fieldstring (non-empty)Yes—No effect: accepted, but nothing reads it. Event field to test.
openumYeseq, neq, contains, matches, gt, lt, gte, lteNo effect: accepted, but nothing reads it. Comparison.
valueanyYes—No effect: accepted, but nothing reads it. Value to compare with.

memory_schema ​

FieldTypeRequiredDefault / valuesDescription
<field>.typestring (non-empty)Yes—Kind of value, as a hint such as string, number, date or array.
<field>.descriptionstringNo—What the entry holds and how to update it.

output ​

FieldTypeRequiredDefault / valuesDescription
notifyobjectNo—No effect: accepted, but nothing reads it. Notification settings.
notify.systembooleanNo—No effect: accepted, but nothing reads it. Desktop notifications. The user sets them per Digital Human under Messages & Notifications › System Notifications.
notify.channelsenum[]Noemail, wecom, dingtalk, feishu, webhookNo effect: accepted, but nothing reads it. Notification channels.
formatstringNo—No effect: accepted, but nothing reads it. Output format.

escalation ​

FieldTypeRequiredDefault / valuesDescription
enabledbooleanNo—No effect: accepted, but nothing reads it. false does not stop it from asking, and true changes nothing. How far it may act alone comes from the system prompt.
timeout_hoursnumberNo> 0Hours a question waits before it expires; the run then ends as failed. Without it, a question waits until someone answers.

browser_login ​

FieldTypeRequiredDefault / valuesDescription
urlstring (URL)Yes—Sign-in page.
labelstring (non-empty)Yes—Name of the site, shown to the user.

Fields that have no effect ​

Halo accepts these fields so that older specs still install, but nothing reads them. Don't rely on them:

  • output (notifications and format). For notifications, ask for them in system_prompt; the Digital Human sends them through the channels set up in Settings › Message Channels. Desktop notifications are set per Digital Human under Messages & Notifications › System Notifications.
  • escalation.enabled, which is never read. A Digital Human can always stop and ask; how far it may act alone comes from system_prompt. Only escalation.timeout_hours has an effect.
  • filters. Write such conditions into system_prompt.
  • subscriptions[].config_key (checked, then ignored), subscriptions[].frequency.min and .max, and requires.mcps[].bundled.
  • The trigger types webpage, rss, custom and wecom: nothing produces their events. Use a schedule that checks the page or feed, and bind a bot in Settings › Message Channels for chat messages.

基于 MIT 协议开源 · Open source under the MIT license