mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-05 00:45:29 +08:00
95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
package promptcompat
|
|
|
|
import "strings"
|
|
|
|
func CollectOpenAIRefFileIDs(req map[string]any) []string {
|
|
if len(req) == 0 {
|
|
return nil
|
|
}
|
|
out := make([]string, 0, 4)
|
|
seen := map[string]struct{}{}
|
|
for _, key := range []string{
|
|
"ref_file_ids",
|
|
"file_ids",
|
|
"attachments",
|
|
"messages",
|
|
"input",
|
|
} {
|
|
raw := req[key]
|
|
if raw == nil {
|
|
continue
|
|
}
|
|
// Skip top-level strings for 'messages' and 'input' as they are likely plain text content,
|
|
// not file IDs. String file IDs are expected in 'ref_file_ids' or 'file_ids'.
|
|
if key == "messages" || key == "input" {
|
|
if _, ok := raw.(string); ok {
|
|
continue
|
|
}
|
|
}
|
|
appendOpenAIRefFileIDs(&out, seen, raw)
|
|
}
|
|
if len(out) == 0 {
|
|
return nil
|
|
}
|
|
return out
|
|
}
|
|
|
|
func appendOpenAIRefFileIDs(out *[]string, seen map[string]struct{}, raw any) {
|
|
switch x := raw.(type) {
|
|
case string:
|
|
addOpenAIRefFileID(out, seen, x)
|
|
case []string:
|
|
for _, item := range x {
|
|
addOpenAIRefFileID(out, seen, item)
|
|
}
|
|
case []any:
|
|
for _, item := range x {
|
|
appendOpenAIRefFileIDs(out, seen, item)
|
|
}
|
|
case map[string]any:
|
|
if fileID := strings.TrimSpace(asString(x["file_id"])); fileID != "" {
|
|
addOpenAIRefFileID(out, seen, fileID)
|
|
}
|
|
if strings.Contains(strings.ToLower(strings.TrimSpace(asString(x["type"]))), "file") {
|
|
if fileID := strings.TrimSpace(asString(x["id"])); fileID != "" {
|
|
addOpenAIRefFileID(out, seen, fileID)
|
|
}
|
|
}
|
|
if fileMap, ok := x["file"].(map[string]any); ok {
|
|
if fileID := strings.TrimSpace(asString(fileMap["file_id"])); fileID != "" {
|
|
addOpenAIRefFileID(out, seen, fileID)
|
|
}
|
|
if fileID := strings.TrimSpace(asString(fileMap["id"])); fileID != "" {
|
|
addOpenAIRefFileID(out, seen, fileID)
|
|
}
|
|
}
|
|
// Recurse into potential containers. Note: we do NOT recurse into 'content' or 'input'
|
|
// if they are plain strings (handled by the top-level switch), but they are usually
|
|
// nested inside the map branch anyway.
|
|
// To be safe, we only recurse into these known container keys.
|
|
for _, key := range []string{"ref_file_ids", "file_ids", "attachments", "messages", "input", "content", "files", "items", "data", "source"} {
|
|
if nested, ok := x[key]; ok {
|
|
// If it's a message content that is a string, we must NOT treat it as an ID.
|
|
if key == "content" || key == "input" {
|
|
if _, ok := nested.(string); ok {
|
|
continue
|
|
}
|
|
}
|
|
appendOpenAIRefFileIDs(out, seen, nested)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func addOpenAIRefFileID(out *[]string, seen map[string]struct{}, fileID string) {
|
|
fileID = strings.TrimSpace(fileID)
|
|
if fileID == "" {
|
|
return
|
|
}
|
|
if _, ok := seen[fileID]; ok {
|
|
return
|
|
}
|
|
seen[fileID] = struct{}{}
|
|
*out = append(*out, fileID)
|
|
}
|