Commit Β·
89aba88
0
Parent(s):
Initial commit
Browse files- .chainlit/config.toml +84 -0
- .chainlit/translations/en-US.json +155 -0
- .chainlit/translations/pt-BR.json +155 -0
- .gitignore +4 -0
- README.md +60 -0
- __pycache__/app.cpython-311.pyc +0 -0
- app.py +222 -0
- chainlit.md +6 -0
- poligen_logo.png +0 -0
- requirements.txt +2 -0
.chainlit/config.toml
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[project]
|
| 2 |
+
# Whether to enable telemetry (default: true). No personal data is collected.
|
| 3 |
+
enable_telemetry = true
|
| 4 |
+
|
| 5 |
+
# List of environment variables to be provided by each user to use the app.
|
| 6 |
+
user_env = ["OPENAI_API_KEY"]
|
| 7 |
+
|
| 8 |
+
# Duration (in seconds) during which the session is saved when the connection is lost
|
| 9 |
+
session_timeout = 3600
|
| 10 |
+
|
| 11 |
+
# Enable third parties caching (e.g LangChain cache)
|
| 12 |
+
cache = false
|
| 13 |
+
|
| 14 |
+
# Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
|
| 15 |
+
# follow_symlink = false
|
| 16 |
+
|
| 17 |
+
[features]
|
| 18 |
+
# Show the prompt playground
|
| 19 |
+
prompt_playground = true
|
| 20 |
+
|
| 21 |
+
# Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript)
|
| 22 |
+
unsafe_allow_html = false
|
| 23 |
+
|
| 24 |
+
# Process and display mathematical expressions. This can clash with "$" characters in messages.
|
| 25 |
+
latex = false
|
| 26 |
+
|
| 27 |
+
# Authorize users to upload files with messages
|
| 28 |
+
multi_modal = false
|
| 29 |
+
|
| 30 |
+
# Allows user to use speech to text
|
| 31 |
+
[features.speech_to_text]
|
| 32 |
+
enabled = false
|
| 33 |
+
# See all languages here https://github.com/JamesBrill/react-speech-recognition/blob/HEAD/docs/API.md#language-string
|
| 34 |
+
# language = "en-US"
|
| 35 |
+
|
| 36 |
+
[UI]
|
| 37 |
+
# Name of the app and chatbot.
|
| 38 |
+
name = "PoliGen"
|
| 39 |
+
|
| 40 |
+
# Show the readme while the conversation is empty.
|
| 41 |
+
show_readme_as_default = true
|
| 42 |
+
|
| 43 |
+
# Description of the app and chatbot. This is used for HTML tags.
|
| 44 |
+
# description = ""
|
| 45 |
+
|
| 46 |
+
# Large size content are by default collapsed for a cleaner ui
|
| 47 |
+
default_collapse_content = true
|
| 48 |
+
|
| 49 |
+
# The default value for the expand messages settings.
|
| 50 |
+
default_expand_messages = false
|
| 51 |
+
|
| 52 |
+
# Hide the chain of thought details from the user in the UI.
|
| 53 |
+
hide_cot = false
|
| 54 |
+
|
| 55 |
+
# Link to your github repo. This will add a github button in the UI's header.
|
| 56 |
+
github = "https://github.com/mrwadams/poligen"
|
| 57 |
+
|
| 58 |
+
# Specify a CSS file that can be used to customize the user interface.
|
| 59 |
+
# The CSS file can be served from the public directory or via an external link.
|
| 60 |
+
# custom_css = "/public/test.css"
|
| 61 |
+
|
| 62 |
+
# Override default MUI light theme. (Check theme.ts)
|
| 63 |
+
[UI.theme.light]
|
| 64 |
+
#background = "#FAFAFA"
|
| 65 |
+
#paper = "#FFFFFF"
|
| 66 |
+
|
| 67 |
+
[UI.theme.light.primary]
|
| 68 |
+
#main = "#F80061"
|
| 69 |
+
#dark = "#980039"
|
| 70 |
+
#light = "#FFE7EB"
|
| 71 |
+
|
| 72 |
+
# Override default MUI dark theme. (Check theme.ts)
|
| 73 |
+
[UI.theme.dark]
|
| 74 |
+
#background = "#FAFAFA"
|
| 75 |
+
#paper = "#FFFFFF"
|
| 76 |
+
|
| 77 |
+
[UI.theme.dark.primary]
|
| 78 |
+
#main = "#F80061"
|
| 79 |
+
#dark = "#980039"
|
| 80 |
+
#light = "#FFE7EB"
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
[meta]
|
| 84 |
+
generated_by = "0.7.700"
|
.chainlit/translations/en-US.json
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"components": {
|
| 3 |
+
"atoms": {
|
| 4 |
+
"buttons": {
|
| 5 |
+
"userButton": {
|
| 6 |
+
"menu": {
|
| 7 |
+
"settings": "Settings",
|
| 8 |
+
"settingsKey": "S",
|
| 9 |
+
"APIKeys": "API Keys",
|
| 10 |
+
"logout": "Logout"
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
"molecules": {
|
| 16 |
+
"newChatButton": {
|
| 17 |
+
"newChat": "New Chat"
|
| 18 |
+
},
|
| 19 |
+
"tasklist": {
|
| 20 |
+
"TaskList": {
|
| 21 |
+
"title": "\ud83d\uddd2\ufe0f Task List",
|
| 22 |
+
"loading": "Loading...",
|
| 23 |
+
"error": "An error occured"
|
| 24 |
+
}
|
| 25 |
+
},
|
| 26 |
+
"attachments": {
|
| 27 |
+
"cancelUpload": "Cancel upload",
|
| 28 |
+
"removeAttachment": "Remove attachment"
|
| 29 |
+
},
|
| 30 |
+
"newChatDialog": {
|
| 31 |
+
"createNewChat": "Create new chat?",
|
| 32 |
+
"clearChat": "This will clear the current messages and start a new chat.",
|
| 33 |
+
"cancel": "Cancel",
|
| 34 |
+
"confirm": "Confirm"
|
| 35 |
+
},
|
| 36 |
+
"settingsModal": {
|
| 37 |
+
"expandMessages": "Expand Messages",
|
| 38 |
+
"hideChainOfThought": "Hide Chain of Thought",
|
| 39 |
+
"darkMode": "Dark Mode"
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
"organisms": {
|
| 43 |
+
"chat": {
|
| 44 |
+
"history": {
|
| 45 |
+
"index": {
|
| 46 |
+
"lastInputs": "Last Inputs",
|
| 47 |
+
"noInputs": "Such empty...",
|
| 48 |
+
"loading": "Loading..."
|
| 49 |
+
}
|
| 50 |
+
},
|
| 51 |
+
"inputBox": {
|
| 52 |
+
"input": {
|
| 53 |
+
"placeholder": "Type your message here..."
|
| 54 |
+
},
|
| 55 |
+
"speechButton": {
|
| 56 |
+
"start": "Start recording",
|
| 57 |
+
"stop": "Stop recording"
|
| 58 |
+
},
|
| 59 |
+
"SubmitButton": {
|
| 60 |
+
"sendMessage": "Send message",
|
| 61 |
+
"stopTask": "Stop Task"
|
| 62 |
+
},
|
| 63 |
+
"UploadButton": {
|
| 64 |
+
"attachFiles": "Attach files"
|
| 65 |
+
},
|
| 66 |
+
"waterMark": {
|
| 67 |
+
"text": "Built with"
|
| 68 |
+
}
|
| 69 |
+
},
|
| 70 |
+
"Messages": {
|
| 71 |
+
"index": {
|
| 72 |
+
"running": "Running",
|
| 73 |
+
"executedSuccessfully": "executed successfully",
|
| 74 |
+
"failed": "failed",
|
| 75 |
+
"feedbackUpdated": "Feedback updated",
|
| 76 |
+
"updating": "Updating"
|
| 77 |
+
}
|
| 78 |
+
},
|
| 79 |
+
"dropScreen": {
|
| 80 |
+
"dropYourFilesHere": "Drop your files here"
|
| 81 |
+
},
|
| 82 |
+
"index": {
|
| 83 |
+
"failedToUpload": "Failed to upload",
|
| 84 |
+
"cancelledUploadOf": "Cancelled upload of",
|
| 85 |
+
"couldNotReachServer": "Could not reach the server",
|
| 86 |
+
"continuingChat": "Continuing previous chat"
|
| 87 |
+
},
|
| 88 |
+
"settings": {
|
| 89 |
+
"settingsPanel": "Settings panel",
|
| 90 |
+
"reset": "Reset",
|
| 91 |
+
"cancel": "Cancel",
|
| 92 |
+
"confirm": "Confirm"
|
| 93 |
+
}
|
| 94 |
+
},
|
| 95 |
+
"threadHistory": {
|
| 96 |
+
"sidebar": {
|
| 97 |
+
"filters": {
|
| 98 |
+
"FeedbackSelect": {
|
| 99 |
+
"feedbackAll": "Feedback: All",
|
| 100 |
+
"feedbackPositive": "Feedback: Positive",
|
| 101 |
+
"feedbackNegative": "Feedback: Negative"
|
| 102 |
+
},
|
| 103 |
+
"SearchBar": {
|
| 104 |
+
"search": "Search"
|
| 105 |
+
}
|
| 106 |
+
},
|
| 107 |
+
"DeleteThreadButton": {
|
| 108 |
+
"confirmMessage": "This will delete the thread as well as it's messages and elements.",
|
| 109 |
+
"cancel": "Cancel",
|
| 110 |
+
"confirm": "Confirm",
|
| 111 |
+
"deletingChat": "Deleting chat",
|
| 112 |
+
"chatDeleted": "Chat deleted"
|
| 113 |
+
},
|
| 114 |
+
"index": {
|
| 115 |
+
"pastChats": "Past Chats"
|
| 116 |
+
},
|
| 117 |
+
"ThreadList": {
|
| 118 |
+
"empty": "Empty..."
|
| 119 |
+
},
|
| 120 |
+
"TriggerButton": {
|
| 121 |
+
"closeSidebar": "Close sidebar",
|
| 122 |
+
"openSidebar": "Open sidebar"
|
| 123 |
+
}
|
| 124 |
+
},
|
| 125 |
+
"Thread": {
|
| 126 |
+
"backToChat": "Go back to chat",
|
| 127 |
+
"chatCreatedOn": "This chat was created on"
|
| 128 |
+
}
|
| 129 |
+
},
|
| 130 |
+
"header": {
|
| 131 |
+
"chat": "Chat",
|
| 132 |
+
"readme": "Readme"
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
},
|
| 136 |
+
"hooks": {
|
| 137 |
+
"useLLMProviders": {
|
| 138 |
+
"failedToFetchProviders": "Failed to fetch providers:"
|
| 139 |
+
}
|
| 140 |
+
},
|
| 141 |
+
"pages": {
|
| 142 |
+
"Design": {},
|
| 143 |
+
"Env": {
|
| 144 |
+
"savedSuccessfully": "Saved successfully",
|
| 145 |
+
"requiredApiKeys": "Required API Keys",
|
| 146 |
+
"requiredApiKeysInfo": "To use this app, the following API keys are required. The keys are stored on your device's local storage."
|
| 147 |
+
},
|
| 148 |
+
"Page": {
|
| 149 |
+
"notPartOfProject": "You are not part of this project."
|
| 150 |
+
},
|
| 151 |
+
"ResumeButton": {
|
| 152 |
+
"resumeChat": "Resume Chat"
|
| 153 |
+
}
|
| 154 |
+
}
|
| 155 |
+
}
|
.chainlit/translations/pt-BR.json
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"components": {
|
| 3 |
+
"atoms": {
|
| 4 |
+
"buttons": {
|
| 5 |
+
"userButton": {
|
| 6 |
+
"menu": {
|
| 7 |
+
"settings": "Configura\u00e7\u00f5es",
|
| 8 |
+
"settingsKey": "S",
|
| 9 |
+
"APIKeys": "Chaves de API",
|
| 10 |
+
"logout": "Sair"
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
"molecules": {
|
| 16 |
+
"newChatButton": {
|
| 17 |
+
"newChat": "Nova Conversa"
|
| 18 |
+
},
|
| 19 |
+
"tasklist": {
|
| 20 |
+
"TaskList": {
|
| 21 |
+
"title": "\ud83d\uddd2\ufe0f Lista de Tarefas",
|
| 22 |
+
"loading": "Carregando...",
|
| 23 |
+
"error": "Ocorreu um erro"
|
| 24 |
+
}
|
| 25 |
+
},
|
| 26 |
+
"attachments": {
|
| 27 |
+
"cancelUpload": "Cancelar envio",
|
| 28 |
+
"removeAttachment": "Remover anexo"
|
| 29 |
+
},
|
| 30 |
+
"newChatDialog": {
|
| 31 |
+
"createNewChat": "Criar novo chat?",
|
| 32 |
+
"clearChat": "Isso limpar\u00e1 as mensagens atuais e iniciar\u00e1 uma nova conversa.",
|
| 33 |
+
"cancel": "Cancelar",
|
| 34 |
+
"confirm": "Confirmar"
|
| 35 |
+
},
|
| 36 |
+
"settingsModal": {
|
| 37 |
+
"expandMessages": "Expandir Mensagens",
|
| 38 |
+
"hideChainOfThought": "Esconder Sequ\u00eancia de Pensamento",
|
| 39 |
+
"darkMode": "Modo Escuro"
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
"organisms": {
|
| 43 |
+
"chat": {
|
| 44 |
+
"history": {
|
| 45 |
+
"index": {
|
| 46 |
+
"lastInputs": "\u00daltimas Entradas",
|
| 47 |
+
"noInputs": "Vazio...",
|
| 48 |
+
"loading": "Carregando..."
|
| 49 |
+
}
|
| 50 |
+
},
|
| 51 |
+
"inputBox": {
|
| 52 |
+
"input": {
|
| 53 |
+
"placeholder": "Digite sua mensagem aqui..."
|
| 54 |
+
},
|
| 55 |
+
"speechButton": {
|
| 56 |
+
"start": "Iniciar grava\u00e7\u00e3o",
|
| 57 |
+
"stop": "Parar grava\u00e7\u00e3o"
|
| 58 |
+
},
|
| 59 |
+
"SubmitButton": {
|
| 60 |
+
"sendMessage": "Enviar mensagem",
|
| 61 |
+
"stopTask": "Parar Tarefa"
|
| 62 |
+
},
|
| 63 |
+
"UploadButton": {
|
| 64 |
+
"attachFiles": "Anexar arquivos"
|
| 65 |
+
},
|
| 66 |
+
"waterMark": {
|
| 67 |
+
"text": "Constru\u00eddo com"
|
| 68 |
+
}
|
| 69 |
+
},
|
| 70 |
+
"Messages": {
|
| 71 |
+
"index": {
|
| 72 |
+
"running": "Executando",
|
| 73 |
+
"executedSuccessfully": "executado com sucesso",
|
| 74 |
+
"failed": "falhou",
|
| 75 |
+
"feedbackUpdated": "Feedback atualizado",
|
| 76 |
+
"updating": "Atualizando"
|
| 77 |
+
}
|
| 78 |
+
},
|
| 79 |
+
"dropScreen": {
|
| 80 |
+
"dropYourFilesHere": "Solte seus arquivos aqui"
|
| 81 |
+
},
|
| 82 |
+
"index": {
|
| 83 |
+
"failedToUpload": "Falha ao enviar",
|
| 84 |
+
"cancelledUploadOf": "Envio cancelado de",
|
| 85 |
+
"couldNotReachServer": "N\u00e3o foi poss\u00edvel conectar ao servidor",
|
| 86 |
+
"continuingChat": "Continuando o chat anterior"
|
| 87 |
+
},
|
| 88 |
+
"settings": {
|
| 89 |
+
"settingsPanel": "Painel de Configura\u00e7\u00f5es",
|
| 90 |
+
"reset": "Redefinir",
|
| 91 |
+
"cancel": "Cancelar",
|
| 92 |
+
"confirm": "Confirmar"
|
| 93 |
+
}
|
| 94 |
+
},
|
| 95 |
+
"threadHistory": {
|
| 96 |
+
"sidebar": {
|
| 97 |
+
"filters": {
|
| 98 |
+
"FeedbackSelect": {
|
| 99 |
+
"feedbackAll": "Feedback: Todos",
|
| 100 |
+
"feedbackPositive": "Feedback: Positivo",
|
| 101 |
+
"feedbackNegative": "Feedback: Negativo"
|
| 102 |
+
},
|
| 103 |
+
"SearchBar": {
|
| 104 |
+
"search": "Buscar"
|
| 105 |
+
}
|
| 106 |
+
},
|
| 107 |
+
"DeleteThreadButton": {
|
| 108 |
+
"confirmMessage": "Isso deletar\u00e1 a conversa, assim como suas mensagens e elementos.",
|
| 109 |
+
"cancel": "Cancelar",
|
| 110 |
+
"confirm": "Confirmar",
|
| 111 |
+
"deletingChat": "Deletando conversa",
|
| 112 |
+
"chatDeleted": "Conversa deletada"
|
| 113 |
+
},
|
| 114 |
+
"index": {
|
| 115 |
+
"pastChats": "Conversas Anteriores"
|
| 116 |
+
},
|
| 117 |
+
"ThreadList": {
|
| 118 |
+
"empty": "Vazio..."
|
| 119 |
+
},
|
| 120 |
+
"TriggerButton": {
|
| 121 |
+
"closeSidebar": "Fechar barra lateral",
|
| 122 |
+
"openSidebar": "Abrir barra lateral"
|
| 123 |
+
}
|
| 124 |
+
},
|
| 125 |
+
"Thread": {
|
| 126 |
+
"backToChat": "Voltar para a conversa",
|
| 127 |
+
"chatCreatedOn": "Esta conversa foi criada em"
|
| 128 |
+
}
|
| 129 |
+
},
|
| 130 |
+
"header": {
|
| 131 |
+
"chat": "Conversa",
|
| 132 |
+
"readme": "Leia-me"
|
| 133 |
+
}
|
| 134 |
+
},
|
| 135 |
+
"hooks": {
|
| 136 |
+
"useLLMProviders": {
|
| 137 |
+
"failedToFetchProviders": "Falha ao buscar provedores:"
|
| 138 |
+
}
|
| 139 |
+
},
|
| 140 |
+
"pages": {
|
| 141 |
+
"Design": {},
|
| 142 |
+
"Env": {
|
| 143 |
+
"savedSuccessfully": "Salvo com sucesso",
|
| 144 |
+
"requiredApiKeys": "Chaves de API necess\u00e1rias",
|
| 145 |
+
"requiredApiKeysInfo": "Para usar este aplicativo, as seguintes chaves de API s\u00e3o necess\u00e1rias. As chaves s\u00e3o armazenadas localmente em seu dispositivo."
|
| 146 |
+
},
|
| 147 |
+
"Page": {
|
| 148 |
+
"notPartOfProject": "Voc\u00ea n\u00e3o faz parte deste projeto."
|
| 149 |
+
},
|
| 150 |
+
"ResumeButton": {
|
| 151 |
+
"resumeChat": "Continuar Conversa"
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
}
|
| 155 |
+
}
|
.gitignore
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
venv/
|
| 2 |
+
.env
|
| 3 |
+
.cache
|
| 4 |
+
.__pycache__
|
README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+

|
| 2 |
+
|
| 3 |
+
# PoliGen ππ€
|
| 4 |
+
## A Multi-Agent Chat Interface for Generating Cybersecurity Policies
|
| 5 |
+
|
| 6 |
+
PoliGen harnesses the power of multi-agent chat interfaces to streamline the generation of cybersecurity policies. Tailored for organisations seeking to update their policy documentation to align with recognised information security best practices, PoliGen simplifies the process, enabling both cybersecurity experts and non-experts to craft policies that meet their specific needs.
|
| 7 |
+
|
| 8 |
+
## Overview
|
| 9 |
+
|
| 10 |
+
Utilising an innovative combination of OpenAI's [GPT](https://openai.com/product#gpt) models and [AutoGen](https://microsoft.github.io/autogen/), a cutting-edge multi-agent conversation framework, PoliGen facilitates a dynamic, interactive environment where users can directly specify their cybersecurity policy requirements. This collaboration between human input and artificial intelligence enables policy documents to be produced within minutes instead of days.
|
| 11 |
+
|
| 12 |
+
## Features
|
| 13 |
+
|
| 14 |
+
* **Interactive Multi-Agent System:** Engage with a team of AI agents, including a User Proxy, Technical Writer, and Reviewer, each with specific roles to ensure the creation of comprehensive and professionally structured policy documents.
|
| 15 |
+
* **User-Guided Policy Generation:** Influence the policy generation process in real-time, providing feedback and direction to refine and tailor the output according to your organisational needs.
|
| 16 |
+
* **Best Practices Alignment:** Generated policies reflect the latest in cybersecurity best practices, ensuring your documentation is both current and effective.
|
| 17 |
+
* **Flexible and Accessible:** Designed for a wide range of users, from cybersecurity professionals to those with limited technical expertise, making policy generation accessible to all.
|
| 18 |
+
|
| 19 |
+
## Installation
|
| 20 |
+
|
| 21 |
+
1. Clone the PoliGen repository to your local machine.
|
| 22 |
+
|
| 23 |
+
```bash
|
| 24 |
+
git clone https://github.com/mrwadams/poligen.git
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
2. Change into the PoliGen directory.
|
| 28 |
+
|
| 29 |
+
```bash
|
| 30 |
+
cd poligen
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
3. Install the required dependencies.
|
| 34 |
+
|
| 35 |
+
```bash
|
| 36 |
+
pip install -r requirements.txt
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
4. Start the application.
|
| 40 |
+
|
| 41 |
+
```bash
|
| 42 |
+
chainlit run app.py
|
| 43 |
+
``````
|
| 44 |
+
|
| 45 |
+
5. If you don't already have one stored, you will be prompted to enter your OpenAI API key.
|
| 46 |
+
|
| 47 |
+
## Live Demo
|
| 48 |
+
You can also try out PoliGen in your browser using the HuggingFace Spaces platform. Click the button below to launch the live demo.
|
| 49 |
+
|
| 50 |
+
[](https://huggingface.co/spaces/mrwadams/poligen)
|
| 51 |
+
|
| 52 |
+
## Contributions
|
| 53 |
+
|
| 54 |
+
PoliGen is an open-source project and contributions are welcome. If you're interested in improving the tool or adding new features, please fork the repository and submit a pull request with your changes.
|
| 55 |
+
|
| 56 |
+
## Acknowledgements
|
| 57 |
+
This project was inspired by Antoine Ross' AutoGen Article Generator, which can be found [here](https://github.com/antoineross/autogen-article-generator/tree/main).
|
| 58 |
+
|
| 59 |
+
## License
|
| 60 |
+
PoliGen is released under MIT License, allowing for wide-ranging flexibility in both personal and commercial use.
|
__pycache__/app.cpython-311.pyc
ADDED
|
Binary file (11.3 kB). View file
|
|
|
app.py
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Dict, Optional, Union
|
| 2 |
+
|
| 3 |
+
import chainlit as cl
|
| 4 |
+
|
| 5 |
+
import autogen
|
| 6 |
+
from autogen import Agent, AssistantAgent, UserProxyAgent
|
| 7 |
+
|
| 8 |
+
CONTEXT = """- Task: PoliGen specialises in creating high-quality and detailed cybersecurity policies. The target audience is organisations that want to update their policy documentation to reflect recognised information security best practices.
|
| 9 |
+
|
| 10 |
+
Output Specifications:
|
| 11 |
+
|
| 12 |
+
β’ Output Style and Format: Write policy documents that are thorough and detailed. Ensure grammatical accuracy, coherence, and stylistic refinement. Structure the policy document logically and clearly.
|
| 13 |
+
|
| 14 |
+
β’ Tone: The tone is formal and professional.
|
| 15 |
+
|
| 16 |
+
β’ Section Headings and Subheadings: Create titles and subheadings that are clear, concise, and descriptive.
|
| 17 |
+
|
| 18 |
+
β’ Section Headings: Use a consistent format for section headings.
|
| 19 |
+
|
| 20 |
+
β’ Subheadings: Use a consistent format for subheadings.
|
| 21 |
+
|
| 22 |
+
β’ Content Structure: Use bullet points or numbered lists to present information in a clear and concise manner.
|
| 23 |
+
|
| 24 |
+
Sample output:
|
| 25 |
+
|
| 26 |
+
- Introduction
|
| 27 |
+
- Purpose
|
| 28 |
+
- Scope
|
| 29 |
+
- Policy Details (this section and subheadings will vary depending on the policy type)
|
| 30 |
+
- Responsibilities
|
| 31 |
+
- Enforcement
|
| 32 |
+
- Definitions
|
| 33 |
+
- References
|
| 34 |
+
- Revision History
|
| 35 |
+
- Appendix A: Glossary
|
| 36 |
+
- Appendix B: Acronyms
|
| 37 |
+
- Appendix C: Document Control
|
| 38 |
+
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
# Agents
|
| 42 |
+
USER_PROXY_NAME = "User Proxy"
|
| 43 |
+
REVIEWER = "Reviewer"
|
| 44 |
+
WRITER = "Technical Writer"
|
| 45 |
+
|
| 46 |
+
async def ask_helper(func, **kwargs):
|
| 47 |
+
res = await func(**kwargs).send()
|
| 48 |
+
while not res:
|
| 49 |
+
res = await func(**kwargs).send()
|
| 50 |
+
return res
|
| 51 |
+
|
| 52 |
+
class ChainlitAssistantAgent(AssistantAgent):
|
| 53 |
+
"""
|
| 54 |
+
Wrapper for AutoGens Assistant Agent
|
| 55 |
+
"""
|
| 56 |
+
def send(
|
| 57 |
+
self,
|
| 58 |
+
message: Union[Dict, str],
|
| 59 |
+
recipient: Agent,
|
| 60 |
+
request_reply: Optional[bool] = None,
|
| 61 |
+
silent: Optional[bool] = False,
|
| 62 |
+
) -> bool:
|
| 63 |
+
cl.run_sync(
|
| 64 |
+
cl.Message(
|
| 65 |
+
content=f'*Sending message to "{recipient.name}":*\n\n{message}',
|
| 66 |
+
author=self.name,
|
| 67 |
+
).send()
|
| 68 |
+
)
|
| 69 |
+
super(ChainlitAssistantAgent, self).send(
|
| 70 |
+
message=message,
|
| 71 |
+
recipient=recipient,
|
| 72 |
+
request_reply=request_reply,
|
| 73 |
+
silent=silent,
|
| 74 |
+
)
|
| 75 |
+
class ChainlitUserProxyAgent(UserProxyAgent):
|
| 76 |
+
"""
|
| 77 |
+
Wrapper for AutoGens UserProxy Agent. Simplifies the UI by adding CL Actions.
|
| 78 |
+
"""
|
| 79 |
+
def get_human_input(self, prompt: str) -> str:
|
| 80 |
+
if prompt.startswith(
|
| 81 |
+
"Provide feedback to chat_manager. Press enter to skip and use auto-reply"
|
| 82 |
+
):
|
| 83 |
+
res = cl.run_sync(
|
| 84 |
+
ask_helper(
|
| 85 |
+
cl.AskActionMessage,
|
| 86 |
+
content="Continue or provide feedback?",
|
| 87 |
+
actions=[
|
| 88 |
+
cl.Action( name="continue", value="continue", label="β
Continue" ),
|
| 89 |
+
cl.Action( name="feedback",value="feedback", label="π¬ Provide feedback"),
|
| 90 |
+
cl.Action( name="exit",value="exit", label="π Exit Conversation" )
|
| 91 |
+
],
|
| 92 |
+
)
|
| 93 |
+
)
|
| 94 |
+
if res.get("value") == "continue":
|
| 95 |
+
return ""
|
| 96 |
+
if res.get("value") == "exit":
|
| 97 |
+
return "exit"
|
| 98 |
+
|
| 99 |
+
reply = cl.run_sync(ask_helper(cl.AskUserMessage, content=prompt, timeout=60))
|
| 100 |
+
|
| 101 |
+
return reply["content"].strip()
|
| 102 |
+
|
| 103 |
+
def send(
|
| 104 |
+
self,
|
| 105 |
+
message: Union[Dict, str],
|
| 106 |
+
recipient: Agent,
|
| 107 |
+
request_reply: Optional[bool] = None,
|
| 108 |
+
silent: Optional[bool] = False,
|
| 109 |
+
):
|
| 110 |
+
cl.run_sync(
|
| 111 |
+
cl.Message(
|
| 112 |
+
content=f'*Sending message to "{recipient.name}"*:\n\n{message}',
|
| 113 |
+
author=self.name,
|
| 114 |
+
).send()
|
| 115 |
+
)
|
| 116 |
+
super(ChainlitUserProxyAgent, self).send(
|
| 117 |
+
message=message,
|
| 118 |
+
recipient=recipient,
|
| 119 |
+
request_reply=request_reply,
|
| 120 |
+
silent=silent,
|
| 121 |
+
)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
config_list = [
|
| 126 |
+
{
|
| 127 |
+
"model": "gpt-4-turbo-preview",
|
| 128 |
+
},
|
| 129 |
+
]
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
@cl.action_callback("confirm_action")
|
| 134 |
+
async def on_action(action: cl.Action):
|
| 135 |
+
if action.value == "everything":
|
| 136 |
+
content = "everything"
|
| 137 |
+
elif action.value == "top-headlines":
|
| 138 |
+
content = "top_headlines"
|
| 139 |
+
else:
|
| 140 |
+
await cl.ErrorMessage(content="Invalid action").send()
|
| 141 |
+
return
|
| 142 |
+
|
| 143 |
+
prev_msg = cl.user_session.get("url_actions") # type: cl.Message
|
| 144 |
+
if prev_msg:
|
| 145 |
+
await prev_msg.remove_actions()
|
| 146 |
+
cl.user_session.set("url_actions", None)
|
| 147 |
+
|
| 148 |
+
await cl.Message(content=content).send()
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
@cl.on_chat_start
|
| 152 |
+
async def start():
|
| 153 |
+
# OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
| 154 |
+
OPENAI_API_KEY = cl.user_session.get("OPENAI_API_KEY")
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
try:
|
| 158 |
+
# app_user = cl.user_session.get("user")
|
| 159 |
+
# await cl.Message(f"Hello {app_user.username}").send()
|
| 160 |
+
# config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")
|
| 161 |
+
llm_config = {"config_list": config_list, "api_key": OPENAI_API_KEY, "seed": 42, "request_timeout": 120, "retry_wait_time": 10}
|
| 162 |
+
reviewer = ChainlitAssistantAgent(
|
| 163 |
+
name="Reviewer", llm_config=llm_config,
|
| 164 |
+
system_message="""Reviewer. Reviews the policy document, focuses on the structure and clarity of the content.
|
| 165 |
+
Ensures policies are detailed and thorough.
|
| 166 |
+
Highly focussed on helping the Technical Writer to create a high-quality policy document.
|
| 167 |
+
Only provides suggestions for improvement."""
|
| 168 |
+
)
|
| 169 |
+
writer = ChainlitAssistantAgent(
|
| 170 |
+
name="Technical_Writer", llm_config=llm_config,
|
| 171 |
+
system_message="""Technical Writer. Creates high-quality and detailed information security policies, focusing on recognised information security best practices.
|
| 172 |
+
Writes policy documents that are thorough and detailed.
|
| 173 |
+
Crafts documents using a formal and professional tone.
|
| 174 |
+
Structures content with effective subheadings and bullet points to facilitate reader comprehension."""
|
| 175 |
+
)
|
| 176 |
+
user_proxy = ChainlitUserProxyAgent(
|
| 177 |
+
name="User_Proxy",
|
| 178 |
+
human_input_mode="ALWAYS",
|
| 179 |
+
llm_config=llm_config,
|
| 180 |
+
# max_consecutive_auto_reply=3,
|
| 181 |
+
# is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
|
| 182 |
+
code_execution_config=False,
|
| 183 |
+
system_message="""User Proxy. Provides feedback on the policy document and guides the team through the process."""
|
| 184 |
+
)
|
| 185 |
+
|
| 186 |
+
cl.user_session.set(USER_PROXY_NAME, user_proxy)
|
| 187 |
+
cl.user_session.set(REVIEWER, reviewer)
|
| 188 |
+
cl.user_session.set(WRITER, writer)
|
| 189 |
+
|
| 190 |
+
msg = cl.Message(content=f"""Hi, this is the PoliGen agent team π€. Please specify a cybersecurity domain for us to write a policy about (e.g. Data Classification, Remote Access).""",
|
| 191 |
+
disable_human_feedback=True,
|
| 192 |
+
author="User_Proxy")
|
| 193 |
+
await msg.send()
|
| 194 |
+
|
| 195 |
+
except Exception as e:
|
| 196 |
+
print("Error: ", e)
|
| 197 |
+
pass
|
| 198 |
+
|
| 199 |
+
@cl.on_message
|
| 200 |
+
async def run_conversation(message: cl.Message):
|
| 201 |
+
#try:
|
| 202 |
+
MESSAGE = message.content
|
| 203 |
+
print("Task: ", MESSAGE)
|
| 204 |
+
reviewer = cl.user_session.get(REVIEWER)
|
| 205 |
+
user_proxy = cl.user_session.get(USER_PROXY_NAME)
|
| 206 |
+
writer = cl.user_session.get(WRITER)
|
| 207 |
+
|
| 208 |
+
groupchat = autogen.GroupChat(agents=[user_proxy, reviewer, writer], messages=[], max_round=10)
|
| 209 |
+
manager = autogen.GroupChatManager(groupchat=groupchat)
|
| 210 |
+
|
| 211 |
+
print("Initiated GC messages... \nGC messages length: ", len(groupchat.messages))
|
| 212 |
+
|
| 213 |
+
if len(groupchat.messages) == 0:
|
| 214 |
+
message = f"""Write a policy document for the following cybersecurity domain: """ + MESSAGE + """. The final output should adhere to these requirements: \n""" + CONTEXT
|
| 215 |
+
await cl.Message(content=f"""Starting agents on task of creating a policy document...""").send()
|
| 216 |
+
await cl.make_async(user_proxy.initiate_chat)( manager, message=message, )
|
| 217 |
+
else:
|
| 218 |
+
await cl.make_async(user_proxy.send)( manager, message=MESSAGE, )
|
| 219 |
+
|
| 220 |
+
# except Exception as e:
|
| 221 |
+
# print("Error: ", e)
|
| 222 |
+
# pass
|
chainlit.md
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PoliGen ππ€
|
| 2 |
+
## A multi-agent chat inferface for generating cybersecurity policies
|
| 3 |
+
|
| 4 |
+
PoliGen is a multi-agent chat interface for generating cybersecurity policies. It is designed to be used by non-experts in cybersecurity, to help them generate policies that are tailored to their specific needs.
|
| 5 |
+
|
| 6 |
+
The tool uses an OpenAI [GPT model](https://openai.com/product#gpt) in combination with [AutoGen](https://microsoft.github.io/autogen/) - a multi-agent conversation framework for building Large Language Model (LLM) workflows. Together, they allow users to simply specify the type of policy they need, and then have it generated by a team of AI agents. The user can also participate in the conversation, providing feedback and guidance to the agents to improve the quality of the generated policy.
|
poligen_logo.png
ADDED
|
requirements.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
pyautogen
|
| 2 |
+
chainlit
|