Quickstart
Installation
go get github.com/zoobz-io/chit
Requires Go 1.21 or later.
Basic Usage
A minimal chat application needs three things: a processor (your brain), an emitter (your output), and the chat controller.
package main
import (
"context"
"fmt"
"github.com/zoobz-io/chit"
"github.com/zoobz-io/zyn"
)
func main() {
// 1. Define your processor — this is where reasoning happens
processor := chit.ProcessorFunc(func(ctx context.Context, input string, session *zyn.Session) (chit.Result, error) {
// Your LLM call, tool execution, or other logic goes here
return &chit.Response{Content: "You said: " + input}, nil
})
// 2. Define your emitter — this is where output goes
emitter := &PrintEmitter{}
// 3. Create the chat
chat := chit.New(processor, emitter,
chit.WithSystemPrompt("You are a helpful assistant."),
)
// 4. Handle user input
ctx := context.Background()
_ = chat.Handle(ctx, "Hello!")
// Output: You said: Hello!
}
// PrintEmitter writes messages to stdout
type PrintEmitter struct{}
func (e *PrintEmitter) Emit(_ context.Context, msg chit.Message) error {
fmt.Println(msg.Content)
return nil
}
func (e *PrintEmitter) Push(_ context.Context, _ chit.Resource) error {
return nil
}
func (e *PrintEmitter) Close() error {
return nil
}
The Processor
The processor is your pluggable brain. It receives user input and conversation history, then returns either a Response (complete) or a Yield (awaiting more input).
processor := chit.ProcessorFunc(func(ctx context.Context, input string, session *zyn.Session) (chit.Result, error) {
// Access conversation history
messages := session.Messages()
// Return a complete response
return &chit.Response{
Content: "Hello!",
Metadata: map[string]any{"model": "gpt-4"},
}, nil
})
Wire your own reasoning stack here — cogito for thinking, ago for actions, scio for data. See the Concepts guide for more.
Multi-Turn Conversations
When your processor needs more information, yield with a continuation:
processor := chit.ProcessorFunc(func(ctx context.Context, input string, session *zyn.Session) (chit.Result, error) {
if input == "start" {
return &chit.Yield{
Prompt: "What's your name?",
Continuation: func(ctx context.Context, name string) (chit.Result, error) {
return &chit.Response{Content: "Hello, " + name + "!"}, nil
},
}, nil
}
return &chit.Response{Content: "Say 'start' to begin."}, nil
})
The chat controller stores the continuation. The next call to Handle() resumes from where you left off. See the Testing guide for YieldingProcessor helper.
Streaming Resources
Processors can push structured data alongside text responses by retrieving the emitter from context:
processor := chit.ProcessorFunc(func(ctx context.Context, input string, session *zyn.Session) (chit.Result, error) {
// Get emitter from context
emitter := chit.EmitterFromContext(ctx)
// Push structured data to client
if emitter != nil {
emitter.Push(ctx, chit.Resource{
Type: "data",
URI: "db://users/123",
Payload: map[string]string{"name": "Alice"},
})
}
return &chit.Response{Content: "Found user Alice."}, nil
})
Configuration Options
chat := chit.New(processor, emitter,
chit.WithSystemPrompt("You are a helpful assistant."),
chit.WithSession(existingSession), // Use existing zyn.Session
chit.WithMetadata(map[string]any{"user_id": "123"}),
chit.WithConfig(&chit.Config{
SystemPrompt: "Custom prompt",
Metadata: map[string]any{"version": "1.0"},
}),
)
Reliability Options
Chit uses pipz for composable reliability patterns. Add them as options:
chat := chit.New(processor, emitter,
chit.WithSystemPrompt("You are helpful."),
// Middleware (runs before processor)
chit.WithMiddleware(
chit.UseValidation(4096), // Reject inputs over 4096 chars
),
// Reliability wrappers
chit.WithRetry(3), // Retry up to 3 times
chit.WithTimeout(30 * time.Second), // 30s timeout
chit.WithRateLimit(10, 5), // 10 req/s, burst of 5
chit.WithCircuitBreaker(5, 30*time.Second), // Open after 5 failures
)
See the Reliability Guide for custom middleware and advanced patterns.
Next Steps
- Concepts — understand Chat, Processor, Emitter, and Result
- Architecture — how the lifecycle works internally
- Reliability Guide — retry, timeout, middleware
- Testing Guide — mocks and helpers for testing
- API Reference — complete function documentation