///
import {
type BuiltInLLMMessage,
computed,
handler,
ifElse,
llmDialog,
NAME,
pattern,
patternTool,
type Stream,
toSchema,
UI,
type VNode,
wish,
Writable,
} from "commontools";
import { type MentionablePiece } from "./backlinks-index.tsx";
import {
searchPattern as summarySearchPattern,
type SummaryIndexEntry,
} from "./summary-index.tsx";
import { listMentionable, listRecent } from "./common-tools.tsx";
// ===== Types =====
type SpaceOverviewResult = {
headline: string;
themes: Array<{ name: string; description: string; relatedPieces: string[] }>;
recentActivity: string;
connections: Array<{ description: string; pieceNames: string[] }>;
suggestions: string[];
};
type SpaceOverviewInput = Record;
interface SpaceOverviewOutput {
[NAME]: string;
[UI]: VNode;
summary: string;
}
// ===== Handlers =====
const triggerAnalysis = handler<
unknown,
{ addMessage: Stream }
>((_, { addMessage }) => {
addMessage.send({
role: "user",
content: [{
type: "text" as const,
text:
"Analyze this space and give me an overview of what's here and what's been happening recently.",
}],
});
});
// ===== Main Pattern =====
export default pattern(() => {
// Fetch space data references for tools
const mentionable = wish({
query: "#mentionable",
}).result;
const recentPieces = wish({ query: "#recent" }).result;
const { entries: summaryEntries } = wish<{ entries: SummaryIndexEntry[] }>({
query: "#summaryIndex",
}).result;
const profileWish = wish({ query: "#profile" });
const profileText = computed(() => profileWish.result ?? "");
const systemPrompt = computed(() => {
const profile = profileText;
const profileSection = profile
? `\n\n--- User Context ---\n${profile}\n---`
: "";
return `You are a space orientation assistant. When activated, you explore the user's knowledge space using your tools and produce a clear, insightful overview of what's going on.
Process:
1. Use searchSpace to browse the space contents — search for broad terms and specific topics
2. Use listRecent to see what's been active lately
3. Use listMentionable to get a full inventory
4. Synthesize what you find into a structured overview
After exploring, call the finalResult tool with your structured findings:
- headline: A punchy one-sentence summary of the space
- themes: 2-4 active themes or topic clusters you identified (each with name, description, and relatedPieces)
- recentActivity: A narrative of what's been captured/changed lately
- connections: Notable connections between pieces (each with description and pieceNames)
- suggestions: 2-3 suggested next actions or things to explore
Conventions:
- Notes are prefixed with "📝 ", notebooks with "📓 "
- "Transcript:" notes contain raw voice memo captures
- "Capture Summary:" notes are reflections on ingestion sessions
- The "📓 Capture Log" notebook groups transcripts and summaries
- [[Wiki-links]] in note content indicate intentional connections
Be concise and insightful. Focus on patterns and connections, not just listing things. Reference actual piece names.${profileSection}`;
});
const messages = Writable.of([]);
const llmTools = {
searchSpace: patternTool(summarySearchPattern, {
entries: summaryEntries,
}),
listMentionable: patternTool(listMentionable, { mentionable }),
listRecent: patternTool(listRecent, { recentPieces }),
};
const dialogParams = {
system: systemPrompt,
messages,
tools: llmTools,
model: "anthropic:claude-haiku-4-5" as const,
builtinTools: false,
resultSchema: toSchema(),
};
const { addMessage, pending, result } = llmDialog(dialogParams);
const overview = computed(() => result as SpaceOverviewResult | undefined);
const hasResult = computed(() => !!overview);
const summary = computed(() => overview?.headline ?? "Space Overview");
return {
[NAME]: "Space Overview",
[UI]: (