> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withsutro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Modules, AI, and HTTP

> Import SLang modules and call built-in AI and HTTP capabilities.

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:

| Module | Import          | Export                                         |
| ------ | --------------- | ---------------------------------------------- |
| AI     | `import "AI"`   | `AI.prompt(message := "text")`                 |
| HTTP   | `import "HTTP"` | `HTTP.fetch(url := "https://api.example.com")` |

`import "AI"` is shorthand for `import "slang:AI"`. You can also alias built-ins with `as`.

```slang theme={null}
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.

```slang theme={null}
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`.

## HTTP Fetching

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

```slang theme={null}
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.

```slang theme={null}
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.

```slang theme={null}
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.
