fix(console): v1.3.90 — deps textarea compact, linter внешние импорты, python env v1.1
- deps textarea: rows=3, resize:none, overflow-y:auto - aiCheck (Python): после линтера проверяет внешние импорты если deps поле пустое — предупреждение с именами модулей - Python env: v1.0 → v1.1 (содержит boto3+requests+psycopg2-binary)
This commit is contained in:
@@ -58,7 +58,7 @@ spec:
|
|||||||
serviceAccountName: fission-console
|
serviceAccountName: fission-console
|
||||||
containers:
|
containers:
|
||||||
- name: console
|
- name: console
|
||||||
image: naeel/fission-console:v1.3.89
|
image: naeel/fission-console:v1.3.90
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8090
|
- containerPort: 8090
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ type LangEnvDef struct {
|
|||||||
// LangEnvMap сопоставляет идентификатор языка (string) с описанием среды выполнения.
|
// LangEnvMap сопоставляет идентификатор языка (string) с описанием среды выполнения.
|
||||||
// Ключ используется в createFunctionRequest.Language и как суффикс имени Environment.
|
// Ключ используется в createFunctionRequest.Language и как суффикс имени Environment.
|
||||||
var LangEnvMap = map[string]LangEnvDef{
|
var LangEnvMap = map[string]LangEnvDef{
|
||||||
"python": {Image: "naeel/fission-python-env:v1.0"},
|
"python": {Image: "naeel/fission-python-env:v1.1"},
|
||||||
"nodejs": {Image: "ghcr.io/fission/node-env"},
|
"nodejs": {Image: "ghcr.io/fission/node-env"},
|
||||||
"go": {Image: "ghcr.io/fission/go-env", BuilderImage: "naeel/go-builder-fast:v1"},
|
"go": {Image: "ghcr.io/fission/go-env", BuilderImage: "naeel/go-builder-fast:v1"},
|
||||||
"php": {Image: "ghcr.io/fission/php-env"},
|
"php": {Image: "ghcr.io/fission/php-env"},
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
<div class="nubes">NUBES</div>
|
<div class="nubes">NUBES</div>
|
||||||
<div class="product">FISSION CONSOLE</div>
|
<div class="product">FISSION CONSOLE</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size:0.65rem; color:var(--text-secondary); margin-left:10px; align-self:center; opacity:0.7;">v1.3.89</div>
|
<div style="font-size:0.65rem; color:var(--text-secondary); margin-left:10px; align-self:center; opacity:0.7;">v1.3.90</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin:0;">
|
<div class="row" style="margin:0;">
|
||||||
<button class="btn ghost" onclick="reloadAll()">Refresh</button>
|
<button class="btn ghost" onclick="reloadAll()">Refresh</button>
|
||||||
@@ -308,9 +308,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="margin-top:10px;">
|
<div style="margin-top:10px;">
|
||||||
<label id="cc-deps-label" style="font-size:12px; color:var(--text-secondary); margin-bottom:4px; display:block;">Зависимости (requirements.txt)</label>
|
<label id="cc-deps-label" style="font-size:12px; color:var(--text-secondary); margin-bottom:4px; display:block;">Зависимости (requirements.txt)</label>
|
||||||
<textarea id="cc-deps" rows="4" placeholder="boto3
|
<textarea id="cc-deps" rows="3" placeholder="boto3
|
||||||
requests>=2.28
|
requests>=2.28
|
||||||
psycopg2-binary" style="width:100%; box-sizing:border-box; font-family:monospace; font-size:12px; background:#1a1a2e; border:1px dashed #3a3a5c; border-radius:4px; color:#cdd6f4; padding:6px 8px; resize:vertical;"></textarea>
|
psycopg2-binary" style="width:100%; box-sizing:border-box; font-family:monospace; font-size:12px; background:#1a1a2e; border:1px dashed #3a3a5c; border-radius:4px; color:#cdd6f4; padding:6px 8px; resize:none; overflow-y:auto;"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="cc-gen-prompt" style="display:none; margin-top:8px; gap:6px; align-items:center;">
|
<div id="cc-gen-prompt" style="display:none; margin-top:8px; gap:6px; align-items:center;">
|
||||||
@@ -453,9 +453,9 @@ psycopg2-binary" style="width:100%; box-sizing:border-box; font-family:monospace
|
|||||||
</div>
|
</div>
|
||||||
<div style="margin-top:10px;">
|
<div style="margin-top:10px;">
|
||||||
<label id="e-deps-label" style="font-size:12px; color:var(--text-secondary); margin-bottom:4px; display:block;">Зависимости (requirements.txt)</label>
|
<label id="e-deps-label" style="font-size:12px; color:var(--text-secondary); margin-bottom:4px; display:block;">Зависимости (requirements.txt)</label>
|
||||||
<textarea id="e-deps" rows="4" placeholder="boto3
|
<textarea id="e-deps" rows="3" placeholder="boto3
|
||||||
requests>=2.28
|
requests>=2.28
|
||||||
psycopg2-binary" style="width:100%; box-sizing:border-box; font-family:monospace; font-size:12px; background:#1a1a2e; border:1px dashed #3a3a5c; border-radius:4px; color:#cdd6f4; padding:6px 8px; resize:vertical;"></textarea>
|
psycopg2-binary" style="width:100%; box-sizing:border-box; font-family:monospace; font-size:12px; background:#1a1a2e; border:1px dashed #3a3a5c; border-radius:4px; color:#cdd6f4; padding:6px 8px; resize:none; overflow-y:auto;"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="e-archive-area" style="display:none;">
|
<div id="e-archive-area" style="display:none;">
|
||||||
@@ -626,7 +626,7 @@ psycopg2-binary" style="width:100%; box-sizing:border-box; font-family:monospace
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions" style="justify-content:space-between; align-items:center;">
|
<div class="actions" style="justify-content:space-between; align-items:center;">
|
||||||
<span style="font-size:0.75rem; color:var(--text-secondary);">v1.3.89</span>
|
<span style="font-size:0.75rem; color:var(--text-secondary);">v1.3.90</span>
|
||||||
<button class="btn ghost" onclick="closeHelp()">Закрыть</button>
|
<button class="btn ghost" onclick="closeHelp()">Закрыть</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+57
-1
@@ -1,5 +1,43 @@
|
|||||||
/* ai.js — AI/LLM функции: проверка, генерация, объяснение, ассистент */
|
/* ai.js — AI/LLM функции: проверка, генерация, объяснение, ассистент */
|
||||||
|
|
||||||
|
// PYTHON_STDLIB — стандартная библиотека Python (не требуют pip install).
|
||||||
|
var PYTHON_STDLIB = new Set([
|
||||||
|
'os','sys','json','time','re','math','io','collections','itertools','functools',
|
||||||
|
'datetime','pathlib','urllib','http','threading','asyncio','logging','random',
|
||||||
|
'string','struct','hashlib','hmac','base64','uuid','copy','abc','typing',
|
||||||
|
'dataclasses','contextlib','enum','warnings','traceback','inspect','importlib',
|
||||||
|
'subprocess','socket','ssl','email','html','xml','csv','sqlite3','unittest',
|
||||||
|
'gc','weakref','array','queue','heapq','bisect','decimal','fractions',
|
||||||
|
'statistics','textwrap','difflib','shutil','glob','fnmatch','tempfile',
|
||||||
|
'zipfile','tarfile','gzip','bz2','lzma','pickle','shelve','codecs',
|
||||||
|
'unicodedata','ast','dis','types','builtins','operator','numbers','cmath',
|
||||||
|
'pprint','reprlib','platform','signal','mmap','ctypes','multiprocessing',
|
||||||
|
'concurrent','select','selectors','errno','atexit','sched','calendar',
|
||||||
|
'locale','gettext','argparse','getopt','shlex','configparser','tokenize',
|
||||||
|
'runpy','pkgutil','site','sysconfig','distutils','zipimport','abc','io',
|
||||||
|
'__future__','_thread','threading','contextvars','netrc','plistlib',
|
||||||
|
'html','xml','http','urllib','email','mailbox','mimetypes','encodings',
|
||||||
|
'codecs','unicodedata','readline','rlcompleter','curses','idlelib','tkinter',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// detectExternalPythonImports — возвращает список модулей, которых нет в stdlib.
|
||||||
|
function detectExternalPythonImports(code) {
|
||||||
|
var external = [];
|
||||||
|
var seen = {};
|
||||||
|
var patterns = [/^import\s+([\w]+)/gm, /^from\s+([\w]+)/gm];
|
||||||
|
for (var pi = 0; pi < patterns.length; pi++) {
|
||||||
|
var m;
|
||||||
|
while ((m = patterns[pi].exec(code)) !== null) {
|
||||||
|
var mod = m[1];
|
||||||
|
if (!PYTHON_STDLIB.has(mod) && !seen[mod]) {
|
||||||
|
seen[mod] = true;
|
||||||
|
external.push(mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return external;
|
||||||
|
}
|
||||||
|
|
||||||
function llmGeneratedWarning(lang) {
|
function llmGeneratedWarning(lang) {
|
||||||
var text = 'Сделано LLM. Не доверяй, проверяй!';
|
var text = 'Сделано LLM. Не доверяй, проверяй!';
|
||||||
switch (lang) {
|
switch (lang) {
|
||||||
@@ -45,7 +83,25 @@ async function aiCheck(codeId, langId, resultId) {
|
|||||||
var data = await requestJSON(API_BASE + '/ai/check', 'POST', { language: lang, code: code });
|
var data = await requestJSON(API_BASE + '/ai/check', 'POST', { language: lang, code: code });
|
||||||
resEl.style.background = data.ok ? '#1a3a1a' : '#3a1a1a';
|
resEl.style.background = data.ok ? '#1a3a1a' : '#3a1a1a';
|
||||||
resEl.style.color = data.ok ? '#8f8' : '#f88';
|
resEl.style.color = data.ok ? '#8f8' : '#f88';
|
||||||
resEl.textContent = data.result || '(пустой ответ)';
|
var resultText = data.result || '(пустой ответ)';
|
||||||
|
|
||||||
|
// Для Python: проверяем внешние импорты vs поле зависимостей
|
||||||
|
if (lang === 'python') {
|
||||||
|
var depsId = codeId.replace('-code', '-deps'); // cc-code→cc-deps, e-code→e-deps
|
||||||
|
var depsEl = document.getElementById(depsId);
|
||||||
|
var depsVal = depsEl ? depsEl.value.trim() : '';
|
||||||
|
var external = detectExternalPythonImports(code);
|
||||||
|
if (external.length > 0 && !depsVal) {
|
||||||
|
resultText += '\n\n⚠️ Внешние библиотеки: ' + external.join(', ') +
|
||||||
|
'\nДобавьте их в поле "Зависимости (requirements.txt)" или убедитесь что они уже есть в Python-окружении.';
|
||||||
|
if (data.ok) {
|
||||||
|
resEl.style.background = '#3a2a00';
|
||||||
|
resEl.style.color = '#ffa';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resEl.textContent = resultText;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
resEl.style.background = '#3a2a00';
|
resEl.style.background = '#3a2a00';
|
||||||
resEl.style.color = '#ffa';
|
resEl.style.color = '#ffa';
|
||||||
|
|||||||
Reference in New Issue
Block a user