Help

Airscript Functions

Airgentic Help

Coming Soon — This feature is currently in development and not yet available. This guide is a preview of what's coming.

This page is the full parameter-level reference for the air object available inside AirScript functions. Your function receives air as the only argument: async def run(air):.


Table of Contents


Properties

Property Description
air.args Dictionary of arguments passed to the function by the LLM (based on your schema parameters).
air.loop_back Set to True to have the agent process another turn after this function returns. Default is False.
air.chat_history_html The conversation history formatted as HTML (useful for emails or summaries).

Messaging

await air.send_message_to_user(text, show_rating=False, continue_message=False, no_typewriter=False)

Send a chat message directly to the user (bypasses the LLM).

Parameter Type Description
text str The message to display to the user (supports HTML).
show_rating bool, optional Show rating icons after the message. Default: False.
continue_message bool, optional If True, this message continues a previous one (no new message bubble). Default: False.
no_typewriter bool, optional If True, display instantly without typewriter animation. Useful for HTML content. Default: False.
# Simple text message
await air.send_message_to_user("Your order has been placed successfully!")

# HTML content displayed instantly (no typewriter effect)
await air.send_message_to_user(
    "<div style='padding: 10px;'><h3>Results</h3><p>Found 5 items.</p></div>",
    no_typewriter=True
)

air.send_interim_message_to_user(message=None)

Show a "Please wait..." style message to the user while your function runs.

Parameter Type Description
message str, optional Custom message to display (supports HTML). If not provided, a random message is selected from the platform's predefined set (e.g. "Just a moment while I look that up...").
air.send_interim_message_to_user()  # Random message
air.send_interim_message_to_user("Checking the weather forecast...")  # Custom message

air.reply_to_llm(message)

Send a result back to the LLM so it can formulate an appropriate response to the user. This is how your function communicates outcomes (success, failure, data) to the AI.

Parameter Type Description
message str The text to send back to the LLM. Plain text only.
location = air.args.get("location")
if not location:
    air.reply_to_llm("No location was provided. Please ask the user for a location.")
    return

# ... fetch weather data ...
air.reply_to_llm(f"The weather in {location} is 72°F and sunny.")

When to use this:

  • After validation failures — Tell the LLM what's missing so it can ask the user
  • After successful operations — Confirm what happened
  • After fetching data — Pass the data to the LLM

Important: Every function must call air.reply_to_llm() unless you call air.search() or air.search_and_answer(), which handle this automatically. If you forget to call it, the next LLM request will fail.


await air.search(query, url_scopes=None, field_filters=None)

Search the knowledge base and retrieve relevant information. A small selection of the most relevant results is provided back to the current agent as context, which it can use to handle the enquiry.

Parameter Type Description
query str The search query.
url_scopes list, optional List of URL prefixes to constrain search results (e.g. ["https://example.com/products/"]).
field_filters list, optional List of dicts with field and value keys to filter by indexed metadata fields.
await air.search("return policy for damaged items")

# Search within a specific section of the site
await air.search("shipping options", url_scopes=["https://example.com/help/"])

# Search for a specific product model
await air.search("battery replacement", field_filters=[{"field": "product_model", "value": "XYZ-100"}])

await air.search_and_answer(query, url_scopes=None, field_filters=None)

Search the knowledge base and hand the results to the Frontline agent, which generates and streams an answer to the user. The search results themselves are not shown to the user.

Parameter Type Description
query str The search query.
url_scopes list, optional List of URL prefixes to constrain search results.
field_filters list, optional List of dicts with field and value keys to filter by indexed metadata fields.
air.send_interim_message_to_user()
await air.search_and_answer("How do I reset my password?")

# Search with URL scope
await air.search_and_answer("installation guide", url_scopes=["https://example.com/docs/"])

# Search for compatible products
await air.search_and_answer(
    "compatible accessories",
    field_filters=[{"field": "compatible_products", "value": "iPhone 15"}]
)

await air.search_with_scopes_and_answer(search_query, scope=None)

A Global Function that searches the knowledge base within a specific URL scope and answers the user's question. Useful when you need to constrain results to a particular section of your site (e.g. only search within /products/ or /support/).

Parameter Type Description
search_query str The search query to find relevant information.
scope str, optional URL prefix to constrain search results.
async def run(air):
    search_query = air.args.get("search_query", "").strip()
    scope = air.args.get("scope", "").strip()

    air.send_interim_message_to_user()
    url_scopes = [scope] if scope else None
    await air.search_and_answer(query=search_query, url_scopes=url_scopes)

await air.search_with_product_model_scope(product_model)

A Global Function that searches the knowledge base for information about a specific product model. Filters results to only include content matching the product_model metadata field.

Parameter Type Description
product_model str The product model name or number (e.g. "YAS-109", "Model X500").
async def run(air):
    product_model = air.args.get("product_model", "").strip()

    air.send_interim_message_to_user()
    await air.search_and_answer(
        query=product_model,
        field_filters=[{"field": "product_model", "value": product_model}]
    )

await air.search_with_compatible_products_scope(compatible_products)

A Global Function that searches the knowledge base for products or accessories compatible with a specific model. Filters results using the compatible_products metadata field.

Parameter Type Description
compatible_products str The product model to find compatible items for.
async def run(air):
    compatible_products = air.args.get("compatible_products", "").strip()

    air.send_interim_message_to_user()
    await air.search_and_answer(
        query=compatible_products,
        field_filters=[{"field": "compatible_products", "value": compatible_products}]
    )

Email

await air.send_email(to, subject, body, cc=None, bcc=None)

Send an email. Returns True on success, False on failure. Reply-to is set by the system.

Parameter Type Description
to list or str Recipient email address(es). Can be a Python list (e.g. ["a@x.com", "b@x.com"]) or a single string.
subject str Email subject line.
body str Email body as HTML. Use <p>, <br>, etc. for formatting.
cc list or str, optional CC recipient(s). Same list-or-string format as to.
bcc list or str, optional BCC recipient(s). Same list-or-string format as to.
success = await air.send_email(
    to="support@example.com",
    subject="New enquiry from website",
    body=f"<p>A customer needs assistance:</p>{air.chat_history_html}",
    cc=["manager@example.com"]
)
if success:
    air.reply_to_llm("Email sent successfully.")
else:
    air.reply_to_llm("Failed to send email.")

HTTP

air.http_get() and air.http_post() are convenience helpers for the most common cases — they return the response body as a string and handle errors simply. If you need more control (e.g. checking the HTTP status code, or using methods like PUT, PATCH, or DELETE), use air.http_request() instead.

await air.http_get(url, params=None, headers=None)

Make an HTTP GET request. Returns the response body as a string, or None on error. Subject to timeout and response size limits.

Parameter Type Description
url str The URL to fetch.
params dict, optional Query string parameters, e.g. {"q": "search"}.
headers dict, optional HTTP headers to include in the request.
response = await air.http_get(
    "https://api.weather.gov/points/40.7128,-74.0060",
    headers={"User-Agent": "MyApp/1.0"}
)
if response:
    data = json.loads(response)
    air.reply_to_llm(f"Location: {data['properties']['relativeLocation']['properties']['city']}")

await air.http_post(url, data=None, headers=None)

Make an HTTP POST request. The data parameter is sent as JSON. Returns the response body as a string, or None on error. Subject to timeout and response size limits.

Parameter Type Description
url str The URL to post to.
data dict, optional Payload to send as JSON in the request body.
headers dict, optional HTTP headers to include in the request.
response = await air.http_post(
    "https://api.example.com/orders",
    data={"product_id": "12345", "quantity": 2},
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
if response:
    result = json.loads(response)
    air.reply_to_llm(f"Order created: {result['order_id']}")

await air.http_post_form(url, form_data=None, headers=None)

Make an HTTP POST request with form-encoded data (application/x-www-form-urlencoded). Use this for legacy APIs or WordPress AJAX endpoints that expect form data rather than JSON.

Parameter Type Description
url str The URL to post to.
form_data dict, optional Key-value pairs to send as form data.
headers dict, optional HTTP headers to include in the request.

Returns: A dict with:
- status (int): HTTP status code
- ok (bool): True if status is 2xx
- body (str): Response body as string

response = await air.http_post_form(
    "https://example.com/wp-admin/admin-ajax.php",
    form_data={"action": "get_stores", "lat": -33.8688, "lng": 151.2093},
    headers={"User-Agent": "MyApp/1.0"}
)
if response and response["ok"]:
    data = json.loads(response["body"])

await air.http_request(method, url, data=None, headers=None)

Make an HTTP request with any method (GET, POST, PUT, PATCH, DELETE). Returns a dict with status information, or None on network/timeout error. Use this when you need to check the status code or use methods other than GET/POST.

Parameter Type Description
method str HTTP method: "GET", "POST", "PUT", "PATCH", "DELETE".
url str The URL to request.
data dict, optional Payload to send as JSON (for POST, PUT, PATCH).
headers dict, optional HTTP headers to include in the request.

Returns: A dict with:
- status (int): HTTP status code (e.g. 200, 404, 500)
- ok (bool): True if status is 2xx
- body (str): Response body as string

resp = await air.http_request(
    "PATCH",
    "https://api.example.com/contacts/123",
    data={"phone": "+1234567890"},
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
if resp and resp["ok"]:
    contact = json.loads(resp["body"])
    air.reply_to_llm(f"Contact updated: {contact['id']}")
else:
    air.log(f"API error: {resp}")
    air.reply_to_llm("Failed to update contact.")

Location & Maps

await air.geocode(location_name)

Geocode a location name (e.g. "Sydney" or "10 Downing Street") to latitude/longitude coordinates using Google Maps.

Parameter Type Description
location_name str The location to geocode (address, city name, landmark, etc.).

Returns: A dict with:
- lat (float): Latitude
- lng (float): Longitude
- address (str): Formatted address from Google

Returns None if geocoding fails.

Requires: The google_maps_api_key AirScript variable must be set (mark as secret).

geo = await air.geocode("Melbourne, Australia")
if geo:
    air.log(f"Coordinates: {geo['lat']}, {geo['lng']}")
    air.log(f"Address: {geo['address']}")
else:
    air.reply_to_llm("Could not find that location.")

await air.send_map_markers(locations, map_provider="google")

Send map marker data to display on the frontend map widget. Each marker appears as a pin on the map.

Parameter Type Description
locations list List of location dicts, each containing name, lat, and lng.
map_provider str, optional Map provider to use. Default: "google".
locations = [
    {"name": "Sydney Opera House", "lat": -33.8568, "lng": 151.2153},
    {"name": "Harbour Bridge", "lat": -33.8523, "lng": 151.2108}
]
await air.send_map_markers(locations)

LLM Generation

await air.llm_generate(prompt, stream_to_user=True, include_history=True)

Generate text using an LLM with the given prompt. Useful for summarizing data, generating personalized responses, or creating formatted output.

Parameter Type Description
prompt str The system/instruction prompt for the LLM.
stream_to_user bool, optional If True (default), stream the response to the user. If False, return the text without displaying it.
include_history bool, optional If True (default), include the conversation history with the request. Set to False for standalone generation tasks that don't need context.

Returns: The generated text string, or None on error.

# Stream a summary to the user (includes conversation context)
summary_prompt = f"""Summarize these search results in 2-3 sentences:
{json.dumps(results)}"""
await air.llm_generate(summary_prompt, stream_to_user=True)

# Generate text without streaming (for internal use)
response = await air.llm_generate(
    "Classify this query as 'sales' or 'support': " + user_query,
    stream_to_user=False
)
if "sales" in response.lower():
    # Route to sales...

# Standalone generation without conversation history
formatted = await air.llm_generate(
    f"Format this data as a bullet list: {data}",
    stream_to_user=False,
    include_history=False
)

Utilities

air.log(message)

Log a message for debugging. Messages appear in the trace log panel when testing your agent in the admin console.

Parameter Type Description
message str The message to log.
air.log(f"Received location: {air.args.get('location')}")

air.get_config(key, default=None)

Get a configuration value. You can read:

  • AirScript variables defined in the admin console for this agent (Edit Agent → AirScript Variables). Use these for API URLs, keys, and other per-agent settings.
  • Values set in your function via air.set_config() (persist for the duration of the conversation).
  • Permitted system config keys.

Returns default if the key is not found or not permitted.

Parameter Type Description
key str The config key to read.
default any, optional Value to return if the key is not found or not permitted.
api_calls = air.get_config("api_call_count", 0)
air.log(f"API calls so far: {api_calls}")

air.set_config(key, value)

Set a custom configuration value that persists for the current user's session only. Use this to store state between function calls within the same conversation.

Parameter Type Description
key str The config key to set.
value any The value to store.

Important: Values set with set_config() are:
- Available for subsequent function calls within the same conversation
- Not shared across different users
- Not persisted after the conversation ends

For permanent configuration (API keys, email addresses, etc.), use AirScript Variables in the admin console instead — see Editing an Agent.

count = air.get_config("api_call_count", 0)
air.set_config("api_call_count", count + 1)

Tips

  • Your function must be defined as async def run(air):. Use await when calling async methods such as air.search(), air.send_message_to_user(), air.send_email(), air.http_get(), air.http_post(), and air.http_request().
  • The json module is available without importing (e.g. json.loads(), json.dumps()). Use it to parse API responses or build structured data.
  • The following modules are all available without importing: time, datetime, zoneinfo, calendar, re, math, decimal, base64, hashlib, hmac, collections, itertools, functools, string, textwrap, unicodedata, and urllib.parse. See the AirScript Reference for details on each.
  • See AirScript Reference for the full list of Python functions and modules you can use.

← Back to Functions overview

You have unsaved changes