3.3 Project Interface V2
Note: This document is about the creation and usage of
ProjectInterface.In this document, PI refers to
ProjectInterfaceand Client refers to the tool that can process PI.
Introduction
The so-called ProjectInterface is a standardized project structure declaration for MaaFramework. It currently consists of a single file, interface.json. By defining a PI, you can leverage various derivative tools of MaaFramework. Therefore, even if you intend to integrate solely using a general-purpose programming language, it is recommended to define a PI containing the basic information.
TIP
You can find general UI and other tools that use PI in the Community Projects section.
Version Notes
Due to the rapid iteration of business development, the release schedule of MaaFramework cannot be properly aligned with the iteration pace of the PI. Therefore, PI will have its own separate version control, and its version number will not be completely synchronized with the MaaFramework release version number.
We have designated the version number for the independent release (January 30, 2026) as v2.1.0. Subsequent additions and fixes will be marked with version numbers in the documentation.
| Date | Version | Changes |
|---|---|---|
| 2026-01-30 | v2.1.0 | Standalone release |
| 2026-01-30 | v2.2.0 | Added attach_resource_path and import fields |
| 2026-02-23 | v2.3.0 | Added checkbox multi-select type, option.controller, option.resource, global/resource/controller-level options, focus.display display channel tag, preset field, import supports importing preset |
| 2026-03-05 | v2.3.1 | Clarified option applicability filtering |
interface.json
TIP
This file can be validated and receive hints via the schema file.
When opening the project template folder with VSCode, the schema and file will be automatically associated.
Overall Structure
interface_version
number
The interface version number, currently 2, fixed and required. Used to identify the ProjectInterface protocol version.languages
object
Multi-language support configuration. Keys are language codes, values are paths to corresponding translation files. If not specified, only Chinese is supported by default.
File paths are relative to the directory containing interface.json.jsonc"languages": { "zh_cn": "interface_zh.json", "en_us": "interface_en.json" }name
string
The unique project identifier, used as the project ID.label
string
The project display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed. Optional.jsonc{ "name": "MyProject", "label": "$project_name" // Internationalized project name }title
string
The window title. The Client will display this content directly without additional decoration. Optional, defaults to a combination ofnameandversion. Supports internationalization (starting with$).icon
string
The application icon file path, relative to the project root directory. If not specified, the default icon is used. Supports internationalization (starting with$).mirrorchyan_rid
string
MirrorChyan resource package identifier, used for resource management and distribution.mirrorchyan_multiplatform
boolean
Whether multi-platform is supported, affecting resource package packaging and distribution strategies.github
string
The project's GitHub repository URL, used for version update checking and issue feedback.
Software Update Convention:After painful lessons from version history,we expect general-purpose UIs to only provide update functionality for this GitHub release, not separate updates for the UI itself or MaaFW.
Resource authors should package their specified UI/MaaFW when releasing, ensuring that a specific resource version on the user side corresponds to a unique UI and MaaFW version, avoiding various issues caused by version mixing.version
string
The project version number. The Client can display it to users and use it for version update checking.contact
string
Contact information, displayed on the "About" page. Supports file paths, URLs, or direct text. Content supports Markdown format. Supports internationalization (starting with$).license
string
Project license information, displayed on the "About" page. Supports file paths, URLs, or direct text. Content supports Markdown format. Supports internationalization (starting with$).welcome
string
Welcome message, displayed in a popup when the user first uses the application, can also be used as an announcement. Supports file paths, URLs, or direct text. Content supports Markdown format. The system records the displayed content and will show the popup again when the content is updated. Supports internationalization (starting with$).description
string
Project description information, displayed on the "About" page. Supports file paths, URLs, or direct text. Content supports Markdown format. Supports internationalization (starting with$).controller
object[]
Controller configuration, an array of objects containing preset controller information.name
string
Unique name identifier, used as the controller ID.label
string
Display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed.description
string
Detailed controller description. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with$).icon
string
Controller icon file path, relative to the project root directory. Optional. Supports internationalization (starting with$).type
'Adb' | 'Win32' | 'PlayCover' | 'Gamepad' | 'WlRoots'
Controller type; valid values areAdb,Win32(Windows only),PlayCover(macOS only),Gamepad(Windows only), andWlRoots(Linux only).display_short_side
number
The short side length of the default scaled resolution, used for screen adaptation. Optional, defaults to 720. Mutually exclusive withdisplay_long_sideanddisplay_raw.display_long_side
number
The long side length of the default scaled resolution, used for screen adaptation. Optional. Mutually exclusive withdisplay_short_sideanddisplay_raw.display_raw
boolean
Whether to use the original resolution for screenshots without scaling. Optional, defaults to false. Mutually exclusive with scaled resolution settings.permission_required
boolean
Whether this controller requires running with administrator privileges. Optional, defaults to false.
Before running tasks, if the current process is not elevated, it will prompt and try to restart itself as an administrator.attach_resource_path
string[]💡 v2.2.0
Optional. An array of additional resource paths. These paths will be loaded afterresource.pathhas finished loading.option
string[]💡 v2.3.0
Optional. Controller-level option configuration, an array of strings. Array elements should correspond to the key names in the outeroptionconfiguration. The parameters generated by this option will participate in the pipeline override of all tasks that use this controller, serving as controller-level parameter passing.
If a referenced option does not satisfy the current controller/resource constraints, that option'spipeline_override(including nestedoption.option) must not be merged. 💡 v2.3.1adb
object
Specific configuration for theAdbcontroller.Note: In V2 protocol, the input/screencap methods for Adb controllers are automatically detected and selected by MaaFramework, no manual configuration required.
win32
object
Specific configuration for theWin32controller.class_regex
string
Optional. The regular expression used to search for window class names by the Win32 controller.window_regex
string
Optional. The regular expression used to search for window titles by the Win32 controller.mouse
string
Optional. The mouse control method for the Win32 controller. If not provided, the default is used. See Control Methods for details.keyboard
string
Optional. The keyboard control method for the Win32 controller. If not provided, the default is used. See Control Methods for details.screencap
string
Optional. The screenshot method for the Win32 controller. If not provided, the default is used. See Control Methods for details.
playcover
object
Specific configuration for thePlayCovercontroller (macOS only). Used to control iOS applications running via PlayCover. See Control Methods for details.- uuid
string
Optional. The Bundle Identifier of the target application. If not provided, the defaultmaa.playcoverwill be used. This is only used as a controller identifier and is unrelated to the application being controlled.
- uuid
gamepad
object
Specific configuration for theGamepadcontroller (Windows only). Used to create a virtual gamepad for game control. Requires ViGEm Bus Driver to be installed. See Control Methods for details.class_regex
string
Optional. The regular expression used to search for window class names by the Win32 controller.window_regex
string
Optional. The regular expression used to search for window titles by the Win32 controller.gamepad_type
string
Optional. The virtual gamepad type. Valid values areXbox360,DualShock4(orDS4). If not provided,Xbox360is used by default.screencap
string
Optional. The screenshot method. If not provided, the default is used. Only effective when window regex is configured. See Control Methods for details.
wlroots
object
Specific configuration for theWlRootscontroller.
resource
object[]
Resource configuration, an array of objects containing information about resource loading.name
string
Unique name identifier, used as the resource package ID.label
string
Display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed. Optional.description
string
Detailed resource description. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional.icon
string
Resource icon file path, relative to the project root directory. Optional. Supports internationalization (starting with$).path
string[]
An array of paths to load. If multiple paths are provided, they will be loaded sequentially; resources loaded later will override those loaded earlier.
File paths are relative to the directory containing interface.json.
Note: Resources include not onlypipelinebut alsoimageandmodel. Therefore, do not specify thepipelinedirectory directly.controller
string[]
Optional. Specifies the list of controller types supported by this resource package. Array elements should correspond to thenamefield in thecontrollerconfiguration. If not specified, all controller types are supported.When a user selects a controller, only resource packages that support that controller will be displayed in the user interface for selection. This allows providing specially optimized resource packages for different controller types.
option
string[]
Optional. Resource-level option configuration, an array of strings. Array elements should correspond to the key names in the outeroptionconfiguration. The parameters generated by this option will participate in the pipeline override of all tasks, serving as resource-level parameter passing.
If a referenced option does not satisfy the current controller/resource constraints, that option'spipeline_override(including nestedoption.option) must not be merged. 💡 v2.3.1jsonc"resource": [ { "name": "AndroidSpecificResource", "label": "$AndroidSpecificResource", "controller": ["Android"], "path": ["resource_android"] }, { "name": "GeneralResource", "label": "$GeneralResource", "path": ["resource"] } ]
agent
object | object[]
Agent configuration; it can be a single object or an array of objects, containing information about the subprocess(es) (AgentServer). Supports configuring multiple Agents simultaneously for more complex automation scenarios.child_exec
string
The subprocess path, an executable file available in the system path. For example, if the Python path exists in the environment variables (system or user), you can simply write"python".
CWD is the directory containing interface.json.child_args
string[]
Optional. An array of arguments for the subprocess.identifier
string
Optional. A connection identifier used to create a communication socket. If provided, it will be used; otherwise, one is created automatically.
Single Agent Example:
jsonc"agent": { "child_exec": "python", "child_args": [ "./agent/main.py", // Note: CWD is the directory containing interface.json "--test-mode" // Fixed string, passed as-is ] }Multiple Agents Example:
jsonc"agent": [ { "child_exec": "python", "child_args": ["./agent/recognition.py"] }, { "child_exec": "python", "child_args": ["./agent/action.py"] } ]task
object[]
Task configuration, an array of objects containing information about executable tasks.name
string
Unique task identifier, used as the task ID.label
string
Task display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed. Optional.entry
string
The task entry, which is the name of theTaskin thepipeline.default_check
boolean
Whether this task is selected by default. Optional, defaults to false. The Client will use this value to determine whether to check this task by default during initialization.description
string
Detailed task description to help users understand the task's functionality. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional.icon
string
Task icon file path, relative to the project root directory. Used for display in the user interface. Optional. Supports internationalization (starting with$).resource
string[]
Optional. Specifies the list of resource packages supported by this task. Array elements should correspond to thenamefield in theresourceconfiguration. If not specified, this task is available in all resource packages.When a user selects a resource package, the Client may hide tasks that do not support that resource package, or display them in a disabled (grayed-out) state to inform the user. This allows providing specialized task configurations for different resource packages, such as event tasks that are only available in specific resource packages.
jsonc"task": [ { "name": "EventTask", "label": "$EventTask", "entry": "ActivityTask", "resource": ["Official"], "description": "Event task only available in the Official resource package" }, { "name": "CommonTask", "label": "$CommonTask", "entry": "CommonTask" } ]controller
string[]
Optional. Specifies the list of controller types supported by this task. Array elements should correspond to thenamefield in thecontrollerconfiguration. If not specified, this task is available for all controller types.When a user selects a controller, the Client may hide tasks that do not support that controller, or display them in a disabled (grayed-out) state to inform the user. This allows providing specialized task configurations for different controller types, such as tasks that are only available for Adb controllers or Win32 controllers.
jsonc"task": [ { "name": "AndroidOnlyTask", "label": "$AndroidOnlyTask", "entry": "AndroidSpecificTask", "controller": ["Android"], "description": "Task only available for Android controllers" }, { "name": "Win32OnlyTask", "label": "$Win32OnlyTask", "entry": "Win32SpecificTask", "controller": ["Win32Emulator"], "description": "Task only available for Win32 controllers" }, { "name": "CommonTask", "label": "$CommonTask", "entry": "CommonTask" } ]pipeline_override
pipeline
Optional. Task parameters that override the loaded resources when executing the task. This structure is exactly the same as the JSON file in thepipelineand must include the task name part, for example:jsonc"pipeline_override": { "Quit": { "enabled": true } }option
string[]
Optional. Task configuration options, an array containing keys from subsequentoptionobjects. The Client will prompt the user to make selections based on these.The Client can display the options in the order provided in the
optionarray.
option
record<string, object>
Definition of configuration options, an object mapping containing information about each option.key
Unique name identifier; tasks will reference this name.type
string
The option type. Optional, defaults to"select". Valid values:"select": Dropdown selection box, user selects one from predefined options"checkbox": Multi-select box, user selects multiple from predefined options 💡 v2.3.0"input": User input field, allows manual input"switch": Toggle switch, Yes or No
controller
string[]💡 v2.3.0
Optional. Specifies the list of controller types this option applies to. Array elements should correspond to thenamefield in thecontrollerconfiguration. If not specified, this option is available for all controller types.
When a user selects a controller, the Client may hide options that do not apply to that controller, or display them in a disabled (grayed-out) state to inform the user.
If the current controller is not in this list, the option is treated as inactive: allpipeline_overridegenerated by this option and its sub-options (option.option) must be excluded from merging. 💡 v2.3.1resource
string[]💡 v2.3.0
Optional. Specifies the list of resource packages this option applies to. Array elements should correspond to thenamefield in theresourceconfiguration. If not specified, this option is available for all resource packages.
When a user selects a resource package, the Client may hide options that do not apply to that resource package, or display them in a disabled (grayed-out) state to inform the user.
If the current resource package is not in this list, the option is treated as inactive: allpipeline_overridegenerated by this option and its sub-options (option.option) must be excluded from merging. 💡 v2.3.1label
string
Option display label, shown in the user interface. Supports internationalized strings (starting with$). Optional.description
string
Detailed option description to help users understand the option's purpose. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with$).icon
string
Option icon file path, relative to the project root directory. Optional. Supports internationalization (starting with$).cases
object[]
Used only whentypeis"select","checkbox", or"switch". Available options, an array of objects containing information about each option.Note: When
typeis"checkbox", the user can select multiple cases simultaneously. Thepipeline_overrideof all selected cases will be merged in the order they appear in thecasesarray — regardless of the order in which the user checked them.Note: When
typeis"switch", only two cases are supported, and the following rules must be followed:- If
case.nameis one of"Yes","yes","Y", or"y", that case will be recognized as the Yes option - If
case.nameis one of"No","no","N", or"n", that case will be recognized as the No option - The Client will match the user's Y/N input based on the case's name, and other inputs will prompt the user to re-enter
It is recommended to use
"Yes"and"No"as the names of the two cases to ensure consistency across different Clients.The Client can display the options in the order provided in the
casesarray.name
string
Unique option identifier, used as the option ID.label
string
Option display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed. Optional.description
string
Detailed option description. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with$).icon
string
Option icon file path, relative to the project root directory. Optional. Supports internationalization (starting with$).option
string[]
Sub-option list. Optional. These sub-options are only displayed when the user selects the current option. These sub-options are also defined in the outeroptionand support unlimited nesting.pipeline_override
pipeline
Same as thepipeline_overridein thetask. It takes effect when the option is activated.
- If
inputs
object[]
Used only whentypeis"input". Input configuration, an array of objects defining user-inputtable fields.name
string
Unique input field identifier, used as the input field ID.label
string
Input field display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed. Optional.description
string
Detailed input field description to help users understand input requirements. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with$).default
string
Default value for the input field. Optional.pipeline_type
string
The data type of the input field in pipeline_override. Valid values:"string","int","bool". When using variable substitution in pipeline_override, type conversion is performed according to this type.verify
string
Regular expression used to validate whether user input is valid. Optional.pattern_msg
string
Message displayed when regex validation of user input fails. Optional. Supports internationalization (starting with$).
pipeline_override
pipeline
Used when the option type is"input", as a substitution template for user input content. Supports using{name}format in strings to reference input field values. Optional.default_case
string|string[]
Default option name. Optional.- When
typeis"select"or"switch": provide a single string; the Client uses it as the initial selected value. - When
typeis"checkbox": provide a string array; the Client uses it as the initial set of selected values. 💡 v2.3.0
- When
global_option
string[]💡 v2.3.0
Optional. Global option configuration, an array of strings. Array elements should correspond to key names in theoptionconfiguration.
The parameters generated by this option will participate in the pipeline override of all tasks, regardless of which resource package or controller the user has selected.
Unlikeresource.optionandcontroller.option, global options do not depend on any resource package or controller selection.
However, options referenced byglobal_optionmust still satisfy their ownresource/controllerconstraints; otherwise, nopipeline_overrideis applied. 💡 v2.3.1jsonc"global_option": [ "BattleMode", "AutoDodge" ]import
string[]💡 v2.2.0
Optional. An array of paths to other PI files to import. File paths are relative to the directory containing interface.json.
Supports importingtask,option, andpreset💡 v2.3.0 fields from these files.
The Client will load these files sequentially and merge their contents with the current file, enabling configuration splitting and reuse.preset
object[]💡 v2.3.0
Optional. Preset configurations, an array of objects. Each preset is a snapshot of predefined task checkbox states and option values. Users can apply a preset with a single click to quickly switch between different usage scenarios.name
string
Unique identifier, used as the preset ID.label
string
Display name, shown in the user interface. Supports internationalized strings (starting with$). If not set, the value of thenamefield is displayed. Optional.description
string
Detailed preset description to help users understand the applicable scenario. Supports file paths, URLs, or direct text. Content supports Markdown format. Optional. Supports internationalization (starting with$).icon
string
Preset icon file path, relative to the project root directory. Optional. Supports internationalization (starting with$).task
object[]
List of task configurations included in this preset.name
string
Required. The task name corresponding totask[].nameat the top level.enabled
boolean
Optional, defaults totrue. Whether this task is checked in the preset.option
record<string, OptionValue>
Optional. Preset values for each option of this task. Keys are option key names from the top-leveloption. TheOptionValuetype depends on the correspondingoption.type:option.type OptionValue type Example select/switchstring(case.name)"x3"/"Yes"checkboxstring[](array ofcase.name)["AutoBattle", "AutoPickup"]inputrecord<string, string>(input field name → value){ "ChapterNumber": "4" }
Preset Example:
jsonc"preset": [ { "name": "DailyRoutine", "label": "$DailyRoutine", "description": "Daily routine: Wilderness + Insight + 3-9 + Claim Rewards", "icon": "preset_daily.png", "task": [ { "name": "Collect Wilderness", "enabled": true }, { "name": "Daily Insight (Will Analysis)", "enabled": true }, { "name": "Standard Combat", "enabled": true, "option": { "BattleStage": "3-9 Dire (Lark)", // select type: fill case.name "RepeatCount": "x3", // select type: fill case.name "DrainAllSanity": "No", // switch type: fill case.name "EnableFeatures": ["AutoBattle", "AutoPickup"] // checkbox type: fill case.name array } }, { "name": "Claim Rewards", "enabled": true }, { "name": "Event: Stage 17 Hard (Event Ended)", "enabled": false } ] }, { "name": "RealtimeAssist", "label": "$RealtimeAssist", "description": "Background assist mode, only runs auto-assist tasks", "task": [ { "name": "Standard Combat", "enabled": true, "option": { "EnableFeatures": ["AutoBattle", "AutoPickup", "AutoHeal"] } } ] } ]Managing presets across files via
import:Preset configurations can be split into separate files via
importfor easier management and reuse. For example:jsonc// interface.json { "import": [ "preset_daily.json", "preset_realtime.json" ], "preset": [ // Presets can also be defined directly in the main file and will be merged with imported presets ] }jsonc// preset_daily.json { "preset": [ { "name": "DailyRoutine", "label": "$DailyRoutine", "description": "Daily routine package", "task": [ { "name": "Collect Wilderness", "enabled": true }, { "name": "Claim Rewards", "enabled": true } ] } ] }
Option Override Order 💡 v2.3.0
The pipeline_override generated by each level of option is merged in the following order — later-merged fields override earlier ones with the same key name:
global_option— global options, applied first, lowest priorityresource.option— resource-level optionscontroller.option— controller-level optionstask.option— task-level options, applied last, highest priority
In other words: task.option > controller.option > resource.option > global_option.
Before applying the merge order above, inactive options must be filtered out. Any option that does not satisfy the current controller / resource constraints (including options referenced by global_option, resource.option, controller.option, task.option, and nested option.option) must not generate pipeline_override. 💡 v2.3.1
The reasoning behind this design is that more specific configuration (task-level) should have higher priority, while more general configuration (global-level) serves as the fallback default.
Example:
If both global_option and a task.option reference the same option, and that option's cases make different overrides to the same pipeline node, the task-level override will take final effect.
Option Examples
Select Type Option Example
{
"option": {
"BattleStage": {
"type": "select",
"label": "$SelectBattleStage",
"description": "Select the stage to farm",
"default_case": "3-9 Dire",
"cases": [
{
"name": "3-9 Dire (Lark)",
"label": "$3-9Dire",
"description": "Farm Lark",
"icon": "lark.png",
"option": [
"UseSanityPotion",
"AfterFarmingXXX"
],
"pipeline_override": {
"EnterTheShow": {
"next": "MainChapter_3"
}
}
}
]
}
}
}Input Type Option Example
{
"option": {
"CustomStage": {
"type": "input",
"label": "Custom Stage",
"description": "Choose which stage to play",
"icon": "wrench.png",
"inputs": [
{
"name": "ChapterNumber",
"label": "$ChapterNumber",
"description": "Stage chapter number, use Arabic numerals",
"default": "4",
"pipeline_type": "string",
"verify": "^\\d+$"
},
{
"name": "Timeout",
"label": "$Timeout",
"description": "Wait timeout duration",
"default": "20000",
"pipeline_type": "int",
"verify": "^\\d+$"
}
],
"pipeline_override": {
"EnterTheShow": {
"next": "MainChapter_{ChapterNumber}",
"timeout": "{Timeout}"
}
}
}
}
}Checkbox Type Option Example 💡 v2.3.0
{
"option": {
"BattleFeatures": {
"type": "checkbox",
"label": "$BattleFeatures",
"description": "Select the battle features to enable, multiple selections allowed",
"default_case": ["NormalStrike", "ChargedStrike"],
"cases": [
{
"name": "NormalStrike",
"label": "$NormalStrike",
"description": "Enable normal strike",
"pipeline_override": {
"NormalMatch": {
"enabled": true
}
}
},
{
"name": "ChargedStrike",
"label": "$ChargedStrike",
"description": "Enable charged strike",
"pipeline_override": {
"ChargedMatch": {
"enabled": true
}
}
},
{
"name": "ComboStrike",
"label": "$ComboStrike",
"description": "Enable combo strike",
"pipeline_override": {
"ComboMatch": {
"enabled": true
}
}
}
]
}
}
}Note: In
checkboxtype, thepipeline_overrideof multiple selected cases is merged in the definition order of thecasesarray — regardless of the order in which the user checked them.
Internationalization Support
For all string fields that support internationalization, if the string starts with $, it indicates that the string is an internationalized string. The Client needs to read the actual value from the translation file before displaying it.
For example:
{
"name": "MyDemo3",
"label": "$MyDemo3",
"controller": [
{
"name": "Android",
"label": "$Android"
}
]
}Corresponding translation file (e.g., interface_en.json):
{
"MyDemo3": "My Demo 3",
"Android": "Android Device"
}Resource Override
If a later-loaded resource contains a task with the same name as one already loaded, the tasks will be merged. Generally, the top-level keys of the new task will replace those of the old task. For example:
Old Task
{
"task1": {
"enabled": false,
"recognition": "DirectHit",
"next": [ "T1", "T2" ]
}
}New Task
{
"task1": {
"enabled": true,
"action": "Click",
"next": [ "T2", "T3" ]
}
}Merged Task
{
"task1": {
"enabled": true,
"recognition": "DirectHit",
"action": "Click",
"next": [ "T2", "T3" ] // Direct replacement; inner arrays/lists are not merged.
}
}Node Notification Handling
MaaFramework sends node notifications via callback functions during task execution. The Client needs to implement the corresponding handling logic to display task execution status to users.
Callback Function Signature
The Client needs to register a callback function to receive notifications. For the function signature, refer to MaaDef.h:
typedef void(MAA_CALL* MaaEventCallback)(
void* handle,
const char* message,
const char* details_json,
void* trans_arg
);- message: Message type identifier (e.g.,
Node.Action.Starting,Node.Recognition.Succeeded, etc.) - details_json: JSON string containing specific data
Message Template Mechanism
Resource authors can configure message templates in the Pipeline using the focus field. The focus field is a dictionary where keys are message types and values are template strings or template objects. Template strings support file paths, URLs, or direct text, content supports Markdown format, and support internationalization (starting with $). When the Client receives a callback, it should perform placeholder replacement based on the template and display the result to users via the specified channel.
Two Forms of focus Values
Shorthand (plain string): Equivalent to display: "log" — content is only shown in the run log.
"focus": {
"Node.Action.Starting": "{name} starts execution"
}Full form (object): Use the display field to specify the display channel. 💡 v2.3.0
"focus": {
"Node.Action.Starting": {
"content": "{name} starts execution",
"display": "toast"
}
}display Values 💡 v2.3.0
| Value | Description | Behavior |
|---|---|---|
"log" | Run log (default) | Appended to the log stream, non-interrupting |
"toast" | In-app lightweight notification | Briefly appears then auto-dismisses, non-blocking |
"notification" | System-level notification | Pushed to OS notification center, received even when app is in background |
"dialog" | Non-blocking dialog | Popup message box, task pipeline continues running in the background |
"modal" | Blocking popup | Task is paused until the user confirms — suitable for scenarios requiring manual intervention |
display supports arrays so the same message can be pushed to multiple channels simultaneously:
"focus": {
"Node.Action.Succeeded": {
"content": "✅ {name} executed successfully",
"display": ["log", "toast"]
},
"Node.Action.Failed": {
"content": "❌ Execution failed, please check the environment",
"display": ["log", "modal"]
}
}Complete Pipeline Configuration Example:
{
"NodeA": {
"focus": {
"Node.Recognition.Succeeded": "{name} recognition hit, ready to start execution",
"Node.Action.Starting": {
"content": "{name} starts execution, task ID: {task_id}",
"display": ["log", "toast"]
},
"Node.Action.Failed": {
"content": "{name} execution failed",
"display": "modal"
}
}
}
}Callback Function Parameters Example:
// message parameter:
"Node.Action.Starting"
// details_json parameter (after parsing):
{
"task_id": 12345,
"action_id": 11111,
"name": "NodeA",
"focus": {
"Node.Recognition.Succeeded": "{name} recognition hit, ready to start execution",
"Node.Action.Starting": {
"content": "{name} starts execution, task ID: {task_id}",
"display": ["log", "toast"]
},
"Node.Action.Failed": {
"content": "{name} execution failed",
"display": "modal"
}
}
}Client Processing Flow
- Parse the
details_jsonparameter in the callback function - Check if the parsed object contains a
focusfield - If present, find the corresponding template (string or object) in
focusbased on themessageparameter - If the template is a string, treat it as
contentand setdisplayto["log"]; if it is an object, readcontentanddisplayseparately - Replace placeholders in
content(e.g.,{name},{task_id}) with data fromdetails_json - Display the processed text to the user via the channel(s) specified in
display(may be multiple) 💡 v2.3.0
Using the example above, upon receiving Node.Action.Starting, the Client should append to the log and show a toast: NodeA starts execution, task ID: 12345
More Message Types
For a complete list of callback messages and detailed descriptions, please refer to Callback Protocol and MaaMsg.h.
