graph context: a separate marker message before the first user turn
The map picks no longer glue into the opening prompt as seed text
(owner, 2026-10-04 late). POST /api/chats accepts graphContext
{propositions}; the route resolves the picks against the live graph,
derives the reasoning chains among them (chainsForSelection →
formatChainLine), and writes a graph-context custom marker as
message[0] — before the learner's first user message, in either mode.
- Core: newGraphContextMessage (model-facing content = the
contextualization framing + proposition lines + chain lines;
details = the structured pick); toLlmMessages flattens it to a user
message like every marker, so the model reads it for free.
- View: projects to a user-side data-graph-context part.
- UI: GraphContextCard — minimal, muted, dashed, collapsed by default
(counts only); expand reveals name — statement rows and the chain
lines. Same compact-expandable pattern as the practice cards.
- Home: sends graphContext with the creation whenever picks exist;
the prompt param carries the learner's own words only.
This commit is contained in:
@@ -19,6 +19,8 @@ import { describe, it } from "node:test";
|
||||
|
||||
import { PracticeDock } from "../components/practice-dock.tsx";
|
||||
import { ConcludeCard, ProblemCard, ThinkingCard } from "../components/practice-cards.tsx";
|
||||
import { GraphContextCard } from "../components/graph-context-card.tsx";
|
||||
import { newGraphContextMessage } from "../src/core/native-messages.ts";
|
||||
import { projectView } from "../src/core/view.ts";
|
||||
import type { ArtifactPartProps } from "../src/core";
|
||||
import {
|
||||
@@ -164,3 +166,37 @@ describe("the practice view projection", () => {
|
||||
assert.equal(toolPart.state, "input-available");
|
||||
});
|
||||
});
|
||||
|
||||
// ── the graph-context card (a session's map pick; collapsed by default) ─────
|
||||
|
||||
describe("GraphContextCard", () => {
|
||||
it("collapsed: counts only — the statements stay hidden until expanded", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<GraphContextCard data={{ propositions: [
|
||||
{ id: "n1", name: "Modus ponens", statement: "If P implies Q and P holds, Q holds." },
|
||||
{ id: "n2", name: "Soundness", statement: "A valid argument from true premises has a true conclusion." },
|
||||
], chains: ["Modus ponens → Soundness"] }} />,
|
||||
);
|
||||
assert.ok(html.includes('data-testid="graph-context-card"'));
|
||||
assert.ok(html.includes("2 propositions"));
|
||||
assert.ok(html.includes("1 chain"));
|
||||
// minimal: the collapsed bar carries NO statement text
|
||||
assert.ok(!html.includes("If P implies Q"));
|
||||
assert.ok(!html.includes("graph-context-body"));
|
||||
});
|
||||
|
||||
it("zero chains: the chain count stays out of the summary", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<GraphContextCard data={{ propositions: [{ id: "n1", name: "A", statement: "S." }], chains: [] }} />,
|
||||
);
|
||||
assert.ok(html.includes("1 proposition</span>"));
|
||||
assert.ok(!html.includes("chain"));
|
||||
});
|
||||
|
||||
it("the marker projects to the card's part (projectView fold)", () => {
|
||||
const view = projectView([newGraphContextMessage(
|
||||
[{ id: "n1", name: "A", statement: "S." }], [],
|
||||
) as unknown as LhMessage]);
|
||||
assert.equal((view[0]!.parts[0] as { type: string }).type, "data-graph-context");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user