package llm import ( "context" "errors" "fmt" "strings" "time" "github.com/geo-platform/tenant-api/internal/shared/config" ) var ErrNotConfigured = errors.New("llm provider is not configured") type GenerateRequest struct { Model string Prompt string Timeout time.Duration MaxOutputTokens int64 WebSearch *WebSearchOptions ResponseFormat *ResponseFormat } type GenerateResult struct { Content string Model string } type ResponseFormat struct { Type ResponseFormatType Name string Description string SchemaJSON []byte Strict bool } type ResponseFormatType string const ( ResponseFormatTypeText ResponseFormatType = "text" ResponseFormatTypeJSONObject ResponseFormatType = "json_object" ResponseFormatTypeJSONSchema ResponseFormatType = "json_schema" ) type WebSearchOptions struct { Enabled bool Limit int32 } type Client interface { Validate() error Generate(ctx context.Context, req GenerateRequest, onDelta func(string)) (*GenerateResult, error) } func New(cfg config.LLMConfig) Client { provider := strings.ToLower(strings.TrimSpace(cfg.Provider)) switch provider { case "", "disabled": return disabledClient{reason: "llm provider is disabled"} case "ark": return NewArkClient(cfg) default: return disabledClient{reason: fmt.Sprintf("unsupported llm provider %q", cfg.Provider)} } } type disabledClient struct { reason string } func (c disabledClient) Validate() error { if c.reason == "" { c.reason = "missing LLM configuration" } return fmt.Errorf("%w: %s", ErrNotConfigured, c.reason) } func (c disabledClient) Generate(context.Context, GenerateRequest, func(string)) (*GenerateResult, error) { return nil, c.Validate() }