Compound Action Patterns

View as Markdown

This document’s purpose is to accelerate your development process by providing a collection of reusable patterns for common tasks.

Instead of showcasing entire** end-to-end** use cases, this guide focuses on individual, common “steps” you’ll encounter while building. For each pattern, we recommend the most efficient method, whether it’s an LLM action, a Moveworks Data Mapper expression, a DSL query, or a Python Script.

Let’s dive into the patterns.

Performing Actions in Batch

Problem: You want to perform a series of actions repetitively for a list elements. For example, sending a notification to a group of users.

List of users

1{
2 "data": {
3 "email_list": [
4 "jane.doe@example.com",
5 "john_smith88@gmail.com",
6 "alice.w@yahoo.com",
7 "support@mybusiness.net",
8 "data-report-user@company.org",
9 "tester_01@outlook.com"
10 ]
11 }
12}

Usage Compound Action

1steps:
2 - action:
3 action_name: mw.batch_get_users_by_email
4 output_key: list_of_users
5 input_args:
6 user_emails: data.email_list
7 - for:
8 output_key: list_of_notifications
9 each: record
10 in: data.list_of_users.user_records
11 index: idx
12 steps:
13 - notify:
14 output_key: notification_output
15 recipient_id: record.lookup_id
16 message:
17 RENDER():
18 args:
19 user_name: record.user.full_name
20 template: Hi {{user_name}}, you have not submitted your project update this week. Please do before the end of the day!
21 - action:
22 action_name: do_some_action_for_user
23 output_key: action_result
24 input_args:
25 user: record.user
26...

Deduplicating a List

Problem: You have a list that contains duplicate values, and you need a list with only unique elements.

Deduplicating a list of scalars

Input

1{
2 "data": {
3 "duplicated_fruit_list": ["apple", "banana", "cherry", "apple", "banana", "date"]
4 }
5}
1seen = set()
2unique = []
3for x in elements:
4 if x in seen:
5 continue
6 seen.add(x)
7 unique.append(x)
8return unique

Usage in Compound Action

1steps:
2 - action:
3 name: deduplicate_list
4 output_key: deduplicate_list_result
5 input_args:
6 elements: data.duplicated_fruit_list
7 - return:
8 output_mapper:
9 unique_list: steps.deduplicate_list

Result

1{
2 "duplicated_fruit_list": ["apple", "banana", "cherry", "date"]
3}

Deduplicating a list of objects

In this case we will deduplicating a list of objects that have the same email key

1seen = set()
2out = []
3for obj in elements:
4 if not isinstance(obj, dict) or key_field not in obj:
5 continue
6 k = obj[key_field]
7 if k in seen:
8 continue
9 seen.add(k)
10 out.append(obj)
11return out

Usage in Compound Action

1steps:
2 - action:
3 name: deduplicate_object_list
4 output_key: deduplicate_list_result
5 input_args:
6 elements: data.input_list
7 key_field: '''email'''
8 - return:
9 output_mapper:
10 unique_list: steps.deduplicate_list

Sort Alphabetically

Problem: You need to provide a list of elements sorted alphabetically

Input Arguments

1{
2 "data":{
3 "fruits": ["red", "green", "blue", "yellow", "purple"]
4 }
5}

Compound Action

1steps:
2 - action:
3 name: enter_fruits_into_system
4 ouput_key: fruits_result
5 inputs_args:
6 sorted_fruits:
7 SORT():
8 items: data.fruits
9 key: item

Result

1{
2 "sorted_fruits": [
3 "blue",
4 "green",
5 "purple",
6 "red",
7 "yellow"
8 ]
9}

Sort Timestamps

Problem: You want to sort a list of based on the timestamp

Sorting a list of timestamps

input

1{
2 "data": {
3 "ts": [
4 "Monday, Sep 22, 2025 at 8:15 AM MDT",
5 "Saturday, Sep 20, 2025 at 10:30 AM MDT",
6 "Friday, Sep 19, 2025 at 5:07 PM MDT",
7 "Friday, Sep 19, 2025 at 9:00 PM MDT"
8 ]
9 }
10}

Compound Action

1steps:
2 - action:
3 name: enter_timestamps
4 ouput_key: timestamps_result
5 inputs_args:
6 sorted_timestamps:
7 SORT():
8 items: data.ts
9 key: item.$PARSE_TIME()

Result

1{
2 "sorted_timestamps": [
3 "Friday, Sep 19, 2025 at 5:07 PM MDT",
4 "Friday, Sep 19, 2025 at 9:00 PM MDT",
5 "Saturday, Sep 20, 2025 at 10:30 AM MDT",
6 "Monday, Sep 22, 2025 at 8:15 AM MDT"
7 ]
8}

Sorting a list of objects by timestamp

Input

1{
2 "data": {
3 "finances": [
4 {
5 "id": "txn_k5p1",
6 "ts": "2025-09-20T10:30:00-06:00",
7 "amount": 2500.0
8 },
9 {
10 "id": "txn_z7h3",
11 "ts": "2025-09-22T08:15:00-06:00",
12 "amount": -29.99
13 },
14 {
15 "id": "txn_8x4f",
16 "ts": "2025-09-19T17:14:04-06:00",
17 "amount": -8.5
18 },
19 {
20 "id": "txn_a2d9",
21 "ts": "2025-09-19T21:00:00-06:00",
22 "amount": 150.75
23 }
24 ]
25 }
26}

Compound Action

1steps:
2 - action:
3 name: enter_finances
4 ouput_key: finances_result
5 inputs_args:
6 sorted_financials:
7 SORT():
8 items: data.finances
9 key: item.ts.$PARSE_TIME()

Result

1{
2 "sorted_financials": [
3 {
4 "amount": -8.5,
5 "id": "txn_8x4f",
6 "ts": "2025-09-19T17:14:04-06:00"
7 },
8 {
9 "amount": 150.75,
10 "id": "txn_a2d9",
11 "ts": "2025-09-19T21:00:00-06:00"
12 },
13 {
14 "amount": 2500,
15 "id": "txn_k5p1",
16 "ts": "2025-09-20T10:30:00-06:00"
17 },
18 {
19 "amount": -29.99,
20 "id": "txn_z7h3",
21 "ts": "2025-09-22T08:15:00-06:00"
22 }
23 ]
24}

Easiest way to multiline string usage in YAML

Problem: You want to a multiline string’s structure to be maintained

Solution: Use Render() and the | character with your template value indented

Compound Action

1result:
2 display_instruction_for_model:
3 RENDER():
4 template: |
5 Each row = one unique order line item in a customer’s purchase.
6 Uniqueness: LINE_ITEM_ID is the primary key (unique per row).
7 Aggregation grain:
8 - Line item–level -> count rows / COUNT(DISTINCT LINE_ITEM_ID)
9 - Order-level -> COUNT(DISTINCT ORDER_ID)
10 - Customer-level -> COUNT(DISTINCT CUSTOMER_ID)
11 - Product-level -> COUNT(DISTINCT PRODUCT_ID)
12 Rule: Always aggregate at the appropriate grain to ensure metrics align correctly with the business question.