Skip to main content

Go SDK user guide

The Crusoe AI Platform Go SDK provides idiomatic Go packages to interact with platform services using context.Context, strong typing, and explicit error handling.


Installation

Add the Go SDK module to your go.mod file:

go get github.com/crusoe/cai/sdk/go

Requirements

  • Go 1.20 or higher

Authentication & Configuration

The SDK uses secrets.NewConfiguration() and accepts a bearer token passed through context.Context:

package main

import (
"context"
"os"

secrets "github.com/crusoe/cai/sdk/go"
)

func main() {
cfg := secrets.NewConfiguration()
cfg.Host = "api.codyhill.dev"
cfg.Scheme = "https"

client := secrets.NewAPIClient(cfg)

// Set Bearer authentication in context
token := os.Getenv("CAI_API_KEY")
ctx := context.WithValue(context.Background(), secrets.ContextAccessToken, token)

_ = client
_ = ctx
}

Code examples by service

1. Agents

Invoke agents synchronously or with streaming responses, retrieve sessions, and commit agent memories.

package main

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)

type InvokeRequest struct {
Prompt string `json:"prompt"`
SessionID string `json:"session_id"`
UserID string `json:"user_id"`
}

type InvokeResponse struct {
Response string `json:"response"`
}

func main() {
apiBase := os.Getenv("CAI_API")
if apiBase == "" {
apiBase = "https://api.codyhill.dev"
}
apiKey := os.Getenv("CAI_API_KEY")
projectID := os.Getenv("CAI_PROJECT")

// 1. Invoke Agent
reqBody, _ := json.Marshal(InvokeRequest{
Prompt: "Summarize microservice patterns.",
SessionID: "sess_go_001",
UserID: "user_go",
})

url := fmt.Sprintf("%s/v1/agents/research-assistant/invoke?project=%s", apiBase, projectID)
req, _ := http.NewRequestWithContext(context.Background(), "POST", url, bytes.NewBuffer(reqBody))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()

var result InvokeResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println("Agent Output:", result.Response)

// 2. Memorize Session
memURL := fmt.Sprintf("%s/v1/agents/research-assistant/sessions/sess_go_001/memorize?project=%s", apiBase, projectID)
memReq, _ := http.NewRequestWithContext(context.Background(), "POST", memURL, nil)
memReq.Header.Set("Authorization", "Bearer "+apiKey)

memResp, err := client.Do(memReq)
if err == nil {
defer memResp.Body.Close()
fmt.Println("Memorize Status:", memResp.StatusCode)
}
}

2. VectorDB

Create vector indexes, upsert point embeddings, query vector similarity, and scroll collections.

package main

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"os"
)

type Point struct {
ID string `json:"id"`
Vector []float32 `json:"vector"`
Payload map[string]interface{} `json:"payload,omitempty"`
}

type UpsertPayload struct {
Points []Point `json:"points"`
}

type QueryPayload struct {
Vector []float32 `json:"vector"`
TopK int `json:"top_k"`
IncludePayload bool `json:"include_payload"`
}

func main() {
vectorBase := os.Getenv("CAI_VECTORDB_API")
if vectorBase == "" {
vectorBase = "https://api.codyhill.dev"
}
apiKey := os.Getenv("CAI_API_KEY")
projectID := os.Getenv("CAI_PROJECT")

client := &http.Client{}

// 1. Upsert vector points
vector := make([]float32, 1536)
for i := range vector {
vector[i] = 0.05
}

pts := []Point{
{
ID: "doc_201",
Vector: vector,
Payload: map[string]interface{}{
"source": "go-sdk-guide",
},
},
}

body, _ := json.Marshal(UpsertPayload{Points: pts})
upsertURL := fmt.Sprintf("%s/v1/projects/%s/indexes/kb-go-index:upsert", vectorBase, projectID)

req, _ := http.NewRequestWithContext(context.Background(), "POST", upsertURL, bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Upsert Status:", resp.StatusCode)

// 2. Query similarity
queryBody, _ := json.Marshal(QueryPayload{
Vector: vector,
TopK: 5,
IncludePayload: true,
})
queryURL := fmt.Sprintf("%s/v1/projects/%s/indexes/kb-go-index:query", vectorBase, projectID)

qReq, _ := http.NewRequestWithContext(context.Background(), "POST", queryURL, bytes.NewBuffer(queryBody))
qReq.Header.Set("Authorization", "Bearer "+apiKey)
qReq.Header.Set("Content-Type", "application/json")

qResp, err := client.Do(qReq)
if err == nil {
defer qResp.Body.Close()
fmt.Println("Query Status:", qResp.StatusCode)
}
}

3. Functions

Deploy serverless functions, execute code payloads, and fetch execution logs.

package main

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)

func main() {
apiBase := os.Getenv("CAI_API")
if apiBase == "" {
apiBase = "https://api.codyhill.dev"
}
apiKey := os.Getenv("CAI_API_KEY")
projectID := os.Getenv("CAI_PROJECT")

client := &http.Client{}

// 1. Invoke Serverless Function
payload, _ := json.Marshal(map[string]interface{}{
"filename": "data.csv",
"format": "parquet",
})

url := fmt.Sprintf("%s/v1/agents/csv-converter/invoke?project=%s", apiBase, projectID)
req, _ := http.NewRequestWithContext(context.Background(), "POST", url, bytes.NewBuffer(payload))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()

out, _ := io.ReadAll(resp.Body)
fmt.Println("Function Result:", string(out))

// 2. Fetch Function Logs
logURL := fmt.Sprintf("%s/v1/agents/csv-converter/logs?project=%s", apiBase, projectID)
logReq, _ := http.NewRequestWithContext(context.Background(), "GET", logURL, nil)
logReq.Header.Set("Authorization", "Bearer "+apiKey)

logResp, err := client.Do(logReq)
if err == nil {
defer logResp.Body.Close()
logs, _ := io.ReadAll(logResp.Body)
fmt.Println("Function Logs:\n", string(logs))
}
}

4. Secrets

Manage secrets using official Go API client types.

package main

import (
"context"
"fmt"
"os"

secrets "github.com/crusoe/cai/sdk/go"
)

func main() {
cfg := secrets.NewConfiguration()
cfg.Host = "api.codyhill.dev"
cfg.Scheme = "https"

client := secrets.NewAPIClient(cfg)

apiKey := os.Getenv("CAI_API_KEY")
projectID := "0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f"

ctx := context.WithValue(context.Background(), secrets.ContextAccessToken, apiKey)

// 1. Create a secret
createReq := secrets.CreateSecretRequest{
Name: "database-url",
Value: "postgres://user:pass@db.example.com:5432/main",
}

secResp, _, err := client.SecretsAPI.CreateProjectSecret(ctx, projectID).CreateSecretRequest(createReq).Execute()
if err != nil {
fmt.Printf("Error creating secret: %v\n", err)
return
}
fmt.Printf("Created secret: %s, version: %d\n", secResp.Name, secResp.Version)

// 2. Bind secret to an agent
bindReq := secrets.PutBindingRequest{
SecretName: secrets.PtrString("database-url"),
}

_, _, err = client.BindingsAPI.PutAgentSecretBinding(ctx, projectID, "db-worker", "DATABASE_URL").PutBindingRequest(bindReq).Execute()
if err == nil {
fmt.Println("Bound secret to db-worker")
}

// 3. Apply secret binding map
applyResp, _, err := client.BindingsAPI.ApplyAgentSecretBindings(ctx, projectID, "db-worker").Execute()
if err == nil {
fmt.Printf("Applied secrets successfully. Status: %s\n", applyResp.Status)
}

// 4. Reveal secret value (Admin only, audited)
revealed, _, err := client.SecretsAPI.RevealSecret(ctx, projectID, "database-url").Execute()
if err == nil {
fmt.Printf("Revealed secret value: %s\n", *revealed.Value)
}
}

5. MemoryStore

Manage Redis-compatible instances, check metrics, and rotate access credentials.

package main

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)

type CreateStoreRequest struct {
Name string `json:"name"`
MaxMemoryMB int `json:"max_memory_mb"`
}

func main() {
memBase := os.Getenv("CAI_MEMORYSTORE_API")
if memBase == "" {
memBase = "https://api.codyhill.dev"
}
apiKey := os.Getenv("CAI_API_KEY")
projectID := os.Getenv("CAI_PROJECT")

client := &http.Client{}

// 1. Create MemoryStore Instance
body, _ := json.Marshal(CreateStoreRequest{
Name: "cache-go",
MaxMemoryMB: 256,
})

url := fmt.Sprintf("%s/v1/projects/%s/memorystores", memBase, projectID)
req, _ := http.NewRequestWithContext(context.Background(), "POST", url, bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()

resBody, _ := io.ReadAll(resp.Body)
fmt.Println("MemoryStore Created:", string(resBody))

// 2. Fetch Instance Stats
statsURL := fmt.Sprintf("%s/v1/projects/%s/memorystores/cache-go/stats", memBase, projectID)
statsReq, _ := http.NewRequestWithContext(context.Background(), "GET", statsURL, nil)
statsReq.Header.Set("Authorization", "Bearer "+apiKey)

statsResp, err := client.Do(statsReq)
if err == nil {
defer statsResp.Body.Close()
statsOut, _ := io.ReadAll(statsResp.Body)
fmt.Println("Stats:", string(statsOut))
}
}

6. PubSub

Publish message batches to Pub/Sub topics, pull pending messages, and acknowledge receipts.

package main

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)

type PubSubMessage struct {
Data string `json:"data"`
Attributes map[string]string `json:"attributes,omitempty"`
}

type PublishRequest struct {
Messages []PubSubMessage `json:"messages"`
}

func main() {
pubsubBase := os.Getenv("CAI_PUBSUB_API")
if pubsubBase == "" {
pubsubBase = "https://api.codyhill.dev"
}
apiKey := os.Getenv("CAI_API_KEY")
projectID := os.Getenv("CAI_PROJECT")

client := &http.Client{}

// 1. Publish Message
payload := map[string]string{"event": "payment_processed", "amount": "99.00"}
rawJSON, _ := json.Marshal(payload)
encodedData := base64.StdEncoding.EncodeToString(rawJSON)

pubBody, _ := json.Marshal(PublishRequest{
Messages: []PubSubMessage{
{
Data: encodedData,
Attributes: map[string]string{
"source": "go-billing-service",
},
},
},
})

url := fmt.Sprintf("%s/v1/projects/%s/topics/billing-events:publish", pubsubBase, projectID)
req, _ := http.NewRequestWithContext(context.Background(), "POST", url, bytes.NewBuffer(pubBody))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()

resBytes, _ := io.ReadAll(resp.Body)
fmt.Println("Publish Result:", string(resBytes))
}

Error handling

Check error returns from SDK methods and inspect HTTP status codes:

secResp, httpResp, err := client.SecretsAPI.CreateProjectSecret(ctx, projectID).CreateSecretRequest(createReq).Execute()
if err != nil {
if httpResp != nil {
fmt.Printf("HTTP Status Code: %d\n", httpResp.StatusCode)
fmt.Printf("Request ID: %s\n", httpResp.Header.Get("X-Request-Id"))
}
fmt.Printf("API Error: %v\n", err)
}