Initial commit

This commit is contained in:
John Wang
2023-05-15 08:51:32 +08:00
commit db896255d6
744 changed files with 56028 additions and 0 deletions

96
web/service/apps.ts Normal file
View File

@@ -0,0 +1,96 @@
import type { Fetcher } from 'swr'
import { del, get, post } from './base'
import type { ApikeysListResponse, AppDailyConversationsResponse, AppDailyEndUsersResponse, AppDetailResponse, AppListResponse, AppTemplatesResponse, AppTokenCostsResponse, CreateApiKeyResponse, GenerationIntroductionResponse, UpdateAppModelConfigResponse, UpdateAppNameResponse, UpdateAppSiteCodeResponse, UpdateOpenAIKeyResponse, ValidateOpenAIKeyResponse } from '@/models/app'
import type { CommonResponse } from '@/models/common'
import type { AppMode, ModelConfig } from '@/types/app'
export const fetchAppList: Fetcher<AppListResponse, { params?: Record<string, any> }> = ({ params }) => {
return get('apps', params) as Promise<AppListResponse>
}
export const fetchAppDetail: Fetcher<AppDetailResponse, { url: string; id: string }> = ({ url, id }) => {
return get(`${url}/${id}`) as Promise<AppDetailResponse>
}
export const fetchAppTemplates: Fetcher<AppTemplatesResponse, { url: string }> = ({ url }) => {
return get(url) as Promise<AppTemplatesResponse>
}
export const createApp: Fetcher<AppDetailResponse, { name: string; mode: AppMode; config?: ModelConfig }> = ({ name, mode, config }) => {
return post('apps', { body: { name, mode, model_config: config } }) as Promise<AppDetailResponse>
}
export const deleteApp: Fetcher<CommonResponse, string> = (appID) => {
return del(`apps/${appID}`) as Promise<CommonResponse>
}
// path: /apps/{appId}/name
export const updateAppName: Fetcher<UpdateAppNameResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<UpdateAppNameResponse>
}
export const updateAppSiteStatus: Fetcher<AppDetailResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<AppDetailResponse>
}
export const updateAppApiStatus: Fetcher<AppDetailResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<AppDetailResponse>
}
// path: /apps/{appId}/rate-limit
export const updateAppRateLimit: Fetcher<AppDetailResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<AppDetailResponse>
}
export const updateAppSiteAccessToken: Fetcher<UpdateAppSiteCodeResponse, { url: string }> = ({ url }) => {
return post(url) as Promise<UpdateAppSiteCodeResponse>
}
export const updateAppSiteConfig: Fetcher<AppDetailResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<AppDetailResponse>
}
export const getAppDailyConversations: Fetcher<AppDailyConversationsResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<AppDailyConversationsResponse>
}
export const getAppDailyEndUsers: Fetcher<AppDailyEndUsersResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<AppDailyEndUsersResponse>
}
export const getAppTokenCosts: Fetcher<AppTokenCostsResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<AppTokenCostsResponse>
}
export const updateAppModelConfig: Fetcher<UpdateAppModelConfigResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<UpdateAppModelConfigResponse>
}
// For temp testing
export const fetchAppListNoMock: Fetcher<AppListResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, params) as Promise<AppListResponse>
}
export const fetchApiKeysList: Fetcher<ApikeysListResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, params) as Promise<ApikeysListResponse>
}
export const delApikey: Fetcher<CommonResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return del(url, params) as Promise<CommonResponse>
}
export const createApikey: Fetcher<CreateApiKeyResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, body) as Promise<CreateApiKeyResponse>
}
export const validateOpenAIKey: Fetcher<ValidateOpenAIKeyResponse, { url: string; body: { token: string } }> = ({ url, body }) => {
return post(url, { body }) as Promise<ValidateOpenAIKeyResponse>
}
export const updateOpenAIKey: Fetcher<UpdateOpenAIKeyResponse, { url: string; body: { token: string } }> = ({ url, body }) => {
return post(url, { body }) as Promise<UpdateOpenAIKeyResponse>
}
export const generationIntroduction: Fetcher<GenerationIntroductionResponse, { url: string; body: { prompt_template: string } }> = ({ url, body }) => {
return post(url, { body }) as Promise<GenerationIntroductionResponse>
}

353
web/service/base.ts Normal file
View File

@@ -0,0 +1,353 @@
import { API_PREFIX, MOCK_API_PREFIX, PUBLIC_API_PREFIX, IS_CE_EDITION } from '@/config'
import Toast from '@/app/components/base/toast'
const TIME_OUT = 100000
const ContentType = {
json: 'application/json',
stream: 'text/event-stream',
form: 'application/x-www-form-urlencoded; charset=UTF-8',
download: 'application/octet-stream', // for download
upload: 'multipart/form-data', // for upload
}
const baseOptions = {
method: 'GET',
mode: 'cors',
credentials: 'include', // always send cookies、HTTP Basic authentication.
headers: new Headers({
'Content-Type': ContentType.json,
}),
redirect: 'follow',
}
export type IOnDataMoreInfo = {
conversationId: string | undefined
messageId: string
errorMessage?: string
}
export type IOnData = (message: string, isFirstMessage: boolean, moreInfo: IOnDataMoreInfo) => void
export type IOnCompleted = (hasError?: boolean) => void
export type IOnError = (msg: string) => void
type IOtherOptions = {
isPublicAPI?: boolean
isMock?: boolean
needAllResponseContent?: boolean
onData?: IOnData // for stream
onError?: IOnError
onCompleted?: IOnCompleted // for stream
getAbortController?: (abortController: AbortController) => void
}
function unicodeToChar(text: string) {
return text.replace(/\\u[0-9a-f]{4}/g, (_match, p1) => {
return String.fromCharCode(parseInt(p1, 16))
})
}
export function format(text: string) {
let res = text.trim()
if (res.startsWith('\n')) {
res = res.replace('\n', '')
}
return res.replaceAll('\n', '<br/>').replaceAll('```', '')
}
const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted) => {
if (!response.ok)
throw new Error('Network response was not ok')
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
let buffer = ''
let bufferObj: any
let isFirstMessage = true
function read() {
let hasError = false
reader.read().then((result: any) => {
if (result.done) {
onCompleted && onCompleted()
return
}
buffer += decoder.decode(result.value, { stream: true })
const lines = buffer.split('\n')
try {
lines.forEach((message) => {
if (message.startsWith('data: ')) { // check if it starts with data:
// console.log(message);
bufferObj = JSON.parse(message.substring(6)) // remove data: and parse as json
if (bufferObj.status === 400) {
onData('', false, {
conversationId: undefined,
messageId: '',
errorMessage: bufferObj.message
})
hasError = true
onCompleted && onCompleted(true)
return
}
// can not use format here. Because message is splited.
onData(unicodeToChar(bufferObj.answer), isFirstMessage, {
conversationId: bufferObj.conversation_id,
messageId: bufferObj.id,
})
isFirstMessage = false
}
})
buffer = lines[lines.length - 1]
} catch (e) {
onData('', false, {
conversationId: undefined,
messageId: '',
errorMessage: e + ''
})
hasError = true
onCompleted && onCompleted(true)
return
}
if (!hasError) {
read()
}
})
}
read()
}
const baseFetch = (url: string, fetchOptions: any, { isPublicAPI = false, isMock = false, needAllResponseContent }: IOtherOptions) => {
const options = Object.assign({}, baseOptions, fetchOptions)
if (isPublicAPI) {
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
options.headers.set('Authorization', `bearer ${sharedToken}`)
}
let urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
if (isMock)
urlPrefix = MOCK_API_PREFIX
let urlWithPrefix = `${urlPrefix}${url.startsWith('/') ? url : `/${url}`}`
const { method, params, body } = options
// handle query
if (method === 'GET' && params) {
const paramsArray: string[] = []
Object.keys(params).forEach(key =>
paramsArray.push(`${key}=${encodeURIComponent(params[key])}`),
)
if (urlWithPrefix.search(/\?/) === -1)
urlWithPrefix += `?${paramsArray.join('&')}`
else
urlWithPrefix += `&${paramsArray.join('&')}`
delete options.params
}
if (body)
options.body = JSON.stringify(body)
// Handle timeout
return Promise.race([
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('request timeout'))
}, TIME_OUT)
}),
new Promise((resolve, reject) => {
globalThis.fetch(urlWithPrefix, options)
.then((res: any) => {
const resClone = res.clone()
// Error handler
if (!/^(2|3)\d{2}$/.test(res.status)) {
const bodyJson = res.json()
switch (res.status) {
case 401: {
if (isPublicAPI) {
Toast.notify({ type: 'error', message: 'Invalid token' })
return
}
const loginUrl = `${globalThis.location.origin}/signin`
if (IS_CE_EDITION) {
bodyJson.then((data: any) => {
if (data.code === 'not_setup') {
globalThis.location.href = `${globalThis.location.origin}/install`
} else {
if (location.pathname === '/signin') {
bodyJson.then((data: any) => {
Toast.notify({ type: 'error', message: data.message })
})
} else {
globalThis.location.href = loginUrl
}
}
})
return Promise.reject()
}
globalThis.location.href = loginUrl
break
}
case 403:
new Promise(() => {
bodyJson.then((data: any) => {
Toast.notify({ type: 'error', message: data.message })
if (data.code === 'already_setup') {
globalThis.location.href = `${globalThis.location.origin}/signin`
}
})
})
break
// fall through
default:
// eslint-disable-next-line no-new
new Promise(() => {
bodyJson.then((data: any) => {
Toast.notify({ type: 'error', message: data.message })
})
})
}
return Promise.reject(resClone)
}
// handle delete api. Delete api not return content.
if (res.status === 204) {
resolve({ result: "success" })
return
}
// return data
const data = options.headers.get('Content-type') === ContentType.download ? res.blob() : res.json()
resolve(needAllResponseContent ? resClone : data)
})
.catch((err) => {
Toast.notify({ type: 'error', message: err })
reject(err)
})
}),
])
}
export const upload = (options: any): Promise<any> => {
const defaultOptions = {
method: 'POST',
url: `${API_PREFIX}/files/upload`,
headers: {},
data: {},
}
options = {
...defaultOptions,
...options,
headers: { ...defaultOptions.headers, ...options.headers },
};
return new Promise(function (resolve, reject) {
const xhr = options.xhr
xhr.open(options.method, options.url);
for (const key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
xhr.withCredentials = true
xhr.responseType = 'json'
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 201) {
resolve(xhr.response)
} else {
reject(xhr)
}
}
}
xhr.upload.onprogress = options.onprogress
xhr.send(options.data)
})
}
export const ssePost = (url: string, fetchOptions: any, { isPublicAPI = false, onData, onCompleted, onError, getAbortController }: IOtherOptions) => {
const abortController = new AbortController()
const options = Object.assign({}, baseOptions, {
method: 'POST',
signal: abortController.signal,
}, fetchOptions)
getAbortController?.(abortController)
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
const urlWithPrefix = `${urlPrefix}${url.startsWith('/') ? url : `/${url}`}`
const { body } = options
if (body)
options.body = JSON.stringify(body)
globalThis.fetch(urlWithPrefix, options)
.then((res: any) => {
// debugger
if (!/^(2|3)\d{2}$/.test(res.status)) {
// eslint-disable-next-line no-new
new Promise(() => {
res.json().then((data: any) => {
Toast.notify({ type: 'error', message: data.message || 'Server Error' })
})
})
onError?.('Server Error')
return
}
return handleStream(res, (str: string, isFirstMessage: boolean, moreInfo: IOnDataMoreInfo) => {
if (moreInfo.errorMessage) {
Toast.notify({ type: 'error', message: moreInfo.errorMessage })
return
}
onData?.(str, isFirstMessage, moreInfo)
}, onCompleted)
}).catch((e) => {
// debugger
Toast.notify({ type: 'error', message: e })
onError?.(e)
})
}
export const request = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return baseFetch(url, options, otherOptions || {})
}
export const get = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return request(url, Object.assign({}, options, { method: 'GET' }), otherOptions)
}
// For public API
export const getPublic = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return get(url, options, { ...otherOptions, isPublicAPI: true })
}
export const post = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return request(url, Object.assign({}, options, { method: 'POST' }), otherOptions)
}
export const postPublic = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return post(url, options, { ...otherOptions, isPublicAPI: true })
}
export const put = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return request(url, Object.assign({}, options, { method: 'PUT' }), otherOptions)
}
export const putPublic = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return put(url, options, { ...otherOptions, isPublicAPI: true })
}
export const del = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return request(url, Object.assign({}, options, { method: 'DELETE' }), otherOptions)
}
export const delPublic = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return del(url, options, { ...otherOptions, isPublicAPI: true })
}
export const patch = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return request(url, Object.assign({}, options, { method: 'PATCH' }), otherOptions)
}
export const patchPublic = (url: string, options = {}, otherOptions?: IOtherOptions) => {
return patch(url, options, { ...otherOptions, isPublicAPI: true })
}

91
web/service/common.ts Normal file
View File

@@ -0,0 +1,91 @@
import type { Fetcher } from 'swr'
import { get, post, del, put } from './base'
import type {
CommonResponse, LangGeniusVersionResponse, OauthResponse,
TenantInfoResponse, UserProfileOriginResponse, Member,
AccountIntegrate, Provider, ProviderAzureToken, IWorkspace
} from '@/models/common'
import type {
ValidateOpenAIKeyResponse,
UpdateOpenAIKeyResponse
} from '@/models/app'
export const login: Fetcher<CommonResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<CommonResponse>
}
export const setup: Fetcher<CommonResponse, { body: Record<string, any> }> = ({ body }) => {
return post('/setup', { body }) as Promise<CommonResponse>
}
export const fetchUserProfile: Fetcher<UserProfileOriginResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, params, { needAllResponseContent: true }) as Promise<UserProfileOriginResponse>
}
export const updateUserProfile: Fetcher<CommonResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<CommonResponse>
}
export const fetchTenantInfo: Fetcher<TenantInfoResponse, { url: string }> = ({ url }) => {
return get(url) as Promise<TenantInfoResponse>
}
export const logout: Fetcher<CommonResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, params) as Promise<CommonResponse>
}
export const fetchLanggeniusVersion: Fetcher<LangGeniusVersionResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<LangGeniusVersionResponse>
}
export const oauth: Fetcher<OauthResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<OauthResponse>
}
export const oneMoreStep: Fetcher<CommonResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<CommonResponse>
}
export const fetchMembers: Fetcher<{ accounts: Member[] | null }, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<{ accounts: Member[] | null }>
}
export const fetchProviders: Fetcher<Provider[] | null, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<Provider[] | null>
}
export const validateProviderKey: Fetcher<ValidateOpenAIKeyResponse, { url: string; body: { token: string } }> = ({ url, body }) => {
return post(url, { body }) as Promise<ValidateOpenAIKeyResponse>
}
export const updateProviderAIKey: Fetcher<UpdateOpenAIKeyResponse, { url: string; body: { token: string | ProviderAzureToken } }> = ({ url, body }) => {
return post(url, { body }) as Promise<UpdateOpenAIKeyResponse>
}
export const fetchAccountIntegrates: Fetcher<{ data: AccountIntegrate[] | null }, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<{ data: AccountIntegrate[] | null }>
}
export const inviteMember: Fetcher<CommonResponse & { account: Member }, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<CommonResponse & { account: Member }>
}
export const updateMemberRole: Fetcher<CommonResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return put(url, { body }) as Promise<CommonResponse>
}
export const deleteMemberOrCancelInvitation: Fetcher<CommonResponse, { url: string; }> = ({ url }) => {
return del(url) as Promise<CommonResponse>
}
export const fetchFilePreview: Fetcher<{ content: string }, { fileID: string }> = ({ fileID }) => {
return get(`/files/${fileID}/preview`) as Promise<{ content: string }>
}
export const fetchWorkspaces: Fetcher<{ workspaces: IWorkspace[] }, { url: string; params: Record<string, any> }> = ({ url, params }) => {
return get(url, { params }) as Promise<{ workspaces: IWorkspace[] }>
}
export const switchWorkspace: Fetcher<CommonResponse & { new_tenant: IWorkspace }, { url: string; body: Record<string, any> }> = ({ url, body }) => {
return post(url, { body }) as Promise<CommonResponse & { new_tenant: IWorkspace }>
}

127
web/service/datasets.ts Normal file
View File

@@ -0,0 +1,127 @@
import type { Fetcher } from 'swr'
import { del, get, post, put, patch } from './base'
import qs from 'qs'
import type { RelatedAppResponse, DataSet, HitTestingResponse, HitTestingRecordsResponse, DataSetListResponse, CreateDocumentReq, InitialDocumentDetail, DocumentDetailResponse, DocumentListResponse, IndexingEstimateResponse, FileIndexingEstimateResponse, IndexingStatusResponse, ProcessRuleResponse, SegmentsQuery, SegmentsResponse, createDocumentResponse } from '@/models/datasets'
import type { CommonResponse } from '@/models/common'
// apis for documents in a dataset
type CommonDocReq = {
datasetId: string
documentId: string
}
export type SortType = 'created_at' | 'hit_count' | '-created_at' | '-hit_count'
export type MetadataType = 'all' | 'only' | 'without'
export const fetchDataDetail: Fetcher<DataSet, string> = (datasetId: string) => {
return get(`/datasets/${datasetId}`) as Promise<DataSet>
}
export const updateDatasetSetting: Fetcher<DataSet, { datasetId: string, body: Partial<Pick<DataSet, 'name' | 'description' | 'permission' | 'indexing_technique'>>}> = ({ datasetId, body }) => {
return patch(`/datasets/${datasetId}`, { body } ) as Promise<DataSet>
}
export const fetchDatasetRelatedApps: Fetcher<RelatedAppResponse, string> = (datasetId: string) => {
return get(`/datasets/${datasetId}/related-apps`) as Promise<RelatedAppResponse>
}
export const fetchDatasets: Fetcher<DataSetListResponse, { url: string, params: { page: number, ids?: string[], limit?: number } }> = ({ url, params }) => {
const urlParams = qs.stringify(params, { indices: false })
return get(`${url}?${urlParams}`,) as Promise<DataSetListResponse>
}
export const createEmptyDataset: Fetcher<DataSet, { name: string }> = ({ name }) => {
return post('/datasets', { body: { name } }) as Promise<DataSet>
}
export const deleteDataset: Fetcher<DataSet, string> = (datasetID) => {
return del(`/datasets/${datasetID}`) as Promise<DataSet>
}
export const fetchDefaultProcessRule: Fetcher<ProcessRuleResponse, { url: string }> = ({ url }) => {
return get(url) as Promise<ProcessRuleResponse>
}
export const fetchProcessRule: Fetcher<ProcessRuleResponse, { params: { documentId: string } }> = ({ params: { documentId } }) => {
return get('/datasets/process-rule', { params: { document_id: documentId } }) as Promise<ProcessRuleResponse>
}
export const fetchDocuments: Fetcher<DocumentListResponse, { datasetId: string; params: { keyword: string; page: number; limit: number; sort?: SortType } }> = ({ datasetId, params }) => {
return get(`/datasets/${datasetId}/documents`, { params }) as Promise<DocumentListResponse>
}
export const createFirstDocument: Fetcher<createDocumentResponse, { body: CreateDocumentReq }> = ({ body }) => {
return post(`/datasets/init`, { body }) as Promise<createDocumentResponse>
}
export const createDocument: Fetcher<InitialDocumentDetail, { datasetId: string; body: CreateDocumentReq }> = ({ datasetId, body }) => {
return post(`/datasets/${datasetId}/documents`, { body }) as Promise<InitialDocumentDetail>
}
export const fetchIndexingEstimate: Fetcher<IndexingEstimateResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return get(`/datasets/${datasetId}/documents/${documentId}/indexing-estimate`, {}) as Promise<IndexingEstimateResponse>
}
export const fetchIndexingStatus: Fetcher<IndexingStatusResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return get(`/datasets/${datasetId}/documents/${documentId}/indexing-status`, {}) as Promise<IndexingStatusResponse>
}
export const fetchDocumentDetail: Fetcher<DocumentDetailResponse, CommonDocReq & { params: { metadata?: MetadataType } }> = ({ datasetId, documentId, params }) => {
return get(`/datasets/${datasetId}/documents/${documentId}`, { params }) as Promise<DocumentDetailResponse>
}
export const pauseDocIndexing: Fetcher<CommonResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return patch(`/datasets/${datasetId}/documents/${documentId}/processing/pause`) as Promise<CommonResponse>
}
export const resumeDocIndexing: Fetcher<CommonResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return patch(`/datasets/${datasetId}/documents/${documentId}/processing/resume`) as Promise<CommonResponse>
}
export const deleteDocument: Fetcher<CommonResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return del(`/datasets/${datasetId}/documents/${documentId}`) as Promise<CommonResponse>
}
export const archiveDocument: Fetcher<CommonResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return patch(`/datasets/${datasetId}/documents/${documentId}/status/archive`) as Promise<CommonResponse>
}
export const enableDocument: Fetcher<CommonResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return patch(`/datasets/${datasetId}/documents/${documentId}/status/enable`) as Promise<CommonResponse>
}
export const disableDocument: Fetcher<CommonResponse, CommonDocReq> = ({ datasetId, documentId }) => {
return patch(`/datasets/${datasetId}/documents/${documentId}/status/disable`) as Promise<CommonResponse>
}
export const modifyDocMetadata: Fetcher<CommonResponse, CommonDocReq & { body: { doc_type: string; doc_metadata: Record<string, any> } }> = ({ datasetId, documentId, body }) => {
return put(`/datasets/${datasetId}/documents/${documentId}/metadata`, { body }) as Promise<CommonResponse>
}
// apis for segments in a document
export const fetchSegments: Fetcher<SegmentsResponse, CommonDocReq & { params: SegmentsQuery }> = ({ datasetId, documentId, params }) => {
return get(`/datasets/${datasetId}/documents/${documentId}/segments`, { params }) as Promise<SegmentsResponse>
}
export const enableSegment: Fetcher<CommonResponse, { datasetId: string; segmentId: string }> = ({ datasetId, segmentId }) => {
return patch(`/datasets/${datasetId}/segments/${segmentId}/enable`) as Promise<CommonResponse>
}
export const disableSegment: Fetcher<CommonResponse, { datasetId: string; segmentId: string }> = ({ datasetId, segmentId }) => {
return patch(`/datasets/${datasetId}/segments/${segmentId}/disable`) as Promise<CommonResponse>
}
// hit testing
export const hitTesting: Fetcher<HitTestingResponse, { datasetId: string; queryText: string }> = ({ datasetId, queryText }) => {
return post(`/datasets/${datasetId}/hit-testing`, { body: { query: queryText } }) as Promise<HitTestingResponse>
}
export const fetchTestingRecords: Fetcher<HitTestingRecordsResponse, { datasetId: string; params: { page: number; limit: number } }> = ({ datasetId, params }) => {
return get(`/datasets/${datasetId}/queries`, { params }) as Promise<HitTestingRecordsResponse>
}
export const fetchFileIndexingEstimate: Fetcher<FileIndexingEstimateResponse, any> = (body: any) => {
return post(`/datasets/file-indexing-estimate`, { body }) as Promise<FileIndexingEstimateResponse>
}

40
web/service/debug.ts Normal file
View File

@@ -0,0 +1,40 @@
import { ssePost, get, IOnData, IOnCompleted, IOnError } from './base'
export const sendChatMessage = async (appId: string, body: Record<string, any>, { onData, onCompleted, onError, getAbortController }: {
onData: IOnData
onCompleted: IOnCompleted
onError: IOnError,
getAbortController?: (abortController: AbortController) => void
}) => {
return ssePost(`apps/${appId}/chat-messages`, {
body: {
...body,
response_mode: 'streaming'
}
}, { onData, onCompleted, onError, getAbortController })
}
export const sendCompletionMessage = async (appId: string, body: Record<string, any>, { onData, onCompleted, onError }: {
onData: IOnData
onCompleted: IOnCompleted
onError: IOnError
}) => {
return ssePost(`apps/${appId}/completion-messages`, {
body: {
...body,
response_mode: 'streaming'
}
}, { onData, onCompleted, onError })
}
export const fetchSuggestedQuestions = (appId: string, messageId: string) => {
return get(`apps/${appId}/chat-messages/${messageId}/suggested-questions`)
}
export const fetchConvesationMessages = (appId: string, conversation_id: string) => {
return get(`apps/${appId}/chat-messages`, {
params: {
conversation_id
}
})
}

106
web/service/demo/index.tsx Normal file
View File

@@ -0,0 +1,106 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import useSWR, { useSWRConfig } from 'swr'
import { createApp, fetchAppDetail, fetchAppList, getAppDailyConversations, getAppDailyEndUsers, updateAppApiStatus, updateAppModelConfig, updateAppName, updateAppRateLimit, updateAppSiteAccessToken, updateAppSiteConfig, updateAppSiteStatus } from '../apps'
import Loading from '@/app/components/base/loading'
const Service: FC = () => {
const { data: appList, error: appListError } = useSWR({ url: '/apps', params: { page: 1 } }, fetchAppList)
const { data: firstApp, error: appDetailError } = useSWR({ url: '/apps', id: '1' }, fetchAppDetail)
const { data: appName, error: appNameError } = useSWR({ url: '/apps', id: '1', body: { name: 'new name' } }, updateAppName)
const { data: updateAppSiteStatusRes, error: err1 } = useSWR({ url: '/apps', id: '1', body: { enable_site: false } }, updateAppSiteStatus)
const { data: updateAppApiStatusRes, error: err2 } = useSWR({ url: '/apps', id: '1', body: { enable_api: true } }, updateAppApiStatus)
const { data: updateAppRateLimitRes, error: err3 } = useSWR({ url: '/apps', id: '1', body: { api_rpm: 10, api_rph: 20 } }, updateAppRateLimit)
const { data: updateAppSiteCodeRes, error: err4 } = useSWR({ url: '/apps', id: '1', body: {} }, updateAppSiteAccessToken)
const { data: updateAppSiteConfigRes, error: err5 } = useSWR({ url: '/apps', id: '1', body: { title: 'title test', author: 'author test' } }, updateAppSiteConfig)
const { data: getAppDailyConversationsRes, error: err6 } = useSWR({ url: '/apps', id: '1', body: { start: '1', end: '2' } }, getAppDailyConversations)
const { data: getAppDailyEndUsersRes, error: err7 } = useSWR({ url: '/apps', id: '1', body: { start: '1', end: '2' } }, getAppDailyEndUsers)
const { data: updateAppModelConfigRes, error: err8 } = useSWR({ url: '/apps', id: '1', body: { model_id: 'gpt-100' } }, updateAppModelConfig)
const { mutate } = useSWRConfig()
const handleCreateApp = async () => {
await createApp({
name: `new app${Math.round(Math.random() * 100)}`,
mode: 'chat',
})
// reload app list
mutate({ url: '/apps', params: { page: 1 } })
}
if (appListError || appDetailError || appNameError || err1 || err2 || err3 || err4 || err5 || err6 || err7 || err8)
return <div>{JSON.stringify(appNameError)}</div>
if (!appList || !firstApp || !appName || !updateAppSiteStatusRes || !updateAppApiStatusRes || !updateAppRateLimitRes || !updateAppSiteCodeRes || !updateAppSiteConfigRes || !getAppDailyConversationsRes || !getAppDailyEndUsersRes || !updateAppModelConfigRes)
return <Loading />
return (
<div>
<div className='flex flex-col gap-3'>
<div>
<div>1.App list</div>
<div>
{appList.data.map(item => (
<div key={item.id}>{item.id} {item.name}</div>
))}
</div>
</div>
<div>
<div>2.First app detail</div>
<div>{JSON.stringify(firstApp)}</div>
</div>
<div>
<button onClick={handleCreateApp}>Click me to Create App</button>
</div>
<div>
<div>3.updateAppName</div>
<div>{JSON.stringify(appName)}</div>
</div>
<div>
<div>4.updateAppSiteStatusRes</div>
<div>{JSON.stringify(updateAppSiteStatusRes)}</div>
</div>
<div>
<div>5.updateAppApiStatusRes</div>
<div>{JSON.stringify(updateAppApiStatusRes)}</div>
</div>
<div>
<div>6.updateAppRateLimitRes</div>
<div>{JSON.stringify(updateAppRateLimitRes)}</div>
</div>
<div>
<div>7.updateAppSiteCodeRes</div>
<div>{JSON.stringify(updateAppSiteCodeRes)}</div>
</div>
<div>
<div>8.updateAppSiteConfigRes</div>
<div>{JSON.stringify(updateAppSiteConfigRes)}</div>
</div>
<div>
<div>9.getAppDailyConversationsRes</div>
<div>{JSON.stringify(getAppDailyConversationsRes)}</div>
</div>
<div>
<div>10.getAppDailyEndUsersRes</div>
<div>{JSON.stringify(getAppDailyEndUsersRes)}</div>
</div>
<div>
<div>11.updateAppModelConfigRes</div>
<div>{JSON.stringify(updateAppModelConfigRes)}</div>
</div>
</div>
</div>
)
}
export default React.memo(Service)

59
web/service/log.ts Normal file
View File

@@ -0,0 +1,59 @@
import type { Fetcher } from 'swr'
import { get, post } from './base'
import type {
AnnotationsCountResponse,
ChatConversationFullDetailResponse,
ChatConversationsRequest,
ChatConversationsResponse,
ChatMessagesRequest,
ChatMessagesResponse,
CompletionConversationFullDetailResponse,
CompletionConversationsRequest,
CompletionConversationsResponse,
ConversationListResponse,
LogMessageAnnotationsRequest,
LogMessageAnnotationsResponse,
LogMessageFeedbacksRequest,
LogMessageFeedbacksResponse,
} from '@/models/log'
export const fetchConversationList: Fetcher<ConversationListResponse, { name: string; appId: string; params?: Record<string, any> }> = ({ appId, params }) => {
return get(`/console/api/apps/${appId}/messages`, params) as Promise<ConversationListResponse>
}
// (Text Generation Application) Session List
export const fetchCompletionConversations: Fetcher<CompletionConversationsResponse, { url: string; params?: CompletionConversationsRequest }> = ({ url, params }) => {
return get(url, { params }) as Promise<CompletionConversationsResponse>
}
// (Text Generation Application) Session Detail
export const fetchCompletionConversationDetail: Fetcher<CompletionConversationFullDetailResponse, { url: string }> = ({ url }) => {
return get(url, {}) as Promise<CompletionConversationFullDetailResponse>
}
// (Chat Application) Session List
export const fetchChatConversations: Fetcher<ChatConversationsResponse, { url: string; params?: ChatConversationsRequest }> = ({ url, params }) => {
return get(url, { params }) as Promise<ChatConversationsResponse>
}
// (Chat Application) Session Detail
export const fetchChatConversationDetail: Fetcher<ChatConversationFullDetailResponse, { url: string }> = ({ url }) => {
return get(url, {}) as Promise<ChatConversationFullDetailResponse>
}
// (Chat Application) Message list in one session
export const fetchChatMessages: Fetcher<ChatMessagesResponse, { url: string; params: ChatMessagesRequest }> = ({ url, params }) => {
return get(url, { params }) as Promise<ChatMessagesResponse>
}
export const updateLogMessageFeedbacks: Fetcher<LogMessageFeedbacksResponse, { url: string; body: LogMessageFeedbacksRequest }> = ({ url, body }) => {
return post(url, { body }) as Promise<LogMessageFeedbacksResponse>
}
export const updateLogMessageAnnotations: Fetcher<LogMessageAnnotationsResponse, { url: string; body: LogMessageAnnotationsRequest }> = ({ url, body }) => {
return post(url, { body }) as Promise<LogMessageAnnotationsResponse>
}
export const fetchAnnotationsCount: Fetcher<AnnotationsCountResponse, { url: string }> = ({ url }) => {
return get(url) as Promise<AnnotationsCountResponse>
}

81
web/service/share.ts Normal file
View File

@@ -0,0 +1,81 @@
import type { IOnCompleted, IOnData, IOnError } from './base'
import { getPublic as get, postPublic as post, ssePost, delPublic as del } from './base'
import type { Feedbacktype } from '@/app/components/app/chat'
export const sendChatMessage = async (body: Record<string, any>, { onData, onCompleted, onError, getAbortController }: {
onData: IOnData
onCompleted: IOnCompleted
onError: IOnError,
getAbortController?: (abortController: AbortController) => void
}) => {
return ssePost('chat-messages', {
body: {
...body,
response_mode: 'streaming',
},
}, { onData, onCompleted, isPublicAPI: true, onError, getAbortController })
}
export const sendCompletionMessage = async (body: Record<string, any>, { onData, onCompleted, onError }: {
onData: IOnData
onCompleted: IOnCompleted
onError: IOnError
}) => {
return ssePost('completion-messages', {
body: {
...body,
response_mode: 'streaming',
},
}, { onData, onCompleted, isPublicAPI: true, onError })
}
export const fetchAppInfo = async () => {
return get('/site')
}
export const fetchConversations = async () => {
return get('conversations', { params: { limit: 20, first_id: '' } })
}
export const fetchChatList = async (conversationId: string) => {
return get('messages', { params: { conversation_id: conversationId, limit: 20, last_id: '' } })
}
// Abandoned API interface
// export const fetchAppVariables = async () => {
// return get(`variables`)
// }
// init value. wait for server update
export const fetchAppParams = async () => {
return get('parameters')
}
export const updateFeedback = async ({ url, body }: { url: string; body: Feedbacktype }) => {
return post(url, { body })
}
export const fetcMoreLikeThis = async (messageId: string) => {
return get(`/messages/${messageId}/more-like-this`, {
params: {
response_mode: 'blocking',
}
})
}
export const saveMessage = (messageId: string) => {
return post('/saved-messages', { body: { message_id: messageId } })
}
export const fetchSavedMessage = async () => {
return get(`/saved-messages`)
}
export const removeMessage = (messageId: string) => {
return del(`/saved-messages/${messageId}`)
}
export const fetchSuggestedQuestions = (messageId: string) => {
return get(`/messages/${messageId}/suggested-questions`)
}