Skip to content

Commit 2cb3d00

Browse files
authored
Merge pull request #84 from cheshire-cat-ai/api-service
add ApiService; fix bug on reconnection
2 parents 60f6d22 + 793ec31 commit 2cb3d00

21 files changed

+147
-123
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ jobs:
3131
uses: actions/setup-node@v4
3232
with:
3333
node-version: 18.x
34-
cache: "pnpm"
34+
cache: 'pnpm'
3535
- run: pnpm install --frozen-lockfile
3636
- name: 'TODO to Issue'
37-
uses: 'alstr/todo-to-issue-action@v4'
37+
uses: alstr/todo-to-issue-action@v4
3838
with:
3939
IDENTIFIERS: '[{"name": "FEATURE", "labels": ["enhancement"]}, {"name": "BUG", "labels": ["bug"]}]'
4040
ISSUE_TEMPLATE: '**Describe the reason of this issue**\n{{ body }}\n\nThe issue is present here:\n\n{{ snippet }}'

.github/workflows/develop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
uses: actions/setup-node@v4
3131
with:
3232
node-version: 18.x
33-
cache: "pnpm"
33+
cache: 'pnpm'
3434
- run: pnpm install --frozen-lockfile
3535
- name: Build static files
3636
run: pnpm run build

.github/workflows/playwright.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
uses: actions/setup-node@v4
3030
with:
3131
node-version: 18.x
32-
cache: "pnpm"
32+
cache: 'pnpm'
3333
- run: pnpm install --frozen-lockfile
3434
- name: Install Playwright Browsers
3535
run: pnpx playwright install --with-deps

.github/workflows/vitest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
uses: actions/setup-node@v4
3030
with:
3131
node-version: 18.x
32-
cache: "pnpm"
32+
cache: 'pnpm'
3333
- run: pnpm install --frozen-lockfile
3434
- name: Run Vitest tests
3535
run: pnpm run unit

pnpm-lock.yaml

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App.vue

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,4 @@
1-
<script setup lang="ts">
2-
import { createMongoAbility } from '@casl/ability'
3-
import { useSettings } from '@stores/useSettings'
4-
import { updateCredential } from './api'
5-
import { useAbility } from '@casl/vue'
6-
import LogService from '@services/LogService'
7-
8-
const { cookie, jwt } = storeToRefs(useSettings())
9-
const perms = useAbility()
10-
11-
onBeforeMount(() => {
12-
const payload = jwt.value
13-
updateCredential(cookie.value)
14-
perms.update(
15-
createMongoAbility(
16-
payload === null
17-
? []
18-
: Object.entries(payload.permissions).map(([subject, action]) => ({
19-
subject,
20-
action,
21-
})),
22-
).rules,
23-
)
24-
if (payload) LogService.success(`Authenticated as ${payload.username}`)
25-
})
26-
</script>
1+
<script setup lang="ts"></script>
272

283
<template>
294
<div

src/components/ThemeButton.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script setup lang="ts">
2-
import { useSettings } from '@stores/useSettings'
2+
import { useMainStore } from '@stores/useMainStore'
33
import githubLight from 'highlight.js/styles/github.css?raw'
44
import githubDark from 'highlight.js/styles/github-dark.css?raw'
55
6-
const store = useSettings()
6+
const store = useMainStore()
77
const { toggleDark } = store
88
const { isDark } = storeToRefs(store)
99

src/composables/perms.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { useAbility } from '@casl/vue'
2-
import type { AppAbility } from '@/api'
2+
import type { AppAbility } from '@services/ApiService'
33

44
export const usePerms = () => useAbility<AppAbility>()

src/api.ts renamed to src/services/ApiService.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,32 @@ const getPort = () => {
1212
}
1313

1414
/**
15-
* API client to make requests to the endpoints and passing the API_KEY for authentication.
15+
* API client to make requests to the endpoints and passing the JWT for authentication.
16+
* Start as null and is initialized by App.vue
1617
*/
17-
export const apiClient = new CatClient({
18-
baseUrl: window.location.hostname,
19-
port: getPort(),
20-
secure: window.location.protocol === 'https:',
21-
timeout: 15000,
22-
instant: false,
23-
ws: {
24-
retries: 3,
25-
delay: 3000,
26-
onFailed: () => {
27-
console.error('Failed to connect WebSocket after 3 retries.')
28-
},
29-
},
30-
})
18+
export let apiClient: CatClient | undefined = undefined
3119

32-
export const updateCredential = (cred: string | undefined) => (apiClient.credential = cred)
20+
/**
21+
* Function to instantiate the API client with the JWT token
22+
* @param credential The JWT token to pass to the API client
23+
*/
24+
export const instantiateApiClient = (credential: string | undefined) => {
25+
apiClient = new CatClient({
26+
baseUrl: window.location.hostname,
27+
port: getPort(),
28+
secure: window.location.protocol === 'https:',
29+
credential: credential,
30+
timeout: 15000,
31+
instant: true,
32+
ws: {
33+
retries: 5,
34+
delay: 2000,
35+
onFailed: () => {
36+
console.error('Failed to connect WebSocket after several retries.')
37+
},
38+
},
39+
})
40+
}
3341

3442
/**
3543
* A function that wraps the promise request into a try/catch block

src/services/EmbedderConfigService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { apiClient, tryRequest } from '@/api'
1+
import { apiClient, tryRequest } from '@services/ApiService'
22
import type { JSONSettings } from '@models/JSONSchema'
33

44
/*
@@ -7,14 +7,14 @@ import type { JSONSettings } from '@models/JSONSchema'
77
const EmbedderService = Object.freeze({
88
getEmbedders: async () => {
99
return await tryRequest(
10-
apiClient.api?.embedder.getEmbeddersSettings(),
10+
apiClient?.api?.embedder.getEmbeddersSettings(),
1111
'Getting all the available embedders',
1212
'Unable to get the list of available embedders',
1313
)
1414
},
1515
setEmbedderSettings: async (languageEmbedderName: string, settings: JSONSettings) => {
1616
return await tryRequest(
17-
apiClient.api?.embedder.upsertEmbedderSetting(languageEmbedderName, settings),
17+
apiClient?.api?.embedder.upsertEmbedderSetting(languageEmbedderName, settings),
1818
'Language model embedder updated successfully',
1919
"Language model embedder couldn't be updated",
2020
'Sending the embedder settings to the cat',

src/services/LLMConfigService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { apiClient, tryRequest } from '@/api'
1+
import { apiClient, tryRequest } from '@services/ApiService'
22
import type { JSONSettings } from '@models/JSONSchema'
33

44
/*
@@ -7,14 +7,14 @@ import type { JSONSettings } from '@models/JSONSchema'
77
const LLMService = Object.freeze({
88
getProviders: async () => {
99
return await tryRequest(
10-
apiClient.api?.llm.getLlmsSettings(),
10+
apiClient?.api?.llm.getLlmsSettings(),
1111
'Getting all the available providers',
1212
'Unable to get the list of available providers',
1313
)
1414
},
1515
setProviderSettings: async (languageModelName: string, settings: JSONSettings) => {
1616
return await tryRequest(
17-
apiClient.api?.llm.upsertLlmSetting(languageModelName, settings),
17+
apiClient?.api?.llm.upsertLlmSetting(languageModelName, settings),
1818
'Language model provider updated successfully',
1919
"Language model provider couldn't be updated",
2020
'Sending the language model settings to the cat',

src/services/MemoryService.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,55 @@
1-
import { apiClient, tryRequest } from '@/api'
1+
import { apiClient, tryRequest } from '@services/ApiService'
22

33
/*
44
* This is a service that is used to manage the memory of the Cheshire Cat.
55
*/
66
const MemoryService = Object.freeze({
77
getCollections: async () => {
88
return await tryRequest(
9-
apiClient.api?.memory.getCollections(),
9+
apiClient?.api?.memory.getCollections(),
1010
'Getting all the available collections',
1111
'Unable to fetch available collections',
1212
)
1313
},
1414
deleteMemoryPoint: async (collection: string, memory: string) => {
1515
return await tryRequest(
16-
apiClient.api?.memory.deletePointInMemory(collection, memory),
16+
apiClient?.api?.memory.deletePointInMemory(collection, memory),
1717
'The selected memory point was wiped successfully',
1818
'Unable to wipe the memory point',
1919
)
2020
},
2121
wipeAllCollections: async () => {
2222
return await tryRequest(
23-
apiClient.api?.memory.wipeCollections(),
23+
apiClient?.api?.memory.wipeCollections(),
2424
'All in-memory collections were wiped',
2525
'Unable to wipe the in-memory collections',
2626
)
2727
},
2828
wipeCollection: async (collectionId: string) => {
2929
return await tryRequest(
30-
apiClient.api?.memory.wipeSingleCollection(collectionId),
30+
apiClient?.api?.memory.wipeSingleCollection(collectionId),
3131
`The ${collectionId} collection was wiped`,
3232
`Unable to wipe the ${collectionId} collection`,
3333
)
3434
},
3535
wipeConversation: async () => {
3636
return await tryRequest(
37-
apiClient.api?.memory.wipeConversationHistory(),
37+
apiClient?.api?.memory.wipeConversationHistory(),
3838
'The current conversation was wiped',
3939
'Unable to wipe the in-memory current conversation',
4040
)
4141
},
4242
getConversation: async () => {
4343
const result = await tryRequest(
44-
apiClient.api?.memory.getConversationHistory(),
44+
apiClient?.api?.memory.getConversationHistory(),
4545
'Retrieved the conversation history',
4646
'Unable to retrieve the in-memory conversation history',
4747
)
4848
return result.data?.history ?? []
4949
},
5050
callMemory: async (query: string, memories = 10) => {
5151
const result = await tryRequest(
52-
apiClient.api?.memory.recallMemoriesFromText(query, memories),
52+
apiClient?.api?.memory.recallMemoriesFromText(query, memories),
5353
`Recalling ${memories} memories with ${query} as query`,
5454
'Unable to recall memory',
5555
`Recalling ${memories} memories from the cat with "${query}"`,

src/services/PluginService.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { apiClient, tryRequest } from '@/api'
1+
import { apiClient, tryRequest } from '@services/ApiService'
22
import type { JSONSettings } from '@models/JSONSchema'
33

44
/*
@@ -8,45 +8,45 @@ import type { JSONSettings } from '@models/JSONSchema'
88
const PluginService = Object.freeze({
99
installFromRegistry: async (url: string) => {
1010
return await tryRequest(
11-
apiClient.api?.plugins.installPluginFromRegistry({ url }),
11+
apiClient?.api?.plugins.installPluginFromRegistry({ url }),
1212
'Installing plugin from registry',
1313
'Unable to install the plugin from this url',
1414
)
1515
},
1616
getPlugins: async (query?: string) => {
1717
return await tryRequest(
18-
apiClient.api?.plugins.listAvailablePlugins(query),
18+
apiClient?.api?.plugins.listAvailablePlugins(query),
1919
query ? `Searching plugins with query: ${query}` : 'Getting all the available plugins',
2020
query ? `Unable to search plugins with query: ${query}` : 'Unable to fetch the plugins',
2121
)
2222
},
2323
getPluginsSettings: async () => {
24-
return await tryRequest(apiClient.api?.plugins.getPluginsSettings(), `Getting plugins settings`, `Unable to get plugins settings`)
24+
return await tryRequest(apiClient?.api?.plugins.getPluginsSettings(), `Getting plugins settings`, `Unable to get plugins settings`)
2525
},
2626
getSinglePluginSettings: async (id: string) => {
2727
const result = await tryRequest(
28-
apiClient.api?.plugins.getPluginSettings(id),
28+
apiClient?.api?.plugins.getPluginSettings(id),
2929
`Getting plugin ${id} settings`,
3030
`Unable to get plugin ${id} settings`,
3131
)
3232
return result.data
3333
},
3434
togglePlugin: async (id: string) => {
35-
return await tryRequest(apiClient.api?.plugins.togglePlugin(id), `Toggle plugin ${id}`, `Unable to toggle plugin ${id}`)
35+
return await tryRequest(apiClient?.api?.plugins.togglePlugin(id), `Toggle plugin ${id}`, `Unable to toggle plugin ${id}`)
3636
},
3737
updateSettings: async (id: string, settings: JSONSettings) => {
3838
return await tryRequest(
39-
apiClient.api?.plugins.upsertPluginSettings(id, settings),
39+
apiClient?.api?.plugins.upsertPluginSettings(id, settings),
4040
`Updated plugin ${id} settings`,
4141
`Unable to update plugin ${id} settings`,
4242
)
4343
},
4444
deletePlugin: async (id: string) => {
45-
return await tryRequest(apiClient.api?.plugins.deletePlugin(id), `Deleted plugin ${id}`, `Unable to delete plugin ${id}`)
45+
return await tryRequest(apiClient?.api?.plugins.deletePlugin(id), `Deleted plugin ${id}`, `Unable to delete plugin ${id}`)
4646
},
4747
sendFile: async (file: File) => {
4848
return await tryRequest(
49-
apiClient.api?.plugins.installPlugin({ file }),
49+
apiClient?.api?.plugins.installPlugin({ file }),
5050
`Plugin ${file.name} installed successfully!`,
5151
`Unable to install the plugin ${file.name}`,
5252
)

0 commit comments

Comments
 (0)