sync: UI animations select styling TLS verify flag via proxy second line brand spacing

This commit is contained in:
2025-09-14 11:54:28 +03:00
parent 11a0535712
commit 81014d26f8
11 changed files with 3633 additions and 1459 deletions

View File

@@ -20,6 +20,18 @@
loop_max_iters: 1000,
loop_time_budget_ms: 10000,
clear_var_store: true,
// New: default HTTP timeout for upstream requests (seconds)
http_timeout_sec: 60,
// New (v1): стратегия извлечения текста для [[OUTx]] (глобальная по умолчанию)
// auto | deep | openai | gemini | claude | jsonpath
text_extract_strategy: 'auto',
// Используется при стратегии jsonpath (dot-нотация, поддержка индексов: a.b.0.c)
text_extract_json_path: '',
// Разделитель при объединении массива результатов
text_join_sep: '\n',
// v2: коллекция пресетов извлечения текста, управляется в "Запуск"
// [{ id, name, strategy, json_path, join_sep }]
text_extract_presets: [],
};
function getPipelineMeta() {
@@ -28,16 +40,45 @@
function updatePipelineMeta(p) {
if (!p || typeof p !== 'object') return;
const keys = ['id','name','parallel_limit','loop_mode','loop_max_iters','loop_time_budget_ms','clear_var_store'];
const keys = [
'id','name','parallel_limit','loop_mode','loop_max_iters','loop_time_budget_ms','clear_var_store','http_timeout_sec',
'text_extract_strategy','text_extract_json_path','text_join_sep','text_join_sep','text_join_SEP',
// v2 presets collection
'text_extract_presets'
];
for (const k of keys) {
if (Object.prototype.hasOwnProperty.call(p, k) && p[k] !== undefined && p[k] !== null && (k === 'clear_var_store' ? true : p[k] !== '')) {
if (k === 'parallel_limit' || k === 'loop_max_iters' || k === 'loop_time_budget_ms') {
const v = parseInt(p[k], 10);
if (!Number.isNaN(v) && v > 0) _pipelineMeta[k] = v;
} else if (k === 'http_timeout_sec') {
const fv = parseFloat(p[k]);
if (!Number.isNaN(fv) && fv > 0) _pipelineMeta[k] = fv;
} else if (k === 'clear_var_store') {
_pipelineMeta[k] = !!p[k];
} else {
_pipelineMeta[k] = String(p[k]);
// спец-обработка коллекции пресетов
if (k === 'text_extract_presets') {
try {
const arr = Array.isArray(p[k]) ? p[k] : [];
_pipelineMeta[k] = arr
.filter(it => it && typeof it === 'object')
.map(it => ({
id: String((it.id ?? '') || ('p' + Date.now().toString(36) + Math.random().toString(36).slice(2))),
name: String(it.name ?? 'Preset'),
strategy: String(it.strategy ?? 'auto'),
json_path: String(it.json_path ?? ''),
join_sep: String(it.join_sep ?? '\n'),
}));
} catch (_) {
_pipelineMeta[k] = [];
}
} else if (k.toLowerCase() === 'text_join_sep') {
// нормализация ключа join separator (допускаем разные написания)
_pipelineMeta['text_join_sep'] = String(p[k]);
} else {
_pipelineMeta[k] = String(p[k]);
}
}
}
}
@@ -60,11 +101,24 @@
const wantIds = {}; // drawflow id -> желаемый/финальный nX
const isValidNid = (s) => typeof s === 'string' && /^n\d+$/i.test(s.trim());
// Helper: вернуть исключительно «живые» данные ноды из редактора (если доступны).
// Это исключает расхождения между DOM.__data и editor.getNodeFromId(..).data.
function mergedNodeData(df, el, dfid) {
try {
const nid = parseInt(dfid, 10);
const n = (w.editor && typeof w.editor.getNodeFromId === 'function') ? w.editor.getNodeFromId(nid) : null;
if (n && n.data) return n.data;
} catch (_) {}
if (df && df.data) return df.data;
// как последний fallback — DOM.__data (почти не используется после этого изменения)
return (el && el.__data) ? el.__data : {};
}
// Первый проход: резервируем существующие валидные _origId
for (const id in dfNodes) {
const df = dfNodes[id];
const el = document.querySelector(`#node-${id}`);
const datacopySrc = el && el.__data ? el.__data : (df.data || {});
const datacopySrc = mergedNodeData(df, el, id);
const tmp = typeof w.applyNodeDefaults === 'function'
? w.applyNodeDefaults(df.name, JSON.parse(JSON.stringify(datacopySrc)))
: (JSON.parse(JSON.stringify(datacopySrc)));
@@ -95,11 +149,22 @@
for (const id in dfNodes) {
const df = dfNodes[id];
const el = document.querySelector(`#node-${id}`);
const datacopySrc = el && el.__data ? el.__data : (df.data || {});
const datacopySrc = mergedNodeData(df, el, id);
const datacopy = typeof w.applyNodeDefaults === 'function'
? w.applyNodeDefaults(df.name, JSON.parse(JSON.stringify(datacopySrc)))
: (JSON.parse(JSON.stringify(datacopySrc)));
try { datacopy._origId = idMap[id]; } catch (e) {}
// Спец-обработка SetVars: гарантированно берём свежие variables из живых данных редактора
try {
if (String(df.name) === 'SetVars') {
const nid = parseInt(id, 10);
const nLive = (w.editor && typeof w.editor.getNodeFromId === 'function') ? w.editor.getNodeFromId(nid) : null;
const v = nLive && nLive.data && Array.isArray(nLive.data.variables) ? nLive.data.variables : (Array.isArray(datacopy.variables) ? datacopy.variables : []);
datacopy.variables = v.map(x => ({ ...(x || {}) })); // глубокая копия
}
} catch (_) {}
nodes.push({
id: idMap[id],
type: df.name,
@@ -205,6 +270,12 @@
loop_max_iters: (typeof meta.loop_max_iters === 'number' ? meta.loop_max_iters : 1000),
loop_time_budget_ms: (typeof meta.loop_time_budget_ms === 'number' ? meta.loop_time_budget_ms : 10000),
clear_var_store: (typeof meta.clear_var_store === 'boolean' ? meta.clear_var_store : true),
http_timeout_sec: (typeof meta.http_timeout_sec === 'number' ? meta.http_timeout_sec : 60),
text_extract_strategy: (meta.text_extract_strategy || 'auto'),
text_extract_json_path: (meta.text_extract_json_path || ''),
text_join_sep: (meta.text_join_sep || '\n'),
// v2: persist presets
text_extract_presets: (Array.isArray(meta.text_extract_presets) ? meta.text_extract_presets : []),
nodes
};
}
@@ -225,6 +296,12 @@
loop_max_iters: (p && typeof p.loop_max_iters === 'number') ? p.loop_max_iters : 1000,
loop_time_budget_ms: (p && typeof p.loop_time_budget_ms === 'number') ? p.loop_time_budget_ms : 10000,
clear_var_store: (p && typeof p.clear_var_store === 'boolean') ? p.clear_var_store : true,
http_timeout_sec: (p && typeof p.http_timeout_sec === 'number') ? p.http_timeout_sec : 60,
text_extract_strategy: (p && typeof p.text_extract_strategy === 'string') ? p.text_extract_strategy : 'auto',
text_extract_json_path: (p && typeof p.text_extract_json_path === 'string') ? p.text_extract_json_path : '',
text_join_sep: (p && typeof p.text_join_sep === 'string') ? p.text_join_sep : '\n',
// v2: presets from pipeline.json
text_extract_presets: (p && Array.isArray(p.text_extract_presets)) ? p.text_extract_presets : [],
});
} catch (e) {}