nai-aclab 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web/main.js +37 -21
- package/web/styles.css +6 -0
- package/web_app.py +4 -1
package/package.json
CHANGED
package/web/main.js
CHANGED
|
@@ -149,20 +149,26 @@ function scheduleSave() {
|
|
|
149
149
|
saveTimer = setTimeout(saveNow, 450);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async function saveNow() {
|
|
153
|
-
if (!state) return;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
async function saveNow() {
|
|
153
|
+
if (!state) return;
|
|
154
|
+
const tokenInput = $("#api_token");
|
|
155
|
+
const hadPendingToken = Boolean(tokenInput?.value.trim());
|
|
156
|
+
syncEditorsToState();
|
|
157
|
+
try {
|
|
158
|
+
const data = await request("/api/state", {
|
|
159
|
+
method: "POST",
|
|
160
|
+
body: JSON.stringify({ state }),
|
|
161
|
+
});
|
|
162
|
+
state = data.state;
|
|
163
|
+
if (hadPendingToken && tokenInput) {
|
|
164
|
+
tokenInput.value = "";
|
|
165
|
+
tokenInput.placeholder = "저장된 토큰을 사용합니다. 새 토큰을 입력하면 교체됩니다.";
|
|
166
|
+
}
|
|
167
|
+
setSaveState(hadPendingToken ? "API 토큰 변경 저장됨" : "자동 저장됨");
|
|
168
|
+
} catch (error) {
|
|
169
|
+
setSaveState("저장 실패");
|
|
170
|
+
console.error(error);
|
|
171
|
+
}
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
function syncEditorsToState() {
|
|
@@ -601,9 +607,17 @@ function renderSettings() {
|
|
|
601
607
|
input.value = key === "token" ? "" : state.api[key] ?? "";
|
|
602
608
|
}
|
|
603
609
|
if (key === "token") {
|
|
604
|
-
input.placeholder = state.api.token_saved
|
|
610
|
+
input.placeholder = state.api.token_saved
|
|
611
|
+
? "저장된 토큰을 사용합니다. 새 토큰을 입력하면 교체됩니다."
|
|
612
|
+
: "API 토큰을 입력하세요";
|
|
605
613
|
input.autocomplete = "off";
|
|
606
|
-
|
|
614
|
+
const help = document.createElement("small");
|
|
615
|
+
help.className = "field-help";
|
|
616
|
+
help.textContent = state.api.token_saved
|
|
617
|
+
? "보안을 위해 저장된 토큰은 다시 표시하지 않습니다. 새 토큰을 입력하고 설정 저장을 누르면 기존 토큰을 교체합니다."
|
|
618
|
+
: "토큰은 브라우저에 다시 노출하지 않고 로컬에만 저장합니다.";
|
|
619
|
+
wrap.appendChild(help);
|
|
620
|
+
}
|
|
607
621
|
if (type === "number") input.step = "any";
|
|
608
622
|
}
|
|
609
623
|
$("#mockMode").checked = !!state.api.mock_mode;
|
|
@@ -1619,11 +1633,13 @@ function bindAutosaveInputs(root = document) {
|
|
|
1619
1633
|
root.querySelectorAll("input, textarea, select").forEach((node) => {
|
|
1620
1634
|
if (node.id === "compareHistorySelect") return;
|
|
1621
1635
|
if (node.id === "deleteFilesToggle" || node.closest("#historyList")) return;
|
|
1622
|
-
if (node.id === "api_token") {
|
|
1623
|
-
node.oninput =
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1636
|
+
if (node.id === "api_token") {
|
|
1637
|
+
node.oninput = () => {
|
|
1638
|
+
setSaveState(node.value.trim() ? "새 API 토큰 입력됨" : "저장된 API 토큰 유지");
|
|
1639
|
+
};
|
|
1640
|
+
node.onchange = () => {
|
|
1641
|
+
syncEditorsToState();
|
|
1642
|
+
scheduleSave();
|
|
1627
1643
|
};
|
|
1628
1644
|
return;
|
|
1629
1645
|
}
|
package/web/styles.css
CHANGED
package/web_app.py
CHANGED
|
@@ -381,7 +381,6 @@ def run_batting_test(job_id: str, state: AppState) -> None:
|
|
|
381
381
|
run_id = now_id()
|
|
382
382
|
out_dir = OUTPUT_DIR / f"{run_id}_타율테스트_{len(scenes)}씬"
|
|
383
383
|
out_dir.mkdir(parents=True, exist_ok=True)
|
|
384
|
-
client = NovelAIClient(state.api)
|
|
385
384
|
items = []
|
|
386
385
|
progress = 0
|
|
387
386
|
JOBS[job_id].update(
|
|
@@ -402,6 +401,7 @@ def run_batting_test(job_id: str, state: AppState) -> None:
|
|
|
402
401
|
JOBS[job_id]["log"].append("중지 요청으로 남은 씬을 건너뜁니다.")
|
|
403
402
|
break
|
|
404
403
|
current = scene_state(state, scene)
|
|
404
|
+
client = NovelAIClient(current.api)
|
|
405
405
|
base = selected_base(current)
|
|
406
406
|
character = selected_character(current)
|
|
407
407
|
count = scene_count(scene)
|
|
@@ -426,6 +426,9 @@ def run_batting_test(job_id: str, state: AppState) -> None:
|
|
|
426
426
|
"scene_index": scene_index,
|
|
427
427
|
"source_base_preset": base.name if base else "",
|
|
428
428
|
"source_character_preset": character.name if character else "",
|
|
429
|
+
"image_size": current.generation.image_size,
|
|
430
|
+
"width": current.api.width,
|
|
431
|
+
"height": current.api.height,
|
|
429
432
|
"created_at": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
430
433
|
}
|
|
431
434
|
try:
|