/**
* Tool Connection Matrix
* Defines research flow relationships between tools based on empirical usage patterns
* Aligned with tool workflows: Discovery -> Search -> Read -> Explore
*
* Connection Strength:
* - strong: Primary next step, frequently used together, natural progression
* - moderate: Secondary option, contextually useful, alternative path
* - weak: Edge cases, rarely used together, special scenarios
*
* Updated to reflect enhanced tool descriptions and workflows
*/
export type ToolName =
| 'LOCAL_VIEW_STRUCTURE'
| 'LOCAL_RIPGREP'
| 'LOCAL_FIND_FILES'
| 'LOCAL_FETCH_CONTENT';
export type ConnectionStrength = 'strong' | 'moderate' | 'weak';
export interface ToolConnection {
tool: ToolName;
strength: ConnectionStrength;
reason: string;
}
export interface ToolConnectionMap {
strong: ToolConnection[];
moderate: ToolConnection[];
weak: ToolConnection[];
nextStep: {
hasResults: ToolConnection[];
empty: ToolConnection[];
};
}
/**
* Complete tool connection matrix
* Defines all relationships between tools for intelligent research flow
*/
export const TOOL_CONNECTIONS: Record<ToolName, ToolConnectionMap> = {
LOCAL_VIEW_STRUCTURE: {
strong: [
{ tool: 'LOCAL_RIPGREP', strength: 'strong', reason: 'Search code patterns in discovered structure (Workflow: Overview -> Search)' },
{ tool: 'LOCAL_FIND_FILES', strength: 'strong', reason: 'Filter by metadata (time/size/perms) after exploring structure' },
],
moderate: [
{ tool: 'LOCAL_FETCH_CONTENT', strength: 'moderate', reason: 'Read interesting files directly after discovery' },
],
weak: [],
nextStep: {
hasResults: [
{ tool: 'LOCAL_RIPGREP', strength: 'strong', reason: 'Search patterns in discovered dirs (mode=discovery first)' },
{ tool: 'LOCAL_FIND_FILES', strength: 'strong', reason: 'Filter by metadata (modifiedWithin, sizeGreater, permissions)' },
{ tool: 'LOCAL_FETCH_CONTENT', strength: 'moderate', reason: 'Read config/key files found in structure' },
],
empty: [
{ tool: 'LOCAL_FIND_FILES', strength: 'moderate', reason: 'Broader discovery with type="d" or parent directory' },
],
},
},
LOCAL_RIPGREP: {
strong: [
{ tool: 'LOCAL_FETCH_CONTENT', strength: 'strong', reason: 'Read full file with matchString + charLength for context (Workflow: Discovery -> Detailed -> Read)' },
],
moderate: [
{ tool: 'LOCAL_VIEW_STRUCTURE', strength: 'moderate', reason: 'Explore directory structure when pattern search is too narrow' },
{ tool: 'LOCAL_FIND_FILES', strength: 'moderate', reason: 'Refine results by metadata (modifiedWithin, sizeGreater)' },
],
weak: [],
nextStep: {
hasResults: [
{ tool: 'LOCAL_FETCH_CONTENT', strength: 'strong', reason: 'Read matched files with matchString + charLength for full context (most efficient)' },
{ tool: 'LOCAL_FIND_FILES', strength: 'moderate', reason: 'Filter results by time (recent changes) or size (large files)' },
],
empty: [
{ tool: 'LOCAL_VIEW_STRUCTURE', strength: 'moderate', reason: 'Explore dirs to understand layout (depth=1 then depth=2)' },
{ tool: 'LOCAL_FIND_FILES', strength: 'moderate', reason: 'Try metadata search: name patterns, modifiedWithin="7d"' },
],
},
},
LOCAL_FIND_FILES: {
strong: [
{ tool: 'LOCAL_FETCH_CONTENT', strength: 'strong', reason: 'Read discovered files with matchString + charLength for targeted extraction (Workflow: Filter -> Read)' },
],
moderate: [
{ tool: 'LOCAL_RIPGREP', strength: 'moderate', reason: 'Search patterns within found files (content-based refinement)' },
{ tool: 'LOCAL_VIEW_STRUCTURE', strength: 'moderate', reason: 'Understand directory context when results are unclear' },
],
weak: [],
nextStep: {
hasResults: [
{ tool: 'LOCAL_FETCH_CONTENT', strength: 'strong', reason: 'Read files with matchString + charLength (UNIQUE: modifiedWithin="7d" for recent)' },
{ tool: 'LOCAL_RIPGREP', strength: 'moderate', reason: 'Search patterns in found files (combine metadata + content search)' },
],
empty: [
{ tool: 'LOCAL_VIEW_STRUCTURE', strength: 'moderate', reason: 'See what exists (verify path, check with hidden=true)' },
{ tool: 'LOCAL_RIPGREP', strength: 'moderate', reason: 'Try content search if filename unknown (filesOnly first)' },
],
},
},
LOCAL_FETCH_CONTENT: {
strong: [],
moderate: [
{ tool: 'LOCAL_RIPGREP', strength: 'moderate', reason: 'Find related patterns/imports/usage after understanding code (Workflow: Read -> Explore)' },
],
weak: [],
nextStep: {
hasResults: [
{ tool: 'LOCAL_RIPGREP', strength: 'moderate', reason: 'Find related patterns, imports, function usage (filesOnly or targeted)' },
],
empty: [
{ tool: 'LOCAL_RIPGREP', strength: 'moderate', reason: 'Search for file location (filesOnly=true for discovery)' },
{ tool: 'LOCAL_FIND_FILES', strength: 'moderate', reason: 'Discover by name pattern (iname for case-insensitive)' },
],
},
},
};
/**
* Get next tool suggestions based on current tool and result status
*/
export function getNextToolSuggestions(
currentTool: ToolName,
status: 'hasResults' | 'empty'
): ToolConnection[] {
return TOOL_CONNECTIONS[currentTool]?.nextStep[status] || [];
}
/**
* Get all connections for a tool by strength
*/
export function getToolConnections(
tool: ToolName,
strength?: ConnectionStrength
): ToolConnection[] {
const connections = TOOL_CONNECTIONS[tool];
if (!connections) return [];
if (strength) {
return connections[strength] || [];
}
return [...connections.strong, ...connections.moderate, ...connections.weak];
}
/**
* Get connection strength between two tools
*/
export function getConnectionStrength(
fromTool: ToolName,
toTool: ToolName
): ConnectionStrength | null {
const connections = TOOL_CONNECTIONS[fromTool];
if (!connections) return null;
const allConnections = [...connections.strong, ...connections.moderate, ...connections.weak];
const connection = allConnections.find((c) => c.tool === toTool);
return connection?.strength || null;
}
/**
* RESEARCH FLOW PATTERNS (Updated)
*
* Primary Workflows:
*
* 1. DISCOVERY -> SEARCH -> READ -> EXPLORE
* VIEW_STRUCTURE (depth=1) -> RIPGREP (filesOnly) -> FETCH_CONTENT (matchString) -> RIPGREP (related)
*
* 2. PATTERN SEARCH -> READ -> EXPLORE
* RIPGREP (mode=discovery) -> FETCH_CONTENT (matchString) -> RIPGREP (imports/usage)
*
* 3. METADATA SEARCH -> READ -> CONTENT SEARCH
* FIND_FILES (modifiedWithin) -> FETCH_CONTENT (matchString) -> RIPGREP (patterns)
*
* Key Connection Principles:
* - Strong: Primary workflow step, frequently chained
* - Moderate: Alternative path or context-dependent
* - Weak: Special cases, rarely needed
*
* Connection Reasons Include:
* - Workflow indicators (Discovery -> Detailed -> Read)
* - Parameter suggestions (matchString, modifiedWithin, filesOnly)
* - Unique feature callouts (ONLY time-based tool, most efficient)
* - Common patterns (combine metadata + content search)
*/