sync: Idea Genealogy + Quick Capture Overhaul
From private repo: Idea Genealogy: - Required edge explanations across UI/tools/API/MCP - Inferred edge schema (category/type/confidence) - Added part_of relationship type - Connection UI chips (Made by / Part of / Came from / Related) Quick Capture Overhaul: - Jina.ai fallback for JS-rendered sites (Twitter, SPAs) - Simplified UI: removed mode buttons, auto-detect input type - Renamed to "Add Stuff", moved to top-right - Auto-edge creation from description entities - Increased content summary length (500→1500 chars) Description Generation Fix: - Simplified prompt to "what is this" - Added link/dimensions context - Better creator attribution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
f7b8b2058c
commit
2cbc950fd4
@@ -5,12 +5,32 @@ import { nodeService } from '@/services/database/nodes';
|
||||
import { formatNodeForChat } from '../infrastructure/nodeFormatter';
|
||||
|
||||
export const createEdgeTool = tool({
|
||||
description: 'Create directed relationship between nodes',
|
||||
description:
|
||||
'Create directed relationship between nodes.\n\n' +
|
||||
'Direction rule: FROM node → TO node should read correctly.\n' +
|
||||
'Prefer the 4 core relations unless the user clearly wants an advanced intellectual relation:\n' +
|
||||
'- Made by → created_by (attribution)\n' +
|
||||
'- Part of → part_of (attribution)\n' +
|
||||
'- Came from → source_of (intellectual)\n' +
|
||||
'- Related → related_to (intellectual fallback)\n\n' +
|
||||
'Examples:\n' +
|
||||
'- Episode → Podcast: "Episode of this podcast"\n' +
|
||||
'- Book → Author: "Written by"\n' +
|
||||
'- Company → Founder: "Founded by"\n' +
|
||||
'- Insight → Source: "Came from / inspired by"\n',
|
||||
inputSchema: z.object({
|
||||
from_node_id: z.number().describe('The ID of the source node (where the connection originates)'),
|
||||
to_node_id: z.number().describe('The ID of the target node (where the connection points to)'),
|
||||
context: z.record(z.any()).optional().describe('Additional context about this connection - can include explanation, relationship type, strength, notes, etc.'),
|
||||
source: z.enum(['user', 'ai', 'ai_similarity', 'helper_name']).default('ai').describe('Source of this edge - use "ai" for AI-created connections, "user" for manual connections, "ai_similarity" for similarity-based connections')
|
||||
explanation: z.string().describe(
|
||||
'REQUIRED: Why does this connection exist? Be specific. ' +
|
||||
'Write it as a relationship that reads FROM → TO. ' +
|
||||
'Examples: "Author of this book", "Guest on this podcast", ' +
|
||||
'"Episode of this podcast", "This insight came from this podcast episode", "Extends the concept introduced here"'
|
||||
),
|
||||
source: z.enum(['user', 'ai', 'ai_similarity', 'helper_name']).default('ai').describe(
|
||||
'Source of this edge. Use "ai" (or "helper_name") for AI-created connections, ' +
|
||||
'"user" for manual connections, "ai_similarity" for similarity-based connections.'
|
||||
)
|
||||
}),
|
||||
execute: async (params) => {
|
||||
console.log('🔗 CreateEdge tool called with params:', JSON.stringify(params, null, 2));
|
||||
@@ -41,6 +61,15 @@ export const createEdgeTool = tool({
|
||||
};
|
||||
}
|
||||
|
||||
const explanation = (params.explanation || '').trim();
|
||||
if (!explanation) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'explanation is required. Provide a clear reason for why these two nodes should be connected.',
|
||||
data: null
|
||||
};
|
||||
}
|
||||
|
||||
const [fromNode, toNode] = await Promise.all([
|
||||
nodeService.getNodeById(params.from_node_id),
|
||||
nodeService.getNodeById(params.to_node_id)
|
||||
@@ -84,7 +113,8 @@ export const createEdgeTool = tool({
|
||||
const newEdge = await edgeService.createEdge({
|
||||
from_node_id: params.from_node_id,
|
||||
to_node_id: params.to_node_id,
|
||||
context: params.context || {},
|
||||
explanation,
|
||||
created_via: 'agent',
|
||||
source
|
||||
});
|
||||
|
||||
|
||||
@@ -15,14 +15,15 @@ Description: "${description}"
|
||||
|
||||
Respond with ONLY valid JSON (no markdown, no code blocks):
|
||||
{
|
||||
"enhancedDescription": "Improved 2-3 sentence description explaining what this content is about",
|
||||
"enhancedDescription": "A comprehensive summary of what this content is about (can be several paragraphs, up to ~1500 characters)",
|
||||
"tags": ["relevant", "semantic", "tags", "like", "ai", "economics", "research"],
|
||||
"reasoning": "Brief explanation of why you chose these categories"
|
||||
}
|
||||
|
||||
Guidelines:
|
||||
- enhancedDescription should be thorough - cover key points, arguments, and takeaways
|
||||
- Aim for 3-6 paragraphs or 800-1500 characters - don't artificially truncate
|
||||
- Include 3-8 relevant semantic tags (not just generic ones)
|
||||
- Make description informative and contextual
|
||||
- For academic papers, include tags like: research, academic, paper, plus domain-specific tags
|
||||
- For AI/ML papers, include: ai, machine-learning, artificial-intelligence, deep-learning
|
||||
- For economics papers, include: economics, finance, markets, policy
|
||||
@@ -32,7 +33,7 @@ Guidelines:
|
||||
const response = await generateText({
|
||||
model: openai('gpt-5-mini'),
|
||||
prompt,
|
||||
maxOutputTokens: 500
|
||||
maxOutputTokens: 800
|
||||
});
|
||||
|
||||
let content = response.text || '{}';
|
||||
@@ -122,7 +123,7 @@ export const paperExtractTool = tool({
|
||||
// Step 2: AI Analysis for enhanced metadata
|
||||
const aiAnalysis = await analyzeContentWithAI(
|
||||
result.metadata?.title || `PDF: ${new URL(url).pathname.split('/').pop()?.replace('.pdf', '')}`,
|
||||
result.content?.substring(0, 1000) || 'PDF document content',
|
||||
result.content?.substring(0, 2000) || 'PDF document content',
|
||||
'pdf'
|
||||
);
|
||||
|
||||
|
||||
@@ -15,14 +15,15 @@ Description: "${description}"
|
||||
|
||||
Respond with ONLY valid JSON (no markdown, no code blocks):
|
||||
{
|
||||
"enhancedDescription": "Improved 2-3 sentence description explaining what this content is about",
|
||||
"enhancedDescription": "A comprehensive summary of what this content is about (can be several paragraphs, up to ~1500 characters)",
|
||||
"tags": ["relevant", "semantic", "tags", "like", "ai", "economics", "research"],
|
||||
"reasoning": "Brief explanation of why you chose these categories"
|
||||
}
|
||||
|
||||
Guidelines:
|
||||
- enhancedDescription should be thorough - cover key points, arguments, and takeaways
|
||||
- Aim for 3-6 paragraphs or 800-1500 characters - don't artificially truncate
|
||||
- Include 3-8 relevant semantic tags (not just generic ones)
|
||||
- Make description informative and contextual
|
||||
- For AI/ML content, include tags like: ai, machine-learning, artificial-intelligence, deep-learning
|
||||
- For economics content, include: economics, finance, markets, policy
|
||||
- Be specific and insightful
|
||||
@@ -31,7 +32,7 @@ Guidelines:
|
||||
const response = await generateText({
|
||||
model: openai('gpt-5-mini'),
|
||||
prompt,
|
||||
maxOutputTokens: 500
|
||||
maxOutputTokens: 800
|
||||
});
|
||||
|
||||
let content = response.text || '{}';
|
||||
@@ -113,7 +114,7 @@ export const websiteExtractTool = tool({
|
||||
// Step 2: AI Analysis for enhanced metadata
|
||||
const aiAnalysis = await analyzeContentWithAI(
|
||||
result.metadata?.title || `Website: ${new URL(url).hostname}`,
|
||||
result.content?.substring(0, 500) || 'Website content',
|
||||
result.content?.substring(0, 2000) || 'Website content',
|
||||
'website'
|
||||
);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Available types: ${AVAILABLE_SEGMENTS.join(', ')}
|
||||
|
||||
Respond with ONLY valid JSON (no markdown, no code blocks):
|
||||
{
|
||||
"enhancedDescription": "Improved 2-3 sentence description explaining what this content is about",
|
||||
"enhancedDescription": "A comprehensive summary of what this content is about (can be several paragraphs, up to ~1500 characters)",
|
||||
"tags": ["relevant", "semantic", "tags", "like", "ai", "economics", "research"],
|
||||
"segments": ["research"],
|
||||
"reasoning": "Brief explanation of why you chose these categories"
|
||||
@@ -30,8 +30,9 @@ Respond with ONLY valid JSON (no markdown, no code blocks):
|
||||
|
||||
Guidelines:
|
||||
- Choose 1 segment that best fits the content type
|
||||
- enhancedDescription should be thorough - cover key points, arguments, and takeaways
|
||||
- Aim for 3-6 paragraphs or 800-1500 characters - don't artificially truncate
|
||||
- Include 3-8 relevant semantic tags (not just generic ones)
|
||||
- Make description informative and contextual
|
||||
- For AI/ML content, include tags like: ai, machine-learning, artificial-intelligence, deep-learning
|
||||
- For economics content, include: economics, finance, markets, policy
|
||||
- Be specific and insightful
|
||||
@@ -40,7 +41,7 @@ Guidelines:
|
||||
const response = await generateText({
|
||||
model: openai('gpt-5-mini'),
|
||||
prompt,
|
||||
maxOutputTokens: 500
|
||||
maxOutputTokens: 800
|
||||
});
|
||||
|
||||
let content = response.text || '{}';
|
||||
|
||||
Reference in New Issue
Block a user