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.
- package/README.md +63 -674
- package/dist/clients/reddit.d.ts +1 -6
- package/dist/clients/reddit.d.ts.map +1 -1
- package/dist/clients/reddit.js +24 -60
- package/dist/clients/reddit.js.map +1 -1
- package/dist/clients/scraper.d.ts +1 -6
- package/dist/clients/scraper.d.ts.map +1 -1
- package/dist/clients/scraper.js +33 -71
- package/dist/clients/scraper.js.map +1 -1
- package/dist/clients/search.d.ts +2 -2
- package/dist/clients/search.d.ts.map +1 -1
- package/dist/clients/search.js +6 -11
- package/dist/clients/search.js.map +1 -1
- package/dist/config/env.d.ts +75 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +87 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -5
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +1 -6
- package/dist/config/loader.js.map +1 -1
- package/dist/config/yaml/tools-enhanced.yaml +0 -0
- package/dist/index.js +85 -25
- package/dist/index.js.map +1 -1
- package/dist/schemas/web-search.js +1 -1
- package/dist/schemas/web-search.js.map +1 -1
- package/dist/services/file-attachment.d.ts.map +1 -1
- package/dist/services/file-attachment.js +22 -25
- package/dist/services/file-attachment.js.map +1 -1
- package/dist/services/llm-processor.js +0 -25
- package/dist/services/llm-processor.js.map +1 -1
- package/dist/tools/reddit.d.ts.map +1 -1
- package/dist/tools/reddit.js +77 -29
- package/dist/tools/reddit.js.map +1 -1
- package/dist/tools/registry.js +2 -2
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/research.d.ts +2 -6
- package/dist/tools/research.d.ts.map +1 -1
- package/dist/tools/research.js +64 -53
- package/dist/tools/research.js.map +1 -1
- package/dist/tools/scrape.d.ts +1 -5
- package/dist/tools/scrape.d.ts.map +1 -1
- package/dist/tools/scrape.js +108 -66
- package/dist/tools/scrape.js.map +1 -1
- package/dist/tools/search.d.ts +1 -5
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +26 -16
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/utils.d.ts +20 -59
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +25 -61
- package/dist/tools/utils.js.map +1 -1
- package/dist/utils/logger.d.ts +36 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/response.d.ts +101 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +183 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/url-aggregator.d.ts.map +1 -1
- package/dist/utils/url-aggregator.js +4 -6
- package/dist/utils/url-aggregator.js.map +1 -1
- package/package.json +8 -2
- package/dist/utils/concurrency.d.ts +0 -29
- package/dist/utils/concurrency.d.ts.map +0 -1
- package/dist/utils/concurrency.js +0 -73
- package/dist/utils/concurrency.js.map +0 -1
package/dist/tools/utils.js
CHANGED
|
@@ -1,31 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared Tool Utilities
|
|
3
|
-
*
|
|
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
|
-
//
|
|
11
|
+
// Token Budget Constants
|
|
7
12
|
// ============================================================================
|
|
8
13
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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)`;
|
package/dist/tools/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA
|
|
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;
|
|
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
|
|
36
|
-
if (result.position <
|
|
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
|
|
266
|
-
if (position <
|
|
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;
|