Skip to content
Open
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
100 changes: 100 additions & 0 deletions providers/atlascloud/atlascloud.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Package atlascloud provides an implementation of the fantasy AI SDK for Atlas Cloud's OpenAI-compatible language models.
package atlascloud

import (
"charm.land/fantasy"
"charm.land/fantasy/providers/openaicompat"
"github.com/charmbracelet/openai-go/option"
)

const (
// DefaultURL is the default URL for the Atlas Cloud LLM API.
DefaultURL = "https://api.atlascloud.ai/v1"
// Name is the name of the Atlas Cloud provider.
Name = "atlascloud"
)

type options struct {
openaicompatOptions []openaicompat.Option
}

// Option defines a function that configures Atlas Cloud provider options.
type Option = func(*options)

// New creates a new Atlas Cloud provider with the given options.
func New(opts ...Option) (fantasy.Provider, error) {
providerOptions := options{
openaicompatOptions: []openaicompat.Option{
openaicompat.WithName(Name),
openaicompat.WithBaseURL(DefaultURL),
},
}
for _, o := range opts {
o(&providerOptions)
}
return openaicompat.New(providerOptions.openaicompatOptions...)
}

// WithAPIKey sets the API key for the Atlas Cloud provider.
func WithAPIKey(apiKey string) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithAPIKey(apiKey))
}
}

// WithBaseURL sets the base URL for the Atlas Cloud provider.
func WithBaseURL(url string) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithBaseURL(url))
}
}

// WithName sets the name for the Atlas Cloud provider.
func WithName(name string) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithName(name))
}
}

// WithHeaders sets the headers for the Atlas Cloud provider.
func WithHeaders(headers map[string]string) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithHeaders(headers))
}
}

// WithHTTPClient sets the HTTP client for the Atlas Cloud provider.
func WithHTTPClient(client option.HTTPClient) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithHTTPClient(client))
}
}

// WithUserAgent sets an explicit User-Agent header, overriding the default and any
// value set via WithHeaders.
func WithUserAgent(ua string) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithUserAgent(ua))
}
}

// WithObjectMode sets the object generation mode for the Atlas Cloud provider.
func WithObjectMode(om fantasy.ObjectMode) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithObjectMode(om))
}
}

// WithUseResponsesAPI configures the provider to use the responses API for models that support it.
func WithUseResponsesAPI() Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithUseResponsesAPI())
}
}

// WithResponsesAPIFunc sets a custom filter for which models use the Responses API.
func WithResponsesAPIFunc(fn func(modelID string) bool) Option {
return func(o *options) {
o.openaicompatOptions = append(o.openaicompatOptions, openaicompat.WithResponsesAPIFunc(fn))
}
}
85 changes: 85 additions & 0 deletions providers/atlascloud/atlascloud_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package atlascloud

import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"

"charm.land/fantasy"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestProviderName(t *testing.T) {
t.Parallel()

provider, err := New(WithAPIKey("k"))
require.NoError(t, err)
model, err := provider.LanguageModel(t.Context(), "qwen/qwen3.5-flash")
require.NoError(t, err)

assert.Equal(t, Name, model.Provider())
}

func TestDefaultRequest(t *testing.T) {
t.Parallel()

var captured []map[string]string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := make(map[string]string)
for k, v := range r.Header {
if len(v) > 0 {
h[k] = v[0]
}
}
captured = append(captured, h)

w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"id": "chatcmpl-test",
"object": "chat.completion",
"created": 1711115037,
"model": "qwen/qwen3.5-flash",
"choices": []map[string]any{
{
"index": 0,
"message": map[string]any{
"role": "assistant",
"content": "Hi there",
},
"finish_reason": "stop",
},
},
"usage": map[string]any{
"prompt_tokens": 4,
"completion_tokens": 2,
"total_tokens": 6,
},
})
}))
defer server.Close()

provider, err := New(WithAPIKey("k"), WithBaseURL(server.URL))
require.NoError(t, err)

model, err := provider.LanguageModel(t.Context(), "qwen/qwen3.5-flash")
require.NoError(t, err)

_, err = model.Generate(t.Context(), fantasy.Call{
Prompt: fantasy.Prompt{
{
Role: fantasy.MessageRoleUser,
Content: []fantasy.MessagePart{
fantasy.TextPart{Text: "Hi"},
},
},
},
})
require.NoError(t, err)

require.Len(t, captured, 1)
assert.Equal(t, "Bearer k", captured[0]["Authorization"])
assert.True(t, strings.HasPrefix(captured[0]["User-Agent"], "Charm-Fantasy/"))
}
21 changes: 21 additions & 0 deletions providers/atlascloud/provider_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package atlascloud

import (
"charm.land/fantasy"
"charm.land/fantasy/providers/openaicompat"
)

// ProviderOptions represents additional options for the Atlas Cloud provider.
type ProviderOptions = openaicompat.ProviderOptions

// NewProviderOptions creates new provider options for Atlas Cloud.
func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
return fantasy.ProviderOptions{
Name: opts,
}
}

// ParseOptions parses provider options from a map for Atlas Cloud.
func ParseOptions(data map[string]any) (*ProviderOptions, error) {
return openaicompat.ParseOptions(data)
}
2 changes: 2 additions & 0 deletions providertests/provider_registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"charm.land/fantasy"
"charm.land/fantasy/providers/anthropic"
"charm.land/fantasy/providers/atlascloud"
"charm.land/fantasy/providers/google"
"charm.land/fantasy/providers/openai"
"charm.land/fantasy/providers/openaicompat"
Expand Down Expand Up @@ -354,6 +355,7 @@ func TestProviderRegistry_AllTypesRegistered(t *testing.T) {
{"Google Options", google.Name, &google.ProviderOptions{}},
{"OpenRouter Options", openrouter.Name, &openrouter.ProviderOptions{}},
{"OpenAICompat Options", openaicompat.Name, &openaicompat.ProviderOptions{}},
{"AtlasCloud Options", atlascloud.Name, &atlascloud.ProviderOptions{}},
}

for _, tc := range tests {
Expand Down
Loading