@blocklet/aigne-hub 0.2.16 → 0.2.18

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.
@@ -3,35 +3,81 @@ 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 component_1 = require("@blocklet/sdk/lib/component");
11
- const json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
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
- async function chatCompletionsV2(input, { useAIKitService, ...options } = {}) {
17
- const response = (0, api_1.catchAndRethrowUpstreamError)(useAIKitService
18
- ? (0, api_1.aiKitApi)('/api/v2/chat/completions', {
19
- responseType: 'stream',
20
- method: 'POST',
21
- data: (0, json_stable_stringify_1.default)(input),
22
- headers: {
23
- ...(0, auth_1.getRemoteComponentCallHeaders)(input, options.userDid),
24
- Accept: 'text/event-stream',
25
- 'Content-Type': 'application/json',
26
- },
27
- })
28
- : (0, component_1.call)({
29
- name: 'ai-kit',
30
- path: 'api/v2/chat/completions',
31
- data: input,
32
- responseType: 'stream',
33
- headers: { Accept: 'text/event-stream' },
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
+ responseType: options === null || options === void 0 ? void 0 : options.responseType,
66
+ };
67
+ if (method === 'GET') {
68
+ requestConfig.params = input;
69
+ }
70
+ else {
71
+ requestConfig.data = input;
72
+ }
73
+ return (0, api_1.catchAndRethrowUpstreamError)(axios_1.default.request(requestConfig));
74
+ }
75
+ async function chatCompletionsV2(input, options = {}) {
76
+ const params = {
77
+ endpoint: 'api/v2/chat/completions',
78
+ isStreamEndpoint: true,
79
+ };
80
+ const response = await callRemoteApi(input, params, { ...options, responseType: 'stream' });
35
81
  if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
36
82
  return response;
37
83
  return new web_1.ReadableStream({
@@ -65,37 +111,20 @@ async function chatCompletionsV2(input, { useAIKitService, ...options } = {}) {
65
111
  },
66
112
  });
67
113
  }
68
- async function imageGenerationsV2(input, { useAIKitService, ...options } = {}) {
69
- const response = await (0, api_1.catchAndRethrowUpstreamError)(useAIKitService
70
- ? api_1.aiKitApi.post('/api/v2/image/generations', input, {
71
- responseType: options.responseType,
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
- }));
114
+ async function imageGenerationsV2(input, options = {}) {
115
+ const response = await callRemoteApi(input, { endpoint: 'api/v2/image/generations' }, 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, { useAIKitService, ...options } = {}) {
87
- const response = await (0, api_1.catchAndRethrowUpstreamError)(useAIKitService
88
- ? api_1.aiKitApi.post('/api/v2/embeddings', input, {
89
- responseType: options.responseType,
90
- headers: { ...(0, auth_1.getRemoteComponentCallHeaders)(input, options.userDid) },
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, { endpoint: 'api/v2/embeddings' }, options);
122
+ if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream') {
99
123
  return response;
124
+ }
125
+ return response.data;
126
+ }
127
+ async function getUserCreditInfo() {
128
+ const response = await callRemoteApi({}, { endpoint: 'api/user/info', method: 'GET' });
100
129
  return response.data;
101
130
  }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,12 +8,13 @@ const error_1 = require("@blocklet/error");
8
8
  const axios_1 = __importDefault(require("axios"));
9
9
  const ufo_1 = require("ufo");
10
10
  const util_1 = require("./utils/util");
11
- async function getUserInfo({ baseUrl, accessKey, }) {
11
+ async function getUserInfo({ baseUrl = '', accessKey = '', }) {
12
12
  let finalBaseUrl = (0, util_1.getPrefix)();
13
+ const windowExist = typeof window !== 'undefined';
13
14
  try {
14
15
  if (baseUrl) {
15
16
  const tmp = new URL(baseUrl);
16
- if (tmp.origin !== window.location.origin) {
17
+ if (!windowExist || (windowExist && tmp.origin !== window.location.origin)) {
17
18
  finalBaseUrl = await (0, util_1.getRemoteBaseUrl)(baseUrl);
18
19
  }
19
20
  }
@@ -22,6 +23,9 @@ async function getUserInfo({ baseUrl, accessKey, }) {
22
23
  console.warn('Failed to parse baseUrl:', err);
23
24
  throw new Error(`Failed to parse baseUrl: ${(0, error_1.formatError)(err)}`);
24
25
  }
26
+ if (!finalBaseUrl || !accessKey) {
27
+ throw new Error('baseUrl or accessKey is not set');
28
+ }
25
29
  return axios_1.default
26
30
  .get((0, ufo_1.joinURL)(finalBaseUrl, '/api/user/info'), {
27
31
  headers: {
@@ -9,7 +9,7 @@ const ufo_1 = require("ufo");
9
9
  const AIGNE_HUB_DID = 'z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ';
10
10
  const getRemoteBaseUrl = async (url) => {
11
11
  const tmp = new URL(url);
12
- if (tmp.origin === window.location.origin) {
12
+ if (typeof window !== 'undefined' && tmp.origin === window.location.origin) {
13
13
  return (0, exports.getPrefix)();
14
14
  }
15
15
  const scriptUrl = (0, ufo_1.joinURL)(tmp.origin, '__blocklet__.js?type=json');
@@ -24,6 +24,9 @@ const getRemoteBaseUrl = async (url) => {
24
24
  exports.getRemoteBaseUrl = getRemoteBaseUrl;
25
25
  const getPrefix = () => {
26
26
  var _a, _b, _c, _d;
27
+ if (typeof window === 'undefined') {
28
+ return '';
29
+ }
27
30
  const prefix = ((_a = window.blocklet) === null || _a === void 0 ? void 0 : _a.prefix) || '/';
28
31
  const baseUrl = (_b = window.location) === null || _b === void 0 ? void 0 : _b.origin; // required when use payment feature cross origin
29
32
  const componentId = (((_c = window.blocklet) === null || _c === void 0 ? void 0 : _c.componentId) || '').split('/').pop();
@@ -1,29 +1,73 @@
1
1
  import { ReadableStream, TextDecoderStream } from 'stream/web';
2
- import { call } from '@blocklet/sdk/lib/component';
3
- import stringify from 'json-stable-stringify';
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 { aiKitApi, catchAndRethrowUpstreamError } from './api';
8
- export async function chatCompletionsV2(input, { useAIKitService, ...options } = {}) {
9
- const response = catchAndRethrowUpstreamError(useAIKitService
10
- ? aiKitApi('/api/v2/chat/completions', {
11
- responseType: 'stream',
12
- method: 'POST',
13
- data: stringify(input),
14
- headers: {
15
- ...getRemoteComponentCallHeaders(input, options.userDid),
16
- Accept: 'text/event-stream',
17
- 'Content-Type': 'application/json',
18
- },
19
- })
20
- : call({
21
- name: 'ai-kit',
22
- path: 'api/v2/chat/completions',
23
- data: input,
24
- responseType: 'stream',
25
- headers: { Accept: 'text/event-stream' },
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
+ responseType: options === null || options === void 0 ? void 0 : options.responseType,
56
+ };
57
+ if (method === 'GET') {
58
+ requestConfig.params = input;
59
+ }
60
+ else {
61
+ requestConfig.data = input;
62
+ }
63
+ return catchAndRethrowUpstreamError(axios.request(requestConfig));
64
+ }
65
+ export async function chatCompletionsV2(input, options = {}) {
66
+ const params = {
67
+ endpoint: 'api/v2/chat/completions',
68
+ isStreamEndpoint: true,
69
+ };
70
+ const response = await callRemoteApi(input, params, { ...options, responseType: 'stream' });
27
71
  if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream')
28
72
  return response;
29
73
  return new ReadableStream({
@@ -57,37 +101,20 @@ export async function chatCompletionsV2(input, { useAIKitService, ...options } =
57
101
  },
58
102
  });
59
103
  }
60
- export async function imageGenerationsV2(input, { useAIKitService, ...options } = {}) {
61
- const response = await catchAndRethrowUpstreamError(useAIKitService
62
- ? aiKitApi.post('/api/v2/image/generations', input, {
63
- responseType: options.responseType,
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
- }));
104
+ export async function imageGenerationsV2(input, options = {}) {
105
+ const response = await callRemoteApi(input, { endpoint: 'api/v2/image/generations' }, 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, { useAIKitService, ...options } = {}) {
79
- const response = await catchAndRethrowUpstreamError(useAIKitService
80
- ? aiKitApi.post('/api/v2/embeddings', input, {
81
- responseType: options.responseType,
82
- headers: { ...getRemoteComponentCallHeaders(input, options.userDid) },
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, { endpoint: 'api/v2/embeddings' }, options);
112
+ if ((options === null || options === void 0 ? void 0 : options.responseType) === 'stream') {
91
113
  return response;
114
+ }
115
+ return response.data;
116
+ }
117
+ export async function getUserCreditInfo() {
118
+ const response = await callRemoteApi({}, { endpoint: 'api/user/info', method: 'GET' });
92
119
  return response.data;
93
120
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -2,12 +2,13 @@ import { formatError } from '@blocklet/error';
2
2
  import axios from 'axios';
3
3
  import { joinURL } from 'ufo';
4
4
  import { getPrefix, getRemoteBaseUrl } from './utils/util';
5
- export async function getUserInfo({ baseUrl, accessKey, }) {
5
+ export async function getUserInfo({ baseUrl = '', accessKey = '', }) {
6
6
  let finalBaseUrl = getPrefix();
7
+ const windowExist = typeof window !== 'undefined';
7
8
  try {
8
9
  if (baseUrl) {
9
10
  const tmp = new URL(baseUrl);
10
- if (tmp.origin !== window.location.origin) {
11
+ if (!windowExist || (windowExist && tmp.origin !== window.location.origin)) {
11
12
  finalBaseUrl = await getRemoteBaseUrl(baseUrl);
12
13
  }
13
14
  }
@@ -16,6 +17,9 @@ export async function getUserInfo({ baseUrl, accessKey, }) {
16
17
  console.warn('Failed to parse baseUrl:', err);
17
18
  throw new Error(`Failed to parse baseUrl: ${formatError(err)}`);
18
19
  }
20
+ if (!finalBaseUrl || !accessKey) {
21
+ throw new Error('baseUrl or accessKey is not set');
22
+ }
19
23
  return axios
20
24
  .get(joinURL(finalBaseUrl, '/api/user/info'), {
21
25
  headers: {
@@ -3,7 +3,7 @@ import { joinURL } from 'ufo';
3
3
  const AIGNE_HUB_DID = 'z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ';
4
4
  export const getRemoteBaseUrl = async (url) => {
5
5
  const tmp = new URL(url);
6
- if (tmp.origin === window.location.origin) {
6
+ if (typeof window !== 'undefined' && tmp.origin === window.location.origin) {
7
7
  return getPrefix();
8
8
  }
9
9
  const scriptUrl = joinURL(tmp.origin, '__blocklet__.js?type=json');
@@ -17,6 +17,9 @@ export const getRemoteBaseUrl = async (url) => {
17
17
  };
18
18
  export const getPrefix = () => {
19
19
  var _a, _b, _c, _d;
20
+ if (typeof window === 'undefined') {
21
+ return '';
22
+ }
20
23
  const prefix = ((_a = window.blocklet) === null || _a === void 0 ? void 0 : _a.prefix) || '/';
21
24
  const baseUrl = (_b = window.location) === null || _b === void 0 ? void 0 : _b.origin; // required when use payment feature cross origin
22
25
  const componentId = (((_c = window.blocklet) === null || _c === void 0 ? void 0 : _c.componentId) || '').split('/').pop();
@@ -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
+ }
@@ -1,18 +1,4 @@
1
- import { 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
- }
1
+ import { UserInfoResult } from './types/user';
16
2
  export declare function getUserInfo({ baseUrl, accessKey, }: {
17
3
  baseUrl: string;
18
4
  accessKey: string;
@@ -1,4 +1,4 @@
1
- import { UserInfoResult } from '../api/user';
1
+ import { UserInfoResult } from '../api/types/user';
2
2
  interface UserCreditCardProps {
3
3
  baseUrl: string;
4
4
  accessKey: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/aigne-hub",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "The react.js component library for AIGNE Hub",
5
5
  "publishConfig": {
6
6
  "access": "public"