antigravity

package module
v0.0.0-...-216fec7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 17, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

Google Antigravity SDK for Go

The Google Antigravity SDK is a Go library for building autonomous AI agents powered by Antigravity and Gemini. It provides a secure, scalable, and stateful infrastructure layer that abstracts the agentic loop, letting you focus on what your agent does rather than how it runs.

Prerequisites

  • Go 1.21+
  • Gemini API Key — set via GEMINI_API_KEY environment variable
  • localharness runtime binary — see Setup below

Installation

go get github.com/JulienBreux/antigravity-sdk-go

Setup

The SDK requires the localharness runtime binary, which is the Antigravity agent backend. A download script is included to fetch it automatically from PyPI — no Python installation required.

# Download localharness and prepare the project
make setup
Manual Setup
# Download the binary for your platform (macOS, Linux, Windows)
./scripts/download_harness.sh

# The binary is placed in bin/localharness
# The SDK automatically finds it there at runtime
Binary Resolution Order

The SDK searches for localharness in the following order:

  1. ANTIGRAVITY_HARNESS_PATH environment variable (explicit override)
  2. bin/localharness in the working directory (populated by make setup)
  3. localharness in the system PATH

[!TIP] For CI/CD pipelines, set ANTIGRAVITY_HARNESS_PATH to an absolute path. For local development, make setup is the easiest option.


Quickstart

Simple Agent

The Agent struct is the easiest way to get started. It manages the full lifecycle — starting the local harness, registering tools, hooks, safety policies, and background triggers — behind a simple lifecycle pattern.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/JulienBreux/antigravity-sdk-go"
	"github.com/JulienBreux/antigravity-sdk-go/agent"
	"github.com/JulienBreux/antigravity-sdk-go/connections/local"
	_ "github.com/JulienBreux/antigravity-sdk-go/conversation" // Registers conversation factory
	"github.com/JulienBreux/antigravity-sdk-go/hooks"
)

func main() {
	ctx := context.Background()

	// 1. Initialize local configuration
	config := local.NewLocalAgentConfig()

	// Optional: Configure API Key or Model
	apiKey := os.Getenv("GEMINI_API_KEY")
	config.APIKey = &apiKey

	// Safety policy: allow all tool calls for this simple demo
	config.Policies = []any{hooks.AllowAll()}

	// 2. Create the Agent
	myAgent := agent.NewAgent(config)

	// 3. Start the agent session
	if err := myAgent.Start(ctx); err != nil {
		log.Fatalf("Failed to start agent: %v", err)
	}
	defer myAgent.Close()

	// 4. Send a prompt to the agent
	prompt := antigravity.Content{
		antigravity.StringContent("Say 'Hello World!'"),
	}
	response, err := myAgent.Chat(ctx, prompt)
	if err != nil {
		log.Fatalf("Chat error: %v", err)
	}

	// 5. Get the full response text
	text, err := response.Text()
	if err != nil {
		log.Fatalf("Failed to retrieve text response: %v", err)
	}

	fmt.Printf("Agent Response:\n%s\n", text)
}

Run it:

export GEMINI_API_KEY="your_key_here"
make setup        # Download localharness (first time only)
go run ./examples/hello_world/

Key Concepts

Streaming Responses

For fluid console outputs or user interfaces, you can stream the agent's response, thoughts, or tool calls in real-time without waiting for the full turn to finish.

// Stream text tokens as they arrive
for chunk := range response.Chunks() {
	if txt, ok := chunk.(antigravity.Text); ok {
		fmt.Print(txt.Text)
	}
}
fmt.Println()

For advanced streaming:

  • response.Thoughts(): Returns a read channel (<-chan string) for internal reasoning steps.
  • response.ToolCalls(): Returns a read channel (<-chan ToolCall) for intercepted tool dispatches.

Multimodal Inputs

Pass text instructions along with images, documents, audio, or video files to the agent.

// Load a PDF document from the filesystem
specDoc, err := antigravity.FromFile("architecture_spec.pdf", "System Architecture Spec")
if err != nil {
	log.Fatal(err)
}

// Or construct in-memory media directly (e.g. for PNG image bytes)
chartImage := antigravity.Image{
	BaseMedia: antigravity.BaseMedia{
		Data:        pngBytes,
		MimeType:    "image/png",
		Description: "System Diagram",
	},
}

prompt := antigravity.Content{
	antigravity.StringContent("Compare this diagram against the spec document and list three security issues:"),
	chartImage,
	specDoc,
}

response, err := agent.Chat(ctx, prompt)

Custom Tools

Register Go functions as tools. The SDK inspects function signatures using reflection, automatically generates the JSON Schema for the model, and parses/populates input arguments when called.

type WeatherArgs struct {
	City string `json:"city" description:"The city to get weather for"`
}

// Custom function tool
func getWeather(ctx context.Context, args WeatherArgs) (string, error) {
	return fmt.Sprintf("It is currently sunny and 22°C in %s.", args.City), nil
}

import "github.com/JulienBreux/antigravity-sdk-go/agent"

func main() {
	config := local.NewLocalAgentConfig()
	
	// Register custom tool functions in the Tools slice
	config.Tools = []any{getWeather}
	
	myAgent := agent.NewAgent(config)
	// ... start and chat ...
}

If a custom tool function declares a parameter of type *tools.ToolContext, it receives the context automatically, allowing it to send background notifications or check the conversation state.


Declarative Safety Policies

By default, the SDK enables all builtin tools. If write capabilities or external MCP servers are used, you must provide safety policies to control tool execution.

Policies are evaluated using a strict priority-based matching model.

import (
	"github.com/JulienBreux/antigravity-sdk-go/hooks"
)

func main() {
	config := local.NewLocalAgentConfig()
	config.Capabilities.EnabledTools = []antigravity.BuiltinTools{
		antigravity.BuiltinViewFile,
		antigravity.BuiltinRunCommand,
	}

	// Expose write tools but require user confirmation before executing commands
	config.Policies = []any{
		hooks.AskUser(string(antigravity.BuiltinRunCommand), myApprovalHandler, nil, "confirm_run_cmd"),
		hooks.AllowAll(),
	}

	myAgent := agent.NewAgent(config)
	// ...
}

func myApprovalHandler(ctx context.Context, call antigravity.ToolCall) (bool, error) {
	fmt.Printf("[PROPOSAL] Execute: %v\n", call.Args["CommandLine"])
	fmt.Print("Approve? (y/n): ")
	var input string
	fmt.Scanln(&input)
	return input == "y" || input == "yes", nil
}

Built-in policies:

  • hooks.AllowAll(): Approves all tool calls immediately (useful for local development).
  • hooks.DenyAll(): Denies all tool calls.
  • hooks.WorkspaceOnly(workspaces): Blocks file-modifying tools from reading/writing files outside the configured workspace paths.
  • hooks.ConfirmRunCommand(handler): Denies or asks the user before executing shell commands.

Background Triggers

Triggers are concurrent background watchdogs that react to events (timers, files, webhooks) and push messages back to the agent session.

[!IMPORTANT] The localharness requires at least one chat turn to initialize the conversation before triggers can send notifications. Always complete an initial chat before enabling trigger logic.

import (
	"github.com/JulienBreux/antigravity-sdk-go/triggers"
)

func main() {
	config := local.NewLocalAgentConfig()

	// Trigger callback runs every 60 seconds
	onTicker := triggers.Every(60*time.Second, func(ctx context.Context, tc *triggers.TriggerContext) error {
		return tc.Send(ctx, "Check the deployment build status.")
	})

	config.Triggers = []any{onTicker}

	myAgent := agent.NewAgent(config)
	// ...
}

Available triggers:

  • triggers.Every(interval, callback): Periodically invokes a callback.
  • triggers.OnFileChange(path, callback): Monitors file changes at the given path (uses file notify system calls).

Examples

Complete working examples are available in the examples/ directory:

Example Description
hello_world Minimal agent that sends a prompt and prints the response
custom_tools Register Go functions as agent-callable tools
triggers_and_policies Background SRE triggers with interactive safety policy approval
# Run any example
export GEMINI_API_KEY="your_key_here"
make setup  # first time only
go run ./examples/hello_world/

See the examples README for detailed documentation.


Development

# Download localharness binary
make setup

# Run all tests
make test

# Build all packages
make build

# Verify all examples compile
make examples

# Clean downloaded binaries
make clean

# Show all available targets
make help

Architecture

The SDK is organized in a decoupled three-layer architecture to maximize customizability and prevent cyclic imports:

Layer Purpose Key Components
Layer 1 — Interface High-level developer API Agent
Layer 2 — Session Stateful history and event streaming Conversation, ChatResponse, Step, ToolRunner, HookRunner, TriggerRunner
Layer 3 — Transport Process lifecycle, handshakes, and protocol framing Connection, ConnectionStrategy, LocalConnectionStrategy

License

Apache License 2.0. See LICENSE for details.

Documentation

Index

Constants

View Source
const (
	DefaultModel                = "gemini-3.5-flash"
	DefaultImageGenerationModel = "gemini-3.1-flash-image-preview"
)

Variables

View Source
var DefaultNewHookRunner func() HookRunner
View Source
var DefaultNewToolRunner func(tools []any) ToolRunner
View Source
var DefaultNewTriggerRunner func(trigs []any, conn any) TriggerRunner
View Source
var DefaultToolFromFunc func(name string, description string, fn any) (any, error)
View Source
var EnforcePolicies func(policies []any, mcpServers []McpServerConfig) any

Functions

This section is empty.

Types

type AgentConfig

type AgentConfig interface {
	CreateStrategy(toolRunner any, hookRunner any) (ConnectionStrategy, error)
	GetBaseConfig() *BaseAgentConfig
}

AgentConfig represents the configuration interface for initializing a strategy.

type AskQuestionEntry

type AskQuestionEntry struct {
	Question      string
	Options       []AskQuestionOption
	IsMultiSelect bool
}

AskQuestionEntry a single question definition.

type AskQuestionInteractionSpec

type AskQuestionInteractionSpec struct {
	Questions []AskQuestionEntry
}

AskQuestionInteractionSpec the list of questions for a clarifying question flow.

type AskQuestionOption

type AskQuestionOption struct {
	ID   string
	Text string
}

AskQuestionOption option for a multiple-choice question.

type Audio

type Audio struct{ BaseMedia }

type BaseAgentConfig

type BaseAgentConfig struct {
	SystemInstructions SystemInstructions
	Capabilities       CapabilitiesConfig
	Tools              []any
	Policies           []any
	Hooks              []any
	Triggers           []any
	McpServers         []McpServerConfig
	Workspaces         []string
	ConversationID     *string
	SaveDir            *string
	AppDataDir         *string
	ResponseSchema     *string
	SkillsPaths        []string
}

BaseAgentConfig holds the fields shared across different connection strategies.

func (*BaseAgentConfig) GetBaseConfig

func (b *BaseAgentConfig) GetBaseConfig() *BaseAgentConfig

GetBaseConfig returns the pointer to BaseAgentConfig.

type BaseMcpServerConfig

type BaseMcpServerConfig struct {
	Name           string
	TimeoutSeconds *int
}

BaseMcpServerConfig contains common configuration fields for all MCP servers.

func (BaseMcpServerConfig) GetName

func (b BaseMcpServerConfig) GetName() string

GetName returns the name of the MCP server.

func (BaseMcpServerConfig) GetTimeoutSeconds

func (b BaseMcpServerConfig) GetTimeoutSeconds() *int

GetTimeoutSeconds returns the timeout of the MCP server in seconds.

type BaseMedia

type BaseMedia struct {
	Data        []byte
	MimeType    string
	Description string
}

func (BaseMedia) GetData

func (m BaseMedia) GetData() []byte

func (BaseMedia) GetDescription

func (m BaseMedia) GetDescription() string

func (BaseMedia) GetMimeType

func (m BaseMedia) GetMimeType() string

type BuiltinSlashCommandName

type BuiltinSlashCommandName string
const (
	SlashCommandPlan BuiltinSlashCommandName = "plan"
)

type BuiltinTools

type BuiltinTools string

BuiltinTools identifiers for common connection-provided builtin tools.

const (
	BuiltinListDir       BuiltinTools = "list_directory"
	BuiltinSearchDir     BuiltinTools = "search_directory"
	BuiltinFindFile      BuiltinTools = "find_file"
	BuiltinViewFile      BuiltinTools = "view_file"
	BuiltinCreateFile    BuiltinTools = "create_file"
	BuiltinEditFile      BuiltinTools = "edit_file"
	BuiltinRunCommand    BuiltinTools = "run_command"
	BuiltinAskQuestion   BuiltinTools = "ask_question"
	BuiltinStartSubagent BuiltinTools = "start_subagent"
	BuiltinGenerateImage BuiltinTools = "generate_image"
	BuiltinFinish        BuiltinTools = "finish"
)

func FileBuiltinTools

func FileBuiltinTools() []BuiltinTools

func NondestructiveBuiltinTools

func NondestructiveBuiltinTools() []BuiltinTools

func ReadOnlyBuiltinTools

func ReadOnlyBuiltinTools() []BuiltinTools

type CapabilitiesConfig

type CapabilitiesConfig struct {
	EnableSubagents      bool
	EnabledTools         []BuiltinTools
	DisabledTools        []BuiltinTools
	CompactionThreshold  *int
	ImageModel           string
	FinishToolSchemaJSON *string
}

CapabilitiesConfig general agent capability configuration.

type ChatResponse

type ChatResponse struct {
	// contains filtered or unexported fields
}

ChatResponse wraps the real-time chunk stream from Agent.Chat.

func NewChatResponse

func NewChatResponse(chunks chan StreamChunk, conv Conversation) *ChatResponse

func (*ChatResponse) Cancel

func (r *ChatResponse) Cancel(ctx context.Context) error

func (*ChatResponse) Chunks

func (r *ChatResponse) Chunks() <-chan StreamChunk

func (*ChatResponse) StructuredOutput

func (r *ChatResponse) StructuredOutput() (any, error)

func (*ChatResponse) Text

func (r *ChatResponse) Text() (string, error)

func (*ChatResponse) Thoughts

func (r *ChatResponse) Thoughts() <-chan string

func (*ChatResponse) ToolCalls

func (r *ChatResponse) ToolCalls() <-chan ToolCall

func (*ChatResponse) UsageMetadata

func (r *ChatResponse) UsageMetadata() *UsageMetadata

type Connection

type Connection interface {
	IsIdle() bool
	ConversationID() string
	Send(ctx context.Context, prompt Content) error
	ReceiveSteps(ctx context.Context) <-chan *Step
	Disconnect(ctx context.Context) error
	Cancel(ctx context.Context) error
	Delete(ctx context.Context) error
	SignalIdle(ctx context.Context) error
	WaitForIdle(ctx context.Context) error
	WaitForWakeup(ctx context.Context, timeout time.Duration) (bool, error)
	SendToolResults(ctx context.Context, results []ToolResult) error
	SendTriggerNotification(ctx context.Context, content string) error
}

Connection represents a live session with an agent backend.

type ConnectionStrategy

type ConnectionStrategy interface {
	Start(ctx context.Context) error
	Connect() (Connection, error)
	io.Closer
}

ConnectionStrategy manages starting the backend, connecting, and clean teardown.

type Content

type Content []ContentPrimitive

Content input primitive or sequence of primitives.

type ContentPrimitive

type ContentPrimitive interface {
	// contains filtered or unexported methods
}

ContentPrimitive represents a single piece of user input.

type Conversation

type Conversation interface {
	History() []Step
	LastResponse() string
	TurnCount() int
	CompactionIndices() []int
	ClearHistory()
	GetLastStructuredOutput() any
	CumulativeUsage() UsageMetadata
	TurnUsage() *UsageMetadata
	Cancel(ctx context.Context) error
	Chat(ctx context.Context, prompt Content) (*ChatResponse, error)
	Connection() any
}

Conversation represents a stateful session with the agent.

type ConversationFactory

type ConversationFactory func(conn any) Conversation

ConversationFactory is the factory function for creating conversations.

var NewConversation ConversationFactory

NewConversation is the registered factory to create conversations.

type CustomSystemInstructions

type CustomSystemInstructions struct {
	Text string
}

CustomSystemInstructions replaces the default system instructions entirely.

type Document

type Document struct{ BaseMedia }

type FileChange

type FileChange struct {
	Kind FileChangeKind
	Path string
}

FileChange a single filesystem event.

type FileChangeKind

type FileChangeKind string

FileChangeKind represents the filesystem event type.

const (
	FileChangeAdded    FileChangeKind = "added"
	FileChangeModified FileChangeKind = "modified"
	FileChangeDeleted  FileChangeKind = "deleted"
)

type GeminiConfig

type GeminiConfig struct {
	APIKey   *string
	Vertex   bool
	Project  *string
	Location *string
	Models   ModelConfig
}

GeminiConfig is the configuration for the Gemini model backend.

type GenerationConfig

type GenerationConfig struct {
	ThinkingLevel *ThinkingLevel
}

GenerationConfig contains generation parameters for a model.

type HookResult

type HookResult struct {
	Allow   bool
	Message string
}

HookResult represents the decision of a hook.

type HookRunner

type HookRunner interface {
	RegisterHook(hook any)
}

type Image

type Image struct{ BaseMedia }

type McpServerConfig

type McpServerConfig interface {
	GetName() string
	GetTimeoutSeconds() *int
	// contains filtered or unexported methods
}

McpServerConfig represents an MCP server configuration (Stdio or Http).

type McpStdioServer

type McpStdioServer struct {
	BaseMcpServerConfig
	Command       string
	Args          []string
	Env           map[string]string
	EnabledTools  []string
	DisabledTools []string
}

McpStdioServer is the configuration for an MCP server connected via stdio.

type McpStreamableHttpServer

type McpStreamableHttpServer struct {
	BaseMcpServerConfig
	URL              string
	Headers          map[string]string
	TimeoutSeconds   float64
	SSEReadTimeout   float64
	TerminateOnClose bool
	EnabledTools     []string
	DisabledTools    []string
}

McpStreamableHttpServer is the configuration for an MCP server connected via Http/SSE.

type Media

type Media interface {
	ContentPrimitive
	GetData() []byte
	GetMimeType() string
	GetDescription() string
}

func FromFile

func FromFile(path string, description string) (Media, error)

Helper function to load media from a file path.

type ModelConfig

type ModelConfig struct {
	Default         ModelEntry
	ImageGeneration ModelEntry
}

ModelConfig is the model selection for each capability.

func NewDefaultModelConfig

func NewDefaultModelConfig() ModelConfig

type ModelEntry

type ModelEntry struct {
	Name       string
	APIKey     *string
	Generation GenerationConfig
}

ModelEntry is a model with optional auth and generation overrides.

type QuestionHookResult

type QuestionHookResult struct {
	Responses []QuestionResponse
	Cancelled bool
}

QuestionHookResult contains the results of a question prompt session.

type QuestionResponse

type QuestionResponse struct {
	SelectedOptionIDs []string
	FreeformResponse  string
	Skipped           bool
}

QuestionResponse represents an individual response to an AskQuestion question.

type SlashCommand

type SlashCommand struct {
	Name BuiltinSlashCommandName
}

type Step

type Step struct {
	ID                 string
	StepIndex          int
	Type               StepType
	Source             StepSource
	Target             StepTarget
	Status             StepStatus
	Content            string
	ContentDelta       string
	Thinking           string
	ThinkingDelta      string
	ToolCalls          []ToolCall
	Error              string
	IsCompleteResponse *bool
	StructuredOutput   any
	UsageMetadata      *UsageMetadata
}

Step represents a single event in the agent trajectory.

type StepSource

type StepSource string

StepSource represents the source that generated the step.

const (
	StepSourceSystem  StepSource = "SYSTEM"
	StepSourceUser    StepSource = "USER"
	StepSourceModel   StepSource = "MODEL"
	StepSourceUnknown StepSource = "UNKNOWN"
)

type StepStatus

type StepStatus string

StepStatus represents the status of a step.

const (
	StepStatusActive         StepStatus = "ACTIVE"
	StepStatusDone           StepStatus = "DONE"
	StepStatusWaitingForUser StepStatus = "WAITING_FOR_USER"
	StepStatusError          StepStatus = "ERROR"
	StepStatusCanceled       StepStatus = "CANCELED"
	StepStatusUnknown        StepStatus = "UNKNOWN"
)

type StepTarget

type StepTarget string

StepTarget represents the target interacting with the step.

const (
	StepTargetUser        StepTarget = "TARGET_USER"
	StepTargetEnvironment StepTarget = "TARGET_ENVIRONMENT"
	StepTargetUnspecified StepTarget = "TARGET_UNSPECIFIED"
	StepTargetUnknown     StepTarget = "UNKNOWN"
)

type StepType

type StepType string

StepType represents the high-level type of a step.

const (
	StepTypeTextResponse  StepType = "TEXT_RESPONSE"
	StepTypeToolCall      StepType = "TOOL_CALL"
	StepTypeSystemMessage StepType = "SYSTEM_MESSAGE"
	StepTypeCompaction    StepType = "COMPACTION"
	StepTypeFinish        StepType = "FINISH"
	StepTypeUnknown       StepType = "UNKNOWN"
)

type StreamChunk

type StreamChunk interface {
	GetStepIndex() int
	// contains filtered or unexported methods
}

StreamChunk is the interface for real-time semantic chunks.

type StringContent

type StringContent string

type SystemInstructionSection

type SystemInstructionSection struct {
	Content string
	Title   string
}

SystemInstructionSection is a named section to append to the system instructions.

type SystemInstructions

type SystemInstructions interface {
	// contains filtered or unexported methods
}

SystemInstructions is the interface representing either CustomSystemInstructions or TemplatedSystemInstructions.

type TemplatedSystemInstructions

type TemplatedSystemInstructions struct {
	Identity string
	Sections []SystemInstructionSection
}

TemplatedSystemInstructions overrides the agent identity and appends sections.

type Text

type Text struct {
	StepIndex int
	Text      string
}

Text delta output token.

func (Text) GetStepIndex

func (t Text) GetStepIndex() int

type ThinkingLevel

type ThinkingLevel string

ThinkingLevel for Gemini models that support extended thinking.

const (
	ThinkingMinimal ThinkingLevel = "minimal"
	ThinkingLow     ThinkingLevel = "low"
	ThinkingMedium  ThinkingLevel = "medium"
	ThinkingHigh    ThinkingLevel = "high"
)

type Thought

type Thought struct {
	StepIndex int
	Text      string
	Signature []byte
}

Thought delta reasoning token.

func (Thought) GetStepIndex

func (t Thought) GetStepIndex() int

type ToolCall

type ToolCall struct {
	Name          string         `json:"name"`
	Args          map[string]any `json:"args"`
	ID            *string        `json:"id,omitempty"`
	CanonicalPath *string        `json:"canonical_path,omitempty"`
}

ToolCall represents a tool call.

func (ToolCall) GetStepIndex

func (tc ToolCall) GetStepIndex() int

type ToolResult

type ToolResult struct {
	Name      string  `json:"name"`
	ID        *string `json:"id,omitempty"`
	Result    any     `json:"result,omitempty"`
	Error     *string `json:"error,omitempty"`
	Exception error   `json:"-"`
}

ToolResult represents the result of a tool execution.

type ToolRunner

type ToolRunner interface {
	SetContext(ctx any)
}

type TriggerDelivery

type TriggerDelivery string

TriggerDelivery controls how trigger messages are delivered.

const (
	TriggerDeliverySendImmediately TriggerDelivery = "send_immediately"
	TriggerDeliveryWaitIdle        TriggerDelivery = "wait_idle"
)

type TriggerRunner

type TriggerRunner interface {
	Start(ctx context.Context) error
	Stop()
}

type UsageMetadata

type UsageMetadata struct {
	PromptTokenCount        *uint64
	CachedContentTokenCount *uint64
	CandidatesTokenCount    *uint64
	ThoughtsTokenCount      *uint64
	TotalTokenCount         *uint64
}

UsageMetadata contains token usage counters.

type Video

type Video struct{ BaseMedia }

Directories

Path Synopsis
connections
examples
custom_tools command
hello_world command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL