-
Notifications
You must be signed in to change notification settings - Fork 59.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix model leak issue #5883
base: main
Are you sure you want to change the base?
fix model leak issue #5883
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; | |||||||||||||||||||||||||||||||||||||||||||||
import { getServerSideConfig } from "../config/server"; | ||||||||||||||||||||||||||||||||||||||||||||||
import { OPENAI_BASE_URL, ServiceProvider } from "../constant"; | ||||||||||||||||||||||||||||||||||||||||||||||
import { cloudflareAIGatewayUrl } from "../utils/cloudflare"; | ||||||||||||||||||||||||||||||||||||||||||||||
import { getModelProvider, isModelAvailableInServer } from "../utils/model"; | ||||||||||||||||||||||||||||||||||||||||||||||
import { getModelProvider, isModelNotavailableInServer } from "../utils/model"; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
const serverConfig = getServerSideConfig(); | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -118,15 +118,14 @@ export async function requestOpenai(req: NextRequest) { | |||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
// not undefined and is false | ||||||||||||||||||||||||||||||||||||||||||||||
if ( | ||||||||||||||||||||||||||||||||||||||||||||||
isModelAvailableInServer( | ||||||||||||||||||||||||||||||||||||||||||||||
isModelNotavailableInServer( | ||||||||||||||||||||||||||||||||||||||||||||||
serverConfig.customModels, | ||||||||||||||||||||||||||||||||||||||||||||||
jsonBody?.model as string, | ||||||||||||||||||||||||||||||||||||||||||||||
ServiceProvider.OpenAI as string, | ||||||||||||||||||||||||||||||||||||||||||||||
) || | ||||||||||||||||||||||||||||||||||||||||||||||
isModelAvailableInServer( | ||||||||||||||||||||||||||||||||||||||||||||||
serverConfig.customModels, | ||||||||||||||||||||||||||||||||||||||||||||||
jsonBody?.model as string, | ||||||||||||||||||||||||||||||||||||||||||||||
ServiceProvider.Azure as string, | ||||||||||||||||||||||||||||||||||||||||||||||
[ | ||||||||||||||||||||||||||||||||||||||||||||||
ServiceProvider.OpenAI, | ||||||||||||||||||||||||||||||||||||||||||||||
ServiceProvider.Azure, | ||||||||||||||||||||||||||||||||||||||||||||||
jsonBody?.model as string, // support provider-unspecified model | ||||||||||||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+121
to
+128
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve error handling and code clarity. Several improvements can be made to this section:
Apply these changes: - // #1815 try to refuse gpt4 request
+ // Check if the requested model is restricted based on server configuration
if (
isModelNotavailableInServer(
serverConfig.customModels,
jsonBody?.model as string,
[
ServiceProvider.OpenAI,
ServiceProvider.Azure,
- jsonBody?.model as string, // support provider-unspecified model
+ jsonBody?.model, // support provider-unspecified model
],
)
) {
return NextResponse.json(
{
error: true,
- message: `you are not allowed to use ${jsonBody?.model} model`,
+ message: `Access to model '${jsonBody?.model}' is restricted by server configuration`,
},
{
status: 403,
},
);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||
return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -202,3 +202,27 @@ export function isModelAvailableInServer( | |
const modelTable = collectModelTable(DEFAULT_MODELS, customModels); | ||
return modelTable[fullName]?.available === false; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Function has incorrect logic that caused the model leak The
This function should be deprecated in favor of the new |
||
/** | ||
* Checks if a model is not available on any of the specified providers in the server. | ||
* | ||
* @param {string} customModels - A string of custom models, comma-separated. | ||
* @param {string} modelName - The name of the model to check. | ||
* @param {string|string[]} providerNames - A string or array of provider names to check against. | ||
* | ||
* @returns {boolean} True if the model is not available on any of the specified providers, false otherwise. | ||
*/ | ||
export function isModelNotavailableInServer( | ||
customModels: string, | ||
modelName: string, | ||
providerNames: string | string[], | ||
) { | ||
const modelTable = collectModelTable(DEFAULT_MODELS, customModels); | ||
const providerNamesArray = Array.isArray(providerNames) ? providerNames : [providerNames]; | ||
for (const providerName of providerNamesArray){ | ||
const fullName = `${modelName}@${providerName.toLowerCase()}`; | ||
if (modelTable[fullName]?.available === true) | ||
return false; | ||
} | ||
return true; | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,59 @@ | ||||||||||||||||||||||||||||||
import { isModelNotavailableInServer } from "../app/utils/model"; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
describe("isModelNotavailableInServer", () => { | ||||||||||||||||||||||||||||||
test("test model will return false, which means the model is available", () => { | ||||||||||||||||||||||||||||||
const customModels = ""; | ||||||||||||||||||||||||||||||
const modelName = "gpt-4"; | ||||||||||||||||||||||||||||||
const providerNames = "OpenAI"; | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer(customModels, modelName, providerNames); | ||||||||||||||||||||||||||||||
expect(result).toBe(false); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("test model will return true when model is not available in custom models", () => { | ||||||||||||||||||||||||||||||
const customModels = "-all,gpt-4o-mini"; | ||||||||||||||||||||||||||||||
const modelName = "gpt-4"; | ||||||||||||||||||||||||||||||
const providerNames = "OpenAI"; | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer(customModels, modelName, providerNames); | ||||||||||||||||||||||||||||||
expect(result).toBe(true); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("should respect DISABLE_GPT4 setting", () => { | ||||||||||||||||||||||||||||||
process.env.DISABLE_GPT4 = "1"; | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer("", "gpt-4", "OpenAI"); | ||||||||||||||||||||||||||||||
expect(result).toBe(true); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("should handle empty provider names", () => { | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer("-all,gpt-4", "gpt-4", ""); | ||||||||||||||||||||||||||||||
expect(result).toBe(true); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("should be case insensitive for model names", () => { | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer("-all,GPT-4", "gpt-4", "OpenAI"); | ||||||||||||||||||||||||||||||
expect(result).toBe(true); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("support passing multiple providers, model unavailable on one of the providers will return true", () => { | ||||||||||||||||||||||||||||||
const customModels = "-all,gpt-4@Google"; | ||||||||||||||||||||||||||||||
const modelName = "gpt-4"; | ||||||||||||||||||||||||||||||
const providerNames = ["OpenAI", "Azure"]; | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer(customModels, modelName, providerNames); | ||||||||||||||||||||||||||||||
expect(result).toBe(true); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("support passing multiple providers, model available on one of the providers will return false", () => { | ||||||||||||||||||||||||||||||
const customModels = "-all,gpt-4@Google"; | ||||||||||||||||||||||||||||||
const modelName = "gpt-4"; | ||||||||||||||||||||||||||||||
const providerNames = ["OpenAI", "Google"]; | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer(customModels, modelName, providerNames); | ||||||||||||||||||||||||||||||
expect(result).toBe(false); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
test("test custom model without setting provider", () => { | ||||||||||||||||||||||||||||||
const customModels = "-all,mistral-large"; | ||||||||||||||||||||||||||||||
const modelName = "mistral-large"; | ||||||||||||||||||||||||||||||
const providerNames = modelName; | ||||||||||||||||||||||||||||||
const result = isModelNotavailableInServer(customModels, modelName, providerNames); | ||||||||||||||||||||||||||||||
expect(result).toBe(false); | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
Comment on lines
+52
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review provider name assignment in custom model test Setting - const providerNames = modelName;
+ const providerNames = "Default"; // or ["Default"] to match other test patterns 📝 Committable suggestion
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. provider 设计问题,default 是无效参数 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @code-october,明白了,谢谢您的解释。确实, ✏️ Learnings added
|
||||||||||||||||||||||||||||||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Remove unused
isModelAvailableInServer
function from model.tsThe old function is not being used anywhere in the codebase but still exists in
app/utils/model.ts
. This dead code should be removed to prevent confusion and potential future misuse.app/utils/model.ts
: Remove the unusedisModelAvailableInServer
function🔗 Analysis chain
LGTM! Verify consistent usage across the codebase.
The import change from
isModelAvailableInServer
toisModelNotavailableInServer
aligns with the PR objective to fix model leak issues.Both old and new functions coexist in model.ts - needs cleanup
The verification revealed that while the new
isModelNotavailableInServer
function is consistently used across API handlers, the oldisModelAvailableInServer
function still exists inapp/utils/model.ts
. Let's verify if it's actually being used anywhere:🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 1674
Script:
Length of output: 192