mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
fix: emit Responses API lifecycle events in mock OpenAI server (#22702)
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/openai/openai-go/v3/responses"
|
||||
)
|
||||
|
||||
// OpenAIHandler handles OpenAI API requests and returns a response.
|
||||
@@ -306,6 +307,17 @@ func writeChatCompletionsStreaming(w http.ResponseWriter, r *http.Request, chunk
|
||||
}
|
||||
}
|
||||
|
||||
// writeSSEEvent marshals v as JSON and writes it as an SSE data
|
||||
// frame. Returns any write error.
|
||||
func writeSSEEvent(w http.ResponseWriter, v interface{}) error {
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, "data: %s\n\n", data)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeResponsesAPIStreaming(w http.ResponseWriter, r *http.Request, chunks <-chan OpenAIChunk) {
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
@@ -329,7 +341,23 @@ func writeResponsesAPIStreaming(w http.ResponseWriter, r *http.Request, chunks <
|
||||
return
|
||||
case chunk, ok = <-chunks:
|
||||
if !ok {
|
||||
_, _ = fmt.Fprintf(w, "data: [DONE]\n\n")
|
||||
// Emit Responses API lifecycle events so
|
||||
// the fantasy client closes open text
|
||||
// blocks and persists the step content.
|
||||
for outputIndex, itemID := range itemIDs {
|
||||
_ = writeSSEEvent(w, responses.ResponseTextDoneEvent{
|
||||
ItemID: itemID,
|
||||
OutputIndex: int64(outputIndex),
|
||||
})
|
||||
_ = writeSSEEvent(w, responses.ResponseOutputItemDoneEvent{
|
||||
OutputIndex: int64(outputIndex),
|
||||
Item: responses.ResponseOutputItemUnion{
|
||||
ID: itemID,
|
||||
Type: "message",
|
||||
},
|
||||
})
|
||||
}
|
||||
_ = writeSSEEvent(w, responses.ResponseCompletedEvent{})
|
||||
flusher.Flush()
|
||||
return
|
||||
}
|
||||
@@ -344,6 +372,19 @@ func writeResponsesAPIStreaming(w http.ResponseWriter, r *http.Request, chunks <
|
||||
if !found {
|
||||
itemID = fmt.Sprintf("msg_%s", uuid.New().String()[:8])
|
||||
itemIDs[outputIndex] = itemID
|
||||
|
||||
// Emit response.output_item.added so the
|
||||
// fantasy client triggers TextStart.
|
||||
if err := writeSSEEvent(w, responses.ResponseOutputItemAddedEvent{
|
||||
OutputIndex: int64(outputIndex),
|
||||
Item: responses.ResponseOutputItemUnion{
|
||||
ID: itemID,
|
||||
Type: "message",
|
||||
},
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
flusher.Flush()
|
||||
}
|
||||
|
||||
chunkData := map[string]interface{}{
|
||||
|
||||
@@ -490,6 +490,7 @@ require (
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/go-git/go-git/v5 v5.16.5
|
||||
github.com/mark3labs/mcp-go v0.38.0
|
||||
github.com/openai/openai-go/v3 v3.15.0
|
||||
github.com/sergi/go-diff v1.4.0
|
||||
gonum.org/v1/gonum v0.17.0
|
||||
)
|
||||
@@ -574,7 +575,6 @@ require (
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/openai/openai-go v1.12.0 // indirect
|
||||
github.com/openai/openai-go/v2 v2.7.1 // indirect
|
||||
github.com/openai/openai-go/v3 v3.15.0 // indirect
|
||||
github.com/package-url/packageurl-go v0.1.3 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
|
||||
Reference in New Issue
Block a user