genesis-ai-cli 7.4.7 → 7.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/dist/src/cli/dispatcher.js +74 -4
- package/dist/src/mcp/cache.d.ts +100 -0
- package/dist/src/mcp/cache.js +395 -0
- package/dist/src/mcp/index.d.ts +15 -1
- package/dist/src/mcp/index.js +37 -7
- package/dist/src/mcp/multimodal.d.ts +52 -0
- package/dist/src/mcp/multimodal.js +355 -0
- package/dist/src/mcp/parallel-executor.d.ts +113 -0
- package/dist/src/mcp/parallel-executor.js +335 -0
- package/dist/src/mcp/streaming.d.ts +78 -0
- package/dist/src/mcp/streaming.js +345 -0
- package/dist/src/mcp/tool-chain.d.ts +79 -0
- package/dist/src/mcp/tool-chain.js +323 -0
- package/dist/src/mcp/transformers.d.ts +156 -0
- package/dist/src/mcp/transformers.js +362 -0
- package/package.json +1 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis MCP Tool Chaining Framework
|
|
4
|
+
*
|
|
5
|
+
* Automatic orchestration of dependent tool calls.
|
|
6
|
+
* Enables workflows like: generate image → open it → edit it
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Declarative chain definitions
|
|
10
|
+
* - Automatic output → input mapping
|
|
11
|
+
* - Conditional branching
|
|
12
|
+
* - Error recovery and rollback
|
|
13
|
+
* - Chain execution history
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ChainBuilder = exports.ToolChainExecutor = exports.CHAIN_TEMPLATES = void 0;
|
|
17
|
+
exports.getChainExecutor = getChainExecutor;
|
|
18
|
+
exports.chain = chain;
|
|
19
|
+
exports.executeChain = executeChain;
|
|
20
|
+
const index_js_1 = require("./index.js");
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Predefined Chain Templates
|
|
23
|
+
// ============================================================================
|
|
24
|
+
exports.CHAIN_TEMPLATES = {
|
|
25
|
+
// Generate image and open it
|
|
26
|
+
'generate-and-display': {
|
|
27
|
+
id: 'generate-and-display',
|
|
28
|
+
name: 'Generate and Display Image',
|
|
29
|
+
description: 'Generate an image with Stability AI and open it in the default viewer',
|
|
30
|
+
steps: [
|
|
31
|
+
{
|
|
32
|
+
id: 'generate',
|
|
33
|
+
server: 'stability-ai',
|
|
34
|
+
tool: 'stability-ai-generate-image',
|
|
35
|
+
params: (ctx) => ({
|
|
36
|
+
prompt: ctx.data.prompt || 'a beautiful landscape',
|
|
37
|
+
outputImageFileName: ctx.data.filename || `genesis-${Date.now()}`,
|
|
38
|
+
}),
|
|
39
|
+
transform: (result) => ({
|
|
40
|
+
imagePath: result.imagePath || result.outputPath || result,
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'open',
|
|
45
|
+
server: 'filesystem',
|
|
46
|
+
tool: 'read_file',
|
|
47
|
+
params: (ctx) => ({
|
|
48
|
+
path: ctx.results.get('generate')?.imagePath,
|
|
49
|
+
}),
|
|
50
|
+
condition: (ctx) => !!ctx.results.get('generate')?.imagePath,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
// Search and scrape
|
|
55
|
+
'search-and-scrape': {
|
|
56
|
+
id: 'search-and-scrape',
|
|
57
|
+
name: 'Search and Scrape',
|
|
58
|
+
description: 'Search for a topic and scrape the top result',
|
|
59
|
+
steps: [
|
|
60
|
+
{
|
|
61
|
+
id: 'search',
|
|
62
|
+
server: 'brave-search',
|
|
63
|
+
tool: 'brave_web_search',
|
|
64
|
+
params: (ctx) => ({
|
|
65
|
+
query: ctx.data.query,
|
|
66
|
+
count: 3,
|
|
67
|
+
}),
|
|
68
|
+
transform: (result) => ({
|
|
69
|
+
url: result.results?.[0]?.url || result.web?.results?.[0]?.url,
|
|
70
|
+
title: result.results?.[0]?.title || result.web?.results?.[0]?.title,
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'scrape',
|
|
75
|
+
server: 'firecrawl',
|
|
76
|
+
tool: 'firecrawl_scrape',
|
|
77
|
+
params: (ctx) => ({
|
|
78
|
+
url: ctx.results.get('search')?.url,
|
|
79
|
+
formats: ['markdown'],
|
|
80
|
+
}),
|
|
81
|
+
condition: (ctx) => !!ctx.results.get('search')?.url,
|
|
82
|
+
onError: 'skip',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
// Research paper workflow
|
|
87
|
+
'research-paper': {
|
|
88
|
+
id: 'research-paper',
|
|
89
|
+
name: 'Research Paper Workflow',
|
|
90
|
+
description: 'Search arXiv, get citations, save to memory',
|
|
91
|
+
steps: [
|
|
92
|
+
{
|
|
93
|
+
id: 'search-arxiv',
|
|
94
|
+
server: 'arxiv',
|
|
95
|
+
tool: 'search_arxiv',
|
|
96
|
+
params: (ctx) => ({
|
|
97
|
+
query: ctx.data.query,
|
|
98
|
+
maxResults: 5,
|
|
99
|
+
}),
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'get-citations',
|
|
103
|
+
server: 'semantic-scholar',
|
|
104
|
+
tool: 'get_paper_citations',
|
|
105
|
+
params: (ctx) => {
|
|
106
|
+
const papers = ctx.results.get('search-arxiv')?.papers || [];
|
|
107
|
+
const firstPaper = papers[0];
|
|
108
|
+
return {
|
|
109
|
+
paperId: firstPaper?.id?.replace('arxiv:', '') || '',
|
|
110
|
+
maxResults: 10,
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
condition: (ctx) => {
|
|
114
|
+
const papers = ctx.results.get('search-arxiv')?.papers || [];
|
|
115
|
+
return papers.length > 0;
|
|
116
|
+
},
|
|
117
|
+
onError: 'skip',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 'save-to-memory',
|
|
121
|
+
server: 'memory',
|
|
122
|
+
tool: 'create_entities',
|
|
123
|
+
params: (ctx) => {
|
|
124
|
+
const papers = ctx.results.get('search-arxiv')?.papers || [];
|
|
125
|
+
return {
|
|
126
|
+
entities: papers.slice(0, 3).map((p) => ({
|
|
127
|
+
name: p.title || 'Unknown Paper',
|
|
128
|
+
entityType: 'research_paper',
|
|
129
|
+
observations: [
|
|
130
|
+
`Authors: ${p.authors?.join(', ') || 'Unknown'}`,
|
|
131
|
+
`Abstract: ${p.abstract?.slice(0, 200) || 'N/A'}...`,
|
|
132
|
+
],
|
|
133
|
+
})),
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
condition: (ctx) => {
|
|
137
|
+
const papers = ctx.results.get('search-arxiv')?.papers || [];
|
|
138
|
+
return papers.length > 0;
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
// ============================================================================
|
|
145
|
+
// Chain Executor
|
|
146
|
+
// ============================================================================
|
|
147
|
+
class ToolChainExecutor {
|
|
148
|
+
mcpClient = (0, index_js_1.getMCPClient)();
|
|
149
|
+
async execute(chain, initialData = {}) {
|
|
150
|
+
const context = {
|
|
151
|
+
results: new Map(),
|
|
152
|
+
currentStep: 0,
|
|
153
|
+
errors: [],
|
|
154
|
+
data: { ...chain.initialContext, ...initialData },
|
|
155
|
+
startTime: new Date(),
|
|
156
|
+
log: [],
|
|
157
|
+
};
|
|
158
|
+
let stepsExecuted = 0;
|
|
159
|
+
let stepsFailed = 0;
|
|
160
|
+
for (let i = 0; i < chain.steps.length; i++) {
|
|
161
|
+
const step = chain.steps[i];
|
|
162
|
+
context.currentStep = i;
|
|
163
|
+
// Check condition
|
|
164
|
+
if (step.condition && !step.condition(context)) {
|
|
165
|
+
this.log(context, step.id, 'skip', { reason: 'condition not met' });
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const stepStart = Date.now();
|
|
169
|
+
this.log(context, step.id, 'start');
|
|
170
|
+
try {
|
|
171
|
+
// Resolve params (can be function)
|
|
172
|
+
const params = typeof step.params === 'function'
|
|
173
|
+
? step.params(context)
|
|
174
|
+
: step.params;
|
|
175
|
+
// Execute the tool
|
|
176
|
+
const result = await this.executeStep(step, params, context);
|
|
177
|
+
if (!result.success) {
|
|
178
|
+
throw new Error(result.error || 'Tool call failed');
|
|
179
|
+
}
|
|
180
|
+
// Transform result if needed
|
|
181
|
+
const transformedResult = step.transform
|
|
182
|
+
? step.transform(result.data)
|
|
183
|
+
: result.data;
|
|
184
|
+
context.results.set(step.id, transformedResult);
|
|
185
|
+
stepsExecuted++;
|
|
186
|
+
this.log(context, step.id, 'success', {
|
|
187
|
+
latency: Date.now() - stepStart,
|
|
188
|
+
resultKeys: Object.keys(transformedResult || {}),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
stepsFailed++;
|
|
193
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
194
|
+
context.errors.push({ stepId: step.id, error: err });
|
|
195
|
+
this.log(context, step.id, 'error', {
|
|
196
|
+
message: err.message,
|
|
197
|
+
latency: Date.now() - stepStart,
|
|
198
|
+
});
|
|
199
|
+
// Handle error based on strategy
|
|
200
|
+
if (step.onError === 'stop') {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
else if (step.onError === 'retry') {
|
|
204
|
+
const retryResult = await this.retryStep(step, context, step.maxRetries || 3);
|
|
205
|
+
if (retryResult) {
|
|
206
|
+
context.results.set(step.id, retryResult);
|
|
207
|
+
stepsExecuted++;
|
|
208
|
+
this.log(context, step.id, 'retry', { success: true });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (typeof step.onError === 'function') {
|
|
212
|
+
const recoveryStep = step.onError(err, context);
|
|
213
|
+
if (recoveryStep) {
|
|
214
|
+
// Insert recovery step
|
|
215
|
+
chain.steps.splice(i + 1, 0, recoveryStep);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// 'skip' just continues to next step
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const finalResult = chain.finalTransform
|
|
222
|
+
? chain.finalTransform(context)
|
|
223
|
+
: context.results.get(chain.steps[chain.steps.length - 1]?.id);
|
|
224
|
+
return {
|
|
225
|
+
success: stepsFailed === 0,
|
|
226
|
+
finalResult,
|
|
227
|
+
context,
|
|
228
|
+
totalLatency: Date.now() - context.startTime.getTime(),
|
|
229
|
+
stepsExecuted,
|
|
230
|
+
stepsFailed,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async executeStep(step, params, context) {
|
|
234
|
+
return this.mcpClient.call(step.server, step.tool, params);
|
|
235
|
+
}
|
|
236
|
+
async retryStep(step, context, maxRetries) {
|
|
237
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
238
|
+
try {
|
|
239
|
+
const params = typeof step.params === 'function'
|
|
240
|
+
? step.params(context)
|
|
241
|
+
: step.params;
|
|
242
|
+
const result = await this.executeStep(step, params, context);
|
|
243
|
+
if (result.success) {
|
|
244
|
+
return step.transform ? step.transform(result.data) : result.data;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// Continue retrying
|
|
249
|
+
}
|
|
250
|
+
// Exponential backoff
|
|
251
|
+
await new Promise(r => setTimeout(r, 100 * Math.pow(2, attempt)));
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
log(context, stepId, action, details) {
|
|
256
|
+
context.log.push({
|
|
257
|
+
timestamp: new Date(),
|
|
258
|
+
stepId,
|
|
259
|
+
action,
|
|
260
|
+
details,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
exports.ToolChainExecutor = ToolChainExecutor;
|
|
265
|
+
// ============================================================================
|
|
266
|
+
// Chain Builder (Fluent API)
|
|
267
|
+
// ============================================================================
|
|
268
|
+
class ChainBuilder {
|
|
269
|
+
chain;
|
|
270
|
+
constructor(id, name) {
|
|
271
|
+
this.chain = {
|
|
272
|
+
id,
|
|
273
|
+
name,
|
|
274
|
+
steps: [],
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
description(desc) {
|
|
278
|
+
this.chain.description = desc;
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
initialContext(ctx) {
|
|
282
|
+
this.chain.initialContext = ctx;
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
step(step) {
|
|
286
|
+
this.chain.steps.push(step);
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
call(id, server, tool, params) {
|
|
290
|
+
return this.step({ id, server, tool, params });
|
|
291
|
+
}
|
|
292
|
+
finalTransform(fn) {
|
|
293
|
+
this.chain.finalTransform = fn;
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
build() {
|
|
297
|
+
return this.chain;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
exports.ChainBuilder = ChainBuilder;
|
|
301
|
+
// ============================================================================
|
|
302
|
+
// Singleton & Factory
|
|
303
|
+
// ============================================================================
|
|
304
|
+
let executorInstance = null;
|
|
305
|
+
function getChainExecutor() {
|
|
306
|
+
if (!executorInstance) {
|
|
307
|
+
executorInstance = new ToolChainExecutor();
|
|
308
|
+
}
|
|
309
|
+
return executorInstance;
|
|
310
|
+
}
|
|
311
|
+
function chain(id, name) {
|
|
312
|
+
return new ChainBuilder(id, name);
|
|
313
|
+
}
|
|
314
|
+
async function executeChain(chainOrId, data = {}) {
|
|
315
|
+
const executor = getChainExecutor();
|
|
316
|
+
const chainDef = typeof chainOrId === 'string'
|
|
317
|
+
? exports.CHAIN_TEMPLATES[chainOrId]
|
|
318
|
+
: chainOrId;
|
|
319
|
+
if (!chainDef) {
|
|
320
|
+
throw new Error(`Chain not found: ${chainOrId}`);
|
|
321
|
+
}
|
|
322
|
+
return executor.execute(chainDef, data);
|
|
323
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis MCP Result Transformers
|
|
3
|
+
*
|
|
4
|
+
* Composable data transformations for MCP tool results.
|
|
5
|
+
* Pipe-style API for chaining transformations.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Common transformers (extract, filter, map, reduce)
|
|
9
|
+
* - Domain-specific transformers (papers, search, code)
|
|
10
|
+
* - Type-safe pipeline composition
|
|
11
|
+
* - Error handling in pipelines
|
|
12
|
+
* - Custom transformer creation
|
|
13
|
+
*/
|
|
14
|
+
export type Transformer<TIn, TOut> = (input: TIn) => TOut;
|
|
15
|
+
export type AsyncTransformer<TIn, TOut> = (input: TIn) => Promise<TOut>;
|
|
16
|
+
export interface TransformPipeline<T> {
|
|
17
|
+
pipe<TOut>(transformer: Transformer<T, TOut>): TransformPipeline<TOut>;
|
|
18
|
+
pipeAsync<TOut>(transformer: AsyncTransformer<T, TOut>): AsyncTransformPipeline<TOut>;
|
|
19
|
+
value(): T;
|
|
20
|
+
valueOr<TDefault>(fallback: TDefault): T | TDefault;
|
|
21
|
+
}
|
|
22
|
+
export interface AsyncTransformPipeline<T> {
|
|
23
|
+
pipe<TOut>(transformer: Transformer<T, TOut>): AsyncTransformPipeline<TOut>;
|
|
24
|
+
pipeAsync<TOut>(transformer: AsyncTransformer<T, TOut>): AsyncTransformPipeline<TOut>;
|
|
25
|
+
value(): Promise<T>;
|
|
26
|
+
valueOr<TDefault>(fallback: TDefault): Promise<T | TDefault>;
|
|
27
|
+
}
|
|
28
|
+
export declare function transform<T>(data: T): TransformPipeline<T>;
|
|
29
|
+
export declare function transformAsync<T>(data: Promise<T>): AsyncTransformPipeline<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Extract a nested property by path
|
|
32
|
+
*/
|
|
33
|
+
export declare function extract<TIn, TOut = any>(path: string): Transformer<TIn, TOut | undefined>;
|
|
34
|
+
/**
|
|
35
|
+
* Filter an array
|
|
36
|
+
*/
|
|
37
|
+
export declare function filter<T>(predicate: (item: T, index: number) => boolean): Transformer<T[], T[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Map over an array
|
|
40
|
+
*/
|
|
41
|
+
export declare function map<TIn, TOut>(mapper: (item: TIn, index: number) => TOut): Transformer<TIn[], TOut[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Reduce an array
|
|
44
|
+
*/
|
|
45
|
+
export declare function reduce<T, TOut>(reducer: (acc: TOut, item: T, index: number) => TOut, initial: TOut): Transformer<T[], TOut>;
|
|
46
|
+
/**
|
|
47
|
+
* Take first N items
|
|
48
|
+
*/
|
|
49
|
+
export declare function take<T>(n: number): Transformer<T[], T[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Sort an array
|
|
52
|
+
*/
|
|
53
|
+
export declare function sort<T>(compareFn?: (a: T, b: T) => number): Transformer<T[], T[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Get unique items by key
|
|
56
|
+
*/
|
|
57
|
+
export declare function unique<T>(keyFn?: (item: T) => any): Transformer<T[], T[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Group by key
|
|
60
|
+
*/
|
|
61
|
+
export declare function groupBy<T>(keyFn: (item: T) => string): Transformer<T[], Record<string, T[]>>;
|
|
62
|
+
/**
|
|
63
|
+
* Default value if null/undefined
|
|
64
|
+
*/
|
|
65
|
+
export declare function defaultTo<T>(fallback: T): Transformer<T | null | undefined, T>;
|
|
66
|
+
/**
|
|
67
|
+
* Pluck a property from each item
|
|
68
|
+
*/
|
|
69
|
+
export declare function pluck<T, K extends keyof T>(key: K): Transformer<T[], T[K][]>;
|
|
70
|
+
/**
|
|
71
|
+
* Flatten nested arrays
|
|
72
|
+
*/
|
|
73
|
+
export declare function flatten<T>(): Transformer<T[][], T[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Extract papers from arXiv/semantic-scholar results
|
|
76
|
+
*/
|
|
77
|
+
export declare function extractPapers(): Transformer<any, any[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Extract search results from brave/exa/firecrawl
|
|
80
|
+
*/
|
|
81
|
+
export declare function extractSearchResults(): Transformer<any, any[]>;
|
|
82
|
+
/**
|
|
83
|
+
* Normalize search result to common format
|
|
84
|
+
*/
|
|
85
|
+
export interface NormalizedSearchResult {
|
|
86
|
+
title: string;
|
|
87
|
+
url: string;
|
|
88
|
+
description: string;
|
|
89
|
+
source: string;
|
|
90
|
+
}
|
|
91
|
+
export declare function normalizeSearchResult(): Transformer<any, NormalizedSearchResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Normalize paper to common format
|
|
94
|
+
*/
|
|
95
|
+
export interface NormalizedPaper {
|
|
96
|
+
id: string;
|
|
97
|
+
title: string;
|
|
98
|
+
authors: string[];
|
|
99
|
+
abstract: string;
|
|
100
|
+
url: string;
|
|
101
|
+
year?: number;
|
|
102
|
+
citations?: number;
|
|
103
|
+
}
|
|
104
|
+
export declare function normalizePaper(): Transformer<any, NormalizedPaper>;
|
|
105
|
+
/**
|
|
106
|
+
* Filter by minimum citation count
|
|
107
|
+
*/
|
|
108
|
+
export declare function minCitations(min: number): Transformer<NormalizedPaper[], NormalizedPaper[]>;
|
|
109
|
+
/**
|
|
110
|
+
* Sort papers by citations (descending)
|
|
111
|
+
*/
|
|
112
|
+
export declare function sortByCitations(): Transformer<NormalizedPaper[], NormalizedPaper[]>;
|
|
113
|
+
/**
|
|
114
|
+
* Extract code from firecrawl/exa results
|
|
115
|
+
*/
|
|
116
|
+
export declare function extractCode(): Transformer<any, string[]>;
|
|
117
|
+
/**
|
|
118
|
+
* Extract URLs from content
|
|
119
|
+
*/
|
|
120
|
+
export declare function extractUrls(): Transformer<any, string[]>;
|
|
121
|
+
/**
|
|
122
|
+
* Summarize content to max length
|
|
123
|
+
*/
|
|
124
|
+
export declare function summarize(maxLength: number): Transformer<string, string>;
|
|
125
|
+
/**
|
|
126
|
+
* Format as markdown list
|
|
127
|
+
*/
|
|
128
|
+
export declare function toMarkdownList(): Transformer<string[], string>;
|
|
129
|
+
/**
|
|
130
|
+
* Format as numbered list
|
|
131
|
+
*/
|
|
132
|
+
export declare function toNumberedList(): Transformer<string[], string>;
|
|
133
|
+
/**
|
|
134
|
+
* Compose multiple transformers into one
|
|
135
|
+
*/
|
|
136
|
+
export declare function compose<TIn, TOut>(...transformers: Transformer<any, any>[]): Transformer<TIn, TOut>;
|
|
137
|
+
/**
|
|
138
|
+
* Create a transformer that tries multiple paths and returns first success
|
|
139
|
+
*/
|
|
140
|
+
export declare function tryPaths<TIn, TOut>(...paths: string[]): Transformer<TIn, TOut | undefined>;
|
|
141
|
+
/**
|
|
142
|
+
* Conditional transformer
|
|
143
|
+
*/
|
|
144
|
+
export declare function when<T>(predicate: (input: T) => boolean, thenTransform: Transformer<T, T>, elseTransform?: Transformer<T, T>): Transformer<T, T>;
|
|
145
|
+
/**
|
|
146
|
+
* Process arXiv search results into normalized papers
|
|
147
|
+
*/
|
|
148
|
+
export declare function processArxivResults(): Transformer<any, NormalizedPaper[]>;
|
|
149
|
+
/**
|
|
150
|
+
* Process web search results into normalized format
|
|
151
|
+
*/
|
|
152
|
+
export declare function processSearchResults(): Transformer<any, NormalizedSearchResult[]>;
|
|
153
|
+
/**
|
|
154
|
+
* Extract and summarize key information
|
|
155
|
+
*/
|
|
156
|
+
export declare function extractKeyInfo(maxItems?: number): Transformer<any, string[]>;
|