Easybeam - quick tutorial
The easybeam API
Two things must ye know about the easybeam API.
- Configure it
- 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.