66 "errors"
77 "fmt"
88 "net/http"
9- "strings"
109 "time"
1110
1211 "github.com/memohai/twilight-ai/internal/utils"
@@ -17,17 +16,15 @@ const (
1716 defaultBaseURL = "https://api.openai.com/v1"
1817
1918 // Output item types for OpenAI Responses API
20- outputTypeMessage = "message"
21- outputTypeReasoning = "reasoning"
22- outputTypeFunctionCall = "function_call"
23- outputTypeImageGeneration = "image_generation_call"
19+ outputTypeMessage = "message"
20+ outputTypeReasoning = "reasoning"
21+ outputTypeFunctionCall = "function_call"
2422)
2523
2624type Provider struct {
27- apiKey string
28- baseURL string
29- httpClient * http.Client
30- prepareRequest func (* http.Request ) error
25+ apiKey string
26+ baseURL string
27+ httpClient * http.Client
3128}
3229
3330type Option func (* Provider )
@@ -36,22 +33,6 @@ func WithAPIKey(apiKey string) Option {
3633 return func (p * Provider ) { p .apiKey = apiKey }
3734}
3835
39- // WithBedrockRegion enables AWS SigV4 authentication for Amazon Bedrock's
40- // OpenAI-compatible endpoint using the default AWS credential chain.
41- func WithBedrockRegion (region string ) Option {
42- return func (p * Provider ) {
43- p .prepareRequest = utils .NewBedrockDefaultCredentialsPreparer (region )
44- }
45- }
46-
47- // WithBedrockCredentials enables AWS SigV4 authentication for Amazon Bedrock's
48- // OpenAI-compatible endpoint using static credentials.
49- func WithBedrockCredentials (region , accessKeyID , secretAccessKey , sessionToken string ) Option {
50- return func (p * Provider ) {
51- p .prepareRequest = utils .NewBedrockStaticCredentialsPreparer (region , accessKeyID , secretAccessKey , sessionToken )
52- }
53- }
54-
5536func WithBaseURL (baseURL string ) Option {
5637 return func (p * Provider ) { p .baseURL = baseURL }
5738}
@@ -78,8 +59,7 @@ func (p *Provider) ListModels(ctx context.Context) ([]sdk.Model, error) {
7859 Method : http .MethodGet ,
7960 BaseURL : p .baseURL ,
8061 Path : "/models" ,
81- Headers : p .authHeaders (),
82- Prepare : p .prepareRequest ,
62+ Headers : utils .AuthHeader (p .apiKey ),
8363 })
8464 if err != nil {
8565 return nil , fmt .Errorf ("openai-responses: list models request failed: %w" , err )
@@ -102,8 +82,7 @@ func (p *Provider) Test(ctx context.Context) *sdk.ProviderTestResult {
10282 BaseURL : p .baseURL ,
10383 Path : "/models" ,
10484 Query : map [string ]string {"limit" : "1" },
105- Headers : p .authHeaders (),
106- Prepare : p .prepareRequest ,
85+ Headers : utils .AuthHeader (p .apiKey ),
10786 })
10887 if err != nil {
10988 return classifyError (err )
@@ -116,8 +95,7 @@ func (p *Provider) TestModel(ctx context.Context, modelID string) (*sdk.ModelTes
11695 Method : http .MethodGet ,
11796 BaseURL : p .baseURL ,
11897 Path : "/models/" + modelID ,
119- Headers : p .authHeaders (),
120- Prepare : p .prepareRequest ,
98+ Headers : utils .AuthHeader (p .apiKey ),
12199 })
122100 if err == nil {
123101 return & sdk.ModelTestResult {Supported : true , Message : "supported" }, nil
@@ -131,8 +109,7 @@ func (p *Provider) TestModel(ctx context.Context, modelID string) (*sdk.ModelTes
131109 Method : http .MethodPost ,
132110 BaseURL : p .baseURL ,
133111 Path : "/responses" ,
134- Headers : p .authHeaders (),
135- Prepare : p .prepareRequest ,
112+ Headers : utils .AuthHeader (p .apiKey ),
136113 Body : map [string ]any {
137114 "model" : modelID ,
138115 "input" : "hi" ,
@@ -166,8 +143,7 @@ func (p *Provider) DoGenerate(ctx context.Context, params sdk.GenerateParams) (*
166143 Method : http .MethodPost ,
167144 BaseURL : p .baseURL ,
168145 Path : "/responses" ,
169- Headers : p .authHeaders (),
170- Prepare : p .prepareRequest ,
146+ Headers : utils .AuthHeader (p .apiKey ),
171147 Body : req ,
172148 })
173149 if err != nil {
@@ -379,7 +355,7 @@ func (p *Provider) parseResponse(resp *responsesResponse) (*sdk.GenerateResult,
379355 Response : sdk.ResponseMetadata {
380356 ID : resp .ID ,
381357 ModelID : resp .Model ,
382- Timestamp : time .Unix (int64 ( resp .CreatedAt ) , 0 ),
358+ Timestamp : time .Unix (resp .CreatedAt , 0 ),
383359 },
384360 }
385361
@@ -443,14 +419,6 @@ func (p *Provider) parseResponse(resp *responsesResponse) (*sdk.GenerateResult,
443419 ToolName : item .Name ,
444420 Input : input ,
445421 })
446-
447- case outputTypeImageGeneration :
448- if data := strings .TrimSpace (item .Result ); data != "" {
449- result .Files = append (result .Files , sdk.GeneratedFile {
450- Data : data ,
451- MediaType : "image/png" ,
452- })
453- }
454422 }
455423 }
456424
@@ -523,8 +491,7 @@ func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sd
523491 Method : http .MethodPost ,
524492 BaseURL : p .baseURL ,
525493 Path : "/responses" ,
526- Headers : p .authHeaders (),
527- Prepare : p .prepareRequest ,
494+ Headers : utils .AuthHeader (p .apiKey ),
528495 Body : req ,
529496 }, func (ev * utils.SSEEvent ) error {
530497 eventType := ev .Event
@@ -546,7 +513,7 @@ func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sd
546513 }
547514 responseID = chunk .Response .ID
548515 responseModel = chunk .Response .Model
549- responseCreated = int64 ( chunk .Response .CreatedAt )
516+ responseCreated = chunk .Response .CreatedAt
550517
551518 case "response.output_item.added" :
552519 var chunk responsesOutputItemAddedChunk
@@ -691,28 +658,6 @@ func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sd
691658 })
692659 }
693660
694- case "response.image_generation_call.completed" :
695- var chunk responsesImageGenCompletedChunk
696- if err := json .Unmarshal ([]byte (ev .Data ), & chunk ); err != nil {
697- return nil
698- }
699- if data := strings .TrimSpace (chunk .Result ); data != "" {
700- if textStartSent {
701- send (& sdk.TextEndPart {ID : responseID })
702- textStartSent = false
703- }
704- if reasoningStartSent {
705- send (& sdk.ReasoningEndPart {ID : responseID })
706- reasoningStartSent = false
707- }
708- send (& sdk.StreamFilePart {
709- File : sdk.GeneratedFile {
710- Data : data ,
711- MediaType : "image/png" ,
712- },
713- })
714- }
715-
716661 case "response.completed" , "response.incomplete" :
717662 var chunk responsesCompletedChunk
718663 if err := json .Unmarshal ([]byte (ev .Data ), & chunk ); err != nil {
@@ -775,16 +720,6 @@ func (p *Provider) DoStream(ctx context.Context, params sdk.GenerateParams) (*sd
775720 return & sdk.StreamResult {Stream : ch }, nil
776721}
777722
778- func (p * Provider ) authHeaders () map [string ]string {
779- if p .prepareRequest != nil {
780- return nil
781- }
782- if p .apiKey == "" {
783- return nil
784- }
785- return utils .AuthHeader (p .apiKey )
786- }
787-
788723// ---------- helpers ----------
789724
790725func mapResponsesFinishReason (incompleteReason string , hasFunctionCall bool ) sdk.FinishReason {
0 commit comments