Skip to content

Commit c9be4a9

Browse files
authored
js & .yml now conform to Gradio queue_api
Mismatched output format - Old '/gradio_api/call/{event_id}' SSE 'complete' event returned data wrapped as '[function_result]'. Gradio 5's queue API 'process_completed' event returns 'function_result' directly (no outer array). Both callers ('result[0]' for markers, 'result.forEach' for tags) expect the wrapper. Caused 'frames.filter is not a function' and 'result.forEach is not a function' on first test. - Switched '_gradioCall()' to 'POST /gradio_api/queue/join' with 'fn_index' (0 = predict_tags, 1 = predict_markers) + random 'session_hash', SSE stream from '/gradio_api/queue/data' - Parses 'data:' JSON lines for 'msg: "process_completed"' (Gradio 5 SSE v3 format) - Wraps result as '[msg.output.data[0]]' to match old callers' expected shape - Consolidated two URL constants into one 'STASHMARKER_API_BASE' ONNX Space pins 'gradio>=5.0.0' (no minor lock). On container rebuild (cold start, cache eviction), pip resolves to latest Gradio 5.x. Old '/gradio_api/call/' endpoint was never correct for queue-enabled Gradio 5 it worked during testing due to whatever version/cache state the container had at that time. Testing the new endpoint returns tags on inputs that would not appear previously, and the accuracy of the returned tags appears anecdotally to be more accurate than the previous non -ONNX endpoint. Also included an Agnets.md file in the event that a user wants to have an agent work with the API directly. this was sourced from [source](https://huggingface.co/spaces/cc1234/stashtag_onnx/agents.md)
1 parent 7f0f64a commit c9be4a9

2 files changed

Lines changed: 53 additions & 45 deletions

File tree

plugins/stashAI/stashai.js

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
(function () {
22
"use strict";
33

4-
let STASHMARKER_API_URL = "https://cc1234-stashtag-onnx.hf.space/gradio_api/call/predict_tags";
5-
let STASHMARKER_API_MARKER = "https://cc1234-stashtag-onnx.hf.space/gradio_api/call/predict_markers";
4+
let STASHMARKER_API_BASE = "https://cc1234-stashtag-onnx.hf.space";
65

76
var OPTIONS = [
87
"Anal",
@@ -2242,7 +2241,7 @@
22422241
const [, scene_id] = getScenarioAndID();
22432242
let time;
22442243
let tagId;
2245-
const tagLower = frame.tag.label.toLowerCase();
2244+
const tagLower = frame.tag.label.toLowerCase().replace(/_/g, " ");
22462245

22472246
if (tags[tagLower] === undefined) {
22482247
const tagID = await createTag(tagLower);
@@ -2544,38 +2543,44 @@
25442543
});
25452544
}
25462545

2547-
async function gradioCall(url, image, vtt, threshold, retries = 3) {
2546+
async function gradioCall(fn_index, image, vtt, threshold, retries = 3) {
25482547
for (let attempt = 0; attempt < retries; attempt++) {
25492548
try {
2550-
return await _gradioCall(url, image, vtt, threshold);
2549+
return await _gradioCall(fn_index, image, vtt, threshold);
25512550
} catch (err) {
25522551
if (attempt === retries - 1) throw err;
25532552
await new Promise((r) => setTimeout(r, 3000));
25542553
}
25552554
}
25562555
}
25572556

2558-
async function _gradioCall(url, image, vtt, threshold) {
2559-
const body = {
2560-
data: [
2561-
{ url: image, meta: { _type: "gradio.FileData" } },
2562-
vtt,
2563-
threshold,
2564-
],
2565-
};
2557+
async function _gradioCall(fn_index, image, vtt, threshold) {
2558+
const session_hash = crypto.randomUUID
2559+
? crypto.randomUUID()
2560+
: "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
2561+
const r = (Math.random() * 16) | 0;
2562+
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
2563+
});
25662564

2567-
const response = await fetch(url, {
2565+
const queueResponse = await fetch(STASHMARKER_API_BASE + "/gradio_api/queue/join", {
25682566
method: "POST",
25692567
headers: { "Content-Type": "application/json" },
2570-
body: JSON.stringify(body),
2568+
body: JSON.stringify({
2569+
data: [
2570+
{ url: image, meta: { _type: "gradio.FileData" }, orig_name: "sprite.jpg" },
2571+
vtt,
2572+
threshold,
2573+
],
2574+
fn_index: fn_index,
2575+
session_hash: session_hash,
2576+
}),
25712577
});
25722578

2573-
if (!response.ok) {
2574-
throw new Error("HTTP " + response.status);
2579+
if (!queueResponse.ok) {
2580+
throw new Error("HTTP " + queueResponse.status);
25752581
}
25762582

2577-
const { event_id } = await response.json();
2578-
const sseUrl = url + "/" + event_id;
2583+
const sseUrl = STASHMARKER_API_BASE + "/gradio_api/queue/data?session_hash=" + session_hash;
25792584

25802585
const controller = new AbortController();
25812586
const timeout = setTimeout(() => controller.abort(), 120000);
@@ -2591,31 +2596,33 @@
25912596
clearTimeout(timeout);
25922597
}
25932598

2594-
let currentEvent = "";
2595-
let currentData = "";
2596-
2599+
let result;
25972600
for (const line of text.split("\n")) {
2598-
if (line.startsWith("event: ")) {
2599-
currentEvent = line.slice(7).trim();
2600-
} else if (line.startsWith("data: ")) {
2601-
currentData = line.slice(6);
2602-
} else if (line === "") {
2603-
if (currentEvent === "complete") {
2604-
try {
2605-
return JSON.parse(currentData);
2606-
} catch (e) {
2607-
throw new Error("Failed to parse result");
2601+
if (line.startsWith("data: ")) {
2602+
try {
2603+
const msg = JSON.parse(line.slice(6));
2604+
if (msg.msg === "process_completed") {
2605+
if (msg.success === false) {
2606+
throw new Error(msg.output?.error || "Model inference failed");
2607+
}
2608+
result = [msg.output?.data?.[0]];
2609+
break;
26082610
}
2611+
if (msg.msg === "error") {
2612+
throw new Error(msg.output?.error || "API error");
2613+
}
2614+
} catch (e) {
2615+
if (
2616+
e.message === "Model inference failed" ||
2617+
e.message === "API error"
2618+
)
2619+
throw e;
26092620
}
2610-
if (currentEvent === "error") {
2611-
throw new Error(currentData || "API error");
2612-
}
2613-
currentEvent = "";
2614-
currentData = "";
26152621
}
26162622
}
26172623

2618-
throw new Error("No result received");
2624+
if (result === undefined) throw new Error("No result received");
2625+
return result;
26192626
}
26202627

26212628
function instance$3($$self, $$props, $$invalidate) {
@@ -2645,7 +2652,7 @@
26452652
let vtt = await download(vtt_url);
26462653

26472654
try {
2648-
let result = await gradioCall(STASHMARKER_API_MARKER, image, vtt, 0.4);
2655+
let result = await gradioCall(1, image, vtt, 0.4);
26492656
let frames = result[0];
26502657

26512658
$$invalidate(0, (scanner = false));
@@ -2677,7 +2684,7 @@
26772684
$$self.$capture_state = () => ({
26782685
getScenarioAndID,
26792686
getUrlSprite,
2680-
STASHMARKER_API_URL,
2687+
STASHMARKER_API_BASE,
26812688
MarkerMatches,
26822689
scanner,
26832690
download,
@@ -3772,11 +3779,12 @@
37723779
let existingTags = await getTagsForScene(scene_id);
37733780

37743781
for (const [tag] of filteredMatches) {
3775-
let tagLower = tag.toLowerCase();
3782+
const tagNormalized = tag.replace(/_/g, " ");
3783+
let tagLower = tagNormalized.toLowerCase();
37763784

37773785
// if tag doesn't exist, create it
37783786
if (tags[tagLower] === undefined) {
3779-
existingTags.push(await createTag(tag));
3787+
existingTags.push(await createTag(tagNormalized));
37803788
} else if (!existingTags.includes(tags[tagLower])) {
37813789
existingTags.push(tags[tagLower]);
37823790
}
@@ -4075,7 +4083,7 @@
40754083
});
40764084

40774085
try {
4078-
let result = await gradioCall(STASHMARKER_API_URL, image, vtt, 0.2);
4086+
let result = await gradioCall(0, image, vtt, 0.2);
40794087
let tags = {};
40804088
result.forEach((item) => Object.assign(tags, item));
40814089

@@ -4112,7 +4120,7 @@
41124120
$$self.$capture_state = () => ({
41134121
getScenarioAndID,
41144122
getUrlSprite,
4115-
STASHMARKER_API_URL,
4123+
STASHMARKER_API_BASE,
41164124
TagMatches,
41174125
scanner,
41184126
getTags,

plugins/stashAI/stashai.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Stash AI
22
# requires: CommunityScriptsUILibrary
33
description: Add Tags or Markers to a video using AI
4-
version: 1.0.3
4+
version: 1.1.0
55
url: https://discourse.stashapp.cc/t/stash-ai/1392
66
ui:
77
requires:

0 commit comments

Comments
 (0)