/** * Knowledge-Based Tool Pattern * * Reusable pattern for tools that query the knowledge base and return * structured plans instead of making AI calls. This pattern enables: * - Fast, deterministic tool execution (<100ms) * - Zero AI calls within tools (client AI generates content using plans) * - Testable, consistent behavior * - Reduced code duplication (30-50% code reduction per tool) * * @module tools/shared/knowledge-tool-pattern */ import { type Result } from '../../types/index.js'; import type { ToolContext } from '../../core/context.js'; import type { Topic } from '../../types/topics.js'; import type { KnowledgeCategory } from '../../knowledge/types.js'; import type { KnowledgeSnippet } from '../../knowledge/schemas.js'; /** * Configuration for knowledge query construction. * Defines how to translate tool input into knowledge base queries. */ export interface KnowledgeQueryConfig { /** Knowledge topic to query */ topic: Topic | ((input: TInput) => Topic); /** Knowledge category to filter by */ category: KnowledgeCategory; /** Maximum characters to return */ maxChars?: number; /** Maximum number of snippets to return */ maxSnippets?: number; /** Extract filters from input for knowledge query */ extractFilters: (input: TInput) => { environment?: string | undefined; language?: string | undefined; framework?: string | undefined; [key: string]: unknown; }; } /** * Categorized knowledge snippets. * Tools typically categorize knowledge into 3-4 meaningful buckets * (e.g., security, optimization, best practices). */ export interface CategorizedKnowledge { /** All knowledge snippets */ all: KnowledgeSnippet[]; /** Categorized by type */ categories: Record; } /** * Configuration for categorizing knowledge snippets. * Defines rules for grouping snippets into meaningful categories. */ export interface CategorizationConfig { /** Category names */ categoryNames: readonly TCategories[]; /** * Categorize a snippet into one or more categories. * Returns array of category names that this snippet belongs to. */ categorize: (snippet: KnowledgeSnippet, input?: TInput) => TCategories[]; } /** * Configuration for rule-based logic. * Defines deterministic rules that tools apply to inputs. */ export interface RulesConfig { /** * Apply deterministic rules to input and knowledge. * This replaces AI decision-making with explicit, testable logic. */ applyRules: (input: TInput, knowledge: CategorizedKnowledge, ctx: ToolContext) => TRuleResults | Promise; } /** * Configuration for confidence calculation. * Confidence indicates how well the knowledge base can address this request. */ export interface ConfidenceConfig { /** * Calculate confidence score (0.0 to 1.0) based on knowledge matches. * Higher match counts typically indicate higher confidence. * * Default: Math.min(0.95, 0.5 + matchCount * 0.05) */ calculateConfidence?: (matchCount: number) => number; } /** * Configuration for building the final plan output. * Defines how to structure the tool's response. */ export interface PlanBuilderConfig { /** * Build the final plan from all gathered information. * This is the structured output that the MCP client AI will use. */ buildPlan: (input: TInput, knowledge: CategorizedKnowledge, rules: TRuleResults, confidence: number, ctx: ToolContext) => TPlan | Promise; } /** * Complete configuration for a knowledge-based tool. * Combines all aspects of the pattern into a single config object. */ export interface KnowledgeToolConfig> { /** Tool name for logging */ name: string; /** Knowledge query configuration */ query: KnowledgeQueryConfig; /** Categorization configuration */ categorization: CategorizationConfig; /** Rule-based logic configuration */ rules: RulesConfig; /** Confidence calculation configuration */ confidence?: ConfidenceConfig; /** Plan building configuration */ plan: PlanBuilderConfig; } /** * Default confidence calculation. * Starts at 0.5 and increases by 0.05 per match, capped at 0.95. */ export declare const defaultConfidenceCalculation: (matchCount: number) => number; /** * Create a knowledge-based tool runner from configuration. * * This factory function creates a tool `run` function that: * 1. Queries the knowledge base (fast, deterministic) * 2. Categorizes knowledge snippets * 3. Applies rule-based logic * 4. Calculates confidence * 5. Builds and returns a structured plan * * No AI calls are made - the tool returns data for the MCP client AI to use. * * @param config - Complete tool configuration * @returns Tool run function * * @example * ```typescript * const run = createKnowledgeTool({ * name: 'generate-dockerfile-plan', * query: { * topic: TOPICS.DOCKERFILE, * category: CATEGORY.DOCKERFILE, * maxChars: 8000, * maxSnippets: 20, * extractFilters: (input) => ({ * environment: input.environment || 'production', * language: input.language, * framework: input.framework, * }), * }, * categorization: { * categoryNames: ['security', 'optimization', 'bestPractices'] as const, * categorize: (snippet) => { * const categories = []; * if (snippet.category === 'security' || snippet.tags?.includes('security')) { * categories.push('security'); * } * // ... more categorization logic * return categories; * }, * }, * rules: { * applyRules: (input, knowledge) => ({ * multistage: ['java', 'go', 'rust'].includes(input.language), * }), * }, * plan: { * buildPlan: (input, knowledge, rules, confidence) => ({ * repositoryInfo: { ... }, * recommendations: { ... }, * knowledgeMatches: knowledge.all, * confidence, * }), * }, * }); * ``` */ export declare function createKnowledgeTool>(config: KnowledgeToolConfig): (input: TInput, ctx: ToolContext) => Promise>; /** * Helper: Create a simple categorizer based on tags and category fields. * * This is a common pattern where snippets are categorized by checking * if they have specific tags or category values. * * @param rules - Mapping of category names to filter predicates * @returns Categorization function * * @example * ```typescript * const categorize = createSimpleCategorizer({ * security: (s) => s.category === 'security' || s.tags?.includes('security'), * optimization: (s) => s.tags?.includes('optimization') || s.tags?.includes('caching'), * bestPractices: (s) => true, // catch-all * }); * ``` */ export declare function createSimpleCategorizer(rules: Record boolean>): (snippet: KnowledgeSnippet) => TCategories[]; //# sourceMappingURL=knowledge-tool-pattern.d.ts.map