Skip to content

Commit 94b07ad

Browse files
bwlclaude
andcommitted
Upgrade node synthesize to full GPT-5 capabilities and register write command
- Upgrade synthesize to match write command quality: • Default to high reasoning effort (was medium) • Default to high verbosity for comprehensive synthesis (was medium) • Add verbosity-aware token limits (4096/8192/16384) • Add word count guidance (500-800/800-1200/1200-2000 words) • Improve prompt with token warnings and better structure • Enhance tag generation to identify emergent themes vs generic tags - Fix write command registration: • Import createWriteCommand in CLI index • Register command so it appears in CLI 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 81d89f2 commit 94b07ad

2 files changed

Lines changed: 62 additions & 16 deletions

File tree

src/cli/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createCaptureCommand } from './commands/capture';
2+
import { createWriteCommand } from './commands/write';
23
import { createAdminRecomputeEmbeddingsCommand } from './commands/admin-recompute-embeddings';
34
import { createAdminRetagAllCommand } from './commands/admin-retag-all';
45
import { createExploreCommand } from './commands/explore';
@@ -42,6 +43,7 @@ export async function createForestCli() {
4243
.use(completionsPlugin());
4344

4445
cli.command(createCaptureCommand(clerc));
46+
cli.command(createWriteCommand(clerc));
4547
cli.command(createExploreCommand(clerc));
4648
cli.command(createSearchCommand(clerc));
4749
cli.command(createStatsCommand(clerc));

src/core/synthesize.ts

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ export async function synthesizeNodesCore(
5757

5858
// Set defaults
5959
const model = options.model || 'gpt-5';
60-
const reasoning = options.reasoning || 'medium';
61-
const verbosity = options.verbosity || 'medium';
62-
const maxTokens = options.maxTokens || 9001; // It's over 9000!
60+
const reasoning = options.reasoning || 'high'; // Default to high reasoning for quality synthesis
61+
const verbosity = options.verbosity || 'high'; // Default to comprehensive synthesis
62+
63+
// Set realistic token limits based on verbosity if not explicitly provided
64+
const maxTokens = options.maxTokens || getDefaultMaxTokens(verbosity);
6365

6466
// Get API key
6567
const config = loadConfig();
@@ -71,7 +73,7 @@ export async function synthesizeNodesCore(
7173
}
7274

7375
// Build synthesis prompt
74-
const prompt = buildSynthesisPrompt(nodes);
76+
const prompt = buildSynthesisPrompt(nodes, maxTokens, verbosity);
7577

7678
// Call OpenAI Responses API
7779
const response = await fetch('https://api.openai.com/v1/responses', {
@@ -144,10 +146,44 @@ export async function synthesizeNodesCore(
144146
};
145147
}
146148

149+
/**
150+
* Get default max tokens based on verbosity level
151+
*/
152+
function getDefaultMaxTokens(verbosity: TextVerbosity): number {
153+
switch (verbosity) {
154+
case 'low':
155+
return 4096;
156+
case 'medium':
157+
return 8192;
158+
case 'high':
159+
return 16384;
160+
default:
161+
return 16384;
162+
}
163+
}
164+
165+
/**
166+
* Get word count guidance based on verbosity
167+
*/
168+
function getWordCountGuidance(verbosity: TextVerbosity): string {
169+
switch (verbosity) {
170+
case 'low':
171+
return '500-800 words';
172+
case 'medium':
173+
return '800-1200 words';
174+
case 'high':
175+
return '1200-2000 words';
176+
default:
177+
return '1200-2000 words';
178+
}
179+
}
180+
147181
/**
148182
* Build the synthesis prompt from source nodes
149183
*/
150-
function buildSynthesisPrompt(nodes: NodeRecord[]): string {
184+
function buildSynthesisPrompt(nodes: NodeRecord[], maxTokens: number, verbosity: TextVerbosity): string {
185+
const wordGuidance = getWordCountGuidance(verbosity);
186+
151187
const nodeDescriptions = nodes
152188
.map((node, i) => {
153189
return `## Note ${i + 1}: ${node.title}
@@ -157,28 +193,36 @@ ${node.body}`;
157193
})
158194
.join('\n\n---\n\n');
159195

160-
return `You are synthesizing knowledge from a personal knowledge base.
196+
return `You are synthesizing knowledge from a personal knowledge base, creating new insights by connecting existing notes.
197+
198+
I will provide you with ${nodes.length} notes. Your task is to write a NEW article that synthesizes these ideas.
199+
200+
IMPORTANT: Your response MUST be under ${maxTokens} tokens. Keep your synthesis concise and well-structured.
161201
162-
I will provide you with ${nodes.length} notes. Your task is to write a NEW article that:
163-
1. Explores connections and relationships between these notes
164-
2. Expands on ideas at the boundaries/edges of this knowledge
165-
3. Introduces novel perspectives or synthesis that emerge from combining these ideas
166-
4. Is comprehensive and well-structured (aim for 500-1500 words)
202+
Requirements:
203+
1. Explore connections and relationships between the notes (${wordGuidance})
204+
2. Identify patterns, themes, and emergent ideas that span across the notes
205+
3. Expand on ideas at the boundaries/edges of this knowledge
206+
4. Introduce novel perspectives or insights that emerge from combining these ideas
207+
5. Use clear, engaging prose with proper markdown formatting
208+
6. Include section headers (## and ###) to organize your synthesis
209+
7. Be comprehensive yet focused - synthesize, don't just summarize
210+
8. CRITICAL: Stay under ${maxTokens} tokens - complete your JSON response properly
167211
168212
Source notes:
169213
170214
${nodeDescriptions}
171215
172216
---
173217
174-
Based on these notes, write a synthesized article. Return your response as JSON:
218+
Based on these notes, write a synthesized article that reveals new insights. Return your response as JSON:
175219
{
176-
"title": "A compelling title for the synthesized article",
177-
"body": "The full article text (markdown formatted, 500-1500 words)",
178-
"suggestedTags": ["tag1", "tag2", "tag3"]
220+
"title": "A compelling, specific title for the synthesized article",
221+
"body": "The full synthesis in markdown format (${wordGuidance}, well-structured with headers)",
222+
"suggestedTags": ["3-5 relevant topic tags based on the synthesis themes and cross-cutting concepts"]
179223
}
180224
181-
The article should reveal new insights that emerge from combining these notes. Focus on connections, patterns, and emergent ideas that aren't obvious from reading the notes individually.`;
225+
Focus on connections, patterns, and emergent ideas that aren't obvious from reading the notes individually. For tags, identify the key themes and concepts that emerge from the synthesis - not just the source note tags, but the new concepts that arise from combining them. This synthesis will become part of the knowledge base, so make it genuinely insightful.`;
182226
}
183227

184228
/**

0 commit comments

Comments
 (0)