Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite1c2e00

Browse files
committed
chore: get openai proxy working
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent92385f8 commite1c2e00

File tree

2 files changed

+98
-1547
lines changed

2 files changed

+98
-1547
lines changed

‎aibridged/bridge.go

Lines changed: 98 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import (
1616
"time"
1717

1818
"github.com/anthropics/anthropic-sdk-go"
19-
"github.com/anthropics/anthropic-sdk-go/packages/ssestream"
19+
ant_ssestream"github.com/anthropics/anthropic-sdk-go/packages/ssestream"
2020
"github.com/charmbracelet/log"
2121
"github.com/openai/openai-go"
22+
openai_ssestream"github.com/openai/openai-go/packages/ssestream"
2223
"golang.org/x/xerrors"
2324

2425
"github.com/coder/coder/v2/aibridged/proto"
@@ -61,24 +62,13 @@ func NewBridge(addr string, clientFn func() (proto.DRPCAIBridgeDaemonClient, boo
6162
}
6263

6364
func (b*Bridge)proxyOpenAIRequest(w http.ResponseWriter,r*http.Request) {
64-
body,err:=io.ReadAll(r.Body)
65-
iferr!=nil {
66-
// TODO: error handling.
67-
panic(err)
68-
return
69-
}
70-
r.Body.Close()
71-
72-
varmsg openai.ChatCompletionNewParams
73-
err=json.Unmarshal(body,&msg)
74-
iferr!=nil {
75-
// TODO: error handling.
76-
panic(err)
65+
coderdClient,ok:=b.clientFn()
66+
if!ok {
67+
// TODO: log issue.
68+
http.Error(w,"could not acquire coderd client",http.StatusInternalServerError)
7769
return
7870
}
7971

80-
fmt.Println(msg)
81-
8272
target,err:=url.Parse("https://api.openai.com")
8373
iferr!=nil {
8474
http.Error(w,"failed to parse OpenAI URL",http.StatusInternalServerError)
@@ -103,8 +93,99 @@ func (b *Bridge) proxyOpenAIRequest(w http.ResponseWriter, r *http.Request) {
10393
req.URL.Scheme=target.Scheme
10494
req.URL.Host=target.Host
10595

96+
body,err:=io.ReadAll(req.Body)
97+
iferr!=nil {
98+
http.Error(w,"could not ready request body",http.StatusBadRequest)
99+
return
100+
}
101+
_=req.Body.Close()
102+
103+
varmsg openai.ChatCompletionNewParams
104+
err=json.NewDecoder(bytes.NewReader(body)).Decode(&msg)
105+
iferr!=nil {
106+
http.Error(w,"could not unmarshal request body",http.StatusBadRequest)
107+
return
108+
}
109+
110+
// TODO: robustness
111+
iflen(msg.Messages)>0 {
112+
latest:=msg.Messages[len(msg.Messages)-1]
113+
iflatest.OfUser!=nil {
114+
iflatest.OfUser.Content.OfString.String()!="" {
115+
_,_=coderdClient.TrackUserPrompts(r.Context(),&proto.TrackUserPromptsRequest{
116+
Prompt:strings.TrimSpace(latest.OfUser.Content.OfString.String()),
117+
})
118+
}else {
119+
fmt.Println()
120+
}
121+
}
122+
}
123+
124+
req.Body=io.NopCloser(bytes.NewReader(body))
125+
106126
fmt.Printf("Proxying %s request to: %s\n",req.Method,req.URL.String())
107127
}
128+
proxy.ModifyResponse=func(response*http.Response)error {
129+
body,err:=io.ReadAll(response.Body)
130+
iferr!=nil {
131+
returnxerrors.Errorf("read response body: %w",err)
132+
}
133+
iferr=response.Body.Close();err!=nil {
134+
returnxerrors.Errorf("close body: %w",err)
135+
}
136+
137+
if!strings.Contains(response.Header.Get("Content-Type"),"text/event-stream") {
138+
varmsg openai.ChatCompletion
139+
140+
// TODO: check content-encoding to handle others.
141+
gr,err:=gzip.NewReader(bytes.NewReader(body))
142+
iferr!=nil {
143+
returnxerrors.Errorf("parse gzip-encoded body: %w",err)
144+
}
145+
146+
err=json.NewDecoder(gr).Decode(&msg)
147+
iferr!=nil {
148+
returnxerrors.Errorf("parse non-streaming body: %w",err)
149+
}
150+
151+
_,_=coderdClient.TrackTokenUsage(r.Context(),&proto.TrackTokenUsageRequest{
152+
MsgId:msg.ID,
153+
InputTokens:msg.Usage.PromptTokens,
154+
OutputTokens:msg.Usage.CompletionTokens,
155+
})
156+
157+
response.Body=io.NopCloser(bytes.NewReader(body))
158+
returnnil
159+
}
160+
161+
response.Body=io.NopCloser(bytes.NewReader(body))
162+
stream:=openai_ssestream.NewStream[openai.ChatCompletionChunk](openai_ssestream.NewDecoder(response),nil)
163+
164+
var (
165+
inputToks,outputToksint64
166+
)
167+
168+
varmsg openai.ChatCompletionAccumulator
169+
forstream.Next() {
170+
chunk:=stream.Current()
171+
msg.AddChunk(chunk)
172+
173+
ifmsg.Usage.PromptTokens+msg.Usage.CompletionTokens>0 {
174+
inputToks=msg.Usage.PromptTokens
175+
outputToks=msg.Usage.CompletionTokens
176+
}
177+
}
178+
179+
_,_=coderdClient.TrackTokenUsage(r.Context(),&proto.TrackTokenUsageRequest{
180+
MsgId:msg.ID,
181+
InputTokens:inputToks,
182+
OutputTokens:outputToks,
183+
})
184+
185+
response.Body=io.NopCloser(bytes.NewReader(body))
186+
187+
returnnil
188+
}
108189
proxy.ServeHTTP(w,r)
109190
}
110191

@@ -207,7 +288,7 @@ func (b *Bridge) proxyAnthropicRequest(w http.ResponseWriter, r *http.Request) {
207288
}
208289

209290
response.Body=io.NopCloser(bytes.NewReader(body))
210-
stream:=ssestream.NewStream[anthropic.MessageStreamEventUnion](ssestream.NewDecoder(response),nil)
291+
stream:=ant_ssestream.NewStream[anthropic.MessageStreamEventUnion](ant_ssestream.NewDecoder(response),nil)
211292

212293
var (
213294
inputToks,outputToksint64

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp