SDKs

Kotlin SDK

Using Spectron from Kotlin applications and agents on JVM, Android, and iOS.

The Spectron client for Kotlin ships inside the SurrealDB Kotlin SDK — there is no separate package. It lives in the com.surrealdb.kotlin.spectron package and talks to Spectron's HTTP API directly, independently of the SurrealDB RPC engine. Like the rest of the Kotlin SDK, it is Kotlin Multiplatform (JVM, Android, iOS) and every method is a suspend function.

Add the Kotlin SDK to your project as described in the installation guide:

dependencies {
implementation("com.surrealdb:kotlin:0.1.0-SNAPSHOT")
}

Construct a Spectron client with a context id, an API key, and your endpoint. Authentication uses the Authorization: Bearer header on every request.

import com.surrealdb.kotlin.spectron.Spectron

val memory = Spectron(
contextId = "acme-prod",
apiKey = "sk-spec-...",
endpoint = "https://api.spectron.example",
)
ParameterDefaultDescription
contextIdrequiredThe context to operate in, e.g. "acme-prod".
apiKeyrequiredBearer token. Mutable — takes effect on the next request.
endpointrequiredBase URL, e.g. "https://api.spectron.example".
timeout30sPer-request timeout.
maxRetries3GET-only retries on 5xx and connection errors.
httpClientplatform defaultOptional Ktor HttpClient to inject.
jsonlenientOptional kotlinx.serialization Json instance.

Wrap calls in a coroutine — for example runBlocking { ... } from a synchronous caller — and call memory.close() when finished.

Store a free-form fact (extracted server-side) or caller-supplied triples.

import com.surrealdb.kotlin.spectron.model.InferMode

// Free-form fact, extracted server-side.
memory.remember("Christian was promoted to CTO", infer = InferMode.FULL)
import com.surrealdb.kotlin.spectron.model.Triple
import com.surrealdb.kotlin.spectron.model.TripleEntity

// Caller-supplied triples, no LLM.
memory.remember(
triples = listOf(
Triple(entity = TripleEntity("christian", "Person"), key = "role", value = "CTO"),
),
infer = InferMode.TRIPLES,
)

Ingest a whole conversation in one call with rememberMany:

import com.surrealdb.kotlin.spectron.model.BatchMessage
import com.surrealdb.kotlin.spectron.model.TurnRole

memory.rememberMany(
messages = listOf(
BatchMessage("I was promoted to CTO.", role = TurnRole.USER),
BatchMessage("Congratulations!", role = TurnRole.ASSISTANT),
),
scope = listOf("org/acme/user/alice"),
)
val result = memory.recall("What role does Christian have?", k = 10, mode = "hybrid")
result.hits.forEach { println("${it.score} ${it.text}") }

// Assemble a ready-to-use context block.
memory.queryContext("brief on tobie", k = 10)

Upload a document (pass a ByteArray), then query across passages.

val doc = memory.documents.upload(
file = bytes,
filename = "returns.pdf",
contentType = "application/pdf",
title = "Returns Policy",
scope = listOf("org/acme/team/eng"),
labels = listOf("team=eng"),
)

memory.documents.get(doc.id)
memory.documents.list(status = "ready", mimeType = "application/pdf")
import com.surrealdb.kotlin.spectron.model.QueryMode

val hits = memory.documents.query(
"what is the return window for unopened items?",
mode = QueryMode.HYBRID_GRAPH,
k = 10,
)

Run a server-driven turn (retrieve, generate, and persist) in one call.

val reply = memory.chat("What do you know about me?", sessionId = session.id)
println(reply.reply)

Create a session handle and either let Spectron drive the turn or drive it yourself.

import com.surrealdb.kotlin.spectron.model.TurnRole

val session = memory.sessions.create(scope = listOf("user/tobie"))

// Server-driven turn scoped to the session.
val reply = session.chat("What do you know about me?")

// Or drive the turns yourself.
session.remember("I just got promoted to CTO", role = TurnRole.USER)
val ctx = session.context("What is Tobie's role?")

Scopes are hierarchical slash-path strings. Build them with the scopePaths helper:

import com.surrealdb.kotlin.spectron.scopePaths

scopePaths("team" to "eng", "org" to "acme") // ["team/eng", "org/acme"]

Every method accepts an optional onBehalfOf, which sends the X-Spectron-On-Behalf-Of header so a privileged caller can act as another principal:

memory.recall("open incidents", onBehalfOf = "alpha-bot")
memory.documents.list(status = "ready", onBehalfOf = "alpha-bot")

All failures throw a subclass of SpectronException. See the Kotlin SDK reference for the full exception → status mapping and Errors and retries.

import com.surrealdb.kotlin.spectron.SpectronNotFoundException
import com.surrealdb.kotlin.spectron.SpectronRateLimitException

try {
memory.documents.get("doc:missing")
} catch (e: SpectronNotFoundException) {
println("${e.status}: ${e.title}")
} catch (e: SpectronRateLimitException) {
println("retry after ${e.retryAfter}")
}

Was this page helpful?