Task: workarena.servicenow.create-user
Goal: Create a new user with a value of "3341048433170662999" for field "User ID", a value of "Gonzalez-Thomas" for field "Last name", a value of "Dawn-Amy" for field "First name", a value of "dawn-amy.gonzalez-thomas@workarena.com" for field "Email", a value of "(514) 667-8215" for field "Business phone", a value of "saltatorial scribeship nonfacultative Ricinulei cassiduloid" for field "Title", a value of "false" for field "Locked out", a value of "(514) 244-3294" for field "Mobile phone", a value of "Outlook" for field "Calendar integration", a value of "Europe/Madrid" for field "Time zone", a value of "true" for field "Active", a value of "false" for field "Password needs reset", and a value of "MM-dd-yyyy" for field "Date format".
Task configuration: {'table_name': 'sys_user', 'task_fields': ['user_name', 'last_name', 'first_name', 'email', 'phone', 'title', 'locked_out', 'mobile_phone', 'calendar_integration', 'time_zone', 'active', 'password_needs_reset', 'date_format'], 'template_record': {'active': 'true', 'avatar': '', 'building': '', 'calendar_integration': 'Outlook', 'city': '', 'company': {'display_value': 'ACME North America', 'link': 'https://dev215901.service-now.com/api/now/table/core_company/31bea3d53790200044e0bfc8bcbe5dec'}, 'cost_center': {'display_value': 'Engineering', 'link': 'https://dev215901.service-now.com/api/now/table/cmn_cost_center/d9d07bddc0a80a647cf932056ed24652'}, 'country': None, 'date_format': 'MM-dd-yyyy', 'default_perspective': '', 'department': 'Development', 'email': 'dawn-amy.gonzalez-thomas@workarena.com', 'employee_number': '', 'enable_multifactor_authn': 'false', 'failed_attempts': '', 'first_name': 'Dawn-Amy', 'gender': 'Female', 'home_phone': '', 'internal_integration_user': 'false', 'introduction': None, 'last_login': '', 'last_login_time': '', 'last_name': 'Gonzalez-Thomas', 'ldap_server': '', 'location': {'display_value': '946 Donax Avenue, Imperial Beach,CA', 'link': 'https://dev215901.service-now.com/api/now/table/cmn_location/f9084ba00a0a0b910060ba2ce83f882b'}, 'locked_out': 'false', 'manager': '', 'middle_name': '', 'mobile_phone': '(514) 244-3294', 'name': 'Kerry Evertt', 'notification': 'Enable', 'password_needs_reset': 'false', 'phone': '(514) 667-8215', 'photo': '', 'preferred_language': 'English', 'roles': '', 'schedule': '', 'source': '', 'state': '', 'street': '', 'sys_class_name': 'User', 'sys_created_by': 'admin', 'sys_created_on': '2012-02-17 19:04:50', 'sys_domain': {'display_value': 'global', 'link': 'https://dev215901.service-now.com/api/now/table/sys_user_group/global'}, 'sys_domain_path': '/', 'sys_id': '82826bf03710200044e0bfc8bcbe5d80', 'sys_mod_count': '6', 'sys_tags': '', 'sys_updated_by': 'developer.program.hop@snc', 'sys_updated_on': '2024-03-09 12:33:10', 'time_format': None, 'time_zone': 'Europe/Madrid', 'title': 'saltatorial scribeship nonfacultative Ricinulei cassiduloid', 'user_name': '3341048433170662999', 'user_password': '********', 'vip': 'false', 'web_service_access_only': 'false', 'zip': ''}}

Validation code:
import json
import os
import re
import urllib.parse as parse
from typing import Any, Dict, List

import requests


def validate(messages: List[Dict[str, str]], config: Dict[str, Any]) -> int:
    """
    Validate that a record was created with expected field values.
    Returns 1 on success, else 0.

    Expected config keys:
      - task_fields (list[str])                  # fields to validate
      - template_record (dict)                   # expected display values for those fields
    """

    # Check whether we have the necessary information to validate
    print(config)
    if "table_name" not in config or "task_fields" not in config or "template_record" not in config:
        raise ValueError("Target must contain 'table_name', 'task_fields' and 'template_record'")

    # Check whether we have messages
    if not messages:
        raise ValueError("Messages must not be empty")

    # Extract last message content
    content = messages[-1].get("content", "")

    # Extract all URLs — markdown links first, then bare URLs
    seen = set()
    urls = []
    for m in re.finditer(r"\[.*?\]\((https?://[^)]+)\)", content):
        url = m.group(1)
        if url not in seen:
            seen.add(url)
            urls.append(url)
    for m in re.finditer(r"https?://\S+", content):
        url = m.group(0).rstrip(")].,")
        if url not in seen:
            seen.add(url)
            urls.append(url)
    if not urls:
        return 0

    def extract_sys_id(url: str) -> str | None:
        """
        Return the 32-hex sys_id from a ServiceNow URL, or None if not found.
        Handles encoded target URLs like .../params/target/incident.do%3Fsys_id%3D<id>
        """
        # Unquote repeatedly (some SN URLs are doubly-encoded)
        for _ in range(3):
            new = parse.unquote(url)
            if new == url:
                break
            url = new

        m = re.search(r"(?:[?&])sys_id=([0-9a-f]{32})", url, re.IGNORECASE)
        return m.group(1) if m else None

    sys_id = None
    for raw_url in urls:
        current_url = parse.urlunparse(parse.urlparse(parse.unquote(raw_url)))
        sys_id = extract_sys_id(current_url)
        if sys_id:
            break
    if not sys_id:
        return 0

    # Query instance to get record
    response = requests.request(
        method="GET",
        url=os.getenv("SERVICENOW_INSTANCE_URL", "").rstrip("/") + f"/api/now/table/{config['table_name']}",
        headers={
            "Content-Type": "application/json",
            "Accept": "application/json",
            **json.loads(os.getenv("SERVICENOW_EXTRA_HTTP_HEADERS", "{}")),
        },
        params={
            "sysparm_query": f"sys_id={sys_id}",
            "sysparm_display_value": "true",
            "sysparm_fields": ",".join(config["task_fields"]),
        },
    )
    response.raise_for_status()
    if type(response) == dict:
        record = response
    else:
        record = response.json()

    if "result" in record:
        record = record["result"]

    if isinstance(record, list):
        if len(record) == 0:
            return 0
        record = record[0]

    # Check that the record matches the expected values
    for f in config["task_fields"]:
        val = record.get(f)
        # Handle nested display_value dicts from the API
        if isinstance(val, dict) and "display_value" in val:
            val = val["display_value"]
        if val is None:
            return 0
        if val != config["template_record"][f]:
            return 0
    return 1