Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
577b18a1
authored
Apr 11, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: enhance file handling and logging in the application
parent
7e0d4cd0
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
82 additions
and
9 deletions
+82
-9
common/init.go
+5
-5
dto/openai_request.go
+46
-0
main.go
+1
-1
relay/channel/gemini/relay-gemini.go
+28
-3
service/token_counter.go
+2
-0
No files found.
common/init.go
View file @
577b18a1
...
@@ -73,25 +73,25 @@ func LoadEnv() {
...
@@ -73,25 +73,25 @@ func LoadEnv() {
DebugEnabled
=
os
.
Getenv
(
"DEBUG"
)
==
"true"
DebugEnabled
=
os
.
Getenv
(
"DEBUG"
)
==
"true"
MemoryCacheEnabled
=
os
.
Getenv
(
"MEMORY_CACHE_ENABLED"
)
==
"true"
MemoryCacheEnabled
=
os
.
Getenv
(
"MEMORY_CACHE_ENABLED"
)
==
"true"
IsMasterNode
=
os
.
Getenv
(
"NODE_TYPE"
)
!=
"slave"
IsMasterNode
=
os
.
Getenv
(
"NODE_TYPE"
)
!=
"slave"
// Parse requestInterval and set RequestInterval
// Parse requestInterval and set RequestInterval
requestInterval
,
_
=
strconv
.
Atoi
(
os
.
Getenv
(
"POLLING_INTERVAL"
))
requestInterval
,
_
=
strconv
.
Atoi
(
os
.
Getenv
(
"POLLING_INTERVAL"
))
RequestInterval
=
time
.
Duration
(
requestInterval
)
*
time
.
Second
RequestInterval
=
time
.
Duration
(
requestInterval
)
*
time
.
Second
// Initialize variables with GetEnvOrDefault
// Initialize variables with GetEnvOrDefault
SyncFrequency
=
GetEnvOrDefault
(
"SYNC_FREQUENCY"
,
60
)
SyncFrequency
=
GetEnvOrDefault
(
"SYNC_FREQUENCY"
,
60
)
BatchUpdateInterval
=
GetEnvOrDefault
(
"BATCH_UPDATE_INTERVAL"
,
5
)
BatchUpdateInterval
=
GetEnvOrDefault
(
"BATCH_UPDATE_INTERVAL"
,
5
)
RelayTimeout
=
GetEnvOrDefault
(
"RELAY_TIMEOUT"
,
0
)
RelayTimeout
=
GetEnvOrDefault
(
"RELAY_TIMEOUT"
,
0
)
// Initialize string variables with GetEnvOrDefaultString
// Initialize string variables with GetEnvOrDefaultString
GeminiSafetySetting
=
GetEnvOrDefaultString
(
"GEMINI_SAFETY_SETTING"
,
"BLOCK_NONE"
)
GeminiSafetySetting
=
GetEnvOrDefaultString
(
"GEMINI_SAFETY_SETTING"
,
"BLOCK_NONE"
)
CohereSafetySetting
=
GetEnvOrDefaultString
(
"COHERE_SAFETY_SETTING"
,
"NONE"
)
CohereSafetySetting
=
GetEnvOrDefaultString
(
"COHERE_SAFETY_SETTING"
,
"NONE"
)
// Initialize rate limit variables
// Initialize rate limit variables
GlobalApiRateLimitEnable
=
GetEnvOrDefaultBool
(
"GLOBAL_API_RATE_LIMIT_ENABLE"
,
true
)
GlobalApiRateLimitEnable
=
GetEnvOrDefaultBool
(
"GLOBAL_API_RATE_LIMIT_ENABLE"
,
true
)
GlobalApiRateLimitNum
=
GetEnvOrDefault
(
"GLOBAL_API_RATE_LIMIT"
,
180
)
GlobalApiRateLimitNum
=
GetEnvOrDefault
(
"GLOBAL_API_RATE_LIMIT"
,
180
)
GlobalApiRateLimitDuration
=
int64
(
GetEnvOrDefault
(
"GLOBAL_API_RATE_LIMIT_DURATION"
,
180
))
GlobalApiRateLimitDuration
=
int64
(
GetEnvOrDefault
(
"GLOBAL_API_RATE_LIMIT_DURATION"
,
180
))
GlobalWebRateLimitEnable
=
GetEnvOrDefaultBool
(
"GLOBAL_WEB_RATE_LIMIT_ENABLE"
,
true
)
GlobalWebRateLimitEnable
=
GetEnvOrDefaultBool
(
"GLOBAL_WEB_RATE_LIMIT_ENABLE"
,
true
)
GlobalWebRateLimitNum
=
GetEnvOrDefault
(
"GLOBAL_WEB_RATE_LIMIT"
,
60
)
GlobalWebRateLimitNum
=
GetEnvOrDefault
(
"GLOBAL_WEB_RATE_LIMIT"
,
60
)
GlobalWebRateLimitDuration
=
int64
(
GetEnvOrDefault
(
"GLOBAL_WEB_RATE_LIMIT_DURATION"
,
180
))
GlobalWebRateLimitDuration
=
int64
(
GetEnvOrDefault
(
"GLOBAL_WEB_RATE_LIMIT_DURATION"
,
180
))
...
...
dto/openai_request.go
View file @
577b18a1
...
@@ -111,6 +111,7 @@ type MediaContent struct {
...
@@ -111,6 +111,7 @@ type MediaContent struct {
Text
string
`json:"text,omitempty"`
Text
string
`json:"text,omitempty"`
ImageUrl
any
`json:"image_url,omitempty"`
ImageUrl
any
`json:"image_url,omitempty"`
InputAudio
any
`json:"input_audio,omitempty"`
InputAudio
any
`json:"input_audio,omitempty"`
File
any
`json:"file,omitempty"`
}
}
func
(
m
*
MediaContent
)
GetImageMedia
()
*
MessageImageUrl
{
func
(
m
*
MediaContent
)
GetImageMedia
()
*
MessageImageUrl
{
...
@@ -120,6 +121,20 @@ func (m *MediaContent) GetImageMedia() *MessageImageUrl {
...
@@ -120,6 +121,20 @@ func (m *MediaContent) GetImageMedia() *MessageImageUrl {
return
nil
return
nil
}
}
func
(
m
*
MediaContent
)
GetInputAudio
()
*
MessageInputAudio
{
if
m
.
InputAudio
!=
nil
{
return
m
.
InputAudio
.
(
*
MessageInputAudio
)
}
return
nil
}
func
(
m
*
MediaContent
)
GetFile
()
*
MessageFile
{
if
m
.
File
!=
nil
{
return
m
.
File
.
(
*
MessageFile
)
}
return
nil
}
type
MessageImageUrl
struct
{
type
MessageImageUrl
struct
{
Url
string
`json:"url"`
Url
string
`json:"url"`
Detail
string
`json:"detail"`
Detail
string
`json:"detail"`
...
@@ -135,10 +150,17 @@ type MessageInputAudio struct {
...
@@ -135,10 +150,17 @@ type MessageInputAudio struct {
Format
string
`json:"format"`
Format
string
`json:"format"`
}
}
type
MessageFile
struct
{
FileName
string
`json:"filename,omitempty"`
FileData
string
`json:"file_data,omitempty"`
FileId
string
`json:"file_id,omitempty"`
}
const
(
const
(
ContentTypeText
=
"text"
ContentTypeText
=
"text"
ContentTypeImageURL
=
"image_url"
ContentTypeImageURL
=
"image_url"
ContentTypeInputAudio
=
"input_audio"
ContentTypeInputAudio
=
"input_audio"
ContentTypeFile
=
"file"
)
)
func
(
m
*
Message
)
GetPrefix
()
bool
{
func
(
m
*
Message
)
GetPrefix
()
bool
{
...
@@ -292,6 +314,30 @@ func (m *Message) ParseContent() []MediaContent {
...
@@ -292,6 +314,30 @@ func (m *Message) ParseContent() []MediaContent {
})
})
}
}
}
}
case
ContentTypeFile
:
if
fileData
,
ok
:=
contentItem
[
"file"
]
.
(
map
[
string
]
interface
{});
ok
{
fileId
,
ok3
:=
fileData
[
"file_id"
]
.
(
string
)
if
ok3
{
contentList
=
append
(
contentList
,
MediaContent
{
Type
:
ContentTypeFile
,
File
:
&
MessageFile
{
FileId
:
fileId
,
},
})
}
else
{
fileName
,
ok1
:=
fileData
[
"filename"
]
.
(
string
)
fileDataStr
,
ok2
:=
fileData
[
"file_data"
]
.
(
string
)
if
ok1
&&
ok2
{
contentList
=
append
(
contentList
,
MediaContent
{
Type
:
ContentTypeFile
,
File
:
&
MessageFile
{
FileName
:
fileName
,
FileData
:
fileDataStr
,
},
})
}
}
}
}
}
}
}
}
}
...
...
main.go
View file @
577b18a1
...
@@ -34,7 +34,7 @@ var indexPage []byte
...
@@ -34,7 +34,7 @@ var indexPage []byte
func
main
()
{
func
main
()
{
err
:=
godotenv
.
Load
(
".env"
)
err
:=
godotenv
.
Load
(
".env"
)
if
err
!=
nil
{
if
err
!=
nil
{
common
.
SysLog
(
"Support for .env file is disabled
"
)
common
.
SysLog
(
"Support for .env file is disabled
: "
+
err
.
Error
()
)
}
}
common
.
LoadEnv
()
common
.
LoadEnv
()
...
...
relay/channel/gemini/relay-gemini.go
View file @
577b18a1
...
@@ -208,6 +208,34 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -208,6 +208,34 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
},
},
})
})
}
}
}
else
if
part
.
Type
==
dto
.
ContentTypeFile
{
if
part
.
GetFile
()
.
FileId
!=
""
{
return
nil
,
fmt
.
Errorf
(
"only base64 file is supported in gemini"
)
}
format
,
base64String
,
err
:=
service
.
DecodeBase64FileData
(
part
.
GetFile
()
.
FileData
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"decode base64 file data failed: %s"
,
err
.
Error
())
}
parts
=
append
(
parts
,
GeminiPart
{
InlineData
:
&
GeminiInlineData
{
MimeType
:
format
,
Data
:
base64String
,
},
})
}
else
if
part
.
Type
==
dto
.
ContentTypeInputAudio
{
if
part
.
GetInputAudio
()
.
Data
==
""
{
return
nil
,
fmt
.
Errorf
(
"only base64 audio is supported in gemini"
)
}
format
,
base64String
,
err
:=
service
.
DecodeBase64FileData
(
part
.
GetInputAudio
()
.
Data
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"decode base64 audio data failed: %s"
,
err
.
Error
())
}
parts
=
append
(
parts
,
GeminiPart
{
InlineData
:
&
GeminiInlineData
{
MimeType
:
format
,
Data
:
base64String
,
},
})
}
}
}
}
...
@@ -233,7 +261,6 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -233,7 +261,6 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
return
&
geminiRequest
,
nil
return
&
geminiRequest
,
nil
}
}
// cleanFunctionParameters recursively removes unsupported fields from Gemini function parameters.
// cleanFunctionParameters recursively removes unsupported fields from Gemini function parameters.
func
cleanFunctionParameters
(
params
interface
{})
interface
{}
{
func
cleanFunctionParameters
(
params
interface
{})
interface
{}
{
if
params
==
nil
{
if
params
==
nil
{
...
@@ -307,7 +334,6 @@ func cleanFunctionParameters(params interface{}) interface{} {
...
@@ -307,7 +334,6 @@ func cleanFunctionParameters(params interface{}) interface{} {
cleanedMap
[
"items"
]
=
cleanedItemsArray
cleanedMap
[
"items"
]
=
cleanedItemsArray
}
}
// Recursively clean other schema composition keywords if necessary
// Recursively clean other schema composition keywords if necessary
for
_
,
field
:=
range
[]
string
{
"allOf"
,
"anyOf"
,
"oneOf"
}
{
for
_
,
field
:=
range
[]
string
{
"allOf"
,
"anyOf"
,
"oneOf"
}
{
if
nested
,
ok
:=
cleanedMap
[
field
]
.
([]
interface
{});
ok
{
if
nested
,
ok
:=
cleanedMap
[
field
]
.
([]
interface
{});
ok
{
...
@@ -322,7 +348,6 @@ func cleanFunctionParameters(params interface{}) interface{} {
...
@@ -322,7 +348,6 @@ func cleanFunctionParameters(params interface{}) interface{} {
return
cleanedMap
return
cleanedMap
}
}
func
removeAdditionalPropertiesWithDepth
(
schema
interface
{},
depth
int
)
interface
{}
{
func
removeAdditionalPropertiesWithDepth
(
schema
interface
{},
depth
int
)
interface
{}
{
if
depth
>=
5
{
if
depth
>=
5
{
return
schema
return
schema
...
...
service/token_counter.go
View file @
577b18a1
...
@@ -398,6 +398,8 @@ func CountTokenMessages(info *relaycommon.RelayInfo, messages []dto.Message, mod
...
@@ -398,6 +398,8 @@ func CountTokenMessages(info *relaycommon.RelayInfo, messages []dto.Message, mod
}
else
if
m
.
Type
==
dto
.
ContentTypeInputAudio
{
}
else
if
m
.
Type
==
dto
.
ContentTypeInputAudio
{
// TODO: 音频token数量计算
// TODO: 音频token数量计算
tokenNum
+=
100
tokenNum
+=
100
}
else
if
m
.
Type
==
dto
.
ContentTypeFile
{
tokenNum
+=
5000
}
else
{
}
else
{
tokenNum
+=
getTokenNum
(
tokenEncoder
,
m
.
Text
)
tokenNum
+=
getTokenNum
(
tokenEncoder
,
m
.
Text
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment