Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web app UI fixes #335

Merged
merged 49 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
7211007
Merge pull request #316 from CommandDash/web-app
samyakkkk Jul 8, 2024
12b9c4d
(feat): CommandDash badge added
samyakkkk Jul 11, 2024
3462734
(fix): blank target added
samyakkkk Jul 11, 2024
7b110f6
(feat): no referrer
samyakkkk Jul 11, 2024
87fd4dc
(feat): revert target blank
samyakkkk Jul 11, 2024
7391719
Merge pull request #317 from CommandDash/badge
samyakkkk Jul 11, 2024
79e66ae
(feat): thread responses with typing working
samyakkkk Jul 11, 2024
d3d623a
(fix): code optimizations
samyakkkk Jul 11, 2024
6858ec3
(feat): better code samples handing.
samyakkkk Jul 11, 2024
b94f3d5
(feat): Quick Tip in disabled state
samyakkkk Jul 11, 2024
10aaae5
(feat): fetch handler agent from guild_id
samyakkkk Jul 12, 2024
d5d510c
(feat): web config file
samyakkkk Jul 12, 2024
90eb63d
Add or update the Azure App Service build and deployment workflow config
samyakkkk Jul 12, 2024
0384a9f
Merge branch 'discord-bot' of github.com:Welltested-AI/fluttergpt int…
samyakkkk Jul 12, 2024
1fc901b
(feat): path corrections
samyakkkk Jul 12, 2024
82f3d07
(feat): test script removed
samyakkkk Jul 12, 2024
f25d416
(feat): updated zip step
samyakkkk Jul 12, 2024
ae1e2a5
(feat) zip fix
samyakkkk Jul 12, 2024
74db396
(feat): test fetch
samyakkkk Jul 12, 2024
100a14f
(feat): express added
samyakkkk Jul 12, 2024
c9e6177
(feat): gitignore update for discord bot
samyakkkk Jul 15, 2024
6c5002a
(feat): for-the-badge-style
samyakkkk Jul 15, 2024
214dd71
Merge pull request #318 from CommandDash/badge
samyakkkk Jul 15, 2024
ae55b33
Merge pull request #320 from CommandDash/discord-bot
samyakkkk Jul 23, 2024
6f67400
fix(Chat UX): message changes on bottom tip. Questionnaire changes ba…
wadhia-yash Aug 14, 2024
5315ac0
feat(Chat header): Added agent description in chat header when agent …
wadhia-yash Aug 15, 2024
42ef9c6
fix(Questionnaire): Removed grid with two columns and made with one c…
wadhia-yash Aug 15, 2024
085b6dc
fix(Chat window): Changed the questionaire paddings, and changed the …
wadhia-yash Aug 15, 2024
cc86086
fix(Search agent text input): Agents search with '@' has new search f…
wadhia-yash Aug 16, 2024
4d831c1
fix(Agent logo, bottom info): Agent logo showing when message is clea…
wadhia-yash Aug 16, 2024
003e04e
fix(Footer message): Fixed the condition to change the footer message
wadhia-yash Aug 16, 2024
e575138
fix(Header, Tip message): When agent is switched and the conversation…
wadhia-yash Aug 19, 2024
aa375d3
fix(placeholder): placeholder color not showing properly
wadhia-yash Aug 19, 2024
8fe1b71
fix(create agent): Create agent navigation. When agent is not available
wadhia-yash Aug 19, 2024
251ff0b
Merge branch 'develop' into vscode-ux-revamp
samyakkkk Aug 19, 2024
2e2181f
Merge branch 'web-app' into web-app-ui-fixes
wadhia-yash Aug 26, 2024
97ba5f4
fix(Chat window): Disabling the text input in the chat window when in…
wadhia-yash Aug 26, 2024
4d77ede
fix(Chat indexing): Changed notify view when the agent is being indexed
wadhia-yash Aug 26, 2024
d977f48
Merge branch 'web-app' into web-app-ui-fixes
samyakkkk Aug 26, 2024
51890e3
fix(Chat indexing): Changed chat indexing UI
wadhia-yash Aug 26, 2024
216e256
Merge branch 'web-app-ui-fixes' of github.com:CommandDash/commanddash…
wadhia-yash Aug 26, 2024
d4eb770
(feat): copywriting
samyakkkk Aug 26, 2024
24ad5ee
Merge branch 'web-app-ui-fixes' of github.com:Welltested-AI/fluttergp…
samyakkkk Aug 26, 2024
bdb6fc9
(feat): copywiritng
samyakkkk Aug 26, 2024
b12d7a3
fix(Discord): removed node_modules
wadhia-yash Aug 26, 2024
5bcc315
fix(discord): removed node_modules
wadhia-yash Aug 26, 2024
7f4569a
fix(discord): removed node_modules
wadhia-yash Aug 26, 2024
4abfd3c
Merge branch 'web-app-ui-fixes' of github.com:CommandDash/commanddash…
wadhia-yash Aug 26, 2024
63307cf
(feat): copywriting
samyakkkk Aug 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/discord-bot_discord-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js app to Azure Web App - discord-app

on:
push:
branches:
- discord-bot
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Node.js version
uses: actions/setup-node@v3
with:
node-version: '18.x'

- name: npm install, build, and test
run: |
cd discord
npm install
npm run build --if-present
npm run test --if-present

- name: Zip artifact for deployment
run: |
cd discord
zip -r ../release.zip ./*

- name: Upload artifact for deployment job
uses: actions/upload-artifact@v4
with:
name: node-app
path: release.zip

deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
permissions:
id-token: write #This is required for requesting the JWT

steps:
- name: Download artifact from build job
uses: actions/download-artifact@v4
with:
name: node-app

- name: Unzip artifact for deployment
run: unzip release.zip

- name: Login to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F79B5525A24E4DD1B0474AE8E88AC734 }}
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_82993AB6E0F44B589C524B05273985DB }}
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_BD59F4177F7646289B41D15D6119C77B }}

- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v3
with:
app-name: 'discord-app'
slot-name: 'Production'
package: .

3 changes: 3 additions & 0 deletions discord/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env
./node_modules/
package-lock.json
196 changes: 196 additions & 0 deletions discord/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
require('dotenv').config();
const { Client, GatewayIntentBits, ChannelType } = require('discord.js');
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMembers
]
});

// Parse the GUILD_AGENT_MAP from the environment variable
const guildAgentMap = JSON.parse(process.env.GUILD_AGENT_MAP);

client.once('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});

client.on('messageCreate', async message => {
console.log('message received');

// Ignore messages from the bot itself
if (message.author.bot) return;

// Check if the bot is tagged in the message
if (message.mentions.has(client.user)) {
const fetch = (await import('node-fetch')).default;

// Function to split message into chunks of 2000 characters or less
function splitMessage(message, maxLength = 2000) {
if (message.length <= maxLength) return [message];
const parts = [];
let currentPart = '';
let inCodeBlock = false;

const lines = message.split('\n');
for (const line of lines) {
if (line.startsWith('```')) {
inCodeBlock = !inCodeBlock;
}

if (currentPart.length + line.length + 1 > maxLength) {
if (inCodeBlock) {
currentPart += '\n```';
parts.push(currentPart);
currentPart = '```';
} else {
parts.push(currentPart);
currentPart = '';
}
}

currentPart += (currentPart.length > 0 ? '\n' : '') + line;

if (!inCodeBlock && currentPart.length >= maxLength) {
parts.push(currentPart);
currentPart = '';
}
}

if (currentPart.length > 0) {
parts.push(currentPart);
}

return parts;
}

// Function to keep typing indicator active
function keepTyping(channel) {
const interval = setInterval(() => {
channel.sendTyping();
}, 5000); // Typing indicator lasts for 10 seconds, so we refresh it every 5 seconds
return interval;
}

// Function to stop typing indicator
function stopTyping(interval) {
clearInterval(interval);
}

// Determine the channel (thread or main channel)
let channel;
if (message.channel.type === ChannelType.PublicThread || message.channel.type === ChannelType.PrivateThread) {
channel = message.channel
} else {
channel = await message.startThread({
name: `Thread for ${message.author.username}`,
autoArchiveDuration: 60,
});

// await channel.send("Hold tight, I'm preparing your answer!\n\nQuick tip ⚡️, I can help you better from your IDE. Install the [VSCode extension](https://marketplace.visualstudio.com/items?itemName=WelltestedAI.fluttergpt)");
}

// Start typing indicator
const typingInterval = keepTyping(channel);

// Fetch agent details
const guildId = message.guild.id;
const agentName = guildAgentMap[guildId];
if (!agentName) {
channel.send('Sorry, I could not find the agent for this guild.');
stopTyping(typingInterval); // Stop typing indicator
return;
}

let agentDetails;
try {
const response = await fetch("https://api.commanddash.dev/agent/get-latest-agent", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name: agentName }),
});

if (!response.ok) {
throw new Error(`Failed to load the agent: ${await response.json()}`);
}

agentDetails = await response.json();
console.log(agentDetails)
} catch (error) {
console.error('Error fetching agent details:', error);
channel.send('Sorry, I could not fetch the agent details.');
stopTyping(typingInterval); // Stop typing indicator
return;
}

try {
// Fetch all messages in the thread if it's a thread
let history = [];
history.push({ "role": "user", "text": "This conversation is happening on Discord, so please keep response concise and quote snippets only when necessary (unless of course explicity requested) " });
if (channel.type === ChannelType.PublicThread || channel.type === ChannelType.PrivateThread) {
const messages = await channel.messages.fetch({ limit: 100 });
history = messages.map(msg => ({
"role": msg.author.id === client.user.id ? "model" : "user",
"text": msg.content
}));
}

history.push({ "role": "user", "text": message.content });

// Prepare data for agent answer API
const agentData = {
agent_name: agentDetails.name,
agent_version: agentDetails.version,
chat_history: history,
included_references: [],
private: agentDetails.testing,
};

// Get answer from agent
const response = await fetch("https://api.commanddash.dev/v2/ai/agent/answer", {
method: "POST",
body: JSON.stringify(agentData),
headers: {
"Content-Type": "application/json",
},
});
const modelResponse = await response.json();
console.log(modelResponse);

// Split the response into chunks and send each chunk
const responseChunks = splitMessage(modelResponse.response);
for (const chunk of responseChunks) {
await channel.send(chunk);
}
} catch (error) {
console.error('Error getting answer from agent:', error);
channel.send('Sorry, I could not get an answer from the agent.');
} finally {
stopTyping(typingInterval); // Stop typing indicator
}
}
});

// Handle errors to prevent the bot from crashing
client.on('error', error => {
console.error('An error occurred:', error);
});

client.login(process.env.DISCORD_TOKEN);

// API endpoint to return the Discord token
app.get('/api/token', (req, res) => {
res.json({ token: process.env.DISCORD_TOKEN });
});

app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
18 changes: 18 additions & 0 deletions discord/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "discord",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"discord.js": "^14.15.3",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"node-fetch": "^3.3.2"
}
}
25 changes: 25 additions & 0 deletions discord/web.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="index.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="index.js" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
<h1 align="center">CommandDash</h1>
<div align = "center">

[![VScode Downloads](https://img.shields.io/visual-studio-marketplace/d/WelltestedAI.fluttergpt)](https://marketplace.visualstudio.com/items?itemName=WelltestedAI.fluttergpt&ssr=false#overview) [![License: APACHE](https://img.shields.io/badge/License-APACHE%202.0-yellow)](/LICENSE)
[![VScode Downloads](https://img.shields.io/visual-studio-marketplace/d/WelltestedAI.fluttergpt?style=for-the-badge)](https://marketplace.visualstudio.com/items?itemName=WelltestedAI.fluttergpt&ssr=false#overview) [![License: APACHE](https://img.shields.io/badge/License-APACHE%202.0-yellow?style=for-the-badge)](/LICENSE) <a href="https://app.commanddash.io/agent/dash"><img src="https://img.shields.io/badge/Ask-AI%20Assist-EB9FDA?style=for-the-badge"></a>

</div>

<h3 align="center">Integrate APIs, SDKs or Packages with AI Agents</h3>
Expand Down
2 changes: 1 addition & 1 deletion vscode/media/agent-ui-builder/agent-ui-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class AgentUIBuilder {
textHtml = textHtml.replace(`<${input.id}>`, inputElement.outerHTML);
});

activeCommandsAttach.textContent = `${slug}`;
// activeCommandsAttach.textContent = `${slug}`;
this.container.innerHTML = `${textHtml}`;
this.ref.appendChild(this.container);
this.registerCodeInputListener();
Expand Down
19 changes: 13 additions & 6 deletions vscode/media/command-deck/command-deck.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,19 @@ class CommandDeck {
this.ref.innerHTML = textContent.substring(0, atIndex) + textContent.substring(atIndex + 1);
}
if (option?.name.startsWith('@')) {
console.log('agents options', option?.metadata);
activeAgentAttach.style = "color: #497BEF; !important";
activeAgentAttach.textContent = `@${option?.metadata.display_name}`;

agentName = option?.metadata.display_name;
headerLogo.src = option.metadata.avatar_id;
headerText.classList.add("hidden");
headerAgentName.classList.remove("hidden");
headerAgentName.textContent = option?.metadata.display_name;
headerAgentDescription.classList.remove("hidden");
headerAgentDescription.textContent = option?.metadata.description;
activeAgent = true;
commandEnable = false;
activeCommandsAttach.style = "color: var(--vscode-input-placeholderForeground); !important";
activeCommandsAttach.textContent = "/";

currentActiveAgent = option.name;
this.closeMenu();
// Move the cursor to the end of the word
Expand All @@ -164,7 +171,7 @@ class CommandDeck {
setTimeout(() => {
adjustHeight();
commandEnable = true;
activeCommandsAttach.style = "color: rgb(236 72 153); !important";
// activeCommandsAttach.style = "color: rgb(236 72 153); !important";
}, 0);
}
};
Expand Down Expand Up @@ -247,10 +254,10 @@ class CommandDeck {
setTimeout(() => {
if (this.ref.textContent.trim() === "") {
commandEnable = false;
activeCommandsAttach.style = "color: var(--vscode-input-placeholderForeground); !important";
// activeCommandsAttach.style = "color: var(--vscode-input-placeholderForeground); !important";
agentInputsJson.length = 0;
codeInputId = 0;
activeCommandsAttach.textContent = "/";
// activeCommandsAttach.textContent = "/";
}
}, 0);
}
Expand Down
Loading