diff --git a/expose.cpp b/expose.cpp
index 5ca4a7813..822e9c12f 100644
--- a/expose.cpp
+++ b/expose.cpp
@@ -221,6 +221,10 @@ extern "C"
{
return sdtype_get_ongoing_generation_info();
}
+ void sd_request_ongoing_generation_preview()
+ {
+ sdtype_request_ongoing_generation_preview();
+ }
bool whisper_load_model(const whisper_load_model_inputs inputs)
{
diff --git a/koboldcpp.py b/koboldcpp.py
index 604aabe88..57f72ec78 100644
--- a/koboldcpp.py
+++ b/koboldcpp.py
@@ -1003,6 +1003,8 @@ def init_library():
handle.sd_abort_generation.restype = None
handle.sd_get_ongoing_generation_info.argtypes = []
handle.sd_get_ongoing_generation_info.restype = sd_info_outputs
+ handle.sd_request_ongoing_generation_preview.argtypes = []
+ handle.sd_request_ongoing_generation_preview.restype = None
handle.whisper_load_model.argtypes = [whisper_load_model_inputs]
handle.whisper_load_model.restype = ctypes.c_bool
handle.whisper_generate.argtypes = [whisper_generation_inputs]
@@ -2979,11 +2981,26 @@ def sd_get_ongoing_generation_info():
try:
return json.loads(info.data)
except Exception:
- print("An error occurred while decoding sd ongoig generation info")
+ print("An error occurred while decoding sd ongoing generation info")
else:
- print("An error occurred while getting sd ongoig generation info")
+ print("An error occurred while getting sd ongoing generation info")
return {}
+def parse_query_bool(parsed_dict, key, default=False):
+ value = parsed_dict.get(key, [default])
+ if isinstance(value, list):
+ value = value[0] if value else default
+ if isinstance(value, bool):
+ return value
+ if value is None:
+ return default
+ value = str(value).strip().lower()
+ if value in ('1', 'true', 'yes', 'on'):
+ return True
+ if value in ('0', 'false', 'no', 'off'):
+ return False
+ return default
+
def build_a1111_progress_response(
status: str,
step_count: int = 0,
@@ -3061,12 +3078,14 @@ def build_a1111_progress_response(
}
def a1111_progress_response(preview=False):
+ if preview:
+ handle.sd_request_ongoing_generation_preview()
status = sd_get_ongoing_generation_info()
result = build_a1111_progress_response(
status.get('status', 0),
status.get('step', 0),
status.get('steps', 1),
- status.get('step_time', 1),
+ status.get('elapsed_time', 0),
preview and status.get('preview') or None)
return result
@@ -6584,7 +6603,7 @@ Change Mode
parsed_url = urllib.parse.urlparse(self.path)
parsed_dict = urllib.parse.parse_qs(parsed_url.query)
genkey = parsed_dict.get('genkey', [''])[0]
- skip_current_image = bool(parsed_dict.get('skip_current_image', False))
+ skip_current_image = parse_query_bool(parsed_dict, 'skip_current_image')
# with no auth, reveal status without preview image
auth = bool(genkey and genkey==currgenimgkey)
info = a1111_progress_response(auth and not skip_current_image)
@@ -7731,6 +7750,7 @@ Change Mode
self.end_headers(content_type='application/json')
self.wfile.write(genresp)
except Exception as ex:
+ currgenimgkey = ''
utfprint(ex,1)
print("Generate Image: The response could not be sent, maybe connection was terminated?")
time.sleep(0.2) #short delay
diff --git a/model_adapter.h b/model_adapter.h
index d4b144533..e2711b0c3 100644
--- a/model_adapter.h
+++ b/model_adapter.h
@@ -113,6 +113,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs);
sd_generation_outputs sdtype_upscale(const sd_upscale_inputs inputs);
sd_info_outputs sdtype_get_info();
sd_info_outputs sdtype_get_ongoing_generation_info();
+void sdtype_request_ongoing_generation_preview();
void sdtype_abort_generation();
bool whispertype_load_model(const whisper_load_model_inputs inputs);
diff --git a/otherarch/sdcpp/sdtype_adapter.cpp b/otherarch/sdcpp/sdtype_adapter.cpp
index d0b57f14e..107a4d09b 100644
--- a/otherarch/sdcpp/sdtype_adapter.cpp
+++ b/otherarch/sdcpp/sdtype_adapter.cpp
@@ -161,16 +161,17 @@ static bool is_vid_model = false;
static bool remove_limits = false;
struct gendata_st {
- int status;
- int step;
- double step_time;
+ int status = 0;
+ int step = 0;
+ double step_time = 0.0;
std::string preview;
};
struct {
std::mutex mux;
std::chrono::steady_clock::time_point start_time;
- int steps;
+ int steps = 0;
+ bool preview_requested = false;
gendata_st gendata;
} geninfo;
@@ -574,7 +575,7 @@ bool sdtype_load_model(const sd_load_model_inputs inputs) {
}
}
- sd_set_preview_callback(step_callback, PREVIEW_PROJ, 1, true, false, nullptr);
+ sd_set_preview_callback(step_callback, PREVIEW_PROJ, 1, false, false, nullptr);
if (sddebugmode) {
// the default progress bar would become intermingled with the debug log
@@ -1028,8 +1029,12 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
{
struct CleanupInfoOnExit {
~CleanupInfoOnExit() {
- std::lock_guard lock(geninfo.mux);
- geninfo.gendata.status = 0;
+ {
+ std::lock_guard lock(geninfo.mux);
+ geninfo.gendata.status = 0;
+ geninfo.preview_requested = false;
+ }
+ sd_set_preview_callback(step_callback, PREVIEW_PROJ, 1, false, false, nullptr);
}
} cleanup_info_on_exit;
@@ -1041,9 +1046,12 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
{
std::lock_guard lock(geninfo.mux);
geninfo.start_time = std::chrono::steady_clock::now();
- geninfo.gendata.status = 1;
geninfo.steps = inputs.sample_steps;
+ geninfo.preview_requested = false;
+ geninfo.gendata = {};
+ geninfo.gendata.status = 1;
}
+ sd_set_preview_callback(step_callback, PREVIEW_PROJ, 1, false, false, nullptr);
sd_image_t * results = nullptr;
int generated_num_results = 0;
@@ -1730,6 +1738,15 @@ static inline double get_time_delta(const std::chrono::steady_clock::time_point&
static void step_callback(int step, int frame_count, sd_image_t* image, bool is_noisy, void* data)
{
+ {
+ std::lock_guard lock(geninfo.mux);
+ if (!geninfo.preview_requested) {
+ return;
+ }
+ geninfo.preview_requested = false;
+ }
+ sd_set_preview_callback(step_callback, PREVIEW_PROJ, 1, false, false, nullptr);
+
gendata_st gendata;
gendata.status = 2;
if (frame_count == 1) {
@@ -1737,8 +1754,12 @@ static void step_callback(int step, int frame_count, sd_image_t* image, bool is_
} else {
uint8_t * out_data = nullptr;
size_t out_len = 0;
- create_gif_buf_from_sd_images_msf(image, frame_count, 16, &out_data,&out_len);
- gendata.preview = kcpp_base64_encode(out_data, out_len);
+ if (create_gif_buf_from_sd_images_msf(image, frame_count, 16, &out_data,&out_len) == 0 && out_data && out_len > 0) {
+ gendata.preview = kcpp_base64_encode(out_data, out_len);
+ }
+ if (out_data) {
+ free(out_data);
+ }
}
gendata.step = step;
gendata.step_time = get_time_delta(geninfo.start_time);
@@ -1749,6 +1770,15 @@ static void step_callback(int step, int frame_count, sd_image_t* image, bool is_
geninfo.gendata = gendata;
}
+void sdtype_request_ongoing_generation_preview()
+{
+ std::lock_guard lock(geninfo.mux);
+ if (geninfo.gendata.status != 0) {
+ geninfo.preview_requested = true;
+ sd_set_preview_callback(step_callback, PREVIEW_PROJ, 1, true, false, nullptr);
+ }
+}
+
sd_generation_outputs sdtype_upscale(const sd_upscale_inputs inputs)
{
sd_generation.reset();
@@ -1843,14 +1873,16 @@ sd_info_outputs sdtype_get_info()
sd_info_outputs sdtype_get_ongoing_generation_info()
{
- double elapsed_time;
- int steps;
+ double elapsed_time = 0.0;
+ int steps = 0;
gendata_st gendata;
{
std::lock_guard lock(geninfo.mux);
gendata = geninfo.gendata;
- elapsed_time = get_time_delta(geninfo.start_time);
steps = geninfo.steps;
+ if (gendata.status != 0) {
+ elapsed_time = get_time_delta(geninfo.start_time);
+ }
}
nlohmann::json j;
@@ -1868,7 +1900,7 @@ sd_info_outputs sdtype_get_ongoing_generation_info()
j["status"] = "idle";
j["preview"] = gendata.preview;
- static std::string recent_info;
+ static thread_local std::string recent_info;
recent_info = j.dump();
sd_info_outputs output;
output.status = 0;