reasonkit-core 0.1.8

The Reasoning Engine — Auditable Reasoning for Production AI | Rust-Native | Turn Prompts into Protocols
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
//! Docset Tools Benchmarks
//!
//! Benchmarks for the docset MCP tools implementation in ReasonKit.

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use reasonkit::mcp::docset_tools::*;
use reasonkit::mcp::tools::Tool;
use reasonkit::retrieval::HybridRetriever;
use serde_json::json;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::runtime::Runtime;

fn tool_by_name<'a>(tools: &'a [Tool], name: &str) -> &'a Tool {
    tools
        .iter()
        .find(|tool| tool.name == name)
        .unwrap_or_else(|| panic!("Expected tool '{name}' to exist"))
}

fn get_string_arg<'a>(args: &'a HashMap<String, serde_json::Value>, key: &str) -> Option<&'a str> {
    args.get(key).and_then(|value| value.as_str())
}

/// Benchmark tool definition creation
fn bench_tool_definitions_creation(c: &mut Criterion) {
    c.bench_function("docset_tool_definitions_creation", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            black_box(tools);
        })
    });
}

/// Benchmark argument extraction
fn bench_argument_extraction(c: &mut Criterion) {
    c.bench_function("docset_argument_extraction", |b| {
        // Setup test data
        let mut args = HashMap::new();
        args.insert("doc_id".to_string(), json!("test-document-id"));
        args.insert("chunk_id".to_string(), json!("test-chunk-id"));

        b.iter(|| {
            let result = get_string_arg(&args, "doc_id");
            black_box(result);
        })
    });
}

/// Benchmark tool name validation
fn bench_tool_name_validation(c: &mut Criterion) {
    c.bench_function("docset_tool_name_validation", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let names: Vec<&str> = tools.iter().map(|t| t.name.as_str()).collect();
            black_box(names.contains(&"rkmem_docs_search"));
        })
    });
}

/// Benchmark JSON schema validation
fn bench_json_schema_validation(c: &mut Criterion) {
    let tools = DocsetHandler::tool_definitions();
    let tool = tool_by_name(&tools, "rkmem_docs_search").clone();

    c.bench_function("docset_json_schema_validation", move |b| {
        b.iter(|| black_box(tool.input_schema.is_object()))
    });
}

/// Benchmark tool definitions access
fn bench_tool_definitions_access(c: &mut Criterion) {
    c.bench_function("docset_tool_definitions_access", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            for tool in tools {
                black_box(&tool.name);
                black_box(&tool.description);
                black_box(&tool.input_schema);
            }
        })
    });
}

/// Benchmark individual tool creation
fn bench_individual_tool_creation(c: &mut Criterion) {
    c.bench_function("docset_individual_tool_creation", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let get_chunk = tool_by_name(&tools, "rkmem_docs_get_chunk");
            let get_neighbors = tool_by_name(&tools, "rkmem_docs_get_neighbors");
            let search = tool_by_name(&tools, "rkmem_docs_search");
            let ingest = tool_by_name(&tools, "rkmem_docs_ingest");
            let list = tool_by_name(&tools, "rkmem_docs_list");

            black_box(get_chunk);
            black_box(get_neighbors);
            black_box(search);
            black_box(ingest);
            black_box(list);
        })
    });
}

/// Benchmark handler creation
fn bench_handler_creation(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();

    c.bench_function("docset_handler_creation", |b| {
        b.to_async(&rt).iter(|| async {
            let retriever = HybridRetriever::in_memory().expect("Failed to create retriever");
            let handler = DocsetHandler::new(Arc::new(retriever));
            black_box(handler);
        })
    });
}

/// Benchmark tool calling with missing arguments (error case)
fn bench_tool_calling_error_case(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();

    c.bench_function("docset_tool_calling_error_case", |b| {
        b.to_async(&rt).iter(|| async {
            let retriever = HybridRetriever::in_memory().expect("Failed to create retriever");
            let handler = DocsetHandler::new(Arc::new(retriever));

            let args = HashMap::new(); // Empty args should cause error
            let result = handler.call_tool("rkmem_docs_get_chunk", args).await;
            let _ = black_box(result);
        })
    });
}

/// Benchmark extract_required_string with various input sizes
fn bench_argument_extraction_various_sizes(c: &mut Criterion) {
    c.bench_function("docset_argument_extraction_short", |b| {
        let mut args = HashMap::new();
        args.insert("key".to_string(), json!("short"));
        b.iter(|| {
            let result = get_string_arg(&args, "key");
            black_box(result);
        })
    });

    c.bench_function("docset_argument_extraction_medium", |b| {
        let mut args = HashMap::new();
        args.insert(
            "key".to_string(),
            json!("medium length string for testing purposes"),
        );
        b.iter(|| {
            let result = get_string_arg(&args, "key");
            black_box(result);
        })
    });

    c.bench_function("docset_argument_extraction_long", |b| {
        let mut args = HashMap::new();
        args.insert("key".to_string(), json!("very long string that is meant to simulate a large input for performance testing of the extraction function to ensure it handles various sizes efficiently without significant performance degradation"));
        b.iter(|| {
            let result = get_string_arg(&args, "key");
            black_box(result);
        })
    });
}

/// Benchmark schema validation for different tools
fn bench_schema_validation_all_tools(c: &mut Criterion) {
    c.bench_function("docset_schema_validation_all_tools", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            for tool in tools {
                black_box(tool.input_schema.is_object());
            }
        })
    });
}

/// Benchmark tool name lookup performance
fn bench_tool_name_lookup(c: &mut Criterion) {
    c.bench_function("docset_tool_name_lookup_existing", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let names: Vec<&str> = tools.iter().map(|t| t.name.as_str()).collect();
            let exists = names.contains(&"rkmem_docs_search");
            black_box(exists);
        })
    });

    c.bench_function("docset_tool_name_lookup_nonexistent", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let names: Vec<&str> = tools.iter().map(|t| t.name.as_str()).collect();
            let exists = names.contains(&"nonexistent_tool_name");
            black_box(exists);
        })
    });
}

/// Benchmark memory allocation for tool definitions
fn bench_tool_definitions_memory_allocation(c: &mut Criterion) {
    c.bench_function("docset_tool_definitions_memory_allocation", |b| {
        b.iter(|| {
            // This tests the memory allocation overhead of creating tool definitions
            let tools = DocsetHandler::tool_definitions();
            let mut total_chars = 0;

            for tool in &tools {
                total_chars += tool.name.len();
                if let Some(desc) = &tool.description {
                    total_chars += desc.len();
                }
                // Add JSON schema size approximation
                total_chars += tool.input_schema.to_string().len();
            }

            black_box(total_chars);
        })
    });
}

/// Benchmark concurrent tool definition access
fn bench_concurrent_tool_access(c: &mut Criterion) {
    c.bench_function("docset_concurrent_tool_access", |b| {
        b.iter(|| {
            // Simulate concurrent access by accessing multiple times
            let tools1 = DocsetHandler::tool_definitions();
            let tools2 = DocsetHandler::tool_definitions();
            let tools3 = DocsetHandler::tool_definitions();

            black_box(tools1.len());
            black_box(tools2.len());
            black_box(tools3.len());
        })
    });
}

/// Benchmark error message generation
fn bench_error_message_generation(c: &mut Criterion) {
    c.bench_function("docset_error_message_generation", |b| {
        b.iter(|| {
            // Test various error message generation scenarios
            let error1 = format!("Missing required argument: {}", "doc_id");
            let error2 = format!("Invalid {} format", "UUID");
            let error3 = format!("{} not found in {}", "Chunk", "Document");

            black_box(error1);
            black_box(error2);
            black_box(error3);
        })
    });
}

/// Benchmark JSON serialization of results
fn bench_json_serialization_performance(c: &mut Criterion) {
    c.bench_function("docset_json_serialization_small", |b| {
        b.iter(|| {
            let small_result = json!({
                "status": "success",
                "message": "test"
            });
            let serialized = serde_json::to_string(&small_result).unwrap();
            black_box(serialized);
        })
    });

    c.bench_function("docset_json_serialization_medium", |b| {
        b.iter(|| {
            let medium_result = json!({
                "status": "success",
                "doc_id": "123e4567-e89b-12d3-a456-426614174000",
                "chunk_id": "abcdef12-3456-7890-abcd-ef1234567890",
                "text": "This is a sample text for testing JSON serialization performance with medium sized content.",
                "section": "Test Section",
                "index": 0,
                "start_char": 0,
                "end_char": 85
            });
            let serialized = serde_json::to_string(&medium_result).unwrap();
            black_box(serialized);
        })
    });
}

/// Benchmark tool handler method resolution
fn bench_tool_handler_method_resolution(c: &mut Criterion) {
    c.bench_function("docset_tool_handler_method_resolution", |b| {
        b.iter(|| {
            // Test the match statement performance for tool resolution
            let tool_names = [
                "rkmem_docs_get_chunk",
                "rkmem_docs_get_neighbors",
                "rkmem_docs_search",
                "rkmem_docs_ingest",
                "rkmem_docs_list",
                "unknown_tool",
            ];

            for &name in &tool_names {
                match name {
                    "rkmem_docs_get_chunk" => black_box(1),
                    "rkmem_docs_get_neighbors" => black_box(2),
                    "rkmem_docs_search" => black_box(3),
                    "rkmem_docs_ingest" => black_box(4),
                    "rkmem_docs_list" => black_box(5),
                    _ => black_box(0), // Unknown tool
                };
            }
        })
    });
}

/// Benchmark tool definitions count validation
fn bench_tool_definitions_count_validation(c: &mut Criterion) {
    c.bench_function("docset_tool_definitions_count_validation", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let count = tools.len();
            black_box(count == 5); // Should always be 5 tools
        })
    });
}

/// Benchmark schema property access
fn bench_schema_property_access(c: &mut Criterion) {
    let tools = DocsetHandler::tool_definitions();
    let tool = tool_by_name(&tools, "rkmem_docs_search").clone();

    c.bench_function("docset_schema_property_access", move |b| {
        b.iter(|| {
            let schema_obj = tool.input_schema.as_object().unwrap();

            // Access various schema properties
            let properties = schema_obj.get("properties");
            let required = schema_obj.get("required");
            let additional_props = schema_obj.get("additionalProperties");

            black_box(properties);
            black_box(required);
            black_box(additional_props);
        })
    });
}

/// Benchmark tool description access patterns
fn bench_tool_description_access(c: &mut Criterion) {
    c.bench_function("docset_tool_description_access", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let mut total_length = 0;

            for tool in tools {
                if let Some(description) = tool.description {
                    total_length += description.len();
                }
            }

            black_box(total_length);
        })
    });
}

/// Benchmark argument extraction error cases
fn bench_argument_extraction_error_cases(c: &mut Criterion) {
    c.bench_function("docset_argument_extraction_missing_key", |b| {
        let args = HashMap::new(); // Empty map
        b.iter(|| {
            let result = get_string_arg(&args, "nonexistent_key");
            black_box(result.is_none());
        })
    });

    c.bench_function("docset_argument_extraction_wrong_type", |b| {
        let mut args = HashMap::new();
        args.insert("key".to_string(), json!(123)); // Not a string
        b.iter(|| {
            let result = get_string_arg(&args, "key");
            black_box(result.is_none());
        })
    });
}

/// Benchmark tool name iteration
fn bench_tool_name_iteration(c: &mut Criterion) {
    c.bench_function("docset_tool_name_iteration", |b| {
        b.iter(|| {
            let tools = DocsetHandler::tool_definitions();
            let mut names = Vec::new();

            for tool in tools {
                names.push(tool.name);
            }

            black_box(names);
        })
    });
}

criterion_group!(
    benches,
    bench_tool_definitions_creation,
    bench_argument_extraction,
    bench_tool_name_validation,
    bench_json_schema_validation,
    bench_tool_definitions_access,
    bench_individual_tool_creation,
    bench_handler_creation,
    bench_tool_calling_error_case,
    bench_argument_extraction_various_sizes,
    bench_schema_validation_all_tools,
    bench_tool_name_lookup,
    bench_tool_definitions_memory_allocation,
    bench_concurrent_tool_access,
    bench_error_message_generation,
    bench_json_serialization_performance,
    bench_tool_handler_method_resolution,
    bench_tool_definitions_count_validation,
    bench_schema_property_access,
    bench_tool_description_access,
    bench_argument_extraction_error_cases,
    bench_tool_name_iteration
);

criterion_main!(benches);