Upload folder using huggingface_hub
Browse files- .gitattributes +1 -0
- .gradio/certificate.pem +31 -0
- Activate.ps1 +502 -0
- GradioLMstudioInterface.py +103 -0
- README.md +1 -7
- __pycache__/main.cpython-312.pyc +0 -0
- __pycache__/main2.cpython-312.pyc +0 -0
- activate +70 -0
- activate.bat +34 -0
- deactivate.bat +22 -0
- f2py.exe +0 -0
- fastapi.exe +0 -0
- gradio.exe +0 -0
- httpx.exe +0 -0
- huggingface-cli.exe +0 -0
- lmstudio_gradio.py +93 -0
- main.py +113 -0
- main2.py +200 -0
- mainlpy +0 -0
- markdown-it.exe +0 -0
- modal.exe +0 -0
- normalizer.exe +0 -0
- numpy-config.exe +0 -0
- pip.exe +0 -0
- pip3.12.exe +0 -0
- pip3.exe +0 -0
- protoc-gen-grpclib_python.exe +0 -0
- protoc-gen-python_grpc.exe +0 -0
- pygmentize.exe +0 -0
- python.exe +0 -0
- pythonw.exe +0 -0
- ruff.exe +3 -0
- tqdm.exe +0 -0
- typer.exe +0 -0
- upload_theme.exe +0 -0
- uvicorn.exe +0 -0
- watchfiles.exe +0 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
ruff.exe filter=lfs diff=lfs merge=lfs -text
|
.gradio/certificate.pem
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
-----BEGIN CERTIFICATE-----
|
2 |
+
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
3 |
+
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
4 |
+
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
5 |
+
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
6 |
+
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
7 |
+
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
8 |
+
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
9 |
+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
10 |
+
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
11 |
+
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
12 |
+
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
13 |
+
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
14 |
+
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
15 |
+
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
16 |
+
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
17 |
+
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
18 |
+
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
19 |
+
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
20 |
+
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
21 |
+
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
22 |
+
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
23 |
+
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
24 |
+
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
25 |
+
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
26 |
+
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
27 |
+
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
28 |
+
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
29 |
+
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
30 |
+
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
31 |
+
-----END CERTIFICATE-----
|
Activate.ps1
ADDED
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<#
|
2 |
+
.Synopsis
|
3 |
+
Activate a Python virtual environment for the current PowerShell session.
|
4 |
+
|
5 |
+
.Description
|
6 |
+
Pushes the python executable for a virtual environment to the front of the
|
7 |
+
$Env:PATH environment variable and sets the prompt to signify that you are
|
8 |
+
in a Python virtual environment. Makes use of the command line switches as
|
9 |
+
well as the `pyvenv.cfg` file values present in the virtual environment.
|
10 |
+
|
11 |
+
.Parameter VenvDir
|
12 |
+
Path to the directory that contains the virtual environment to activate. The
|
13 |
+
default value for this is the parent of the directory that the Activate.ps1
|
14 |
+
script is located within.
|
15 |
+
|
16 |
+
.Parameter Prompt
|
17 |
+
The prompt prefix to display when this virtual environment is activated. By
|
18 |
+
default, this prompt is the name of the virtual environment folder (VenvDir)
|
19 |
+
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
20 |
+
|
21 |
+
.Example
|
22 |
+
Activate.ps1
|
23 |
+
Activates the Python virtual environment that contains the Activate.ps1 script.
|
24 |
+
|
25 |
+
.Example
|
26 |
+
Activate.ps1 -Verbose
|
27 |
+
Activates the Python virtual environment that contains the Activate.ps1 script,
|
28 |
+
and shows extra information about the activation as it executes.
|
29 |
+
|
30 |
+
.Example
|
31 |
+
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
32 |
+
Activates the Python virtual environment located in the specified location.
|
33 |
+
|
34 |
+
.Example
|
35 |
+
Activate.ps1 -Prompt "MyPython"
|
36 |
+
Activates the Python virtual environment that contains the Activate.ps1 script,
|
37 |
+
and prefixes the current prompt with the specified string (surrounded in
|
38 |
+
parentheses) while the virtual environment is active.
|
39 |
+
|
40 |
+
.Notes
|
41 |
+
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
42 |
+
execution policy for the user. You can do this by issuing the following PowerShell
|
43 |
+
command:
|
44 |
+
|
45 |
+
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
46 |
+
|
47 |
+
For more information on Execution Policies:
|
48 |
+
https://go.microsoft.com/fwlink/?LinkID=135170
|
49 |
+
|
50 |
+
#>
|
51 |
+
Param(
|
52 |
+
[Parameter(Mandatory = $false)]
|
53 |
+
[String]
|
54 |
+
$VenvDir,
|
55 |
+
[Parameter(Mandatory = $false)]
|
56 |
+
[String]
|
57 |
+
$Prompt
|
58 |
+
)
|
59 |
+
|
60 |
+
<# Function declarations --------------------------------------------------- #>
|
61 |
+
|
62 |
+
<#
|
63 |
+
.Synopsis
|
64 |
+
Remove all shell session elements added by the Activate script, including the
|
65 |
+
addition of the virtual environment's Python executable from the beginning of
|
66 |
+
the PATH variable.
|
67 |
+
|
68 |
+
.Parameter NonDestructive
|
69 |
+
If present, do not remove this function from the global namespace for the
|
70 |
+
session.
|
71 |
+
|
72 |
+
#>
|
73 |
+
function global:deactivate ([switch]$NonDestructive) {
|
74 |
+
# Revert to original values
|
75 |
+
|
76 |
+
# The prior prompt:
|
77 |
+
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
78 |
+
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
79 |
+
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
80 |
+
}
|
81 |
+
|
82 |
+
# The prior PYTHONHOME:
|
83 |
+
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
84 |
+
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
85 |
+
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
86 |
+
}
|
87 |
+
|
88 |
+
# The prior PATH:
|
89 |
+
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
90 |
+
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
91 |
+
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
92 |
+
}
|
93 |
+
|
94 |
+
# Just remove the VIRTUAL_ENV altogether:
|
95 |
+
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
96 |
+
Remove-Item -Path env:VIRTUAL_ENV
|
97 |
+
}
|
98 |
+
|
99 |
+
# Just remove VIRTUAL_ENV_PROMPT altogether.
|
100 |
+
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
|
101 |
+
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
|
102 |
+
}
|
103 |
+
|
104 |
+
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
105 |
+
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
106 |
+
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
107 |
+
}
|
108 |
+
|
109 |
+
# Leave deactivate function in the global namespace if requested:
|
110 |
+
if (-not $NonDestructive) {
|
111 |
+
Remove-Item -Path function:deactivate
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
<#
|
116 |
+
.Description
|
117 |
+
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
118 |
+
given folder, and returns them in a map.
|
119 |
+
|
120 |
+
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
121 |
+
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
122 |
+
then it is considered a `key = value` line. The left hand string is the key,
|
123 |
+
the right hand is the value.
|
124 |
+
|
125 |
+
If the value starts with a `'` or a `"` then the first and last character is
|
126 |
+
stripped from the value before being captured.
|
127 |
+
|
128 |
+
.Parameter ConfigDir
|
129 |
+
Path to the directory that contains the `pyvenv.cfg` file.
|
130 |
+
#>
|
131 |
+
function Get-PyVenvConfig(
|
132 |
+
[String]
|
133 |
+
$ConfigDir
|
134 |
+
) {
|
135 |
+
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
136 |
+
|
137 |
+
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
138 |
+
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
139 |
+
|
140 |
+
# An empty map will be returned if no config file is found.
|
141 |
+
$pyvenvConfig = @{ }
|
142 |
+
|
143 |
+
if ($pyvenvConfigPath) {
|
144 |
+
|
145 |
+
Write-Verbose "File exists, parse `key = value` lines"
|
146 |
+
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
147 |
+
|
148 |
+
$pyvenvConfigContent | ForEach-Object {
|
149 |
+
$keyval = $PSItem -split "\s*=\s*", 2
|
150 |
+
if ($keyval[0] -and $keyval[1]) {
|
151 |
+
$val = $keyval[1]
|
152 |
+
|
153 |
+
# Remove extraneous quotations around a string value.
|
154 |
+
if ("'""".Contains($val.Substring(0, 1))) {
|
155 |
+
$val = $val.Substring(1, $val.Length - 2)
|
156 |
+
}
|
157 |
+
|
158 |
+
$pyvenvConfig[$keyval[0]] = $val
|
159 |
+
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
return $pyvenvConfig
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
<# Begin Activate script --------------------------------------------------- #>
|
168 |
+
|
169 |
+
# Determine the containing directory of this script
|
170 |
+
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
171 |
+
$VenvExecDir = Get-Item -Path $VenvExecPath
|
172 |
+
|
173 |
+
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
174 |
+
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
175 |
+
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
176 |
+
|
177 |
+
# Set values required in priority: CmdLine, ConfigFile, Default
|
178 |
+
# First, get the location of the virtual environment, it might not be
|
179 |
+
# VenvExecDir if specified on the command line.
|
180 |
+
if ($VenvDir) {
|
181 |
+
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
182 |
+
}
|
183 |
+
else {
|
184 |
+
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
185 |
+
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
186 |
+
Write-Verbose "VenvDir=$VenvDir"
|
187 |
+
}
|
188 |
+
|
189 |
+
# Next, read the `pyvenv.cfg` file to determine any required value such
|
190 |
+
# as `prompt`.
|
191 |
+
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
192 |
+
|
193 |
+
# Next, set the prompt from the command line, or the config file, or
|
194 |
+
# just use the name of the virtual environment folder.
|
195 |
+
if ($Prompt) {
|
196 |
+
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
197 |
+
}
|
198 |
+
else {
|
199 |
+
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
200 |
+
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
201 |
+
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
202 |
+
$Prompt = $pyvenvCfg['prompt'];
|
203 |
+
}
|
204 |
+
else {
|
205 |
+
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
|
206 |
+
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
207 |
+
$Prompt = Split-Path -Path $venvDir -Leaf
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
Write-Verbose "Prompt = '$Prompt'"
|
212 |
+
Write-Verbose "VenvDir='$VenvDir'"
|
213 |
+
|
214 |
+
# Deactivate any currently active virtual environment, but leave the
|
215 |
+
# deactivate function in place.
|
216 |
+
deactivate -nondestructive
|
217 |
+
|
218 |
+
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
219 |
+
# that there is an activated venv.
|
220 |
+
$env:VIRTUAL_ENV = $VenvDir
|
221 |
+
|
222 |
+
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
223 |
+
|
224 |
+
Write-Verbose "Setting prompt to '$Prompt'"
|
225 |
+
|
226 |
+
# Set the prompt to include the env name
|
227 |
+
# Make sure _OLD_VIRTUAL_PROMPT is global
|
228 |
+
function global:_OLD_VIRTUAL_PROMPT { "" }
|
229 |
+
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
230 |
+
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
231 |
+
|
232 |
+
function global:prompt {
|
233 |
+
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
234 |
+
_OLD_VIRTUAL_PROMPT
|
235 |
+
}
|
236 |
+
$env:VIRTUAL_ENV_PROMPT = $Prompt
|
237 |
+
}
|
238 |
+
|
239 |
+
# Clear PYTHONHOME
|
240 |
+
if (Test-Path -Path Env:PYTHONHOME) {
|
241 |
+
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
242 |
+
Remove-Item -Path Env:PYTHONHOME
|
243 |
+
}
|
244 |
+
|
245 |
+
# Add the venv to the PATH
|
246 |
+
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
247 |
+
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
248 |
+
|
249 |
+
# SIG # Begin signature block
|
250 |
+
# MIIvIwYJKoZIhvcNAQcCoIIvFDCCLxACAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
251 |
+
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
252 |
+
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk
|
253 |
+
# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCE8MwggWQMIIDeKADAgECAhAFmxtXno4h
|
254 |
+
# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
|
255 |
+
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
|
256 |
+
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z
|
257 |
+
# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
|
258 |
+
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
|
259 |
+
# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
|
260 |
+
# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z
|
261 |
+
# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ
|
262 |
+
# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s
|
263 |
+
# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL
|
264 |
+
# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb
|
265 |
+
# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3
|
266 |
+
# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c
|
267 |
+
# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx
|
268 |
+
# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0
|
269 |
+
# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL
|
270 |
+
# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud
|
271 |
+
# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf
|
272 |
+
# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk
|
273 |
+
# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS
|
274 |
+
# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK
|
275 |
+
# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB
|
276 |
+
# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp
|
277 |
+
# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg
|
278 |
+
# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri
|
279 |
+
# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7
|
280 |
+
# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5
|
281 |
+
# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3
|
282 |
+
# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H
|
283 |
+
# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G
|
284 |
+
# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
|
285 |
+
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
|
286 |
+
# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla
|
287 |
+
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
|
288 |
+
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
|
289 |
+
# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C
|
290 |
+
# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce
|
291 |
+
# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da
|
292 |
+
# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T
|
293 |
+
# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA
|
294 |
+
# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh
|
295 |
+
# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM
|
296 |
+
# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z
|
297 |
+
# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05
|
298 |
+
# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY
|
299 |
+
# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP
|
300 |
+
# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T
|
301 |
+
# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD
|
302 |
+
# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
|
303 |
+
# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
|
304 |
+
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
|
305 |
+
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
|
306 |
+
# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
|
307 |
+
# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN
|
308 |
+
# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry
|
309 |
+
# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL
|
310 |
+
# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf
|
311 |
+
# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh
|
312 |
+
# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh
|
313 |
+
# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV
|
314 |
+
# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j
|
315 |
+
# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH
|
316 |
+
# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC
|
317 |
+
# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l
|
318 |
+
# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW
|
319 |
+
# eE4wggd3MIIFX6ADAgECAhAHHxQbizANJfMU6yMM0NHdMA0GCSqGSIb3DQEBCwUA
|
320 |
+
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
|
321 |
+
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
|
322 |
+
# ODQgMjAyMSBDQTEwHhcNMjIwMTE3MDAwMDAwWhcNMjUwMTE1MjM1OTU5WjB8MQsw
|
323 |
+
# CQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQHEwlCZWF2ZXJ0b24x
|
324 |
+
# IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQDExpQ
|
325 |
+
# eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
|
326 |
+
# ADCCAgoCggIBAKgc0BTT+iKbtK6f2mr9pNMUTcAJxKdsuOiSYgDFfwhjQy89koM7
|
327 |
+
# uP+QV/gwx8MzEt3c9tLJvDccVWQ8H7mVsk/K+X+IufBLCgUi0GGAZUegEAeRlSXx
|
328 |
+
# xhYScr818ma8EvGIZdiSOhqjYc4KnfgfIS4RLtZSrDFG2tN16yS8skFa3IHyvWdb
|
329 |
+
# D9PvZ4iYNAS4pjYDRjT/9uzPZ4Pan+53xZIcDgjiTwOh8VGuppxcia6a7xCyKoOA
|
330 |
+
# GjvCyQsj5223v1/Ig7Dp9mGI+nh1E3IwmyTIIuVHyK6Lqu352diDY+iCMpk9Zanm
|
331 |
+
# SjmB+GMVs+H/gOiofjjtf6oz0ki3rb7sQ8fTnonIL9dyGTJ0ZFYKeb6BLA66d2GA
|
332 |
+
# LwxZhLe5WH4Np9HcyXHACkppsE6ynYjTOd7+jN1PRJahN1oERzTzEiV6nCO1M3U1
|
333 |
+
# HbPTGyq52IMFSBM2/07WTJSbOeXjvYR7aUxK9/ZkJiacl2iZI7IWe7JKhHohqKuc
|
334 |
+
# eQNyOzxTakLcRkzynvIrk33R9YVqtB4L6wtFxhUjvDnQg16xot2KVPdfyPAWd81w
|
335 |
+
# tZADmrUtsZ9qG79x1hBdyOl4vUtVPECuyhCxaw+faVjumapPUnwo8ygflJJ74J+B
|
336 |
+
# Yxf6UuD7m8yzsfXWkdv52DjL74TxzuFTLHPyARWCSCAbzn3ZIly+qIqDAgMBAAGj
|
337 |
+
# ggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNVHQ4E
|
338 |
+
# FgQUt/1Teh2XDuUj2WW3siYWJgkZHA8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM
|
339 |
+
# MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp
|
340 |
+
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI
|
341 |
+
# QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
|
342 |
+
# RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex
|
343 |
+
# LmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8v
|
344 |
+
# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUF
|
345 |
+
# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6
|
346 |
+
# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu
|
347 |
+
# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZI
|
348 |
+
# hvcNAQELBQADggIBABxv4AeV/5ltkELHSC63fXAFYS5tadcWTiNc2rskrNLrfH1N
|
349 |
+
# s0vgSZFoQxYBFKI159E8oQQ1SKbTEubZ/B9kmHPhprHya08+VVzxC88pOEvz68nA
|
350 |
+
# 82oEM09584aILqYmj8Pj7h/kmZNzuEL7WiwFa/U1hX+XiWfLIJQsAHBla0i7QRF2
|
351 |
+
# de8/VSF0XXFa2kBQ6aiTsiLyKPNbaNtbcucaUdn6vVUS5izWOXM95BSkFSKdE45O
|
352 |
+
# q3FForNJXjBvSCpwcP36WklaHL+aHu1upIhCTUkzTHMh8b86WmjRUqbrnvdyR2yd
|
353 |
+
# I5l1OqcMBjkpPpIV6wcc+KY/RH2xvVuuoHjlUjwq2bHiNoX+W1scCpnA8YTs2d50
|
354 |
+
# jDHUgwUo+ciwpffH0Riq132NFmrH3r67VaN3TuBxjI8SIZM58WEDkbeoriDk3hxU
|
355 |
+
# 8ZWV7b8AW6oyVBGfM06UgkfMb58h+tJPrFx8VI/WLq1dTqMfZOm5cuclMnUHs2uq
|
356 |
+
# rRNtnV8UfidPBL4ZHkTcClQbCoz0UbLhkiDvIS00Dn+BBcxw/TKqVL4Oaz3bkMSs
|
357 |
+
# M46LciTeucHY9ExRVt3zy7i149sd+F4QozPqn7FrSVHXmem3r7bjyHTxOgqxRCVa
|
358 |
+
# 18Vtx7P/8bYSBeS+WHCKcliFCecspusCDSlnRUjZwyPdP0VHxaZg2unjHY3rMYIa
|
359 |
+
# tjCCGrICAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
|
360 |
+
# Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJT
|
361 |
+
# QTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAHHxQbizANJfMU6yMM0NHdMA0GCWCGSAFl
|
362 |
+
# AwQCAQUAoIHIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC
|
363 |
+
# AQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBnAZ6P7YvTwq0fbF62
|
364 |
+
# o7E75R0LxsW5OtyYiFESQckLhjBcBgorBgEEAYI3AgEMMU4wTKBGgEQAQgB1AGkA
|
365 |
+
# bAB0ADoAIABSAGUAbABlAGEAcwBlAF8AdgAzAC4AMQAyAC4ANwBfADIAMAAyADQA
|
366 |
+
# MQAwADAAMQAuADAAMaECgAAwDQYJKoZIhvcNAQEBBQAEggIANL0qpBF5L2ByXhO6
|
367 |
+
# lg0q62KlhZ8aOqcG2WQMWC0/2z1oE2zAZx3H84mXlheeux326/gE2OQwb6Pwgp5V
|
368 |
+
# yEwj+V/pQsrNELF0w7PM4IDwOQMv5BXTgpqVmhB0oj0tBH3zBUcmyesJmweFHop8
|
369 |
+
# sV53sCNjXEwV6sN2DMwtXasfTYdNAl5dufailrErLAOuteA1WWMPb4uQ93ZhnDND
|
370 |
+
# GgHRWENINvmgM8Uc2k/vTuhZH2JksETiPM7sVfsBsiiK5yFMaybCQJxmKUuWMpGj
|
371 |
+
# S3eLMrxj/hAc4kIPBKhVnvvcBvKliCGYzdaAF1ZwsqvJfwejan0uAw+pc7DdP7gK
|
372 |
+
# r2Nx8JSjmNK5Z/GcDNYpQujSBfrmcjJccc2VOhJXXOfqTRqdb1zMPK1Dm9BHDPQY
|
373 |
+
# xACnGbJi936rbVM3K79wq17o902pw1c7eNMNfRPEJ3bwKejdUbsTWEc4nWaBwGWJ
|
374 |
+
# hz254ow4sXmuPkRaiaeH6qvmhxdUZ37NT1WVTjheZDO533DRRx7w7WTnSiyIapaE
|
375 |
+
# G9hysgBjWzFfCBCZpvKF5f17bRbw4E5pLNiDIEWdiUoVtTbdQDRFb1BC+LvmpyQq
|
376 |
+
# EpTzfWLIN40150fWJ367S30kZup+GQcR6LIEP0uzSQ0Cbbl8eg3zazihaEarpfz+
|
377 |
+
# YUI0nmQ9DvFPs346XiWN5nmshKShghc/MIIXOwYKKwYBBAGCNwMDATGCFyswghcn
|
378 |
+
# BgkqhkiG9w0BBwKgghcYMIIXFAIBAzEPMA0GCWCGSAFlAwQCAQUAMHcGCyqGSIb3
|
379 |
+
# DQEJEAEEoGgEZjBkAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQgAsRX
|
380 |
+
# Lz3fdSC9evjnFG5oUaOsrkjVEcqVXPbev4b9kg0CEH2kQpjJsP7w1n28jWvfqSYY
|
381 |
+
# DzIwMjQxMDAxMDQwMTM0WqCCEwkwggbCMIIEqqADAgECAhAFRK/zlJ0IOaa/2z9f
|
382 |
+
# 5WEWMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp
|
383 |
+
# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2
|
384 |
+
# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjMwNzE0MDAwMDAwWhcNMzQxMDEz
|
385 |
+
# MjM1OTU5WjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x
|
386 |
+
# IDAeBgNVBAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIzMIICIjANBgkqhkiG9w0B
|
387 |
+
# AQEFAAOCAg8AMIICCgKCAgEAo1NFhx2DjlusPlSzI+DPn9fl0uddoQ4J3C9Io5d6
|
388 |
+
# OyqcZ9xiFVjBqZMRp82qsmrdECmKHmJjadNYnDVxvzqX65RQjxwg6seaOy+WZuNp
|
389 |
+
# 52n+W8PWKyAcwZeUtKVQgfLPywemMGjKg0La/H8JJJSkghraarrYO8pd3hkYhftF
|
390 |
+
# 6g1hbJ3+cV7EBpo88MUueQ8bZlLjyNY+X9pD04T10Mf2SC1eRXWWdf7dEKEbg8G4
|
391 |
+
# 5lKVtUfXeCk5a+B4WZfjRCtK1ZXO7wgX6oJkTf8j48qG7rSkIWRw69XloNpjsy7p
|
392 |
+
# Be6q9iT1HbybHLK3X9/w7nZ9MZllR1WdSiQvrCuXvp/k/XtzPjLuUjT71Lvr1KAs
|
393 |
+
# NJvj3m5kGQc3AZEPHLVRzapMZoOIaGK7vEEbeBlt5NkP4FhB+9ixLOFRr7StFQYU
|
394 |
+
# 6mIIE9NpHnxkTZ0P387RXoyqq1AVybPKvNfEO2hEo6U7Qv1zfe7dCv95NBB+plwK
|
395 |
+
# WEwAPoVpdceDZNZ1zY8SdlalJPrXxGshuugfNJgvOuprAbD3+yqG7HtSOKmYCaFx
|
396 |
+
# smxxrz64b5bV4RAT/mFHCoz+8LbH1cfebCTwv0KCyqBxPZySkwS0aXAnDU+3tTbR
|
397 |
+
# yV8IpHCj7ArxES5k4MsiK8rxKBMhSVF+BmbTO77665E42FEHypS34lCh8zrTioPL
|
398 |
+
# QHsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYG
|
399 |
+
# A1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG
|
400 |
+
# SAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4E
|
401 |
+
# FgQUpbbvE+fvzdBkodVWqWUxo97V40kwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDov
|
402 |
+
# L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1
|
403 |
+
# NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUH
|
404 |
+
# MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDov
|
405 |
+
# L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNI
|
406 |
+
# QTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAgRrW3qCp
|
407 |
+
# tZgXvHCNT4o8aJzYJf/LLOTN6l0ikuyMIgKpuM+AqNnn48XtJoKKcS8Y3U623mzX
|
408 |
+
# 4WCcK+3tPUiOuGu6fF29wmE3aEl3o+uQqhLXJ4Xzjh6S2sJAOJ9dyKAuJXglnSoF
|
409 |
+
# eoQpmLZXeY/bJlYrsPOnvTcM2Jh2T1a5UsK2nTipgedtQVyMadG5K8TGe8+c+nji
|
410 |
+
# kxp2oml101DkRBK+IA2eqUTQ+OVJdwhaIcW0z5iVGlS6ubzBaRm6zxbygzc0brBB
|
411 |
+
# Jt3eWpdPM43UjXd9dUWhpVgmagNF3tlQtVCMr1a9TMXhRsUo063nQwBw3syYnhmJ
|
412 |
+
# A+rUkTfvTVLzyWAhxFZH7doRS4wyw4jmWOK22z75X7BC1o/jF5HRqsBV44a/rCcs
|
413 |
+
# QdCaM0qoNtS5cpZ+l3k4SF/Kwtw9Mt911jZnWon49qfH5U81PAC9vpwqbHkB3NpE
|
414 |
+
# 5jreODsHXjlY9HxzMVWggBHLFAx+rrz+pOt5Zapo1iLKO+uagjVXKBbLafIymrLS
|
415 |
+
# 2Dq4sUaGa7oX/cR3bBVsrquvczroSUa31X/MtjjA2Owc9bahuEMs305MfR5ocMB3
|
416 |
+
# CtQC4Fxguyj/OOVSWtasFyIjTvTs0xf7UGv/B3cfcZdEQcm4RtNsMnxYL2dHZeUb
|
417 |
+
# c7aZ+WssBkbvQR7w8F/g29mtkIBEr4AQQYowggauMIIElqADAgECAhAHNje3JFR8
|
418 |
+
# 2Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
|
419 |
+
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
|
420 |
+
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0z
|
421 |
+
# NzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
|
422 |
+
# SW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1
|
423 |
+
# NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
|
424 |
+
# AQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI
|
425 |
+
# 82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9
|
426 |
+
# xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ
|
427 |
+
# 3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5Emfv
|
428 |
+
# DqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDET
|
429 |
+
# qVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHe
|
430 |
+
# IhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jo
|
431 |
+
# n7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ
|
432 |
+
# 9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/T
|
433 |
+
# Xkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJg
|
434 |
+
# o1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkw
|
435 |
+
# EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+e
|
436 |
+
# yG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQD
|
437 |
+
# AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEF
|
438 |
+
# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRw
|
439 |
+
# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy
|
440 |
+
# dDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln
|
441 |
+
# aUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglg
|
442 |
+
# hkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGw
|
443 |
+
# GC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0
|
444 |
+
# MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1D
|
445 |
+
# X+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw
|
446 |
+
# 1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY
|
447 |
+
# +/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0I
|
448 |
+
# SQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr
|
449 |
+
# 5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7y
|
450 |
+
# Rp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDop
|
451 |
+
# hrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/
|
452 |
+
# AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMO
|
453 |
+
# Hds3OBqhK/bt1nz8MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkq
|
454 |
+
# hkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
|
455 |
+
# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBB
|
456 |
+
# c3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5
|
457 |
+
# WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
|
458 |
+
# ExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJv
|
459 |
+
# b3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1K
|
460 |
+
# PDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2r
|
461 |
+
# snnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C
|
462 |
+
# 8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBf
|
463 |
+
# sXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
|
464 |
+
# QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8
|
465 |
+
# rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaY
|
466 |
+
# dj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+
|
467 |
+
# wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw
|
468 |
+
# ++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+N
|
469 |
+
# P8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7F
|
470 |
+
# wI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUw
|
471 |
+
# AwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAU
|
472 |
+
# Reuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEB
|
473 |
+
# BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG
|
474 |
+
# AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1
|
475 |
+
# cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp
|
476 |
+
# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAow
|
477 |
+
# CDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/
|
478 |
+
# Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLe
|
479 |
+
# JLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE
|
480 |
+
# 1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9Hda
|
481 |
+
# XFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbO
|
482 |
+
# byMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYID
|
483 |
+
# djCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
|
484 |
+
# Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg
|
485 |
+
# VGltZVN0YW1waW5nIENBAhAFRK/zlJ0IOaa/2z9f5WEWMA0GCWCGSAFlAwQCAQUA
|
486 |
+
# oIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcN
|
487 |
+
# MjQxMDAxMDQwMTM0WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBRm8CsywsLJD4Jd
|
488 |
+
# zqqKycZPGZzPQDAvBgkqhkiG9w0BCQQxIgQg+mfC3NAx+M6Cygg3D0SkGTrvzQ8B
|
489 |
+
# 9bqgawhsUJ470+wwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQg0vbkbe10IszR1EBX
|
490 |
+
# aEE2b4KK2lWarjMWr00amtQMeCgwDQYJKoZIhvcNAQEBBQAEggIAPQTmknzC/bxA
|
491 |
+
# R80O2wqE2uhGFxAM8LCA/4cnf+tAcKFDa7XiMsy43Fy1WZTIl6YTYBb9BH1LN3jV
|
492 |
+
# tyigjGYkDiuQh1cYPMGRi3jhz4ksn4RdhIpZiDpdw5JZ72jAkprXbOVQMOTlFKgC
|
493 |
+
# mP0qLe8uZZ8i67gCEmu+rCec1cnFzWqXCRezFN1kyEmhwXvCAQN8nY0fCgKNK4z3
|
494 |
+
# +942jESOqFO6U+63mJBbWiV5bAfwVwOErbaNFNe220k8CBCTZ9hLwCbNuBPJ+KKb
|
495 |
+
# ItceQjV7D98geQBl6660NToaIecrCSKvJy6UcdempaD9hphwsIZZ6WMRTkHdYa81
|
496 |
+
# Xc+GDHDM18y+TOzbr48yJIt14b1xJ1pRStFe96zHIXB9ZqGqjFNz43j1Im6UeFvc
|
497 |
+
# o0nPEs3+JVsAwpMU5+B0YWHsRUELypC+v3AhUhXdN3/8gNmBr4pGK/4nDBP77bcN
|
498 |
+
# g7XrQ7enT4qgENybvesuaSXVsVzP+4ioNr2Bryh2dlqVgcf+poPDzHPk72gjhBsg
|
499 |
+
# 1dX1YI3RQL4LWqer1XfxOX+D1f/IVitOJe5dMkEDI/K1M5fJQPeN1zYIwTRhaqnt
|
500 |
+
# ggph5XFXqLTMhEyo4KCH5uHfNQpDFtAJlaReS8hJeMXtKkutzzw8BaaiiGqKWH/R
|
501 |
+
# BZ8EctqWxWV896P76lZ1tPGUS+PTBT4=
|
502 |
+
# SIG # End signature block
|
GradioLMstudioInterface.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import requests
|
3 |
+
|
4 |
+
# LM Studio REST API base URL
|
5 |
+
BASE_URL = "http://localhost:1234/api/v0"
|
6 |
+
|
7 |
+
# Function to handle chat completions
|
8 |
+
def chat_with_lmstudio(messages):
|
9 |
+
url = f"{BASE_URL}/chat/completions"
|
10 |
+
payload = {
|
11 |
+
"model": "granite-3.0-2b-instruct", # Replace with the model you have loaded
|
12 |
+
"messages": messages,
|
13 |
+
"temperature": 0.7,
|
14 |
+
"max_tokens": 1024,
|
15 |
+
"stream": False
|
16 |
+
}
|
17 |
+
response = requests.post(url, json=payload)
|
18 |
+
response.raise_for_status()
|
19 |
+
response_data = response.json()
|
20 |
+
return response_data['choices'][0]['message']['content']
|
21 |
+
|
22 |
+
# Function to handle text completions
|
23 |
+
def get_text_completion(prompt):
|
24 |
+
url = f"{BASE_URL}/completions"
|
25 |
+
payload = {
|
26 |
+
"model": "granite-3.0-2b-instruct", # Replace with the model you have loaded
|
27 |
+
"prompt": prompt,
|
28 |
+
"temperature": 0.7,
|
29 |
+
"max_tokens": 100,
|
30 |
+
"stream": False
|
31 |
+
}
|
32 |
+
response = requests.post(url, json=payload)
|
33 |
+
response.raise_for_status()
|
34 |
+
response_data = response.json()
|
35 |
+
return response_data['choices'][0]['text']
|
36 |
+
|
37 |
+
# Function to handle text embeddings
|
38 |
+
def get_text_embedding(text):
|
39 |
+
url = f"{BASE_URL}/embeddings"
|
40 |
+
payload = {
|
41 |
+
"model": "text-embedding-nomic-embed-text-v1.5", # Replace with your embedding model
|
42 |
+
"input": text
|
43 |
+
}
|
44 |
+
response = requests.post(url, json=payload)
|
45 |
+
response.raise_for_status()
|
46 |
+
response_data = response.json()
|
47 |
+
return response_data['data'][0]['embedding']
|
48 |
+
|
49 |
+
# Gradio interface for chat
|
50 |
+
def gradio_chat_interface():
|
51 |
+
def chat_interface(user_input, history):
|
52 |
+
# Format history in LM Studio messages format
|
53 |
+
messages = []
|
54 |
+
for user_msg, assistant_msg in history:
|
55 |
+
messages.append({"role": "user", "content": user_msg})
|
56 |
+
messages.append({"role": "assistant", "content": assistant_msg})
|
57 |
+
messages.append({"role": "user", "content": user_input})
|
58 |
+
|
59 |
+
# Get response from LM Studio
|
60 |
+
response = chat_with_lmstudio(messages)
|
61 |
+
|
62 |
+
# Update history with the assistant's response
|
63 |
+
history.append((user_input, response))
|
64 |
+
return history, history
|
65 |
+
|
66 |
+
chat_interface = gr.ChatInterface(chat_interface)
|
67 |
+
chat_interface.launch()
|
68 |
+
|
69 |
+
# Gradio interface for text completion
|
70 |
+
def gradio_text_completion():
|
71 |
+
gr.Interface(
|
72 |
+
fn=get_text_completion,
|
73 |
+
inputs="text",
|
74 |
+
outputs="text",
|
75 |
+
title="Text Completion with LM Studio"
|
76 |
+
).launch()
|
77 |
+
|
78 |
+
# Gradio interface for text embedding
|
79 |
+
def gradio_text_embedding():
|
80 |
+
gr.Interface(
|
81 |
+
fn=get_text_embedding,
|
82 |
+
inputs="text",
|
83 |
+
outputs="text",
|
84 |
+
title="Text Embedding with LM Studio"
|
85 |
+
).launch()
|
86 |
+
|
87 |
+
# Main menu to choose the interface
|
88 |
+
def main():
|
89 |
+
with gr.Blocks() as demo:
|
90 |
+
gr.Markdown("""
|
91 |
+
# LM Studio API Interface
|
92 |
+
Choose which function you want to use with LM Studio:
|
93 |
+
""")
|
94 |
+
|
95 |
+
with gr.Row():
|
96 |
+
gr.Button("Chat with Model").click(gradio_chat_interface)
|
97 |
+
gr.Button("Text Completion").click(gradio_text_completion)
|
98 |
+
gr.Button("Text Embedding").click(gradio_text_embedding)
|
99 |
+
|
100 |
+
demo.launch()
|
101 |
+
|
102 |
+
if __name__ == "__main__":
|
103 |
+
main()
|
README.md
CHANGED
@@ -1,12 +1,6 @@
|
|
1 |
---
|
2 |
title: Scripts
|
3 |
-
|
4 |
-
colorFrom: green
|
5 |
-
colorTo: gray
|
6 |
sdk: gradio
|
7 |
sdk_version: 5.7.1
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
title: Scripts
|
3 |
+
app_file: GradioLMstudioInterface.py
|
|
|
|
|
4 |
sdk: gradio
|
5 |
sdk_version: 5.7.1
|
|
|
|
|
6 |
---
|
|
|
|
__pycache__/main.cpython-312.pyc
ADDED
Binary file (5.42 kB). View file
|
|
__pycache__/main2.cpython-312.pyc
ADDED
Binary file (8.69 kB). View file
|
|
activate
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file must be used with "source bin/activate" *from bash*
|
2 |
+
# You cannot run it directly
|
3 |
+
|
4 |
+
deactivate () {
|
5 |
+
# reset old environment variables
|
6 |
+
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
7 |
+
PATH="${_OLD_VIRTUAL_PATH:-}"
|
8 |
+
export PATH
|
9 |
+
unset _OLD_VIRTUAL_PATH
|
10 |
+
fi
|
11 |
+
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
12 |
+
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
13 |
+
export PYTHONHOME
|
14 |
+
unset _OLD_VIRTUAL_PYTHONHOME
|
15 |
+
fi
|
16 |
+
|
17 |
+
# Call hash to forget past commands. Without forgetting
|
18 |
+
# past commands the $PATH changes we made may not be respected
|
19 |
+
hash -r 2> /dev/null
|
20 |
+
|
21 |
+
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
22 |
+
PS1="${_OLD_VIRTUAL_PS1:-}"
|
23 |
+
export PS1
|
24 |
+
unset _OLD_VIRTUAL_PS1
|
25 |
+
fi
|
26 |
+
|
27 |
+
unset VIRTUAL_ENV
|
28 |
+
unset VIRTUAL_ENV_PROMPT
|
29 |
+
if [ ! "${1:-}" = "nondestructive" ] ; then
|
30 |
+
# Self destruct!
|
31 |
+
unset -f deactivate
|
32 |
+
fi
|
33 |
+
}
|
34 |
+
|
35 |
+
# unset irrelevant variables
|
36 |
+
deactivate nondestructive
|
37 |
+
|
38 |
+
# on Windows, a path can contain colons and backslashes and has to be converted:
|
39 |
+
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
|
40 |
+
# transform D:\path\to\venv to /d/path/to/venv on MSYS
|
41 |
+
# and to /cygdrive/d/path/to/venv on Cygwin
|
42 |
+
export VIRTUAL_ENV=$(cygpath "C:\Users\alecb\Documents\LLM\venv")
|
43 |
+
else
|
44 |
+
# use the path as-is
|
45 |
+
export VIRTUAL_ENV="C:\Users\alecb\Documents\LLM\venv"
|
46 |
+
fi
|
47 |
+
|
48 |
+
_OLD_VIRTUAL_PATH="$PATH"
|
49 |
+
PATH="$VIRTUAL_ENV/Scripts:$PATH"
|
50 |
+
export PATH
|
51 |
+
|
52 |
+
# unset PYTHONHOME if set
|
53 |
+
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
54 |
+
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
55 |
+
if [ -n "${PYTHONHOME:-}" ] ; then
|
56 |
+
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
57 |
+
unset PYTHONHOME
|
58 |
+
fi
|
59 |
+
|
60 |
+
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
61 |
+
_OLD_VIRTUAL_PS1="${PS1:-}"
|
62 |
+
PS1="(venv) ${PS1:-}"
|
63 |
+
export PS1
|
64 |
+
VIRTUAL_ENV_PROMPT="(venv) "
|
65 |
+
export VIRTUAL_ENV_PROMPT
|
66 |
+
fi
|
67 |
+
|
68 |
+
# Call hash to forget past commands. Without forgetting
|
69 |
+
# past commands the $PATH changes we made may not be respected
|
70 |
+
hash -r 2> /dev/null
|
activate.bat
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
rem This file is UTF-8 encoded, so we need to update the current code page while executing it
|
4 |
+
for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do (
|
5 |
+
set _OLD_CODEPAGE=%%a
|
6 |
+
)
|
7 |
+
if defined _OLD_CODEPAGE (
|
8 |
+
"%SystemRoot%\System32\chcp.com" 65001 > nul
|
9 |
+
)
|
10 |
+
|
11 |
+
set VIRTUAL_ENV=C:\Users\alecb\Documents\LLM\venv
|
12 |
+
|
13 |
+
if not defined PROMPT set PROMPT=$P$G
|
14 |
+
|
15 |
+
if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT%
|
16 |
+
if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%
|
17 |
+
|
18 |
+
set _OLD_VIRTUAL_PROMPT=%PROMPT%
|
19 |
+
set PROMPT=(venv) %PROMPT%
|
20 |
+
|
21 |
+
if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%
|
22 |
+
set PYTHONHOME=
|
23 |
+
|
24 |
+
if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
|
25 |
+
if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%
|
26 |
+
|
27 |
+
set PATH=%VIRTUAL_ENV%\Scripts;%PATH%
|
28 |
+
set VIRTUAL_ENV_PROMPT=(venv)
|
29 |
+
|
30 |
+
:END
|
31 |
+
if defined _OLD_CODEPAGE (
|
32 |
+
"%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul
|
33 |
+
set _OLD_CODEPAGE=
|
34 |
+
)
|
deactivate.bat
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
if defined _OLD_VIRTUAL_PROMPT (
|
4 |
+
set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
|
5 |
+
)
|
6 |
+
set _OLD_VIRTUAL_PROMPT=
|
7 |
+
|
8 |
+
if defined _OLD_VIRTUAL_PYTHONHOME (
|
9 |
+
set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
|
10 |
+
set _OLD_VIRTUAL_PYTHONHOME=
|
11 |
+
)
|
12 |
+
|
13 |
+
if defined _OLD_VIRTUAL_PATH (
|
14 |
+
set "PATH=%_OLD_VIRTUAL_PATH%"
|
15 |
+
)
|
16 |
+
|
17 |
+
set _OLD_VIRTUAL_PATH=
|
18 |
+
|
19 |
+
set VIRTUAL_ENV=
|
20 |
+
set VIRTUAL_ENV_PROMPT=
|
21 |
+
|
22 |
+
:END
|
f2py.exe
ADDED
Binary file (108 kB). View file
|
|
fastapi.exe
ADDED
Binary file (108 kB). View file
|
|
gradio.exe
ADDED
Binary file (108 kB). View file
|
|
httpx.exe
ADDED
Binary file (108 kB). View file
|
|
huggingface-cli.exe
ADDED
Binary file (108 kB). View file
|
|
lmstudio_gradio.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import requests
|
3 |
+
|
4 |
+
# Base URL for LM Studio REST API
|
5 |
+
BASE_URL = "http://localhost:1234/api/v0"
|
6 |
+
|
7 |
+
# Chat completions function
|
8 |
+
def chat_with_lmstudio(messages, model, temperature=0.7, max_tokens=150):
|
9 |
+
endpoint = f"{BASE_URL}/chat/completions"
|
10 |
+
payload = {
|
11 |
+
"model": model,
|
12 |
+
"messages": messages,
|
13 |
+
"temperature": temperature,
|
14 |
+
"max_tokens": max_tokens,
|
15 |
+
"stream": False
|
16 |
+
}
|
17 |
+
try:
|
18 |
+
response = requests.post(endpoint, json=payload)
|
19 |
+
response.raise_for_status()
|
20 |
+
data = response.json()
|
21 |
+
return data["choices"][0]["message"]["content"]
|
22 |
+
except requests.RequestException as e:
|
23 |
+
return f"Error: {str(e)}"
|
24 |
+
|
25 |
+
# Text completions function
|
26 |
+
def text_completion(prompt, model, temperature=0.7, max_tokens=150):
|
27 |
+
endpoint = f"{BASE_URL}/completions"
|
28 |
+
payload = {
|
29 |
+
"model": model,
|
30 |
+
"prompt": prompt,
|
31 |
+
"temperature": temperature,
|
32 |
+
"max_tokens": max_tokens,
|
33 |
+
"stream": False
|
34 |
+
}
|
35 |
+
try:
|
36 |
+
response = requests.post(endpoint, json=payload)
|
37 |
+
response.raise_for_status()
|
38 |
+
data = response.json()
|
39 |
+
return data["choices"][0]["text"]
|
40 |
+
except requests.RequestException as e:
|
41 |
+
return f"Error: {str(e)}"
|
42 |
+
|
43 |
+
# Embeddings function
|
44 |
+
def text_embedding(text, model):
|
45 |
+
endpoint = f"{BASE_URL}/embeddings"
|
46 |
+
payload = {
|
47 |
+
"model": model,
|
48 |
+
"input": text
|
49 |
+
}
|
50 |
+
try:
|
51 |
+
response = requests.post(endpoint, json=payload)
|
52 |
+
response.raise_for_status()
|
53 |
+
data = response.json()
|
54 |
+
return data["data"][0]["embedding"]
|
55 |
+
except requests.RequestException as e:
|
56 |
+
return f"Error: {str(e)}"
|
57 |
+
|
58 |
+
# Gradio Interface
|
59 |
+
def chat_interface(user_message, history, model="granite-3.0-2b-instruct"):
|
60 |
+
if history is None:
|
61 |
+
history = []
|
62 |
+
history.append({"role": "user", "content": user_message})
|
63 |
+
assistant_response = chat_with_lmstudio(history, model=model)
|
64 |
+
history.append({"role": "assistant", "content": assistant_response})
|
65 |
+
conversation = [(h["content"], history[i+1]["content"]) for i, h in enumerate(history[:-1]) if h["role"] == "user"]
|
66 |
+
return conversation, history
|
67 |
+
|
68 |
+
with gr.Blocks() as demo:
|
69 |
+
gr.Markdown("# LM Studio API Interface")
|
70 |
+
|
71 |
+
with gr.Tab("Chat with Model"):
|
72 |
+
chat_history = gr.State([])
|
73 |
+
chat_model = gr.Textbox(value="granite-3.0-2b-instruct", label="Model")
|
74 |
+
chatbot = gr.Chatbot()
|
75 |
+
msg = gr.Textbox(placeholder="Enter your message", label="User Input")
|
76 |
+
submit_btn = gr.Button("Send")
|
77 |
+
submit_btn.click(chat_interface, inputs=[msg, chat_history, chat_model], outputs=[chatbot, chat_history])
|
78 |
+
|
79 |
+
with gr.Tab("Text Completion"):
|
80 |
+
completion_prompt = gr.Textbox(placeholder="Enter a prompt for text completion", label="Prompt")
|
81 |
+
completion_model = gr.Textbox(value="granite-3.0-2b-instruct", label="Model")
|
82 |
+
completion_output = gr.Textbox(label="Completion")
|
83 |
+
generate_btn = gr.Button("Generate")
|
84 |
+
generate_btn.click(text_completion, inputs=[completion_prompt, completion_model], outputs=completion_output)
|
85 |
+
|
86 |
+
with gr.Tab("Text Embeddings"):
|
87 |
+
embedding_text = gr.Textbox(placeholder="Enter text for embeddings", label="Input Text")
|
88 |
+
embedding_model = gr.Textbox(value="text-embedding-nomic-embed-text-v1.5", label="Model")
|
89 |
+
embedding_output = gr.JSON(label="Embeddings")
|
90 |
+
embed_btn = gr.Button("Get Embeddings")
|
91 |
+
embed_btn.click(text_embedding, inputs=[embedding_text, embedding_model], outputs=embedding_output)
|
92 |
+
|
93 |
+
demo.launch(share=True)
|
main.py
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from __future__ import annotations
|
2 |
+
from typing import AsyncIterable, List, Dict
|
3 |
+
import requests
|
4 |
+
from fastapi_poe import PoeBot, QueryRequest, PartialResponse, SettingsRequest, SettingsResponse, make_app
|
5 |
+
from fastapi import Header, HTTPException
|
6 |
+
from modal import Image, App, asgi_app
|
7 |
+
import os
|
8 |
+
|
9 |
+
# LM Studio endpoint configurations (reuse ngrok URL)
|
10 |
+
NGROK_URL = "https://fca7-2601-2c1-280-1320-b881-aac7-9186-9365.ngrok-free.app"
|
11 |
+
LM_STUDIO_CHAT_URL = f"{NGROK_URL}/api/v0/chat/completions"
|
12 |
+
LM_STUDIO_EMBEDDINGS_URL = f"{NGROK_URL}/api/v0/embeddings"
|
13 |
+
|
14 |
+
# Hardcoded model name for LM Studio
|
15 |
+
MODEL_NAME = "bartowski/Qwen2.5-Coder-32B-Instruct-GGUF/Qwen2.5-Coder-32B-Instruct-IQ2_M.gguf"
|
16 |
+
|
17 |
+
# Poe bot access key for the new bot
|
18 |
+
NEW_BOT_ACCESS_KEY = "Kskn3sHdJh7nkVWGcpwcGOIHYSrsML3l"
|
19 |
+
|
20 |
+
# Dictionary to track user-specific conversation history
|
21 |
+
user_histories: Dict[str, List[dict]] = {}
|
22 |
+
|
23 |
+
class main(PoeBot):
|
24 |
+
async def get_response(
|
25 |
+
self, request: QueryRequest, authorization: str = Header(...)
|
26 |
+
) -> AsyncIterable[PartialResponse]:
|
27 |
+
"""
|
28 |
+
Handle user queries dynamically while validating the Poe access key.
|
29 |
+
"""
|
30 |
+
# Validate the Poe access key
|
31 |
+
if authorization != NEW_BOT_ACCESS_KEY:
|
32 |
+
print("Warning: Unauthorized access key used.")
|
33 |
+
# Proceed without raising an error for testing purposes
|
34 |
+
|
35 |
+
# Extract user identifier
|
36 |
+
user_id = request.user_id if hasattr(request, "user_id") else str(hash(request))
|
37 |
+
if not user_id:
|
38 |
+
yield PartialResponse(text="Error: User identifier not provided.")
|
39 |
+
return
|
40 |
+
|
41 |
+
# Extract user message
|
42 |
+
user_message = request.query[-1].content # Latest user input
|
43 |
+
|
44 |
+
# Get or create user-specific conversation history
|
45 |
+
if user_id not in user_histories:
|
46 |
+
user_histories[user_id] = []
|
47 |
+
conversation_history = user_histories[user_id]
|
48 |
+
|
49 |
+
try:
|
50 |
+
# 1. Update conversation history with the user message
|
51 |
+
conversation_history.append({"role": "user", "content": user_message})
|
52 |
+
|
53 |
+
# 2. Generate response based on conversation history
|
54 |
+
response_text = self.get_chat_completion(conversation_history)
|
55 |
+
|
56 |
+
# 3. Add bot response to conversation history
|
57 |
+
conversation_history.append({"role": "assistant", "content": response_text})
|
58 |
+
|
59 |
+
# 4. Yield the response
|
60 |
+
yield PartialResponse(text=response_text.strip())
|
61 |
+
except Exception as e:
|
62 |
+
# Graceful error handling
|
63 |
+
yield PartialResponse(text=f"An error occurred: {e}")
|
64 |
+
|
65 |
+
def get_chat_completion(self, messages: List[dict]) -> str:
|
66 |
+
"""
|
67 |
+
Send a chat completion request to LM Studio's /api/v0/chat/completions endpoint.
|
68 |
+
"""
|
69 |
+
payload = {
|
70 |
+
"model": MODEL_NAME,
|
71 |
+
"messages": messages,
|
72 |
+
"temperature": 0.7, # Adjusted temperature for different bot behavior
|
73 |
+
"max_tokens": 1024, # Increased max tokens
|
74 |
+
"stream": False # Do not use streaming for now
|
75 |
+
}
|
76 |
+
response = requests.post(LM_STUDIO_CHAT_URL, json=payload, timeout=30) # Increased timeout
|
77 |
+
response.raise_for_status()
|
78 |
+
generated_text = response.json().get("choices", [{}])[0].get("message", {}).get("content", "")
|
79 |
+
|
80 |
+
# Fallback in case of empty content
|
81 |
+
if not generated_text:
|
82 |
+
generated_text = "I'm sorry, I couldn't generate a response. Could you please try again?"
|
83 |
+
|
84 |
+
return generated_text
|
85 |
+
|
86 |
+
def get_embeddings(self, text: str) -> str:
|
87 |
+
"""
|
88 |
+
Generate text embeddings using LM Studio's /api/v0/embeddings endpoint.
|
89 |
+
"""
|
90 |
+
payload = {"model": "openai/clip-vit-base-patch32", "input": text} # Update model if needed
|
91 |
+
response = requests.post(LM_STUDIO_EMBEDDINGS_URL, json=payload, timeout=10)
|
92 |
+
response.raise_for_status()
|
93 |
+
embedding = response.json().get("data", [{}])[0].get("embedding", [])
|
94 |
+
return f"Embeddings: {embedding}"
|
95 |
+
|
96 |
+
async def get_settings(self, setting: SettingsRequest) -> SettingsResponse:
|
97 |
+
"""
|
98 |
+
Configure the bot's capabilities for Poe, such as enabling attachments.
|
99 |
+
"""
|
100 |
+
return SettingsResponse(
|
101 |
+
allow_attachments=False, # Disable file uploads for now
|
102 |
+
)
|
103 |
+
|
104 |
+
# Modal configuration for the new bot
|
105 |
+
REQUIREMENTS = ["fastapi-poe==0.0.24", "requests==2.31.0"]
|
106 |
+
image = Image.debian_slim().pip_install(REQUIREMENTS)
|
107 |
+
new_app = App("another-secure-lmstudio-poe-bot")
|
108 |
+
|
109 |
+
@new_app.function(image=image)
|
110 |
+
@asgi_app()
|
111 |
+
def fastapi_app():
|
112 |
+
bot = AnotherSecureLMStudioBot()
|
113 |
+
return make_app(bot, allow_without_key=True)
|
main2.py
ADDED
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from __future__ import annotations
|
2 |
+
from typing import AsyncIterable, Dict, Deque
|
3 |
+
from collections import deque
|
4 |
+
import requests
|
5 |
+
from fastapi_poe import (
|
6 |
+
PoeBot,
|
7 |
+
QueryRequest,
|
8 |
+
PartialResponse,
|
9 |
+
SettingsRequest,
|
10 |
+
SettingsResponse,
|
11 |
+
make_app,
|
12 |
+
)
|
13 |
+
from fastapi import Header
|
14 |
+
from modal import Image, App, asgi_app, Volume, Mount
|
15 |
+
import os
|
16 |
+
import json
|
17 |
+
import re
|
18 |
+
import tempfile
|
19 |
+
import shutil
|
20 |
+
import logging
|
21 |
+
|
22 |
+
# LM Studio endpoint configurations
|
23 |
+
NGROK_URL = "https://fca7-2601-2c1-280-1320-b881-aac7-9186-9365.ngrok-free.app"
|
24 |
+
LM_STUDIO_CHAT_URL = f"{NGROK_URL}/v1/chat/completions"
|
25 |
+
|
26 |
+
# Hardcoded model name for LM Studio
|
27 |
+
MODEL_NAME = "bartowski/Qwen2.5-Coder-32B-Instruct-GGUF/Qwen2.5-Coder-32B-Instruct-IQ2_M.gguf"
|
28 |
+
|
29 |
+
# Poe bot access key for the new bot
|
30 |
+
NEW_BOT_ACCESS_KEY = "YOUR_ACCESS_KEY_HERE" # Replace with your actual access key
|
31 |
+
|
32 |
+
# Path to store conversation history in volume
|
33 |
+
VOLUME_PATH = "/data/user_histories.json"
|
34 |
+
|
35 |
+
# Configure logging
|
36 |
+
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] [%(levelname)s] %(message)s')
|
37 |
+
|
38 |
+
# Dictionary to track user-specific conversation history (initially empty)
|
39 |
+
user_histories: Dict[str, Deque[dict]] = {}
|
40 |
+
|
41 |
+
# Set a maximum number of messages to keep in the history
|
42 |
+
MAX_HISTORY_MESSAGES = 50 # Adjustable based on expected conversation length
|
43 |
+
|
44 |
+
# Load existing conversation history from volume if available
|
45 |
+
if os.path.exists(VOLUME_PATH):
|
46 |
+
try:
|
47 |
+
with open(VOLUME_PATH, "r") as f:
|
48 |
+
user_histories = {
|
49 |
+
user_id: deque(history, maxlen=MAX_HISTORY_MESSAGES)
|
50 |
+
for user_id, history in json.load(f).items()
|
51 |
+
}
|
52 |
+
logging.info("Loaded existing conversation histories.")
|
53 |
+
except Exception as e:
|
54 |
+
logging.error(f"Failed to load user histories: {e}")
|
55 |
+
user_histories = {}
|
56 |
+
else:
|
57 |
+
logging.info("No existing conversation history found. Initializing a new history store.")
|
58 |
+
|
59 |
+
class AnotherSecureLMStudioBot(PoeBot):
|
60 |
+
async def get_response(
|
61 |
+
self, request: QueryRequest, authorization: str = Header(...)
|
62 |
+
) -> AsyncIterable[PartialResponse]:
|
63 |
+
"""
|
64 |
+
Handle user queries dynamically while validating the Poe access key.
|
65 |
+
"""
|
66 |
+
# Validate the Poe access key
|
67 |
+
if authorization != NEW_BOT_ACCESS_KEY:
|
68 |
+
logging.warning("Unauthorized access key used.")
|
69 |
+
# Proceed without raising an error for testing purposes
|
70 |
+
|
71 |
+
# Extract user identifier
|
72 |
+
user_id = self.get_user_id(request)
|
73 |
+
if not user_id:
|
74 |
+
yield PartialResponse(text="Error: User identifier not provided.")
|
75 |
+
return
|
76 |
+
|
77 |
+
# Get or create user-specific conversation history
|
78 |
+
if user_id not in user_histories:
|
79 |
+
user_histories[user_id] = deque(maxlen=MAX_HISTORY_MESSAGES)
|
80 |
+
logging.info(f"Initializing new conversation history for user {user_id}.")
|
81 |
+
conversation_history = user_histories[user_id]
|
82 |
+
|
83 |
+
# Extract the user's message
|
84 |
+
user_message = request.query[-1].content
|
85 |
+
|
86 |
+
# Sanitize user input to prevent injection attacks
|
87 |
+
user_message = re.sub(r"[<>]", "", user_message)
|
88 |
+
|
89 |
+
# Append the user's message to the conversation history
|
90 |
+
conversation_history.append({"role": "user", "content": user_message})
|
91 |
+
|
92 |
+
# Log the conversation history before generating a response
|
93 |
+
logging.info(f"Conversation history for user {user_id}: {list(conversation_history)}")
|
94 |
+
|
95 |
+
try:
|
96 |
+
# Generate response based on conversation history
|
97 |
+
response_text = self.get_chat_completion_with_context(conversation_history)
|
98 |
+
|
99 |
+
# Add bot response to conversation history
|
100 |
+
conversation_history.append({"role": "assistant", "content": response_text})
|
101 |
+
|
102 |
+
# Log the response generated
|
103 |
+
logging.info(f"Generated response for user {user_id}: {response_text}")
|
104 |
+
|
105 |
+
# Save updated conversation history to volume
|
106 |
+
self.save_conversation_history()
|
107 |
+
except Exception as e:
|
108 |
+
# Graceful error handling
|
109 |
+
logging.error(f"An error occurred while processing the request for user {user_id}: {e}")
|
110 |
+
response_text = f"An error occurred: {e}"
|
111 |
+
|
112 |
+
# Yield the response
|
113 |
+
yield PartialResponse(text=response_text.strip())
|
114 |
+
|
115 |
+
def get_user_id(self, request: QueryRequest) -> str:
|
116 |
+
"""
|
117 |
+
Extract or generate a unique user identifier.
|
118 |
+
"""
|
119 |
+
# Use request.user_id if available
|
120 |
+
if hasattr(request, 'user_id') and request.user_id:
|
121 |
+
return request.user_id
|
122 |
+
|
123 |
+
# Fallback: use a fixed identifier
|
124 |
+
return "default_user_id"
|
125 |
+
|
126 |
+
def get_chat_completion_with_context(self, conversation_history: Deque[dict]) -> str:
|
127 |
+
"""
|
128 |
+
Send a chat completion request to LM Studio's /v1/chat/completions endpoint,
|
129 |
+
including the full conversation history.
|
130 |
+
"""
|
131 |
+
# Prepare the payload
|
132 |
+
payload = {
|
133 |
+
"model": MODEL_NAME,
|
134 |
+
"messages": list(conversation_history),
|
135 |
+
"temperature": 0.7, # Adjust as needed
|
136 |
+
"max_tokens": 1024,
|
137 |
+
"stream": False
|
138 |
+
}
|
139 |
+
|
140 |
+
logging.info(f"Sending request to LM Studio with payload:\n{json.dumps(payload, indent=2)}")
|
141 |
+
response = requests.post(LM_STUDIO_CHAT_URL, json=payload, timeout=120)
|
142 |
+
response.raise_for_status()
|
143 |
+
response_data = response.json()
|
144 |
+
|
145 |
+
# Use the assistant response content from the response
|
146 |
+
if "choices" in response_data and len(response_data["choices"]) > 0:
|
147 |
+
generated_text = response_data["choices"][0].get("message", {}).get("content", "")
|
148 |
+
else:
|
149 |
+
generated_text = ""
|
150 |
+
|
151 |
+
# Fallback in case of empty content
|
152 |
+
if not generated_text:
|
153 |
+
generated_text = "I'm sorry, I couldn't generate a response. Could you please try again?"
|
154 |
+
|
155 |
+
return generated_text
|
156 |
+
|
157 |
+
def save_conversation_history(self):
|
158 |
+
"""
|
159 |
+
Save the current conversation history to the volume in an atomic way.
|
160 |
+
"""
|
161 |
+
try:
|
162 |
+
with tempfile.NamedTemporaryFile('w', delete=False) as tmp_file:
|
163 |
+
json.dump(
|
164 |
+
{user_id: list(history) for user_id, history in user_histories.items()},
|
165 |
+
tmp_file,
|
166 |
+
indent=4
|
167 |
+
)
|
168 |
+
temp_file_path = tmp_file.name
|
169 |
+
shutil.move(temp_file_path, VOLUME_PATH)
|
170 |
+
logging.info("Successfully saved user conversation histories.")
|
171 |
+
except Exception as e:
|
172 |
+
logging.error(f"Failed to save user histories: {e}")
|
173 |
+
|
174 |
+
async def get_settings(self, setting: SettingsRequest) -> SettingsResponse:
|
175 |
+
"""
|
176 |
+
Configure the bot's capabilities for Poe, such as enabling attachments.
|
177 |
+
"""
|
178 |
+
return SettingsResponse(
|
179 |
+
allow_attachments=True,
|
180 |
+
allow_images=True,
|
181 |
+
allow_audio=True,
|
182 |
+
allow_video=True,
|
183 |
+
allow_links=True,
|
184 |
+
)
|
185 |
+
|
186 |
+
# Modal configuration for the new bot
|
187 |
+
REQUIREMENTS = ["fastapi-poe==0.0.24", "requests==2.31.0"]
|
188 |
+
image = Image.debian_slim().pip_install(REQUIREMENTS)
|
189 |
+
|
190 |
+
# Mount the volume to persist user histories
|
191 |
+
app = App(
|
192 |
+
"another-secure-lmstudio-poe-bot",
|
193 |
+
mounts=[Mount.from_local_dir("/data", remote_path="/data", recursive=True)]
|
194 |
+
)
|
195 |
+
|
196 |
+
@app.function(image=image)
|
197 |
+
@asgi_app()
|
198 |
+
def fastapi_app():
|
199 |
+
bot = AnotherSecureLMStudioBot()
|
200 |
+
return make_app(bot, allow_without_key=True)
|
mainlpy
ADDED
File without changes
|
markdown-it.exe
ADDED
Binary file (108 kB). View file
|
|
modal.exe
ADDED
Binary file (108 kB). View file
|
|
normalizer.exe
ADDED
Binary file (108 kB). View file
|
|
numpy-config.exe
ADDED
Binary file (108 kB). View file
|
|
pip.exe
ADDED
Binary file (108 kB). View file
|
|
pip3.12.exe
ADDED
Binary file (108 kB). View file
|
|
pip3.exe
ADDED
Binary file (108 kB). View file
|
|
protoc-gen-grpclib_python.exe
ADDED
Binary file (108 kB). View file
|
|
protoc-gen-python_grpc.exe
ADDED
Binary file (108 kB). View file
|
|
pygmentize.exe
ADDED
Binary file (108 kB). View file
|
|
python.exe
ADDED
Binary file (270 kB). View file
|
|
pythonw.exe
ADDED
Binary file (259 kB). View file
|
|
ruff.exe
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2f7e32421471affb6ef0bc7d704f84c2bafeca3be7a1fa7ad664a5553c6071a9
|
3 |
+
size 26956800
|
tqdm.exe
ADDED
Binary file (108 kB). View file
|
|
typer.exe
ADDED
Binary file (108 kB). View file
|
|
upload_theme.exe
ADDED
Binary file (108 kB). View file
|
|
uvicorn.exe
ADDED
Binary file (108 kB). View file
|
|
watchfiles.exe
ADDED
Binary file (108 kB). View file
|
|