@polycode-projects/the-mechanical-code-talker 4.0.0 → 4.1.0
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/README.md +178 -9
- package/corpus/reference/index.json.gz +0 -0
- package/corpus/reference/manifest.json +8 -8
- package/corpus/reference/shards/ref-00.jsonl.gz +0 -0
- package/corpus/sprites/src/sprite-facts.jsonl +401 -0
- package/corpus/worlds/index.json.gz +0 -0
- package/corpus/worlds/manifest.json +49 -9
- package/corpus/worlds/shards/greyvale-museum.jsonl.gz +0 -0
- package/corpus/worlds/shards/lantern-cottage.jsonl.gz +0 -0
- package/corpus/worlds/shards/mud-hollow.jsonl.gz +0 -0
- package/corpus/worlds/shards/mud-warren.jsonl.gz +0 -0
- package/corpus/worlds/shards/spider-fly.jsonl.gz +0 -0
- package/corpus/worlds/src/greyvale-museum.jsonl +136 -0
- package/corpus/worlds/src/lantern-cottage.jsonl +60 -0
- package/corpus/worlds/src/mud-hollow.jsonl +82 -0
- package/corpus/worlds/src/mud-warren.jsonl +124 -0
- package/corpus/worlds/src/spider-fly.jsonl +1 -1
- package/data/sprites/animal-icon.toml +11 -5
- package/data/sprites/book-icon.toml +9 -5
- package/data/sprites/cabinet-icon.toml +10 -5
- package/data/sprites/cellar-icon.toml +16 -6
- package/data/sprites/container-icon.toml +7 -3
- package/data/sprites/desk-icon.toml +8 -5
- package/data/sprites/dog-icon.toml +8 -5
- package/data/sprites/dog-with-colour-icon.toml +13 -12
- package/data/sprites/drawing-room-icon.toml +14 -5
- package/data/sprites/egg-icon.toml +6 -3
- package/data/sprites/fly-icon.toml +10 -5
- package/data/sprites/furniture-icon.toml +5 -3
- package/data/sprites/garden-icon.toml +10 -3
- package/data/sprites/key-icon.toml +3 -1
- package/data/sprites/kitchen-icon.toml +15 -6
- package/data/sprites/lamp-icon.toml +9 -4
- package/data/sprites/letter-icon.toml +7 -4
- package/data/sprites/library-icon.toml +14 -3
- package/data/sprites/pan-icon.toml +7 -3
- package/data/sprites/person-icon.toml +6 -2
- package/data/sprites/poodle-icon.toml +1 -1
- package/data/sprites/portable-icon.toml +6 -4
- package/data/sprites/portrait-icon.toml +7 -4
- package/data/sprites/room-icon.toml +11 -2
- package/data/sprites/spider-icon.toml +9 -3
- package/data/sprites/study-icon.toml +10 -2
- package/package.json +5 -4
- package/src/adapters/memory/core.mjs +20 -0
- package/src/domain/ask-vocab.mjs +71 -0
- package/src/domain/ask.mjs +168 -0
- package/src/domain/game-config.mjs +11 -0
- package/src/domain/grammar/ace.mjs +40 -4
- package/src/domain/grammar/lexicon-core.json +2 -1
- package/src/domain/grammar/lexicon.mjs +18 -0
- package/src/domain/mud-facts.mjs +15 -0
- package/src/domain/reference-pack.mjs +31 -7
- package/src/domain/router/drive.mjs +35 -9
- package/src/domain/router/registry.mjs +24 -4
- package/src/domain/router/resolver.mjs +102 -40
- package/src/domain/scene-compose.mjs +117 -0
- package/src/domain/spider-fly-world.mjs +37 -1
- package/src/domain/sprite-facts.mjs +0 -0
- package/src/domain/sprite-request.mjs +156 -0
- package/src/domain/sprite-templates.mjs +169 -20
- package/src/services/adventure-editor.mjs +8 -14
- package/src/services/adventure-viz.mjs +209 -157
- package/src/services/adventure.mjs +526 -391
- package/src/services/chat-page-viz.mjs +69 -25
- package/src/services/chat.mjs +200 -51
- package/src/services/code-explorer-viz.mjs +102 -62
- package/src/services/extract-facts.mjs +4 -7
- package/src/services/ingest-viz.mjs +68 -82
- package/src/services/ledger-viz.mjs +136 -67
- package/src/services/memory-panel-viz.mjs +62 -0
- package/src/services/mud-editor.mjs +10 -15
- package/src/services/mud-turn.mjs +6 -6
- package/src/services/mud-viz.mjs +1016 -208
- package/src/services/p2p-room.mjs +90 -23
- package/src/services/plan-pddl.mjs +3 -1
- package/src/services/plan-viz.mjs +123 -64
- package/src/services/research-viz.mjs +160 -108
- package/src/services/spider-fly-turn.mjs +15 -23
- package/src/services/spider-fly-viz.mjs +146 -161
- package/src/services/spider-fly.mjs +69 -11
- package/src/services/sprite-catalog-viz.mjs +414 -240
- package/src/services/viz-boot.mjs +71 -0
- package/src/services/viz-room-graph.mjs +203 -0
- package/src/services/viz-theme.mjs +90 -1
- package/src/services/viz-ticker.mjs +22 -0
- package/src/surfaces/web/adventure-browser-entry.mjs +49 -33
- package/src/surfaces/web/chat-browser-entry.mjs +30 -105
- package/src/surfaces/web/code-explorer-browser-entry.mjs +168 -24
- package/src/surfaces/web/ingest-browser-entry.mjs +3 -13
- package/src/surfaces/web/ledger-browser-entry.mjs +7 -47
- package/src/surfaces/web/memory-ask-browser.bundle.js +127 -124
- package/src/surfaces/web/memory-stats.mjs +11 -0
- package/src/surfaces/web/mud-browser-entry.mjs +71 -29
- package/src/surfaces/web/plan-browser-entry.mjs +22 -40
- package/src/surfaces/web/research-browser-entry.mjs +26 -41
- package/src/surfaces/web/spider-fly-browser-entry.mjs +45 -28
- package/src/surfaces/web/sprites-browser-entry.mjs +14 -27
- package/src/surfaces/web/turn-session.mjs +120 -0
- package/src/tools/definitions.mjs +30 -0
- package/src/tools/handlers/index.mjs +6 -3
- package/src/tools/handlers/kit.mjs +19 -2
- package/src/tools/handlers/tmct-ask.mjs +11 -6
- package/src/tools/handlers/tmct-ingest.mjs +5 -1
- package/src/tools/handlers/tmct-related.mjs +4 -4
- package/src/tools/handlers/tmct-sprite.mjs +147 -0
- package/src/tools/memory-fallthrough.mjs +9 -2
- package/src/tools/server.mjs +25 -1
|
@@ -26,50 +26,24 @@
|
|
|
26
26
|
// input. scripts/build-demo-site.mjs calls it directly and writes the result
|
|
27
27
|
// to public/ingest.html, after ingest-browser.bundle.js already exists.
|
|
28
28
|
import { THEME_TOKENS_CSS, SERIF_STACK, MONO_STACK, escapeHtml } from "./viz-theme.mjs";
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
bandLabelFor,
|
|
31
|
+
statsSummaryLine,
|
|
32
|
+
clearSiteAssetCaches,
|
|
33
|
+
fetchWithProgress,
|
|
34
|
+
renderStatsPanelInto,
|
|
35
|
+
loadProgressLine,
|
|
36
|
+
factTripleParts,
|
|
37
|
+
} from "./memory-panel-viz.mjs";
|
|
38
|
+
import { loadWinkVendor } from "./viz-boot.mjs";
|
|
39
|
+
import { cloneMemoryPayload } from "../adapters/memory/core.mjs";
|
|
30
40
|
|
|
31
41
|
const DEFAULT_TITLE = "the-mechanical-code-talker — ingest";
|
|
32
42
|
|
|
33
|
-
/** One grounded fact as a canonical triple line — subject, predicate, object,
|
|
34
|
-
* each in its own cell so the pane can align them. Pure and
|
|
35
|
-
* `.toString()`-splice safe (no outer refs): the inline script splices this
|
|
36
|
-
* in and calls it per row. */
|
|
37
|
-
export function factTripleParts(fact) {
|
|
38
|
-
return {
|
|
39
|
-
subject: String((fact && fact.subject) || ""),
|
|
40
|
-
predicate: String((fact && fact.predicate) || ""),
|
|
41
|
-
object: String((fact && fact.object) || ""),
|
|
42
|
-
provenance: String((fact && fact.provenance) || ""),
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** The boot statusline while the big assets stream in — the same aggregator
|
|
47
|
-
* chat-page-viz.mjs's own loadProgressLine is (kept as this page's own copy
|
|
48
|
-
* rather than a shared import — the two pages' boot lines diverge slightly
|
|
49
|
-
* and neither is a collaborator the other calls). `parts` is an array of
|
|
50
|
-
* { loaded, total } byte counts (total 0 when the response carried no
|
|
51
|
-
* Content-Length); with no usable total the line shows loaded bytes alone
|
|
52
|
-
* rather than inventing a denominator. Self-contained, `.toString()`-splice
|
|
53
|
-
* safe. */
|
|
54
|
-
export function loadProgressLine(parts) {
|
|
55
|
-
const mb = (n) => (n / 1048576).toFixed(1);
|
|
56
|
-
let loaded = 0;
|
|
57
|
-
let total = 0;
|
|
58
|
-
let totalKnown = true;
|
|
59
|
-
for (const p of parts || []) {
|
|
60
|
-
loaded += (p && p.loaded) || 0;
|
|
61
|
-
if (p && p.total > 0) total += p.total;
|
|
62
|
-
else totalKnown = false;
|
|
63
|
-
}
|
|
64
|
-
return totalKnown && total > 0
|
|
65
|
-
? "loading the engine… " + mb(loaded) + " MB / " + mb(total) + " MB"
|
|
66
|
-
: "loading the engine… " + mb(loaded) + " MB";
|
|
67
|
-
}
|
|
68
|
-
|
|
69
43
|
/** The self-contained ingest page. Pure — the same output for the same
|
|
70
44
|
* `title` every time; every piece of state (the session, each grounded fact)
|
|
71
45
|
* is computed live in the browser once the sibling ingest bundle loads. */
|
|
72
|
-
export function renderIngestHtml({ title = DEFAULT_TITLE } = {}) {
|
|
46
|
+
export function renderIngestHtml({ title = DEFAULT_TITLE, seedStamp = "" } = {}) {
|
|
73
47
|
return `<!doctype html>
|
|
74
48
|
<html lang="en">
|
|
75
49
|
<head>
|
|
@@ -83,8 +57,8 @@ export function renderIngestHtml({ title = DEFAULT_TITLE } = {}) {
|
|
|
83
57
|
The wink lemma/POS tier loads from ./vendor/wink.js — the site's own shared
|
|
84
58
|
first-party bundle (built by scripts/build-wink-vendor.mjs), one cached copy
|
|
85
59
|
for every page, no CDN. The ingest engine needs wink to split sentences and
|
|
86
|
-
to parse each teach frame
|
|
87
|
-
recognized"
|
|
60
|
+
to parse each teach frame. A failed load still answers "nothing
|
|
61
|
+
recognized" instead of erroring.
|
|
88
62
|
-->
|
|
89
63
|
<style>
|
|
90
64
|
${THEME_TOKENS_CSS}
|
|
@@ -103,6 +77,13 @@ ${THEME_TOKENS_CSS}
|
|
|
103
77
|
.eyebrow { font-family: ${MONO_STACK}; font-size: .78rem; letter-spacing: .08em; color: var(--muted); }
|
|
104
78
|
.subtitle { font-size: .82rem; color: var(--muted); }
|
|
105
79
|
|
|
80
|
+
/* the live memory count, in the topbar rather than the status line: it is
|
|
81
|
+
the one number that says what this page's memory actually holds, and the
|
|
82
|
+
status line beside the buttons is where a wrong one goes unnoticed. */
|
|
83
|
+
.topbar-right { display: flex; align-items: center; gap: .7rem; }
|
|
84
|
+
.fact-pill { display: inline-flex; align-items: baseline; gap: .34rem; font-family: ${MONO_STACK}; font-size: .66rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--corpus-t1); border-radius: 99px; padding: .2rem .8rem; background: var(--corpus-soft); white-space: nowrap; }
|
|
85
|
+
.fact-pill .fact-pill-value { font-size: .94rem; letter-spacing: 0; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink); }
|
|
86
|
+
|
|
106
87
|
/* mode pills — Text | Document — the translate-tool idiom: two segments in
|
|
107
88
|
one rounded track, the active one filled. */
|
|
108
89
|
.pills { display: inline-flex; border: 1px solid var(--line); border-radius: 99px; overflow: hidden; font-family: ${MONO_STACK}; font-size: .72rem; }
|
|
@@ -140,7 +121,7 @@ ${THEME_TOKENS_CSS}
|
|
|
140
121
|
#facts .fact .pred { color: var(--corpus); white-space: nowrap; }
|
|
141
122
|
#facts .fact .obj { color: var(--ink); word-break: break-word; }
|
|
142
123
|
#facts .fact .prov { grid-column: 1 / -1; color: var(--muted); font-size: .66rem; }
|
|
143
|
-
#facts .empty { color: var(--muted);
|
|
124
|
+
#facts .empty { color: var(--muted); text-align: center; max-width: 24rem; line-height: 1.6; margin: 3rem auto 0; }
|
|
144
125
|
|
|
145
126
|
.actions { flex: 0 0 auto; display: flex; align-items: center; gap: .6rem; padding: .6rem 1.1rem; border-top: 1px solid var(--line); flex-wrap: wrap; }
|
|
146
127
|
.actions .btn { font-family: ${MONO_STACK}; font-size: .74rem; color: var(--ink); border: 1px solid var(--line); border-radius: 6px; padding: .35rem .9rem; background: var(--card); }
|
|
@@ -153,7 +134,7 @@ ${THEME_TOKENS_CSS}
|
|
|
153
134
|
the same class names and breakpoint chat-page-viz.mjs's own docked panel
|
|
154
135
|
uses, re-rendered after boot and after every ingest from
|
|
155
136
|
window.tmctIngest's own memoryStats(). */
|
|
156
|
-
.statsPanel { flex: 0 0 300px; max-width: 300px; overflow-y: auto; border-left: 1px solid var(--line); padding: 1.1rem 1.2rem 1.6rem; font-family: ${MONO_STACK}; font-size: .74rem; line-height: 1.55; }
|
|
137
|
+
.statsPanel { flex: 0 0 300px; max-width: 300px; overflow-y: auto; border-left: 1px solid var(--line); padding: 1.1rem 1.2rem 1.6rem; font-family: ${MONO_STACK}; font-size: .74rem; line-height: 1.55; display: flex; flex-direction: column; }
|
|
157
138
|
.statsPanel h2 { font-size: .66rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); margin: 1.3rem 0 .5rem; }
|
|
158
139
|
.statsPanel h2:first-child { margin-top: 0; }
|
|
159
140
|
.statsPanel .band-row { display: flex; justify-content: space-between; gap: .6rem; margin: 0; padding: .12rem 0; }
|
|
@@ -161,9 +142,12 @@ ${THEME_TOKENS_CSS}
|
|
|
161
142
|
.statsPanel .taught-item { margin: 0 0 .7rem; }
|
|
162
143
|
.statsPanel .taught-tag { display: block; color: var(--muted); font-size: .66rem; margin-top: .15rem; word-break: break-word; }
|
|
163
144
|
.statsPanel .empty { color: var(--muted); margin: 0; }
|
|
164
|
-
|
|
145
|
+
/* The reset action anchors to the bottom of the rail via the auto margin —
|
|
146
|
+
on a tall viewport with little taught yet, that reads as a pinned
|
|
147
|
+
footer control instead of leaving a trailing gap under it. */
|
|
148
|
+
.statsPanel .forget-btn { font-family: ${MONO_STACK}; font-size: .66rem; color: var(--muted); border: 1px solid var(--line); border-radius: 4px; padding: .18rem .55rem; margin-top: auto; background: var(--card); flex: none; }
|
|
165
149
|
.statsPanel .forget-btn:hover { color: var(--ink); }
|
|
166
|
-
.statsPanel .persist-note { color: var(--muted); font-size: .64rem; margin: .4rem 0 0; }
|
|
150
|
+
.statsPanel .persist-note { color: var(--muted); font-size: .64rem; margin: .4rem 0 0; flex: none; }
|
|
167
151
|
|
|
168
152
|
@media (max-width: 860px) {
|
|
169
153
|
.statsPanel { display: none; }
|
|
@@ -179,19 +163,25 @@ ${THEME_TOKENS_CSS}
|
|
|
179
163
|
<header class="topbar">
|
|
180
164
|
<div class="brand">
|
|
181
165
|
<span class="eyebrow">the-mechanical-code-talker</span>
|
|
182
|
-
<span class="subtitle">ingest — paste or drop text
|
|
166
|
+
<span class="subtitle">ingest — paste or drop text. It keeps the facts it can ground and skips the rest.</span>
|
|
183
167
|
</div>
|
|
184
|
-
<div class="
|
|
185
|
-
<
|
|
186
|
-
|
|
168
|
+
<div class="topbar-right">
|
|
169
|
+
<span class="fact-pill" id="factPill" aria-live="polite"
|
|
170
|
+
title="every fact this page's memory holds right now — the starter memory it booted with plus everything it has grounded since">
|
|
171
|
+
<span class="fact-pill-value" id="factPillValue">—</span> facts in memory
|
|
172
|
+
</span>
|
|
173
|
+
<div class="pills" role="group" aria-label="Input mode">
|
|
174
|
+
<button type="button" id="modeText" aria-pressed="true">Text</button>
|
|
175
|
+
<button type="button" id="modeDoc" aria-pressed="false">Document</button>
|
|
176
|
+
</div>
|
|
187
177
|
</div>
|
|
188
178
|
</header>
|
|
189
179
|
<div class="optionsRow" id="optionsRow">
|
|
190
|
-
<label class="optionToggle" title="Loads chat.html's own starter memory (persona, ConceptNet, WordNet and the rest) before ingesting, so a taught fact can link into what it already knows. Off
|
|
180
|
+
<label class="optionToggle" title="Loads chat.html's own starter memory (persona, ConceptNet, WordNet and the rest) before ingesting, so a taught fact can link into what it already knows. Off starts from an empty store, which loads faster.">
|
|
191
181
|
<input type="checkbox" id="seedToggle" checked>
|
|
192
182
|
seed with general knowledge
|
|
193
183
|
</label>
|
|
194
|
-
<label class="optionToggle" title="On a miss, also tries a copula or known relation verb
|
|
184
|
+
<label class="optionToggle" title="On a miss, also tries a copula or a known relation verb between two resolvable entities, tagged optimistic-extract. It ranks below every curated source and can never corroborate one.">
|
|
195
185
|
<input type="checkbox" id="fuzzyToggle">
|
|
196
186
|
fuzzy tier (low-trust candidates)
|
|
197
187
|
</label>
|
|
@@ -234,6 +224,7 @@ ${THEME_TOKENS_CSS}
|
|
|
234
224
|
const loadProgressLine = ${loadProgressLine.toString()};
|
|
235
225
|
const bandLabelFor = ${bandLabelFor.toString()};
|
|
236
226
|
const statsSummaryLine = ${statsSummaryLine.toString()};
|
|
227
|
+
const clearSiteAssetCaches = ${clearSiteAssetCaches.toString()};
|
|
237
228
|
const fetchWithProgress = ${fetchWithProgress.toString()};
|
|
238
229
|
const renderStatsPanelInto = ${renderStatsPanelInto.toString()};
|
|
239
230
|
const el = (id) => document.getElementById(id);
|
|
@@ -256,6 +247,7 @@ ${THEME_TOKENS_CSS}
|
|
|
256
247
|
const seedToggleEl = el("seedToggle");
|
|
257
248
|
const fuzzyToggleEl = el("fuzzyToggle");
|
|
258
249
|
const statsPanelEl = el("statsPanel");
|
|
250
|
+
const factPillValueEl = el("factPillValue");
|
|
259
251
|
|
|
260
252
|
let session = null;
|
|
261
253
|
let grounded = 0; // facts on show in the right pane, from the CURRENT ingest only
|
|
@@ -371,9 +363,10 @@ ${THEME_TOKENS_CSS}
|
|
|
371
363
|
try { stats = await window.tmctIngest.memoryStats(session.memoryDir); }
|
|
372
364
|
catch { return; }
|
|
373
365
|
}
|
|
366
|
+
factPillValueEl.textContent = Number(stats.total || 0).toLocaleString();
|
|
374
367
|
renderStatsPanelInto(statsPanelEl, stats, {
|
|
375
368
|
bandLabel: bandLabelFor,
|
|
376
|
-
taughtHint: "nothing yet
|
|
369
|
+
taughtHint: "nothing yet. Ingest some text and its grounded facts land here, with their source.",
|
|
377
370
|
onForget: persist ? forgetEverything : null,
|
|
378
371
|
persistNote: "taught facts are kept best-effort on this device (IndexedDB), never sent anywhere.",
|
|
379
372
|
});
|
|
@@ -391,6 +384,12 @@ ${THEME_TOKENS_CSS}
|
|
|
391
384
|
try { localStorage.setItem(SEED_PREF_KEY, on ? "on" : "off"); } catch { /* private mode — this visit still works */ }
|
|
392
385
|
}
|
|
393
386
|
|
|
387
|
+
// The build's own content hash for the seed. It rides in the URL this page
|
|
388
|
+
// fetches the seed by, so the service worker's cache-first read can only
|
|
389
|
+
// ever return the copy this page asked for. Empty in a build with no seed.
|
|
390
|
+
const SEED_STAMP = ${JSON.stringify(seedStamp)};
|
|
391
|
+
const SEED_QUERY = SEED_STAMP ? "?b=" + SEED_STAMP : "";
|
|
392
|
+
|
|
394
393
|
let seedPayload = null;
|
|
395
394
|
let seedFacts = 0;
|
|
396
395
|
const progressParts = {};
|
|
@@ -406,7 +405,7 @@ ${THEME_TOKENS_CSS}
|
|
|
406
405
|
async function fetchSeedIfWanted() {
|
|
407
406
|
if (!seedToggleEl.checked) { seedPayload = null; seedFacts = 0; return; }
|
|
408
407
|
try {
|
|
409
|
-
const blob = await fetchWithProgress("./chat-seed.json", (loaded, total) => noteProgress("seed", loaded, total));
|
|
408
|
+
const blob = await fetchWithProgress("./chat-seed.json" + SEED_QUERY, (loaded, total) => noteProgress("seed", loaded, total));
|
|
410
409
|
seedPayload = JSON.parse(await blob.text());
|
|
411
410
|
seedFacts = (seedPayload.individuals || []).filter((i) => i.class === "Fact").length;
|
|
412
411
|
} catch (err) {
|
|
@@ -415,30 +414,14 @@ ${THEME_TOKENS_CSS}
|
|
|
415
414
|
console.warn("tmct ingest: chat-seed.json unavailable — starting unseeded", err);
|
|
416
415
|
}
|
|
417
416
|
}
|
|
418
|
-
|
|
419
|
-
if (!seedPayload) return null;
|
|
420
|
-
try { return structuredClone(seedPayload); } catch { return JSON.parse(JSON.stringify(seedPayload)); }
|
|
421
|
-
}
|
|
417
|
+
const cloneMemoryPayload = ${cloneMemoryPayload.toString()};
|
|
422
418
|
function newSession() {
|
|
423
|
-
return window.tmctIngest.createIngestSession({ seedPayload:
|
|
419
|
+
return window.tmctIngest.createIngestSession({ seedPayload: cloneMemoryPayload(seedPayload), vocabSeeded: Boolean(seedPayload) });
|
|
424
420
|
}
|
|
425
421
|
|
|
426
422
|
// ---- engine boot ---------------------------------------------------------
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
let settled = false;
|
|
430
|
-
const timeout = new Promise((_, reject) => setTimeout(() => { if (!settled) reject(new Error("wink load stalled")); }, WINK_LOAD_TIMEOUT_MS));
|
|
431
|
-
try {
|
|
432
|
-
const mod = await Promise.race([import("./vendor/wink.js"), timeout]);
|
|
433
|
-
settled = true;
|
|
434
|
-
window.tmctIngest.registerWinkModel(() => ({ winkNLP: mod.winkNLP, model: mod.model }));
|
|
435
|
-
return "loaded";
|
|
436
|
-
} catch (err) {
|
|
437
|
-
settled = true;
|
|
438
|
-
console.warn("tmct ingest: the wink vendor asset failed to load; the recognizer needs it to split and parse sentences", err);
|
|
439
|
-
return "unavailable";
|
|
440
|
-
}
|
|
441
|
-
}
|
|
423
|
+
const loadWinkVendor = ${loadWinkVendor.toString()};
|
|
424
|
+
const tryLoadWink = loadWinkVendor({ register: (factory) => window.tmctIngest.registerWinkModel(factory) });
|
|
442
425
|
|
|
443
426
|
// The deploy's own version, read off the service worker file the build
|
|
444
427
|
// already stamps — the only same-origin place the number exists at runtime
|
|
@@ -488,7 +471,7 @@ ${THEME_TOKENS_CSS}
|
|
|
488
471
|
clearFactsPane();
|
|
489
472
|
updateIngestEnabled();
|
|
490
473
|
const stats = await window.tmctIngest.memoryStats(session.memoryDir);
|
|
491
|
-
statusEl.textContent = "forgot everything taught on this device
|
|
474
|
+
statusEl.textContent = "forgot everything taught on this device. Back to the fresh seed (" + statsSummaryLine(stats, bandLabelFor) + ").";
|
|
492
475
|
await renderStatsPanel(stats);
|
|
493
476
|
}
|
|
494
477
|
|
|
@@ -506,7 +489,7 @@ ${THEME_TOKENS_CSS}
|
|
|
506
489
|
session = newSession();
|
|
507
490
|
clearFactsPane();
|
|
508
491
|
const stats = await window.tmctIngest.memoryStats(session.memoryDir);
|
|
509
|
-
statusEl.textContent = statsSummaryLine(stats, bandLabelFor) + "
|
|
492
|
+
statusEl.textContent = statsSummaryLine(stats, bandLabelFor) + ". Ready.";
|
|
510
493
|
await renderStatsPanel(stats);
|
|
511
494
|
updateIngestEnabled();
|
|
512
495
|
sourceEl.focus();
|
|
@@ -514,7 +497,7 @@ ${THEME_TOKENS_CSS}
|
|
|
514
497
|
|
|
515
498
|
async function boot() {
|
|
516
499
|
if (!window.tmctIngest) {
|
|
517
|
-
statusEl.textContent = "the ingest engine didn't load
|
|
500
|
+
statusEl.textContent = "the ingest engine didn't load. This page needs its build step (npm run demo:build)";
|
|
518
501
|
return;
|
|
519
502
|
}
|
|
520
503
|
seedToggleEl.checked = readSeedPref();
|
|
@@ -525,7 +508,7 @@ ${THEME_TOKENS_CSS}
|
|
|
525
508
|
]);
|
|
526
509
|
progressActive = false;
|
|
527
510
|
if (window.tmctIngest.openPersistedStore) {
|
|
528
|
-
persist = window.tmctIngest.openPersistedStore({ storeKey: "ingest", stamp: siteVersion + ":" + seedFacts });
|
|
511
|
+
persist = window.tmctIngest.openPersistedStore({ storeKey: "ingest", stamp: siteVersion + ":" + seedFacts + ":" + SEED_STAMP });
|
|
529
512
|
}
|
|
530
513
|
const savedRecord = persist ? await persist.load() : null;
|
|
531
514
|
session = savedRecord && savedRecord.payload
|
|
@@ -536,9 +519,9 @@ ${THEME_TOKENS_CSS}
|
|
|
536
519
|
const stats = await window.tmctIngest.memoryStats(session.memoryDir);
|
|
537
520
|
const winkPart = winkStatus === "loaded"
|
|
538
521
|
? "wink-nlp: loaded"
|
|
539
|
-
: "wink-nlp unavailable
|
|
522
|
+
: "wink-nlp unavailable. The recognizer can't split sentences without it";
|
|
540
523
|
statusEl.textContent = statsSummaryLine(stats, bandLabelFor) + " \\u00b7 " + winkPart
|
|
541
|
-
+ (savedRecord ? "
|
|
524
|
+
+ (savedRecord ? ". Restored from your last visit." : ". Paste or drop text, then ingest.");
|
|
542
525
|
await renderStatsPanel(stats);
|
|
543
526
|
sourceEl.focus();
|
|
544
527
|
}
|
|
@@ -562,7 +545,7 @@ ${THEME_TOKENS_CSS}
|
|
|
562
545
|
});
|
|
563
546
|
statusEl.textContent = summary.sentences + " sentence" + (summary.sentences === 1 ? "" : "s")
|
|
564
547
|
+ " read, " + summary.recognized + " grounded, " + summary.skipped + " skipped"
|
|
565
|
-
+ (summary.skipped ? " (not a recognized fact shape
|
|
548
|
+
+ (summary.skipped ? " (not a recognized fact shape, as expected)" : "");
|
|
566
549
|
if (!summary.recognized) {
|
|
567
550
|
const empty = factsEl.querySelector(".empty");
|
|
568
551
|
if (!empty) {
|
|
@@ -605,13 +588,16 @@ ${THEME_TOKENS_CSS}
|
|
|
605
588
|
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
606
589
|
});
|
|
607
590
|
|
|
608
|
-
// "reset to seed" is the full re-initialisation: drop
|
|
609
|
-
//
|
|
610
|
-
//
|
|
591
|
+
// "reset to seed" is the full re-initialisation: drop everything this device
|
|
592
|
+
// holds and reload, so boot re-seeds from the page's shipped seed as if on a
|
|
593
|
+
// first visit. Both stores go — what you taught lives in IndexedDB, and the
|
|
594
|
+
// seed asset itself lives in the service worker's Cache Storage, so clearing
|
|
595
|
+
// only the first would re-seed out of a cached copy of an older seed.
|
|
611
596
|
el("reinitStore").addEventListener("click", async () => {
|
|
612
597
|
clearTimeout(saveTimer);
|
|
613
598
|
saveTimer = null;
|
|
614
599
|
if (persist) await persist.clear();
|
|
600
|
+
await clearSiteAssetCaches();
|
|
615
601
|
window.location.reload();
|
|
616
602
|
});
|
|
617
603
|
|