Skip to content

Commit

Permalink
What's new:
Browse files Browse the repository at this point in the history
- Added support for different AI APIs and LLMs
- Added processing and validation of the LLM generated code
  • Loading branch information
keadex committed Sep 14, 2024
1 parent 7710fbf commit 636e5f4
Show file tree
Hide file tree
Showing 28 changed files with 418 additions and 98 deletions.
1 change: 0 additions & 1 deletion apps/keadex-battisti/public/img/openai-logo.svg

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"keadex_mina": {
"ai": {
"title": "AI-Powered",
"description": "<span className='text-orange-400'>This feature is in alpha version and in development stages. Therefore, it may currently return results that are not always correct.</span><p>Mina integrates AI to <span className='font-bold'>generate diagram code</span> based on a natural language description of your architecture.</p><p>Mina uses OpenAI's <code>gpt-3.5-turbo-instruct</code> model to provide the functionality of generating code for architectural diagrams from natural language descriptions. Since Mina is and always will be <span className='font-bold'>open source and free</span>, and since the <code>gpt-3.5-turbo-instruct</code> model is not free, you will need to configure your <span className='font-bold'>OpenAI API Key</span> within Mina if you want to use this feature.</p>"
"description": "<p>Mina integrates AI to <span className='font-bold'>generate diagram code</span> based on a natural language description of your architecture.</p><p>Since Mina strongly supports <span className='font-bold'>open-source</span> technologies, it offers a <span className='font-bold'>configurable AI integration</span> that allows you to choose the AI APIs and model you want to use.</p><p>Whatever AI APIs you decide to implement, make sure they are compatible with the <span className='font-bold'>OpenAI format</span>. Tools like <a href='https://github.com/BerriAI/litellm' target='_blank'>LiteLLM</a> can be used to ensure the OpenAI format.</p><p>This flexibility allows you to leverage AI features <span className='font-bold'>for free</span> by running an open-source AI model like <a href='https://llama.meta.com/' target='_blank'>Llama</a> locally, using tools such as <a href='https://ollama.com/' target='_blank'>Ollama</a>.</p><p>For more information, please visit the <a href='/docs/mina/features/ai'>Mina documentation</a>.</p><p>Keadex Mina will then interpret the AI's response and utilize its own <a href='/docs/mina/architecture/rendering-system'>rendering system</a> to render the generated diagram code.</p>"
},
"description": "Open Source<span className='font-extralight'>, serverless IDE to easily code and organize at a scale</span> C4 model diagrams.",
"details": {
Expand Down
4 changes: 1 addition & 3 deletions apps/keadex-battisti/src/components/MinaAI/MinaAI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ export default function MinaAI({
components={{ span: <span /> }}
/>
</div>
<div className="ml-5 bg-dark-brand1 rounded-md py-1 px-5 text-xl my-auto">
ALPHA
</div>
</div>
<div className="mt-5 font-light">
<Trans
Expand All @@ -39,6 +36,7 @@ export default function MinaAI({
components={{
span: <span />,
code: <code />,
a: <a />,
}}
/>
</div>
Expand Down
70 changes: 47 additions & 23 deletions apps/keadex-battisti/src/pages/[lang]/docs/mina/features/ai.mdx
Original file line number Diff line number Diff line change
@@ -1,40 +1,64 @@
import { Callout } from 'nextra/components'
import Image from 'next/image'
import minaLogo from '../../../../../../public/img/keadex-mina-logo-color.svg'
import openaiLogo from '../../../../../../public/img/openai-logo.svg'
import { faRobot } from '@fortawesome/free-solid-svg-icons'
import { faKeadexMina } from '../../../../../../../keadex-mina/src/assets/icons'

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import aiScreenshot from '../../../../../../public/img/mina/ai-powered.gif'

# Diagram Generation w/ AI

<Callout type="warning" emoji="🔬">
The AI integration is currently just an experyment in the early stages and is currently in **alpha version**. It may return incorrect results.
</Callout>

<div align="center" className="my-14 block md:flex items-center justify-center">
<Image src={minaLogo} alt="Keadex Mina Logo" height={55} />
<div className="text-5xl px-5">&plus;</div>
<Image src={openaiLogo} alt="OpenAI Logo" height={50} className="invert"/>
</div>

Mina integrates AI to **generate diagram code** based on a natural language description of your architecture.

<p align="center">
<Image src={aiScreenshot} alt="Screenshot of Keadex Mina generatic diagrams with the AI" width={500} />
<Image
src={aiScreenshot}
alt="Screenshot of Keadex Mina generatic diagrams with the AI"
width={500}
/>
</p>

The current implementation is a rudimentary integration with the OpenAI APIs: the Mina backend sends a completion request with your diagram description, to the `gpt-3.5-turbo-instruct` OpenAI model every time you ask Mina to generate a diagram.
Since Mina strongly supports **open-source** technologies, it offers a **configurable AI integration** that allows you to choose the AI APIs and model you want to use.

Whatever AI APIs you decide to implement, make sure they are compatible with the **OpenAI format**. Tools like [LiteLLM](https://github.com/BerriAI/litellm) can be used to ensure the OpenAI format.

This flexibility allows you to leverage AI features **for free** by running an open-source AI model like [Llama](https://llama.meta.com/) locally, using tools such as [Ollama](https://ollama.com/).

Since Mina is and always will be **open source and free**, and since the `gpt-3.5-turbo-instruct` **OpenAI model is not free**, you will need to configure your **OpenAI API Key** within Mina if you want to use this feature.
Keadex Mina will then interpret the AI's response and utilize its own [rendering system](/docs/mina/architecture/rendering-system) to render the generated diagram code.

If you want an idea of the costs you can consider the following data:
- OpenAI Model: **`gpt-3.5-turbo-instruct`**
- OpenAI pricing: https://openai.com/api/pricing/
- Number of OpenAI requests: **1 OpenAI request/diagram generation request**
- Max allowed tokens for each request: **2048**
## Example of usage with Ollama

In this example, we'll use [Ollama](https://ollama.com/) to run the [Code Llama LLM](https://ai.meta.com/blog/code-llama-large-language-model-coding/) locally and configure Mina to leverage it for enabling AI features, including generating diagrams from natural language prompts.

### Run the LLM locally

1. Download Ollama from https://ollama.com/
2. Install and run Ollama
3. Open the terminal and run the following command: `ollama run codellama:7b-instruct`. This command will download and locally run the [Code Llama LLM](https://ai.meta.com/blog/code-llama-large-language-model-coding/), which can generate code from text prompts. In this case, we're downloading the smallest version of the model due to the hardware limitations of the local machine. However, you're free to choose a larger version or a different LLM based on your requirements.

<Callout type="warning" emoji="⚠️">
Since we're running the **smallest** version of the LLM **locally**, code
generation may be slow and might not always produce valid results. For better
performance and more accurate outputs, consider running a **larger** version
of the LLM on more powerful hardware.
</Callout>

### Configure Mina to integrate with the locally running LLM

## What's Next?
4. Open your project in Mina
5. Click on the _project_ icon (<FontAwesomeIcon icon={faKeadexMina} className="inline w-4 mx-2" />) in the sidebar
6. Click on the _settings_ button
7. In the _AI Integration_ section, fill in the following details:
- **AI API Key**: The API key for accessing the AI APIs. Enter `ollama` since we're using Ollama.
- **AI API (OpenAI compatible) Base URL**: The base URL of the AI APIs you're using (compatible with OpenAI). Ollama provides [OpenAI-compatible APIs](https://ollama.com/blog/openai-compatibility) at this base URL: http://localhost:11434/v1
- **AI Model**: Enter the name of the LLM you're using. Since we selected `codellama:7b-instruct` in step 3, you can use that name here.
8. Click on the _save_ button
9. Mina can now interact with the LLM to generate diagrams

There is a strong interest in evolving the integration of Keadex Mina with AI. The long-term goal is to provide a feature that can generate and render detailed, aesthetically pleasing, and linked C4 Model diagrams.
### Generate a diagram using AI assistance

We will soon plan the roadmap to achieve this goal.
10. Open a diagram in Mina
11. In the code editor, place the cursor where you want the generated code to appear
12. In the code editor toolbar, click on the AI icon (<FontAwesomeIcon icon={faRobot} className="inline w-4 mx-2" />). This will open a text area where you can enter your prompt.
13. Enter in the text area the description of the architecture for which you want to generate the C4 Model diagram
14. Click on the _generate_ button
2 changes: 1 addition & 1 deletion apps/keadex-battisti/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default function MyApp({ Component, pageProps }: AppProps) {
children: [
{
id: 'keadex-mina_ai',
title: 'AI (alpha)',
title: 'AI',
href: ROUTES[MINA_AI].path,
disableTOC: true,
},
Expand Down
2 changes: 1 addition & 1 deletion apps/keadex-mina/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@keadex/keadex-mina",
"description": "Desktop application to draw, manage and share the architectures of software systems.",
"author": "Keadex <keadex.it@gmail.com>",
"version": "1.5.0",
"version": "1.6.0",
"private": true,
"license": "MIT",
"type": "module",
Expand Down
29 changes: 19 additions & 10 deletions apps/keadex-mina/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
"documentation": "Documentation",
"duplicate": "Duplicate",
"edit": "Edit",
"editor": "Editor",
"empty": "Empty",
"enabled": "Enabled",
"example": "Example",
"exit": "Exit",
"export": "Export",
"external": "External",
Expand All @@ -48,13 +50,13 @@
"label": "Label",
"location": "Location",
"max": "Max",
"model": "Model",
"name": "Name",
"new": "New",
"no": "No",
"note": "Note",
"notes": "Notes",
"open": "Open",
"openai_api_key": "OpenAI API Key",
"orientation": "Orientation",
"paste": "Paste",
"path": "Path",
Expand Down Expand Up @@ -99,7 +101,8 @@
"invalid_diagram_link": "Diagram not found. Check the diagram link.",
"invalid_path": "Invalid path",
"missing_project_root": "Missing project root",
"missing_openai_api_key": "Missing OpenAI API Key. Configure it in the project's settings.",
"missing_ai_api_base_url": "Missing AI API Base URL. Configure it in the project's settings.",
"missing_ai_api_key": "Missing AI API Key. Configure it in the project's settings.",
"project_not_closed": "Project not closed: {{errorMessage}}",
"project_not_opened": "Project not opened: {{errorMessage}}"
},
Expand All @@ -125,10 +128,9 @@
"confirm_exit": "Are you sure you want to exit? Not saved changes of the current project will be lost."
}
},
"home": {
"chose_parent_dir_project": "Choose the parent directory of the project",
"create_project": "Create a new project",
"open_project": "Open an existing project"
"about": {
"os_type": "OS Type",
"kernel_version": "Kernel Version"
},
"diagram_editor": {
"add_diagram_element": "Add a diagram element",
Expand All @@ -143,12 +145,19 @@
"select_element_type_to_import": "Select the C4 element type to import from the library",
"warning_enable_autolayout": "You are enabling the auto layout. All the changes you made to the diagram layout will be discarded and replaced with the automatically generated layout."
},
"home": {
"chose_parent_dir_project": "Choose the parent directory of the project",
"create_project": "Create a new project",
"open_project": "Open an existing project"
},
"project_settings": {
"ai_api_key": "AI API Key",
"ai_api_base_url": "AI API (OpenAI compatible) Base URL",
"ai_integration": "AI Integration",
"ai_model": "AI Model"
},
"table": {
"go_to_page": "Go to page",
"current_page": "Page {{currentPage}} of {{totalPages}}"
},
"about": {
"os_type": "OS Type",
"kernel_version": "Kernel Version"
}
}
5 changes: 4 additions & 1 deletion apps/keadex-mina/src-tauri/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"editor.formatOnSave": true,
}
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
}
2 changes: 1 addition & 1 deletion apps/keadex-mina/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/keadex-mina/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "keadex_mina"
version = "1.5.0"
version = "1.6.0"
description = "Desktop application to draw, manage and share the architectures of software systems."
authors = ["Keadex"]
license = "MIT"
Expand Down
10 changes: 8 additions & 2 deletions apps/keadex-mina/src-tauri/src/error_handling/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub const LIBRARY_ERROR_CODE: i32 = 6;
pub const INVALID_NEW_DIAGRAM_PATH_ERROR_CODE: i32 = 7;
pub const DUPLICATED_ALIASES_IN_DIAGRAM_ERROR_CODE: i32 = 8;
pub const DUPLICATED_ALIASES_IN_PROJECT_ERROR_CODE: i32 = 9;
pub const AI_ERROR_CODE: i32 = 10;

// Error messages
pub const GENERIC_ERROR_MSG: &str = "Generic error.";
Expand All @@ -34,9 +35,14 @@ pub const CANNOT_OPEN_FILE_ERROR_MSG: &str = "Cannot open the file. Unknown reas
pub const FILE_DOES_NOT_EXIST: &str = "File does not exist.";
pub const PROJECT_NOT_LOADED_ERROR_MSG: &str = "Project not loaded.";
pub const NOT_A_DIRECTORY_ERROR_MSG: &str = "Provided path is not a directory.";
pub const EXISTING_PROJECT_DIRECTORY_ERROR_MSG: &str = "The following project directory already exists: ";
pub const NOT_EXISTING_PARENT_PATH_PROJECT_ERROR_MSG: &str = "Provided parent path of the project does not exist.";
pub const EXISTING_PROJECT_DIRECTORY_ERROR_MSG: &str =
"The following project directory already exists: ";
pub const NOT_EXISTING_PARENT_PATH_PROJECT_ERROR_MSG: &str =
"Provided parent path of the project does not exist.";
pub const INVALID_LIBRARY_PATH_ERROR_MSG: &str = "Invalid library's path.";
pub const EXISTING_DIAGRAM_ERROR_MSG: &str =
"A diagram with the given name and type already exists. Choose a different name or type.";
pub const INVALID_LIB_ELEMENT_ERROR_MSG: &str = "Provided element is not a valid library element.";
pub const MISSING_AI_SETTINGS_ERROR_MSG: &str = "Missing AI settings.";
pub const INVALID_GENERATED_DIAGRAM: &str =
"The AI-generated diagram contains errors. Try again providing a more detailed description.";
74 changes: 74 additions & 0 deletions apps/keadex-mina/src-tauri/src/model/ai/ai_diagram_gen_response.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*!
Model representing the response of the AI for generating diagrams.
*/

use serde::{Deserialize, Serialize};
use strum::{Display, EnumIter, EnumString};
use ts_rs::TS;

#[derive(TS)]
#[ts(
export,
export_to = "../../../apps/keadex-mina/src/models/autogenerated/"
)]
#[derive(
Serialize, Deserialize, Display, Debug, EnumString, Clone, EnumIter, Hash, Eq, PartialEq,
)]
pub enum AIDiagramGenElementType {
#[serde(rename = "Person")]
#[strum(serialize = "Person")]
Person,
#[serde(rename = "SoftwareSystem")]
#[strum(serialize = "SoftwareSystem")]
SoftwareSystem,
#[serde(rename = "Container")]
#[strum(serialize = "Container")]
Container,
#[serde(rename = "Component")]
#[strum(serialize = "Component")]
Component,
#[serde(rename = "Relationship")]
#[strum(serialize = "Relationship")]
Relationship,
}

#[derive(TS)]
#[ts(
export,
export_to = "../../../apps/keadex-mina/src/models/autogenerated/"
)]
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
pub struct AIDiagramGenElement {
#[serde(skip_serializing_if = "Option::is_none")]
pub alias: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub technology: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub element_type: Option<AIDiagramGenElementType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub from_alias: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub to_alias: Option<String>,
}

#[derive(TS)]
#[ts(
export,
export_to = "../../../apps/keadex-mina/src/models/autogenerated/"
)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AIDiagramGenResponse {
pub diagram_elements: Vec<AIDiagramGenElement>,
}

impl Default for AIDiagramGenResponse {
fn default() -> Self {
AIDiagramGenResponse {
diagram_elements: vec![],
}
}
}
21 changes: 21 additions & 0 deletions apps/keadex-mina/src-tauri/src/model/ai/ai_settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*!
Model representing settings of the AI integration.
*/

use serde::{Deserialize, Serialize};
use ts_rs::TS;

#[derive(TS)]
#[ts(
export,
export_to = "../../../apps/keadex-mina/src/models/autogenerated/"
)]
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
pub struct AISettings {
#[serde(skip_serializing_if = "Option::is_none")]
pub api_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub api_base_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
}
2 changes: 2 additions & 0 deletions apps/keadex-mina/src-tauri/src/model/ai/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod ai_diagram_gen_response;
pub mod ai_settings;
1 change: 1 addition & 0 deletions apps/keadex-mina/src-tauri/src/model/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod ai;
pub mod c4_element;
pub mod diagram;
pub mod diagram_element_search_results;
Expand Down
Loading

0 comments on commit 636e5f4

Please sign in to comment.