research-powerpack-mcp 3.4.8 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +63 -674
  2. package/dist/clients/reddit.d.ts +1 -6
  3. package/dist/clients/reddit.d.ts.map +1 -1
  4. package/dist/clients/reddit.js +24 -60
  5. package/dist/clients/reddit.js.map +1 -1
  6. package/dist/clients/scraper.d.ts +1 -6
  7. package/dist/clients/scraper.d.ts.map +1 -1
  8. package/dist/clients/scraper.js +33 -71
  9. package/dist/clients/scraper.js.map +1 -1
  10. package/dist/clients/search.d.ts +2 -2
  11. package/dist/clients/search.d.ts.map +1 -1
  12. package/dist/clients/search.js +6 -11
  13. package/dist/clients/search.js.map +1 -1
  14. package/dist/config/env.d.ts +75 -0
  15. package/dist/config/env.d.ts.map +1 -0
  16. package/dist/config/env.js +87 -0
  17. package/dist/config/env.js.map +1 -0
  18. package/dist/config/index.d.ts.map +1 -1
  19. package/dist/config/index.js +1 -5
  20. package/dist/config/index.js.map +1 -1
  21. package/dist/config/loader.d.ts.map +1 -1
  22. package/dist/config/loader.js +1 -6
  23. package/dist/config/loader.js.map +1 -1
  24. package/dist/config/yaml/tools-enhanced.yaml +0 -0
  25. package/dist/index.js +85 -25
  26. package/dist/index.js.map +1 -1
  27. package/dist/schemas/web-search.js +1 -1
  28. package/dist/schemas/web-search.js.map +1 -1
  29. package/dist/services/file-attachment.d.ts.map +1 -1
  30. package/dist/services/file-attachment.js +22 -25
  31. package/dist/services/file-attachment.js.map +1 -1
  32. package/dist/services/llm-processor.js +0 -25
  33. package/dist/services/llm-processor.js.map +1 -1
  34. package/dist/tools/reddit.d.ts.map +1 -1
  35. package/dist/tools/reddit.js +77 -29
  36. package/dist/tools/reddit.js.map +1 -1
  37. package/dist/tools/registry.js +2 -2
  38. package/dist/tools/registry.js.map +1 -1
  39. package/dist/tools/research.d.ts +2 -6
  40. package/dist/tools/research.d.ts.map +1 -1
  41. package/dist/tools/research.js +64 -53
  42. package/dist/tools/research.js.map +1 -1
  43. package/dist/tools/scrape.d.ts +1 -5
  44. package/dist/tools/scrape.d.ts.map +1 -1
  45. package/dist/tools/scrape.js +108 -66
  46. package/dist/tools/scrape.js.map +1 -1
  47. package/dist/tools/search.d.ts +1 -5
  48. package/dist/tools/search.d.ts.map +1 -1
  49. package/dist/tools/search.js +26 -16
  50. package/dist/tools/search.js.map +1 -1
  51. package/dist/tools/utils.d.ts +20 -59
  52. package/dist/tools/utils.d.ts.map +1 -1
  53. package/dist/tools/utils.js +25 -61
  54. package/dist/tools/utils.js.map +1 -1
  55. package/dist/utils/logger.d.ts +36 -0
  56. package/dist/utils/logger.d.ts.map +1 -0
  57. package/dist/utils/logger.js +40 -0
  58. package/dist/utils/logger.js.map +1 -0
  59. package/dist/utils/response.d.ts +101 -0
  60. package/dist/utils/response.d.ts.map +1 -0
  61. package/dist/utils/response.js +183 -0
  62. package/dist/utils/response.js.map +1 -0
  63. package/dist/utils/url-aggregator.d.ts.map +1 -1
  64. package/dist/utils/url-aggregator.js +4 -6
  65. package/dist/utils/url-aggregator.js.map +1 -1
  66. package/package.json +8 -2
  67. package/dist/utils/concurrency.d.ts +0 -29
  68. package/dist/utils/concurrency.d.ts.map +0 -1
  69. package/dist/utils/concurrency.js +0 -73
  70. package/dist/utils/concurrency.js.map +0 -1
@@ -1,31 +1,27 @@
1
1
  /**
2
2
  * Shared Tool Utilities
3
- * Extracted from individual handlers to eliminate duplication
3
+ * Central module for common tool functionality
4
+ * Re-exports from specialized utility modules for backwards compatibility
4
5
  */
6
+ // Re-export logging utilities from centralized module
7
+ export { safeLog, createToolLogger } from '../utils/logger.js';
8
+ // Re-export response formatting utilities
9
+ export { formatSuccess, formatError, formatBatchHeader, formatList, formatKeyValues, formatDuration, truncateText, } from '../utils/response.js';
5
10
  // ============================================================================
6
- // Logging Utilities
11
+ // Token Budget Constants
7
12
  // ============================================================================
8
13
  /**
9
- * Safe logger wrapper - NEVER throws
10
- * Logs to provided logger or falls back to console.error
11
- *
12
- * @param logger - Optional logger function
13
- * @param sessionId - Session ID for logging context
14
- * @param level - Log level
15
- * @param message - Message to log
16
- * @param toolName - Name of the tool for prefixing
14
+ * Token budgets for different tools
15
+ * Centralized here to ensure consistency
17
16
  */
18
- export async function safeLog(logger, sessionId, level, message, toolName) {
19
- if (!logger || !sessionId)
20
- return;
21
- try {
22
- await logger(level, `[${toolName}] ${message}`, sessionId);
23
- }
24
- catch {
25
- // Silently ignore logger errors - they should never crash the tool
26
- console.error(`[${toolName}] Logger failed: ${message}`);
27
- }
28
- }
17
+ export const TOKEN_BUDGETS = {
18
+ /** Total token budget for deep research */
19
+ RESEARCH: 32000,
20
+ /** Total token budget for web scraping */
21
+ SCRAPER: 32000,
22
+ /** Total token budget for Reddit post fetching */
23
+ REDDIT: 1000, // Comments budget
24
+ };
29
25
  // ============================================================================
30
26
  // Token Allocation
31
27
  // ============================================================================
@@ -34,22 +30,19 @@ export async function safeLog(logger, sessionId, level, message, toolName) {
34
30
  * Distributes a fixed budget across multiple items
35
31
  *
36
32
  * @param count - Number of items to distribute budget across
37
- * @param budget - Total token budget
33
+ * @param budget - Total token budget (defaults to RESEARCH budget)
38
34
  * @returns Tokens per item
39
35
  */
40
- export function calculateTokenAllocation(count, budget) {
36
+ export function calculateTokenAllocation(count, budget = TOKEN_BUDGETS.RESEARCH) {
41
37
  if (count <= 0)
42
38
  return budget;
43
39
  return Math.floor(budget / count);
44
40
  }
45
41
  // ============================================================================
46
- // Error Formatting
42
+ // Legacy Error Formatting (deprecated - use response.ts instead)
47
43
  // ============================================================================
48
44
  /**
49
- * Format retry hint based on error retryability
50
- *
51
- * @param retryable - Whether the error is retryable
52
- * @returns Hint string or empty string
45
+ * @deprecated Use formatError from response.ts instead
53
46
  */
54
47
  export function formatRetryHint(retryable) {
55
48
  return retryable
@@ -57,14 +50,7 @@ export function formatRetryHint(retryable) {
57
50
  : '';
58
51
  }
59
52
  /**
60
- * Create a standard error markdown response
61
- *
62
- * @param toolName - Name of the tool that errored
63
- * @param errorCode - Error code
64
- * @param message - Error message
65
- * @param retryable - Whether error is retryable
66
- * @param tip - Optional tip for resolution
67
- * @returns Formatted markdown error string
53
+ * @deprecated Use formatError from response.ts instead
68
54
  */
69
55
  export function formatToolError(toolName, errorCode, message, retryable, tip) {
70
56
  const retryHint = formatRetryHint(retryable);
@@ -76,10 +62,6 @@ export function formatToolError(toolName, errorCode, message, retryable, tip) {
76
62
  // ============================================================================
77
63
  /**
78
64
  * Validate that a value is a non-empty array
79
- *
80
- * @param value - Value to check
81
- * @param fieldName - Field name for error message
82
- * @returns Error message or undefined if valid
83
65
  */
84
66
  export function validateNonEmptyArray(value, fieldName) {
85
67
  if (!Array.isArray(value)) {
@@ -92,12 +74,6 @@ export function validateNonEmptyArray(value, fieldName) {
92
74
  }
93
75
  /**
94
76
  * Validate array length is within bounds
95
- *
96
- * @param arr - Array to check
97
- * @param min - Minimum length
98
- * @param max - Maximum length
99
- * @param fieldName - Field name for error message
100
- * @returns Error message or undefined if valid
101
77
  */
102
78
  export function validateArrayBounds(arr, min, max, fieldName) {
103
79
  if (arr.length < min) {
@@ -109,28 +85,16 @@ export function validateArrayBounds(arr, min, max, fieldName) {
109
85
  return undefined;
110
86
  }
111
87
  // ============================================================================
112
- // Response Builders
88
+ // Legacy Response Builders (deprecated - use response.ts instead)
113
89
  // ============================================================================
114
90
  /**
115
- * Build standard header for batch operation results
116
- *
117
- * @param title - Title of the results section
118
- * @param count - Number of items processed
119
- * @param tokensPerItem - Tokens allocated per item
120
- * @param totalBudget - Total token budget
121
- * @returns Formatted header string
91
+ * @deprecated Use formatBatchHeader from response.ts instead
122
92
  */
123
93
  export function buildBatchHeader(title, count, tokensPerItem, totalBudget) {
124
94
  return `# ${title} (${count} items)\n\n**Token Allocation:** ${tokensPerItem.toLocaleString()} tokens/item (${count} items, ${totalBudget.toLocaleString()} total budget)`;
125
95
  }
126
96
  /**
127
- * Build status line for batch results
128
- *
129
- * @param successful - Number of successful items
130
- * @param failed - Number of failed items
131
- * @param batches - Number of batches processed
132
- * @param extras - Optional extra status items
133
- * @returns Formatted status line
97
+ * @deprecated Use formatBatchHeader from response.ts instead
134
98
  */
135
99
  export function buildStatusLine(successful, failed, batches, extras) {
136
100
  let status = `**Status:** ✅ ${successful} successful | ❌ ${failed} failed | 📦 ${batches} batch(es)`;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Centralized Logger Utilities
3
+ * Provides safe logging that NEVER throws - extracted from tool handlers
4
+ */
5
+ /**
6
+ * Logger function type used across all tools
7
+ */
8
+ export type ToolLogger = (level: 'info' | 'error' | 'debug', message: string, sessionId: string) => Promise<void>;
9
+ /**
10
+ * Standard options passed to tool handlers
11
+ */
12
+ export interface ToolOptions {
13
+ sessionId?: string;
14
+ logger?: ToolLogger;
15
+ }
16
+ /**
17
+ * Safe logger wrapper - NEVER throws
18
+ * Logs to provided logger or falls back to console.error
19
+ *
20
+ * @param logger - Optional logger function
21
+ * @param sessionId - Session ID for logging context
22
+ * @param level - Log level ('info' | 'error' | 'debug')
23
+ * @param message - Message to log
24
+ * @param toolName - Name of the tool for prefixing (optional)
25
+ */
26
+ export declare function safeLog(logger: ToolLogger | undefined, sessionId: string | undefined, level: 'info' | 'error' | 'debug', message: string, toolName?: string): Promise<void>;
27
+ /**
28
+ * Create a bound logger for a specific tool
29
+ * Returns a simpler function that only needs level and message
30
+ *
31
+ * @param options - Tool options containing logger and sessionId
32
+ * @param toolName - Name of the tool for log prefixing
33
+ * @returns Bound log function
34
+ */
35
+ export declare function createToolLogger(options: ToolOptions, toolName: string): (level: 'info' | 'error' | 'debug', message: string) => Promise<void>;
36
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,GACf,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAIvE"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Centralized Logger Utilities
3
+ * Provides safe logging that NEVER throws - extracted from tool handlers
4
+ */
5
+ /**
6
+ * Safe logger wrapper - NEVER throws
7
+ * Logs to provided logger or falls back to console.error
8
+ *
9
+ * @param logger - Optional logger function
10
+ * @param sessionId - Session ID for logging context
11
+ * @param level - Log level ('info' | 'error' | 'debug')
12
+ * @param message - Message to log
13
+ * @param toolName - Name of the tool for prefixing (optional)
14
+ */
15
+ export async function safeLog(logger, sessionId, level, message, toolName) {
16
+ if (!logger || !sessionId)
17
+ return;
18
+ const prefix = toolName ? `[${toolName}] ` : '';
19
+ try {
20
+ await logger(level, `${prefix}${message}`, sessionId);
21
+ }
22
+ catch {
23
+ // Silently ignore logger errors - they should never crash the tool
24
+ console.error(`${prefix}Logger failed: ${message}`);
25
+ }
26
+ }
27
+ /**
28
+ * Create a bound logger for a specific tool
29
+ * Returns a simpler function that only needs level and message
30
+ *
31
+ * @param options - Tool options containing logger and sessionId
32
+ * @param toolName - Name of the tool for log prefixing
33
+ * @returns Bound log function
34
+ */
35
+ export function createToolLogger(options, toolName) {
36
+ return async (level, message) => {
37
+ await safeLog(options.logger, options.sessionId, level, message, toolName);
38
+ };
39
+ }
40
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAA8B,EAC9B,SAA6B,EAC7B,KAAiC,EACjC,OAAe,EACf,QAAiB;IAEjB,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;QAAE,OAAO;IAElC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,GAAG,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;QACnE,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,kBAAkB,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAoB,EACpB,QAAgB;IAEhB,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC9B,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7E,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Standardized Response Formatting for MCP Tools
3
+ * Implements the 70/20/10 pattern for agent-optimized responses
4
+ *
5
+ * 70% Summary - Key insights, status, metrics
6
+ * 20% Data - Structured results
7
+ * 10% Next Steps - Actionable follow-ups
8
+ */
9
+ export interface SuccessResponseOptions {
10
+ /** Main title for the response */
11
+ title: string;
12
+ /** Summary section (70% of response) */
13
+ summary: string;
14
+ /** Optional data section (20% of response) */
15
+ data?: string;
16
+ /** Optional next steps (10% of response) */
17
+ nextSteps?: string[];
18
+ /** Optional metadata to append */
19
+ metadata?: Record<string, string | number>;
20
+ }
21
+ export interface ErrorResponseOptions {
22
+ /** Error code (e.g., RATE_LIMITED, TIMEOUT) */
23
+ code: string;
24
+ /** Human-readable error message */
25
+ message: string;
26
+ /** Whether the error is retryable */
27
+ retryable?: boolean;
28
+ /** Steps to fix the error */
29
+ howToFix?: string[];
30
+ /** Alternative actions to try */
31
+ alternatives?: string[];
32
+ /** Tool name for context */
33
+ toolName?: string;
34
+ }
35
+ export interface BatchResultOptions {
36
+ /** Title for the batch results */
37
+ title: string;
38
+ /** Number of items processed */
39
+ totalItems: number;
40
+ /** Number of successful items */
41
+ successful: number;
42
+ /** Number of failed items */
43
+ failed: number;
44
+ /** Tokens allocated per item */
45
+ tokensPerItem?: number;
46
+ /** Total token budget */
47
+ totalBudget?: number;
48
+ /** Number of batches processed */
49
+ batches?: number;
50
+ /** Additional status items */
51
+ extras?: string[];
52
+ }
53
+ /**
54
+ * Format a successful tool response using the 70/20/10 pattern
55
+ *
56
+ * @example
57
+ * formatSuccess({
58
+ * title: 'Web Search Results',
59
+ * summary: '**Found 45 unique URLs** across 5 queries\n• 12 consensus results (appeared 3+ times)\n• Top domains: github.com, stackoverflow.com',
60
+ * data: '## Top Results\n1. [Title](url) - snippet\n2. ...',
61
+ * nextSteps: ['Scrape top URLs: scrape_links({urls: [...]})', 'Deep dive: deep_research({...})']
62
+ * })
63
+ */
64
+ export declare function formatSuccess(options: SuccessResponseOptions): string;
65
+ /**
66
+ * Format an error response with recovery guidance
67
+ *
68
+ * @example
69
+ * formatError({
70
+ * code: 'RATE_LIMITED',
71
+ * message: 'API rate limit exceeded',
72
+ * retryable: true,
73
+ * howToFix: ['Wait 60 seconds', 'Reduce batch size'],
74
+ * alternatives: ['Use cached results', 'Try different API']
75
+ * })
76
+ */
77
+ export declare function formatError(options: ErrorResponseOptions): string;
78
+ /**
79
+ * Format batch operation header with status
80
+ */
81
+ export declare function formatBatchHeader(options: BatchResultOptions): string;
82
+ /**
83
+ * Format a list of items with optional truncation
84
+ */
85
+ export declare function formatList(items: string[], options?: {
86
+ maxItems?: number;
87
+ ordered?: boolean;
88
+ }): string;
89
+ /**
90
+ * Format key-value pairs as a compact list
91
+ */
92
+ export declare function formatKeyValues(data: Record<string, unknown>): string;
93
+ /**
94
+ * Format execution time
95
+ */
96
+ export declare function formatDuration(ms: number): string;
97
+ /**
98
+ * Truncate text with ellipsis
99
+ */
100
+ export declare function truncateText(text: string, maxLength: number): string;
101
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAyCrE;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAwCjE;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAwBrE;AAMD;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACjD,MAAM,CAeR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAKrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGpE"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Standardized Response Formatting for MCP Tools
3
+ * Implements the 70/20/10 pattern for agent-optimized responses
4
+ *
5
+ * 70% Summary - Key insights, status, metrics
6
+ * 20% Data - Structured results
7
+ * 10% Next Steps - Actionable follow-ups
8
+ */
9
+ // ============================================================================
10
+ // Success Response Formatting
11
+ // ============================================================================
12
+ /**
13
+ * Format a successful tool response using the 70/20/10 pattern
14
+ *
15
+ * @example
16
+ * formatSuccess({
17
+ * title: 'Web Search Results',
18
+ * summary: '**Found 45 unique URLs** across 5 queries\n• 12 consensus results (appeared 3+ times)\n• Top domains: github.com, stackoverflow.com',
19
+ * data: '## Top Results\n1. [Title](url) - snippet\n2. ...',
20
+ * nextSteps: ['Scrape top URLs: scrape_links({urls: [...]})', 'Deep dive: deep_research({...})']
21
+ * })
22
+ */
23
+ export function formatSuccess(options) {
24
+ const sections = [];
25
+ // Title
26
+ sections.push(`# ✅ ${options.title}`);
27
+ // Summary (70%)
28
+ sections.push('');
29
+ sections.push(options.summary);
30
+ // Data (20%)
31
+ if (options.data) {
32
+ sections.push('');
33
+ sections.push('---');
34
+ sections.push('');
35
+ sections.push(options.data);
36
+ }
37
+ // Metadata
38
+ if (options.metadata && Object.keys(options.metadata).length > 0) {
39
+ sections.push('');
40
+ sections.push('---');
41
+ sections.push('');
42
+ sections.push('**Metadata:**');
43
+ for (const [key, value] of Object.entries(options.metadata)) {
44
+ sections.push(`- ${key}: ${value}`);
45
+ }
46
+ }
47
+ // Next Steps (10%)
48
+ if (options.nextSteps && options.nextSteps.length > 0) {
49
+ sections.push('');
50
+ sections.push('---');
51
+ sections.push('');
52
+ sections.push('**→ Next Steps:**');
53
+ for (const step of options.nextSteps) {
54
+ sections.push(`- ${step}`);
55
+ }
56
+ }
57
+ return sections.join('\n');
58
+ }
59
+ // ============================================================================
60
+ // Error Response Formatting
61
+ // ============================================================================
62
+ /**
63
+ * Format an error response with recovery guidance
64
+ *
65
+ * @example
66
+ * formatError({
67
+ * code: 'RATE_LIMITED',
68
+ * message: 'API rate limit exceeded',
69
+ * retryable: true,
70
+ * howToFix: ['Wait 60 seconds', 'Reduce batch size'],
71
+ * alternatives: ['Use cached results', 'Try different API']
72
+ * })
73
+ */
74
+ export function formatError(options) {
75
+ const sections = [];
76
+ // Title with tool name if provided
77
+ const titlePrefix = options.toolName ? `${options.toolName}: ` : '';
78
+ sections.push(`# ❌ ${titlePrefix}${options.code}`);
79
+ // Message
80
+ sections.push('');
81
+ sections.push(options.message);
82
+ // Retry hint
83
+ if (options.retryable !== undefined) {
84
+ sections.push('');
85
+ if (options.retryable) {
86
+ sections.push('💡 **This error may be temporary.** Try again in a moment.');
87
+ }
88
+ else {
89
+ sections.push('⚠️ **This error requires manual intervention.**');
90
+ }
91
+ }
92
+ // How to fix
93
+ if (options.howToFix && options.howToFix.length > 0) {
94
+ sections.push('');
95
+ sections.push('**How to Fix:**');
96
+ options.howToFix.forEach((step, i) => {
97
+ sections.push(`${i + 1}. ${step}`);
98
+ });
99
+ }
100
+ // Alternatives
101
+ if (options.alternatives && options.alternatives.length > 0) {
102
+ sections.push('');
103
+ sections.push('**Alternative Actions:**');
104
+ for (const alt of options.alternatives) {
105
+ sections.push(`• ${alt}`);
106
+ }
107
+ }
108
+ return sections.join('\n');
109
+ }
110
+ // ============================================================================
111
+ // Batch Result Formatting
112
+ // ============================================================================
113
+ /**
114
+ * Format batch operation header with status
115
+ */
116
+ export function formatBatchHeader(options) {
117
+ const sections = [];
118
+ // Title with count
119
+ sections.push(`# ${options.title} (${options.totalItems} items)`);
120
+ // Token allocation if provided
121
+ if (options.tokensPerItem && options.totalBudget) {
122
+ sections.push('');
123
+ sections.push(`**Token Allocation:** ${options.tokensPerItem.toLocaleString()} tokens/item (${options.totalItems} items, ${options.totalBudget.toLocaleString()} total budget)`);
124
+ }
125
+ // Status line
126
+ sections.push('');
127
+ let status = `**Status:** ✅ ${options.successful} successful | ❌ ${options.failed} failed`;
128
+ if (options.batches !== undefined) {
129
+ status += ` | 📦 ${options.batches} batch(es)`;
130
+ }
131
+ if (options.extras && options.extras.length > 0) {
132
+ status += ` | ${options.extras.join(' | ')}`;
133
+ }
134
+ sections.push(status);
135
+ return sections.join('\n');
136
+ }
137
+ // ============================================================================
138
+ // Utility Formatters
139
+ // ============================================================================
140
+ /**
141
+ * Format a list of items with optional truncation
142
+ */
143
+ export function formatList(items, options) {
144
+ const maxItems = options?.maxItems ?? items.length;
145
+ const ordered = options?.ordered ?? false;
146
+ const truncated = items.length > maxItems;
147
+ const displayItems = items.slice(0, maxItems);
148
+ const formatted = displayItems.map((item, i) => {
149
+ return ordered ? `${i + 1}. ${item}` : `• ${item}`;
150
+ });
151
+ if (truncated) {
152
+ formatted.push(`... and ${items.length - maxItems} more`);
153
+ }
154
+ return formatted.join('\n');
155
+ }
156
+ /**
157
+ * Format key-value pairs as a compact list
158
+ */
159
+ export function formatKeyValues(data) {
160
+ return Object.entries(data)
161
+ .filter(([, v]) => v !== undefined && v !== null)
162
+ .map(([k, v]) => `• **${k}:** ${v}`)
163
+ .join('\n');
164
+ }
165
+ /**
166
+ * Format execution time
167
+ */
168
+ export function formatDuration(ms) {
169
+ if (ms < 1000)
170
+ return `${ms}ms`;
171
+ if (ms < 60000)
172
+ return `${(ms / 1000).toFixed(1)}s`;
173
+ return `${(ms / 60000).toFixed(1)}m`;
174
+ }
175
+ /**
176
+ * Truncate text with ellipsis
177
+ */
178
+ export function truncateText(text, maxLength) {
179
+ if (text.length <= maxLength)
180
+ return text;
181
+ return text.slice(0, maxLength - 3) + '...';
182
+ }
183
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"url-aggregator.d.ts","sourceRoot":"","sources":["../../src/utils/url-aggregator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAgBpF;;GAEG;AACH,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,UAAU,iBAAiB;IACzB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAsHD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAyBD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,EAAE,EACrB,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CAiER;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,GAAE,MAAU,GAC3B,iBAAiB,CA+BnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAW9E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,GAAG,SAAS,CAG5F;AAqBD;;GAEG;AACH,UAAU,eAAe;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,UAAU,uBAAuB;IAC/B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA+FD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,EAC3C,gBAAgB,GAAE,MAAU,GAC3B,uBAAuB,CA+BzB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,uBAAuB,EACpC,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,GAC7C,MAAM,CAgGR"}
1
+ {"version":3,"file":"url-aggregator.d.ts","sourceRoot":"","sources":["../../src/utils/url-aggregator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAgBpF;;GAEG;AACH,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,UAAU,iBAAiB;IACzB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAqHD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAyBD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,EAAE,EACrB,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CAiER;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,GAAE,MAAU,GAC3B,iBAAiB,CA+BnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAW9E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,GAAG,SAAS,CAG5F;AAqBD;;GAEG;AACH,UAAU,eAAe;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,UAAU,uBAAuB;IAC/B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA8FD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,EAC3C,gBAAgB,GAAE,MAAU,GAC3B,uBAAuB,CA+BzB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,uBAAuB,EACpC,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,GAC7C,MAAM,CAgGR"}
@@ -29,11 +29,10 @@ function aggregateResults(searches) {
29
29
  existing.frequency += 1;
30
30
  existing.positions.push(result.position);
31
31
  existing.queries.push(search.keyword);
32
- const prevBest = existing.bestPosition;
33
32
  existing.bestPosition = Math.min(existing.bestPosition, result.position);
34
33
  existing.totalScore += getCtrWeight(result.position);
35
- // Keep best title/snippet (from highest ranking position)
36
- if (result.position < prevBest) {
34
+ // Keep best title/snippet (from highest position)
35
+ if (result.position < existing.positions[0]) {
37
36
  existing.title = result.title;
38
37
  existing.snippet = result.snippet;
39
38
  }
@@ -259,11 +258,10 @@ function aggregateRedditResults(searches) {
259
258
  existing.frequency += 1;
260
259
  existing.positions.push(position);
261
260
  existing.queries.push(query);
262
- const prevBest = existing.bestPosition;
263
261
  existing.bestPosition = Math.min(existing.bestPosition, position);
264
262
  existing.totalScore += getCtrWeight(position);
265
- // Keep best title/snippet (from highest ranking position)
266
- if (position < prevBest) {
263
+ // Keep best title/snippet (from highest position)
264
+ if (position < existing.positions[0]) {
267
265
  existing.title = result.title;
268
266
  existing.snippet = result.snippet;
269
267
  existing.date = result.date;