File#264
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class file upload + file-aware chat requests by introducing a /v1/files endpoint, extending the “official” request schema to support multimodal content/attachments, and updating the ChatGPT upstream request conversion to include attachment metadata.
Changes:
- Extend
typings/officialrequest message content to support text-or-parts JSON and extract referenced files. - Add
/v1/filesupload handler and an internal ChatGPT upload implementation + in-memory lookup for enriching attachment metadata. - Update ChatGPT request typings/conversion to send multimodal parts/metadata; document + add an integration test for file QA.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| typings/official/request.go | Introduces APIMessage/MessageContent supporting multimodal parts and file extraction helpers. |
| typings/chatgpt/request.go | Allows ChatGPT request parts to be []interface{} and adds multimodal message support. |
| conversion/requests/chatgpt/convert.go | Builds multimodal ChatGPT message payloads with attachments metadata from official messages. |
| internal/chatgpt/files.go | Implements ChatGPT file upload flow and caches uploaded file metadata for later enrichment. |
| initialize/router.go | Adds CORS preflight + authenticated route for /v1/files. |
| initialize/handlers.go | Adds /v1/files handler and routes token selection through a shared helper; updates token counting for multimodal messages. |
| tests/test_file_qa.py | Adds an integration test that uploads a file then queries it via input_file content parts. |
| README.md | Documents file upload + how to reference file_id in chat requests. |
| .gitignore | Ignores chatgpt2api artifact and normalizes .gocache entry. |
Comments suppressed due to low confidence (2)
initialize/handlers.go:189
- When
secretFromAuthorization(...)returns nil (notably when the request includes files and no paid/valid access token is available), the handler responds with a generic "Not Account Found." string. This makes it hard for clients to understand they need a ChatGPT access token for file requests, and is inconsistent with the structured errors used elsewhere in this file (including the new/v1/filesendpoint).
secret := h.secretFromAuthorization(c.GetHeader("Authorization"), original_requestHasFiles(original_request), false)
if secret == nil {
c.JSON(400, gin.H{"error": "Not Account Found."})
c.Abort()
return
initialize/handlers.go:300
responsesreturns a generic "Not Account Found." whensecretFromAuthorization(...)is nil (e.g., when the request contains file parts but no paid/valid access token is available). Returning a structured, actionable error (matching/v1/files) will make client behavior and troubleshooting much clearer.
secret := h.secretFromAuthorization(c.GetHeader("Authorization"), original_requestHasFiles(original_request), false)
if secret == nil {
c.JSON(400, gin.H{"error": "Not Account Found."})
c.Abort()
return
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+60
to
+65
| func (c *ChatGPTRequest) AddMultimodalMessage(role string, parts []interface{}, metadata map[string]interface{}) { | ||
| contentType := "text" | ||
| if len(parts) > 1 || (len(parts) == 1 && !isStringPart(parts[0])) { | ||
| contentType = "multimodal_text" | ||
| } | ||
| c.Messages = append(c.Messages, chatgpt_message{ |
Comment on lines
+541
to
+559
| data, err := io.ReadAll(file) | ||
| if err != nil { | ||
| c.JSON(400, gin.H{"error": gin.H{ | ||
| "message": err.Error(), | ||
| "type": "invalid_request_error", | ||
| "param": "file", | ||
| "code": "file_read_error", | ||
| }}) | ||
| return | ||
| } | ||
| if len(data) == 0 { | ||
| c.JSON(400, gin.H{"error": gin.H{ | ||
| "message": "Uploaded file is empty", | ||
| "type": "invalid_request_error", | ||
| "param": "file", | ||
| "code": "empty_file", | ||
| }}) | ||
| return | ||
| } |
Comment on lines
+58
to
+65
| ```bash | ||
| curl -X POST http://localhost:8080/v1/files \ | ||
| -H "Authorization: Bearer <你的key或access token>" \ | ||
| -F "purpose=assistants" \ | ||
| -F "file=@./test.pdf" | ||
| 然后带 file_id 问答: | ||
| ``` | ||
|
|
Comment on lines
+35
to
+48
| var uploadedFiles sync.Map | ||
|
|
||
| func RegisterUploadedFile(file UploadedFile) { | ||
| if file.FileID == "" { | ||
| file.FileID = file.ID | ||
| } | ||
| if file.ID == "" { | ||
| file.ID = file.FileID | ||
| } | ||
| if file.FileID == "" { | ||
| return | ||
| } | ||
| uploadedFiles.Store(file.FileID, file) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.