feat(mistral-ai): add app with create chat completion action
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
import defineAction from '../../../../helpers/define-action.js';
|
||||
|
||||
const castFloatOrUndefined = (value) => {
|
||||
return value === '' ? undefined : parseFloat(value);
|
||||
};
|
||||
|
||||
export default defineAction({
|
||||
name: 'Create chat completion',
|
||||
key: 'createChatCompletion',
|
||||
description: 'Creates a chat completion.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Model',
|
||||
key: 'model',
|
||||
type: 'dropdown',
|
||||
required: true,
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listModels',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Messages',
|
||||
key: 'messages',
|
||||
type: 'dynamic',
|
||||
required: true,
|
||||
description:
|
||||
'The prompt(s) to generate completions for, encoded as a list of dict with role and content.',
|
||||
value: [{ role: 'system', body: '' }],
|
||||
fields: [
|
||||
{
|
||||
label: 'Role',
|
||||
key: 'role',
|
||||
type: 'dropdown',
|
||||
required: true,
|
||||
options: [
|
||||
{
|
||||
label: 'System',
|
||||
value: 'system',
|
||||
},
|
||||
{
|
||||
label: 'Assistant',
|
||||
value: 'assistant',
|
||||
},
|
||||
{
|
||||
label: 'User',
|
||||
value: 'user',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Content',
|
||||
key: 'content',
|
||||
type: 'string',
|
||||
required: true,
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Temperature',
|
||||
key: 'temperature',
|
||||
type: 'string',
|
||||
required: false,
|
||||
variables: true,
|
||||
description:
|
||||
'What sampling temperature to use. Higher values mean the model will take more risk. Try 0.9 for more creative applications, and 0 for ones with a well-defined answer. We generally recommend altering this or Top P but not both.',
|
||||
},
|
||||
{
|
||||
label: 'Maximum tokens',
|
||||
key: 'maxTokens',
|
||||
type: 'string',
|
||||
required: false,
|
||||
variables: true,
|
||||
description: `The maximum number of tokens to generate in the completion. The token count of your prompt plus max_tokens cannot exceed the model's context length.`,
|
||||
},
|
||||
{
|
||||
label: 'Stop sequences',
|
||||
key: 'stopSequences',
|
||||
type: 'dynamic',
|
||||
required: false,
|
||||
variables: true,
|
||||
description: 'Stop generation if one of these tokens is detected',
|
||||
fields: [
|
||||
{
|
||||
label: 'Stop sequence',
|
||||
key: 'stopSequence',
|
||||
type: 'string',
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Top P',
|
||||
key: 'topP',
|
||||
type: 'string',
|
||||
required: false,
|
||||
variables: true,
|
||||
description:
|
||||
'Nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. We generally recommend altering this or temperature but not both.',
|
||||
},
|
||||
{
|
||||
label: 'Frequency Penalty',
|
||||
key: 'frequencyPenalty',
|
||||
type: 'string',
|
||||
required: false,
|
||||
variables: true,
|
||||
description: `Frequency_penalty penalizes the repetition of words based on their frequency in the generated text. A higher frequency penalty discourages the model from repeating words that have already appeared frequently in the output, promoting diversity and reducing repetition.`,
|
||||
},
|
||||
{
|
||||
label: 'Presence Penalty',
|
||||
key: 'presencePenalty',
|
||||
type: 'string',
|
||||
required: false,
|
||||
variables: true,
|
||||
description: `Presence penalty determines how much the model penalizes the repetition of words or phrases. A higher presence penalty encourages the model to use a wider variety of words and phrases, making the output more diverse and creative.`,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const nonEmptyStopSequences = $.step.parameters.stopSequences
|
||||
.filter(({ stopSequence }) => stopSequence)
|
||||
.map(({ stopSequence }) => stopSequence);
|
||||
|
||||
const messages = $.step.parameters.messages.map((message) => ({
|
||||
role: message.role,
|
||||
content: message.content,
|
||||
}));
|
||||
|
||||
const payload = {
|
||||
model: $.step.parameters.model,
|
||||
messages,
|
||||
stop: nonEmptyStopSequences,
|
||||
temperature: castFloatOrUndefined($.step.parameters.temperature),
|
||||
max_tokens: castFloatOrUndefined($.step.parameters.maxTokens),
|
||||
top_p: castFloatOrUndefined($.step.parameters.topP),
|
||||
frequency_penalty: castFloatOrUndefined(
|
||||
$.step.parameters.frequencyPenalty
|
||||
),
|
||||
presence_penalty: castFloatOrUndefined($.step.parameters.presencePenalty),
|
||||
};
|
||||
|
||||
const { data } = await $.http.post('/v1/chat/completions', payload);
|
||||
|
||||
$.setActionItem({
|
||||
raw: data,
|
||||
});
|
||||
},
|
||||
});
|
||||
3
packages/backend/src/apps/mistral-ai/actions/index.js
Normal file
3
packages/backend/src/apps/mistral-ai/actions/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import createChatCompletion from './create-chat-completion/index.js';
|
||||
|
||||
export default [createChatCompletion];
|
||||
32
packages/backend/src/apps/mistral-ai/assets/favicon.svg
Normal file
32
packages/backend/src/apps/mistral-ai/assets/favicon.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="233px" viewBox="0 0 256 233" version="1.1" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid">
|
||||
<title>Mistral AI</title>
|
||||
<g>
|
||||
<rect fill="#000000" x="186.181818" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F7D046" x="209.454545" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F7D046" x="23.2727273" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="209.454545" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="23.2727273" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="139.636364" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="162.909091" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="69.8181818" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="116.363636" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="162.909091" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="69.8181818" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="93.0909091" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EB5829" x="116.363636" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="209.454545" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="23.2727273" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="186.181818" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EB5829" x="209.454545" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="186.181818" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EB5829" x="23.2727273" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EA3326" x="209.454545" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EA3326" x="23.2727273" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
34
packages/backend/src/apps/mistral-ai/auth/index.js
Normal file
34
packages/backend/src/apps/mistral-ai/auth/index.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import verifyCredentials from './verify-credentials.js';
|
||||
import isStillVerified from './is-still-verified.js';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'screenName',
|
||||
label: 'Screen Name',
|
||||
type: 'string',
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description:
|
||||
'Screen name of your connection to be used on Automatisch UI.',
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'apiKey',
|
||||
label: 'API Key',
|
||||
type: 'string',
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: 'Mistral AI API key of your account.',
|
||||
docUrl: 'https://automatisch.io/docs/mistral-ai#api-key',
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
const isStillVerified = async ($) => {
|
||||
await $.http.get('/v1/models');
|
||||
return true;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
||||
@@ -0,0 +1,5 @@
|
||||
const verifyCredentials = async ($) => {
|
||||
await $.http.get('/v1/models');
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
||||
@@ -0,0 +1,9 @@
|
||||
const addAuthHeader = ($, requestConfig) => {
|
||||
if ($.auth.data?.apiKey) {
|
||||
requestConfig.headers.Authorization = `Bearer ${$.auth.data.apiKey}`;
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
||||
@@ -0,0 +1,3 @@
|
||||
import listModels from './list-models/index.js';
|
||||
|
||||
export default [listModels];
|
||||
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
name: 'List models',
|
||||
key: 'listModels',
|
||||
|
||||
async run($) {
|
||||
const response = await $.http.get('/v1/models');
|
||||
|
||||
const models = response.data.data.map((model) => {
|
||||
return {
|
||||
value: model.id,
|
||||
name: model.id,
|
||||
};
|
||||
});
|
||||
|
||||
return { data: models };
|
||||
},
|
||||
};
|
||||
20
packages/backend/src/apps/mistral-ai/index.js
Normal file
20
packages/backend/src/apps/mistral-ai/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import defineApp from '../../helpers/define-app.js';
|
||||
import addAuthHeader from './common/add-auth-header.js';
|
||||
import auth from './auth/index.js';
|
||||
import actions from './actions/index.js';
|
||||
import dynamicData from './dynamic-data/index.js';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Mistral AI',
|
||||
key: 'mistral-ai',
|
||||
baseUrl: 'https://mistral.ai',
|
||||
apiBaseUrl: 'https://api.mistral.ai',
|
||||
iconUrl: '{BASE_URL}/apps/mistral-ai/assets/favicon.svg',
|
||||
authDocUrl: '{DOCS_URL}/apps/mistral-ai/connection',
|
||||
primaryColor: '#000000',
|
||||
supportsConnections: true,
|
||||
beforeRequest: [addAuthHeader],
|
||||
auth,
|
||||
actions,
|
||||
dynamicData,
|
||||
});
|
||||
@@ -37,6 +37,7 @@ exports[`App model > list should have list of applications keys 1`] = `
|
||||
"mailerlite",
|
||||
"mattermost",
|
||||
"miro",
|
||||
"mistral-ai",
|
||||
"notion",
|
||||
"ntfy",
|
||||
"odoo",
|
||||
|
||||
@@ -313,6 +313,15 @@ export default defineConfig({
|
||||
{ text: 'Connection', link: '/apps/miro/connection' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Mistral AI',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: 'Actions', link: '/apps/mistral-ai/actions' },
|
||||
{ text: 'Connection', link: '/apps/mistral-ai/connection' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Notion',
|
||||
collapsible: true,
|
||||
|
||||
12
packages/docs/pages/apps/mistral-ai/actions.md
Normal file
12
packages/docs/pages/apps/mistral-ai/actions.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
favicon: /favicons/mistral-ai.svg
|
||||
items:
|
||||
- name: Create chat completion
|
||||
desc: Creates a chat completion.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import CustomListing from '../../components/CustomListing.vue'
|
||||
</script>
|
||||
|
||||
<CustomListing />
|
||||
8
packages/docs/pages/apps/mistral-ai/connection.md
Normal file
8
packages/docs/pages/apps/mistral-ai/connection.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Mistral AI
|
||||
|
||||
1. Go to [Your API keys page](https://console.mistral.ai/api-keys/) on Mistral AI.
|
||||
2. Create a new API key.
|
||||
3. Paste the key into the `API Key` field in Automatisch.
|
||||
4. Write any screen name to be displayed in Automatisch.
|
||||
5. Click `Save`.
|
||||
6. Start using Mistral AI integration with Automatisch!
|
||||
@@ -31,6 +31,7 @@ The following integrations are currently supported by Automatisch.
|
||||
- [MailerLite](/apps/mailerlite/triggers)
|
||||
- [Mattermost](/apps/mattermost/actions)
|
||||
- [Miro](/apps/miro/actions)
|
||||
- [Mistral AI](/apps/mistral-ai/actions)
|
||||
- [Notion](/apps/notion/triggers)
|
||||
- [Ntfy](/apps/ntfy/actions)
|
||||
- [Odoo](/apps/odoo/actions)
|
||||
|
||||
32
packages/docs/pages/public/favicons/mistral-ai.svg
Normal file
32
packages/docs/pages/public/favicons/mistral-ai.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="233px" viewBox="0 0 256 233" version="1.1" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid">
|
||||
<title>Mistral AI</title>
|
||||
<g>
|
||||
<rect fill="#000000" x="186.181818" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F7D046" x="209.454545" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="0" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F7D046" x="23.2727273" y="0" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="209.454545" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="23.2727273" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="139.636364" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="162.909091" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#F2A73B" x="69.8181818" y="46.5454545" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="116.363636" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="162.909091" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="69.8181818" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="93.0909091" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EB5829" x="116.363636" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="209.454545" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EE792F" x="23.2727273" y="93.0909091" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="186.181818" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EB5829" x="209.454545" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#000000" x="186.181818" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EB5829" x="23.2727273" y="139.636364" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EA3326" x="209.454545" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
<rect fill="#EA3326" x="23.2727273" y="186.181818" width="46.5454545" height="46.5454545"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user