Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Forge handles the **LLM call → tool execution → response** cycle. You supply
go get github.com/katasec/forge
go get github.com/katasec/forge/provider/anthropic # optional
go get github.com/katasec/forge/provider/openai # optional
go get github.com/katasec/forge/provider/xai # optional — xAI Responses API with web search
```

## Quick Start
Expand Down Expand Up @@ -63,13 +64,29 @@ import "github.com/katasec/forge/provider/openai"
provider := openai.New("https://api.x.ai/v1", os.Getenv("XAI_API_KEY"), "grok-3-mini")
```

The `openai` package works with any OpenAI-compatible API (xAI, OpenAI, Together, Groq, etc.). See [`_examples/hello-world`](./_examples/hello-world) for the full runnable code.
The `openai` package works with any OpenAI-compatible API (xAI, OpenAI, Together, Groq, etc.).

Or use the xAI Responses API with built-in web search:

```go
import "github.com/katasec/forge/provider/xai"

provider := xai.New(os.Getenv("XAI_API_KEY"), "grok-4-1-fast-non-reasoning", xai.WithWebSearch())

// After running the agent, access citations:
citations := provider.LastCitations()
for _, c := range citations {
fmt.Printf("[%s] %s\n", c.Title, c.URL)
}
```

See [`_examples/hello-world`](./_examples/hello-world) for the full runnable code.

## Core Concepts

### Provider

The `Provider` interface makes a single LLM call. Forge ships with two built-in providers, or you can implement your own:
The `Provider` interface makes a single LLM call. Forge ships with three built-in providers, or you can implement your own:

```go
type Provider interface {
Expand Down
29 changes: 26 additions & 3 deletions _examples/hello-world/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
// export ANTHROPIC_API_KEY=sk-ant-...
// go run .
//
// # Or use xAI instead:
// # Or use xAI (OpenAI-compatible) instead:
// export XAI_API_KEY=xai-...
// go run . -provider xai
//
// # Or use xAI Responses API with web search:
// export XAI_API_KEY=xai-...
// go run . -provider xai-search
package main

import (
Expand All @@ -23,14 +27,16 @@ import (
"github.com/katasec/forge"
"github.com/katasec/forge/provider/anthropic"
"github.com/katasec/forge/provider/openai"
"github.com/katasec/forge/provider/xai"
)

func main() {
providerFlag := flag.String("provider", "anthropic", "Provider to use: anthropic or xai")
providerFlag := flag.String("provider", "anthropic", "Provider to use: anthropic, xai, or xai-search")
flag.Parse()

// Pick your provider — this is the only thing that changes.
var provider forge.Provider
var xaiProvider *xai.Provider // for citation access
switch *providerFlag {
case "anthropic":
key := os.Getenv("ANTHROPIC_API_KEY")
Expand All @@ -44,8 +50,15 @@ func main() {
log.Fatal("Set XAI_API_KEY environment variable")
}
provider = openai.New("https://api.x.ai/v1", key, "grok-3-mini")
case "xai-search":
key := os.Getenv("XAI_API_KEY")
if key == "" {
log.Fatal("Set XAI_API_KEY environment variable")
}
xaiProvider = xai.New(key, "grok-4-1-fast-non-reasoning", xai.WithWebSearch())
provider = xaiProvider
default:
log.Fatalf("Unknown provider: %s (use 'anthropic' or 'xai')", *providerFlag)
log.Fatalf("Unknown provider: %s (use 'anthropic', 'xai', or 'xai-search')", *providerFlag)
}

// Build the agent — same code regardless of provider.
Expand All @@ -69,4 +82,14 @@ func main() {

fmt.Println(resp.Messages[len(resp.Messages)-1].Content)
fmt.Printf("\n[%s | tokens: %d in, %d out]\n", *providerFlag, resp.Usage.InputTokens, resp.Usage.OutputTokens)

// Show citations if using xai-search.
if xaiProvider != nil {
if citations := xaiProvider.LastCitations(); len(citations) > 0 {
fmt.Println("\nSources:")
for i, c := range citations {
fmt.Printf(" [%d] %s — %s\n", i+1, c.Title, c.URL)
}
}
}
}
1 change: 1 addition & 0 deletions docs/design/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Sub-packages hold swappable backend implementations (following the `database/sql
forge/ root — interfaces, types, Agent, Config, defaults
forge/provider/anthropic/ Anthropic Messages API provider
forge/provider/openai/ OpenAI-compatible provider (OpenAI, xAI, Together, Groq)
forge/provider/xai/ xAI Responses API provider (web search, X search, citations)
```

Future sub-packages (created when implementations exist, not preemptively):
Expand Down
Loading
Loading