llm_meta_widget 0.15.0 → 0.15.2
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/CHANGELOG.md +51 -0
- data/README.md +1 -1
- data/app/assets/javascripts/llm_meta_widget/element.js +57 -5
- data/app/assets/javascripts/llm_meta_widget/llm-meta-widget.js +16 -5
- data/lib/llm_meta_widget/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 863b128096d9e0813388bb13a03d96a8f2b0f202f2aa5c33a27bdd0a48416c7b
|
|
4
|
+
data.tar.gz: e14113a514e1fa7ffb09e067cc44150e32e90a61fb5dd80946b9d7cfb34c6ad6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c1c3f21142b8de93b5a8216472aa700ac7fd72c589ca810f95eb8e3d368a60045974cec8f56a8e6fd64803da7b6a90a18be296312b7f3dc6f42c3c252ccf0f62
|
|
7
|
+
data.tar.gz: 5ee508999c3a2fe61e26f258b4362e4fac981097d7a3c5a375d6dcfe129e75f0d415d0a26d1404c3d2bc99e7f140347851b55609ca157f25bdb0b889b3fe1703
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,57 @@
|
|
|
3
3
|
This file starts at 0.8.0, the first release with a breaking change worth
|
|
4
4
|
calling out. Earlier releases are in the git history (`git log --oneline v0.7.6`).
|
|
5
5
|
|
|
6
|
+
## 0.15.2
|
|
7
|
+
|
|
8
|
+
### A page that hides the model picker now learns the context window too
|
|
9
|
+
|
|
10
|
+
Both requests for the hub's model list sat inside the branches that fill the
|
|
11
|
+
model picker. A page that pins one model and hides the picker therefore never
|
|
12
|
+
learned that model's context window — and hiding the picker is a reasonable
|
|
13
|
+
choice when the host has already chosen the model.
|
|
14
|
+
|
|
15
|
+
Without a window the resource budget falls back to its 8 KB floor, so a page's
|
|
16
|
+
reference data is reported as skipped even when it would have fitted, and
|
|
17
|
+
oversized tool results are neither trimmed nor evicted, because each of those
|
|
18
|
+
steps returns its input unchanged when it has no window to spend. Release
|
|
19
|
+
0.15.1 could not even warn about it: the warning there fires when a request
|
|
20
|
+
comes back unusable, and here no request was made.
|
|
21
|
+
|
|
22
|
+
The model list is now fetched whenever the hub is the provider, and only
|
|
23
|
+
filling the picker remains conditional. A page configured to talk straight to
|
|
24
|
+
Ollama is left alone, since there is no such endpoint to ask.
|
|
25
|
+
|
|
26
|
+
The widget also says so once, in the browser console, if a turn starts with no
|
|
27
|
+
known window — naming the model and what is lost. Three different causes have
|
|
28
|
+
produced an unknown window so far, and each was reported only where it
|
|
29
|
+
happened, if at all.
|
|
30
|
+
|
|
31
|
+
## 0.15.1
|
|
32
|
+
|
|
33
|
+
### A repeat visit no longer loses the model's context window or the hub tools
|
|
34
|
+
|
|
35
|
+
The hub answers `/api/llms` and `/api/mcp_servers` with an ETag and
|
|
36
|
+
`must-revalidate`, so a browser revalidated them on the second page load and
|
|
37
|
+
got `304 Not Modified`. `Response.ok` is false for a 304, and both handlers
|
|
38
|
+
turned that into an empty payload.
|
|
39
|
+
|
|
40
|
+
Nothing announced it. Without the model's context window the resource budget
|
|
41
|
+
fell to its 8 KB floor, so a page's reference data was reported as skipped even
|
|
42
|
+
when it would have fitted; and tool-result truncation and oldest-result
|
|
43
|
+
eviction both stood down, because each returns its input unchanged when it has
|
|
44
|
+
no window to spend. An empty hub list meanwhile showed as "No hub-registered
|
|
45
|
+
tools available". It all worked on a first load and stopped on every one after,
|
|
46
|
+
which is why a hard reload always looked fine.
|
|
47
|
+
|
|
48
|
+
Both requests now set `cache: "no-store"`, so no conditional request is sent
|
|
49
|
+
and the answer always carries a body. A response that is not ok is reported in
|
|
50
|
+
the browser console, naming what is lost, rather than being treated as an empty
|
|
51
|
+
result.
|
|
52
|
+
|
|
53
|
+
The hub stopped sending those ETags as well, so this release is not required to
|
|
54
|
+
fix a page served by an up-to-date hub. It matters for any other server that
|
|
55
|
+
does send them, and for making the next failure audible.
|
|
56
|
+
|
|
6
57
|
## 0.15.0
|
|
7
58
|
|
|
8
59
|
### The declared global is resolved when a handler is needed, not at startup
|
data/README.md
CHANGED
|
@@ -502,9 +502,33 @@ function boot(cfg) {
|
|
|
502
502
|
});
|
|
503
503
|
if (flat.length > 1) modelPicker.style.display = "";
|
|
504
504
|
}));
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
|
|
505
|
+
}
|
|
506
|
+
// The hub answers with each model's context window, and every budget below
|
|
507
|
+
// is derived from it, so ASK REGARDLESS OF THE PICKER. This used to sit
|
|
508
|
+
// inside the picker branches: a page that pinned a model and hid the
|
|
509
|
+
// picker — which is a sensible thing to do, and what the standalone E2E
|
|
510
|
+
// fixture does — never learned the window at all. The resource budget then
|
|
511
|
+
// fell to its 8 KB floor and both tool-result truncation and eviction stood
|
|
512
|
+
// down, each returning its input unchanged without a window. No warning was
|
|
513
|
+
// possible either, because no request was made to fail.
|
|
514
|
+
//
|
|
515
|
+
// Skipped only when talking straight to Ollama, which has no /api/llms.
|
|
516
|
+
if (LLM_PROVIDER !== "ollama") {
|
|
517
|
+
// cache: "no-store" so the browser never sends a conditional request. The
|
|
518
|
+
// hub answers /api/llms with an ETag and must-revalidate, so a REPEAT visit
|
|
519
|
+
// got 304 Not Modified — and Response.ok is false for a 304, which became
|
|
520
|
+
// an empty payload here. The model's context window was then unknown, so
|
|
521
|
+
// the resource budget fell to its 8 KB floor and BOTH tool-result
|
|
522
|
+
// truncation and eviction stood down, each returning unchanged without a
|
|
523
|
+
// window. It worked on a first load and quietly stopped on every one after.
|
|
524
|
+
tasks.push(fetch(LLM_BASE + "/api/llms", { headers: { "Accept": "application/json" }, cache: "no-store" })
|
|
525
|
+
.then(function(r) {
|
|
526
|
+
if (r.ok) return r.json();
|
|
527
|
+
console.warn("[llm-meta-widget] /api/llms answered " + r.status +
|
|
528
|
+
"; the model context window is unknown, so reference data is" +
|
|
529
|
+
" budgeted at the floor and oversized tool results are not trimmed");
|
|
530
|
+
return { llms: [] };
|
|
531
|
+
})
|
|
508
532
|
.then(function(payload) {
|
|
509
533
|
// /api/llms is heterogeneous per family:
|
|
510
534
|
// - OpenAI/Anthropic/Google: `models: [{ name, display_name, ... }]`
|
|
@@ -515,6 +539,13 @@ function boot(cfg) {
|
|
|
515
539
|
// configured model is often hosted while the picker shows local ones.
|
|
516
540
|
llmsPayload = payload;
|
|
517
541
|
modelWindow = modelWindowFrom(payload, MODEL);
|
|
542
|
+
|
|
543
|
+
// The window is the part every page needs; filling the picker is only for
|
|
544
|
+
// pages that show one, and the code below would dereference a null picker.
|
|
545
|
+
// Without this the TypeError only skips the rest of boot, whose
|
|
546
|
+
// remaining job is the picker's change handler — so nothing a
|
|
547
|
+
// no-picker page needs. Kept for intent, not for a visible bug.
|
|
548
|
+
if (!(ENABLE_MODEL_PICKER && modelPicker)) return;
|
|
518
549
|
var flat = [];
|
|
519
550
|
(payload.llms || []).forEach(function(llm) {
|
|
520
551
|
if (llm.family !== "ollama") return;
|
|
@@ -551,8 +582,16 @@ function boot(cfg) {
|
|
|
551
582
|
}
|
|
552
583
|
|
|
553
584
|
if (ENABLE_TOOL_PICKER && toolsListEl) {
|
|
554
|
-
|
|
555
|
-
|
|
585
|
+
// Same reason as /api/llms above: a 304 on a repeat visit emptied this, and
|
|
586
|
+
// the panel then said "No hub-registered tools available" although the hub
|
|
587
|
+
// had them.
|
|
588
|
+
tasks.push(fetch(TOOL_HUB_BASE + "/api/mcp_servers", { headers: { "Accept": "application/json" }, cache: "no-store" })
|
|
589
|
+
.then(function(r) {
|
|
590
|
+
if (r.ok) return r.json();
|
|
591
|
+
console.warn("[llm-meta-widget] /api/mcp_servers answered " + r.status +
|
|
592
|
+
"; hub-registered tools will be listed as unavailable");
|
|
593
|
+
return { mcp_servers: [] };
|
|
594
|
+
})
|
|
556
595
|
.then(function(payload) {
|
|
557
596
|
hubMcpServers = (payload.mcp_servers || []).filter(function(s) {
|
|
558
597
|
return anyAllowedByAllowlist(s.name, HUB_TOOLS_ALLOWLIST);
|
|
@@ -702,6 +741,7 @@ function boot(cfg) {
|
|
|
702
741
|
// call answers, and null forever if the hub is older than the field — in
|
|
703
742
|
// which case the loop budgets nothing, exactly as it always did.
|
|
704
743
|
var modelWindow = null;
|
|
744
|
+
var warnedNoWindow = false;
|
|
705
745
|
// The /api/llms answer, kept so switching model in the picker can resolve
|
|
706
746
|
// that model's window. Without it a visitor who switches from a 262k model
|
|
707
747
|
// to a 32k one keeps the big window — no eviction, and a resource budget
|
|
@@ -1351,6 +1391,18 @@ function boot(cfg) {
|
|
|
1351
1391
|
inputEl.value = "";
|
|
1352
1392
|
appendTurn("user", userText, pendingTurnLabel);
|
|
1353
1393
|
|
|
1394
|
+
// An unknown window is not a small window: every budget below then uses a
|
|
1395
|
+
// floor, and oversized tool results are neither trimmed nor evicted. Say so
|
|
1396
|
+
// once, at the moment it affects an answer. Three separate causes have led
|
|
1397
|
+
// here — a 304 read as empty, a page that hid the model picker, and a model
|
|
1398
|
+
// the hub does not list — and the first two were silent for days.
|
|
1399
|
+
if (!modelWindow && !warnedNoWindow) {
|
|
1400
|
+
warnedNoWindow = true;
|
|
1401
|
+
console.warn("[llm-meta-widget] no context window known for " + MODEL +
|
|
1402
|
+
"; reference data is budgeted at the floor and oversized tool" +
|
|
1403
|
+
" results are not trimmed");
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1354
1406
|
// Reference data that did not fit, reported once per budget, at the moment
|
|
1355
1407
|
// it affects an answer rather than at boot.
|
|
1356
1408
|
// Plan the page's resources first: the refusals are recorded while planning,
|
|
@@ -4269,12 +4269,16 @@ function boot(cfg) {
|
|
|
4269
4269
|
});
|
|
4270
4270
|
if (flat.length > 1) modelPicker.style.display = "";
|
|
4271
4271
|
}));
|
|
4272
|
-
}
|
|
4273
|
-
|
|
4274
|
-
|
|
4272
|
+
}
|
|
4273
|
+
if (LLM_PROVIDER !== "ollama") {
|
|
4274
|
+
tasks.push(fetch(LLM_BASE + "/api/llms", { headers: { "Accept": "application/json" }, cache: "no-store" }).then(function(r) {
|
|
4275
|
+
if (r.ok) return r.json();
|
|
4276
|
+
console.warn("[llm-meta-widget] /api/llms answered " + r.status + "; the model context window is unknown, so reference data is budgeted at the floor and oversized tool results are not trimmed");
|
|
4277
|
+
return { llms: [] };
|
|
4275
4278
|
}).then(function(payload) {
|
|
4276
4279
|
llmsPayload = payload;
|
|
4277
4280
|
modelWindow = modelWindowFrom(payload, MODEL);
|
|
4281
|
+
if (!(ENABLE_MODEL_PICKER && modelPicker)) return;
|
|
4278
4282
|
var flat = [];
|
|
4279
4283
|
(payload.llms || []).forEach(function(llm) {
|
|
4280
4284
|
if (llm.family !== "ollama") return;
|
|
@@ -4304,8 +4308,10 @@ function boot(cfg) {
|
|
|
4304
4308
|
}));
|
|
4305
4309
|
}
|
|
4306
4310
|
if (ENABLE_TOOL_PICKER && toolsListEl) {
|
|
4307
|
-
tasks.push(fetch(TOOL_HUB_BASE + "/api/mcp_servers", { headers: { "Accept": "application/json" } }).then(function(r) {
|
|
4308
|
-
|
|
4311
|
+
tasks.push(fetch(TOOL_HUB_BASE + "/api/mcp_servers", { headers: { "Accept": "application/json" }, cache: "no-store" }).then(function(r) {
|
|
4312
|
+
if (r.ok) return r.json();
|
|
4313
|
+
console.warn("[llm-meta-widget] /api/mcp_servers answered " + r.status + "; hub-registered tools will be listed as unavailable");
|
|
4314
|
+
return { mcp_servers: [] };
|
|
4309
4315
|
}).then(function(payload) {
|
|
4310
4316
|
hubMcpServers = (payload.mcp_servers || []).filter(function(s) {
|
|
4311
4317
|
return anyAllowedByAllowlist(s.name, HUB_TOOLS_ALLOWLIST);
|
|
@@ -4421,6 +4427,7 @@ function boot(cfg) {
|
|
|
4421
4427
|
return Object.assign({}, p, { source: "page" });
|
|
4422
4428
|
});
|
|
4423
4429
|
var modelWindow = null;
|
|
4430
|
+
var warnedNoWindow = false;
|
|
4424
4431
|
var llmsPayload = null;
|
|
4425
4432
|
var resourceContext = null;
|
|
4426
4433
|
var resourcePlan = null;
|
|
@@ -4864,6 +4871,10 @@ function boot(cfg) {
|
|
|
4864
4871
|
if (!userText) return;
|
|
4865
4872
|
inputEl.value = "";
|
|
4866
4873
|
appendTurn("user", userText, pendingTurnLabel);
|
|
4874
|
+
if (!modelWindow && !warnedNoWindow) {
|
|
4875
|
+
warnedNoWindow = true;
|
|
4876
|
+
console.warn("[llm-meta-widget] no context window known for " + MODEL + "; reference data is budgeted at the floor and oversized tool results are not trimmed");
|
|
4877
|
+
}
|
|
4867
4878
|
pageResourcePlansNow();
|
|
4868
4879
|
if (skippedResources.length && !announcedSkips) {
|
|
4869
4880
|
announcedSkips = true;
|