Skip to content

Commit 166de5d

Browse files
authored
Merge pull request #12 from secondorderai/dev
Add structured meta-chat workflow with feedback, events, and landing page updates
2 parents b5574fd + 72fc29f commit 166de5d

5 files changed

Lines changed: 1544 additions & 107 deletions

File tree

app/page.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Button } from '@/components/ui/button';
2+
import { MermaidDiagram } from '@/components/marketing/mermaid-diagram';
23
import Image from 'next/image';
34
import Link from 'next/link';
45

@@ -38,6 +39,22 @@ const iterativeLoop = [
3839
'Return the answer with visible framing, then capture user feedback.',
3940
];
4041

42+
const marketingThinkingDiagram = String.raw`
43+
flowchart TD
44+
request["User asks for help"]
45+
classify["Classify the task<br/>simple chat, analysis, planning,<br/>decision, or troubleshooting"]
46+
gate{"Use meta mode?"}
47+
direct["Direct answer path<br/>Respond normally when the task is easy"]
48+
plan["Planner pass<br/>Extract goal, constraints, plan,<br/>and response strategy"]
49+
draft["Draft pass<br/>Create a compact draft response"]
50+
critique["Critic pass<br/>Check assumptions, limitations,<br/>and context gaps"]
51+
final["Final answer<br/>Show the response with compact framing<br/>and trust signals"]
52+
53+
request --> classify --> gate
54+
gate -- "No" --> direct --> final
55+
gate -- "Yes" --> plan --> draft --> critique --> final
56+
`;
57+
4158
const overview = [
4259
'A meta layer on top of chat that makes task interpretation visible.',
4360
'Structured planner and critic passes running behind the assistant.',
@@ -258,6 +275,50 @@ export default function Home() {
258275
</div>
259276
</section>
260277

278+
<section className="mx-auto max-w-6xl px-6 py-16 sm:px-10">
279+
<div className="rounded-[2rem] border border-ink/10 bg-white/70 p-8 shadow-soft-edge sm:p-12">
280+
<div className="grid gap-10 lg:grid-cols-[0.42fr_0.58fr]">
281+
<div>
282+
<p className="text-sm uppercase tracking-[0.4em] text-ink/60">
283+
Meta-thinking path
284+
</p>
285+
<h2 className="mt-4 font-display text-4xl">
286+
A visible diagram of how SecondOrder thinks.
287+
</h2>
288+
<p className="mt-4 text-ink/70">
289+
The system does not run the full planner and critic stack for
290+
every prompt. It first classifies the request, then chooses the
291+
light path or the structured path based on how much reasoning
292+
the task needs.
293+
</p>
294+
<div className="mt-8 rounded-3xl border border-ink/10 bg-bone p-5">
295+
<p className="text-xs uppercase tracking-[0.3em] text-ink/55">
296+
Why this matters
297+
</p>
298+
<p className="mt-3 text-sm text-ink/75">
299+
Friends trying the product can understand it as a chat system
300+
with a decision gate: answer directly when the task is easy,
301+
or switch into a planning and critique loop when the task is
302+
ambiguous, risky, or multi-step.
303+
</p>
304+
</div>
305+
</div>
306+
307+
<div className="rounded-[2rem] border border-ink/10 bg-bone p-5 sm:p-6">
308+
<MermaidDiagram
309+
chart={marketingThinkingDiagram}
310+
className="bg-white/90"
311+
/>
312+
<p className="mt-4 text-sm text-ink/65">
313+
The key product idea is the decision gate in the middle:
314+
simple prompts stay fast, while complex prompts trigger the
315+
planning and critique loop.
316+
</p>
317+
</div>
318+
</div>
319+
</div>
320+
</section>
321+
261322
<section className="mx-auto max-w-6xl px-6 py-16 sm:px-10">
262323
<div className="grid gap-10 lg:grid-cols-2">
263324
<div className="rounded-3xl border border-ink/10 bg-white/70 p-8">
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
'use client';
2+
3+
import { useEffect, useId, useState } from 'react';
4+
import { cn } from '@/lib/utils';
5+
6+
interface MermaidDiagramProps {
7+
chart: string;
8+
className?: string;
9+
}
10+
11+
let hasInitializedMermaid = false;
12+
13+
export function MermaidDiagram({
14+
chart,
15+
className,
16+
}: MermaidDiagramProps) {
17+
const [svg, setSvg] = useState<string>('');
18+
const [hasError, setHasError] = useState(false);
19+
const id = useId().replace(/:/g, '');
20+
21+
useEffect(() => {
22+
let isActive = true;
23+
24+
async function renderDiagram() {
25+
try {
26+
const mermaid = (await import('mermaid')).default;
27+
28+
if (!hasInitializedMermaid) {
29+
mermaid.initialize({
30+
startOnLoad: false,
31+
securityLevel: 'loose',
32+
theme: 'base',
33+
flowchart: {
34+
htmlLabels: true,
35+
useMaxWidth: true,
36+
curve: 'stepBefore',
37+
},
38+
themeVariables: {
39+
background: '#F7F7F5',
40+
primaryColor: '#FFFFFF',
41+
primaryTextColor: '#0B0B0B',
42+
primaryBorderColor: '#0B0B0B',
43+
lineColor: '#0B0B0B',
44+
secondaryColor: '#E6E6E1',
45+
tertiaryColor: '#F7F7F5',
46+
fontFamily: 'Manrope, sans-serif',
47+
},
48+
});
49+
50+
hasInitializedMermaid = true;
51+
}
52+
53+
const { svg: nextSvg } = await mermaid.render(`secondorder-${id}`, chart);
54+
55+
if (!isActive) {
56+
return;
57+
}
58+
59+
setSvg(nextSvg);
60+
setHasError(false);
61+
} catch {
62+
if (!isActive) {
63+
return;
64+
}
65+
66+
setHasError(true);
67+
}
68+
}
69+
70+
void renderDiagram();
71+
72+
return () => {
73+
isActive = false;
74+
};
75+
}, [chart, id]);
76+
77+
if (hasError) {
78+
return (
79+
<div
80+
className={cn(
81+
'rounded-3xl border border-ink/10 bg-white/70 p-6 text-sm text-ink/60',
82+
className,
83+
)}
84+
>
85+
Diagram unavailable.
86+
</div>
87+
);
88+
}
89+
90+
return (
91+
<div
92+
className={cn(
93+
'rounded-3xl border border-ink/10 bg-white/80 p-4 shadow-soft-edge',
94+
className,
95+
)}
96+
>
97+
{svg ? (
98+
<div
99+
className={cn(
100+
'[&_foreignObject_div]:font-sans [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none',
101+
'[&_svg_.edgeLabel]:bg-bone [&_svg_.edgeLabel]:px-1',
102+
)}
103+
dangerouslySetInnerHTML={{ __html: svg }}
104+
/>
105+
) : (
106+
<div className="flex min-h-[420px] items-center justify-center text-sm text-ink/50">
107+
Rendering diagram...
108+
</div>
109+
)}
110+
</div>
111+
);
112+
}

docs/architecture-overview.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# SecondOrder Architecture Overview
2+
3+
This document gives two shareable views of the current system:
4+
5+
- the product and system architecture
6+
- the meta-thinking flow used for harder chat requests
7+
8+
## High-Level System
9+
10+
```mermaid
11+
flowchart LR
12+
user["User"]
13+
marketing["Marketing Site<br/>`/`"]
14+
chatUi["Chat UI<br/>`/chat` and `/chat/[threadId]`"]
15+
chatApi["Chat API<br/>`app/api/chat/route.ts`"]
16+
workflow["Meta Chat Workflow<br/>classify -> plan -> draft -> critique"]
17+
agent["SecondOrder Agent<br/>final streamed response"]
18+
memory["Mastra Memory Store<br/>thread history + titles"]
19+
events["Chat Events Store<br/>feedback + analytics events"]
20+
models["LLM Models<br/>main agent + planner + critic"]
21+
storage["Storage Backend<br/>Postgres or LibSQL/local file"]
22+
23+
user --> marketing
24+
user --> chatUi
25+
chatUi --> chatApi
26+
chatApi --> memory
27+
chatApi --> workflow
28+
workflow --> models
29+
workflow --> agent
30+
agent --> models
31+
agent --> memory
32+
chatApi --> events
33+
memory --> storage
34+
events --> storage
35+
chatApi --> chatUi
36+
chatUi --> user
37+
```
38+
39+
### What this means
40+
41+
- The marketing site explains the product and sends people into the chat experience.
42+
- The chat UI talks only to the Next.js chat API route.
43+
- The API route is the orchestration boundary: it validates the request, loads thread history, runs the meta workflow, and streams the final answer back to the UI.
44+
- Mastra provides the workflow engine, agent runtime, memory, and storage integration.
45+
- Thread history and titles live in Mastra memory storage.
46+
- Product analytics events like `thread_started`, `meta_mode_used`, and `feedback_submitted` are recorded separately for measurement.
47+
- Storage can run on Postgres in production or LibSQL/file-backed storage locally.
48+
49+
## Meta-Thinking Process
50+
51+
```mermaid
52+
flowchart TD
53+
request["User message arrives"]
54+
classify["1. Classify task<br/>simple chat, analysis, planning,<br/>decision, or troubleshooting"]
55+
gate{"Use meta mode?"}
56+
direct["Respond directly"]
57+
plan["2. Planner pass<br/>goal, constraints, plan,<br/>response strategy"]
58+
draft["3. Draft pass<br/>short draft answer"]
59+
critique["4. Critic pass<br/>confidence, limitations,<br/>context gaps, adjustments"]
60+
context["5. Build request context<br/>task type + meta guidance"]
61+
final["6. SecondOrder agent writes<br/>the final user-visible reply"]
62+
stream["7. Stream answer to UI<br/>with compact metadata"]
63+
feedback["8. Capture product events<br/>and user feedback"]
64+
65+
request --> classify
66+
classify --> gate
67+
gate -- "No" --> direct
68+
direct --> final
69+
gate -- "Yes" --> plan
70+
plan --> draft
71+
draft --> critique
72+
critique --> context
73+
context --> final
74+
final --> stream
75+
stream --> feedback
76+
```
77+
78+
### How to explain this to a friend
79+
80+
- SecondOrder does not always use a heavy workflow. It first decides whether the request is simple or whether it needs a more structured pass.
81+
- For harder requests, it creates a compact plan before answering.
82+
- It then critiques that draft so the final response can include better framing, clearer limitations, and missing-context signals.
83+
- The user does not see the full hidden chain-of-thought. They get a normal answer plus compact, useful signals about how the system approached the task.
84+
- That makes the product feel like a chat assistant with visible reasoning discipline, not just raw text generation.
85+
86+
## Current Building Blocks
87+
88+
- UI: [`app/page.tsx`](/Users/henry/workspace/secondorder-web/app/page.tsx), [`app/chat/page.tsx`](/Users/henry/workspace/secondorder-web/app/chat/page.tsx), [`app/chat/[threadId]/page.tsx`](/Users/henry/workspace/secondorder-web/app/chat/[threadId]/page.tsx)
89+
- API: [`app/api/chat/route.ts`](/Users/henry/workspace/secondorder-web/app/api/chat/route.ts)
90+
- Workflow: [`mastra/workflows/meta-chat-workflow.ts`](/Users/henry/workspace/secondorder-web/mastra/workflows/meta-chat-workflow.ts)
91+
- Agents and memory: [`mastra/agents.ts`](/Users/henry/workspace/secondorder-web/mastra/agents.ts)
92+
- Runtime wiring: [`mastra/index.ts`](/Users/henry/workspace/secondorder-web/mastra/index.ts)
93+
- Storage and events: [`lib/chat/history.ts`](/Users/henry/workspace/secondorder-web/lib/chat/history.ts), [`lib/chat/events.ts`](/Users/henry/workspace/secondorder-web/lib/chat/events.ts), [`lib/chat/storage.ts`](/Users/henry/workspace/secondorder-web/lib/chat/storage.ts)

0 commit comments

Comments
 (0)