From b5460712e640d2b1673569bbdefd722e9cdddc1a Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Tue, 2 Jan 2024 19:06:07 +0100 Subject: [PATCH] feat: Implement Helix app with new chat action --- .../backend/src/apps/helix/actions/index.ts | 3 ++ .../src/apps/helix/actions/new-chat/index.ts | 50 +++++++++++++++++++ .../backend/src/apps/helix/assets/favicon.svg | 6 +++ packages/backend/src/apps/helix/auth/index.ts | 45 +++++++++++++++++ .../src/apps/helix/auth/is-still-verified.ts | 9 ++++ .../src/apps/helix/auth/verify-credentials.ts | 11 ++++ .../src/apps/helix/common/add-auth-header.ts | 12 +++++ .../src/apps/helix/common/set-base-url.ts | 13 +++++ packages/backend/src/apps/helix/index.d.ts | 0 packages/backend/src/apps/helix/index.ts | 19 +++++++ 10 files changed, 168 insertions(+) create mode 100644 packages/backend/src/apps/helix/actions/index.ts create mode 100644 packages/backend/src/apps/helix/actions/new-chat/index.ts create mode 100644 packages/backend/src/apps/helix/assets/favicon.svg create mode 100644 packages/backend/src/apps/helix/auth/index.ts create mode 100644 packages/backend/src/apps/helix/auth/is-still-verified.ts create mode 100644 packages/backend/src/apps/helix/auth/verify-credentials.ts create mode 100644 packages/backend/src/apps/helix/common/add-auth-header.ts create mode 100644 packages/backend/src/apps/helix/common/set-base-url.ts create mode 100644 packages/backend/src/apps/helix/index.d.ts create mode 100644 packages/backend/src/apps/helix/index.ts diff --git a/packages/backend/src/apps/helix/actions/index.ts b/packages/backend/src/apps/helix/actions/index.ts new file mode 100644 index 00000000..92ff1f82 --- /dev/null +++ b/packages/backend/src/apps/helix/actions/index.ts @@ -0,0 +1,3 @@ +import newChat from './new-chat'; + +export default [newChat]; diff --git a/packages/backend/src/apps/helix/actions/new-chat/index.ts b/packages/backend/src/apps/helix/actions/new-chat/index.ts new file mode 100644 index 00000000..b33b2325 --- /dev/null +++ b/packages/backend/src/apps/helix/actions/new-chat/index.ts @@ -0,0 +1,50 @@ +import FormData from 'form-data'; +import defineAction from '../../../../helpers/define-action'; + +export default defineAction({ + name: 'New chat', + key: 'newChat', + description: 'Create a new chat session for Helix AI.', + arguments: [ + { + label: 'Input', + key: 'input', + type: 'string' as const, + required: true, + description: 'Prompt to start the chat with.', + variables: true, + }, + ], + + async run($) { + const formData = new FormData(); + formData.append('input', $.step.parameters.input as string); + formData.append('mode', 'inference'); + formData.append('type', 'text'); + + const sessionResponse = await $.http.post('/api/v1/sessions', formData, { + headers: { + ...formData.getHeaders(), + }, + }); + + const sessionId = sessionResponse.data.id; + + let chatGenerated = false; + + while (!chatGenerated) { + const response = await $.http.get(`/api/v1/sessions/${sessionId}`); + + const message = + response.data.interactions[response.data.interactions.length - 1]; + + if (message.creator === 'system' && message.state === 'complete') { + $.setActionItem({ + raw: message, + }); + + chatGenerated = true; + } + } + }, +}); diff --git a/packages/backend/src/apps/helix/assets/favicon.svg b/packages/backend/src/apps/helix/assets/favicon.svg new file mode 100644 index 00000000..e5e0b0b3 --- /dev/null +++ b/packages/backend/src/apps/helix/assets/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/backend/src/apps/helix/auth/index.ts b/packages/backend/src/apps/helix/auth/index.ts new file mode 100644 index 00000000..bfc045b4 --- /dev/null +++ b/packages/backend/src/apps/helix/auth/index.ts @@ -0,0 +1,45 @@ +import verifyCredentials from './verify-credentials'; +import isStillVerified from './is-still-verified'; + +export default { + fields: [ + { + key: 'screenName', + label: 'Screen Name', + type: 'string' as const, + required: true, + readOnly: false, + value: null, + placeholder: null, + description: + 'Screen name of your connection to be used on Automatisch UI.', + clickToCopy: false, + }, + { + key: 'instanceUrl', + label: 'Helix instance URL', + type: 'string' as const, + required: false, + readOnly: false, + value: 'https://app.tryhelix.ai', + placeholder: 'https://app.tryhelix.ai', + description: + 'Your Helix instance URL. Default is https://app.tryhelix.ai.', + clickToCopy: true, + }, + { + key: 'apiKey', + label: 'API Key', + type: 'string' as const, + required: true, + readOnly: false, + value: null, + placeholder: null, + description: 'Helix API Key of your account.', + clickToCopy: false, + }, + ], + + verifyCredentials, + isStillVerified, +}; diff --git a/packages/backend/src/apps/helix/auth/is-still-verified.ts b/packages/backend/src/apps/helix/auth/is-still-verified.ts new file mode 100644 index 00000000..66bb963e --- /dev/null +++ b/packages/backend/src/apps/helix/auth/is-still-verified.ts @@ -0,0 +1,9 @@ +import { IGlobalVariable } from '@automatisch/types'; +import verifyCredentials from './verify-credentials'; + +const isStillVerified = async ($: IGlobalVariable) => { + await verifyCredentials($); + return true; +}; + +export default isStillVerified; diff --git a/packages/backend/src/apps/helix/auth/verify-credentials.ts b/packages/backend/src/apps/helix/auth/verify-credentials.ts new file mode 100644 index 00000000..63c122ef --- /dev/null +++ b/packages/backend/src/apps/helix/auth/verify-credentials.ts @@ -0,0 +1,11 @@ +import { IGlobalVariable } from '@automatisch/types'; + +const verifyCredentials = async ($: IGlobalVariable) => { + await $.http.get('/api/v1/sessions'); + + await $.auth.set({ + screenName: $.auth.data.screenName, + }); +}; + +export default verifyCredentials; diff --git a/packages/backend/src/apps/helix/common/add-auth-header.ts b/packages/backend/src/apps/helix/common/add-auth-header.ts new file mode 100644 index 00000000..f4d16fd4 --- /dev/null +++ b/packages/backend/src/apps/helix/common/add-auth-header.ts @@ -0,0 +1,12 @@ +import { TBeforeRequest } from '@automatisch/types'; + +const addAuthHeader: TBeforeRequest = ($, requestConfig) => { + if ($.auth.data?.apiKey) { + const authorizationHeader = `Bearer ${$.auth.data.apiKey}`; + requestConfig.headers.Authorization = authorizationHeader; + } + + return requestConfig; +}; + +export default addAuthHeader; diff --git a/packages/backend/src/apps/helix/common/set-base-url.ts b/packages/backend/src/apps/helix/common/set-base-url.ts new file mode 100644 index 00000000..8aef4b23 --- /dev/null +++ b/packages/backend/src/apps/helix/common/set-base-url.ts @@ -0,0 +1,13 @@ +import { TBeforeRequest } from '@automatisch/types'; + +const setBaseUrl: TBeforeRequest = ($, requestConfig) => { + if ($.auth.data.instanceUrl) { + requestConfig.baseURL = $.auth.data.instanceUrl as string; + } else if ($.app.apiBaseUrl) { + requestConfig.baseURL = $.app.apiBaseUrl as string; + } + + return requestConfig; +}; + +export default setBaseUrl; diff --git a/packages/backend/src/apps/helix/index.d.ts b/packages/backend/src/apps/helix/index.d.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/backend/src/apps/helix/index.ts b/packages/backend/src/apps/helix/index.ts new file mode 100644 index 00000000..727cc56a --- /dev/null +++ b/packages/backend/src/apps/helix/index.ts @@ -0,0 +1,19 @@ +import defineApp from '../../helpers/define-app'; +import setBaseUrl from './common/set-base-url'; +import addAuthHeader from './common/add-auth-header'; +import auth from './auth'; +import actions from './actions'; + +export default defineApp({ + name: 'Helix', + key: 'helix', + baseUrl: 'https://tryhelix.ai', + apiBaseUrl: 'https://app.tryhelix.ai', + iconUrl: '{BASE_URL}/apps/helix/assets/favicon.svg', + authDocUrl: 'https://automatisch.io/docs/apps/helix/connection', + primaryColor: '000000', + supportsConnections: true, + beforeRequest: [setBaseUrl, addAuthHeader], + auth, + actions, +});