Skip to main content

REFERENCE

Developer Reference

Authentication, APIs, SDKs, Flow Agent processors and parameter resolution, in full.

Expression built-in functions

Asgard's Expression system provides eight functions for handling conversation history, data conversion and encoding inside dynamic content.

  1. The functions​

    Conversation history​

    history​

    Returns the conversation history over an index range.

    Syntax:

    history(start, end)

    Parameters:

    • start (number): where to start, from 0, with negative values counting from the end
    • end (number): where to stop, inclusive, with negative values counting from the end

    Returns:

    • string: the history as plain text, one message per line

    Examples:

    // the three messages at indexes 0, 1 and 2
    history(0, 2)

    // the last three messages
    history(-3, -1)

    // everything
    history(0, -1)

    The returned format:

    bot: Hi, how can I help you?
    user: Hello, I need assistance with my order.
    bot: Okay, please provide your order number.

    historySize​

    Returns how many messages the channel's history holds.

    Syntax:

    historySize()

    Returns:

    • number: the message count

    Example:

    // returns a number, for example 5
    historySize()

    Data handling​

    urlEncode​

    URL-encodes a string.

    Syntax:

    urlEncode(val)

    Parameters:

    • val (string): the string to encode

    Returns:

    • string: the encoded result

    Examples:

    // "hello%20world"
    urlEncode('hello world')

    // "%E6%90%9C%E5%B0%8B%E9%97%9C%E9%8D%B5%E5%AD%97"
    urlEncode('搜尋關鍵字')

    // URL-encode the previous message
    urlEncode(prevMessage)

    vecToStr​

    Converts a vector array into a string.

    Syntax:

    vecToStr(vector, prefix, suffix, delimiter)

    Parameters:

    • vector (array<number>): the vector array
    • prefix (string): the opening character
    • suffix (string): the closing character
    • delimiter (string): the separator

    Returns:

    • string: the converted string

    Examples:

    // "{1,2,3}"
    vecToStr([1, 2, 3], '{', '}', ',')

    // "[0.1|0.5|0.8]"
    vecToStr([0.1, 0.5, 0.8], '[', ']', '|')

    xpathExtract​

    Looks up a value in an XML document with XPath.

    Syntax:

    xpathExtract(xml, path)

    Parameters:

    • xml (string): the XML document
    • path (string): the XPath query

    Returns:

    • string: the inner text of every matching element, separated by newlines

    Examples:

    const xml = '<root><item>1</item><item>2</item></root>'
    // "1\n2"
    xpathExtract(xml, '/root/item')

    // every result title
    xpathExtract(responseXml, '//result/title')

    Date and time​

    isoNow​

    Returns the current date and time in a given timezone, as an RFC3339 string.

    Syntax:

    isoNow(timezone)

    Parameters:

    • timezone (string): an IANA timezone name

    Returns:

    • string: the current date and time in RFC3339

    Examples:

    // "2025-05-27T01:08:44+08:00"
    isoNow('Asia/Taipei')

    // "2025-05-26T17:08:44Z"
    isoNow('UTC')

    // "2025-05-26T13:08:44-04:00"
    isoNow('America/New_York')

    isoToday​

    Returns the current date in a given timezone, as an RFC3339 string.

    Syntax:

    isoToday(timezone)

    Parameters:

    • timezone (string): an IANA timezone name

    Returns:

    • string: the current date in RFC3339

    Examples:

    // "2025-05-27"
    isoToday('Asia/Taipei')

    // "2025-05-26"
    isoToday('UTC')

    // "2025-05-26"
    isoToday('America/New_York')
  2. Fuller examples​

    Analysing and summarising a conversation​

    // look at how the conversation is going
    (() => {
    const totalMessages = historySize();
    if (totalMessages === 0) return 'no conversation yet';

    // take the recent messages to analyse
    const recentCount = Math.min(10, totalMessages);
    const recentHistory = history(-recentCount, -1);

    const lines = recentHistory.split('\n');
    const userMessages = lines.filter(line => line.startsWith('user:')).length;
    const botMessages = lines.filter(line => line.startsWith('bot:')).length;

    return `Across the last ${recentCount} messages: ${userMessages} from the user, ${botMessages} from the bot`;
    })()

    Integrating with an API​

    // build a query URL
    (() => {
    const keyword = prevMessage || '';
    const encodedQuery = urlEncode(keyword);
    const timestamp = isoNow('UTC');

    // build the query string
    const params = [`q=${encodedQuery}`, `timestamp=${timestamp}`, `channel=${customChannelId || 'default'}`].join('&');

    return `https://api.example.com/search?${params}`;
    })()

    Parsing XML​

    // handle a richer XML response
    (() => {
    if (!xmlResponse) return 'no XML data';

    try {
    const titles = xpathExtract(xmlResponse, '//result/title');
    const prices = xpathExtract(xmlResponse, '//result/price');

    if (!titles) return 'no results';

    const titleList = titles.split('\n');
    const priceList = prices ? prices.split('\n') : [];

    let result = 'Results:\n';
    titleList.forEach((title, index) => {
    const price = priceList[index] || 'price unknown';
    result += `${index + 1}. ${title} - ${price}\n`;
    });

    return result;
    } catch (e) {
    return 'XML parse error';
    }
    })()

    Handling vectors​

    // format a vector for several consumers
    (() => {
    const userVector = [0.1, 0.5, 0.8, 0.2];
    const systemVector = [0.2, 0.4, 0.7, 0.3];

    const formats = {
    json: vecToStr(userVector, '[', ']', ','),
    csv: vecToStr(userVector, '', '', ','),
    sql: vecToStr(userVector, '(', ')', ','),
    };

    return `Formatted:
    JSON: ${formats.json}
    CSV: ${formats.csv}
    SQL: ${formats.sql}`;
    })()

    Timestamped logging​

    // build a log line with a timestamp
    (() => {
    const timezone = 'Asia/Taipei';
    const now = isoNow(timezone);
    const today = isoToday(timezone);

    const messageCount = historySize();
    const hasError = prevError ? true : false;

    const logEntry = {
    date: today,
    timestamp: now,
    messages: messageCount,
    hasError: hasError,
    channel: customChannelId || 'unknown',
    };

    return `[${now}] log: channel ${logEntry.channel}, ${logEntry.messages} messages${hasError ? ', with an error' : ''}`;
    })()
  3. Performance​

    Cache what you call​

    // ✅ cache the values you reuse rather than calling again
    (() => {
    const messageCount = historySize(); // called once
    const timezone = 'Asia/Taipei';
    const currentTime = isoNow(timezone); // called once

    if (messageCount === 0) {
    return `[${currentTime}] a new conversation`;
    }

    const recentHistory = messageCount > 5 ? history(-5, -1) : history(0, -1);

    return `[${currentTime}] ${messageCount} messages\n${recentHistory}`;
    })()

    Call conditionally​

    // ✅ avoid calls you do not need
    (() => {
    // check the basics first
    if (!prevMessage) return 'nothing to process';

    // only encode when encoding is needed
    const needsEncoding = /[^\w\s]/.test(prevMessage);
    const processedMessage = needsEncoding ? urlEncode(prevMessage) : prevMessage;

    return `Result: ${processedMessage}`;
    })()

    These functions cover the data handling an Expression needs for conversation logic and format conversion.

Ready to get started?

Want to see how Asgard fits your team? Talk to us.

Contact us