/// 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]: (

Space Overview

{ifElse( hasResult,

{overview?.headline}

Themes

{overview?.themes.map((theme) => ( {theme.name}

{theme.description}

))}

Recent Activity

{overview?.recentActivity}

{ifElse( computed(() => (overview?.connections?.length ?? 0) > 0),

Connections

{overview?.connections.map((conn) => (

{conn.description}

))}
, , )}

Explore Next

    {overview?.suggestions.map((s) =>
  • {s}
  • )}
,
{ifElse( pending, Exploring the space..., , )}
, )}
), summary, }; });