Render, validate, and (optionally) attach interaction placeholders to Microsoft Adaptive Cards — with a focus on cross-channel compatibility (Teams, Web Chat, Webex up to 1.3) and graceful downsampling when a channel can’t render a full card.
This component is designed to be used inside Greentic flows (via greentic-dev flow add-step) and tested locally (via greentic-component test).
The component now uses a single canonical component-config surface for install/setup defaults:
default_sourcedefault_card_inlinedefault_card_assetmultilinguallanguage_modesupported_localesdirection_modevalidation_modetrace_enabledtrace_capture_inputs
Operation input stays focused on per-call overrides:
card_sourcecard_speclocalepayloadsessionstateinteractionmodevalidation_modenode_idenvelope
Runtime precedence is:
- explicit operation input override
- component config
- deprecated env-var fallback
- hardcoded default
English (en) is always the implicit baseline and fallback locale.
multilingual = falseforces English rendering behaviormultilingual = truewithlanguage_mode = allallows the built-in locale set fromconfig/supported_locales.jsonmultilingual = truewithlanguage_mode = customusessupported_locales, with English still retained as fallbackdirection_mode = ltremits"rtl": falsedirection_mode = rtlemits"rtl": truedirection_mode = autoinfers direction from locale and currently treats Arabic variants as RTL
At render time the component injects Adaptive Card root lang and rtl.
The setup/update QA flow now offers a Remote card choice alongside Inline JSON and Asset file.
That remote question is an asset ref with host-assisted remote resolution enabled, so Greentic Flow can accept refs such as:
https://example.com/cards/welcome.jsonoci://registry.example.com/cards/welcomestore://greentic-biz/_/adaptive-cards/defaultrepo://my-repo/cards/welcome.json
When Remote card is selected, the host/orchestrator is expected to import the card into the pack and return the local assets/cards/*.json path through apply_answers. This component then stores that local path as default_card_asset with default_source = "asset".
Catalog-style runtime resolution remains available for direct invocation payloads and backwards-compatible configs.
What is implemented today at runtime:
repo://...refs are resolved as local repo-relative paths in native/local executionstore://...refs require host/distributor resolution and can be satisfied through the existing host asset resolver hook- legacy
ADAPTIVE_CARD_CATALOG_FILEandADAPTIVE_CARD_ASSET_REGISTRYenv vars remain as deprecated fallback only
The component does not perform remote distributor fetches by itself inside the wasm runtime.
- Component ABI:
greentic:component/component@0.6.0 - Guest bindings:
greentic-interfaces-guestwithfeatures = ["component-v0-6"]
If you compile this component with different interface versions or features, exports will not match the manifest world.
Adaptive Cards are a JSON-based UI description format (“cards”) that host apps (e.g. Microsoft Teams, Bot Framework Web Chat, Webex) can render. You author a single card payload, and host apps render it according to their capabilities.
Key ideas:
- A card has a top-level schema version (
"version": "1.3"etc.) - Hosts support different subsets of elements/properties
- The safest approach for broad compatibility is to target 1.3 and avoid features not supported by your host(s)
Official references:
- Adaptive Cards documentation and schema explorer: https://adaptivecards.io/explorer/
- Adaptive Card Designer (interactive authoring): https://adaptivecards.io/designer/
Teams supports Adaptive Cards across bots, message extensions, and task modules. Actual feature support depends on the client and surface.
Recommendation: Target Adaptive Cards 1.3 unless you control all clients.
Docs: https://learn.microsoft.com/microsoftteams/platform/task-modules-and-cards/cards/cards-reference
Web Chat renders Adaptive Cards using the bundled Adaptive Cards renderer. Supported schema depends on the version shipped with Web Chat.
Recommendation: Treat 1.3 as the safe baseline unless you pin versions end-to-end.
Docs: https://www.npmjs.com/package/botframework-webchat
Webex bots explicitly support Adaptive Cards 1.3 with a documented subset of elements and properties.
Recommendation: Always target 1.3 for Webex bots.
Docs: https://developer.webex.com/messaging/docs/buttons-and-cards https://developer.webex.com/blog/webex-bots-support-for-buttons-and-cards-v1-3
Greentic messaging providers handle cards according to channel capability:
-
Full Adaptive Card support
- Card JSON is delivered as-is (or minimally transformed)
-
Partial / 1.3-only support
- Unsupported elements or properties are stripped or rewritten
- Schema version may be clamped to
1.3
-
No Adaptive Card support
- Card is downsampled to readable text/markdown
- Actions are rendered as textual options or links
- Inputs are summarized as expected fields
The goal is to preserve intent, even when rich UI is unavailable.
Default mode now centers on component config, not invocation defaults.
greentic-dev flow add-step \
--flow flows/main.ygtc \
--after start \
--node-id adaptive-card \
--operation card \
--payload '{"card_source":"asset","card_spec":{"asset_path":"card.json","template_params":{}},"locale":"en","mode":"renderAndValidate"}' \
--component oci://ghcr.io/greentic-ai/components/component-adaptive-card:latestDefault mode expects an explicit payload, so no interactive prompts are required.
Config mode exposes the full configuration surface.
greentic-dev flow add-step \
--flow flows/main.ygtc \
--after start \
--node-id adaptive-card \
--mode config \
--component oci://ghcr.io/greentic-ai/components/component-adaptive-card:latest \
--manifest component.manifest.jsonOr with a custom config flow file:
greentic-dev flow add-step \
--flow flows/main.ygtc \
--after start \
--node-id adaptive-card \
--mode config \
--config-flow ./dev_flows.custom \
--component oci://ghcr.io/greentic-ai/components/component-adaptive-card:latest \
--manifest component.manifest.jsonConfig mode now drives the canonical component config:
- selecting default source (
inline,asset,remote) - default inline card, local asset path, or remote card import ref
- multilingual support
- custom locales such as
en,en-GB,fr,de,nl - text direction (
ltr,rtl,auto) - validation and tracing defaults
The config flow supports conditional questions via show_if. A question is only asked (and required) when its show_if evaluates to true against the current answers, in order. If the controlling answer hasn't been asked yet, the dependent question is skipped.
Boolean form (always show or always hide):
{ "id": "debug", "type": "bool", "show_if": true }
{ "id": "internal_only", "type": "string", "show_if": false }Conditional on another answer (string/bool/number/choice):
{ "id": "mode", "type": "choice", "options": ["asset", "inline"] }
{ "id": "asset_path", "type": "string", "required": true,
"show_if": { "id": "mode", "equals": "asset" } }Notes:
show_ifis evaluated against answers collected so far; missing answers mean "hide".- Only
equalsis supported right now; anything else falls back to "show".
greentic-component store fetch \
--out . \
oci://ghcr.io/greentic-ai/components/component-adaptive-card:latestThis downloads the component artifact locally.
Example test with two sequential steps and state dump:
greentic-component test \
--wasm ./component_adaptive_card.wasm \
--manifest ./component.manifest.json \
--op card --input-json '{
"card_source": "asset",
"card_spec": {
"asset_path": "card.json",
"template_params": {}
},
"mode": "renderAndValidate",
"interaction": {
"enabled": true,
"interaction_type": "Submit",
"action_id": "save",
"card_instance_id": "card-1",
"raw_inputs": { "comment": "Hello from state" }
}
}' \
--step --op card --input-json '{
"card_source": "asset",
"card_spec": {
"asset_path": "card2.json",
"template_params": {}
},
"mode": "renderAndValidate",
"interaction": {
"enabled": true,
"interaction_type": "Submit",
"action_id": "save",
"card_instance_id": "card-1",
"raw_inputs": {}
}
}' \
--state-dump \
--pretty- Use the Adaptive Card Designer to validate schema version and supported elements
- Prefer schema 1.3 for cross-channel compatibility
- Avoid host-specific features unless you target a single channel
- Verify schema version compatibility
- Remove unsupported elements for the target host
- Run with
mode=validateand inspect validation output
- Confirm correct action type (
SubmitvsExecute) - Verify provider routing and permissions
- Check host limitations on interactive actions
- Adaptive Cards Explorer: https://adaptivecards.io/explorer/
- Adaptive Card Designer: https://adaptivecards.io/designer/
- Microsoft Teams Cards: https://learn.microsoft.com/microsoftteams/platform/task-modules-and-cards/cards/cards-reference
- Webex Adaptive Cards: https://developer.webex.com/messaging/docs/buttons-and-cards