v0 scaffold: teacher runtime (hermetic pi SDK), data model, ledgers, normalizer
- teacher/system-prompt.md: teach methodology + quiz/ask guidelines folded in - extensions/: quiz.ts + ask-user-question.ts (hermetic copies) - src/teacher/create-session.ts: isolated agent (noTools builtin, own agentDir/sessions/prompt) - src/schema.ts + ledger.ts: append-only ledgers, known-vs-understood data model - src/extract/normalize.ts: session JSONL -> canonical doc (verified on real session) - extractor/merger/derive/what-next: specified stubs
This commit is contained in:
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* learning-harness CLI
|
||||
*
|
||||
* teach [message] launch an interactive teaching session (full pi TUI)
|
||||
* doctor non-interactive smoke test of the teacher wiring
|
||||
* ingest <file> normalize a session JSONL and print the canonical document
|
||||
* (Stage 1 only — extractor/merger not yet implemented)
|
||||
* graph print graph/ledger stats
|
||||
* what-next (not yet implemented)
|
||||
*/
|
||||
|
||||
import * as fs from "node:fs";
|
||||
import { doctor, runTeachingSession } from "./teacher/create-session.ts";
|
||||
import { normalizeSession } from "./extract/normalize.ts";
|
||||
import { ledgers } from "./ledger.ts";
|
||||
import { deriveAll } from "./derive.ts";
|
||||
import { PATHS } from "../config.ts";
|
||||
|
||||
async function main() {
|
||||
const [command, ...rest] = process.argv.slice(2);
|
||||
|
||||
switch (command) {
|
||||
case "teach": {
|
||||
await runTeachingSession(rest.join(" ") || undefined);
|
||||
break;
|
||||
}
|
||||
case "doctor": {
|
||||
await doctor();
|
||||
break;
|
||||
}
|
||||
case "ingest": {
|
||||
const file = rest[0];
|
||||
if (!file) {
|
||||
console.error("Usage: ingest <session.jsonl>");
|
||||
process.exit(1);
|
||||
}
|
||||
const doc = normalizeSession(file);
|
||||
ledgers.appendSession(doc.session);
|
||||
console.log(`Session: ${doc.session.id}`);
|
||||
console.log(`Topic: ${doc.session.topic}`);
|
||||
console.log(`Entries: ${doc.entries.length}`);
|
||||
const quizzes = doc.entries.filter((e) => e.kind === "quiz");
|
||||
console.log(`Quizzes: ${quizzes.length}`);
|
||||
// Full canonical document for inspection / later pipeline stages.
|
||||
fs.mkdirSync(PATHS.graph, { recursive: true });
|
||||
const out = `${PATHS.graph}/canonical-${doc.session.id.slice(0, 8)}.json`;
|
||||
fs.writeFileSync(out, JSON.stringify(doc, null, "\t"), "utf-8");
|
||||
console.log(`Canonical document written: ${out}`);
|
||||
break;
|
||||
}
|
||||
case "graph": {
|
||||
const nodes = ledgers.nodes();
|
||||
const edges = ledgers.edges();
|
||||
const events = ledgers.events();
|
||||
const sessions = ledgers.sessions();
|
||||
const derived = deriveAll();
|
||||
console.log(`Sessions: ${sessions.length}`);
|
||||
console.log(`Nodes: ${nodes.length} (known: ${derived.filter((d) => d.known).length})`);
|
||||
console.log(`Edges: ${edges.length}`);
|
||||
console.log(`Events: ${events.length}`);
|
||||
break;
|
||||
}
|
||||
case "what-next": {
|
||||
console.error("Not implemented yet — needs extractor + merger first.");
|
||||
process.exit(1);
|
||||
}
|
||||
default: {
|
||||
console.log("Commands: teach [message] | doctor | ingest <file> | graph | what-next");
|
||||
process.exit(command ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user