├── .github └── FUNDING.yml ├── WAGIapp ├── wwwroot │ ├── favicon.ico │ ├── icon-512.png │ ├── service-worker.js │ ├── manifest.json │ ├── Scripts.js │ ├── index.html │ ├── service-worker.published.js │ └── css │ │ └── app.css ├── Pages │ └── Index.razor ├── Components │ ├── ScriptButton.razor │ ├── SettingsButton.razor │ ├── Errors │ │ └── KeyErrorDialog.razor │ ├── ActionCard.razor │ ├── SettingsWindow.razor │ ├── Background.razor │ ├── Notes.razor │ ├── ScriptWindow.razor │ ├── ActionStack.razor │ └── StartStopAI.razor ├── AI │ ├── AICommands │ │ ├── Command.cs │ │ ├── NoActionCommand.cs │ │ ├── GoalReachedCommand.cs │ │ ├── AddNoteCommand.cs │ │ ├── RemoveLineCommand.cs │ │ ├── WriteLineCommand.cs │ │ ├── RemoveNoteCommand.cs │ │ └── SearchWebCommand.cs │ ├── LogAction.cs │ ├── ActionList.cs │ ├── Settings.cs │ ├── ScriptFile.cs │ ├── Commands.cs │ ├── Memory.cs │ ├── Texts.cs │ ├── OpenAI.cs │ ├── Utils.cs │ ├── LongTermMemory.cs │ └── Master.cs ├── _Imports.razor ├── MainLayout.razor ├── App.razor ├── WAGIapp.csproj └── Program.cs ├── LICENSE ├── WAGIapp.sln ├── README.md └── .gitignore /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: woltvint 2 | -------------------------------------------------------------------------------- /WAGIapp/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Woltvint/WAGI/HEAD/WAGIapp/wwwroot/favicon.ico -------------------------------------------------------------------------------- /WAGIapp/wwwroot/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Woltvint/WAGI/HEAD/WAGIapp/wwwroot/icon-512.png -------------------------------------------------------------------------------- /WAGIapp/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WAGIapp/wwwroot/service-worker.js: -------------------------------------------------------------------------------- 1 | // In development, always fetch from the network and do not enable offline support. 2 | // This is because caching would make development more difficult (changes would not 3 | // be reflected on the first load after each change). 4 | self.addEventListener('fetch', () => { }); 5 | -------------------------------------------------------------------------------- /WAGIapp/Components/ScriptButton.razor: -------------------------------------------------------------------------------- 1 | @inject IDialogService DialogService 2 | 3 | 4 | 5 | @code { 6 | private void OpenWindow() 7 | { 8 | DialogService.Show("Script Window", new DialogOptions() {CloseButton = true, MaxWidth = MaxWidth.ExtraLarge}); 9 | } 10 | } -------------------------------------------------------------------------------- /WAGIapp/Components/SettingsButton.razor: -------------------------------------------------------------------------------- 1 | @inject IDialogService DialogService 2 | 3 | 4 | 5 | @code { 6 | private void OpenWindow() 7 | { 8 | DialogService.Show("Settings Window", new DialogOptions() {CloseButton = true, MaxWidth = MaxWidth.Large}); 9 | } 10 | } -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/Command.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI.AICommands 2 | { 3 | internal abstract class Command 4 | { 5 | public abstract string Name { get; } 6 | public abstract string Description { get; } 7 | 8 | public abstract string Format { get; } 9 | 10 | public abstract Task Execute(Master caller, string[] args); 11 | 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WAGIapp/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Routing 4 | @using Microsoft.AspNetCore.Components.Web 5 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 6 | @using Microsoft.JSInterop 7 | @using WAGIapp 8 | @using WAGIapp.Components 9 | @using WAGIapp.Components.Errors 10 | @using WAGIapp.AI 11 | 12 | @using MudBlazor -------------------------------------------------------------------------------- /WAGIapp/wwwroot/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WAGI-app", 3 | "short_name": "WAGI-app", 4 | "start_url": "./", 5 | "display": "standalone", 6 | "background_color": "#ffffff", 7 | "theme_color": "#03173d", 8 | "prefer_related_applications": false, 9 | "icons": [ 10 | { 11 | "src": "icon-512.png", 12 | "type": "image/png", 13 | "sizes": "512x512" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /WAGIapp/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 4 | 5 | 6 | 7 | @Body 8 | 9 | @code { 10 | MudTheme CustomTheme = new MudTheme() 11 | { 12 | PaletteDark = new PaletteDark() 13 | { 14 | Background = "#1a1b1e", 15 | Surface = "#1a1b1e", 16 | } 17 | }; 18 | } -------------------------------------------------------------------------------- /WAGIapp/Components/Errors/KeyErrorDialog.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Wrong API key

5 |

Please make sure the OpenAI API key is set correctly in the settings

6 |
7 |
8 |
9 |
10 | 11 | @code { 12 | [CascadingParameter] MudDialogInstance MudDialog { get; set; } 13 | 14 | void Close() => MudDialog.Close(DialogResult.Ok(true)); 15 | } -------------------------------------------------------------------------------- /WAGIapp/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /WAGIapp/AI/LogAction.cs: -------------------------------------------------------------------------------- 1 | using MudBlazor; 2 | 3 | namespace WAGIapp.AI 4 | { 5 | public class LogAction 6 | { 7 | public string Title { get; set; } = ""; 8 | public string Icon { get; set; } = ""; 9 | public string Text { get; set; } = ""; 10 | public bool Last { get; set; } = false; 11 | 12 | public const string InfoIcon = Icons.Material.Filled.Info; 13 | public const string MemoryIcon = Icons.Material.Filled.Memory; 14 | public const string ThinkIcon = Icons.Material.Filled.Psychology; 15 | public const string CommandIcon = Icons.Material.Filled.Terminal; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WAGIapp/Components/ActionCard.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @if (action.Last && !Master.Singleton.Done) 4 | { 5 | 6 | } 7 | else 8 | { 9 | 10 | } 11 |

@action.Title

12 |
13 |

14 | @action.Text 15 |

16 |
17 | 18 | @code { 19 | [Parameter] 20 | public LogAction action { get; set; } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/NoActionCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography.X509Certificates; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace WAGIapp.AI.AICommands 9 | { 10 | internal class NoActionCommand : Command 11 | { 12 | public override string Name => "no-action"; 13 | 14 | public override string Description => "does nothing"; 15 | 16 | public override string Format => "no-action"; 17 | 18 | public override async Task Execute(Master caller, string[] args) 19 | { 20 | return "command did nothing"; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/GoalReachedCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WAGIapp.AI.AICommands 8 | { 9 | internal class GoalReachedCommand : Command 10 | { 11 | public override string Name => "goal-reached"; 12 | 13 | public override string Description => "Command that you must call when you reach the main goal"; 14 | 15 | public override string Format => "goal-reached"; 16 | 17 | public override async Task Execute(Master caller, string[] args) 18 | { 19 | caller.Done = true; 20 | return "done."; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WAGIapp/Components/SettingsWindow.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 |
10 |
11 | 12 | @code { 13 | [CascadingParameter] MudDialogInstance MudDialog { get; set; } 14 | 15 | void Close() => MudDialog.Close(DialogResult.Ok(true)); 16 | } -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/AddNoteCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WAGIapp.AI.AICommands 8 | { 9 | internal class AddNoteCommand : Command 10 | { 11 | public override string Name => "add-note"; 12 | 13 | public override string Description => "Adds a note to the list"; 14 | 15 | public override string Format => "add-note | text to add to the list"; 16 | 17 | public override async Task Execute(Master caller, string[] args) 18 | { 19 | if (args.Length < 2) 20 | return "error! not enough parameters"; 21 | 22 | caller.Notes.Add(args[1]); 23 | 24 | return "Note added"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /WAGIapp/Components/Background.razor: -------------------------------------------------------------------------------- 1 | @using WAGIapp.AI; 2 | @inject IJSRuntime JS 3 | 4 |
5 | 6 | @code { 7 | protected override void OnAfterRender(bool firstRender) 8 | { 9 | if (!firstRender) 10 | return; 11 | 12 | 13 | //JS.InvokeVoidAsync("console.log", "hewo"); 14 | JS.InvokeVoidAsync("inicGraph"); 15 | 16 | Task.Run(async () => 17 | { 18 | while (true) 19 | { 20 | await Task.Delay(1000); 21 | JS.InvokeVoidAsync("resizeGraph"); 22 | 23 | if (Master.Singleton.Memory.MemoryChanged) 24 | JS.InvokeVoidAsync("setGraphData",Master.Singleton.Memory.GetGraphData()); 25 | } 26 | }); 27 | } 28 | } -------------------------------------------------------------------------------- /WAGIapp/Components/Notes.razor: -------------------------------------------------------------------------------- 1 | 2 | @if (showNotes) 3 | { 4 | 5 | @foreach (var note in Master.Singleton.FormatedNotes.Split("\n")) 6 | { 7 |

@note

8 | } 9 |
10 | } 11 | 12 | @code { 13 | private bool showNotes = true; 14 | } 15 | 16 | @code { 17 | protected override void OnAfterRender(bool firstRender) 18 | { 19 | if (!firstRender) 20 | return; 21 | 22 | Task.Run(async () => 23 | { 24 | while (true) 25 | { 26 | await Task.Delay(1000); 27 | StateHasChanged(); 28 | } 29 | }); 30 | } 31 | } -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/RemoveLineCommand.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI.AICommands 2 | { 3 | internal class RemoveLineCommand : Command 4 | { 5 | public override string Name => "remove-line"; 6 | 7 | public override string Description => "deletes a line from the script"; 8 | 9 | public override string Format => "remove-line | line number"; 10 | 11 | public override async Task Execute(Master caller, string[] args) 12 | { 13 | if (args.Length < 2) 14 | return "error! not enough parameters"; 15 | 16 | int line; 17 | 18 | try 19 | { 20 | line = Convert.ToInt32(args[1]); 21 | } 22 | catch (Exception) 23 | { 24 | return "error! given line number is not a number"; 25 | } 26 | 27 | return caller.scriptFile.RemoveLine(line); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WAGIapp/Components/ScriptWindow.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
9 | 10 | @code { 11 | [CascadingParameter] MudDialogInstance MudDialog { get; set; } 12 | 13 | string Code = ""; 14 | 15 | void Close() => MudDialog.Close(DialogResult.Ok(true)); 16 | 17 | protected override void OnAfterRender(bool firstRender) 18 | { 19 | if (!firstRender) 20 | return; 21 | 22 | Task.Run(async () => 23 | { 24 | while (true) 25 | { 26 | Code = Master.Singleton.scriptFile.GetText(); 27 | StateHasChanged(); 28 | await Task.Delay(1000); 29 | } 30 | }); 31 | } 32 | } -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/WriteLineCommand.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI.AICommands 2 | { 3 | internal class WriteLineCommand : Command 4 | { 5 | public override string Name => "write-line"; 6 | 7 | public override string Description => "writes the given text to the line number"; 8 | 9 | public override string Format => "write-line | line number | text"; 10 | 11 | public override async Task Execute(Master caller, string[] args) 12 | { 13 | if (args.Length < 3) 14 | return "error! not enough parameters"; 15 | 16 | int line; 17 | 18 | try 19 | { 20 | line = Convert.ToInt32(args[1]); 21 | } 22 | catch (Exception) 23 | { 24 | return "error! given line number is not a number"; 25 | } 26 | 27 | return caller.scriptFile.WriteLine(line, args[2]); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WAGIapp/WAGIapp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | service-worker-assets.js 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /WAGIapp/Components/ActionStack.razor: -------------------------------------------------------------------------------- 1 | @inject IJSRuntime JS 2 | 3 | 4 | @if (showStack) 5 | { 6 | 7 | @foreach (var action in Master.Singleton.Actions.GetActions()) 8 | { 9 | 10 | } 11 | 12 | } 13 | 14 | 15 | 16 | @code { 17 | private bool showStack = true; 18 | } 19 | 20 | @code { 21 | protected override void OnAfterRender(bool firstRender) 22 | { 23 | if (!firstRender) 24 | return; 25 | 26 | Task.Run(async () => 27 | { 28 | while (true) 29 | { 30 | await Task.Delay(500); 31 | StateHasChanged(); 32 | } 33 | }); 34 | } 35 | } -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/RemoveNoteCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WAGIapp.AI.AICommands 8 | { 9 | internal class RemoveNoteCommand : Command 10 | { 11 | public override string Name => "remove-note"; 12 | 13 | public override string Description => "Removes a note from the list"; 14 | 15 | public override string Format => "remove-note | number of the note to remove"; 16 | 17 | public override async Task Execute(Master caller, string[] args) 18 | { 19 | if (args.Length < 2) 20 | return "error! not enough parameters"; 21 | 22 | if (!int.TryParse(args[1], out int number)) 23 | return "error! number could not be parsed"; 24 | 25 | if (number - 1 >= caller.Notes.Count) 26 | return "error! number out of range"; 27 | 28 | caller.Notes.RemoveAt(number - 1); 29 | 30 | return $"Note {number} removed"; 31 | 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /WAGIapp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WAGIapp", "WAGIapp\WAGIapp.csproj", "{1DFE72C2-BF6E-45E9-9B7B-6BA17D884D24}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1DFE72C2-BF6E-45E9-9B7B-6BA17D884D24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1DFE72C2-BF6E-45E9-9B7B-6BA17D884D24}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1DFE72C2-BF6E-45E9-9B7B-6BA17D884D24}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1DFE72C2-BF6E-45E9-9B7B-6BA17D884D24}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {35EE9DFB-01D8-4B06-858C-73C58519C28A} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /WAGIapp/AI/ActionList.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI 2 | { 3 | public class ActionList 4 | { 5 | private readonly object dataLock = new object(); 6 | 7 | private List Actions; 8 | private int MaxActions; 9 | 10 | public ActionList(int maxActions) 11 | { 12 | Actions = new List(); 13 | MaxActions = maxActions; 14 | } 15 | 16 | public LogAction AddAction(string action, string icon = LogAction.InfoIcon) 17 | { 18 | LogAction a = new LogAction() { Title = action, Icon = icon }; 19 | 20 | lock (dataLock) 21 | { 22 | Actions.Add(a); 23 | 24 | if (Actions.Count >= MaxActions) 25 | Actions.RemoveAt(0); 26 | } 27 | 28 | return a; 29 | } 30 | 31 | public List GetActions() 32 | { 33 | foreach (var action in Actions) 34 | { 35 | action.Last = false; 36 | } 37 | 38 | if (Actions.Count > 0) 39 | Actions.Last().Last = true; 40 | 41 | return Actions.ToList(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /WAGIapp/wwwroot/Scripts.js: -------------------------------------------------------------------------------- 1 | const Graph = ForceGraph(); 2 | 3 | function inicGraph() { 4 | console.log("inic start"); 5 | 6 | const N = 10; 7 | const gData = { 8 | nodes: [...Array(N).keys()].map(i => ({ id: i, label: "hewo" })), 9 | links: [...Array(N).keys()] 10 | .filter(id => id) 11 | .map(id => ({ 12 | source: id, 13 | target: Math.round(Math.random() * (id - 1)) 14 | })) 15 | }; 16 | 17 | 18 | Graph(document.getElementById('graph')); 19 | Graph.nodeLabel('text'); 20 | Graph.linkWidth("width"); 21 | Graph.linkLabel('label'); 22 | Graph.nodeColor("color"); 23 | Graph.graphData(gData); 24 | 25 | console.log("inic end"); 26 | } 27 | 28 | function resizeGraph() { 29 | Graph.zoomToFit(1000, 100); 30 | 31 | 32 | Graph.enableNodeDrag(false); 33 | Graph.enableZoomInteraction(false); 34 | Graph.enablePanInteraction(false); 35 | } 36 | 37 | function setGraphData(data) 38 | { 39 | console.log(data); 40 | Graph.graphData(data); 41 | } 42 | 43 | function scrollToEnd(id) 44 | { 45 | var objDiv = document.getElementById(id); 46 | objDiv.scrollTop = objDiv.scrollHeight; 47 | } -------------------------------------------------------------------------------- /WAGIapp/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | WAGIapp 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 |
Loading...
22 | 23 |
24 | An unhandled error has occurred. 25 | Reload 26 | 🗙 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /WAGIapp/Components/StartStopAI.razor: -------------------------------------------------------------------------------- 1 | @inject IDialogService DialogService 2 | 3 | 8 | 9 | @code { 10 | protected override void OnAfterRender(bool firstRender) 11 | { 12 | if (!Settings.OpenAIApiKey.StartsWith("sk-") && !Master.Singleton.Done) 13 | { 14 | DialogService.Show("Error", new DialogOptions() { CloseButton = true }); 15 | Master.Singleton.Done = true; 16 | } 17 | 18 | if (!firstRender) 19 | return; 20 | 21 | Task.Run(async () => 22 | { 23 | while (true) 24 | { 25 | await Task.Delay(1000); 26 | StateHasChanged(); 27 | } 28 | }); 29 | } 30 | 31 | private void Click() 32 | { 33 | if (Settings.OpenAIApiKey.StartsWith("sk-")) 34 | Master.Singleton.Done = !Master.Singleton.Done; 35 | else 36 | DialogService.Show("Error", new DialogOptions() { CloseButton = true }); 37 | } 38 | } -------------------------------------------------------------------------------- /WAGIapp/AI/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI 2 | { 3 | internal static class Settings 4 | { 5 | public static string OpenAIApiKey = ""; 6 | public static string Rules = "" + 7 | "The basic info\n" + 8 | "1. You are now an autonomous AI\n" + 9 | "3. You can use the commands given above, but only one command at a time\n" + 10 | "4. You have memory and can remember things you already thought about\n" + 11 | "5. You have a script file you can write to using commands given above\n" + 12 | "6. You have a notepad you can write things you want to using given commands\n" + 13 | 14 | "\n" + 15 | "Here are the rules you must follow\n" + 16 | "1. You can only respond in the specified output format\n" + 17 | "2. Only call one command at the time\n" + 18 | "3. Call the goal-reached command as soon as you finish the main goal\n"; 19 | 20 | public static string Goal = "1. Write me a javascript script into your script file that will compute the digits of pi and write them out one by one into the console\n2. Comment and edit the script file to make it more readable\n3. recheck the code before you call goal-reached"; 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WAGIapp/AI/ScriptFile.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI 2 | { 3 | public class ScriptFile 4 | { 5 | public List Lines { get; set; } 6 | 7 | public ScriptFile() 8 | { 9 | Lines = new List(); 10 | 11 | for (int i = 0; i < 21; i++) 12 | Lines.Add(string.Empty); 13 | } 14 | 15 | public string GetText() 16 | { 17 | string output = ""; 18 | 19 | for (int i = 0; i < Lines.Count; i++) 20 | { 21 | output += i.ToString("D2") + " | " + Lines[i] + "\n"; 22 | } 23 | 24 | return output; 25 | } 26 | 27 | 28 | public string WriteLine(int line, string text) 29 | { 30 | for (int i = 0; i < 100; i++) 31 | { 32 | if (line <= Lines.Count) 33 | break; 34 | 35 | Lines.Add(""); 36 | } 37 | 38 | 39 | string[] lines = text.Split('\n'); 40 | 41 | if (line == Lines.Count) 42 | Lines.Add(lines[0]); 43 | else 44 | Lines[line] = lines[0]; 45 | 46 | if (lines.Length != 1) 47 | { 48 | for (int i = 1; i < lines.Length; i++) 49 | { 50 | if (line + i == Lines.Count) 51 | Lines.Add(lines[i]); 52 | else 53 | Lines.Insert(line + i, lines[i]); 54 | } 55 | } 56 | 57 | return "Line written"; 58 | } 59 | 60 | public string RemoveLine(int line) 61 | { 62 | if (line >= Lines.Count) 63 | return "error! line outside of bounds"; 64 | 65 | Lines.RemoveAt(line); 66 | 67 | return "Line removed"; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /WAGIapp/AI/Commands.cs: -------------------------------------------------------------------------------- 1 | using WAGIapp.AI.AICommands; 2 | 3 | namespace WAGIapp.AI 4 | { 5 | internal class Commands 6 | { 7 | private static Dictionary commands; 8 | static Commands() 9 | { 10 | commands = new Dictionary(); 11 | 12 | Command c; 13 | 14 | c = new NoActionCommand(); 15 | commands.Add(c.Name, c); 16 | c = new GoalReachedCommand(); 17 | commands.Add(c.Name, c); 18 | c = new AddNoteCommand(); 19 | commands.Add(c.Name, c); 20 | c = new RemoveNoteCommand(); 21 | commands.Add(c.Name, c); 22 | c = new SearchWebCommand(); 23 | commands.Add(c.Name, c); 24 | c = new RemoveLineCommand(); 25 | commands.Add(c.Name, c); 26 | c = new WriteLineCommand(); 27 | commands.Add(c.Name, c); 28 | 29 | } 30 | 31 | 32 | public static string GetCommands() 33 | { 34 | string output = ""; 35 | 36 | foreach (Command c in commands.Values) 37 | { 38 | output += c.Name + "\n"; 39 | output += "\t" + c.Description + "\n"; 40 | output += "\t" + "Call format: " + c.Format + "\n"; 41 | } 42 | 43 | return output; 44 | } 45 | 46 | public static async Task TryToRun(Master caller, string commandText) 47 | { 48 | string[] args = commandText.Split("|"); 49 | 50 | for (int i = 0; i < args.Length; i++) 51 | { 52 | args[i] = args[i].Trim(); 53 | } 54 | 55 | args[0] = args[0].ToLower(); 56 | 57 | caller.Actions.AddAction("Running cmd: " + args[0], LogAction.CommandIcon); 58 | 59 | if (!commands.ContainsKey(args[0])) 60 | return "error! command not found"; 61 | 62 | return await commands[args[0]].Execute(caller, args); 63 | } 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WAGI 2 | 3 | 4 | https://user-images.githubusercontent.com/43929136/235311140-554f0145-d0d8-4dd4-bae8-34a35cceb545.mp4 5 | 6 | 7 | WAGI is a hobby project focused on creating an AutoGPT web app. 8 | The project is in early development and is being worked on in leftover time, so I am sorry in advance for the code quality :) 9 | [Demo](https://wagi.woltvint.net) 10 | 11 | ## Features 12 | 13 | - a web app for monitoring the agent 14 | - chatGPT based agent 15 | - chatGPT-powered long-term memory system (with a graph to display it) 16 | - limited web search using duckduckgo 17 | - stopping when a goal is reached 18 | - a code window the AI can write into 19 | 20 | ## Planned Features 21 | 22 | - access to websites with an URL 23 | - gpt-4 support 24 | - state export & import (or saving to web storage) 25 | - spawning sub-agents to perform other tasks 26 | - shell commands using ssh 27 | - custom commands written by the AI itself for itself at runtime 28 | - user input (or prompts from the AI for the user) 29 | - simulated file system 30 | - full agent input customization in the UI 31 | 32 | 33 | ## Demo 34 | 35 | A demo of this app is available [here](https://wagi.woltvint.net) 36 | 37 | to use it you just have to enter the OpenAI API key in the settings, edit the goal, and press the play button 38 | 39 | 40 | 41 | 42 | https://user-images.githubusercontent.com/43929136/236652342-f67cf8df-0da2-4626-942e-5fdb27627f66.mp4 43 | 44 | code writing (sped up) 45 | 46 | 47 | 48 | ## Contributing 49 | 50 | Any pull requests with fixes or upgrades are welcome, but please keep in mind that it can take a while until they are accepted. 51 | 52 | The same goes for bugs or ideas, if you found a bug or have an idea to make the app better please create an issue and describe it there. 53 | 54 | ## Support 55 | 56 | If you want to support the project you are welcome to: 57 | 58 | Buy Me A Coffee 59 | -------------------------------------------------------------------------------- /WAGIapp/wwwroot/service-worker.published.js: -------------------------------------------------------------------------------- 1 | // Caution! Be sure you understand the caveats before publishing an application with 2 | // offline support. See https://aka.ms/blazor-offline-considerations 3 | 4 | self.importScripts('./service-worker-assets.js'); 5 | self.addEventListener('install', event => event.waitUntil(onInstall(event))); 6 | self.addEventListener('activate', event => event.waitUntil(onActivate(event))); 7 | self.addEventListener('fetch', event => event.respondWith(onFetch(event))); 8 | 9 | const cacheNamePrefix = 'offline-cache-'; 10 | const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; 11 | const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; 12 | const offlineAssetsExclude = [ /^service-worker\.js$/ ]; 13 | 14 | async function onInstall(event) { 15 | console.info('Service worker: Install'); 16 | 17 | // Fetch and cache all matching items from the assets manifest 18 | const assetsRequests = self.assetsManifest.assets 19 | .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))) 20 | .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))) 21 | .map(asset => new Request(asset.url, { integrity: asset.hash, cache: 'no-cache' })); 22 | await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); 23 | } 24 | 25 | async function onActivate(event) { 26 | console.info('Service worker: Activate'); 27 | 28 | // Delete unused caches 29 | const cacheKeys = await caches.keys(); 30 | await Promise.all(cacheKeys 31 | .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName) 32 | .map(key => caches.delete(key))); 33 | } 34 | 35 | async function onFetch(event) { 36 | let cachedResponse = null; 37 | if (event.request.method === 'GET') { 38 | // For all navigation requests, try to serve index.html from cache 39 | const shouldServeIndexHtml = event.request.mode === 'navigate'; 40 | 41 | const request = shouldServeIndexHtml ? 'index.html' : event.request; 42 | const cache = await caches.open(cacheName); 43 | cachedResponse = await cache.match(request); 44 | } 45 | 46 | return cachedResponse || fetch(event.request); 47 | } 48 | -------------------------------------------------------------------------------- /WAGIapp/AI/Memory.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI 2 | { 3 | internal class Memory 4 | { 5 | public string Content { get; private set; } 6 | public HashSet Tags { get; private set; } 7 | public int Remembered { get; set; } 8 | 9 | public Memory(string content, HashSet tags) 10 | { 11 | Content = content; 12 | Tags = tags; 13 | Remembered = 0; 14 | } 15 | 16 | public Memory(OutputMemoryAI m) 17 | { 18 | Content = m.content; 19 | Tags = Utils.CleanInput(m.tags.Split(",")).ToHashSet(); 20 | } 21 | 22 | public int GetScore(HashSet tags) 23 | { 24 | int output = 0; 25 | foreach (string tag in tags) 26 | { 27 | if (Tags.Contains(tag)) 28 | output++; 29 | } 30 | 31 | return output; 32 | } 33 | 34 | public string GetCommonTag(HashSet tags) 35 | { 36 | foreach (string tag in tags) 37 | { 38 | if (Tags.Contains(tag)) 39 | return tag; 40 | } 41 | 42 | return ""; 43 | } 44 | 45 | public override string ToString() 46 | { 47 | return Content; 48 | } 49 | 50 | } 51 | 52 | internal struct OutputMemoryAI 53 | { 54 | public string tags { get; set; } 55 | public string content { get; set; } 56 | } 57 | 58 | internal struct OutputMemoryTagsJson 59 | { 60 | public string tags { get; set; } 61 | } 62 | 63 | internal struct GraphMemoryData 64 | { 65 | public List nodes { get; set; } 66 | public List links { get; set; } 67 | 68 | public GraphMemoryData() 69 | { 70 | nodes = new List(); 71 | links = new List(); 72 | } 73 | } 74 | 75 | internal struct GraphMemoryNode 76 | { 77 | public int id { get; set; } 78 | public string name { get; set; } 79 | public string text { get; set; } 80 | public string color { get; set; } 81 | } 82 | 83 | internal struct GraphMemoryLink 84 | { 85 | public string label { get; set; } 86 | public int width { get; set; } 87 | public int source { get; set; } 88 | public int target { get; set; } 89 | } 90 | } -------------------------------------------------------------------------------- /WAGIapp/AI/Texts.cs: -------------------------------------------------------------------------------- 1 | namespace WAGIapp.AI 2 | { 3 | public static class Texts 4 | { 5 | 6 | public static ChatMessage MasterStartText => new(ChatRole.System, Settings.Rules); 7 | 8 | public static ChatMessage MasterOutputFormat = new ChatMessage( 9 | ChatRole.System, 10 | "only reply in this json format" + 11 | "Output format:" + 12 | "{" + 13 | "\"thoughts\": \"your thoughts\"" + 14 | "\"command\": \"command you want to execute in the format specified for that command\"" + 15 | "}" + 16 | ""); 17 | 18 | public static ChatMessage ShortTermMemoryAddPrompt = new ChatMessage( 19 | ChatRole.System, 20 | "You are the memory of an AI.\n" + 21 | "Your job is to look at a piece of text and create a memory from it\n" + 22 | "The memory should be helpful for the AI that will remember it in the future\n" + 23 | "The memory should be up to 100 words long, but can be shorter\n" + 24 | "The memory should be in a form of a fact that the AI can understand without any additional context\n" + 25 | "With the memory you also need to provide between 10 to 40 tags that will help search for it later\n" + 26 | "There is a list of tags you can use, but you can also create new ones if none of them are aplicable\n" + 27 | "The tags should be relevant to the memory so the AI can later remember it by them\n" + 28 | ""); 29 | 30 | public static ChatMessage ShortTermMemoryAddFormat = new ChatMessage( 31 | ChatRole.System, 32 | "You must only output the memory in this json format\n" + 33 | "{\n" + 34 | "\"tags\": \"a list of 5-40 single word tags separated by a comma\"\n" + 35 | "\"content\": \"the text of the memory\"\n" + 36 | "}\n" + 37 | ""); 38 | 39 | public static ChatMessage ShortTermMemoryGetPrompt = new ChatMessage( 40 | ChatRole.System, 41 | "You are the memory of an AI.\n" + 42 | "Your job is to look at the input the AI will receive and select tags that it should use to search the memory from the list\n" + 43 | "You should always try to select the most relevant tags\n" + 44 | "You should only choose tags that you are given in the Available tags:\n" + 45 | "You should always output 5 to 20 tags\n" + 46 | ""); 47 | 48 | public static ChatMessage ShortTermMemoryGetFormat = new ChatMessage( 49 | ChatRole.System, 50 | "You must only output the memory in this json format\n" + 51 | "{\n" + 52 | "\"tags\": \"a list of 5-20 single word tags separated by a comma\"\n" + 53 | "}\n" + 54 | ""); 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /WAGIapp/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.Web; 2 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 3 | using Microsoft.AspNetCore.Cors.Infrastructure; 4 | 5 | using WAGIapp; 6 | 7 | using MudBlazor.Services; 8 | using WAGIapp.AI; 9 | 10 | using System; 11 | using System.Threading; 12 | using System.Runtime.Versioning; 13 | using System.Runtime.InteropServices.JavaScript; 14 | using System.Net.Http; 15 | 16 | [assembly: SupportedOSPlatform("browser")] 17 | 18 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 19 | builder.RootComponents.Add("#app"); 20 | builder.RootComponents.Add("head::after"); 21 | 22 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 23 | 24 | builder.Services.AddMudServices(); 25 | /* 26 | builder.Services.AddCors(options => 27 | { 28 | options.AddDefaultPolicy( 29 | policy => 30 | { 31 | policy.AllowAnyHeader(); //set the allowed origin 32 | policy.AllowAnyMethod(); 33 | policy.AllowAnyOrigin(); 34 | }); 35 | });*/ 36 | 37 | /* 38 | Master.Singleton.Actions.AddAction("Thinking", LogAction.ThinkIcon); 39 | Master.Singleton.Actions.AddAction("Creating a memory", LogAction.MemoryIcon); 40 | Master.Singleton.Actions.AddAction("Hello there"); 41 | */ 42 | 43 | 44 | Task.Run(async () => 45 | { 46 | while (true) 47 | { 48 | await Task.Delay(10000); 49 | await Master.Singleton.Tick(); 50 | /*switch (Random.Shared.Next(0,6)) 51 | { 52 | case 0: 53 | var a = Master.Singleton.Actions.AddAction("Thinking", LogAction.ThinkIcon); 54 | await Task.Delay(4000); 55 | a.Text = "testing text is cool and all but does the transition finally work of what? im quite tired of waiting for it to start working .. i would love to get to other things and stop obsesing about this."; 56 | break; 57 | case 1: 58 | Master.Singleton.Actions.AddAction("Creating a memory", LogAction.MemoryIcon); 59 | break; 60 | case 2: 61 | Master.Singleton.Actions.AddAction("Hello there"); 62 | break; 63 | case 3: 64 | Master.Singleton.Notes.Add("Notes are cool and its cool i can show them!"); 65 | break; 66 | case 4: 67 | Master.Singleton.Notes.Add("Notes are cool and its\ncool i can show them!"); 68 | break; 69 | case 5: 70 | Master.Singleton.Notes.Add("Notes are cool and its cool i can show them! but what if they are looooong as fuck .. will the ui manage or will it breaky?"); 71 | break; 72 | 73 | }*/ 74 | 75 | 76 | 77 | } 78 | }).ConfigureAwait(true); 79 | 80 | 81 | 82 | await builder.Build().RunAsync(); 83 | -------------------------------------------------------------------------------- /WAGIapp/AI/OpenAI.cs: -------------------------------------------------------------------------------- 1 | /*using OpenAI.Chat; 2 | using OpenAI.Models; 3 | using OpenAI;*/ 4 | 5 | using System.Net.Http.Headers; 6 | using System.Text.Json; 7 | 8 | namespace WAGIapp.AI 9 | { 10 | internal class OpenAI 11 | { 12 | public static async Task GetChatCompletion(string model, List messages, int maxTokens = 8192) 13 | { 14 | 15 | ChatRequest req = new ChatRequest() { messages = messages, model = model }; 16 | ChatResponse res; 17 | 18 | 19 | var client = new HttpClient(); 20 | var request = new HttpRequestMessage 21 | { 22 | Method = HttpMethod.Post, 23 | RequestUri = new Uri("https://api.openai.com/v1/chat/completions"), 24 | Headers = 25 | { 26 | { "User-Agent", "WAGIapp" }, 27 | { "Authorization", "Bearer " + Settings.OpenAIApiKey }, 28 | }, 29 | 30 | Content = new StringContent(JsonSerializer.Serialize(req)) 31 | { 32 | Headers = 33 | { 34 | ContentType = new MediaTypeHeaderValue("application/json") 35 | } 36 | } 37 | }; 38 | using (var response = await client.SendAsync(request)) 39 | { 40 | response.EnsureSuccessStatusCode(); 41 | var body = await response.Content.ReadAsStringAsync(); 42 | res = JsonSerializer.Deserialize(body); 43 | } 44 | 45 | 46 | 47 | return res.choices.First().message.content; 48 | } 49 | } 50 | 51 | public struct ChatRequest 52 | { 53 | public string model { get; set; } 54 | public List messages { get; set; } 55 | } 56 | 57 | public struct ChatResponse 58 | { 59 | public string id { get; set; } 60 | public List choices { get; set; } 61 | } 62 | 63 | public struct ChatChoice 64 | { 65 | public ChatMessage message { get; set; } 66 | public string finish_reason { get; set; } 67 | public int index { get; set; } 68 | } 69 | 70 | public struct ChatMessage 71 | { 72 | public string role { get; set; } 73 | public string content { get; set; } 74 | 75 | public ChatMessage(string _role, string _content) 76 | { 77 | role = _role; 78 | content = _content; 79 | } 80 | } 81 | 82 | public static class ChatRole 83 | { 84 | public static string System => "system"; 85 | public static string User => "user"; 86 | public static string Assistant => "assistant"; 87 | } 88 | 89 | public static class ChatModel 90 | { 91 | public static string ChatGPT => "gpt-3.5-turbo"; 92 | } 93 | } -------------------------------------------------------------------------------- /WAGIapp/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | h1:focus { 2 | outline: none; 3 | } 4 | 5 | #blazor-error-ui { 6 | background: lightyellow; 7 | bottom: 0; 8 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 9 | display: none; 10 | left: 0; 11 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 12 | position: fixed; 13 | width: 100%; 14 | z-index: 1000; 15 | } 16 | 17 | #blazor-error-ui .dismiss { 18 | cursor: pointer; 19 | position: absolute; 20 | right: 0.75rem; 21 | top: 0.5rem; 22 | } 23 | 24 | .blazor-error-boundary { 25 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; 26 | padding: 1rem 1rem 1rem 3.7rem; 27 | color: white; 28 | } 29 | 30 | .blazor-error-boundary::after { 31 | content: "An error has occurred." 32 | } 33 | 34 | 35 | .actionStack { 36 | /*--mask: linear-gradient(to top, rgba(0,0,0, 1) 0, rgba(0,0,0, 1) 40%, rgba(0,0,0, 0) 95%, rgba(0,0,0, 0) 0 ) 100% 50% / 100% 100% repeat-x;*/ 37 | /*border: 1px #d8d8d8 dashed;*/ 38 | /*font: 2em/1.6em Arial;*/ 39 | -webkit-mask: linear-gradient(to top, rgba(0,0,0, 1) 0, rgba(0,0,0, 1) 40%, rgba(0,0,0, 0) 95%, rgba(0,0,0, 0) 0 ) 100% 50% / 100% 100% repeat-x; 40 | mask: linear-gradient(to top, rgba(0,0,0, 1) 0, rgba(0,0,0, 1) 40%, rgba(0,0,0, 0) 95%, rgba(0,0,0, 0) 0 ) 100% 50% / 100% 100% repeat-x; 41 | } -------------------------------------------------------------------------------- /WAGIapp/AI/Utils.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | using System.Text.RegularExpressions; 3 | using System.Web; 4 | using System; 5 | using Microsoft.Extensions.Options; 6 | using Microsoft.AspNetCore.Components.WebAssembly.Http; 7 | 8 | namespace WAGIapp.AI 9 | { 10 | internal class Utils 11 | { 12 | public static string ExtractJson(string input) 13 | { 14 | input = input.Replace("\"\n", "\",\n"); 15 | 16 | int firstBracket = input.IndexOf("{"); 17 | int lastBracket = input.LastIndexOf("}"); 18 | 19 | if (firstBracket < 0) 20 | { 21 | Console.WriteLine("Json extraction failed: missing '{'"); 22 | return ""; 23 | } 24 | 25 | if (lastBracket < 0) 26 | { 27 | Console.WriteLine("Json extraction failed: missing '}'"); 28 | return ""; 29 | } 30 | 31 | return input.Substring(firstBracket, lastBracket - firstBracket + 1); 32 | } 33 | 34 | public static T? GetObjectFromJson(string json) 35 | { 36 | return JsonSerializer.Deserialize(ExtractJson(json), new JsonSerializerOptions() 37 | { 38 | AllowTrailingCommas = true, 39 | }); 40 | } 41 | 42 | public static IEnumerable CleanInput(IEnumerable input) 43 | { 44 | var list = input.ToArray(); 45 | 46 | for (int i = 0; i < list.Length; i++) 47 | { 48 | list[i] = list[i].Trim(); 49 | list[i] = list[i].ToLower(); 50 | } 51 | 52 | return list; 53 | } 54 | 55 | public static async Task WebResult(string url, bool corsProxy = false) 56 | { 57 | try 58 | { 59 | var client = new HttpClient(); 60 | 61 | var request = new HttpRequestMessage 62 | { 63 | Method = HttpMethod.Get, 64 | RequestUri = new Uri((corsProxy ? "https://wapi.woltvint.net/cors-proxy?url=" : "") + url), 65 | }; 66 | 67 | using (var response = await client.SendAsync(request)) 68 | { 69 | response.EnsureSuccessStatusCode(); 70 | var body = await response.Content.ReadAsStringAsync(); 71 | return body; 72 | } 73 | } 74 | catch (Exception) 75 | { 76 | return "Web request failed"; 77 | } 78 | } 79 | 80 | 81 | public static string CleanHtmlInput(string input) 82 | { 83 | string output = input; 84 | 85 | output = HttpUtility.HtmlDecode(output); 86 | output = Regex.Replace(output, "<[^>]*>", " ", RegexOptions.ExplicitCapture); 87 | output = output.Trim(); 88 | 89 | return output; 90 | } 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /WAGIapp/AI/AICommands/SearchWebCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WAGIapp.AI.AICommands 8 | { 9 | internal class SearchWebCommand : Command 10 | { 11 | public override string Name => "search-web"; 12 | 13 | public override string Description => "Searches the web and returns a list of links and descriptions"; 14 | 15 | public override string Format => "search-web | querry"; 16 | 17 | public override async Task Execute(Master caller, string[] args) 18 | { 19 | if (args.Length < 2) 20 | return "error! not enough parameters"; 21 | 22 | string web = await Utils.WebResult("https://html.duckduckgo.com/html/?q=" + args[1],true); 23 | 24 | List headers = new List(); 25 | List urls = new List(); 26 | List descritpions = new List(); 27 | 28 | int i = 0; 29 | while (true) 30 | { 31 | int tagStart = web.IndexOf("", tagStart); 37 | 38 | int blockEnd = web.IndexOf("", tagEnd); 39 | 40 | headers.Add(web.Substring(tagEnd + 1, blockEnd - tagEnd - 1)); 41 | 42 | i = blockEnd; 43 | } 44 | 45 | 46 | i = 0; 47 | while (true) 48 | { 49 | int tagStart = web.IndexOf("", tagStart); 55 | 56 | int blockEnd = web.IndexOf("", tagEnd); 57 | 58 | urls.Add(web.Substring(tagEnd + 1, blockEnd - tagEnd - 1)); 59 | 60 | i = blockEnd; 61 | } 62 | 63 | 64 | i = 0; 65 | while (true) 66 | { 67 | int tagStart = web.IndexOf("", tagStart); 73 | 74 | int blockEnd = web.IndexOf("", tagEnd); 75 | 76 | descritpions.Add(web.Substring(tagEnd + 1, blockEnd - tagEnd - 1)); 77 | 78 | i = blockEnd; 79 | } 80 | 81 | string output = ""; 82 | 83 | for (int j = 0; j < headers.Count; j++) 84 | { 85 | headers[j] = Utils.CleanHtmlInput(headers[j]); 86 | urls[j] = Utils.CleanHtmlInput(urls[j]); 87 | descritpions[j] = Utils.CleanHtmlInput(descritpions[j]); 88 | } 89 | 90 | i = 0; 91 | while (output.Split(" ").Length < 800 && i < headers.Count) 92 | { 93 | output += (i + 1) + ". " + headers[i] + "\n"; 94 | output += "[" + urls[i] + "]\n"; 95 | output += descritpions[i] + "\n\n"; 96 | i++; 97 | } 98 | 99 | return output; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /WAGIapp/AI/LongTermMemory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WAGIapp.AI; 3 | 4 | namespace WAGIapp.AI 5 | { 6 | internal class LongTermMemory 7 | { 8 | public List memories; 9 | public HashSet lastUsedMemories; 10 | public HashSet tags; 11 | 12 | public bool MemoryChanged = false; 13 | 14 | private int maxMemorySize; 15 | 16 | public LongTermMemory(int maxMem = 256) 17 | { 18 | memories = new List(); 19 | lastUsedMemories = new HashSet(); 20 | tags = new HashSet(); 21 | maxMemorySize = maxMem; 22 | } 23 | 24 | public async Task MakeMemory(string state) 25 | { 26 | string tagString = "Tags:\n"; 27 | 28 | foreach (var tag in tags) 29 | tagString += tag + " ,"; 30 | tagString.TrimEnd(','); 31 | tagString += "\n"; 32 | 33 | ChatMessage tagsListMessage = new ChatMessage(ChatRole.System, tagString); 34 | ChatMessage stateMessage = new ChatMessage(ChatRole.User, state); 35 | 36 | string mem = await OpenAI.GetChatCompletion(ChatModel.ChatGPT, new List() { tagsListMessage, Texts.ShortTermMemoryAddPrompt, stateMessage, Texts.ShortTermMemoryAddFormat }); 37 | mem = Utils.ExtractJson(mem); 38 | 39 | try 40 | { 41 | Memory memory = new Memory(Utils.GetObjectFromJson(mem)); 42 | memories.Add(memory); 43 | 44 | foreach (var tag in memory.Tags) 45 | { 46 | tags.Add(tag); 47 | } 48 | 49 | Console.WriteLine("New short term memory:" + mem); 50 | } 51 | catch (Exception) 52 | { 53 | Console.WriteLine("Add memory failed"); 54 | } 55 | 56 | MemoryChanged = true; 57 | } 58 | 59 | public async Task GetMemories(string input) 60 | { 61 | string memoryInput = ""; 62 | 63 | memoryInput += "Available tags:\n"; 64 | 65 | foreach (string tag in tags) 66 | memoryInput += tag + ", "; 67 | 68 | memoryInput += "\nInput:\n"; 69 | memoryInput += input; 70 | 71 | ChatMessage memoryState = new ChatMessage(ChatRole.User, memoryInput); 72 | 73 | 74 | string mem; 75 | OutputMemoryTagsJson memoryTags; 76 | while (true) 77 | { 78 | try 79 | { 80 | mem = await OpenAI.GetChatCompletion(ChatModel.ChatGPT, new List() { Texts.ShortTermMemoryGetPrompt, memoryState, Texts.ShortTermMemoryGetFormat }); 81 | memoryTags = Utils.GetObjectFromJson(mem); 82 | break; 83 | } 84 | catch (Exception) 85 | { 86 | Console.WriteLine("Get memory failed - trying again"); 87 | } 88 | 89 | } 90 | 91 | HashSet splitTags = Utils.CleanInput(memoryTags.tags.Split(",")).ToHashSet(); 92 | 93 | memories.Sort((memory1, memory2) => MathF.Sign(memory2.GetScore(splitTags) - memory1.GetScore(splitTags))); 94 | lastUsedMemories.Clear(); 95 | 96 | string output = ""; 97 | 98 | for (int i = 0; i < memories.Count && output.Split(" ").Length < maxMemorySize; i++) 99 | { 100 | output += (i + 1) + ". \n"; 101 | foreach (var tag in memories[i].Tags) 102 | { 103 | output += tag + ","; 104 | } 105 | output += "\nScore: " + memories[i].GetScore(splitTags) + "\n"; 106 | memories[i].Remembered += memories[i].GetScore(splitTags); 107 | output += memories[i].Content + "\n"; 108 | lastUsedMemories.Add(i); 109 | } 110 | 111 | MemoryChanged = true; 112 | return output; 113 | } 114 | 115 | 116 | public object GetGraphData() 117 | { 118 | MemoryChanged = false; 119 | 120 | GraphMemoryData data = new(); 121 | 122 | data.nodes = new List(); 123 | 124 | for (int i = 0; i < memories.Count; i++) 125 | { 126 | data.nodes.Add(new GraphMemoryNode() { id = i, name = memories[i].Tags.First(), text = memories[i].Content, color = lastUsedMemories.Contains(i)? "#0bba83" : "#dddddd" }); 127 | } 128 | 129 | 130 | for (int i = 0; i < memories.Count; i++) 131 | { 132 | for (int j = 0; j < memories.Count; j++) 133 | { 134 | if (i == j) 135 | continue; 136 | 137 | if (memories[i].GetScore(memories[j].Tags) > 0) 138 | data.links.Add(new GraphMemoryLink() { target = i, source = j, label = memories[i].GetCommonTag(memories[j].Tags), width = memories[i].GetScore(memories[j].Tags) }); 139 | 140 | } 141 | } 142 | 143 | return data; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /WAGIapp/AI/Master.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace WAGIapp.AI 4 | { 5 | internal class Master 6 | { 7 | private static Master singleton; 8 | public static Master Singleton 9 | { 10 | get 11 | { 12 | if (singleton == null) 13 | { 14 | Console.WriteLine("Create master"); 15 | singleton = new Master(); 16 | Console.WriteLine("Master created"); 17 | } 18 | 19 | return singleton; 20 | } 21 | } 22 | 23 | 24 | public LongTermMemory Memory; 25 | public ActionList Actions; 26 | public ScriptFile scriptFile; 27 | 28 | public bool Done = true; 29 | 30 | private string nextMemoryPrompt = ""; 31 | private string lastCommandOuput = ""; 32 | 33 | 34 | public List Notes; 35 | 36 | private List LastMessages = new List(); 37 | private List LastCommand = new List(); 38 | 39 | public string FormatedNotes 40 | { 41 | get 42 | { 43 | string output = ""; 44 | for (int i = 0; i < Notes.Count; i++) 45 | { 46 | output += (i + 1) + ". " + Notes[i] + "\n"; 47 | } 48 | 49 | return output; 50 | } 51 | } 52 | 53 | public Master() 54 | { 55 | Notes = new List(); 56 | 57 | Memory = new LongTermMemory(1024); 58 | Actions = new ActionList(10); 59 | scriptFile = new ScriptFile(); 60 | 61 | singleton = this; 62 | } 63 | 64 | public async Task Tick() 65 | { 66 | 67 | Console.WriteLine("master tick -master"); 68 | 69 | if (Done) 70 | return; 71 | 72 | if (Memory.memories.Count == 0) 73 | { 74 | await Memory.MakeMemory(Settings.Goal); 75 | Console.WriteLine("master start memory done"); 76 | } 77 | 78 | var masterInput = await GetMasterInput(); 79 | 80 | string responseString; 81 | MasterResponse response; 82 | 83 | var action = Actions.AddAction("Thinking", LogAction.ThinkIcon); 84 | 85 | while (true) 86 | { 87 | try 88 | { 89 | responseString = await OpenAI.GetChatCompletion(ChatModel.ChatGPT, masterInput); 90 | 91 | response = Utils.GetObjectFromJson(responseString) ?? new(); 92 | break; 93 | } 94 | catch (Exception) 95 | { 96 | Console.WriteLine("Master failed - trying again"); 97 | } 98 | } 99 | 100 | nextMemoryPrompt = response.thoughts; 101 | 102 | lastCommandOuput = await Commands.TryToRun(this, response.command); 103 | 104 | LastMessages.Add(new ChatMessage(ChatRole.Assistant, responseString)); 105 | LastCommand.Add(new ChatMessage(ChatRole.System, "Command output:\n" + lastCommandOuput)); 106 | 107 | if (LastMessages.Count >= 10) 108 | LastMessages.RemoveAt(0); 109 | 110 | if (LastCommand.Count >= 10) 111 | LastCommand.RemoveAt(0); 112 | 113 | action.Text = response.thoughts; 114 | 115 | masterInput.Add(LastMessages.Last()); 116 | masterInput.Add(LastCommand.Last()); 117 | 118 | Console.WriteLine(JsonSerializer.Serialize(masterInput, new JsonSerializerOptions() { WriteIndented = true })); 119 | Console.WriteLine(scriptFile.GetText()); 120 | Console.WriteLine("------------------------------------------------------------------------"); 121 | 122 | 123 | Actions.AddAction("Memory", LogAction.MemoryIcon); 124 | 125 | await Memory.MakeMemory(responseString); 126 | 127 | } 128 | 129 | public async Task> GetMasterInput() 130 | { 131 | List messages = new List(); 132 | 133 | messages.Add(Texts.MasterStartText); 134 | messages.Add(new ChatMessage(ChatRole.System, "Memories:\n" + await Memory.GetMemories(nextMemoryPrompt))); 135 | messages.Add(new ChatMessage(ChatRole.System, "Notes:\n" + FormatedNotes)); 136 | messages.Add(new ChatMessage(ChatRole.System, "Commands:\n" + Commands.GetCommands())); 137 | messages.Add(new ChatMessage(ChatRole.System, "Main Goal:\n" + Settings.Goal)); 138 | messages.Add(new ChatMessage(ChatRole.System, "Script file:\n" + scriptFile.GetText() + "\nEnd of script file")); 139 | messages.Add(Texts.MasterStartText); 140 | messages.Add(Texts.MasterOutputFormat); 141 | 142 | 143 | for (int i = 0; i < LastMessages.Count; i++) 144 | { 145 | messages.Add(LastMessages[i]); 146 | messages.Add(LastCommand[i]); 147 | } 148 | 149 | return messages; 150 | } 151 | } 152 | 153 | 154 | class MasterResponse 155 | { 156 | public string thoughts { get; set; } = ""; 157 | public string command { get; set; } = ""; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> VisualStudio 2 | ## Ignore Visual Studio temporary files, build results, and 3 | ## files generated by popular Visual Studio add-ons. 4 | ## 5 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 6 | 7 | # User-specific files 8 | *.rsuser 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Mono auto generated files 18 | mono_crash.* 19 | 20 | # Build results 21 | [Dd]ebug/ 22 | [Dd]ebugPublic/ 23 | [Rr]elease/ 24 | [Rr]eleases/ 25 | x64/ 26 | x86/ 27 | [Ww][Ii][Nn]32/ 28 | [Aa][Rr][Mm]/ 29 | [Aa][Rr][Mm]64/ 30 | bld/ 31 | [Bb]in/ 32 | [Oo]bj/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.tlog 95 | *.vspscc 96 | *.vssscc 97 | .builds 98 | *.pidb 99 | *.svclog 100 | *.scc 101 | 102 | # Chutzpah Test files 103 | _Chutzpah* 104 | 105 | # Visual C++ cache files 106 | ipch/ 107 | *.aps 108 | *.ncb 109 | *.opendb 110 | *.opensdf 111 | *.sdf 112 | *.cachefile 113 | *.VC.db 114 | *.VC.VC.opendb 115 | 116 | # Visual Studio profiler 117 | *.psess 118 | *.vsp 119 | *.vspx 120 | *.sap 121 | 122 | # Visual Studio Trace Files 123 | *.e2e 124 | 125 | # TFS 2012 Local Workspace 126 | $tf/ 127 | 128 | # Guidance Automation Toolkit 129 | *.gpState 130 | 131 | # ReSharper is a .NET coding add-in 132 | _ReSharper*/ 133 | *.[Rr]e[Ss]harper 134 | *.DotSettings.user 135 | 136 | # TeamCity is a build add-in 137 | _TeamCity* 138 | 139 | # DotCover is a Code Coverage Tool 140 | *.dotCover 141 | 142 | # AxoCover is a Code Coverage Tool 143 | .axoCover/* 144 | !.axoCover/settings.json 145 | 146 | # Coverlet is a free, cross platform Code Coverage Tool 147 | coverage*.json 148 | coverage*.xml 149 | coverage*.info 150 | 151 | # Visual Studio code coverage results 152 | *.coverage 153 | *.coveragexml 154 | 155 | # NCrunch 156 | _NCrunch_* 157 | .*crunch*.local.xml 158 | nCrunchTemp_* 159 | 160 | # MightyMoose 161 | *.mm.* 162 | AutoTest.Net/ 163 | 164 | # Web workbench (sass) 165 | .sass-cache/ 166 | 167 | # Installshield output folder 168 | [Ee]xpress/ 169 | 170 | # DocProject is a documentation generator add-in 171 | DocProject/buildhelp/ 172 | DocProject/Help/*.HxT 173 | DocProject/Help/*.HxC 174 | DocProject/Help/*.hhc 175 | DocProject/Help/*.hhk 176 | DocProject/Help/*.hhp 177 | DocProject/Help/Html2 178 | DocProject/Help/html 179 | 180 | # Click-Once directory 181 | publish/ 182 | 183 | # Publish Web Output 184 | *.[Pp]ublish.xml 185 | *.azurePubxml 186 | # Note: Comment the next line if you want to checkin your web deploy settings, 187 | # but database connection strings (with potential passwords) will be unencrypted 188 | *.pubxml 189 | *.publishproj 190 | 191 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 192 | # checkin your Azure Web App publish settings, but sensitive information contained 193 | # in these scripts will be unencrypted 194 | PublishScripts/ 195 | 196 | # NuGet Packages 197 | *.nupkg 198 | # NuGet Symbol Packages 199 | *.snupkg 200 | # The packages folder can be ignored because of Package Restore 201 | **/[Pp]ackages/* 202 | # except build/, which is used as an MSBuild target. 203 | !**/[Pp]ackages/build/ 204 | # Uncomment if necessary however generally it will be regenerated when needed 205 | #!**/[Pp]ackages/repositories.config 206 | # NuGet v3's project.json files produces more ignorable files 207 | *.nuget.props 208 | *.nuget.targets 209 | 210 | # Microsoft Azure Build Output 211 | csx/ 212 | *.build.csdef 213 | 214 | # Microsoft Azure Emulator 215 | ecf/ 216 | rcf/ 217 | 218 | # Windows Store app package directories and files 219 | AppPackages/ 220 | BundleArtifacts/ 221 | Package.StoreAssociation.xml 222 | _pkginfo.txt 223 | *.appx 224 | *.appxbundle 225 | *.appxupload 226 | 227 | # Visual Studio cache files 228 | # files ending in .cache can be ignored 229 | *.[Cc]ache 230 | # but keep track of directories ending in .cache 231 | !?*.[Cc]ache/ 232 | 233 | # Others 234 | ClientBin/ 235 | ~$* 236 | *~ 237 | *.dbmdl 238 | *.dbproj.schemaview 239 | *.jfm 240 | *.pfx 241 | *.publishsettings 242 | orleans.codegen.cs 243 | 244 | # Including strong name files can present a security risk 245 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 246 | #*.snk 247 | 248 | # Since there are multiple workflows, uncomment next line to ignore bower_components 249 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 250 | #bower_components/ 251 | 252 | # RIA/Silverlight projects 253 | Generated_Code/ 254 | 255 | # Backup & report files from converting an old project file 256 | # to a newer Visual Studio version. Backup files are not needed, 257 | # because we have git ;-) 258 | _UpgradeReport_Files/ 259 | Backup*/ 260 | UpgradeLog*.XML 261 | UpgradeLog*.htm 262 | ServiceFabricBackup/ 263 | *.rptproj.bak 264 | 265 | # SQL Server files 266 | *.mdf 267 | *.ldf 268 | *.ndf 269 | 270 | # Business Intelligence projects 271 | *.rdl.data 272 | *.bim.layout 273 | *.bim_*.settings 274 | *.rptproj.rsuser 275 | *- [Bb]ackup.rdl 276 | *- [Bb]ackup ([0-9]).rdl 277 | *- [Bb]ackup ([0-9][0-9]).rdl 278 | 279 | # Microsoft Fakes 280 | FakesAssemblies/ 281 | 282 | # GhostDoc plugin setting file 283 | *.GhostDoc.xml 284 | 285 | # Node.js Tools for Visual Studio 286 | .ntvs_analysis.dat 287 | node_modules/ 288 | 289 | # Visual Studio 6 build log 290 | *.plg 291 | 292 | # Visual Studio 6 workspace options file 293 | *.opt 294 | 295 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 296 | *.vbw 297 | 298 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 299 | *.vbp 300 | 301 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 302 | *.dsw 303 | *.dsp 304 | 305 | # Visual Studio 6 technical files 306 | *.ncb 307 | *.aps 308 | 309 | # Visual Studio LightSwitch build output 310 | **/*.HTMLClient/GeneratedArtifacts 311 | **/*.DesktopClient/GeneratedArtifacts 312 | **/*.DesktopClient/ModelManifest.xml 313 | **/*.Server/GeneratedArtifacts 314 | **/*.Server/ModelManifest.xml 315 | _Pvt_Extensions 316 | 317 | # Paket dependency manager 318 | .paket/paket.exe 319 | paket-files/ 320 | 321 | # FAKE - F# Make 322 | .fake/ 323 | 324 | # CodeRush personal settings 325 | .cr/personal 326 | 327 | # Python Tools for Visual Studio (PTVS) 328 | __pycache__/ 329 | *.pyc 330 | 331 | # Cake - Uncomment if you are using it 332 | # tools/** 333 | # !tools/packages.config 334 | 335 | # Tabs Studio 336 | *.tss 337 | 338 | # Telerik's JustMock configuration file 339 | *.jmconfig 340 | 341 | # BizTalk build output 342 | *.btp.cs 343 | *.btm.cs 344 | *.odx.cs 345 | *.xsd.cs 346 | 347 | # OpenCover UI analysis results 348 | OpenCover/ 349 | 350 | # Azure Stream Analytics local run output 351 | ASALocalRun/ 352 | 353 | # MSBuild Binary and Structured Log 354 | *.binlog 355 | 356 | # NVidia Nsight GPU debugger configuration file 357 | *.nvuser 358 | 359 | # MFractors (Xamarin productivity tool) working folder 360 | .mfractor/ 361 | 362 | # Local History for Visual Studio 363 | .localhistory/ 364 | 365 | # Visual Studio History (VSHistory) files 366 | .vshistory/ 367 | 368 | # BeatPulse healthcheck temp database 369 | healthchecksdb 370 | 371 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 372 | MigrationBackup/ 373 | 374 | # Ionide (cross platform F# VS Code tools) working folder 375 | .ionide/ 376 | 377 | # Fody - auto-generated XML schema 378 | FodyWeavers.xsd 379 | 380 | # VS Code files for those working on multiple tools 381 | .vscode/* 382 | !.vscode/settings.json 383 | !.vscode/tasks.json 384 | !.vscode/launch.json 385 | !.vscode/extensions.json 386 | *.code-workspace 387 | 388 | # Local History for Visual Studio Code 389 | .history/ 390 | 391 | # Windows Installer files from build outputs 392 | *.cab 393 | *.msi 394 | *.msix 395 | *.msm 396 | *.msp 397 | 398 | # JetBrains Rider 399 | *.sln.iml 400 | 401 | WAGIapp/Properties/launchSettings.json 402 | --------------------------------------------------------------------------------