Go Client & Toolchain Integration
The Go client library (github.com/retail-cortex/castor/clients/go/pkg/castor_client) integrates into Go’s native build workflows via //go:generate directives, go test validation hooks, and Bazel rules_go targets.
In corporate Go codebases, skill compilation and validation are bound directly to the build phase using //go:generate directives in your main package or service package:
package main
// Generate pre-compiled zero-I/O manifest prior to compilation
//go:generate cstr compile -d ./skills -o ./skills_manifest.json
// Verify cryptographic integrity of skills lockfile during build
//go:generate cstr verify -d ./skills
import (
"embed"
"fmt"
"log"
"github.com/retail-cortex/castor/clients/go/pkg/castor_client"
)
// Embed pre-compiled skills manifest into static Go binary
//go:embed skills_manifest.json
var embeddedManifest embed.FS
func main() {
manifestData, err := embeddedManifest.ReadFile("skills_manifest.json")
if err != nil {
log.Fatalf("Failed to read embedded manifest: %v", err)
}
skills, err := castor_client.LoadSkillsFromManifestData(manifestData)
if err != nil {
log.Fatalf("Corrupt manifest: %v", err)
}
fmt.Printf("Instantly loaded %d embedded skills into Go binary.\n", len(skills))
}
# 1. Trigger pre-build generation & validation hooks
go generate ./...
# 2. Compile statically linked binary with embedded skills
go build -o agent_service ./cmd/agent
If cstr verify or cstr compile detects corrupt frontmatter or checksum mismatches during go generate, the build pipeline terminates before binary compilation.
In your BUILD.bazel:
load("@rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "agent_lib",
srcs = ["main.go"],
embedsrcs = ["skills_manifest.json"],
importpath = "com.company.agent/lib",
deps = [
"//clients/go/pkg/castor_client",
],
)
go_binary(
name = "agent_service",
embed = [":agent_lib"],
)
Incorporate skill verification into your automated _test.go suites:
package main_test
import (
"testing"
"github.com/retail-cortex/castor/clients/go/pkg/castor_client"
"github.com/stretchr/testify/assert"
)
func TestSkillsIntegrity(t *testing.T) {
report, err := castor_client.VerifySkills("./skills", "./skills/.manifest.lock")
assert.NoError(t, err)
assert.Equal(t, 0, report.ModifiedCount, "Skills directory has been tampered with")
assert.Equal(t, 0, report.MissingCount, "Skills files are missing")
}
The Go client provides dynamic semantic tool retrieval for autonomous agents to limit active tools to the top ≤ 3 ranked skills:
package main
import (
"context"
"fmt"
"log"
"github.com/retail-cortex/castor/clients/go/pkg/castor_client"
)
func main() {
// Initialize registry from local workspace or embedded assets
registry, err := castor_client.NewSkillRegistry("", nil, nil, "")
if err != nil {
log.Fatalf("Failed to initialize registry: %v", err)
}
// Suggest top 3 skills for user prompt via remote vector search (fallback to local keyword search)
suggested := registry.SuggestSkills("raster image canvas drawing 2d", 3, "http://localhost:8000")
fmt.Printf("Dynamically suggested %d skills:\n", len(suggested))
for _, s := range suggested {
fmt.Printf("- %s: %s\n", s.Name, s.Description)
}
}
Loaded SkillDefinition objects map directly to Google ADK Agent system instructions, prompt guidelines, and executable tools.
package main
import (
"context"
"fmt"
"log"
"github.com/google/adk/agent"
"github.com/retail-cortex/castor/clients/go/pkg/castor_client"
"github.com/rrmcguinness/modenv/pkg/modenv"
)
type AppConfig struct {
Castor struct {
ServerURL string `toml:"server_url"`
APIKey string `toml:"api_key"`
} `toml:"castor"`
}
func main() {
ctx := context.Background()
// 1. Load application configuration using modenv
var cfg AppConfig
if _, err := modenv.Load(&cfg); err != nil {
log.Printf("Warning: failed to load modenv configuration: %v", err)
}
serverURL := cfg.Castor.ServerURL
if serverURL == "" {
serverURL = "http://localhost:8000"
}
registry, _ := castor_client.NewSkillRegistry("", nil, nil, "")
// 2. Pre-call prompt grounding: retrieve top 3 skills dynamically
prompt := "Synthesize demand forecasting query for store #42"
skills := registry.SuggestSkills(prompt, 3, serverURL)
instructions := "You are an enterprise AI coding agent.\n"
for _, skill := range skills {
instructions += fmt.Sprintf("\n### %s\n%s\n", skill.Name, skill.Instructions)
}
// 3. Instantiate Google ADK Agent grounded in suggested skill instructions
adkAgent := agent.New(agent.Config{
Name: "retail-coding-agent",
Model: "gemini-2.0-flash",
SystemInstructions: instructions,
})
// 4. Run prompt through ADK agent pipeline
res, err := adkAgent.Run(ctx, prompt)
if err != nil {
log.Fatalf("ADK execution error: %v", err)
}
fmt.Println("ADK Agent Response:", res.Text)
}
The Go client parses and evaluates scenarios defined under scenarios/*.md:
package main
import (
"fmt"
"log"
"github.com/retail-cortex/castor/clients/go/pkg/castor_client"
)
func main() {
skill, err := castor_client.LoadSkillFromDir("./skills/bazel-modules")
if err != nil {
log.Fatalf("Failed loading skill: %v", err)
}
for name, scenario := range skill.Scenarios {
// Mock or real agent output & tools executed
agentOutput := "To build a Bazel module hermetically: bazel build //..."
toolsUsed := []string{"bazel"}
res := castor_client.EvaluateScenario(scenario, agentOutput, toolsUsed)
if res.Passed {
fmt.Printf("[PASS] Scenario '%s': similarity=%.2f\n", name, res.SimilarityScore)
} else {
fmt.Printf("[FAIL] Scenario '%s': similarity=%.2f, errors=%v\n", name, res.SimilarityScore, res.Errors)
}
}
}
- Distroless Packaging: Statically link Go binaries (
CGO_ENABLED=0) with embedded skill manifests for deployment in minimalscratchordistrolesscontainer images. - JIT Dynamic Retrieval: Use
registry.SuggestSkills(prompt, 3, serverURL)to prevent LLM context saturation. - Hermetic Testing: Mock external HTTP requests in unit tests using
httptest.NewServer.