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)
}