fast-agent-mcp 0.3.13__py3-none-any.whl → 0.3.15__py3-none-any.whl

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.

Potentially problematic release.


This version of fast-agent-mcp might be problematic. Click here for more details.

Files changed (44) hide show
  1. fast_agent/agents/llm_agent.py +59 -37
  2. fast_agent/agents/llm_decorator.py +13 -2
  3. fast_agent/agents/mcp_agent.py +21 -5
  4. fast_agent/agents/tool_agent.py +41 -29
  5. fast_agent/agents/workflow/router_agent.py +2 -1
  6. fast_agent/cli/commands/check_config.py +48 -1
  7. fast_agent/config.py +65 -2
  8. fast_agent/constants.py +3 -0
  9. fast_agent/context.py +42 -9
  10. fast_agent/core/fastagent.py +14 -1
  11. fast_agent/core/logging/listeners.py +1 -1
  12. fast_agent/core/validation.py +31 -33
  13. fast_agent/event_progress.py +2 -3
  14. fast_agent/human_input/form_fields.py +4 -1
  15. fast_agent/interfaces.py +12 -2
  16. fast_agent/llm/fastagent_llm.py +31 -0
  17. fast_agent/llm/model_database.py +2 -2
  18. fast_agent/llm/model_factory.py +8 -1
  19. fast_agent/llm/provider_key_manager.py +1 -0
  20. fast_agent/llm/provider_types.py +1 -0
  21. fast_agent/llm/request_params.py +3 -1
  22. fast_agent/mcp/mcp_aggregator.py +313 -40
  23. fast_agent/mcp/mcp_connection_manager.py +39 -9
  24. fast_agent/mcp/prompt_message_extended.py +2 -2
  25. fast_agent/mcp/skybridge.py +45 -0
  26. fast_agent/mcp/sse_tracking.py +287 -0
  27. fast_agent/mcp/transport_tracking.py +37 -3
  28. fast_agent/mcp/types.py +24 -0
  29. fast_agent/resources/examples/workflows/router.py +1 -0
  30. fast_agent/resources/setup/fastagent.config.yaml +7 -1
  31. fast_agent/ui/console_display.py +946 -84
  32. fast_agent/ui/elicitation_form.py +23 -1
  33. fast_agent/ui/enhanced_prompt.py +153 -58
  34. fast_agent/ui/interactive_prompt.py +57 -34
  35. fast_agent/ui/markdown_truncator.py +942 -0
  36. fast_agent/ui/mcp_display.py +110 -29
  37. fast_agent/ui/plain_text_truncator.py +68 -0
  38. fast_agent/ui/rich_progress.py +4 -1
  39. fast_agent/ui/streaming_buffer.py +449 -0
  40. {fast_agent_mcp-0.3.13.dist-info → fast_agent_mcp-0.3.15.dist-info}/METADATA +4 -3
  41. {fast_agent_mcp-0.3.13.dist-info → fast_agent_mcp-0.3.15.dist-info}/RECORD +44 -38
  42. {fast_agent_mcp-0.3.13.dist-info → fast_agent_mcp-0.3.15.dist-info}/WHEEL +0 -0
  43. {fast_agent_mcp-0.3.13.dist-info → fast_agent_mcp-0.3.15.dist-info}/entry_points.txt +0 -0
  44. {fast_agent_mcp-0.3.13.dist-info → fast_agent_mcp-0.3.15.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,449 @@
1
+ """Streaming buffer for markdown content with intelligent truncation.
2
+
3
+ This module provides a simple, robust streaming buffer that:
4
+ 1. Accumulates streaming chunks from LLM responses
5
+ 2. Truncates to fit terminal height (keeps most recent content)
6
+ 3. Preserves markdown context when truncating:
7
+ - Code blocks: retains opening ```language fence
8
+ - Tables: retains header + separator rows
9
+ - Code blocks: adds closing ``` if unclosed
10
+
11
+ Design Philosophy
12
+ =================
13
+ KISS (Keep It Simple, Stupid):
14
+ - No binary search (streaming is linear)
15
+ - No dual modes (streaming always keeps recent content)
16
+ - Parse once per truncation (not per chunk)
17
+ - Position-based tracking (clear, testable)
18
+ """
19
+
20
+ from dataclasses import dataclass
21
+ from math import ceil
22
+ from typing import List, Optional
23
+
24
+ from markdown_it import MarkdownIt
25
+ from markdown_it.token import Token
26
+
27
+
28
+ @dataclass
29
+ class CodeBlock:
30
+ """Position and metadata for a code block."""
31
+
32
+ start_pos: int # Character position where block starts
33
+ end_pos: int # Character position where block ends
34
+ language: str # Language identifier (e.g., "python")
35
+
36
+
37
+ @dataclass
38
+ class Table:
39
+ """Position and metadata for a table."""
40
+
41
+ start_pos: int # Character position where table starts
42
+ end_pos: int # Character position where table ends
43
+ header_lines: List[str] # Header row + separator (e.g., ["| A | B |", "|---|---|"])
44
+
45
+
46
+ class StreamBuffer:
47
+ """Buffer for streaming markdown content with smart truncation.
48
+
49
+ Usage:
50
+ buffer = StreamBuffer()
51
+ for chunk in stream:
52
+ buffer.append(chunk)
53
+ display_text = buffer.get_display_text(terminal_height)
54
+ render(display_text)
55
+ """
56
+
57
+ def __init__(self):
58
+ """Initialize the stream buffer."""
59
+ self._chunks: List[str] = []
60
+ self._parser = MarkdownIt().enable("table")
61
+
62
+ def append(self, chunk: str) -> None:
63
+ """Add a chunk to the buffer.
64
+
65
+ Args:
66
+ chunk: Text chunk from streaming response
67
+ """
68
+ if chunk:
69
+ self._chunks.append(chunk)
70
+
71
+ def get_full_text(self) -> str:
72
+ """Get the complete buffered text.
73
+
74
+ Returns:
75
+ Full concatenated text from all chunks
76
+ """
77
+ return "".join(self._chunks)
78
+
79
+ def get_display_text(
80
+ self,
81
+ terminal_height: int,
82
+ target_ratio: float = 0.7,
83
+ terminal_width: Optional[int] = None,
84
+ ) -> str:
85
+ """Get text for display, truncated to fit terminal.
86
+
87
+ This applies intelligent truncation when content exceeds terminal height:
88
+ 1. Keeps most recent content (last N lines)
89
+ 2. Preserves code block fences if truncated mid-block
90
+ 3. Preserves table headers if truncated in table data
91
+ 4. Adds closing fence if code block is unclosed
92
+
93
+ Args:
94
+ terminal_height: Height of terminal in lines
95
+ target_ratio: Keep this multiple of terminal height (default 1.5)
96
+ terminal_width: Optional terminal width for estimating wrapped lines
97
+
98
+ Returns:
99
+ Text ready for display (truncated if needed)
100
+ """
101
+ full_text = self.get_full_text()
102
+ if not full_text:
103
+ return full_text
104
+ return self._truncate_for_display(
105
+ full_text, terminal_height, target_ratio, terminal_width
106
+ )
107
+
108
+ def clear(self) -> None:
109
+ """Clear the buffer."""
110
+ self._chunks.clear()
111
+
112
+ def _truncate_for_display(
113
+ self,
114
+ text: str,
115
+ terminal_height: int,
116
+ target_ratio: float,
117
+ terminal_width: Optional[int],
118
+ ) -> str:
119
+ """Truncate text to fit display with context preservation.
120
+
121
+ Algorithm:
122
+ 1. If text fits, return as-is
123
+ 2. Otherwise, keep last N lines (where N = terminal_height * target_ratio)
124
+ 3. Parse markdown to find code blocks and tables
125
+ 4. If we truncated mid-code-block, prepend opening fence
126
+ 5. If we truncated mid-table-data, prepend table header
127
+ 6. If code block is unclosed, append closing fence
128
+
129
+ Args:
130
+ text: Full markdown text
131
+ terminal_height: Terminal height in lines
132
+ target_ratio: Multiplier for target line count
133
+
134
+ Returns:
135
+ Truncated text with preserved context
136
+ """
137
+ lines = text.split("\n")
138
+
139
+ if target_ratio <= 1:
140
+ extra_lines = 0
141
+ else:
142
+ extra_lines = int(ceil(terminal_height * (target_ratio - 1)))
143
+ raw_target_lines = terminal_height + extra_lines
144
+
145
+ # Estimate how many rendered lines the text will occupy
146
+ if terminal_width and terminal_width > 0:
147
+ # Treat each logical line as taking at least one row, expanding based on width
148
+ display_counts = self._estimate_display_counts(lines, terminal_width)
149
+ total_display_lines = sum(display_counts)
150
+ else:
151
+ display_counts = None
152
+ total_display_lines = len(lines)
153
+
154
+ # Fast path: no truncation needed if content still fits the viewport
155
+ if total_display_lines <= terminal_height:
156
+ # Still need to check for unclosed code blocks
157
+ return self._add_closing_fence_if_needed(text)
158
+
159
+ # Determine how many display lines we want to keep after truncation
160
+ desired_display_lines = min(total_display_lines, raw_target_lines)
161
+ if desired_display_lines > terminal_height:
162
+ window_lines = max(1, terminal_height // 5) # keep ~20% headroom
163
+ desired_display_lines = max(terminal_height, desired_display_lines - window_lines)
164
+ else:
165
+ desired_display_lines = terminal_height
166
+
167
+ # Determine how many logical lines we can keep based on estimated display rows
168
+ if display_counts:
169
+ running_total = 0
170
+ start_index = len(lines) - 1
171
+ for idx in range(len(lines) - 1, -1, -1):
172
+ running_total += display_counts[idx]
173
+ start_index = idx
174
+ if running_total >= desired_display_lines:
175
+ break
176
+ else:
177
+ start_index = max(len(lines) - desired_display_lines, 0)
178
+
179
+ # Compute character position where truncation occurs
180
+ truncation_pos = sum(len(line) + 1 for line in lines[:start_index])
181
+ truncated_text = text[truncation_pos:]
182
+
183
+ if terminal_width and terminal_width > 0:
184
+ truncated_text, truncation_pos = self._trim_within_line_if_needed(
185
+ text=text,
186
+ truncated_text=truncated_text,
187
+ truncation_pos=truncation_pos,
188
+ terminal_width=terminal_width,
189
+ max_display_lines=desired_display_lines,
190
+ )
191
+
192
+ # Parse markdown structures once
193
+ code_blocks = self._find_code_blocks(text)
194
+ tables = self._find_tables(text)
195
+
196
+ # Preserve code block context if needed
197
+ truncated_text = self._preserve_code_block_context(
198
+ text, truncated_text, truncation_pos, code_blocks
199
+ )
200
+
201
+ # Preserve table context if needed
202
+ truncated_text = self._preserve_table_context(
203
+ text, truncated_text, truncation_pos, tables
204
+ )
205
+
206
+ # Add closing fence if code block is unclosed
207
+ truncated_text = self._add_closing_fence_if_needed(truncated_text)
208
+
209
+ return truncated_text
210
+
211
+ def _find_code_blocks(self, text: str) -> List[CodeBlock]:
212
+ """Find all code blocks in text using markdown-it parser.
213
+
214
+ Args:
215
+ text: Markdown text to analyze
216
+
217
+ Returns:
218
+ List of CodeBlock objects with position information
219
+ """
220
+ tokens = self._parser.parse(text)
221
+ lines = text.split("\n")
222
+ blocks = []
223
+
224
+ for token in self._flatten_tokens(tokens):
225
+ if token.type in ("fence", "code_block") and token.map:
226
+ start_line = token.map[0]
227
+ end_line = token.map[1]
228
+ start_pos = sum(len(line) + 1 for line in lines[:start_line])
229
+ end_pos = sum(len(line) + 1 for line in lines[:end_line])
230
+ language = getattr(token, "info", "") or ""
231
+
232
+ blocks.append(
233
+ CodeBlock(start_pos=start_pos, end_pos=end_pos, language=language)
234
+ )
235
+
236
+ return blocks
237
+
238
+ def _find_tables(self, text: str) -> List[Table]:
239
+ """Find all tables in text using markdown-it parser.
240
+
241
+ Args:
242
+ text: Markdown text to analyze
243
+
244
+ Returns:
245
+ List of Table objects with position and header information
246
+ """
247
+ tokens = self._parser.parse(text)
248
+ lines = text.split("\n")
249
+ tables = []
250
+
251
+ for i, token in enumerate(tokens):
252
+ if token.type == "table_open" and token.map:
253
+ # Find tbody within this table to extract header
254
+ tbody_start_line = None
255
+
256
+ # Look ahead for tbody
257
+ for j in range(i + 1, len(tokens)):
258
+ if tokens[j].type == "tbody_open" and tokens[j].map:
259
+ tbody_start_line = tokens[j].map[0]
260
+ break
261
+ elif tokens[j].type == "table_close":
262
+ break
263
+
264
+ if tbody_start_line is not None:
265
+ table_start_line = token.map[0]
266
+ table_end_line = token.map[1]
267
+
268
+ # Calculate positions
269
+ start_pos = sum(len(line) + 1 for line in lines[:table_start_line])
270
+ end_pos = sum(len(line) + 1 for line in lines[:table_end_line])
271
+
272
+ # Header lines = everything before tbody (header row + separator)
273
+ header_lines = lines[table_start_line:tbody_start_line]
274
+
275
+ tables.append(
276
+ Table(start_pos=start_pos, end_pos=end_pos, header_lines=header_lines)
277
+ )
278
+
279
+ return tables
280
+
281
+ def _preserve_code_block_context(
282
+ self, original_text: str, truncated_text: str, truncation_pos: int, code_blocks: List[CodeBlock]
283
+ ) -> str:
284
+ """Prepend code block opening fence if truncation removed it.
285
+
286
+ When we truncate mid-code-block, we need to preserve the opening fence
287
+ so the remaining code still renders with syntax highlighting.
288
+
289
+ Args:
290
+ original_text: Full original text
291
+ truncated_text: Text after truncation
292
+ truncation_pos: Character position where truncation happened
293
+ code_blocks: List of code blocks in original text
294
+
295
+ Returns:
296
+ Truncated text with fence prepended if needed
297
+ """
298
+ for block in code_blocks:
299
+ # Check if we truncated within this code block
300
+ if block.start_pos < truncation_pos < block.end_pos:
301
+ # We're inside this block - did we remove the opening fence?
302
+ if truncation_pos > block.start_pos:
303
+ fence = f"```{block.language}\n"
304
+ # Avoid duplicates
305
+ if not truncated_text.startswith(fence):
306
+ return fence + truncated_text
307
+ # Found the relevant block, no need to check others
308
+ break
309
+
310
+ return truncated_text
311
+
312
+ def _preserve_table_context(
313
+ self, original_text: str, truncated_text: str, truncation_pos: int, tables: List[Table]
314
+ ) -> str:
315
+ """Prepend table header if truncation removed it.
316
+
317
+ When we truncate table data rows, we need to preserve the header
318
+ (header row + separator) so the remaining rows have context.
319
+
320
+ Design Point #4: Keep the 3 lines marking beginning of table:
321
+ - Newline before table (if present)
322
+ - Header row (e.g., "| Name | Size |")
323
+ - Separator (e.g., "|------|------|")
324
+
325
+ Args:
326
+ original_text: Full original text
327
+ truncated_text: Text after truncation
328
+ truncation_pos: Character position where truncation happened
329
+ tables: List of tables in original text
330
+
331
+ Returns:
332
+ Truncated text with header prepended if needed
333
+ """
334
+ for table in tables:
335
+ # Check if we truncated within this table
336
+ if table.start_pos < truncation_pos < table.end_pos:
337
+ # Check if we removed the header (header is at start of table)
338
+ # If truncation happened after the header, we need to restore it
339
+ lines = original_text.split("\n")
340
+ table_start_line = sum(
341
+ 1 for line in original_text[:table.start_pos].split("\n")
342
+ ) - 1
343
+
344
+ # Find where the data rows start (after separator)
345
+ # Header lines include header row + separator
346
+ data_start_line = table_start_line + len(table.header_lines)
347
+ data_start_pos = sum(len(line) + 1 for line in lines[:data_start_line])
348
+
349
+ # If we truncated in the data section, restore header
350
+ if truncation_pos >= data_start_pos:
351
+ header_text = "\n".join(table.header_lines) + "\n"
352
+ return header_text + truncated_text
353
+
354
+ # Found the relevant table, no need to check others
355
+ break
356
+
357
+ return truncated_text
358
+
359
+ def _add_closing_fence_if_needed(self, text: str) -> str:
360
+ """Add closing ``` fence if code block is unclosed.
361
+
362
+ Design Point #5: Add closing fence to bottom if we detect unclosed block.
363
+ This ensures partial code blocks render correctly during streaming.
364
+
365
+ Args:
366
+ text: Markdown text to check
367
+
368
+ Returns:
369
+ Text with closing fence added if needed
370
+ """
371
+ # Count opening vs closing fences
372
+ import re
373
+
374
+ opening_fences = len(re.findall(r"^```", text, re.MULTILINE))
375
+ closing_fences = len(re.findall(r"^```\s*$", text, re.MULTILINE))
376
+
377
+ # If odd number of fences, we have an unclosed block
378
+ if opening_fences > closing_fences:
379
+ # Check if text already ends with a closing fence
380
+ if not re.search(r"```\s*$", text):
381
+ return text + "\n```\n"
382
+
383
+ return text
384
+
385
+ def _flatten_tokens(self, tokens: List[Token]) -> List[Token]:
386
+ """Flatten nested token tree.
387
+
388
+ Args:
389
+ tokens: List of tokens from markdown-it
390
+
391
+ Yields:
392
+ Flattened tokens
393
+ """
394
+ for token in tokens:
395
+ is_fence = token.type == "fence"
396
+ is_image = token.tag == "img"
397
+ if token.children and not (is_image or is_fence):
398
+ yield from self._flatten_tokens(token.children)
399
+ else:
400
+ yield token
401
+
402
+ def _estimate_display_counts(self, lines: List[str], terminal_width: int) -> List[int]:
403
+ """Estimate how many terminal rows each logical line will occupy."""
404
+ return [
405
+ max(1, ceil(len(line) / terminal_width)) if line else 1
406
+ for line in lines
407
+ ]
408
+
409
+ def _estimate_display_lines(self, text: str, terminal_width: int) -> int:
410
+ """Estimate how many terminal rows the given text will occupy."""
411
+ if not text:
412
+ return 0
413
+ lines = text.split("\n")
414
+ return sum(self._estimate_display_counts(lines, terminal_width))
415
+
416
+ def _trim_within_line_if_needed(
417
+ self,
418
+ text: str,
419
+ truncated_text: str,
420
+ truncation_pos: int,
421
+ terminal_width: int,
422
+ max_display_lines: int,
423
+ ) -> tuple[str, int]:
424
+ """Trim additional characters when a single line exceeds the viewport."""
425
+ current_pos = truncation_pos
426
+ current_text = truncated_text
427
+ estimated_lines = self._estimate_display_lines(current_text, terminal_width)
428
+
429
+ while estimated_lines > max_display_lines and current_pos < len(text):
430
+ excess_display = estimated_lines - max_display_lines
431
+ chars_to_trim = excess_display * terminal_width
432
+ if chars_to_trim <= 0:
433
+ break
434
+
435
+ candidate_pos = min(len(text), current_pos + chars_to_trim)
436
+
437
+ # Prefer trimming at the next newline to keep markdown structures intact
438
+ newline_pos = text.find("\n", current_pos, candidate_pos)
439
+ if newline_pos != -1:
440
+ candidate_pos = newline_pos + 1
441
+
442
+ if candidate_pos <= current_pos:
443
+ break
444
+
445
+ current_pos = candidate_pos
446
+ current_text = text[current_pos:]
447
+ estimated_lines = self._estimate_display_lines(current_text, terminal_width)
448
+
449
+ return current_text, current_pos
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.3.13
3
+ Version: 0.3.15
4
4
  Summary: Define, Prompt and Test MCP enabled Agents and Workflows
5
5
  Author-email: Shaun Smith <fastagent@llmindset.co.uk>
6
6
  License: Apache License
@@ -219,8 +219,8 @@ Requires-Dist: email-validator>=2.2.0
219
219
  Requires-Dist: fastapi>=0.115.6
220
220
  Requires-Dist: google-genai>=1.33.0
221
221
  Requires-Dist: keyring>=24.3.1
222
- Requires-Dist: mcp==1.16.0
223
- Requires-Dist: openai>=2.1.0
222
+ Requires-Dist: mcp==1.18.0
223
+ Requires-Dist: openai>=2.3.0
224
224
  Requires-Dist: opentelemetry-distro>=0.55b0
225
225
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.7.0
226
226
  Requires-Dist: opentelemetry-instrumentation-anthropic>=0.43.1; python_version >= '3.10' and python_version < '4.0'
@@ -234,6 +234,7 @@ Requires-Dist: pyperclip>=1.9.0
234
234
  Requires-Dist: pyyaml>=6.0.2
235
235
  Requires-Dist: rich>=14.1.0
236
236
  Requires-Dist: tensorzero>=2025.7.5
237
+ Requires-Dist: textual>=6.2.1
237
238
  Requires-Dist: typer>=0.15.1
238
239
  Description-Content-Type: text/markdown
239
240
 
@@ -1,32 +1,32 @@
1
1
  fast_agent/__init__.py,sha256=ns6CPmjOL5y7cyV4XgFTfMGcfLnuBJwVTbcjJ5Co3x4,4152
2
- fast_agent/config.py,sha256=tKnAhGAADpuwU7DggScG0VESs7el4R1Y1T3MUPzD5_U,22509
3
- fast_agent/constants.py,sha256=IoXL5m4L0iLlcRrKerMaK3ZPcS6KCJgK8b_bj1BAR60,345
4
- fast_agent/context.py,sha256=nBelOqehSH91z3aG2nYhwETP-biRzz-iuA2fqmKdHP8,7700
2
+ fast_agent/config.py,sha256=6V2ndiN9tccEWGmaYR3oYbqvLrHI555i7Yme8rCK21c,24796
3
+ fast_agent/constants.py,sha256=GQZw66l9_X58T1fwSnOQZbPnj3ydJxWdwzvLo0RnGYU,520
4
+ fast_agent/context.py,sha256=kHCWvj6Smo2WwfcKHF4bFdnqD7H2HdCmiTWePos-4NM,8890
5
5
  fast_agent/context_dependent.py,sha256=KU1eydVBoIt4bYOZroqxDgE1AUexDaZi7hurE26QsF4,1584
6
- fast_agent/event_progress.py,sha256=OETeh-4jJGyxvvPAlVTzW4JsCbFUmOTo-ti0ROgtG5M,1999
7
- fast_agent/interfaces.py,sha256=XktRxJjLfCMPbC5ReV23dP-dRy0gDNtYfMCvSp0QD0I,6373
6
+ fast_agent/event_progress.py,sha256=iTGlD-tAG3n_mLnUr7h03nPMSZK8piyLeaA-IB9erBw,2064
7
+ fast_agent/interfaces.py,sha256=JjgcvT8WQk4UW42Eh6TVDW5Vq11pitSVZ6nKt8BiXBE,6689
8
8
  fast_agent/mcp_server_registry.py,sha256=TDCNpQIehsh1PK4y7AWp_rkQMcwYx7FaouUbK3kWNZo,2635
9
9
  fast_agent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  fast_agent/agents/__init__.py,sha256=WfgtR9MgmJUJI7rb-CUH_10s7308LjxYIYzJRIBZ_9Y,2644
11
11
  fast_agent/agents/agent_types.py,sha256=xAFEFWIvOtSnTNDcqqfaAnBx_lFLhnS2_b4hm9xKMo8,1719
12
- fast_agent/agents/llm_agent.py,sha256=1lO-DtgeaOoYshHxGKNUIViR_gFJjW6GudEWxRFdVU4,10697
13
- fast_agent/agents/llm_decorator.py,sha256=OezFrnjLwcl3W-1K1sGPtTqD_zVp67wlBUb4SxTesKw,29702
14
- fast_agent/agents/mcp_agent.py,sha256=O9CrjjUrkmbNYsXQevZy2b8EG4B0KdNSH3wtnbe2HI4,39279
15
- fast_agent/agents/tool_agent.py,sha256=bR0V06zCjuPVtOpOQQzym2Mmyt6EsDzAodJmQOEMoFI,8883
12
+ fast_agent/agents/llm_agent.py,sha256=re6pzAbOngjeq_8r9bw2NMRxHWiro31ALfHImiXmUrs,11374
13
+ fast_agent/agents/llm_decorator.py,sha256=aJ3ynv_YMARCOh7Lk9Srf-sWOt3ax1rDkjvNiabW4-A,30135
14
+ fast_agent/agents/mcp_agent.py,sha256=oDkafePCqFJZJ8HfN46As2ILGfezFdbF1UxJLQW79DE,39926
15
+ fast_agent/agents/tool_agent.py,sha256=8IcMeMzxNtgRWv2r6kz5AlRzzvDxFazPYV7krRP1rEA,9321
16
16
  fast_agent/agents/workflow/chain_agent.py,sha256=Pd8dOH_YdKu3LXsKa4fwqzY_B2qVuhzdfCUiKi5v17s,6293
17
17
  fast_agent/agents/workflow/evaluator_optimizer.py,sha256=rhzazy8Aj-ydId6kmBC77TmtYZ5mirSe7eV6PPMWkBA,12040
18
18
  fast_agent/agents/workflow/iterative_planner.py,sha256=CTtDpK-YGrFFZMQQmFeE-2I_9-cZv23pNwUoh8w5voA,20478
19
19
  fast_agent/agents/workflow/orchestrator_models.py,sha256=VNnnVegnjimgiuL8ZhxkBPhg8tjbeJRGq2JAIl0FAbU,7216
20
20
  fast_agent/agents/workflow/orchestrator_prompts.py,sha256=EXKEI174sshkZyPPEnWbwwNafzSPuA39MXL7iqG9cWc,9106
21
21
  fast_agent/agents/workflow/parallel_agent.py,sha256=DlJXDURAfx-WBF297tKBLfH93gDFSAPUyEmJr7QNGyw,7476
22
- fast_agent/agents/workflow/router_agent.py,sha256=4jL7AM9FcOvsuf0BSWs-r17xa9vMml0BuF89PiFeVQs,11345
22
+ fast_agent/agents/workflow/router_agent.py,sha256=gugcp0a-3Ldn42JbPJZ7AbO2G6FvqE0A3tsWcLorwSY,11400
23
23
  fast_agent/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  fast_agent/cli/__main__.py,sha256=iF9mNX1ja9Ea9T6gzNg9nfYAuei_vRowfHpUPiFbJVI,1260
25
25
  fast_agent/cli/constants.py,sha256=flYDsml3_8wVcGg7T1t5mPFT9CC1M-XMjBigXjX6PuI,559
26
26
  fast_agent/cli/main.py,sha256=tERbfQjure3kgKYqzZCNDSLyiVZGXCH2coZ8YBwvq64,4398
27
27
  fast_agent/cli/terminal.py,sha256=tDN1fJ91Nc_wZJTNafkQuD7Z7gFscvo1PHh-t7Wl-5s,1066
28
28
  fast_agent/cli/commands/auth.py,sha256=nJEC7zrz5UXYUz5O6AgGZnfJPHIrgHk68CUwGo-7Nyg,15063
29
- fast_agent/cli/commands/check_config.py,sha256=D0emHGl6yc9XRq-HjAwS4KfS7a9r5gkA55MyiIRptGQ,26638
29
+ fast_agent/cli/commands/check_config.py,sha256=Fz8Agyg3n4PkgFkrpEcIvO0GVTmlHbiPbXhEUNRx1Es,28711
30
30
  fast_agent/cli/commands/go.py,sha256=mZJv1jXO9xqVUzuDCO5iWKI8ubBUACHO6i3lZwu5NFU,15148
31
31
  fast_agent/cli/commands/quickstart.py,sha256=UOTqAbaVGLECHkTvpUNQ41PWXssqCijVvrqh30YUqnM,20624
32
32
  fast_agent/cli/commands/server_helpers.py,sha256=Nuded8sZb4Rybwoq5LbXXUgwtJZg-OO04xhmPUp6e98,4073
@@ -39,9 +39,9 @@ fast_agent/core/direct_decorators.py,sha256=-oGOqgLKJhJJJyn0KBN7iAOjtdg4XrX3JCxj
39
39
  fast_agent/core/direct_factory.py,sha256=SYYVtEqPQh7ElvAVC_445a5pZkKstM0RhKNGZ2CJQT8,18338
40
40
  fast_agent/core/error_handling.py,sha256=tZkO8LnXO-qf6jD8a12Pv5fD4NhnN1Ag5_tJ6DwbXjg,631
41
41
  fast_agent/core/exceptions.py,sha256=ENAD_qGG67foxy6vDkIvc-lgopIUQy6O7zvNPpPXaQg,2289
42
- fast_agent/core/fastagent.py,sha256=ZJYJAgJc-wNmgy2IR3TBc2Gr_Q2dxEoOccbA8kQkPEI,30894
42
+ fast_agent/core/fastagent.py,sha256=Qf84XjVkp-1LhjdyxSZOqyCdcK2XvOIXyj8YI8kLwOI,31442
43
43
  fast_agent/core/prompt.py,sha256=qNUFlK3KtU7leYysYUglzBYQnEYiXu__iR_T8189zc0,203
44
- fast_agent/core/validation.py,sha256=GZ0hUTxkr5KMY1wr6_ifDy91Ycvcx384gZEMOwdie9w,12681
44
+ fast_agent/core/validation.py,sha256=cesQeT8jfLlPqew6S9bq8ZJqde7ViVQXHF9fhAnyOHI,11950
45
45
  fast_agent/core/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  fast_agent/core/executor/executor.py,sha256=egmu1bBJmNjfkMZRdaF2CowyHu0t20TiroKBEGgn2t8,9398
47
47
  fast_agent/core/executor/task_registry.py,sha256=PCALFeYtkQrPBg4RBJnlA0aDI8nHclrNkHGUS4kV3W8,1242
@@ -49,26 +49,26 @@ fast_agent/core/executor/workflow_signal.py,sha256=Cg1uZBk3fn8kXhPOg-wINNuVaf3v9
49
49
  fast_agent/core/logging/__init__.py,sha256=dFW2bbTtz45zebUuQs7RVi7mg1RJm4DHH6TGfBMhW14,167
50
50
  fast_agent/core/logging/events.py,sha256=WTjr26uIxtbxhnoLNPROVUIt0HNJrzK1g1fUMZ-zVsQ,4207
51
51
  fast_agent/core/logging/json_serializer.py,sha256=kQDkwTHIkHSQgbhDOJhMoetNvfJVMZGOScaKoLX8kmw,5797
52
- fast_agent/core/logging/listeners.py,sha256=LVZMf274gN-T-MKNpkmwaE_FbJX2AS0HoHdROrrkmdQ,9400
52
+ fast_agent/core/logging/listeners.py,sha256=U4RpiUTFRUXO9YmujKiBsvVmwNablDtZdLePs6mG34g,9446
53
53
  fast_agent/core/logging/logger.py,sha256=L-hLfUGFCIABoNYDiUkNHWvFxL6j-6zn5Pc5E7aC44M,11074
54
54
  fast_agent/core/logging/transport.py,sha256=i_WYXk5mqyfetT72bCYrbdrMWcuL1HJCyeQKfQg7U2w,16994
55
55
  fast_agent/history/history_exporter.py,sha256=oqkw7qC5rrW73u20tkIqt8yBWPoVzCTC61x2Q2rOKGs,1404
56
56
  fast_agent/human_input/__init__.py,sha256=4Jr_0JLJwdQ3iEUNd6Api9InldtnRMDv_WeZq_WEHpA,935
57
57
  fast_agent/human_input/elicitation_handler.py,sha256=diR8jWRCAuoqTDQHJ3C097EORcLFxpLjdz6EubVOnI8,4776
58
58
  fast_agent/human_input/elicitation_state.py,sha256=L_vSTpw1-TSDumRYa89Me-twWRbUL2w7GNVhVJmn3KE,1152
59
- fast_agent/human_input/form_fields.py,sha256=aE7HdR-wOPO_6HllNaJXtn3BzpPsC4TctUApbveRk8g,7644
59
+ fast_agent/human_input/form_fields.py,sha256=IjStNO8DxyTokLKTmTeZw_pczsvL5ObQPQa49o4k5l4,7770
60
60
  fast_agent/human_input/simple_form.py,sha256=_flUll9z93VPjKqLS7gvz4L1_YJ3-KNx8_ZpUaaxhoQ,3508
61
61
  fast_agent/human_input/types.py,sha256=3Zz89yIt8SuDAVAaRy-r4Vw0-M6AWahwbqQ0yOcoe20,954
62
62
  fast_agent/llm/__init__.py,sha256=MCsrkfnTQXYvn0SofJ-JFmp1l1jX_eidgvegbWbgpsw,184
63
- fast_agent/llm/fastagent_llm.py,sha256=GyvBGAgwd1frWUzSiBANNQdFX-a50ps97WPEX7q2uw8,25119
63
+ fast_agent/llm/fastagent_llm.py,sha256=Y_2RKApjUv5jlF9XcJo6k5bSQIR7Bt7x1tk2tH26aX4,26138
64
64
  fast_agent/llm/memory.py,sha256=POFoBVMHK0wX4oLd3Gz-6Ru3uC4kTCvAqsVQ77e7KJA,8551
65
- fast_agent/llm/model_database.py,sha256=qhC4CX_dKNDTQ3bJA_YCq2wIJK5YP_xlbqNuI1K-a6g,12948
66
- fast_agent/llm/model_factory.py,sha256=y0gmgFzk15UJHZuTbnp5ExYG4DhlX0X1YzzUc1leNVo,13043
65
+ fast_agent/llm/model_database.py,sha256=73SzG22yzUPK3-zB1yjqR3PpZM9k05HUQiK09Fb24v4,13019
66
+ fast_agent/llm/model_factory.py,sha256=pKkWG2OwwxjfL-Hov_UBqcQhw1zd0IIOfTapRDR43FY,13290
67
67
  fast_agent/llm/model_info.py,sha256=DAIMW70W-EFqNLIudhjHJE2gobHUAKg90gkwOPuaFUc,4125
68
68
  fast_agent/llm/prompt_utils.py,sha256=1WU67G-BFqftja5I8FKPMMzsvDk1K_1jDi9A9kkFdOg,4899
69
- fast_agent/llm/provider_key_manager.py,sha256=igzs1ghXsUp0wA4nJVVfWCWiYOib8Ux4jMGlhWbgXu8,3396
70
- fast_agent/llm/provider_types.py,sha256=Ya0MGo_4cE0oCwinqPvr9SJUwx4hEJ7CFbCrLB_27FI,1142
71
- fast_agent/llm/request_params.py,sha256=lQxDmPDpqkbKQPI0WxL8Y4FDweovI6lTbxsHPZ_agq8,1735
69
+ fast_agent/llm/provider_key_manager.py,sha256=O8jhoqzLgMbY57TbJxztNwElbsQPC0GMIwgiaz_5SuQ,3455
70
+ fast_agent/llm/provider_types.py,sha256=JyJoyyCI3htgX9VCvvyz2Lx9fBQtdrLbXma0oc9vfsw,1185
71
+ fast_agent/llm/request_params.py,sha256=HjzGLvEvRMXPMDOxDzbVyb4X_QOt0WErdv1nbCEaZnY,1812
72
72
  fast_agent/llm/sampling_converter.py,sha256=YEUpdVeZlJNDljCuwrXyhsb40o0-1QuWGTuorQnvhbo,3102
73
73
  fast_agent/llm/usage_tracking.py,sha256=6FRIIimIaAoSlYTCGVG00GuavGRIFbOBEBWHvfBxWw0,16791
74
74
  fast_agent/llm/internal/passthrough.py,sha256=0P7qc13_xTV1aMHJmZ2KQEtMtGtu0H7ArkEL6hiy5_M,5209
@@ -104,20 +104,23 @@ fast_agent/mcp/hf_auth.py,sha256=ndDvR7E9LCc5dBiMsStFXtvvX9lYrL-edCq_qJw4lDw,447
104
104
  fast_agent/mcp/interfaces.py,sha256=xCWONGXe4uQSmmBlMZRD3mflPegTJnz2caVNihEl3ok,2411
105
105
  fast_agent/mcp/logger_textio.py,sha256=4YLVXlXghdGm1s_qp1VoAWEX_eWufBfD2iD7l08yoak,3170
106
106
  fast_agent/mcp/mcp_agent_client_session.py,sha256=VTPEjNjPMrxZopeCr7bXjlvr_2MTzdqEjjBOeQri04g,16050
107
- fast_agent/mcp/mcp_aggregator.py,sha256=HzNyKuUelAlp5JBkjMAaOB2JvdMgpm0ItEPGjidI9l0,67198
108
- fast_agent/mcp/mcp_connection_manager.py,sha256=g19Y-gNH6wmMtFcN9awgQ9yRGmqWa1wi9CpaV80pdfk,25367
107
+ fast_agent/mcp/mcp_aggregator.py,sha256=bgqETI-hFtkweW-lcQkA2nvmokiVUv3Z0NohdkhnJwg,77890
108
+ fast_agent/mcp/mcp_connection_manager.py,sha256=57trQyXYCI5MjyiEBSBpyzv4qDyty-MEaqQSAl2_UYA,26515
109
109
  fast_agent/mcp/mcp_content.py,sha256=F9bgJ57EO9sgWg1m-eTNM6xd9js79mHKf4e9O8K8jrI,8829
110
110
  fast_agent/mcp/mime_utils.py,sha256=D6YXNdZJ351BjacSW5o0sVF_hrWuRHD6UyWS4TDlLZI,2915
111
111
  fast_agent/mcp/oauth_client.py,sha256=3shN3iwsJNXrk7nbcfUgrzNos3i2RuMuLXA80nR8r6Y,17104
112
112
  fast_agent/mcp/prompt.py,sha256=U3jAIjGyGqCpS96zKf0idC7PI4YdFHq-3qjpCsEybxQ,5983
113
- fast_agent/mcp/prompt_message_extended.py,sha256=BsiV2SsiZkDlvqzvjeSowq8Ojvowr9XeEfEXAc-hWL8,4721
113
+ fast_agent/mcp/prompt_message_extended.py,sha256=rtX5BuEi_B4xJJnk3zF0Lsna45v6MkOOBPfHsSaNuPM,4747
114
114
  fast_agent/mcp/prompt_render.py,sha256=AqDaQqM6kqciV9X79S5rsRr3VjcQ_2JOiLaHqpRzsS4,2888
115
115
  fast_agent/mcp/prompt_serialization.py,sha256=QMbY0aa_UlJ7bbxl_muOm2TYeYbBVTEeEMHFmEy99ss,20182
116
116
  fast_agent/mcp/resource_utils.py,sha256=cu-l9aOy-NFs8tPihYRNjsB2QSuime8KGOGpUvihp84,6589
117
117
  fast_agent/mcp/sampling.py,sha256=6S9bpGCFGC5azIGE-zxODvKgBbBn1x6amL5mc4sMg_4,7491
118
+ fast_agent/mcp/skybridge.py,sha256=IdaZE3BoXLCxI1Tt9Q3L44t94JBNh1ei4IyUkZDKvCQ,1333
119
+ fast_agent/mcp/sse_tracking.py,sha256=BG4Y84oVE3r8Ggsbda3zEh4yHYPsBzVnl9O_sithMxM,11748
118
120
  fast_agent/mcp/stdio_tracking_simple.py,sha256=T6kCIb6YjwqKtXHz_6HvlLLYiSCbuggt2xCXSihVnIg,1918
119
121
  fast_agent/mcp/streamable_http_tracking.py,sha256=bcNNReokho6WMjWEH13F33bUSkjJ2F5l3qnegkDqdMA,11465
120
- fast_agent/mcp/transport_tracking.py,sha256=tsc2Ntf47KbKXs8DzRkqvG0U-FbpwU2VxemNfRbJBpo,24088
122
+ fast_agent/mcp/transport_tracking.py,sha256=Qm0c-QjlU4DJW3lI8oYR1CCia9gYxOHecKPY8hHFXYU,25617
123
+ fast_agent/mcp/types.py,sha256=BSKto-ArpIt1xiMaISF32xsPNlWVaFkf9rUnl085Q7o,643
121
124
  fast_agent/mcp/ui_agent.py,sha256=OBGEuFpOPPK7EthPRwzxmtzu1SDIeZy-vHwdRsyDNQk,1424
122
125
  fast_agent/mcp/ui_mixin.py,sha256=iOlSNJVPwiMUun0clCiWyot59Qgy8R7ZvUgH2afRnQA,7662
123
126
  fast_agent/mcp/helpers/__init__.py,sha256=o6-HuX6bEVFnfT_wgclFOVb1NxtOsJEOnHX8L2IqDdw,857
@@ -178,12 +181,12 @@ fast_agent/resources/examples/workflows/graded_report.md,sha256=QVF38xEtDIO1a2P-
178
181
  fast_agent/resources/examples/workflows/human_input.py,sha256=gFuptgiU0mMMtv3F1XI7syCSyVV8tyi5qTOn9ziJdWI,792
179
182
  fast_agent/resources/examples/workflows/orchestrator.py,sha256=YWSgH8cDqEuWercgof2aZLbrO0idiSL932ym3lrniNM,2526
180
183
  fast_agent/resources/examples/workflows/parallel.py,sha256=kROiRueTm0Wql4EWVjFSyonV5A4gPepm1jllz5alias,1826
181
- fast_agent/resources/examples/workflows/router.py,sha256=lxMxz6g0_XjYnwzEwKdl9l2hxRsD4PSsaIlhH5nLuQY,2075
184
+ fast_agent/resources/examples/workflows/router.py,sha256=_xVOLzSHY3ZcNfUjvtqVrkiiML5atgGp8Xti7z-U_ZY,2109
182
185
  fast_agent/resources/examples/workflows/short_story.md,sha256=XN9I2kzCcMmke3dE5F2lyRH5iFUZUQ8Sy-hS3rm_Wlc,1153
183
186
  fast_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKvucJtDgAFIJfnlbsbGZO5bBWu0,1187
184
187
  fast_agent/resources/setup/.gitignore,sha256=bksf0bkvBXtm3F5Nd4F9FB2LaO2RcTbHujYWjq5JKPo,305
185
188
  fast_agent/resources/setup/agent.py,sha256=IlZecsc9vTtH2rj9BFF4M6BUgClg5fQ2HasYV1PPIHA,518
186
- fast_agent/resources/setup/fastagent.config.yaml,sha256=4lYdNTUqBwp7DiyeoUDqBDlqfnFi9JTihOTnix3V9M0,1464
189
+ fast_agent/resources/setup/fastagent.config.yaml,sha256=3ch91nWMVWRTsErTAmw7ZFj9PN-0Qq6K-M7M4AVJ8Mo,1791
187
190
  fast_agent/resources/setup/fastagent.secrets.yaml.example,sha256=ht-i2_SpAyeXG2OnG_vOA1n7gRsGIInxp9g5Nio-jpI,1038
188
191
  fast_agent/resources/setup/pyproject.toml.tmpl,sha256=SxyVPXbtD67yFOx9wIrzq6Yxo4W2PkSR1rrnPkmpjwA,478
189
192
  fast_agent/tools/elicitation.py,sha256=8FaNvuN__LAM328VSJ5T4Bg3m8auHraqYvIYv6Eh4KU,13464
@@ -191,21 +194,24 @@ fast_agent/types/__init__.py,sha256=y-53m-C4drf4Rx8Bbnk_GAhko9LdNYCyRUWya8e0mos,
191
194
  fast_agent/types/llm_stop_reason.py,sha256=bWe97OfhALUe8uQeAQOnTdPlYzJiabIfo8u38kPgj3Q,2293
192
195
  fast_agent/ui/__init__.py,sha256=MXxTQjFdF7mI_3JHxBPd-aoZYLlxV_-51-Trqgv5-3w,1104
193
196
  fast_agent/ui/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
194
- fast_agent/ui/console_display.py,sha256=brDhUR-VoQWV3-YWrmvWS1q9zYFL3eJkO1Uxs_1AwA4,44017
195
- fast_agent/ui/elicitation_form.py,sha256=t3UhBG44YmxTLu1RjCnHwW36eQQaroE45CiBGJB2czg,29410
197
+ fast_agent/ui/console_display.py,sha256=Z-mgzNhBNfXDjL28m-0TZtSlYVjdLEuIyVUHHblu6Nw,77393
198
+ fast_agent/ui/elicitation_form.py,sha256=2_KuApui8LQVqz-S__0QUBtr2MB13VgR577KUeQrOpk,30307
196
199
  fast_agent/ui/elicitation_style.py,sha256=-WqXgVjVs65oNwhCDw3E0A9cCyw95IOe6LYCJgjT6ok,3939
197
- fast_agent/ui/enhanced_prompt.py,sha256=TPJmC1zKQaiqDbtlI0WcxUoH5uw1sY23uJ8uEeYiMCY,45018
200
+ fast_agent/ui/enhanced_prompt.py,sha256=GrvQ5AZU-Wvrj71CSWlwWndf0stfZP5d45A5VFYJBAM,49343
198
201
  fast_agent/ui/history_display.py,sha256=b7l-pXohSnn1YK1g-8BUmY479x-d-wf5sG2pItG2_ps,19024
199
- fast_agent/ui/interactive_prompt.py,sha256=KI2jSO4roWNivfOeyibiu44J9pu5RU6PiB7Fd59iCYw,46699
200
- fast_agent/ui/mcp_display.py,sha256=piDn0F98yqvlHx1cxuKqTfefpvZkGiGK2QHujJltMtA,28422
202
+ fast_agent/ui/interactive_prompt.py,sha256=2nKETLjLOizYP8MPSDlrPSmp59CPjFenZPUZxDzbP7g,47790
203
+ fast_agent/ui/markdown_truncator.py,sha256=Tb_3UwtQVVcqCGlUpUJr-MYYkDQjB-dcI2VEf-4Gnoc,39842
204
+ fast_agent/ui/mcp_display.py,sha256=pRFbYdTYci0AIl98NJO4v6cwZ-EW4FNa8PP4yKhmYrU,30798
201
205
  fast_agent/ui/mcp_ui_utils.py,sha256=hV7z-yHX86BgdH6CMmN5qyOUjyiegQXLJOa5n5A1vQs,8476
202
206
  fast_agent/ui/mermaid_utils.py,sha256=MpcRyVCPMTwU1XeIxnyFg0fQLjcyXZduWRF8NhEqvXE,5332
203
207
  fast_agent/ui/notification_tracker.py,sha256=-hiBwR47SdnwhvrGIXcgsVaqMlMudmrKAf9Xi_E5Eok,5850
208
+ fast_agent/ui/plain_text_truncator.py,sha256=mx24CuxHq8Vy2r7IGOmGRhVkEZHyyWNsy8ZU0m3YxdA,2326
204
209
  fast_agent/ui/progress_display.py,sha256=hajDob65PttiJ2mPS6FsCtnmTcnyvDWGn-UqQboXqkQ,361
205
- fast_agent/ui/rich_progress.py,sha256=4n5NmsRQTT1GX18faP43yLPhB_gZJqJeWX6-j7g1_zI,7731
210
+ fast_agent/ui/rich_progress.py,sha256=s0HAaZHR3R7ubqtV20SX64RmkwvGCLXuJ8y29VjVKZs,7870
211
+ fast_agent/ui/streaming_buffer.py,sha256=e-zwVUVBOQ_mKyHgLiTXFmShGs4DNQRZ9BZZwWgXoWM,16648
206
212
  fast_agent/ui/usage_display.py,sha256=ltJpn_sDzo8PDNSXWx-QdEUbQWUnhmajCItNt5mA5rM,7285
207
- fast_agent_mcp-0.3.13.dist-info/METADATA,sha256=BJ3SgQEi3XsnCjuK6aiPTtvGKq6khx_w8HD5NAE0gX8,32003
208
- fast_agent_mcp-0.3.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
209
- fast_agent_mcp-0.3.13.dist-info/entry_points.txt,sha256=i6Ujja9J-hRxttOKqTYdbYP_tyaS4gLHg53vupoCSsg,199
210
- fast_agent_mcp-0.3.13.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
211
- fast_agent_mcp-0.3.13.dist-info/RECORD,,
213
+ fast_agent_mcp-0.3.15.dist-info/METADATA,sha256=nzz3drzGRQ-IENtLvUcL6r3wX7H5ucNKmJG5re49rgA,32033
214
+ fast_agent_mcp-0.3.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
215
+ fast_agent_mcp-0.3.15.dist-info/entry_points.txt,sha256=i6Ujja9J-hRxttOKqTYdbYP_tyaS4gLHg53vupoCSsg,199
216
+ fast_agent_mcp-0.3.15.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
217
+ fast_agent_mcp-0.3.15.dist-info/RECORD,,