@blocklet/aigne-hub 0.2.15 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/api/call/index.js +1 -0
- package/lib/cjs/api/call/v2.js +84 -50
- package/lib/cjs/api/types/user.js +2 -0
- package/lib/cjs/api/user.js +36 -0
- package/lib/cjs/api/utils/util.js +42 -0
- package/lib/cjs/components/credit/alert.js +4 -3
- package/lib/cjs/components/index.js +3 -1
- package/lib/cjs/components/user-credit-card.js +97 -0
- package/lib/cjs/utils/util.js +24 -0
- package/lib/esm/api/call/index.js +1 -0
- package/lib/esm/api/call/v2.js +83 -51
- package/lib/esm/api/types/user.js +1 -0
- package/lib/esm/api/user.js +30 -0
- package/lib/esm/api/utils/util.js +34 -0
- package/lib/esm/components/credit/alert.js +2 -1
- package/lib/esm/components/index.js +1 -0
- package/lib/esm/components/user-credit-card.js +92 -0
- package/lib/esm/utils/util.js +18 -0
- package/lib/types/api/call/index.d.ts +1 -0
- package/lib/types/api/call/v2.d.ts +18 -6
- package/lib/types/api/types/user.d.ts +15 -0
- package/lib/types/api/user.d.ts +5 -0
- package/lib/types/api/utils/util.d.ts +2 -0
- package/lib/types/components/index.d.ts +1 -0
- package/lib/types/components/user-credit-card.d.ts +11 -0
- package/lib/types/utils/util.d.ts +1 -0
- package/package.json +14 -2
package/lib/cjs/api/call/v2.js
CHANGED
|
@@ -3,41 +3,85 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.callRemoteApi = callRemoteApi;
|
|
6
7
|
exports.chatCompletionsV2 = chatCompletionsV2;
|
|
7
8
|
exports.imageGenerationsV2 = imageGenerationsV2;
|
|
8
9
|
exports.embeddingsV2 = embeddingsV2;
|
|
10
|
+
exports.getUserCreditInfo = getUserCreditInfo;
|
|
9
11
|
const web_1 = require("stream/web");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
const ufo_1 = require("ufo");
|
|
12
14
|
const types_1 = require("../types");
|
|
13
|
-
const auth_1 = require("../utils/auth");
|
|
14
15
|
const event_stream_1 = require("../utils/event-stream");
|
|
16
|
+
const util_1 = require("../utils/util");
|
|
15
17
|
const api_1 = require("./api");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
18
|
+
let cachedUrl = null;
|
|
19
|
+
const CACHE_TTL = 30 * 60 * 1000; // 30分钟
|
|
20
|
+
function isCacheExpired(cacheItem) {
|
|
21
|
+
if (!cacheItem)
|
|
22
|
+
return true;
|
|
23
|
+
return Date.now() - cacheItem.timestamp > CACHE_TTL;
|
|
24
|
+
}
|
|
25
|
+
function getConfig() {
|
|
26
|
+
const baseUrl = process.env.BLOCKLET_AIGNE_API_URL;
|
|
27
|
+
const credentials = JSON.parse(process.env.BLOCKLET_AIGNE_API_CREDENTIAL || '{}');
|
|
28
|
+
const accessKey = credentials === null || credentials === void 0 ? void 0 : credentials.apiKey;
|
|
29
|
+
if (!baseUrl || !accessKey) {
|
|
30
|
+
throw new Error('Please connect to AIGNE Hub First, baseUrl or accessKey not found');
|
|
31
|
+
}
|
|
32
|
+
return { baseUrl, accessKey };
|
|
33
|
+
}
|
|
34
|
+
async function getCachedUrl(url) {
|
|
35
|
+
if (url !== (cachedUrl === null || cachedUrl === void 0 ? void 0 : cachedUrl.data)) {
|
|
36
|
+
cachedUrl = null;
|
|
37
|
+
}
|
|
38
|
+
if (isCacheExpired(cachedUrl)) {
|
|
39
|
+
const { baseUrl } = getConfig();
|
|
40
|
+
const url = await (0, util_1.getRemoteBaseUrl)(baseUrl);
|
|
41
|
+
cachedUrl = {
|
|
42
|
+
data: url,
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return cachedUrl.data;
|
|
47
|
+
}
|
|
48
|
+
async function callRemoteApi(input, config, options = {}) {
|
|
49
|
+
const { accessKey, baseUrl } = getConfig();
|
|
50
|
+
const url = await getCachedUrl(baseUrl);
|
|
51
|
+
const headers = {
|
|
52
|
+
Authorization: `Bearer ${accessKey}`,
|
|
53
|
+
...config.additionalHeaders,
|
|
54
|
+
};
|
|
55
|
+
if (config.isStreamEndpoint) {
|
|
56
|
+
headers.Accept = 'text/event-stream';
|
|
57
|
+
headers['Content-Type'] = 'application/json';
|
|
58
|
+
}
|
|
59
|
+
const method = config.method || 'POST';
|
|
60
|
+
const requestConfig = {
|
|
61
|
+
method,
|
|
62
|
+
url: (0, ufo_1.joinURL)(url, config.endpoint),
|
|
63
|
+
headers,
|
|
64
|
+
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
65
|
+
};
|
|
66
|
+
if (method === 'GET') {
|
|
67
|
+
requestConfig.params = input;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
requestConfig.data = input;
|
|
71
|
+
}
|
|
72
|
+
return (0, api_1.catchAndRethrowUpstreamError)(axios_1.default.request(requestConfig));
|
|
73
|
+
}
|
|
74
|
+
async function chatCompletionsV2(input, options = {}) {
|
|
75
|
+
const response = await callRemoteApi(input, {
|
|
76
|
+
endpoint: 'api/v2/chat/completions',
|
|
77
|
+
isStreamEndpoint: true,
|
|
78
|
+
}, options);
|
|
35
79
|
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
|
|
36
80
|
return response;
|
|
37
81
|
return new web_1.ReadableStream({
|
|
38
82
|
async start(controller) {
|
|
39
83
|
try {
|
|
40
|
-
const stream = (0, event_stream_1.readableToWeb)(
|
|
84
|
+
const stream = (0, event_stream_1.readableToWeb)(response.data)
|
|
41
85
|
.pipeThrough(new web_1.TextDecoderStream())
|
|
42
86
|
.pipeThrough(new event_stream_1.EventSourceParserStream());
|
|
43
87
|
for await (const chunk of stream) {
|
|
@@ -65,37 +109,27 @@ async function chatCompletionsV2(input, { useAIKitService, ...options } = {}) {
|
|
|
65
109
|
},
|
|
66
110
|
});
|
|
67
111
|
}
|
|
68
|
-
async function imageGenerationsV2(input,
|
|
69
|
-
const response = await (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
headers: { ...(0, auth_1.getRemoteComponentCallHeaders)(input, options.userDid) },
|
|
73
|
-
})
|
|
74
|
-
: // @ts-ignore
|
|
75
|
-
(0, component_1.call)({
|
|
76
|
-
name: 'ai-kit',
|
|
77
|
-
path: '/api/v2/image/generations',
|
|
78
|
-
data: input,
|
|
79
|
-
responseType: options === null || options === void 0 ? void 0 : options.responseType,
|
|
80
|
-
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
81
|
-
}));
|
|
112
|
+
async function imageGenerationsV2(input, options = {}) {
|
|
113
|
+
const response = await callRemoteApi(input, {
|
|
114
|
+
endpoint: 'api/v2/image/generations',
|
|
115
|
+
}, options);
|
|
82
116
|
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
|
|
83
117
|
return response;
|
|
84
118
|
return response.data;
|
|
85
119
|
}
|
|
86
|
-
async function embeddingsV2(input,
|
|
87
|
-
const response = await (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
})
|
|
92
|
-
: (0, component_1.call)({
|
|
93
|
-
name: 'ai-kit',
|
|
94
|
-
path: '/api/v2/embeddings',
|
|
95
|
-
data: input,
|
|
96
|
-
responseType: options === null || options === void 0 ? void 0 : options.responseType,
|
|
97
|
-
}));
|
|
98
|
-
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
|
|
120
|
+
async function embeddingsV2(input, options = {}) {
|
|
121
|
+
const response = await callRemoteApi(input, {
|
|
122
|
+
endpoint: 'api/v2/embeddings',
|
|
123
|
+
}, options);
|
|
124
|
+
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream') {
|
|
99
125
|
return response;
|
|
126
|
+
}
|
|
127
|
+
return response.data;
|
|
128
|
+
}
|
|
129
|
+
async function getUserCreditInfo() {
|
|
130
|
+
const response = await callRemoteApi({}, {
|
|
131
|
+
endpoint: 'api/user/info',
|
|
132
|
+
method: 'GET',
|
|
133
|
+
});
|
|
100
134
|
return response.data;
|
|
101
135
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getUserInfo = getUserInfo;
|
|
7
|
+
const error_1 = require("@blocklet/error");
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const ufo_1 = require("ufo");
|
|
10
|
+
const util_1 = require("./utils/util");
|
|
11
|
+
async function getUserInfo({ baseUrl = '', accessKey = '', }) {
|
|
12
|
+
let finalBaseUrl = (0, util_1.getPrefix)();
|
|
13
|
+
const windowExist = typeof window !== 'undefined';
|
|
14
|
+
try {
|
|
15
|
+
if (baseUrl) {
|
|
16
|
+
const tmp = new URL(baseUrl);
|
|
17
|
+
if (!windowExist || (windowExist && tmp.origin !== window.location.origin)) {
|
|
18
|
+
finalBaseUrl = await (0, util_1.getRemoteBaseUrl)(baseUrl);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
console.warn('Failed to parse baseUrl:', err);
|
|
24
|
+
throw new Error(`Failed to parse baseUrl: ${(0, error_1.formatError)(err)}`);
|
|
25
|
+
}
|
|
26
|
+
if (!finalBaseUrl || !accessKey) {
|
|
27
|
+
throw new Error('baseUrl or accessKey is not set');
|
|
28
|
+
}
|
|
29
|
+
return axios_1.default
|
|
30
|
+
.get((0, ufo_1.joinURL)(finalBaseUrl, '/api/user/info'), {
|
|
31
|
+
headers: {
|
|
32
|
+
Authorization: `Bearer ${accessKey}`,
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
.then((res) => res.data);
|
|
36
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getPrefix = exports.getRemoteBaseUrl = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const ufo_1 = require("ufo");
|
|
9
|
+
const AIGNE_HUB_DID = 'z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ';
|
|
10
|
+
const getRemoteBaseUrl = async (url) => {
|
|
11
|
+
const tmp = new URL(url);
|
|
12
|
+
if (typeof window !== 'undefined' && tmp.origin === window.location.origin) {
|
|
13
|
+
return (0, exports.getPrefix)();
|
|
14
|
+
}
|
|
15
|
+
const scriptUrl = (0, ufo_1.joinURL)(tmp.origin, '__blocklet__.js?type=json');
|
|
16
|
+
const blockletInfo = await axios_1.default.get(scriptUrl).then((res) => res.data);
|
|
17
|
+
const componentId = ((blockletInfo === null || blockletInfo === void 0 ? void 0 : blockletInfo.componentId) || '').split('/').pop();
|
|
18
|
+
if (componentId === AIGNE_HUB_DID) {
|
|
19
|
+
return (0, ufo_1.joinURL)(tmp.origin, blockletInfo.prefix || '/');
|
|
20
|
+
}
|
|
21
|
+
const component = ((blockletInfo === null || blockletInfo === void 0 ? void 0 : blockletInfo.componentMountPoints) || []).find((x) => (x === null || x === void 0 ? void 0 : x.did) === AIGNE_HUB_DID);
|
|
22
|
+
return component ? (0, ufo_1.joinURL)(tmp.origin, component.mountPoint) : url;
|
|
23
|
+
};
|
|
24
|
+
exports.getRemoteBaseUrl = getRemoteBaseUrl;
|
|
25
|
+
const getPrefix = () => {
|
|
26
|
+
var _a, _b, _c, _d;
|
|
27
|
+
if (typeof window === 'undefined') {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
const prefix = ((_a = window.blocklet) === null || _a === void 0 ? void 0 : _a.prefix) || '/';
|
|
31
|
+
const baseUrl = (_b = window.location) === null || _b === void 0 ? void 0 : _b.origin; // required when use payment feature cross origin
|
|
32
|
+
const componentId = (((_c = window.blocklet) === null || _c === void 0 ? void 0 : _c.componentId) || '').split('/').pop();
|
|
33
|
+
if (componentId === AIGNE_HUB_DID) {
|
|
34
|
+
return (0, ufo_1.joinURL)(baseUrl, prefix);
|
|
35
|
+
}
|
|
36
|
+
const component = (((_d = window.blocklet) === null || _d === void 0 ? void 0 : _d.componentMountPoints) || []).find((x) => (x === null || x === void 0 ? void 0 : x.did) === AIGNE_HUB_DID);
|
|
37
|
+
if (component) {
|
|
38
|
+
return (0, ufo_1.joinURL)(baseUrl, component.mountPoint);
|
|
39
|
+
}
|
|
40
|
+
return (0, ufo_1.joinURL)(baseUrl, prefix);
|
|
41
|
+
};
|
|
42
|
+
exports.getPrefix = getPrefix;
|
|
@@ -5,15 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const context_1 = require("@arcblock/ux/lib/Locale/context");
|
|
8
|
+
const error_1 = require("@blocklet/error");
|
|
8
9
|
const material_1 = require("@mui/material");
|
|
9
|
-
const
|
|
10
|
+
const error_2 = require("../../api/error");
|
|
10
11
|
const withLocaleProvider_1 = __importDefault(require("../../utils/withLocaleProvider"));
|
|
11
12
|
const button_1 = __importDefault(require("./button"));
|
|
12
13
|
function CreditErrorAlert({ error, ...props }) {
|
|
13
14
|
const { t } = (0, context_1.useLocaleContext)();
|
|
14
|
-
const isCreditError = (error === null || error === void 0 ? void 0 : error.type) ===
|
|
15
|
+
const isCreditError = (error === null || error === void 0 ? void 0 : error.type) === error_2.CreditErrorType.NOT_ENOUGH;
|
|
15
16
|
if (!isCreditError) {
|
|
16
|
-
return ((0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", ...props, children: (
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", ...props, children: (0, error_1.formatError)(error) || t('unknownError') }));
|
|
17
18
|
}
|
|
18
19
|
return ((0, jsx_runtime_1.jsxs)(material_1.Alert, { severity: "warning", ...props, sx: {
|
|
19
20
|
px: 1,
|
|
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.FormLabel = exports.Table = exports.Switch = exports.CreditErrorAlert = exports.CreditBalance = exports.CreditButton = exports.SubscribeErrorAlert = exports.SubscribeButton = exports.Conversation = exports.ImagePreview = exports.LoadingImage = void 0;
|
|
21
|
+
exports.FormLabel = exports.UserCreditCard = exports.Table = exports.Switch = exports.CreditErrorAlert = exports.CreditBalance = exports.CreditButton = exports.SubscribeErrorAlert = exports.SubscribeButton = exports.Conversation = exports.ImagePreview = exports.LoadingImage = void 0;
|
|
22
22
|
var loading_image_1 = require("./loading-image");
|
|
23
23
|
Object.defineProperty(exports, "LoadingImage", { enumerable: true, get: function () { return __importDefault(loading_image_1).default; } });
|
|
24
24
|
var image_preview_1 = require("./image-preview");
|
|
@@ -41,5 +41,7 @@ var switch_button_1 = require("./switch-button");
|
|
|
41
41
|
Object.defineProperty(exports, "Switch", { enumerable: true, get: function () { return __importDefault(switch_button_1).default; } });
|
|
42
42
|
var table_1 = require("./table");
|
|
43
43
|
Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return __importDefault(table_1).default; } });
|
|
44
|
+
var user_credit_card_1 = require("./user-credit-card");
|
|
45
|
+
Object.defineProperty(exports, "UserCreditCard", { enumerable: true, get: function () { return __importDefault(user_credit_card_1).default; } });
|
|
44
46
|
var form_label_1 = require("./form-label");
|
|
45
47
|
Object.defineProperty(exports, "FormLabel", { enumerable: true, get: function () { return __importDefault(form_label_1).default; } });
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const context_1 = require("@arcblock/ux/lib/Locale/context");
|
|
8
|
+
const Toast_1 = __importDefault(require("@arcblock/ux/lib/Toast"));
|
|
9
|
+
const UserCard_1 = __importDefault(require("@arcblock/ux/lib/UserCard"));
|
|
10
|
+
const error_1 = require("@blocklet/error");
|
|
11
|
+
const material_1 = require("@mui/material");
|
|
12
|
+
const ahooks_1 = require("ahooks");
|
|
13
|
+
const user_1 = require("../api/user");
|
|
14
|
+
const util_1 = require("../utils/util");
|
|
15
|
+
const withLocaleProvider_1 = __importDefault(require("../utils/withLocaleProvider"));
|
|
16
|
+
function UserCreditCard({ baseUrl, accessKey, onSuccess = () => { }, onError = () => { }, mode = 'default', render = () => null, }) {
|
|
17
|
+
var _a, _b, _c, _d, _e, _f;
|
|
18
|
+
const { t } = (0, context_1.useLocaleContext)();
|
|
19
|
+
const { data: userInfoData, loading } = (0, ahooks_1.useRequest)(() => (0, user_1.getUserInfo)({ baseUrl, accessKey }), {
|
|
20
|
+
refreshDeps: [baseUrl, accessKey],
|
|
21
|
+
onError: (err) => {
|
|
22
|
+
Toast_1.default.error((0, error_1.formatError)(err));
|
|
23
|
+
onError === null || onError === void 0 ? void 0 : onError(err);
|
|
24
|
+
},
|
|
25
|
+
onSuccess: (data) => {
|
|
26
|
+
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(data);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
if (loading) {
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { p: 2, textAlign: 'center' }, children: [(0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 24 }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: t('loadingUserInfo') })] }));
|
|
31
|
+
}
|
|
32
|
+
if (!userInfoData) {
|
|
33
|
+
return ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: { p: 2 }, children: (0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "info", sx: { fontSize: '0.875rem' }, children: t('noUserData') }) }));
|
|
34
|
+
}
|
|
35
|
+
if (mode === 'custom') {
|
|
36
|
+
return render(userInfoData);
|
|
37
|
+
}
|
|
38
|
+
return ((0, jsx_runtime_1.jsxs)(material_1.Stack, { sx: { p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2, width: '100%' }, spacing: 2, className: "user-credit-card", children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: t('username') }), (0, jsx_runtime_1.jsx)(UserCard_1.default, { user: userInfoData.user, showHoverCard: true, popupShowDid: true, sx: {
|
|
39
|
+
border: 'none',
|
|
40
|
+
p: 0,
|
|
41
|
+
minWidth: 0,
|
|
42
|
+
}, avatarProps: {
|
|
43
|
+
size: 24,
|
|
44
|
+
} })] }), (userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.enableCredit) ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: t('creditBalance') }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "h6", fontWeight: "bold", children: [(0, util_1.formatNumber)(((_a = userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.creditBalance) === null || _a === void 0 ? void 0 : _a.balance) || '0'), " ", (_c = (_b = userInfoData.currency) === null || _b === void 0 ? void 0 : _b.symbol) !== null && _c !== void 0 ? _c : 'AHC'] })] }), ((_d = userInfoData.creditBalance) === null || _d === void 0 ? void 0 : _d.pendingCredit) && Number(userInfoData.creditBalance.pendingCredit) > 0 && ((0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: t('pendingCredit') }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "h6", fontWeight: "bold", sx: { color: 'error.main' }, children: [(0, util_1.formatNumber)(userInfoData.creditBalance.pendingCredit), " ", (_f = (_e = userInfoData.currency) === null || _e === void 0 ? void 0 : _e.symbol) !== null && _f !== void 0 ? _f : 'AHC'] })] })), (0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", spacing: 1.5, sx: { mt: 1 }, children: [(userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.paymentLink) && ((0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: () => {
|
|
45
|
+
window.open((userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.paymentLink) || '', '_blank');
|
|
46
|
+
}, sx: {
|
|
47
|
+
flex: 1,
|
|
48
|
+
}, children: t('recharge') })), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "text", onClick: () => {
|
|
49
|
+
window.open((userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.profileLink) || '', '_blank');
|
|
50
|
+
}, sx: {
|
|
51
|
+
borderColor: 'primary.main',
|
|
52
|
+
color: 'primary.main',
|
|
53
|
+
}, children: t('manage') })] })] })) : ((0, jsx_runtime_1.jsxs)(material_1.Alert, { severity: "info", sx: {
|
|
54
|
+
textAlign: 'left',
|
|
55
|
+
}, children: [t('creditNotEnabled'), (0, jsx_runtime_1.jsx)(material_1.Typography, { sx: {
|
|
56
|
+
display: 'inline-block',
|
|
57
|
+
fontSize: 'inherit',
|
|
58
|
+
lineHeight: 'inherit',
|
|
59
|
+
ml: 1,
|
|
60
|
+
a: {
|
|
61
|
+
textDecoration: 'none',
|
|
62
|
+
},
|
|
63
|
+
'& .MuiButtonBase-root': { p: 0, minWidth: 'auto' },
|
|
64
|
+
}, children: (0, jsx_runtime_1.jsx)(material_1.Link, { href: (userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.profileLink) || '', target: "_blank", children: t('viewProfile') }) })] }))] }));
|
|
65
|
+
}
|
|
66
|
+
exports.default = (0, withLocaleProvider_1.default)(UserCreditCard, {
|
|
67
|
+
translations: {
|
|
68
|
+
en: {
|
|
69
|
+
username: 'User',
|
|
70
|
+
creditBalance: 'Credit Balance',
|
|
71
|
+
pendingCredit: 'Outstanding Charges',
|
|
72
|
+
recharge: 'Buy Credits',
|
|
73
|
+
manage: 'Manage',
|
|
74
|
+
creditNotEnabled: 'AIGNE Hub Credit billing is not enabled. You can use AI services directly.',
|
|
75
|
+
loadingUserInfo: 'Loading user information...',
|
|
76
|
+
fetchUserInfoFailed: 'Failed to fetch user information',
|
|
77
|
+
unknownUser: 'Unknown User',
|
|
78
|
+
noUserData: 'No user data available',
|
|
79
|
+
retry: 'Retry',
|
|
80
|
+
viewProfile: 'View Profile',
|
|
81
|
+
},
|
|
82
|
+
zh: {
|
|
83
|
+
username: '用户',
|
|
84
|
+
creditBalance: '信用额度',
|
|
85
|
+
pendingCredit: '待结清额度',
|
|
86
|
+
recharge: '购买额度',
|
|
87
|
+
manage: '管理额度',
|
|
88
|
+
creditNotEnabled: 'AIGNE Hub 未启用 Credit 计费功能,您可以直接使用AI服务。',
|
|
89
|
+
loadingUserInfo: '正在加载用户信息...',
|
|
90
|
+
fetchUserInfoFailed: '获取用户信息失败',
|
|
91
|
+
unknownUser: '未知用户',
|
|
92
|
+
noUserData: '暂无用户数据',
|
|
93
|
+
retry: '重试',
|
|
94
|
+
viewProfile: '查看用户信息',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.formatNumber = formatNumber;
|
|
7
|
+
const trimEnd_1 = __importDefault(require("lodash/trimEnd"));
|
|
8
|
+
const numbro_1 = __importDefault(require("numbro"));
|
|
9
|
+
function formatNumber(n, precision = 6, trim = true, thousandSeparated = true) {
|
|
10
|
+
if (!n || n === '0') {
|
|
11
|
+
return '0';
|
|
12
|
+
}
|
|
13
|
+
const num = (0, numbro_1.default)(n);
|
|
14
|
+
const options = {
|
|
15
|
+
thousandSeparated,
|
|
16
|
+
...((precision || precision === 0) && { mantissa: precision }),
|
|
17
|
+
};
|
|
18
|
+
const result = num.format(options);
|
|
19
|
+
if (!trim) {
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
const [left, right] = result.split('.');
|
|
23
|
+
return right ? [left, (0, trimEnd_1.default)(right, '0')].filter(Boolean).join('.') : left;
|
|
24
|
+
}
|
package/lib/esm/api/call/v2.js
CHANGED
|
@@ -1,35 +1,77 @@
|
|
|
1
1
|
import { ReadableStream, TextDecoderStream } from 'stream/web';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { joinURL } from 'ufo';
|
|
4
4
|
import { isChatCompletionError, } from '../types';
|
|
5
|
-
import { getRemoteComponentCallHeaders } from '../utils/auth';
|
|
6
5
|
import { EventSourceParserStream, readableToWeb } from '../utils/event-stream';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
6
|
+
import { getRemoteBaseUrl } from '../utils/util';
|
|
7
|
+
import { catchAndRethrowUpstreamError } from './api';
|
|
8
|
+
let cachedUrl = null;
|
|
9
|
+
const CACHE_TTL = 30 * 60 * 1000; // 30分钟
|
|
10
|
+
function isCacheExpired(cacheItem) {
|
|
11
|
+
if (!cacheItem)
|
|
12
|
+
return true;
|
|
13
|
+
return Date.now() - cacheItem.timestamp > CACHE_TTL;
|
|
14
|
+
}
|
|
15
|
+
function getConfig() {
|
|
16
|
+
const baseUrl = process.env.BLOCKLET_AIGNE_API_URL;
|
|
17
|
+
const credentials = JSON.parse(process.env.BLOCKLET_AIGNE_API_CREDENTIAL || '{}');
|
|
18
|
+
const accessKey = credentials === null || credentials === void 0 ? void 0 : credentials.apiKey;
|
|
19
|
+
if (!baseUrl || !accessKey) {
|
|
20
|
+
throw new Error('Please connect to AIGNE Hub First, baseUrl or accessKey not found');
|
|
21
|
+
}
|
|
22
|
+
return { baseUrl, accessKey };
|
|
23
|
+
}
|
|
24
|
+
async function getCachedUrl(url) {
|
|
25
|
+
if (url !== (cachedUrl === null || cachedUrl === void 0 ? void 0 : cachedUrl.data)) {
|
|
26
|
+
cachedUrl = null;
|
|
27
|
+
}
|
|
28
|
+
if (isCacheExpired(cachedUrl)) {
|
|
29
|
+
const { baseUrl } = getConfig();
|
|
30
|
+
const url = await getRemoteBaseUrl(baseUrl);
|
|
31
|
+
cachedUrl = {
|
|
32
|
+
data: url,
|
|
33
|
+
timestamp: Date.now(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return cachedUrl.data;
|
|
37
|
+
}
|
|
38
|
+
export async function callRemoteApi(input, config, options = {}) {
|
|
39
|
+
const { accessKey, baseUrl } = getConfig();
|
|
40
|
+
const url = await getCachedUrl(baseUrl);
|
|
41
|
+
const headers = {
|
|
42
|
+
Authorization: `Bearer ${accessKey}`,
|
|
43
|
+
...config.additionalHeaders,
|
|
44
|
+
};
|
|
45
|
+
if (config.isStreamEndpoint) {
|
|
46
|
+
headers.Accept = 'text/event-stream';
|
|
47
|
+
headers['Content-Type'] = 'application/json';
|
|
48
|
+
}
|
|
49
|
+
const method = config.method || 'POST';
|
|
50
|
+
const requestConfig = {
|
|
51
|
+
method,
|
|
52
|
+
url: joinURL(url, config.endpoint),
|
|
53
|
+
headers,
|
|
54
|
+
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
55
|
+
};
|
|
56
|
+
if (method === 'GET') {
|
|
57
|
+
requestConfig.params = input;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
requestConfig.data = input;
|
|
61
|
+
}
|
|
62
|
+
return catchAndRethrowUpstreamError(axios.request(requestConfig));
|
|
63
|
+
}
|
|
64
|
+
export async function chatCompletionsV2(input, options = {}) {
|
|
65
|
+
const response = await callRemoteApi(input, {
|
|
66
|
+
endpoint: 'api/v2/chat/completions',
|
|
67
|
+
isStreamEndpoint: true,
|
|
68
|
+
}, options);
|
|
27
69
|
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
|
|
28
70
|
return response;
|
|
29
71
|
return new ReadableStream({
|
|
30
72
|
async start(controller) {
|
|
31
73
|
try {
|
|
32
|
-
const stream = readableToWeb(
|
|
74
|
+
const stream = readableToWeb(response.data)
|
|
33
75
|
.pipeThrough(new TextDecoderStream())
|
|
34
76
|
.pipeThrough(new EventSourceParserStream());
|
|
35
77
|
for await (const chunk of stream) {
|
|
@@ -57,37 +99,27 @@ export async function chatCompletionsV2(input, { useAIKitService, ...options } =
|
|
|
57
99
|
},
|
|
58
100
|
});
|
|
59
101
|
}
|
|
60
|
-
export async function imageGenerationsV2(input,
|
|
61
|
-
const response = await
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
headers: { ...getRemoteComponentCallHeaders(input, options.userDid) },
|
|
65
|
-
})
|
|
66
|
-
: // @ts-ignore
|
|
67
|
-
call({
|
|
68
|
-
name: 'ai-kit',
|
|
69
|
-
path: '/api/v2/image/generations',
|
|
70
|
-
data: input,
|
|
71
|
-
responseType: options === null || options === void 0 ? void 0 : options.responseType,
|
|
72
|
-
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
73
|
-
}));
|
|
102
|
+
export async function imageGenerationsV2(input, options = {}) {
|
|
103
|
+
const response = await callRemoteApi(input, {
|
|
104
|
+
endpoint: 'api/v2/image/generations',
|
|
105
|
+
}, options);
|
|
74
106
|
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
|
|
75
107
|
return response;
|
|
76
108
|
return response.data;
|
|
77
109
|
}
|
|
78
|
-
export async function embeddingsV2(input,
|
|
79
|
-
const response = await
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
})
|
|
84
|
-
: call({
|
|
85
|
-
name: 'ai-kit',
|
|
86
|
-
path: '/api/v2/embeddings',
|
|
87
|
-
data: input,
|
|
88
|
-
responseType: options === null || options === void 0 ? void 0 : options.responseType,
|
|
89
|
-
}));
|
|
90
|
-
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
|
|
110
|
+
export async function embeddingsV2(input, options = {}) {
|
|
111
|
+
const response = await callRemoteApi(input, {
|
|
112
|
+
endpoint: 'api/v2/embeddings',
|
|
113
|
+
}, options);
|
|
114
|
+
if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream') {
|
|
91
115
|
return response;
|
|
116
|
+
}
|
|
117
|
+
return response.data;
|
|
118
|
+
}
|
|
119
|
+
export async function getUserCreditInfo() {
|
|
120
|
+
const response = await callRemoteApi({}, {
|
|
121
|
+
endpoint: 'api/user/info',
|
|
122
|
+
method: 'GET',
|
|
123
|
+
});
|
|
92
124
|
return response.data;
|
|
93
125
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { formatError } from '@blocklet/error';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { joinURL } from 'ufo';
|
|
4
|
+
import { getPrefix, getRemoteBaseUrl } from './utils/util';
|
|
5
|
+
export async function getUserInfo({ baseUrl = '', accessKey = '', }) {
|
|
6
|
+
let finalBaseUrl = getPrefix();
|
|
7
|
+
const windowExist = typeof window !== 'undefined';
|
|
8
|
+
try {
|
|
9
|
+
if (baseUrl) {
|
|
10
|
+
const tmp = new URL(baseUrl);
|
|
11
|
+
if (!windowExist || (windowExist && tmp.origin !== window.location.origin)) {
|
|
12
|
+
finalBaseUrl = await getRemoteBaseUrl(baseUrl);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
console.warn('Failed to parse baseUrl:', err);
|
|
18
|
+
throw new Error(`Failed to parse baseUrl: ${formatError(err)}`);
|
|
19
|
+
}
|
|
20
|
+
if (!finalBaseUrl || !accessKey) {
|
|
21
|
+
throw new Error('baseUrl or accessKey is not set');
|
|
22
|
+
}
|
|
23
|
+
return axios
|
|
24
|
+
.get(joinURL(finalBaseUrl, '/api/user/info'), {
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${accessKey}`,
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
.then((res) => res.data);
|
|
30
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { joinURL } from 'ufo';
|
|
3
|
+
const AIGNE_HUB_DID = 'z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ';
|
|
4
|
+
export const getRemoteBaseUrl = async (url) => {
|
|
5
|
+
const tmp = new URL(url);
|
|
6
|
+
if (typeof window !== 'undefined' && tmp.origin === window.location.origin) {
|
|
7
|
+
return getPrefix();
|
|
8
|
+
}
|
|
9
|
+
const scriptUrl = joinURL(tmp.origin, '__blocklet__.js?type=json');
|
|
10
|
+
const blockletInfo = await axios.get(scriptUrl).then((res) => res.data);
|
|
11
|
+
const componentId = ((blockletInfo === null || blockletInfo === void 0 ? void 0 : blockletInfo.componentId) || '').split('/').pop();
|
|
12
|
+
if (componentId === AIGNE_HUB_DID) {
|
|
13
|
+
return joinURL(tmp.origin, blockletInfo.prefix || '/');
|
|
14
|
+
}
|
|
15
|
+
const component = ((blockletInfo === null || blockletInfo === void 0 ? void 0 : blockletInfo.componentMountPoints) || []).find((x) => (x === null || x === void 0 ? void 0 : x.did) === AIGNE_HUB_DID);
|
|
16
|
+
return component ? joinURL(tmp.origin, component.mountPoint) : url;
|
|
17
|
+
};
|
|
18
|
+
export const getPrefix = () => {
|
|
19
|
+
var _a, _b, _c, _d;
|
|
20
|
+
if (typeof window === 'undefined') {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
const prefix = ((_a = window.blocklet) === null || _a === void 0 ? void 0 : _a.prefix) || '/';
|
|
24
|
+
const baseUrl = (_b = window.location) === null || _b === void 0 ? void 0 : _b.origin; // required when use payment feature cross origin
|
|
25
|
+
const componentId = (((_c = window.blocklet) === null || _c === void 0 ? void 0 : _c.componentId) || '').split('/').pop();
|
|
26
|
+
if (componentId === AIGNE_HUB_DID) {
|
|
27
|
+
return joinURL(baseUrl, prefix);
|
|
28
|
+
}
|
|
29
|
+
const component = (((_d = window.blocklet) === null || _d === void 0 ? void 0 : _d.componentMountPoints) || []).find((x) => (x === null || x === void 0 ? void 0 : x.did) === AIGNE_HUB_DID);
|
|
30
|
+
if (component) {
|
|
31
|
+
return joinURL(baseUrl, component.mountPoint);
|
|
32
|
+
}
|
|
33
|
+
return joinURL(baseUrl, prefix);
|
|
34
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
import { formatError } from '@blocklet/error';
|
|
3
4
|
import { Alert, Stack } from '@mui/material';
|
|
4
5
|
import { CreditErrorType } from '../../api/error';
|
|
5
6
|
import withLocaleProvider from '../../utils/withLocaleProvider';
|
|
@@ -8,7 +9,7 @@ function CreditErrorAlert({ error, ...props }) {
|
|
|
8
9
|
const { t } = useLocaleContext();
|
|
9
10
|
const isCreditError = (error === null || error === void 0 ? void 0 : error.type) === CreditErrorType.NOT_ENOUGH;
|
|
10
11
|
if (!isCreditError) {
|
|
11
|
-
return (_jsx(Alert, { severity: "error", ...props, children: (error
|
|
12
|
+
return (_jsx(Alert, { severity: "error", ...props, children: formatError(error) || t('unknownError') }));
|
|
12
13
|
}
|
|
13
14
|
return (_jsxs(Alert, { severity: "warning", ...props, sx: {
|
|
14
15
|
px: 1,
|
|
@@ -11,4 +11,5 @@ export { default as CreditBalance } from './credit/balance';
|
|
|
11
11
|
export { default as CreditErrorAlert } from './credit/alert';
|
|
12
12
|
export { default as Switch } from './switch-button';
|
|
13
13
|
export { default as Table } from './table';
|
|
14
|
+
export { default as UserCreditCard } from './user-credit-card';
|
|
14
15
|
export { default as FormLabel } from './form-label';
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
import Toast from '@arcblock/ux/lib/Toast';
|
|
4
|
+
import UserCard from '@arcblock/ux/lib/UserCard';
|
|
5
|
+
import { formatError } from '@blocklet/error';
|
|
6
|
+
import { Alert, Box, Button, CircularProgress, Link, Stack, Typography } from '@mui/material';
|
|
7
|
+
import { useRequest } from 'ahooks';
|
|
8
|
+
import { getUserInfo } from '../api/user';
|
|
9
|
+
import { formatNumber } from '../utils/util';
|
|
10
|
+
import withLocaleProvider from '../utils/withLocaleProvider';
|
|
11
|
+
function UserCreditCard({ baseUrl, accessKey, onSuccess = () => { }, onError = () => { }, mode = 'default', render = () => null, }) {
|
|
12
|
+
var _a, _b, _c, _d, _e, _f;
|
|
13
|
+
const { t } = useLocaleContext();
|
|
14
|
+
const { data: userInfoData, loading } = useRequest(() => getUserInfo({ baseUrl, accessKey }), {
|
|
15
|
+
refreshDeps: [baseUrl, accessKey],
|
|
16
|
+
onError: (err) => {
|
|
17
|
+
Toast.error(formatError(err));
|
|
18
|
+
onError === null || onError === void 0 ? void 0 : onError(err);
|
|
19
|
+
},
|
|
20
|
+
onSuccess: (data) => {
|
|
21
|
+
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(data);
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
if (loading) {
|
|
25
|
+
return (_jsxs(Box, { sx: { p: 2, textAlign: 'center' }, children: [_jsx(CircularProgress, { size: 24 }), _jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: t('loadingUserInfo') })] }));
|
|
26
|
+
}
|
|
27
|
+
if (!userInfoData) {
|
|
28
|
+
return (_jsx(Box, { sx: { p: 2 }, children: _jsx(Alert, { severity: "info", sx: { fontSize: '0.875rem' }, children: t('noUserData') }) }));
|
|
29
|
+
}
|
|
30
|
+
if (mode === 'custom') {
|
|
31
|
+
return render(userInfoData);
|
|
32
|
+
}
|
|
33
|
+
return (_jsxs(Stack, { sx: { p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2, width: '100%' }, spacing: 2, className: "user-credit-card", children: [_jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [_jsx(Typography, { variant: "body2", color: "text.secondary", children: t('username') }), _jsx(UserCard, { user: userInfoData.user, showHoverCard: true, popupShowDid: true, sx: {
|
|
34
|
+
border: 'none',
|
|
35
|
+
p: 0,
|
|
36
|
+
minWidth: 0,
|
|
37
|
+
}, avatarProps: {
|
|
38
|
+
size: 24,
|
|
39
|
+
} })] }), (userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.enableCredit) ? (_jsxs(_Fragment, { children: [_jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [_jsx(Typography, { variant: "body2", color: "text.secondary", children: t('creditBalance') }), _jsxs(Typography, { variant: "h6", fontWeight: "bold", children: [formatNumber(((_a = userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.creditBalance) === null || _a === void 0 ? void 0 : _a.balance) || '0'), " ", (_c = (_b = userInfoData.currency) === null || _b === void 0 ? void 0 : _b.symbol) !== null && _c !== void 0 ? _c : 'AHC'] })] }), ((_d = userInfoData.creditBalance) === null || _d === void 0 ? void 0 : _d.pendingCredit) && Number(userInfoData.creditBalance.pendingCredit) > 0 && (_jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [_jsx(Typography, { variant: "body2", color: "text.secondary", children: t('pendingCredit') }), _jsxs(Typography, { variant: "h6", fontWeight: "bold", sx: { color: 'error.main' }, children: [formatNumber(userInfoData.creditBalance.pendingCredit), " ", (_f = (_e = userInfoData.currency) === null || _e === void 0 ? void 0 : _e.symbol) !== null && _f !== void 0 ? _f : 'AHC'] })] })), _jsxs(Stack, { direction: "row", spacing: 1.5, sx: { mt: 1 }, children: [(userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.paymentLink) && (_jsx(Button, { variant: "outlined", onClick: () => {
|
|
40
|
+
window.open((userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.paymentLink) || '', '_blank');
|
|
41
|
+
}, sx: {
|
|
42
|
+
flex: 1,
|
|
43
|
+
}, children: t('recharge') })), _jsx(Button, { variant: "text", onClick: () => {
|
|
44
|
+
window.open((userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.profileLink) || '', '_blank');
|
|
45
|
+
}, sx: {
|
|
46
|
+
borderColor: 'primary.main',
|
|
47
|
+
color: 'primary.main',
|
|
48
|
+
}, children: t('manage') })] })] })) : (_jsxs(Alert, { severity: "info", sx: {
|
|
49
|
+
textAlign: 'left',
|
|
50
|
+
}, children: [t('creditNotEnabled'), _jsx(Typography, { sx: {
|
|
51
|
+
display: 'inline-block',
|
|
52
|
+
fontSize: 'inherit',
|
|
53
|
+
lineHeight: 'inherit',
|
|
54
|
+
ml: 1,
|
|
55
|
+
a: {
|
|
56
|
+
textDecoration: 'none',
|
|
57
|
+
},
|
|
58
|
+
'& .MuiButtonBase-root': { p: 0, minWidth: 'auto' },
|
|
59
|
+
}, children: _jsx(Link, { href: (userInfoData === null || userInfoData === void 0 ? void 0 : userInfoData.profileLink) || '', target: "_blank", children: t('viewProfile') }) })] }))] }));
|
|
60
|
+
}
|
|
61
|
+
export default withLocaleProvider(UserCreditCard, {
|
|
62
|
+
translations: {
|
|
63
|
+
en: {
|
|
64
|
+
username: 'User',
|
|
65
|
+
creditBalance: 'Credit Balance',
|
|
66
|
+
pendingCredit: 'Outstanding Charges',
|
|
67
|
+
recharge: 'Buy Credits',
|
|
68
|
+
manage: 'Manage',
|
|
69
|
+
creditNotEnabled: 'AIGNE Hub Credit billing is not enabled. You can use AI services directly.',
|
|
70
|
+
loadingUserInfo: 'Loading user information...',
|
|
71
|
+
fetchUserInfoFailed: 'Failed to fetch user information',
|
|
72
|
+
unknownUser: 'Unknown User',
|
|
73
|
+
noUserData: 'No user data available',
|
|
74
|
+
retry: 'Retry',
|
|
75
|
+
viewProfile: 'View Profile',
|
|
76
|
+
},
|
|
77
|
+
zh: {
|
|
78
|
+
username: '用户',
|
|
79
|
+
creditBalance: '信用额度',
|
|
80
|
+
pendingCredit: '待结清额度',
|
|
81
|
+
recharge: '购买额度',
|
|
82
|
+
manage: '管理额度',
|
|
83
|
+
creditNotEnabled: 'AIGNE Hub 未启用 Credit 计费功能,您可以直接使用AI服务。',
|
|
84
|
+
loadingUserInfo: '正在加载用户信息...',
|
|
85
|
+
fetchUserInfoFailed: '获取用户信息失败',
|
|
86
|
+
unknownUser: '未知用户',
|
|
87
|
+
noUserData: '暂无用户数据',
|
|
88
|
+
retry: '重试',
|
|
89
|
+
viewProfile: '查看用户信息',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import trimEnd from 'lodash/trimEnd';
|
|
2
|
+
import numbro from 'numbro';
|
|
3
|
+
export function formatNumber(n, precision = 6, trim = true, thousandSeparated = true) {
|
|
4
|
+
if (!n || n === '0') {
|
|
5
|
+
return '0';
|
|
6
|
+
}
|
|
7
|
+
const num = numbro(n);
|
|
8
|
+
const options = {
|
|
9
|
+
thousandSeparated,
|
|
10
|
+
...((precision || precision === 0) && { mantissa: precision }),
|
|
11
|
+
};
|
|
12
|
+
const result = num.format(options);
|
|
13
|
+
if (!trim) {
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
const [left, right] = result.split('.');
|
|
17
|
+
return right ? [left, trimEnd(right, '0')].filter(Boolean).join('.') : left;
|
|
18
|
+
}
|
|
@@ -2,29 +2,41 @@ import type { IncomingMessage } from 'http';
|
|
|
2
2
|
import { ReadableStream } from 'stream/web';
|
|
3
3
|
import { AxiosResponse } from 'axios';
|
|
4
4
|
import { ChatCompletionError, ChatCompletionInput, ChatCompletionResponse, EmbeddingInput, EmbeddingResponse, ImageGenerationInput, ImageGenerationResponse } from '../types';
|
|
5
|
+
import { UserInfoResult } from '../types/user';
|
|
6
|
+
interface RemoteApiOptions {
|
|
7
|
+
responseType?: 'stream';
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
interface RemoteApiConfig {
|
|
11
|
+
endpoint: string;
|
|
12
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
13
|
+
additionalHeaders?: Record<string, string>;
|
|
14
|
+
isStreamEndpoint?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function callRemoteApi<T = any>(input: any, config: RemoteApiConfig, options?: RemoteApiOptions): Promise<AxiosResponse<T, any>>;
|
|
5
17
|
export declare function chatCompletionsV2(input: ChatCompletionInput, options?: {
|
|
6
|
-
useAIKitService?: boolean;
|
|
7
18
|
responseType?: undefined;
|
|
19
|
+
timeout?: number;
|
|
8
20
|
}): Promise<ReadableStream<Exclude<ChatCompletionResponse, ChatCompletionError>>>;
|
|
9
21
|
export declare function chatCompletionsV2(input: ChatCompletionInput, options: {
|
|
10
|
-
useAIKitService?: boolean;
|
|
11
22
|
responseType: 'stream';
|
|
23
|
+
timeout?: number;
|
|
12
24
|
}): Promise<AxiosResponse<IncomingMessage, any>>;
|
|
13
25
|
export declare function imageGenerationsV2(input: ImageGenerationInput, options?: {
|
|
14
|
-
useAIKitService?: boolean;
|
|
15
26
|
responseType?: undefined;
|
|
16
27
|
timeout?: number;
|
|
17
28
|
}): Promise<ImageGenerationResponse>;
|
|
18
29
|
export declare function imageGenerationsV2(input: ImageGenerationInput, options: {
|
|
19
|
-
useAIKitService?: boolean;
|
|
20
30
|
responseType: 'stream';
|
|
21
31
|
timeout?: number;
|
|
22
32
|
}): Promise<AxiosResponse<IncomingMessage, any>>;
|
|
23
33
|
export declare function embeddingsV2(input: EmbeddingInput, options?: {
|
|
24
|
-
useAIKitService?: boolean;
|
|
25
34
|
responseType?: undefined;
|
|
35
|
+
timeout?: number;
|
|
26
36
|
}): Promise<EmbeddingResponse>;
|
|
27
37
|
export declare function embeddingsV2(input: EmbeddingInput, options: {
|
|
28
|
-
useAIKitService?: boolean;
|
|
29
38
|
responseType: 'stream';
|
|
39
|
+
timeout?: number;
|
|
30
40
|
}): Promise<AxiosResponse<IncomingMessage, any>>;
|
|
41
|
+
export declare function getUserCreditInfo(): Promise<UserInfoResult>;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { User } from '@arcblock/ux/lib/type';
|
|
2
|
+
import type { TPaymentCurrency } from '@blocklet/payment-js';
|
|
3
|
+
export interface UserInfoResult {
|
|
4
|
+
user: User;
|
|
5
|
+
enableCredit: boolean;
|
|
6
|
+
creditBalance: {
|
|
7
|
+
balance: string;
|
|
8
|
+
total: string;
|
|
9
|
+
grantCount: number;
|
|
10
|
+
pendingCredit: string;
|
|
11
|
+
} | null;
|
|
12
|
+
paymentLink: string | null;
|
|
13
|
+
currency?: TPaymentCurrency;
|
|
14
|
+
profileLink: string;
|
|
15
|
+
}
|
|
@@ -9,4 +9,5 @@ export { default as CreditBalance } from './credit/balance';
|
|
|
9
9
|
export { default as CreditErrorAlert } from './credit/alert';
|
|
10
10
|
export { default as Switch } from './switch-button';
|
|
11
11
|
export { default as Table } from './table';
|
|
12
|
+
export { default as UserCreditCard } from './user-credit-card';
|
|
12
13
|
export { default as FormLabel } from './form-label';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UserInfoResult } from '../api/types/user';
|
|
2
|
+
interface UserCreditCardProps {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
accessKey: string;
|
|
5
|
+
onSuccess?: (userInfo: UserInfoResult) => void;
|
|
6
|
+
onError?: (error: Error) => void;
|
|
7
|
+
mode?: 'default' | 'custom';
|
|
8
|
+
render?: (userInfo: UserInfoResult) => React.ReactNode | null;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: import("react").ComponentType<UserCreditCardProps>;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatNumber(n: number | string, precision?: number, trim?: boolean, thousandSeparated?: boolean): string | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/aigne-hub",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "The react.js component library for AIGNE Hub",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -46,6 +46,16 @@
|
|
|
46
46
|
"types": "./lib/types/components/*.d.ts",
|
|
47
47
|
"import": "./lib/esm/components/*.js",
|
|
48
48
|
"require": "./lib/cjs/components/*.js"
|
|
49
|
+
},
|
|
50
|
+
"./utils": {
|
|
51
|
+
"types": "./lib/types/utils/index.d.ts",
|
|
52
|
+
"import": "./lib/esm/utils/index.js",
|
|
53
|
+
"require": "./lib/cjs/utils/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./utils/*": {
|
|
56
|
+
"types": "./lib/types/utils/*.d.ts",
|
|
57
|
+
"import": "./lib/esm/utils/*.js",
|
|
58
|
+
"require": "./lib/cjs/utils/*.js"
|
|
49
59
|
}
|
|
50
60
|
},
|
|
51
61
|
"typesVersions": {
|
|
@@ -85,8 +95,9 @@
|
|
|
85
95
|
"dependencies": {
|
|
86
96
|
"@arcblock/did": "^1.21.0",
|
|
87
97
|
"@arcblock/ux": "^3.0.33",
|
|
98
|
+
"@blocklet/error": "0.2.5",
|
|
88
99
|
"@blocklet/logger": "^1.16.46",
|
|
89
|
-
"@blocklet/payment-js": "^1.19.
|
|
100
|
+
"@blocklet/payment-js": "^1.19.8",
|
|
90
101
|
"@blocklet/sdk": "^1.16.46",
|
|
91
102
|
"@emotion/css": "^11.13.5",
|
|
92
103
|
"@emotion/react": "^11.14.0",
|
|
@@ -109,6 +120,7 @@
|
|
|
109
120
|
"json-stable-stringify": "^1.1.1",
|
|
110
121
|
"lodash": "^4.17.21",
|
|
111
122
|
"nanoid": "^5.0.7",
|
|
123
|
+
"numbro": "^2.5.0",
|
|
112
124
|
"openai": "^4.56.0",
|
|
113
125
|
"react-markdown": "^9.0.1",
|
|
114
126
|
"react-photo-view": "^1.2.6",
|