Package not found. Please check the package name and try again.
completion-kit 0.5.0 → 0.5.1
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.
- checksums.yaml +4 -4
- data/README.md +11 -0
- data/app/assets/config/completion_kit_manifest.js +1 -0
- data/app/assets/javascripts/completion_kit/application.js +157 -0
- data/app/assets/stylesheets/completion_kit/application.css +10 -3
- data/app/views/completion_kit/tags/_form.html.erb +1 -0
- data/app/views/layouts/completion_kit/application.html.erb +1 -159
- data/lib/completion_kit/engine.rb +5 -1
- data/lib/completion_kit/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89766aed83665a19253ddf7f4fcbc99ad3e9bc8c17123d7f7d33acac36bf3096
|
|
4
|
+
data.tar.gz: fe71adba78f455a2ce36ef3649bb3e0c94ca77f7534fbe6377604bf6f66d36ab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7dc10c0b796286e5c4535c761da1af4d49d4b1011477167849c8a398644cec30d310534971df8515ff5cda957596589d1277e6942c569b5c943a575a9c2a4e6c
|
|
7
|
+
data.tar.gz: a5a17559fc2032473aa6dd2946948cefd5b195f73dbd48e68c8ead4e322a469a1faca74e170168dad69dd947a88f2687675c007b41a92a91afbacaae752bc50d
|
data/README.md
CHANGED
|
@@ -64,6 +64,17 @@ bin/rails db:migrate
|
|
|
64
64
|
|
|
65
65
|
The engine mounts at `/completion_kit` in your app. CompletionKit's generate and judge flows enqueue Active Job jobs (`CompletionKit::GenerateRowJob`, `CompletionKit::JudgeReviewJob`, `CompletionKit::RunCompletionCheckJob`), so your host app needs an Active Job adapter that actually processes them — Solid Queue, Sidekiq, GoodJob, etc. The `:async` adapter is **not** suitable for production: it runs jobs in the web Puma's thread pool with no durability and no retry, and a long LLM call will block request handling.
|
|
66
66
|
|
|
67
|
+
### Host-app layout integration
|
|
68
|
+
|
|
69
|
+
If your host app overrides the engine layout (e.g. `layout "application"` on engine controllers, or rendering engine views inside your own shell), include both the engine's stylesheet and JavaScript in that layout:
|
|
70
|
+
|
|
71
|
+
```erb
|
|
72
|
+
<%= stylesheet_link_tag "completion_kit/application", media: "all" %>
|
|
73
|
+
<%= javascript_include_tag "completion_kit/application", defer: true %>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Without the JavaScript include, in-page behaviours silently fail: live tag-breadcrumb updates, relative-time ticking, CSV row hover-expand, model-refresh progress, focus-first-error, and local-time formatting.
|
|
77
|
+
|
|
67
78
|
## Providers
|
|
68
79
|
|
|
69
80
|
CompletionKit discovers available models from each provider's API automatically.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
document.addEventListener("turbo:load", function() {
|
|
2
|
+
document.querySelectorAll("[data-local-time]").forEach(function(el) {
|
|
3
|
+
var d = new Date(el.getAttribute("datetime"));
|
|
4
|
+
el.textContent = d.toLocaleString(undefined, {year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"});
|
|
5
|
+
});
|
|
6
|
+
ckTickRelativeTimes();
|
|
7
|
+
ckAutoFocusFirstError();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
document.addEventListener("input", function(e) {
|
|
11
|
+
if (!e.target || e.target.id !== "tag_name") return;
|
|
12
|
+
var text = document.getElementById("tag-pill-text");
|
|
13
|
+
if (!text) return;
|
|
14
|
+
var v = e.target.value.trim().toLowerCase();
|
|
15
|
+
text.textContent = v.length ? v : (text.dataset.placeholder || "");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function ckAutoFocusFirstError() {
|
|
19
|
+
var fieldSelector = "input:not([type=hidden]):not([type=submit]):not([type=button]):not([type=reset]):not([type=file]), textarea, select";
|
|
20
|
+
var marker = document.querySelector("form .ck-flash--alert, form [aria-invalid='true'], form .ck-field-error");
|
|
21
|
+
|
|
22
|
+
var target;
|
|
23
|
+
if (marker) {
|
|
24
|
+
var form = marker.closest("form");
|
|
25
|
+
target = form && (form.querySelector("[aria-invalid='true']") || form.querySelector(fieldSelector));
|
|
26
|
+
} else if (/\/new(\/|$)/.test(window.location.pathname)) {
|
|
27
|
+
target = document.querySelector("form " + fieldSelector);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!target || typeof target.focus !== "function") return;
|
|
31
|
+
target.focus({ preventScroll: false });
|
|
32
|
+
if (typeof target.setSelectionRange === "function" && typeof target.value === "string") {
|
|
33
|
+
try { target.setSelectionRange(target.value.length, target.value.length); } catch (e) {}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ckRelativeTime(then) {
|
|
38
|
+
var seconds = Math.round((Date.now() - then.getTime()) / 1000);
|
|
39
|
+
if (seconds < 5) return "just now";
|
|
40
|
+
if (seconds < 60) return "less than a minute";
|
|
41
|
+
var minutes = Math.round(seconds / 60);
|
|
42
|
+
if (minutes < 60) return minutes === 1 ? "1 minute" : minutes + " minutes";
|
|
43
|
+
var hours = Math.round(minutes / 60);
|
|
44
|
+
if (hours < 24) return hours === 1 ? "about 1 hour" : "about " + hours + " hours";
|
|
45
|
+
var days = Math.round(hours / 24);
|
|
46
|
+
if (days < 30) return days === 1 ? "1 day" : days + " days";
|
|
47
|
+
var months = Math.round(days / 30);
|
|
48
|
+
if (months < 12) return months === 1 ? "about 1 month" : "about " + months + " months";
|
|
49
|
+
var years = Math.round(days / 365);
|
|
50
|
+
return years === 1 ? "about 1 year" : "about " + years + " years";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ckRelativeTimeCompact(then) {
|
|
54
|
+
var seconds = Math.round((Date.now() - then.getTime()) / 1000);
|
|
55
|
+
if (seconds < 60) return "now";
|
|
56
|
+
var minutes = Math.round(seconds / 60);
|
|
57
|
+
if (minutes < 60) return minutes + "m";
|
|
58
|
+
var hours = Math.round(minutes / 60);
|
|
59
|
+
if (hours < 24) return hours + "h";
|
|
60
|
+
var days = Math.round(hours / 24);
|
|
61
|
+
if (days < 30) return days + "d";
|
|
62
|
+
var months = Math.round(days / 30);
|
|
63
|
+
if (months < 12) return months + "mo";
|
|
64
|
+
var years = Math.round(days / 365);
|
|
65
|
+
return years + "y";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function ckTickRelativeTimes() {
|
|
69
|
+
document.querySelectorAll("[data-relative-time]").forEach(function(el) {
|
|
70
|
+
var then = new Date(el.getAttribute("datetime"));
|
|
71
|
+
if (isNaN(then.getTime())) return;
|
|
72
|
+
var verbose = el.getAttribute("data-relative-time") === "verbose";
|
|
73
|
+
el.textContent = verbose ? ckRelativeTime(then) : ckRelativeTimeCompact(then);
|
|
74
|
+
el.setAttribute("title", then.toLocaleString());
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!window.ckRelativeTimeInterval) {
|
|
79
|
+
window.ckRelativeTimeInterval = setInterval(ckTickRelativeTimes, 30000);
|
|
80
|
+
}
|
|
81
|
+
document.addEventListener("turbo:before-stream-render", function() {
|
|
82
|
+
requestAnimationFrame(ckTickRelativeTimes);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
var ckCsvHoverTimer = null;
|
|
86
|
+
var ckCsvHoverRow = null;
|
|
87
|
+
document.addEventListener("mouseover", function(e) {
|
|
88
|
+
var row = e.target.closest && e.target.closest(".ck-csv-table tbody tr");
|
|
89
|
+
if (!row || row === ckCsvHoverRow) return;
|
|
90
|
+
if (ckCsvHoverRow) ckCsvHoverRow.classList.remove("ck-csv-row--expanded");
|
|
91
|
+
ckCsvHoverRow = row;
|
|
92
|
+
clearTimeout(ckCsvHoverTimer);
|
|
93
|
+
ckCsvHoverTimer = setTimeout(function() {
|
|
94
|
+
if (ckCsvHoverRow === row) row.classList.add("ck-csv-row--expanded");
|
|
95
|
+
}, 350);
|
|
96
|
+
});
|
|
97
|
+
document.addEventListener("mouseout", function(e) {
|
|
98
|
+
var row = e.target.closest && e.target.closest(".ck-csv-table tbody tr");
|
|
99
|
+
if (!row) return;
|
|
100
|
+
var related = e.relatedTarget && e.relatedTarget.closest && e.relatedTarget.closest(".ck-csv-table tbody tr");
|
|
101
|
+
if (related === row) return;
|
|
102
|
+
clearTimeout(ckCsvHoverTimer);
|
|
103
|
+
row.classList.remove("ck-csv-row--expanded");
|
|
104
|
+
if (ckCsvHoverRow === row) ckCsvHoverRow = null;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
var ckRefreshing = false;
|
|
108
|
+
function ckRefreshModels() {
|
|
109
|
+
if (ckRefreshing) return;
|
|
110
|
+
ckRefreshing = true;
|
|
111
|
+
var btn = document.querySelector('.ck-icon-btn[title="Refresh models"]');
|
|
112
|
+
if (btn) btn.classList.add('ck-icon-btn--spinning');
|
|
113
|
+
ckUpdateRefreshProgress();
|
|
114
|
+
var csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute("content");
|
|
115
|
+
fetch("/completion_kit/refresh_models", {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: { "X-CSRF-Token": csrfToken }
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function ckUpdateRefreshProgress() {
|
|
122
|
+
var status = document.getElementById('refresh-status');
|
|
123
|
+
if (!status) return;
|
|
124
|
+
var carriers = document.querySelectorAll('[data-refresh-progress-carriers] [id^="discovery_status_"]');
|
|
125
|
+
var totalCurrent = 0, totalTotal = 0, anyDiscovering = false;
|
|
126
|
+
carriers.forEach(function(node) {
|
|
127
|
+
if (!node.querySelector('.ck-discovery-bar')) return;
|
|
128
|
+
if (node.querySelector('.ck-discovery-bar--failed') || node.querySelector('.ck-discovery-bar--completed')) return;
|
|
129
|
+
anyDiscovering = true;
|
|
130
|
+
var match = node.textContent.match(/(\d+)\s*\/\s*(\d+)/);
|
|
131
|
+
if (match) {
|
|
132
|
+
totalCurrent += parseInt(match[1], 10);
|
|
133
|
+
totalTotal += parseInt(match[2], 10);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
if (anyDiscovering || ckRefreshing) {
|
|
137
|
+
if (totalTotal > 0) {
|
|
138
|
+
status.textContent = 'Refreshing models… ' + totalCurrent + '/' + totalTotal;
|
|
139
|
+
} else {
|
|
140
|
+
status.textContent = 'Refreshing models…';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
document.addEventListener("turbo:before-stream-render", function(event) {
|
|
146
|
+
var target = event.target.getAttribute("target");
|
|
147
|
+
if (target && target.indexOf("discovery_status_") === 0) {
|
|
148
|
+
requestAnimationFrame(ckUpdateRefreshProgress);
|
|
149
|
+
}
|
|
150
|
+
if (target === "prompt_llm_model" || target === "run_judge_model") {
|
|
151
|
+
ckRefreshing = false;
|
|
152
|
+
var btn = document.querySelector('.ck-icon-btn[title="Refresh models"]');
|
|
153
|
+
if (btn) btn.classList.remove('ck-icon-btn--spinning');
|
|
154
|
+
var status = document.getElementById('refresh-status');
|
|
155
|
+
if (status) { status.textContent = 'Models updated.'; setTimeout(function() { status.textContent = ' '; }, 3000); }
|
|
156
|
+
}
|
|
157
|
+
});
|
|
@@ -2986,6 +2986,10 @@ a.ck-metric-group-pill {
|
|
|
2986
2986
|
white-space: nowrap;
|
|
2987
2987
|
}
|
|
2988
2988
|
|
|
2989
|
+
.ck-runs-table__identity .tag-marks-row {
|
|
2990
|
+
padding-left: 1.2rem;
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2989
2993
|
.ck-runs-table__config-link {
|
|
2990
2994
|
color: var(--ck-muted);
|
|
2991
2995
|
text-decoration: none;
|
|
@@ -3559,6 +3563,8 @@ a.tag:hover, label.tag:hover { filter: brightness(1.12); }
|
|
|
3559
3563
|
align-items: center;
|
|
3560
3564
|
gap: 5px;
|
|
3561
3565
|
padding: 2px 8px;
|
|
3566
|
+
min-height: 22px;
|
|
3567
|
+
box-sizing: border-box;
|
|
3562
3568
|
border: 1px solid transparent;
|
|
3563
3569
|
border-radius: 4px;
|
|
3564
3570
|
font-family: var(--ck-mono);
|
|
@@ -3644,10 +3650,11 @@ a.tag:hover, label.tag:hover { filter: brightness(1.12); }
|
|
|
3644
3650
|
border-color: var(--ck-line-strong);
|
|
3645
3651
|
color: color-mix(in srgb, var(--mark-color) 80%, var(--ck-text));
|
|
3646
3652
|
}
|
|
3647
|
-
button.tag-mark
|
|
3648
|
-
|
|
3649
|
-
background: color-mix(in srgb, var(--mark-color) 24%, transparent);
|
|
3653
|
+
button.tag-mark {
|
|
3654
|
+
font: inherit;
|
|
3650
3655
|
cursor: pointer;
|
|
3656
|
+
}
|
|
3657
|
+
a.tag-mark {
|
|
3651
3658
|
text-decoration: none;
|
|
3652
3659
|
}
|
|
3653
3660
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<%= favicon_link_tag "completion_kit/logo.svg", type: "image/svg+xml" %>
|
|
10
10
|
<%= stylesheet_link_tag "completion_kit/application", media: "all" %>
|
|
11
11
|
<%= javascript_include_tag "turbo", type: "module" %>
|
|
12
|
+
<%= javascript_include_tag "completion_kit/application", defer: true %>
|
|
12
13
|
<%= action_cable_meta_tag %>
|
|
13
14
|
</head>
|
|
14
15
|
<body class="ck-app">
|
|
@@ -51,164 +52,5 @@
|
|
|
51
52
|
<%= yield %>
|
|
52
53
|
</div>
|
|
53
54
|
</main>
|
|
54
|
-
<script>
|
|
55
|
-
document.addEventListener("turbo:load", function() {
|
|
56
|
-
document.querySelectorAll("[data-local-time]").forEach(function(el) {
|
|
57
|
-
var d = new Date(el.getAttribute("datetime"));
|
|
58
|
-
el.textContent = d.toLocaleString(undefined, {year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"});
|
|
59
|
-
});
|
|
60
|
-
ckTickRelativeTimes();
|
|
61
|
-
ckAutoFocusFirstError();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
document.addEventListener("input", function(e) {
|
|
65
|
-
if (!e.target || e.target.id !== "tag_name") return;
|
|
66
|
-
var text = document.getElementById("tag-pill-text");
|
|
67
|
-
if (!text) return;
|
|
68
|
-
var v = e.target.value.trim().toLowerCase();
|
|
69
|
-
text.textContent = v.length ? v : (text.dataset.placeholder || "");
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
function ckAutoFocusFirstError() {
|
|
73
|
-
var fieldSelector = "input:not([type=hidden]):not([type=submit]):not([type=button]):not([type=reset]):not([type=file]), textarea, select";
|
|
74
|
-
var marker = document.querySelector("form .ck-flash--alert, form [aria-invalid='true'], form .ck-field-error");
|
|
75
|
-
|
|
76
|
-
var target;
|
|
77
|
-
if (marker) {
|
|
78
|
-
var form = marker.closest("form");
|
|
79
|
-
target = form && (form.querySelector("[aria-invalid='true']") || form.querySelector(fieldSelector));
|
|
80
|
-
} else if (/\/new(\/|$)/.test(window.location.pathname)) {
|
|
81
|
-
target = document.querySelector("form " + fieldSelector);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!target || typeof target.focus !== "function") return;
|
|
85
|
-
target.focus({ preventScroll: false });
|
|
86
|
-
if (typeof target.setSelectionRange === "function" && typeof target.value === "string") {
|
|
87
|
-
try { target.setSelectionRange(target.value.length, target.value.length); } catch (e) {}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function ckRelativeTime(then) {
|
|
92
|
-
var seconds = Math.round((Date.now() - then.getTime()) / 1000);
|
|
93
|
-
if (seconds < 5) return "just now";
|
|
94
|
-
if (seconds < 60) return "less than a minute";
|
|
95
|
-
var minutes = Math.round(seconds / 60);
|
|
96
|
-
if (minutes < 60) return minutes === 1 ? "1 minute" : minutes + " minutes";
|
|
97
|
-
var hours = Math.round(minutes / 60);
|
|
98
|
-
if (hours < 24) return hours === 1 ? "about 1 hour" : "about " + hours + " hours";
|
|
99
|
-
var days = Math.round(hours / 24);
|
|
100
|
-
if (days < 30) return days === 1 ? "1 day" : days + " days";
|
|
101
|
-
var months = Math.round(days / 30);
|
|
102
|
-
if (months < 12) return months === 1 ? "about 1 month" : "about " + months + " months";
|
|
103
|
-
var years = Math.round(days / 365);
|
|
104
|
-
return years === 1 ? "about 1 year" : "about " + years + " years";
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function ckRelativeTimeCompact(then) {
|
|
108
|
-
var seconds = Math.round((Date.now() - then.getTime()) / 1000);
|
|
109
|
-
if (seconds < 60) return "now";
|
|
110
|
-
var minutes = Math.round(seconds / 60);
|
|
111
|
-
if (minutes < 60) return minutes + "m";
|
|
112
|
-
var hours = Math.round(minutes / 60);
|
|
113
|
-
if (hours < 24) return hours + "h";
|
|
114
|
-
var days = Math.round(hours / 24);
|
|
115
|
-
if (days < 30) return days + "d";
|
|
116
|
-
var months = Math.round(days / 30);
|
|
117
|
-
if (months < 12) return months + "mo";
|
|
118
|
-
var years = Math.round(days / 365);
|
|
119
|
-
return years + "y";
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function ckTickRelativeTimes() {
|
|
123
|
-
document.querySelectorAll("[data-relative-time]").forEach(function(el) {
|
|
124
|
-
var then = new Date(el.getAttribute("datetime"));
|
|
125
|
-
if (isNaN(then.getTime())) return;
|
|
126
|
-
var verbose = el.getAttribute("data-relative-time") === "verbose";
|
|
127
|
-
el.textContent = verbose ? ckRelativeTime(then) : ckRelativeTimeCompact(then);
|
|
128
|
-
el.setAttribute("title", then.toLocaleString());
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (!window.ckRelativeTimeInterval) {
|
|
133
|
-
window.ckRelativeTimeInterval = setInterval(ckTickRelativeTimes, 30000);
|
|
134
|
-
}
|
|
135
|
-
document.addEventListener("turbo:before-stream-render", function() {
|
|
136
|
-
requestAnimationFrame(ckTickRelativeTimes);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
var ckCsvHoverTimer = null;
|
|
140
|
-
var ckCsvHoverRow = null;
|
|
141
|
-
document.addEventListener("mouseover", function(e) {
|
|
142
|
-
var row = e.target.closest && e.target.closest(".ck-csv-table tbody tr");
|
|
143
|
-
if (!row || row === ckCsvHoverRow) return;
|
|
144
|
-
if (ckCsvHoverRow) ckCsvHoverRow.classList.remove("ck-csv-row--expanded");
|
|
145
|
-
ckCsvHoverRow = row;
|
|
146
|
-
clearTimeout(ckCsvHoverTimer);
|
|
147
|
-
ckCsvHoverTimer = setTimeout(function() {
|
|
148
|
-
if (ckCsvHoverRow === row) row.classList.add("ck-csv-row--expanded");
|
|
149
|
-
}, 350);
|
|
150
|
-
});
|
|
151
|
-
document.addEventListener("mouseout", function(e) {
|
|
152
|
-
var row = e.target.closest && e.target.closest(".ck-csv-table tbody tr");
|
|
153
|
-
if (!row) return;
|
|
154
|
-
var related = e.relatedTarget && e.relatedTarget.closest && e.relatedTarget.closest(".ck-csv-table tbody tr");
|
|
155
|
-
if (related === row) return;
|
|
156
|
-
clearTimeout(ckCsvHoverTimer);
|
|
157
|
-
row.classList.remove("ck-csv-row--expanded");
|
|
158
|
-
if (ckCsvHoverRow === row) ckCsvHoverRow = null;
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
var ckRefreshing = false;
|
|
162
|
-
function ckRefreshModels() {
|
|
163
|
-
if (ckRefreshing) return;
|
|
164
|
-
ckRefreshing = true;
|
|
165
|
-
var btn = document.querySelector('.ck-icon-btn[title="Refresh models"]');
|
|
166
|
-
if (btn) btn.classList.add('ck-icon-btn--spinning');
|
|
167
|
-
ckUpdateRefreshProgress();
|
|
168
|
-
var csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute("content");
|
|
169
|
-
fetch("/completion_kit/refresh_models", {
|
|
170
|
-
method: "POST",
|
|
171
|
-
headers: { "X-CSRF-Token": csrfToken }
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function ckUpdateRefreshProgress() {
|
|
176
|
-
var status = document.getElementById('refresh-status');
|
|
177
|
-
if (!status) return;
|
|
178
|
-
var carriers = document.querySelectorAll('[data-refresh-progress-carriers] [id^="discovery_status_"]');
|
|
179
|
-
var totalCurrent = 0, totalTotal = 0, anyDiscovering = false;
|
|
180
|
-
carriers.forEach(function(node) {
|
|
181
|
-
if (!node.querySelector('.ck-discovery-bar')) return;
|
|
182
|
-
if (node.querySelector('.ck-discovery-bar--failed') || node.querySelector('.ck-discovery-bar--completed')) return;
|
|
183
|
-
anyDiscovering = true;
|
|
184
|
-
var match = node.textContent.match(/(\d+)\s*\/\s*(\d+)/);
|
|
185
|
-
if (match) {
|
|
186
|
-
totalCurrent += parseInt(match[1], 10);
|
|
187
|
-
totalTotal += parseInt(match[2], 10);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
if (anyDiscovering || ckRefreshing) {
|
|
191
|
-
if (totalTotal > 0) {
|
|
192
|
-
status.textContent = 'Refreshing models\u2026 ' + totalCurrent + '/' + totalTotal;
|
|
193
|
-
} else {
|
|
194
|
-
status.textContent = 'Refreshing models\u2026';
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
document.addEventListener("turbo:before-stream-render", function(event) {
|
|
200
|
-
var target = event.target.getAttribute("target");
|
|
201
|
-
if (target && target.indexOf("discovery_status_") === 0) {
|
|
202
|
-
requestAnimationFrame(ckUpdateRefreshProgress);
|
|
203
|
-
}
|
|
204
|
-
if (target === "prompt_llm_model" || target === "run_judge_model") {
|
|
205
|
-
ckRefreshing = false;
|
|
206
|
-
var btn = document.querySelector('.ck-icon-btn[title="Refresh models"]');
|
|
207
|
-
if (btn) btn.classList.remove('ck-icon-btn--spinning');
|
|
208
|
-
var status = document.getElementById('refresh-status');
|
|
209
|
-
if (status) { status.textContent = 'Models updated.'; setTimeout(function() { status.textContent = '\u00a0'; }, 3000); }
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
</script>
|
|
213
55
|
</body>
|
|
214
56
|
</html>
|
|
@@ -8,7 +8,11 @@ module CompletionKit
|
|
|
8
8
|
paths.add "app/services", eager_load: true
|
|
9
9
|
|
|
10
10
|
def self.register_assets(app)
|
|
11
|
-
app.config.assets.precompile += %w(
|
|
11
|
+
app.config.assets.precompile += %w(
|
|
12
|
+
completion_kit/application.css
|
|
13
|
+
completion_kit/application.js
|
|
14
|
+
completion_kit/logo.svg
|
|
15
|
+
)
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
initializer("completion_kit.assets") { |app| Engine.register_assets(app) }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: completion-kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Damien Bastin
|
|
@@ -228,6 +228,7 @@ files:
|
|
|
228
228
|
- app/assets/config/completion_kit_manifest.js
|
|
229
229
|
- app/assets/config/manifest.js
|
|
230
230
|
- app/assets/images/completion_kit/logo.svg
|
|
231
|
+
- app/assets/javascripts/completion_kit/application.js
|
|
231
232
|
- app/assets/stylesheets/completion_kit/application.css
|
|
232
233
|
- app/controllers/completion_kit/api/v1/base_controller.rb
|
|
233
234
|
- app/controllers/completion_kit/api/v1/datasets_controller.rb
|