@polycode-projects/the-mechanical-code-talker 1.5.5 → 1.8.3
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 +123 -14
- package/ROADMAP.md +233 -1392
- package/bin/tmct.mjs +479 -98
- package/corpus/README.md +3 -0
- package/corpus/generated/README.md +43 -0
- package/corpus/generated/ace-surface-variants.jsonl +17 -0
- package/corpus/generated/manifest.json +9 -0
- package/corpus/tier2/generate.mjs +14668 -0
- package/corpus/tier2/human-examples-large.jsonl +1928 -0
- package/corpus/tier2/human-examples-medium.jsonl +356 -0
- package/corpus/tier2/human-examples.jsonl +120 -0
- package/corpus/tier2/human-large.jsonl +12001 -0
- package/corpus/tier2/human-medium.jsonl +944 -0
- package/corpus/tier2/human.jsonl +664 -0
- package/corpus/tier2/manifest.json +42 -0
- package/package.json +14 -8
- package/src/answer-variants.json +47 -0
- package/src/answer-variants.mjs +67 -0
- package/src/ask-browser-entry.mjs +34 -0
- package/src/ask-browser.bundle.js +5095 -0
- package/src/ask-vocab.mjs +93 -8
- package/src/ask.mjs +451 -49
- package/src/chat.mjs +1273 -137
- package/src/cli-args.mjs +164 -0
- package/src/codegraph.mjs +170 -32
- package/src/extensions.mjs +100 -19
- package/src/grammar/ace.mjs +85 -3
- package/src/grammar/lexicon-core.json +9531 -63
- package/src/grammar/lexicon.mjs +58 -8
- package/src/graph-merge.mjs +114 -0
- package/src/index.mjs +14 -0
- package/src/init.mjs +40 -14
- package/src/interpret/normalize.mjs +75 -1
- package/src/interpret/strategies/grammar.mjs +10 -0
- package/src/interpret/strategies/keywords.mjs +20 -0
- package/src/interpret/strategies/noise-strip.mjs +73 -4
- package/src/memory/core.mjs +466 -8
- package/src/router/goal-reasoner.mjs +41 -7
- package/src/router/guardrail.mjs +37 -7
- package/src/router/resolver.mjs +50 -4
- package/src/sessions.mjs +5 -1
- package/src/source.mjs +54 -1
- package/src/syllogise.mjs +398 -27
- package/src/toml-config.mjs +13 -4
- package/src/viz.mjs +541 -0
package/README.md
CHANGED
|
@@ -6,13 +6,16 @@ A pure-JS, **no-LLM**, offline, **$0** chatbot in the ELIZA/PARRY lineage:
|
|
|
6
6
|
pattern-driven, best-efforts, and obsessed with software the way PARRY was
|
|
7
7
|
obsessed with the mafia. No model calls anywhere.
|
|
8
8
|
|
|
9
|
-
tmct turns natural language directly into a graph database.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
tmct turns natural language directly into a graph database. On first run it
|
|
10
|
+
seeds an everyday **human-world persona** — people, places, objects, nature,
|
|
11
|
+
time — so it already has a vocabulary before you teach it anything. A
|
|
12
|
+
code-focused persona is available as an opt-in alternative: a software
|
|
13
|
+
**ontology** (real definitions), a **lexicon** (everyday words mapped onto
|
|
14
|
+
it), and a wider ConceptNet **corpus**. Point tmct at a real codebase's graph
|
|
15
|
+
and it reasons over that too, whichever persona is active. Teach it a fact in
|
|
16
|
+
plain English and it mints a node. Ask it a question and it answers from what
|
|
17
|
+
it was seeded with, what you taught it, and what it can derive by rule from
|
|
18
|
+
both. Every answer is either grounded or an honest miss.
|
|
16
19
|
|
|
17
20
|
## Teach it, then ask it to reason
|
|
18
21
|
|
|
@@ -234,6 +237,54 @@ opener to a useful answer without ever hitting a wall. Natural phrasings are
|
|
|
234
237
|
routed to the capability you meant: *"what functions are in Task"* → its
|
|
235
238
|
members, *"what defined saveStore"* → where it's defined.
|
|
236
239
|
|
|
240
|
+
## Detailed, grounded answers
|
|
241
|
+
|
|
242
|
+
Ask a precise question and tmct gives you a precise answer. Ask for more and
|
|
243
|
+
it gives you more: "give me a detailed summary of how X works" (or "explain
|
|
244
|
+
in detail how X works", or "...detailed overview/explanation of X") gets a
|
|
245
|
+
longer, multi-sentence account instead of one line. Every sentence in it is
|
|
246
|
+
lifted from a real graph edge, attribute, or taught fact — never generated
|
|
247
|
+
free text — and it declines outright rather than pad the gap when nothing
|
|
248
|
+
clears its own relevance bar.
|
|
249
|
+
|
|
250
|
+
From chat, a real run against the shipped `examples/mini-webapp` fixture
|
|
251
|
+
(banner lines trimmed):
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
$ node bin/tmct.mjs chat --repo examples/mini-webapp --ephemeral
|
|
255
|
+
tmct> give me a detailed overview of how the Store works
|
|
256
|
+
Attribute: prose_tokens = memory record store [mgx:hasProseTokens]. Attribute:
|
|
257
|
+
doc = In-memory record store. [seon:hasDoc]. Other matches: src/core/store.mjs
|
|
258
|
+
(Module), loadStore (Function), saveStore (Function), testLoadStore (Function).
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Programmatically, the same pipeline is `generateCompletion()`
|
|
262
|
+
(`src/completions/complete.mjs`):
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
import { fetchEntities } from "./src/source.mjs";
|
|
266
|
+
import { parseEntities } from "./src/codegraph.mjs";
|
|
267
|
+
import { loadMemory } from "./src/memory/core.mjs";
|
|
268
|
+
import { createCompletionsGraphAdapter } from "@polycode-projects/the-mechanical-code-talker/createCompletionsGraphAdapter";
|
|
269
|
+
import { generateCompletion } from "@polycode-projects/the-mechanical-code-talker/generateCompletion";
|
|
270
|
+
|
|
271
|
+
const dir = "examples/mini-webapp";
|
|
272
|
+
const graph = parseEntities(await fetchEntities({ graphFile: `${dir}/.tmct/graph.json` }));
|
|
273
|
+
const memory = await loadMemory(dir);
|
|
274
|
+
const graphService = createCompletionsGraphAdapter(graph, memory);
|
|
275
|
+
|
|
276
|
+
const { text } = await generateCompletion(dir, "Store", { query: "Store", graph, memory, graphService });
|
|
277
|
+
console.log(text);
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
Attribute: prose_tokens = memory record store [mgx:hasProseTokens]. Attribute:
|
|
282
|
+
doc = In-memory record store. [seon:hasDoc]. Other matches: src/core/store.mjs
|
|
283
|
+
(Module), loadStore (Function), saveStore (Function), testLoadStore (Function).
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Full pipeline design in `archive/PLAN_COMPLETIONS.md`.
|
|
287
|
+
|
|
237
288
|
## How it remembers
|
|
238
289
|
|
|
239
290
|
tmct's memory has two layers, both fed by every parsed request and response and
|
|
@@ -246,11 +297,29 @@ by cleaned session logs:
|
|
|
246
297
|
|
|
247
298
|
With no graph at all, tmct starts empty and remembers what you tell it. The
|
|
248
299
|
`.tmct/` graph is created from the conversation. On a first run it seeds the
|
|
249
|
-
committed vocabulary so it knows what it's talking about from turn one:
|
|
250
|
-
**
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
300
|
+
committed vocabulary so it knows what it's talking about from turn one: an
|
|
301
|
+
everyday **human-world** persona — people, places, objects, nature, time/
|
|
302
|
+
events, body/food and mind vocabulary hand-curated from Open English WordNet
|
|
303
|
+
and bridged to Schema.org's top-level classes — so "what is a dog?" answers
|
|
304
|
+
offline, from disk, on turn one. A code-domain persona (a curated **SEON**
|
|
305
|
+
software ontology plus the whole filtered **ConceptNet slice**, CC-BY-SA 4.0)
|
|
306
|
+
is available opt-in: `tmct init --with-persona code`. `--ephemeral` (used by
|
|
307
|
+
the shipped `npm run example:*` demos) reads a graph but writes nothing back.
|
|
308
|
+
|
|
309
|
+
The default persona also comes in three sizes: Small (~664 facts, the
|
|
310
|
+
default), Medium (~1,608, `tmct init --persona-size medium`) and Large
|
|
311
|
+
(~13,609, `--persona-size large`, deep enough to chain real multi-hop
|
|
312
|
+
reasoning). Design detail and the full fact-count tables are in `archive/PLAN_SEED.md`.
|
|
313
|
+
|
|
314
|
+
### Memory backends
|
|
315
|
+
|
|
316
|
+
The default memory backend writes an OWL-labelled JSON file under `.tmct/`.
|
|
317
|
+
Two more exist for a library caller who doesn't want that: `runChat({
|
|
318
|
+
memoryBackend: "memory" })` keeps taught facts in the process only, nothing
|
|
319
|
+
written to disk; `runChat({ memoryBackend: "sqlite" })` persists them to a
|
|
320
|
+
local SQLite file instead. `TMCT_MEMORY_BACKEND=memory|sqlite` does the same
|
|
321
|
+
from the environment. There's no CLI flag yet — this is a library-level
|
|
322
|
+
option for now, newer and less exercised than the default backend.
|
|
254
323
|
|
|
255
324
|
Teaching isn't limited to the ACE grammar's fixed shapes. Tell tmct an
|
|
256
325
|
arbitrary fact, like "margo eats ribs", and it mints a fact you can later ask
|
|
@@ -311,6 +380,7 @@ tmct # bare = chat (the headline)
|
|
|
311
380
|
tmct chat --repo /abs/path/to/repo # chat over a specific repo's graph
|
|
312
381
|
tmct init # scaffold .tmct/, tmct.toml, seed + provenance
|
|
313
382
|
tmct syllogise # offline: pre-derive entailed facts (maintenance)
|
|
383
|
+
npm run viz -- --output graph.html && open graph.html # self-contained HTML graph view
|
|
314
384
|
```
|
|
315
385
|
|
|
316
386
|
Inside the chat: `/help` lists commands, `/memory` inspects what tmct remembers
|
|
@@ -319,12 +389,51 @@ Inside the chat: `/help` lists commands, `/memory` inspects what tmct remembers
|
|
|
319
389
|
|
|
320
390
|
`tmct init` is the onboarding surface for the repository interface below: it
|
|
321
391
|
creates the `.tmct/` directory, writes the externalized `tmct.toml`
|
|
322
|
-
configuration, seeds the
|
|
323
|
-
or a bare user gets a working install in one command.
|
|
392
|
+
configuration, seeds the default persona, and records provenance. A host
|
|
393
|
+
package or a bare user gets a working install in one command.
|
|
324
394
|
|
|
325
395
|
> Install-size note: tmct depends on wink-nlp's deterministic English language
|
|
326
396
|
> model (~3.8 MB installed). That model is a lookup table, not an LLM.
|
|
327
397
|
|
|
398
|
+
### Flags, config, and multiple graphs
|
|
399
|
+
|
|
400
|
+
Every subcommand shares one flag/config resolver (`src/cli-args.mjs`). The
|
|
401
|
+
graph-path precedence is the same everywhere: `--graph` flag(s) beat
|
|
402
|
+
`TMCT_GRAPH_FILE`, which beats `tmct.toml`'s `graph_file`/`graph_files`, which
|
|
403
|
+
beats the `--repo`-derived `<repo>/.tmct/graph.json` default.
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
tmct init --repo /abs/path # scaffold a specific repo, not just cwd
|
|
407
|
+
tmct init --corpus <id|path> # a tier-2 manifest id (aws|python|java|general)
|
|
408
|
+
# or your own corpus jsonl file
|
|
409
|
+
tmct init --ontology <name|path> # activate+seed an ontology bundle
|
|
410
|
+
tmct init --lexicon <name|path> # activate a lexicon bundle (never seeded)
|
|
411
|
+
tmct init --graph <path> [--graph <path> …] # set tmct.toml's graph_file/graph_files
|
|
412
|
+
tmct init --config <path> # write to an alternate tmct.toml location
|
|
413
|
+
tmct init --persona-size medium|large # grow the default persona (Small is default)
|
|
414
|
+
|
|
415
|
+
tmct import --corpus <id|path> # activate+seed into an ALREADY-initialized
|
|
416
|
+
tmct import --ontology <name|path> # repo — any combination of these flags in
|
|
417
|
+
tmct import --lexicon <name|path> # one call. --graph is a DIFFERENT, purely
|
|
418
|
+
tmct import --graph <path> # additive op: it appends to graph_files,
|
|
419
|
+
# never activates an extensions bundle.
|
|
420
|
+
|
|
421
|
+
tmct chat --graph <path> [--graph <path> …] # explicit graph file(s) — multiple merge
|
|
422
|
+
# (ids that collide across graphs are
|
|
423
|
+
# auto-prefixed; see src/graph-merge.mjs)
|
|
424
|
+
tmct chat --config <path> # an alternate tmct.toml (a file or a dir)
|
|
425
|
+
tmct serve --graph <path> --config <path> # same two flags, for the HTTP endpoint
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
`--corpus`/`--ontology`/`--lexicon` each take one value; chain multiple `tmct
|
|
429
|
+
import` calls to combine several. `npm run init:large` in `package.json`
|
|
430
|
+
chains one `init` and five `import --corpus` calls to combine every shipped
|
|
431
|
+
bundle (human persona + seon + conceptnet + aws/python/java) into ~7,380
|
|
432
|
+
facts on the default flat-JSON backend — a working example to copy from.
|
|
433
|
+
|
|
434
|
+
`tmct extend --validate <dir> --config <path>` validates a third-party
|
|
435
|
+
extension pack against an alternate tmct.toml, without mutating anything.
|
|
436
|
+
|
|
328
437
|
### Try it on an example graph
|
|
329
438
|
|
|
330
439
|
tmct *consumes* a code graph at `<repo>/.tmct/graph.json`; it does not build
|