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
The module path is www.codyhill.net/sdk/go/platform, and it is served by the Go module proxy
your own platform's www host runs beside the CLI downloads. Run this from inside your module (the
directory holding your go.mod):
GOPROXY="https://www.codyhill.net/goproxy,$(go env GOPROXY)" \
GONOSUMDB="www.codyhill.net/*" \
go get www.codyhill.net/sdk/go/platform@v0.1.0
Both variables are written in front of the command rather than exported: they apply to this one
go get and leave your shell, your other projects and your CI unchanged.
Install an SDK explains what each one does, why GOSUMDB=off
and GOPRIVATE are the wrong tools here, and how to verify the module's h1: hash before it
reaches your go.sum.
proxy.golang.org, and there is no repository to clonego get without the GOPROXY prefix above will fail, and that is the intended behaviour: during
the private beta this module is published nowhere public. codyhill.net is a reserved
documentation TLD that can never resolve, so a toolchain falling back to direct fails loudly
instead of fetching a path somebody else registered. Substitute your own platform's domain
throughout.
Requirements
- Go 1.18 or higher
Authentication & Configuration
The SDK uses platform.NewConfiguration() and accepts a bearer token passed through context.Context:
package main
import (
"context"
"os"
platform "www.codyhill.net/sdk/go/platform"
)
func main() {
cfg := platform.NewConfiguration()
cfg.Host = "api.codyhill.net"
cfg.Scheme = "https"
client := platform.NewAPIClient(cfg)
// Set Bearer authentication in context
token := os.Getenv("CAI_API_KEY")
ctx := context.WithValue(context.Background(), platform.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.net"
}
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.net"
}
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.net"
}
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"
platform "www.codyhill.net/sdk/go/platform"
)
func main() {
cfg := platform.NewConfiguration()
cfg.Host = "api.codyhill.net"
cfg.Scheme = "https"
client := platform.NewAPIClient(cfg)
apiKey := os.Getenv("CAI_API_KEY")
projectID := "0191f2c4-7777-7c3d-8e4f-5a6b7c8d9e0f"
ctx := context.WithValue(context.Background(), platform.ContextAccessToken, apiKey)
// 1. Create a secret
createReq := platform.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 := platform.PutBindingRequest{
SecretName: "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 {
// RevisionRolled is absent on the no-bindings path, so it is a *bool.
rolled := applyResp.RevisionRolled != nil && *applyResp.RevisionRolled
fmt.Printf("Applied %d bindings to %s (revision rolled: %t): %s\n",
len(applyResp.Applied), applyResp.Agent, rolled, applyResp.Note)
}
// 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.net"
}
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.net"
}
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)
}