Easybeam - quick tutorial

The easybeam API

Two things must ye know about the easybeam API.

  1. Configure it
  2. Call it

And that's it. Couldn't be easier. Don't overthink it.

Configuration

let config = EasyBeamConfig(token: "api-token")
let easybeam = EasyBeam(config: config)

The api-token is your easybeam access token.

Calling the API

Communication with the AI provider can either be a one shot request-response call, or streamed. Either way, it's done via a call to the portal and you get one (or more) PortalResponse types back.

public struct PortalResponse: Codable {
    public let newMessage: ChatMessage
    public let chatId: String
    public let streamFinished: Bool?
}

newMessage is the latest message in the conversation returned by the service.

chatId can be ignored, but easybeam allows you to submit reviews for chats. If you want to do that, you need to keep track of this value.

streamFinished can be ignored for now, I'll get back to you on that.

One shot

public func getPortal(
    portalId: String,
    userId: String? = nil,
    filledVariables: [String: String],
    messages: [ChatMessage]
) async throws -> PortalResponse {

portalId is the Portal ID you promised me you'd remember and userId can be nil, so don't worry about it too much. If you've got an app that has user login this can be whatever you use to identify the user.

filledVariables are the parameters you pass to the prompt. In the example prompt above it was the @level placeholder, which would look something like this:

var filledVariables: [String: String] {
    [
        "level": "Irish Leaving Cert"
    ]
}

messages is your entire conversation with the AI provider. It's important to keep a running record of each message you send and receive. The PortalResponse contains a newMessage that must be appended to the array of previous messages.

A full conversation with the AI provider could be something like this

getPortal([question-1])
portalResponse(answer-1)

getPortal([question-1, answer-1, question-2])
portalResponse(answer-2)

getPortal([question-1, answer-1, question-2, answer-2, question-3])
portalResponse(answer-3)

This means the AI provider gets the full context of the conversation with each call to the endpoint.

For the most part this is all you need, it's following the standard AI flow of question and response, building up a conversation over time.

But when you interact with any of the AIs on their webpages you'll notice they have a feature that outputs the responses as if they're being typed, rather than appearing on screen all at once. Wouldn't it be nice if we could do that?

Ok, let's do that.

Streaming with easybeam

easybeam provides a streamPortal method that takes the same parameters as getPortal, but instead of a single PortalResponse it returns an AsyncThrowingStream of `PortalResponse's.

public func streamPortal(
    portalId: String,
    userId: String? = nil,
    filledVariables: [String: String],
    messages: [ChatMessage]
) -> AsyncThrowingStream<PortalResponse, Error>

The stream of PortalResponse objects contain the same newMessage value as before, but, very importantly, the true newMessage is the final one in the stream.

How do you know the stream is finished? That's what the streamFinished value in PortalResponse tells us.

So what's the point of newMessage in this case? It gives us the ability to display the response in a sequence of text blocks that look like they're being typed.

For example, for the question

What is an acid?

The new messages in the response stream might be

An
An acid
An acid is
An acid is a
An acid is a substance
An acid is a substance that
An acid is a substance that don
An acid is a substance that donates
An acid is a substance that donates a
An acid is a substance that donates a hydrogen
An acid is a substance that donates a hydrogen ion

As you can see the text is built up as it comes in, so you can display it in a text box that overwrites it's content with each portal response, until the stream is finished. This gives a nicer experience for the user and feels just like interacting with the AI iin the browser.

And there we have it. Lovely.

There's a lot more going on with easybeam, this is just a quick tutorial on how to get started. In a future block post I'll be looking at how to make Portals more powerful using Workspaces.