Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ Reference frontend embed code (React / Tailwind CSS; keep either item as needed)

By meeting either attribution requirement above and keeping the link clearly visible, you automatically receive a temporary commercial license for this project, with no separate application or approval required. This is not a perpetual license and remains valid only while the display requirement continues to be met. Its validity period and any later changes are governed by the latest notice published in this README or by the official community.

This project is developed from [One API](https://github.com/songquanpeng/one-api) and [New API](https://github.com/QuantumNous/new-api). Commercial use must also comply with the One API MIT License and the New API AGPLv3 License, subject to each upstream project's current `LICENSE` file. The temporary commercial license provided by this project does not replace or waive any upstream open-source license obligations.
This project is developed from [One API](https://github.com/songquanpeng/one-api) and [New API](https://github.com/QuantumNous/new-api). At this stage, MAX API builds on those foundations by strengthening its AI API gateway and governance capabilities, expanding features, and fixing bugs. Commercial use must also comply with the One API MIT License and the New API AGPLv3 License, subject to each upstream project's current `LICENSE` file. The temporary commercial license provided by this project does not replace or waive any upstream open-source license obligations.

If the display requirement is no longer met, or the temporary license expires, is amended, or is terminated by notice, you must comply with AGPLv3 or obtain separate written authorization. For a long-term commercial license, contact: maxapi@max-api.ai.

Expand All @@ -744,6 +744,8 @@ Issues, documentation improvements, provider adaptation experience, deployment p

This project is licensed under the [GNU Affero General Public License v3.0 (AGPLv3)](./LICENSE).

In addition to the default AGPLv3 license, self-use derivative projects that meet the “Derivative Use and Community Acknowledgement” conditions above automatically receive the non-perpetual temporary commercial license described there. This temporary license covers only additions and modifications that the MAX API project maintainers have the right to license; it does not include or replace licensing from upstream projects such as One API and New API.

If you modify this project and provide it to users over a network, please understand and comply with AGPLv3 source availability obligations. For commercial cooperation, institutional cooperation, or other licensing questions, contact: maxapi@max-api.ai.

---
Expand Down
4 changes: 3 additions & 1 deletion README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ Exemple de code d'intégration frontend (React / Tailwind CSS ; conservez l'un o

En respectant l'une des exigences d'affichage ci-dessus et en maintenant le lien clairement visible, vous obtenez automatiquement une licence commerciale temporaire pour ce projet, sans demande ni approbation supplémentaire. Cette licence n'est pas permanente et reste valable uniquement tant que l'exigence d'affichage est respectée. Sa période de validité et toute modification ultérieure sont régies par le dernier avis publié dans ce README ou par la communauté officielle.

Ce projet est développé à partir de [One API](https://github.com/songquanpeng/one-api) et de [New API](https://github.com/QuantumNous/new-api). Toute utilisation commerciale doit également respecter la licence MIT de One API et la licence AGPLv3 de New API, conformément au fichier `LICENSE` actuellement publié par chaque projet en amont. La licence commerciale temporaire fournie par ce projet ne remplace ni ne supprime aucune obligation liée aux licences open source des projets en amont.
Ce projet est développé à partir de [One API](https://github.com/songquanpeng/one-api) et de [New API](https://github.com/QuantumNous/new-api). À ce stade, MAX API s'appuie sur ces bases pour renforcer ses capacités de passerelle d'API d'IA et de gouvernance, enrichir ses fonctionnalités et corriger les anomalies. Toute utilisation commerciale doit également respecter la licence MIT de One API et la licence AGPLv3 de New API, conformément au fichier `LICENSE` actuellement publié par chaque projet en amont. La licence commerciale temporaire fournie par ce projet ne remplace ni ne supprime aucune obligation liée aux licences open source des projets en amont.

Si l'exigence d'affichage n'est plus respectée, ou si la licence temporaire expire, est modifiée ou prend fin par avis, vous devez respecter l'AGPLv3 ou obtenir une autorisation écrite distincte. Pour une licence commerciale à long terme, contactez : maxapi@max-api.ai.

Expand All @@ -661,6 +661,8 @@ Contributions de code, documentation, expériences d'adaptation fournisseur et p

Ce projet est sous [GNU Affero General Public License v3.0 (AGPLv3)](./LICENSE).

Outre la licence AGPLv3 par défaut, les projets dérivés à usage propre qui respectent les conditions « Développements dérivés et remerciements à la communauté » ci-dessus reçoivent automatiquement la licence commerciale temporaire et non permanente qui y est décrite. Cette licence temporaire ne couvre que les ajouts et modifications que les responsables du projet MAX API sont en droit de concéder ; elle n'inclut ni ne remplace les licences des projets en amont tels que One API et New API.

Si vous modifiez le projet et le fournissez aux utilisateurs via le réseau, comprenez et respectez les obligations AGPLv3 de disponibilité du code source. Pour coopération commerciale, institutionnelle ou autres questions de licence : maxapi@max-api.ai.

---
Expand Down
4 changes: 3 additions & 1 deletion README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ SQLite、MySQL ≥ 5.7.8、PostgreSQL ≥ 9.6 に対応しています。ロー

上記いずれかの表示要件を満たし、リンクを明確に表示し続けることで、申請や承認を別途行うことなく、本プロジェクトの一時的な商用ライセンスを自動的に取得できます。このライセンスは永久ライセンスではなく、表示要件を継続して満たしている期間に限り有効です。有効期間および今後の変更は、本 README または公式コミュニティで公開される最新のお知らせに従います。

本プロジェクトは [One API](https://github.com/songquanpeng/one-api) および [New API](https://github.com/QuantumNous/new-api) をベースに開発されています。商用利用にあたっては、各上流プロジェクトが現在公開している `LICENSE` ファイルに従い、One API の MIT ライセンスおよび New API の AGPLv3 ライセンスも遵守する必要があります。本プロジェクトが提供する一時的な商用ライセンスは、上流プロジェクトのオープンソースライセンス上の義務を置き換えたり免除したりするものではありません。
本プロジェクトは [One API](https://github.com/songquanpeng/one-api) および [New API](https://github.com/QuantumNous/new-api) をベースに開発されています。現段階の MAX API は、これらを基盤として AI API ゲートウェイおよびガバナンス機能の強化、機能拡張、バグ修正を継続しています。商用利用にあたっては、各上流プロジェクトが現在公開している `LICENSE` ファイルに従い、One API の MIT ライセンスおよび New API の AGPLv3 ライセンスも遵守する必要があります。本プロジェクトが提供する一時的な商用ライセンスは、上流プロジェクトのオープンソースライセンス上の義務を置き換えたり免除したりするものではありません。

表示要件を満たさなくなった場合、または一時的なライセンスが期限切れ、告知により変更もしくは終了した場合は、AGPLv3 に従うか、別途書面による許諾を取得する必要があります。長期商用ライセンスについては、maxapi@max-api.ai までお問い合わせください。

Expand All @@ -682,6 +682,8 @@ Issue、ドキュメント改善、プロバイダー適応経験、デプロイ

本プロジェクトは [GNU Affero General Public License v3.0 (AGPLv3)](./LICENSE) で提供されます。

標準の AGPLv3 ライセンスに加え、上記「二次開発とコミュニティへの謝辞」の条件を満たす自己利用の二次開発プロジェクトには、そこで説明されている非永久の一時的な商用ライセンスが自動的に付与されます。この一時的なライセンスが対象とするのは、MAX API プロジェクト運営者がライセンスする権利を有する追加・変更部分のみであり、One API や New API などの上流プロジェクトのライセンスを含む、または代替するものではありません。

本プロジェクトを変更し、ネットワーク経由でユーザーにサービスとして提供する場合は、AGPLv3 のソース提供義務などを理解し遵守してください。商用協力、機関協力、その他ライセンスに関する問い合わせは maxapi@max-api.ai までご連絡ください。

---
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ MAX API 不替代 Dify、LangChain、MCP Server、工作流引擎或业务 Agent

满足上述任一展示要求并保持链接清晰可见,即自动获得本项目的临时商用授权,无需另行申请或等待确认。该授权为非永久授权,仅在持续满足展示要求期间有效;有效期及后续调整以项目方在本 README 或官方社区发布的最新说明为准。

本项目基于 [One API](https://github.com/songquanpeng/one-api) 和 [New API](https://github.com/QuantumNous/new-api) 开发。商业使用本项目时,还须分别遵守 One API 的 MIT 许可证与 New API 的 AGPLv3 许可证,具体以各上游项目的 `LICENSE` 文件为准;本项目提供的临时商用授权不替代、也不免除相关上游项目的开源许可义务。
本项目基于 [One API](https://github.com/songquanpeng/one-api) 和 [New API](https://github.com/QuantumNous/new-api) 开发。现阶段,MAX API 主要在上述项目基础上持续增强 AI API 网关与治理能力、扩展功能并修复问题。商业使用本项目时,还须分别遵守 One API 的 MIT 许可证与 New API 的 AGPLv3 许可证,具体以各上游项目的 `LICENSE` 文件为准;本项目提供的临时商用授权不替代、也不免除相关上游项目的开源许可义务。

如不再满足展示要求,或临时授权到期、被公告调整或终止,仍需按 AGPLv3 或项目方另行书面授权使用本项目。如需长期商用授权,请联系:maxapi@max-api.ai。

Expand All @@ -751,6 +751,8 @@ MAX API 不替代 Dify、LangChain、MCP Server、工作流引擎或业务 Agent

本项目采用 [GNU Affero 通用公共许可证 v3.0 (AGPLv3)](./LICENSE) 授权。

除默认的 AGPLv3 授权外,符合上文“二次开发与社区鸣谢”条件的自用二开项目,可按该说明自动获得非永久的临时商用授权。该临时授权仅覆盖 MAX API 项目方有权授权的新增与修改部分,并不包含或代替 One API、New API 等上游项目的许可授权。

如果你修改并通过网络向用户提供本项目服务,请理解并遵守 AGPLv3 对应源码提供等义务。商业合作、机构合作或其他授权问题,请联系:maxapi@max-api.ai。


Expand Down
4 changes: 3 additions & 1 deletion README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ MAX API 不替代 Dify、LangChain、MCP Server、工作流引擎或业务 Agent

满足上述任一展示要求并保持链接清晰可见,即自动获得本项目的临时商用授权,无需另行申请或等待确认。该授权为非永久授权,仅在持续满足展示要求期间有效;有效期及后续调整以项目方在本 README 或官方社区发布的最新说明为准。

本项目基于 [One API](https://github.com/songquanpeng/one-api) 和 [New API](https://github.com/QuantumNous/new-api) 开发。商业使用本项目时,还须分别遵守 One API 的 MIT 许可证与 New API 的 AGPLv3 许可证,具体以各上游项目的 `LICENSE` 文件为准;本项目提供的临时商用授权不替代、也不免除相关上游项目的开源许可义务。
本项目基于 [One API](https://github.com/songquanpeng/one-api) 和 [New API](https://github.com/QuantumNous/new-api) 开发。现阶段,MAX API 主要在上述项目基础上持续增强 AI API 网关与治理能力、扩展功能并修复问题。商业使用本项目时,还须分别遵守 One API 的 MIT 许可证与 New API 的 AGPLv3 许可证,具体以各上游项目的 `LICENSE` 文件为准;本项目提供的临时商用授权不替代、也不免除相关上游项目的开源许可义务。

如不再满足展示要求,或临时授权到期、被公告调整或终止,仍需按 AGPLv3 或项目方另行书面授权使用本项目。如需长期商用授权,请联系:maxapi@max-api.ai。

Expand All @@ -744,6 +744,8 @@ MAX API 不替代 Dify、LangChain、MCP Server、工作流引擎或业务 Agent

本项目采用 [GNU Affero 通用公共许可证 v3.0 (AGPLv3)](./LICENSE) 授权。

除默认的 AGPLv3 授权外,符合上文“二次开发与社区鸣谢”条件的自用二开项目,可按该说明自动获得非永久的临时商用授权。该临时授权仅覆盖 MAX API 项目方有权授权的新增与修改部分,并不包含或代替 One API、New API 等上游项目的许可授权。

如果你修改并通过网络向用户提供本项目服务,请理解并遵守 AGPLv3 对应源码提供等义务。商业合作、机构合作或其他授权问题,请联系:maxapi@max-api.ai。

---
Expand Down
4 changes: 3 additions & 1 deletion README.zh_TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ MAX API 不替代 Dify、LangChain、MCP Server、工作流引擎或業務 Agent

滿足上述任一展示要求並保持連結清晰可見,即自動獲得本專案的臨時商用授權,無需另行申請或等待確認。該授權為非永久授權,僅在持續滿足展示要求期間有效;有效期及後續調整以專案方在本 README 或官方社群發布的最新說明為準。

本專案基於 [One API](https://github.com/songquanpeng/one-api) 和 [New API](https://github.com/QuantumNous/new-api) 開發。商業使用本專案時,還須分別遵守 One API 的 MIT 許可證與 New API 的 AGPLv3 許可證,具體以各上游專案的 `LICENSE` 檔案為準;本專案提供的臨時商用授權不替代、也不免除相關上游專案的開源許可義務。
本專案基於 [One API](https://github.com/songquanpeng/one-api) 和 [New API](https://github.com/QuantumNous/new-api) 開發。現階段,MAX API 主要在上述專案基礎上持續強化 AI API 閘道與治理能力、擴充功能並修正問題。商業使用本專案時,還須分別遵守 One API 的 MIT 許可證與 New API 的 AGPLv3 許可證,具體以各上游專案的 `LICENSE` 檔案為準;本專案提供的臨時商用授權不替代、也不免除相關上游專案的開源許可義務。

如不再滿足展示要求,或臨時授權到期、被公告調整或終止,仍需按 AGPLv3 或專案方另行書面授權使用本專案。如需長期商用授權,請聯絡:maxapi@max-api.ai。

Expand All @@ -744,6 +744,8 @@ MAX API 不替代 Dify、LangChain、MCP Server、工作流引擎或業務 Agent

本專案采用 [GNU Affero 通用公共許可證 v3.0 (AGPLv3)](./LICENSE) 授權。

除預設的 AGPLv3 授權外,符合上文「二次開發與社群鳴謝」條件的自用二開專案,可按該說明自動獲得非永久的臨時商用授權。該臨時授權僅涵蓋 MAX API 專案方有權授權的新增與修改部分,並不包含或代替 One API、New API 等上游專案的許可授權。

如果你修改并通過網絡向使用者提供本專案服務,請理解并遵守 AGPLv3 對應源碼提供等義務。商業合作、機構合作或其他授權問題,請聯系:maxapi@max-api.ai。

---
Expand Down
55 changes: 50 additions & 5 deletions dto/billing_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ func HasOpenAIUsageTokens(usage *Usage) bool {
usage.CompletionTokenDetails.AudioTokens != 0 {
return true
}
if usage.OutputTokensDetails != nil &&
(usage.OutputTokensDetails.ReasoningTokens != 0 ||
usage.OutputTokensDetails.TextTokens != 0 ||
usage.OutputTokensDetails.ImageTokens != 0 ||
usage.OutputTokensDetails.AudioTokens != 0) {
return true
}
return usage.InputTokensDetails != nil
}

Expand All @@ -108,15 +115,49 @@ func NewEstimatedGeminiChatBillingUsage(usage *Usage) *BillingUsage {
if usage == nil {
return nil
}
metadata := GeminiUsageMetadata{}
if usage.BillingUsage != nil && usage.BillingUsage.GeminiUsageMetadata != nil {
metadata = cloneGeminiUsageMetadata(*usage.BillingUsage.GeminiUsageMetadata)
}

if usage.PromptTokens > 0 {
promptTokens := usage.PromptTokens - metadata.ToolUsePromptTokenCount
if promptTokens < 0 {
promptTokens = 0
}
metadata.PromptTokenCount = promptTokens
}
if usage.CompletionTokenDetails.ReasoningTokens > 0 {
metadata.ThoughtsTokenCount = usage.CompletionTokenDetails.ReasoningTokens
}
candidateTokens := usage.CompletionTokens - metadata.ThoughtsTokenCount
if candidateTokens < 0 {
candidateTokens = 0
}
metadata.CandidatesTokenCount = candidateTokens
metadata.CandidatesTokensDetails = mergeGeminiCandidateTokenDetail(metadata.CandidatesTokensDetails, "TEXT", usage.CompletionTokenDetails.TextTokens)
metadata.CandidatesTokensDetails = mergeGeminiCandidateTokenDetail(metadata.CandidatesTokensDetails, "IMAGE", usage.CompletionTokenDetails.ImageTokens)
metadata.CandidatesTokensDetails = mergeGeminiCandidateTokenDetail(metadata.CandidatesTokensDetails, "AUDIO", usage.CompletionTokenDetails.AudioTokens)

totalTokens := usage.TotalTokens
if totalTokens == 0 {
totalTokens = usage.PromptTokens + usage.CompletionTokens
}
return newGeminiChatBillingUsage(&GeminiUsageMetadata{
PromptTokenCount: usage.PromptTokens,
CandidatesTokenCount: usage.CompletionTokens,
TotalTokenCount: totalTokens,
}, true)
metadata.TotalTokenCount = totalTokens
return newGeminiChatBillingUsage(&metadata, true)
}

func mergeGeminiCandidateTokenDetail(details []GeminiPromptTokensDetails, modality string, tokenCount int) []GeminiPromptTokensDetails {
if tokenCount <= 0 {
return details
}
for i := range details {
if details[i].Modality == modality {
details[i].TokenCount = tokenCount
return details
}
}
return append(details, GeminiPromptTokensDetails{Modality: modality, TokenCount: tokenCount})
}

func newGeminiChatBillingUsage(metadata *GeminiUsageMetadata, estimated bool) *BillingUsage {
Expand Down Expand Up @@ -156,6 +197,10 @@ func cloneOpenAIUsage(usage *Usage) *Usage {
inputTokensDetails := *usage.InputTokensDetails
clone.InputTokensDetails = &inputTokensDetails
}
if usage.OutputTokensDetails != nil {
outputTokensDetails := *usage.OutputTokensDetails
clone.OutputTokensDetails = &outputTokensDetails
}
return &clone
}

Expand Down
11 changes: 11 additions & 0 deletions dto/billing_usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ func TestNewOpenAIChatBillingUsageRequiresTokenContent(t *testing.T) {
assert.Equal(t, 1, billingUsage.OpenAIUsage.PromptTokens)
}

func TestNewOpenAIResponsesBillingUsageSupportsOutputTokenDetails(t *testing.T) {
source := &Usage{OutputTokensDetails: &OutputTokenDetails{AudioTokens: 9}}
billingUsage := NewOpenAIResponsesBillingUsage(source)

require.NotNil(t, billingUsage)
require.NotNil(t, billingUsage.OpenAIUsage)
require.NotNil(t, billingUsage.OpenAIUsage.OutputTokensDetails)
assert.Equal(t, 9, billingUsage.OpenAIUsage.OutputTokensDetails.AudioTokens)
assert.NotSame(t, source.OutputTokensDetails, billingUsage.OpenAIUsage.OutputTokensDetails)
}

func TestNewEstimatedGeminiChatBillingUsage(t *testing.T) {
billingUsage := NewEstimatedGeminiChatBillingUsage(&Usage{
PromptTokens: 11,
Expand Down
Loading
Loading