diff --git a/astrbot/core/provider/sources/anthropic_source.py b/astrbot/core/provider/sources/anthropic_source.py
index 27cc459622..e9dfbc3d8d 100644
--- a/astrbot/core/provider/sources/anthropic_source.py
+++ b/astrbot/core/provider/sources/anthropic_source.py
@@ -131,7 +131,11 @@ def _create_http_client(self, provider_config: dict) -> httpx.AsyncClient | None
try:
from anthropic import _base_client as anthropic_base_client
- httpx_module = getattr(anthropic_base_client, "httpx", httpx)
+ httpx_module = getattr(
+ anthropic_base_client,
+ "httpx2",
+ getattr(anthropic_base_client, "httpx", httpx),
+ )
except ImportError:
pass
return create_proxy_client(
diff --git a/dashboard/src/i18n/locales/en-US/features/extension.json b/dashboard/src/i18n/locales/en-US/features/extension.json
index 49ce481c60..5e91ea8790 100644
--- a/dashboard/src/i18n/locales/en-US/features/extension.json
+++ b/dashboard/src/i18n/locales/en-US/features/extension.json
@@ -178,6 +178,7 @@
"sourceResolved": "Source resolved successfully",
"installPlugin": "Install Plugin",
"randomPlugins": "🎲 Random Plugins",
+ "itemsPerPage": "Items per page",
"sourceSafetyWarning": "Even with the default source, plugin stability and security cannot be fully guaranteed. Please verify carefully before use."
},
"sort": {
diff --git a/dashboard/src/i18n/locales/zh-CN/features/extension.json b/dashboard/src/i18n/locales/zh-CN/features/extension.json
index 476bacd051..25f62388fb 100644
--- a/dashboard/src/i18n/locales/zh-CN/features/extension.json
+++ b/dashboard/src/i18n/locales/zh-CN/features/extension.json
@@ -178,6 +178,7 @@
"sourceResolved": "插件源可用",
"installPlugin": "安装插件",
"randomPlugins": "🎲 随机插件",
+ "itemsPerPage": "\u6bcf\u9875\u663e\u793a",
"sourceSafetyWarning": "即使是默认插件源,我们也不能完全保证插件的稳定性和安全性,使用前请谨慎核查。"
},
"sort": {
diff --git a/dashboard/src/views/extension/MarketPluginsTab.vue b/dashboard/src/views/extension/MarketPluginsTab.vue
index fd03b48f59..fe4eca7054 100644
--- a/dashboard/src/views/extension/MarketPluginsTab.vue
+++ b/dashboard/src/views/extension/MarketPluginsTab.vue
@@ -355,13 +355,30 @@ const openMarketPluginDetail = (plugin) => {
-
-
+
@@ -470,6 +487,45 @@ const openMarketPluginDetail = (plugin) => {
.market-filter-control :deep(.v-field__prepend-inner) {
font-size: 0.875rem;
}
+.market-pagination-footer {
+ display: grid;
+ grid-template-columns: 1fr auto 1fr;
+ align-items: center;
+ gap: 12px;
+ margin-top: 16px;
+}
+
+.market-pagination-footer__pagination {
+ display: flex;
+ justify-content: center;
+}
+
+.market-pagination-footer__page-size {
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ gap: 8px;
+}
+
+.market-pagination-footer__select {
+ width: 110px;
+}
+
+@media (max-width: 960px) {
+ .market-pagination-footer {
+ grid-template-columns: 1fr;
+ }
+
+ .market-pagination-footer__spacer {
+ display: none;
+ }
+
+ .market-pagination-footer__pagination,
+ .market-pagination-footer__page-size {
+ justify-content: center;
+ }
+}
+
@media (max-width: 700px) {
.market-header-row {
diff --git a/dashboard/src/views/extension/useExtensionPage.js b/dashboard/src/views/extension/useExtensionPage.js
index 7c313cd71d..591086e7f4 100644
--- a/dashboard/src/views/extension/useExtensionPage.js
+++ b/dashboard/src/views/extension/useExtensionPage.js
@@ -206,6 +206,17 @@ export const useExtensionPage = (initialTab = "installed") => {
const upload_file = ref(null);
const uploadTab = ref("file");
const showPluginFullName = ref(false);
+ const marketItemsPerPageOptions = [9, 25, 50, 100];
+ const getInitialMarketItemsPerPage = () => {
+ if (typeof window !== "undefined" && window.localStorage) {
+ const rawValue = Number(localStorage.getItem("pluginMarketItemsPerPage"));
+ if (marketItemsPerPageOptions.includes(rawValue)) {
+ return rawValue;
+ }
+ }
+ return 9;
+ };
+ const marketItemsPerPage = ref(getInitialMarketItemsPerPage());
const marketSearch = ref("");
const debouncedMarketSearch = ref("");
const refreshingMarket = ref(false);
@@ -469,12 +480,12 @@ export const useExtensionPage = (initialTab = "installed") => {
const displayItemsPerPage = 9; // 固定每页显示9个卡片(3行)
const totalPages = computed(() => {
- return Math.ceil(sortedPlugins.value.length / displayItemsPerPage);
+ return Math.ceil(sortedPlugins.value.length / marketItemsPerPage.value);
});
const paginatedPlugins = computed(() => {
- const start = (currentPage.value - 1) * displayItemsPerPage;
- const end = start + displayItemsPerPage;
+ const start = (currentPage.value - 1) * marketItemsPerPage.value;
+ const end = start + marketItemsPerPage.value;
return sortedPlugins.value.slice(start, end);
});
@@ -2424,6 +2435,13 @@ export const useExtensionPage = (initialTab = "installed") => {
}, 300); // 300ms 防抖延迟
});
+ watch(marketItemsPerPage, (newVal) => {
+ currentPage.value = 1;
+ if (typeof window !== "undefined" && window.localStorage) {
+ localStorage.setItem("pluginMarketItemsPerPage", String(newVal));
+ }
+ });
+
watch(
[() => dialog.value, () => extension_url.value, () => uploadTab.value],
async ([dialogOpen, _, currentUploadTab]) => {
@@ -2578,6 +2596,8 @@ export const useExtensionPage = (initialTab = "installed") => {
randomPlugins,
shufflePlugins,
refreshRandomPlugins,
+ marketItemsPerPage,
+ marketItemsPerPageOptions,
displayItemsPerPage,
totalPages,
paginatedPlugins,
diff --git a/tests/test_anthropic_kimi_code_provider.py b/tests/test_anthropic_kimi_code_provider.py
index 0dc33f58ba..d54894a05f 100644
--- a/tests/test_anthropic_kimi_code_provider.py
+++ b/tests/test_anthropic_kimi_code_provider.py
@@ -137,7 +137,13 @@ def fake_create_proxy_client(
assert captured["provider_label"] == "Anthropic"
assert captured["proxy"] == "http://127.0.0.1:7890"
assert captured["headers"] == {"X-Trace-Id": "trace-1"}
- assert captured["httpx_module"] is anthropic_base_client.httpx
+ sdk_httpx = getattr(
+ anthropic_base_client,
+ "httpx2",
+ getattr(anthropic_base_client, "httpx", None),
+ )
+ assert sdk_httpx is not None
+ assert captured["httpx_module"] is sdk_httpx
def test_create_http_client_falls_back_to_global_httpx_module(monkeypatch):