Skip to main content
SLang files can import built-in modules and local helper modules. Built-ins are imported by name, and local modules are imported by path.

Built-In Modules

The current built-in modules are:
ModuleImportExport
AIimport "AI"AI.prompt(message := "text")
HTTPimport "HTTP"HTTP.fetch(url := "https://api.example.com")
import "AI" is shorthand for import "slang:AI". You can also alias built-ins with as.
import "slang:AI" as Assistant

action DraftReply(message: TEXT): TEXT
  body
    return Assistant.prompt(
      message := message,
      system := "Write a concise support reply."
    )

AI Prompting

AI.prompt generates text. It accepts a required user message plus optional system instructions, FILE attachments, provider/model overrides, and max token settings.
import "AI"

entity Document
  fields
    title: TEXT
    sourceFile: FILE
    summary: TEXT?

action SummarizeDocument(document: Document): Document
  body
    summary := AI.prompt(
      message := "Summarize this document in five bullet points.",
      system := "You are a precise document analysis assistant.",
      attachments := [document.sourceFile],
      provider := "openai",
      maxTokens := 500
    )
    update document {
      summary := summary
    }
    return document
Supported providers are openai and anthropic. If you omit provider, SLang uses the default configured provider. If you omit modelName, the module uses the default model for that provider. Attachments must be FILE values. Store uploaded files before saving them on an entity; pass either the uploaded file or the stored file to AI.prompt. When building dynamic AI prompts, use template strings instead of chaining many + operators. This is especially useful when mixing literals, fields, and values accumulated in a loop.
import "AI"

entity User
  subject
  identity email
  fields
    email: EMAIL

entity Category
  fields
    name: TEXT

entity Task
  fields
    title: TEXT
    description: TEXT?

relation User[categories] 1 --- * Category[owner]
relation User[tasks] 1 --- * Task[owner]

action ClassifyTask(task: Task, user: User): TEXT
  body
    categories := pageOf Category where owner == user
    categoryNames := ""
    for category in categories.items
      categoryNames := "${categoryNames}${category.name}, "
    prompt := "Classify this task into one of these categories: ${categoryNames}
Task title: ${task.title}
Task description: ${task.description}"
    return AI.prompt(
      message := prompt,
      system := "Return only the best matching category name."
    )

HTTP Fetching

HTTP.fetch makes outbound HTTP or HTTPS calls and returns an object with status, headers, and optional body.
import "HTTP"

action CreateRemoteTicket(baseUrl: TEXT, title: TEXT): UNKNOWN
  body
    response := HTTP.fetch(
      url := baseUrl + "/tickets",
      method := "POST",
      headers := {
        "authorization" := "Bearer example-token"
      },
      query := {
        source := "sutro"
      },
      body := {
        title := title
      }
    )
    return response
To upload a raw binary file, pass a FILE as the top-level body. HTTP.fetch sends the file bytes unchanged and uses the file MIME type as the request content-type unless you provide one explicitly.
import "HTTP"

action UploadRemoteFile(uploadUrl: TEXT, file: FILE): UNKNOWN
  body
    response := HTTP.fetch(
      url := uploadUrl,
      method := "PUT",
      body := file
    )
    return response
To download response bytes without converting them to text, set responseType := "file". The response keeps the same object shape, but body is a FILE value.
import "HTTP"

action DownloadRemoteImage(imageUrl: TEXT): FILE
  body
    response := HTTP.fetch(
      url := imageUrl,
      responseType := "file"
    )
    return response.body
HTTP.fetch behavior:
  • method defaults to GET.
  • Supported methods are GET, POST, PUT, DELETE, PATCH, OPTIONS, and HEAD.
  • query must be a plain object of strings, numbers, booleans, arrays of those primitives, null, or undefined.
  • Object request bodies are JSON-encoded and get content-type: application/json unless you set a content type yourself.
  • Top-level FILE request bodies are sent as raw bytes and get the file MIME type as content-type unless you set a content type yourself.
  • FILE values are not supported inside JSON object or array bodies. Multipart bodies, including multipart/related, are not constructed automatically.
  • JSON responses are parsed into objects; non-JSON responses return text.
  • Set responseType := "file" to return response bytes as a FILE in body. Store the returned file before saving it on an entity if it must survive after the action.

Local Modules

Local imports use relative paths and only expose symbols declared with export. Examples:
  • import "./helpers" merges exported symbols into the current file.
  • import "./helpers" as Helpers places exported symbols under Helpers.
  • export action BuildTitle(title: TEXT): TEXT makes an action importable.
  • export entity SharedModel makes an entity importable.
Use aliases when two modules export symbols with similar names or when you want calls such as Helpers.BuildTitle(title := title) to be explicit.