@ebowwa/large-output 1.0.3 → 1.2.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 +167 -0
- package/dist/index.d.ts +18 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -20
- package/package.json +22 -4
- package/rust/Cargo.lock +690 -0
- package/rust/Cargo.toml +29 -0
- package/rust/README.md +185 -0
- package/rust/src/lib.rs +596 -0
package/rust/Cargo.toml
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "large-output"
|
|
3
|
+
version = "1.2.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
authors = ["ebowwa"]
|
|
6
|
+
description = "Utility for handling large outputs with automatic file fallback and actionable LLM prompts"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
keywords = ["mcp", "output", "pagination", "file-fallback", "llm"]
|
|
9
|
+
categories = ["filesystem", "text-processing"]
|
|
10
|
+
repository = "https://github.com/ebowwa/codespaces"
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
|
|
13
|
+
[dependencies]
|
|
14
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
15
|
+
serde_json = "1.0"
|
|
16
|
+
chrono = "0.4"
|
|
17
|
+
uuid = { version = "1.0", features = ["v4"] }
|
|
18
|
+
|
|
19
|
+
[dev-dependencies]
|
|
20
|
+
tempfile = "3.10"
|
|
21
|
+
|
|
22
|
+
[features]
|
|
23
|
+
default = []
|
|
24
|
+
async = ["tokio", "tokio/fs"]
|
|
25
|
+
|
|
26
|
+
[dependencies.tokio]
|
|
27
|
+
version = "1.0"
|
|
28
|
+
features = ["fs", "io-util"]
|
|
29
|
+
optional = true
|
package/rust/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# large-output (Rust)
|
|
2
|
+
|
|
3
|
+
Shared utility for handling large outputs with automatic file fallback and **actionable LLM prompts**.
|
|
4
|
+
|
|
5
|
+
Rust port of [`@ebowwa/large-output`](../large-output/).
|
|
6
|
+
|
|
7
|
+
## Problem Solved
|
|
8
|
+
|
|
9
|
+
When tools return large outputs, they typically hit character limits. Common solutions like pagination fragment the context and require multiple round-trips.
|
|
10
|
+
|
|
11
|
+
**This library solves it by:**
|
|
12
|
+
- Returning content inline if under the threshold
|
|
13
|
+
- Automatically writing to a temp file if over the threshold
|
|
14
|
+
- **Returning actionable text that prompts the LLM to read the file**
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Add to your `Cargo.toml`:
|
|
19
|
+
|
|
20
|
+
```toml
|
|
21
|
+
[dependencies]
|
|
22
|
+
large-output = "1.1.0"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or use cargo:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cargo add large-output
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```rust
|
|
34
|
+
use large_output::{handle_output, handle_mcp_output, OutputResponse};
|
|
35
|
+
|
|
36
|
+
// Basic usage
|
|
37
|
+
let content = "very large content...".repeat(1000);
|
|
38
|
+
let response = handle_output(&content, None);
|
|
39
|
+
|
|
40
|
+
match response {
|
|
41
|
+
OutputResponse::Inline { content, .. } => println!("{}", content),
|
|
42
|
+
OutputResponse::File { path, size, .. } => {
|
|
43
|
+
println!("Written {} bytes to {:?}", size, path);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// MCP convenience function (returns actionable text by default)
|
|
48
|
+
let mcp_text = handle_mcp_output(&content, None);
|
|
49
|
+
println!("{}", mcp_text);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## API
|
|
53
|
+
|
|
54
|
+
### `handle_output(content, options) -> OutputResponse`
|
|
55
|
+
|
|
56
|
+
Handle output with automatic file fallback.
|
|
57
|
+
|
|
58
|
+
```rust
|
|
59
|
+
use large_output::{handle_output, OutputResponse, OptionsBuilder};
|
|
60
|
+
|
|
61
|
+
let options = OptionsBuilder::new()
|
|
62
|
+
.threshold(20000)
|
|
63
|
+
.preview_length(1000)
|
|
64
|
+
.filename_prefix("my_tool")
|
|
65
|
+
.build();
|
|
66
|
+
|
|
67
|
+
let response = handle_output("content", Some(options));
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### `handle_mcp_output(content, options) -> String`
|
|
71
|
+
|
|
72
|
+
Convenience function that handles output and returns MCP-formatted string.
|
|
73
|
+
|
|
74
|
+
```rust
|
|
75
|
+
use large_output::handle_mcp_output;
|
|
76
|
+
|
|
77
|
+
// Default: actionable format
|
|
78
|
+
let text = handle_mcp_output(&large_content, None);
|
|
79
|
+
|
|
80
|
+
// JSON format for programmatic consumers
|
|
81
|
+
use large_output::{OptionsBuilder, ResponseFormat};
|
|
82
|
+
let options = OptionsBuilder::new()
|
|
83
|
+
.response_format(ResponseFormat::Json)
|
|
84
|
+
.build();
|
|
85
|
+
let json = handle_mcp_output(&large_content, Some(options));
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `to_mcp_response(response, format) -> String`
|
|
89
|
+
|
|
90
|
+
Convert an OutputResponse to a string for MCP tool return.
|
|
91
|
+
|
|
92
|
+
```rust
|
|
93
|
+
use large_output::{handle_output, to_mcp_response, ResponseFormat};
|
|
94
|
+
|
|
95
|
+
let response = handle_output(&content, None);
|
|
96
|
+
let text = to_mcp_response(&response, ResponseFormat::Actionable);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### `handle_batch(contents, options) -> Vec<OutputResponse>`
|
|
100
|
+
|
|
101
|
+
Batch handler for multiple outputs.
|
|
102
|
+
|
|
103
|
+
```rust
|
|
104
|
+
use large_output::handle_batch;
|
|
105
|
+
|
|
106
|
+
let contents = vec!["data1", "data2", "data3"];
|
|
107
|
+
let outputs = handle_batch(&contents.iter().map(|s| *s).collect::<Vec<_>>(), None);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Options
|
|
111
|
+
|
|
112
|
+
| Option | Type | Default | Description |
|
|
113
|
+
|--------|------|---------|-------------|
|
|
114
|
+
| `threshold` | `usize` | `15000` | Character threshold for file fallback |
|
|
115
|
+
| `preview_length` | `usize` | `500` | Preview chars when written to file |
|
|
116
|
+
| `temp_dir` | `Option<PathBuf>` | `None` (OS temp) | Custom temp directory |
|
|
117
|
+
| `filename_prefix` | `String` | `"mcp_output"` | Filename prefix |
|
|
118
|
+
| `include_size` | `bool` | `true` | Include size in file response |
|
|
119
|
+
| `include_preview` | `bool` | `true` | Include preview in file response |
|
|
120
|
+
| `response_format` | `ResponseFormat` | `Actionable` | Response format for file outputs |
|
|
121
|
+
|
|
122
|
+
### Using OptionsBuilder
|
|
123
|
+
|
|
124
|
+
```rust
|
|
125
|
+
use large_output::{OptionsBuilder, ResponseFormat};
|
|
126
|
+
|
|
127
|
+
let options = OptionsBuilder::new()
|
|
128
|
+
.threshold(20000)
|
|
129
|
+
.preview_length(1000)
|
|
130
|
+
.filename_prefix("github_search")
|
|
131
|
+
.response_format(ResponseFormat::Json)
|
|
132
|
+
.build();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Response Formats
|
|
136
|
+
|
|
137
|
+
### Inline (under threshold)
|
|
138
|
+
|
|
139
|
+
Content returned directly.
|
|
140
|
+
|
|
141
|
+
### File - Actionable format (default)
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
Large output (126.5 KB) saved to file.
|
|
145
|
+
|
|
146
|
+
ACTION REQUIRED: Use the Read tool to read this file:
|
|
147
|
+
|
|
148
|
+
/tmp/mcp_output_2025-02-19T12-38-00_abc123.txt
|
|
149
|
+
|
|
150
|
+
--- PREVIEW (first 500 chars) ---
|
|
151
|
+
{...preview...}
|
|
152
|
+
--- END PREVIEW ---
|
|
153
|
+
|
|
154
|
+
File contains the complete data. Read it to proceed.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### File - JSON format (for programmatic consumers)
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"type": "file",
|
|
162
|
+
"path": "/tmp/mcp_output_2025-02-19T12-38-00_abc123.txt",
|
|
163
|
+
"size": 126507,
|
|
164
|
+
"sizeFormatted": "126.5 KB",
|
|
165
|
+
"preview": "..."
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Feature Flags
|
|
170
|
+
|
|
171
|
+
- `default` - Synchronous file operations
|
|
172
|
+
- `async` - Async file operations with tokio (requires `tokio` feature)
|
|
173
|
+
|
|
174
|
+
### Async Usage
|
|
175
|
+
|
|
176
|
+
Enable the `async` feature:
|
|
177
|
+
|
|
178
|
+
```toml
|
|
179
|
+
[dependencies]
|
|
180
|
+
large-output = { version = "1.1.0", features = ["async"] }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|