Agent Development Kit (ADK)
Build powerful, interoperable AI agents with the Agent-to-Agent (A2A) protocol
β οΈ Early Stage Warning: This project is in its early stages of development. Breaking changes are expected as the API evolves and improves. Please use pinned versions in production environments and be prepared to update your code when upgrading versions.
Table of Contents
Overview
The A2A ADK (Agent Development Kit) is a Go library that simplifies building Agent-to-Agent (A2A) protocol compatible agents. A2A enables seamless communication between AI agents, allowing them to collaborate, delegate tasks, and share capabilities across different systems and providers.
What is A2A?
Agent-to-Agent (A2A) is a standardized protocol that enables AI agents to:
- Communicate with each other using a unified JSON-RPC interface
- Delegate tasks to specialized agents with specific capabilities
- Stream responses in real-time for better user experience
- Authenticate securely using OIDC/OAuth2
- Discover capabilities through standardized agent cards
π Quick Start
Installation
go get github.com/inference-gateway/adk
Examples
For complete working examples, see the examples directory:
Getting Started
To run any example:
cd examples/minimal/server
go run main.go
Each example includes its own README with setup instructions and usage details.
β¨ Key Features
Core Capabilities
- π€ A2A Protocol Compliance: Full implementation of the Agent-to-Agent communication standard
- π Multi-Provider Support: Works with
Anthropic (Claude models), Cloudflare Workers AI, Cohere, DeepSeek, Google (Gemini), Groq, llama.cpp, MiniMax, Mistral, Moonshot, Nvidia, Ollama, Ollama Cloud, OpenAI (GPT models)
, and other LLM providers
- π Real-time Streaming: Stream responses as they're generated from language models
- π§ Custom Tools: Easy integration of custom tools and capabilities
- π§© MCP Client: Connect to MCP servers and expose their tools to the agent through a selector that keeps only tool metadata in context - see docs/mcp.md
- πͺ Callback Hooks: Lifecycle hooks for agent, model, and tool execution with flow control
- π File Artifacts: Support for downloadable file artifacts with filesystem and MinIO storage backends
- π Secure Authentication: Built-in OIDC/OAuth2 authentication support
- π¨ Push Notifications: Webhook notifications for real-time task state updates
- βΈοΈ Task Pausing: Built-in support for input-required state pausing and resumption
- ποΈ Multiple Storage Backends: Support for in-memory and Redis storage with horizontal scaling
- π Usage Metadata: Automatic tracking of LLM token consumption and execution metrics
Developer Experience
- βοΈ Environment Configuration: Simple setup through environment variables
- π Task Management: Built-in task queuing, polling, and lifecycle management
- ποΈ Extensible Architecture: Pluggable components for custom business logic
- π Type-Safe: Generated types from A2A schema for compile-time safety
- π§ͺ Well Tested: Comprehensive test coverage with table-driven tests
Enterprise Ready
- πΏ Lightweight: Optimized binary size for efficient deployment
- π‘οΈ Production Hardened: Configurable timeouts, TLS support, and error handling
- βΈοΈ Cloud Native: Ready for cloud-native deployments and orchestration
- π Observability: OpenTelemetry integration for monitoring and tracing
π οΈ Development
Quick Setup
# Clone the repository
git clone https://github.com/inference-gateway/adk.git
cd adk
# Install dependencies
go mod download
# Install pre-commit hook
task precommit:install
Essential Tasks
| Task |
Description |
task a2a:download-schema |
Download the latest A2A schema |
task a2a:generate-types |
Generate Go types from A2A schema |
task lint |
Run linting and code quality checks |
task test |
Run all tests |
task precommit:install |
Install Git pre-commit hook (recommended) |
The ADK supports injecting agent metadata at build time using Go linker flags (LD flags). This makes agent information immutable and embedded in the binary, which is useful for production deployments.
Available LD Flags
The following build-time metadata variables can be set via LD flags:
BuildAgentName - The agent's display name
BuildAgentDescription - A description of the agent's capabilities
BuildAgentVersion - The agent's version number
Usage Examples
Simple A2A Server Example:
package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
zap "go.uber.org/zap"
server "github.com/inference-gateway/adk/server"
config "github.com/inference-gateway/adk/server/config"
types "github.com/inference-gateway/adk/types"
)
func main() {
fmt.Println("π€ Starting Simple A2A Server...")
// Initialize logger
logger, err := zap.NewDevelopment()
if err != nil {
log.Fatalf("failed to create logger: %v", err)
}
defer logger.Sync()
// Get port from environment or use default
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
// Configuration
cfg := config.Config{
AgentName: "simple-agent",
AgentDescription: "A simple A2A server with default handlers",
AgentVersion: "0.1.0",
Debug: true,
QueueConfig: config.QueueConfig{
CleanupInterval: 5 * time.Minute,
},
ServerConfig: config.ServerConfig{
Port: port,
},
}
// Build and start server with default handlers
a2aServer, err := server.NewA2AServerBuilder(cfg, logger).
WithDefaultTaskHandlers().
WithAgentCard(types.AgentCard{
Name: cfg.AgentName,
Description: cfg.AgentDescription,
Version: cfg.AgentVersion,
URL: fmt.Sprintf("http://localhost:%s", port),
ProtocolVersion: "0.3.0",
Capabilities: types.AgentCapabilities{
Streaming: &[]bool{true}[0],
PushNotifications: &[]bool{false}[0],
StateTransitionHistory: &[]bool{false}[0],
},
DefaultInputModes: []string{"text/plain"},
DefaultOutputModes: []string{"text/plain"},
Skills: []types.AgentSkill{},
}).
Build()
if err != nil {
logger.Fatal("failed to create A2A server", zap.Error(err))
}
logger.Info("β
server created")
// Start server
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
if err := a2aServer.Start(ctx); err != nil {
logger.Fatal("server failed to start", zap.Error(err))
}
}()
logger.Info("π server running on port " + port)
// Wait for shutdown signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("π shutting down...")
// Graceful shutdown
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer shutdownCancel()
if err := a2aServer.Stop(shutdownCtx); err != nil {
logger.Error("shutdown error", zap.Error(err))
} else {
logger.Info("β
goodbye!")
}
}
See the Docker Support section for containerized builds.
For detailed development workflows, testing guidelines, and contribution processes, see the Contributing Guide.
π API Reference
Core Components
A2AServer
The main server interface that handles A2A protocol communication. See server examples for complete implementation details.
A2AServerBuilder
Build A2A servers with custom configurations using a fluent interface. The builder provides methods for:
WithAgent() - Configure AI agent integration
WithDefaultTaskHandlers() - Use built-in task processing
WithBackgroundTaskHandler() - Custom background task handling
WithStreamingTaskHandler() - Custom streaming task handling
WithAgentCardFromFile() - Load agent metadata from JSON
See examples for complete usage patterns.
Task Handler Interfaces
The ADK provides two distinct interfaces for handling tasks:
TaskHandler - For background/polling scenarios (message/send)
StreamableTaskHandler - For real-time streaming scenarios (message/stream)
Streaming handlers require an agent to be configured. See task handler examples for implementation details.
AgentBuilder
Build OpenAI-compatible agents using a fluent interface. Supports:
- Custom LLM clients
- System prompts and conversation limits
- Tool integration
- Callback hooks (BeforeAgent, AfterAgent, BeforeModel, AfterModel, BeforeTool, AfterTool)
- Configuration management
See AI-powered examples and callback examples for complete agent setup.
A2AClient
Client interface for communicating with A2A servers. Supports:
- Task sending and streaming
- Health monitoring
- Agent card retrieval
- Custom configuration
See client examples for usage patterns.
A2A JSON-RPC Methods
Beyond message/send, message/stream, and tasks/get, the client exposes
every method in the A2A JSON-RPC surface. Each snippet below is runnable
against any ADK-built server; see examples/protocol-methods/
for an end-to-end demo that ties them all together.
tasks/cancel
Cancel an in-flight task. Works for tasks in any non-terminal state
(SUBMITTED, WORKING, INPUT_REQUIRED, AUTH_REQUIRED, UNSPECIFIED).
resp, err := a2a.CancelTask(ctx, types.TaskIdParams{ID: taskID})
if err != nil {
log.Fatalf("cancel failed: %v", err)
}
taskBytes, _ := json.Marshal(resp.Result)
var task types.Task
_ = json.Unmarshal(taskBytes, &task)
log.Printf("cancelled task %s β state=%s", task.ID, task.Status.State)
tasks/list
List tasks the server knows about. Limit controls page size (server caps
the limit at 100; default is 50) and Offset controls where the page starts.
Iterate until offset >= TotalSize to walk the full result set.
const pageSize = 20
offset := 0
for {
resp, err := a2a.ListTasks(ctx, types.TaskListParams{
Limit: pageSize,
Offset: offset,
})
if err != nil {
log.Fatalf("list failed: %v", err)
}
listBytes, _ := json.Marshal(resp.Result)
var list types.TaskList
_ = json.Unmarshal(listBytes, &list)
for _, t := range list.Tasks {
log.Printf(" task %s [%s]", t.ID, t.Status.State)
}
offset += len(list.Tasks)
if len(list.Tasks) == 0 || offset >= list.TotalSize {
break
}
}
You can also filter by ContextID or by State (e.g. only
TASK_STATE_COMPLETED); both fields are optional pointers on
TaskListParams.
tasks/pushNotificationConfig/{set,get,list,delete}
Register, inspect, and remove webhook callbacks the server will POST to as a
task changes state. The four methods share a common identifier (task.ID)
and form a complete CRUD cycle.
configID := uuid.New().String()
authToken := "shared-secret"
// set: register a webhook for the task.
if _, err := a2a.SetTaskPushNotificationConfig(ctx, types.TaskPushNotificationConfig{
Name: taskID,
PushNotificationConfig: types.PushNotificationConfig{
ID: &configID,
URL: "https://example.com/webhook",
Token: &authToken,
},
}); err != nil {
log.Fatalf("set failed: %v", err)
}
// get: read the active config.
if _, err := a2a.GetTaskPushNotificationConfig(ctx, types.GetTaskPushNotificationConfigParams{
Name: taskID,
}); err != nil {
log.Fatalf("get failed: %v", err)
}
// list: enumerate every config attached to a task.
if _, err := a2a.ListTaskPushNotificationConfig(ctx, types.ListTaskPushNotificationConfigParams{
Parent: taskID,
}); err != nil {
log.Fatalf("list failed: %v", err)
}
// delete: tear the config down.
if _, err := a2a.DeleteTaskPushNotificationConfig(ctx, types.DeleteTaskPushNotificationConfigParams{
Name: taskID,
}); err != nil {
log.Fatalf("delete failed: %v", err)
}
Server-side push notifications require CapabilitiesConfig.PushNotifications
to be true on the server.
tasks/resubscribe
Re-attach to a streaming task after the original SSE connection has dropped.
The server first re-emits the current task state, then forwards any further
streaming events as they happen.
events, err := a2a.ResubscribeTask(ctx, types.TaskResubscriptionParams{
Name: taskID,
})
if err != nil {
log.Fatalf("resubscribe failed: %v", err)
}
for evt := range events {
payload, _ := json.Marshal(evt.Result)
log.Printf("event: %s", string(payload))
}
agent/getAuthenticatedExtendedCard
The JSON-RPC counterpart to the public .well-known/agent-card.json
endpoint. The response is the same AgentCard object, but the call passes
through the JSON-RPC route and is therefore subject to the server's
authentication middleware - useful when the extended card should only be
visible to authenticated callers.
resp, err := a2a.GetAuthenticatedExtendedCard(ctx, types.GetAuthenticatedExtendedCardParams{})
if err != nil {
log.Fatalf("authenticated card fetch failed: %v", err)
}
cardBytes, _ := json.MarshalIndent(resp.Result, "", " ")
log.Println(string(cardBytes))
Agent Health Monitoring
Monitor agent operational status with three health states:
healthy: Fully operational
degraded: Partially operational
unhealthy: Not operational
See client examples for implementation.
LLM Client
Create OpenAI-compatible LLM clients for agent integration. See AI examples for setup details.
Configuration
Configure your A2A agent using environment variables. All configuration is optional and includes sensible defaults.
Core Server Configuration
| Variable |
Default |
Description |
PORT |
8080 |
Server port |
DEBUG |
false |
Enable debug logging |
AGENT_URL |
http://helloworld-agent:8080 |
Agent URL for internal references |
STREAMING_STATUS_UPDATE_INTERVAL |
1s |
How often to send streaming status updates |
Agent & LLM Configuration
| Variable |
Default |
Description |
AGENT_CLIENT_PROVIDER |
- |
LLM provider (openai, anthropic, groq, etc.) |
AGENT_CLIENT_MODEL |
- |
Model name (e.g., openai/gpt-4) |
AGENT_CLIENT_BASE_URL |
- |
Custom LLM endpoint URL |
AGENT_CLIENT_API_KEY |
- |
API key for LLM provider |
AGENT_CLIENT_TIMEOUT |
30s |
Request timeout |
AGENT_CLIENT_MAX_RETRIES |
3 |
Maximum retry attempts |
AGENT_CLIENT_MAX_CHAT_COMPLETION_ITERATIONS |
50 |
Max chat completion rounds |
AGENT_CLIENT_MAX_TOKENS |
4096 |
Maximum tokens per response |
AGENT_CLIENT_TEMPERATURE |
0.7 |
LLM temperature (0.0-2.0) |
AGENT_CLIENT_SYSTEM_PROMPT |
- |
System prompt for the agent |
AGENT_CLIENT_ENABLE_USAGE_METADATA |
true |
Track token usage and execution metrics |
Agent Capabilities
| Variable |
Default |
Description |
CAPABILITIES_STREAMING |
true |
Enable streaming responses |
CAPABILITIES_PUSH_NOTIFICATIONS |
false |
Enable webhook notifications |
CAPABILITIES_STATE_TRANSITION_HISTORY |
false |
Track state changes |
Authentication (Optional)
| Variable |
Default |
Description |
AUTH_ENABLED |
false |
Enable OIDC authentication |
AUTH_ISSUER_URL |
- |
OIDC issuer URL |
AUTH_CLIENT_ID |
- |
OIDC client ID |
AUTH_CLIENT_SECRET |
- |
OIDC client secret |
See docs/authentication.md for the full card-driven auth flow: discovery, out-of-band credentials, the authenticated extended card, and authorization via callbacks.
Task Management
| Variable |
Default |
Description |
TASK_RETENTION_MAX_COMPLETED_TASKS |
100 |
Max completed tasks to keep (0 = unlimited) |
TASK_RETENTION_MAX_FAILED_TASKS |
50 |
Max failed tasks to keep (0 = unlimited) |
TASK_RETENTION_CLEANUP_INTERVAL |
5m |
Cleanup frequency (0 = manual only) |
Storage Configuration (Optional)
| Variable |
Default |
Description |
QUEUE_PROVIDER |
memory |
Storage backend: memory or redis |
QUEUE_URL |
- |
Redis connection URL (required when using Redis) |
QUEUE_MAX_SIZE |
100 |
Maximum queue size |
QUEUE_CLEANUP_INTERVAL |
120s |
How often to clean up completed tasks |
Storage Backends:
- Memory Storage (Default): Fast in-memory storage for development and single-instance deployments
- Redis Storage: Persistent storage with horizontal scaling support for production deployments
Redis Configuration Examples:
# Basic Redis setup
export QUEUE_PROVIDER=redis
export QUEUE_URL=redis://localhost:6379
# Redis with authentication
export QUEUE_URL=redis://:password@localhost:6379
export QUEUE_URL=redis://username:password@localhost:6379
# Redis with specific database
export QUEUE_URL=redis://localhost:6379/1
# Redis with TLS (Redis 6.0+)
export QUEUE_URL=rediss://username:password@redis.example.com:6380/0
MCP Client Configuration (Optional)
Connect the agent to MCP servers and expose their tools through a selector that keeps only tool metadata in the LLM context. Disabled by default and only useful when an LLM is configured. Enable with MCP_ENABLED=true and point MCP_SERVERS at one or more streamable-HTTP MCP servers; the full list of MCP_* variables (timeouts, retry, and polling-backoff tuning) is documented in docs/mcp.md.
Artifacts Configuration (Optional)
Enable file artifacts support for downloadable files generated by your agent:
| Variable |
Default |
Description |
ARTIFACTS_ENABLED |
false |
Enable artifacts support |
ARTIFACTS_SERVER_HOST |
localhost |
Artifacts server host |
ARTIFACTS_SERVER_PORT |
8081 |
Artifacts server port |
ARTIFACTS_STORAGE_PROVIDER |
filesystem |
Storage backend: filesystem or minio |
ARTIFACTS_STORAGE_BASE_PATH |
./artifacts |
Base path for filesystem storage |
ARTIFACTS_STORAGE_BASE_URL |
(auto-generated) |
Override base URL for direct downloads |
ARTIFACTS_STORAGE_ENDPOINT |
- |
MinIO/S3 endpoint URL |
ARTIFACTS_STORAGE_ACCESS_KEY |
- |
MinIO/S3 access key |
ARTIFACTS_STORAGE_SECRET_KEY |
- |
MinIO/S3 secret key |
ARTIFACTS_STORAGE_BUCKET_NAME |
artifacts |
MinIO/S3 bucket name |
ARTIFACTS_STORAGE_USE_SSL |
true |
Use SSL for MinIO/S3 connections |
ARTIFACTS_RETENTION_MAX_ARTIFACTS |
5 |
Max artifacts per task (0 = unlimited) |
ARTIFACTS_RETENTION_MAX_AGE |
7d |
Max artifact age (0 = no age limit) |
ARTIFACTS_RETENTION_CLEANUP_INTERVAL |
24h |
Cleanup frequency (0 = manual only) |
Storage Backends:
- Filesystem Storage (Default): Store artifacts locally on disk, suitable for single-instance deployments
- MinIO Storage: Cloud-native object storage with S3 compatibility, ideal for distributed deployments
Download Modes:
- Proxy Mode (Default): Downloads go through the artifacts server (port 8081) with authentication and logging
- Direct Mode: Configure
ARTIFACTS_STORAGE_BASE_URL to enable direct downloads from storage backend
MinIO Configuration Example:
# Enable artifacts with MinIO storage
export ARTIFACTS_ENABLED=true
export ARTIFACTS_STORAGE_PROVIDER=minio
export ARTIFACTS_STORAGE_ENDPOINT=localhost:9000
export ARTIFACTS_STORAGE_ACCESS_KEY=minioadmin
export ARTIFACTS_STORAGE_SECRET_KEY=minioadmin
export ARTIFACTS_STORAGE_USE_SSL=false
# Optional: Enable direct downloads (bypasses artifacts server)
export ARTIFACTS_STORAGE_BASE_URL=http://localhost:9000
Benefits of Redis Storage:
- β
Persistent Tasks - Tasks survive server restarts
- β
Distributed Processing - Multiple server instances can share the same queue
- β
High Performance - Redis provides fast task queuing and retrieval
- β
Task History - Completed and failed tasks are retained based on configuration
- β
Horizontal Scaling - Scale to N number of A2A servers processing the same queue
TLS Configuration (Optional)
| Variable |
Default |
Description |
SERVER_TLS_ENABLED |
false |
Enable TLS/HTTPS |
SERVER_TLS_CERT_PATH |
- |
Path to TLS certificate |
SERVER_TLS_KEY_PATH |
- |
Path to TLS private key |
Telemetry (Optional)
When enabled, the server exports metrics (Prometheus pull or OTLP push) and can export traces via OTLP over HTTP or gRPC. It also participates in W3C Trace Context propagation: incoming traceparent and baggage headers are extracted, a request-scoped a2a.request span is created, and the session.id / gen_ai.tool.call.id baggage items are surfaced as span attributes. Exporters are selected with the standard OTEL_* variables; the original TELEMETRY_* variables remain supported as deprecated aliases. See docs/telemetry.md for the full matrix.
TELEMETRY_ENABLED=true is the master switch; the OTEL_* variables then choose which exporters run per signal.
| Variable |
Default |
Description |
TELEMETRY_ENABLED |
false |
Master switch for the telemetry subsystem |
OTEL_METRICS_EXPORTER |
prometheus |
Metrics exporter: prometheus, otlp, or none |
OTEL_TRACES_EXPORTER |
otlp |
Traces exporter: otlp or none |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:4318 |
OTLP endpoint base URL for traces and metrics |
OTEL_EXPORTER_OTLP_PROTOCOL |
http/protobuf |
OTLP transport: http/protobuf or grpc |
OTEL_EXPORTER_PROMETHEUS_HOST |
- |
Prometheus pull host (empty = all interfaces) |
OTEL_EXPORTER_PROMETHEUS_PORT |
9090 |
Prometheus pull port |
Attribute keys (default to OTel semantic conventions; used for both the baggage member and the span attribute):
| Variable |
Default |
Description |
TELEMETRY_ATTR_SESSION_ID_KEY |
session.id |
Session id baggage/attribute key |
TELEMETRY_ATTR_TOOL_CALL_ID_KEY |
gen_ai.tool.call.id |
Tool call id baggage/attribute key |
Deprecated aliases (superseded by the OTEL_* variables above, still honored):
| Variable |
Default |
Superseded by |
TELEMETRY_METRICS_PORT |
9090 |
OTEL_EXPORTER_PROMETHEUS_PORT |
TELEMETRY_METRICS_HOST |
- |
OTEL_EXPORTER_PROMETHEUS_HOST |
TELEMETRY_TRACE_ENDPOINT |
http://localhost:4318 |
OTEL_EXPORTER_OTLP_ENDPOINT |
TELEMETRY_TRACE_HEADERS |
- |
OTEL_EXPORTER_OTLP_HEADERS |
TELEMETRY_LOG_* |
- |
Reserved - OTLP log export not yet wired |
The tracing service name is taken from the agent card name (the build-time agent identity), not a separate variable.
Library consumers that already run their own OpenTelemetry setup can inject it with WithTelemetry() instead of letting the ADK build one from the environment. The injected instance activates the middleware, request spans, and /metrics endpoint regardless of TELEMETRY_ENABLED:
srv, err := server.NewA2AServerBuilder(cfg, logger).
WithTelemetry(myOtel).
WithAgentCard(card).
WithDefaultTaskHandlers().
Build()
Example Configuration
See configuration examples for complete setup patterns, including environment variables, custom config structs, and programmatic overrides.
π§ Advanced Usage
For detailed implementation examples and patterns, see the examples directory:
π A2A Ecosystem
This ADK is part of the broader Inference Gateway ecosystem:
A2A Agents
π Requirements
- Go: 1.26 or later
- Dependencies: See go.mod for full dependency list
π³ Docker Support
Build and run your A2A agent application in a container. Here's an example Dockerfile for an application using the ADK:
FROM golang:1.26-alpine AS builder
# Build arguments for agent metadata
ARG AGENT_NAME="My A2A Agent"
ARG AGENT_DESCRIPTION="A custom A2A agent built with the ADK"
ARG AGENT_VERSION="0.1.0"
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go mod tidy && \
go build -ldflags "-X 'github.com/inference-gateway/adk/server.BuildAgentName=${AGENT_NAME}' -X 'github.com/inference-gateway/adk/server.BuildAgentDescription=${AGENT_DESCRIPTION}' -X 'github.com/inference-gateway/adk/server.BuildAgentVersion=${AGENT_VERSION}'" -o bin/agent .
FROM alpine:latest
RUN apk --no-cache add ca-certificates && \
addgroup -g 1001 -S a2a && \
adduser -u 1001 -S agent -G a2a
WORKDIR /home/agent
COPY --from=builder /app/bin/agent .
RUN chown agent:a2a ./agent
USER agent
CMD ["./agent"]
Build with custom metadata:
docker build \
--build-arg AGENT_NAME="Weather Assistant" \
--build-arg AGENT_DESCRIPTION="AI-powered weather forecasting agent" \
--build-arg AGENT_VERSION="0.1.1" \
-t my-a2a-agent .
π License
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
π€ Contributing
Contributions to the A2A ADK are welcome! Whether you're fixing bugs, adding features, improving documentation, or helping with testing, your contributions make the project better for everyone.
Please see the Contributing Guide for:
- π Getting Started - Development environment setup and prerequisites
- π Development Workflow - Step-by-step development process and tools
- π― Coding Guidelines - Code style, testing patterns, and best practices
- π οΈ Making Changes - Branch naming, commit format, and submission process
- π§ͺ Testing Guidelines - Test structure, mocking, and coverage requirements
- π Pull Request Process - Review process and submission checklist
Quick Start for Contributors:
# Fork the repo and clone it
git clone https://github.com/your-username/adk.git
cd adk
# Install pre-commit hook
task precommit:install
For questions or help getting started, please open a discussion or check out the contributing guide.
π Support
Issues & Questions
π Resources
Documentation
GitHub β’
Documentation