Compose the Workflow
Separate deterministic backend orchestration from user-facing conversation and expose one useful result.
Composition is where modular assets become one capability. Use two orchestration layers for different jobs:
- A compound action coordinates uninterrupted backend execution.
- A conversation process coordinates interaction with a user.
The Golden Rule
Never place consecutive action activities in a conversation process without collecting a new required slot between them.
If no new required user input is needed, keep the backend sequence in one compound action. An Activity Confirmation Policy can protect that compound-action activity, but confirmation by itself does not justify exposing each backend step. Every action activity exposed in a conversation process can add output to the reasoning engine’s context; a compound action keeps its internal outputs behind one boundary and returns one shaped result.
Build the Compound Action
A compound action behaves like a typed backend function:
Define Input Arguments
Declare only the values the workflow needs:
The caller maps values into these inputs. Inside the compound action, reference them as data.feature_request_id and data.new_status.
Add Focused Steps
Use supported action blocks and control flow to:
- Look up the current record.
- Validate a deterministic precondition.
- Execute the write.
- Handle provider errors.
- Retrieve the final state.
- Notify a user when the ambient workflow requires a conversational handoff.
Give every useful internal result a descriptive output key.
Return One Public Result
Use return.output_mapper to cross the boundary:
Do not return lookup payloads, raw headers, debug data, or redundant intermediate responses unless the caller needs them.
A compound action invoked by a webhook or schedule has mapped trigger inputs and earlier step outputs, but no automatic meta_info.user. A conversational caller can provide user context.
Build the Conversation Process
A conversation process contains:
Use Action Activities for Operations
An action activity supplies:
- Input Mapping: parent data → typed action arguments.
- Output Mapping: action response → exposed process output.
- Confirmation or execution behavior supported by the activity.
For a compound action:
Then expose only the compound return:
Use Content Activities Deliberately
Use a Content Activity when you must display something explicitly inside the flow:
- Instructions the user must read before continuing.
- A knowledge article.
- A form.
- An intermediate result that must appear before the next step.
Do not add a final Content Activity merely to restate an action output that the reasoning engine can already present. A form is a special case: it must end its branch.
Add Another Conversational Step Only When Needed
Add another action activity only after the assistant collects a new required slot. If the flow needs confirmation, branching, or explicit display but no new required input between backend calls, keep those calls in one compound action and configure the policy or content around that compound-action boundary.
Understand Synchronous and Asynchronous Work
A compound-action activity configured to wait for completion makes its returned output available to later steps.
A compound-action activity configured as fire-and-forget starts backend work without making its output available downstream. Use it only when the conversation does not need the result.
Shape the Model Boundary
The reasoning engine can present a clean result well when keys carry meaning:
Avoid sending several implementation-shaped objects:
Use display_instructions_for_model for presentation preferences. Use mappings and deterministic checks for business correctness.
Build Along: Compose the PurpleSuite Workflow
Create a compound action named Update PurpleSuite feature request workflow with this public contract:
Follow one live feature request through the same three API calls and Agent Studio contracts in every chapter.
https://marketplace.moveworks.comX-Instance-ID.feature_request_id: data.selected_feature_request.id new_status: data.target_status.value
/api/purple-suite/community/feature_requestsDynamic resolver retrieves live candidates/api/purple-suite/community/feature_requests/{id}Compound action updates the selected record/api/purple-suite/community/feature_requests/{id}Compound action verifies the stored resultInside the compound action:
- Call
Update PurpleSuite feature request, which runsPATCH /api/purple-suite/community/feature_requests/{id}. - Call
Get PurpleSuite feature request, which runsGET /api/purple-suite/community/feature_requests/{id}for the same ID. - Handle provider errors without exposing credentials or raw headers.
- Return one
feature_requestobject containingid,name, andstatus.
Then create a conversation process that:
- Collects
selected_feature_request. - Collects
target_status. - Applies confirmation to the compound-action activity.
- Maps both slot values into the compound action.
- Exposes the shaped return for the assistant to present.
Your checkpoint is one conversational action boundary. The PATCH and verification operations remain inside the compound action.
The list GET is not part of this compound action. It already ran in the dynamic resolver before confirmation. A successful conversational run therefore produces the call order shown in the trace: list GET, update PATCH, then verification GET.