← All code samples

Aiden chat from a Go backend

Use a server-side SDK client for a Grafana plugin or another chat application. Keep API tokens in your application’s encrypted secret configuration. This journey is Go-first today: start a turn with StartAgentChat, stream events with SubscribeExecution, and stop a session with TerminateSession.

The Go module is invite-only while the SDK repository is private. Ask StackGen for GitHub access before go get (Python and TypeScript stay on public PyPI / npm).

Step What the SDK does
1. Start POST …/agents/{name}/chat/start returns trace_id and session_id
2. Stream GET …/executions/{trace_id}/subscribe until the turn settles
3. Stop On failure, TerminateSession asks Aiden to cancel in-flight work

How to run

export STACKGEN_URL=https://app.stackgen.com
export STACKGEN_TOKEN=stackgen_…
export STACKGEN_WORKSPACE_ID=<workspace-uuid>

go run ./examples/go/aiden-chat/agent-chat.go \
  --agent grafana-assistant \
  --message 'List the available data sources without changing anything.'

Minimal

client, err := stackgen.NewClient(stackgen.Config{
    BaseURL:     "https://app.stackgen.com",
    APIToken:    os.Getenv("STACKGEN_TOKEN"),
    WorkspaceID: os.Getenv("STACKGEN_WORKSPACE_ID"),
})
if err != nil { return err }
ctx, cancel := context.WithTimeout(ctx, 10*time.Minute)
defer cancel()
run, err := client.Aiden.StartAgentChat(ctx, "grafana-assistant", aiden.StartChatRequest{
    Message: "List the available data sources without changing anything.",
    // SessionID: previousSessionID, // continue a conversation owned by this user
})
if err != nil { return err }
err = client.Aiden.SubscribeExecution(ctx, run.TraceID, func(event aiden.ExecutionEvent) error {
    if !event.Subagent && event.Type == "TEXT_MESSAGE_CONTENT" {
        fmt.Print(event.Text("Content", "content"))
    }
    return nil
})
if err != nil {
    cleanup, done := context.WithTimeout(context.Background(), 20*time.Second)
    defer done()
    _ = client.Aiden.TerminateSession(cleanup, run.SessionID)
}
return err

Python and TypeScript wait for the turn to finish. Streaming text deltas to a browser is Go-only today (SubscribeExecution below).

Imports: context, fmt, os, time, github.com/appcd-dev/stackgen-sdk/clients/go, and github.com/appcd-dev/stackgen-sdk/clients/go/aiden.

SubscribeExecution parses multiline SSE, normalizes CloudEvents and wrapped AG-UI payloads, and confirms completion against the execution record. Handle snapshot events (Delta: false) as replacements. Ignore echoed user messages and subagent answers when rendering a root assistant reply. CUSTOM events named runtime.result contain an explicit final answer delta in value.delta. The helper rejects malformed, interrupted, timed-out, and failed streams. It does not automatically replay streams because replay can coalesce text deltas. The total deadline defaults to 15 minutes or TimeoutSeconds; a caller’s earlier context deadline wins. Start operations are never retried automatically.

Workspace pickers and integrations

client.Workspaces.List(ctx) returns accessible workspace IDs and names. client.Workspaces.Create(ctx, "observability", "Grafana assistant workspace") creates a workspace and adds the token’s calling user as workspace admin. Construct a new client with the selected workspace’s ID as WorkspaceID, then call ListAgents and ListIntegrations. Only send names and descriptions to the browser; integration responses may contain credential references.

On TOOL_APPROVAL_REQUEST, present the approval id, tool name, and arguments. GetApproval reads status and ownership; ResolveApproval approves or rejects only that tool call. Enforce ownership in your backend before resolving with a shared token.

For a new Grafana connection, call UpsertIntegrationWithSecretsContext with Type: "grafana", Scope: "PROJECT", and secrets base_url / api_token. Check GetIntegration before first-time setup and reuse an existing connection. Then attach the integration name to the agent’s complete integrations list.

Treat session identifiers as privileged: with a shared backend token, your application must enforce per-user session ownership before continuation or stop.

Complete scripts

The complete script is Go only. Python and TypeScript use the Minimal snippet above.