fast-agent-mcp 0.3.16__py3-none-any.whl → 0.3.18__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.
- fast_agent/agents/mcp_agent.py +1 -1
- fast_agent/cli/commands/go.py +78 -36
- fast_agent/cli/commands/serve.py +136 -0
- fast_agent/cli/constants.py +3 -0
- fast_agent/cli/main.py +5 -3
- fast_agent/core/fastagent.py +102 -16
- fast_agent/interfaces.py +4 -0
- fast_agent/llm/model_database.py +4 -1
- fast_agent/llm/model_factory.py +4 -2
- fast_agent/llm/model_info.py +19 -43
- fast_agent/llm/provider/google/llm_google_native.py +238 -7
- fast_agent/llm/provider/openai/llm_openai.py +229 -32
- fast_agent/mcp/server/agent_server.py +175 -41
- fast_agent/skills/registry.py +17 -9
- fast_agent/tools/shell_runtime.py +4 -4
- fast_agent/ui/console_display.py +43 -1259
- fast_agent/ui/enhanced_prompt.py +26 -12
- fast_agent/ui/markdown_helpers.py +104 -0
- fast_agent/ui/markdown_truncator.py +103 -45
- fast_agent/ui/message_primitives.py +50 -0
- fast_agent/ui/streaming.py +638 -0
- fast_agent/ui/tool_display.py +417 -0
- {fast_agent_mcp-0.3.16.dist-info → fast_agent_mcp-0.3.18.dist-info}/METADATA +9 -1
- {fast_agent_mcp-0.3.16.dist-info → fast_agent_mcp-0.3.18.dist-info}/RECORD +27 -22
- {fast_agent_mcp-0.3.16.dist-info → fast_agent_mcp-0.3.18.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.3.16.dist-info → fast_agent_mcp-0.3.18.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.3.16.dist-info → fast_agent_mcp-0.3.18.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Mapping
|
|
5
|
+
|
|
6
|
+
from rich.syntax import Syntax
|
|
7
|
+
from rich.text import Text
|
|
8
|
+
|
|
9
|
+
from fast_agent.ui import console
|
|
10
|
+
from fast_agent.ui.message_primitives import MESSAGE_CONFIGS, MessageType
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from mcp.types import CallToolResult
|
|
14
|
+
|
|
15
|
+
from fast_agent.mcp.skybridge import SkybridgeServerConfig
|
|
16
|
+
from fast_agent.ui.console_display import ConsoleDisplay
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ToolDisplay:
|
|
20
|
+
"""Encapsulates rendering logic for tool calls and results."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, display: "ConsoleDisplay") -> None:
|
|
23
|
+
self._display = display
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def _markup(self) -> bool:
|
|
27
|
+
return self._display._markup
|
|
28
|
+
|
|
29
|
+
def show_tool_result(
|
|
30
|
+
self,
|
|
31
|
+
result: CallToolResult,
|
|
32
|
+
*,
|
|
33
|
+
name: str | None = None,
|
|
34
|
+
tool_name: str | None = None,
|
|
35
|
+
skybridge_config: "SkybridgeServerConfig | None" = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Display a tool result in the console."""
|
|
38
|
+
config = self._display.config
|
|
39
|
+
if not config or not config.logger.show_tools:
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
from fast_agent.mcp.helpers.content_helpers import get_text, is_text_content
|
|
43
|
+
|
|
44
|
+
content = result.content
|
|
45
|
+
structured_content = getattr(result, "structuredContent", None)
|
|
46
|
+
has_structured = structured_content is not None
|
|
47
|
+
|
|
48
|
+
is_skybridge_tool = False
|
|
49
|
+
skybridge_resource_uri: str | None = None
|
|
50
|
+
if has_structured and tool_name and skybridge_config:
|
|
51
|
+
for tool_cfg in skybridge_config.tools:
|
|
52
|
+
if tool_cfg.tool_name == tool_name and tool_cfg.is_valid:
|
|
53
|
+
is_skybridge_tool = True
|
|
54
|
+
skybridge_resource_uri = tool_cfg.resource_uri
|
|
55
|
+
break
|
|
56
|
+
|
|
57
|
+
if result.isError:
|
|
58
|
+
status = "ERROR"
|
|
59
|
+
else:
|
|
60
|
+
if len(content) == 0:
|
|
61
|
+
status = "No Content"
|
|
62
|
+
elif len(content) == 1 and is_text_content(content[0]):
|
|
63
|
+
text_content = get_text(content[0])
|
|
64
|
+
char_count = len(text_content) if text_content else 0
|
|
65
|
+
status = f"Text Only {char_count} chars"
|
|
66
|
+
else:
|
|
67
|
+
text_count = sum(1 for item in content if is_text_content(item))
|
|
68
|
+
if text_count == len(content):
|
|
69
|
+
status = f"{len(content)} Text Blocks" if len(content) > 1 else "1 Text Block"
|
|
70
|
+
else:
|
|
71
|
+
status = (
|
|
72
|
+
f"{len(content)} Content Blocks" if len(content) > 1 else "1 Content Block"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
channel = getattr(result, "transport_channel", None)
|
|
76
|
+
bottom_metadata_items: list[str] = []
|
|
77
|
+
if channel:
|
|
78
|
+
if channel == "post-json":
|
|
79
|
+
transport_info = "HTTP (JSON-RPC)"
|
|
80
|
+
elif channel == "post-sse":
|
|
81
|
+
transport_info = "HTTP (SSE)"
|
|
82
|
+
elif channel == "get":
|
|
83
|
+
transport_info = "Legacy SSE"
|
|
84
|
+
elif channel == "resumption":
|
|
85
|
+
transport_info = "Resumption"
|
|
86
|
+
elif channel == "stdio":
|
|
87
|
+
transport_info = "STDIO"
|
|
88
|
+
else:
|
|
89
|
+
transport_info = channel.upper()
|
|
90
|
+
|
|
91
|
+
bottom_metadata_items.append(transport_info)
|
|
92
|
+
|
|
93
|
+
elapsed = getattr(result, "transport_elapsed", None)
|
|
94
|
+
if isinstance(elapsed, (int, float)):
|
|
95
|
+
bottom_metadata_items.append(self._display._format_elapsed(float(elapsed)))
|
|
96
|
+
|
|
97
|
+
if has_structured:
|
|
98
|
+
bottom_metadata_items.append("Structured ■")
|
|
99
|
+
|
|
100
|
+
bottom_metadata = bottom_metadata_items or None
|
|
101
|
+
right_info = f"[dim]tool result - {status}[/dim]"
|
|
102
|
+
|
|
103
|
+
if has_structured:
|
|
104
|
+
config_map = MESSAGE_CONFIGS[MessageType.TOOL_RESULT]
|
|
105
|
+
block_color = "red" if result.isError else config_map["block_color"]
|
|
106
|
+
arrow = config_map["arrow"]
|
|
107
|
+
arrow_style = config_map["arrow_style"]
|
|
108
|
+
left = f"[{block_color}]▎[/{block_color}][{arrow_style}]{arrow}[/{arrow_style}]"
|
|
109
|
+
if name:
|
|
110
|
+
name_color = block_color if not result.isError else "red"
|
|
111
|
+
left += f" [{name_color}]{name}[/{name_color}]"
|
|
112
|
+
|
|
113
|
+
self._display._create_combined_separator_status(left, right_info)
|
|
114
|
+
|
|
115
|
+
self._display._display_content(
|
|
116
|
+
content,
|
|
117
|
+
True,
|
|
118
|
+
result.isError,
|
|
119
|
+
MessageType.TOOL_RESULT,
|
|
120
|
+
check_markdown_markers=False,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
console.console.print()
|
|
124
|
+
total_width = console.console.size.width
|
|
125
|
+
|
|
126
|
+
if is_skybridge_tool:
|
|
127
|
+
resource_label = (
|
|
128
|
+
f"skybridge resource: {skybridge_resource_uri}"
|
|
129
|
+
if skybridge_resource_uri
|
|
130
|
+
else "skybridge resource"
|
|
131
|
+
)
|
|
132
|
+
prefix = Text("─| ")
|
|
133
|
+
prefix.stylize("dim")
|
|
134
|
+
resource_text = Text(resource_label, style="magenta")
|
|
135
|
+
suffix = Text(" |")
|
|
136
|
+
suffix.stylize("dim")
|
|
137
|
+
|
|
138
|
+
separator_line = Text()
|
|
139
|
+
separator_line.append_text(prefix)
|
|
140
|
+
separator_line.append_text(resource_text)
|
|
141
|
+
separator_line.append_text(suffix)
|
|
142
|
+
remaining = total_width - separator_line.cell_len
|
|
143
|
+
if remaining > 0:
|
|
144
|
+
separator_line.append("─" * remaining, style="dim")
|
|
145
|
+
console.console.print(separator_line, markup=self._markup)
|
|
146
|
+
console.console.print()
|
|
147
|
+
|
|
148
|
+
json_str = json.dumps(structured_content, indent=2)
|
|
149
|
+
syntax_obj = Syntax(
|
|
150
|
+
json_str,
|
|
151
|
+
"json",
|
|
152
|
+
theme=self._display.code_style,
|
|
153
|
+
background_color="default",
|
|
154
|
+
)
|
|
155
|
+
console.console.print(syntax_obj, markup=self._markup)
|
|
156
|
+
else:
|
|
157
|
+
prefix = Text("─| ")
|
|
158
|
+
prefix.stylize("dim")
|
|
159
|
+
suffix = Text(" |")
|
|
160
|
+
suffix.stylize("dim")
|
|
161
|
+
available = max(0, total_width - prefix.cell_len - suffix.cell_len)
|
|
162
|
+
|
|
163
|
+
metadata_text = self._display._format_bottom_metadata(
|
|
164
|
+
bottom_metadata_items,
|
|
165
|
+
None,
|
|
166
|
+
config_map["highlight_color"],
|
|
167
|
+
max_width=available,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
line = Text()
|
|
171
|
+
line.append_text(prefix)
|
|
172
|
+
line.append_text(metadata_text)
|
|
173
|
+
line.append_text(suffix)
|
|
174
|
+
remaining = total_width - line.cell_len
|
|
175
|
+
if remaining > 0:
|
|
176
|
+
line.append("─" * remaining, style="dim")
|
|
177
|
+
console.console.print(line, markup=self._markup)
|
|
178
|
+
console.console.print()
|
|
179
|
+
else:
|
|
180
|
+
self._display.display_message(
|
|
181
|
+
content=content,
|
|
182
|
+
message_type=MessageType.TOOL_RESULT,
|
|
183
|
+
name=name,
|
|
184
|
+
right_info=right_info,
|
|
185
|
+
bottom_metadata=bottom_metadata,
|
|
186
|
+
is_error=result.isError,
|
|
187
|
+
truncate_content=True,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
def show_tool_call(
|
|
191
|
+
self,
|
|
192
|
+
tool_name: str,
|
|
193
|
+
tool_args: dict[str, Any] | None,
|
|
194
|
+
*,
|
|
195
|
+
bottom_items: list[str] | None = None,
|
|
196
|
+
highlight_index: int | None = None,
|
|
197
|
+
max_item_length: int | None = None,
|
|
198
|
+
name: str | None = None,
|
|
199
|
+
metadata: dict[str, Any] | None = None,
|
|
200
|
+
) -> None:
|
|
201
|
+
"""Display a tool call header and body."""
|
|
202
|
+
config = self._display.config
|
|
203
|
+
if not config or not config.logger.show_tools:
|
|
204
|
+
return
|
|
205
|
+
|
|
206
|
+
tool_args = tool_args or {}
|
|
207
|
+
metadata = metadata or {}
|
|
208
|
+
|
|
209
|
+
right_info = f"[dim]tool request - {tool_name}[/dim]"
|
|
210
|
+
content: Any = tool_args
|
|
211
|
+
pre_content: Text | None = None
|
|
212
|
+
truncate_content = True
|
|
213
|
+
|
|
214
|
+
if metadata.get("variant") == "shell":
|
|
215
|
+
bottom_items = list()
|
|
216
|
+
max_item_length = 50
|
|
217
|
+
command = metadata.get("command") or tool_args.get("command")
|
|
218
|
+
|
|
219
|
+
command_text = Text()
|
|
220
|
+
if command and isinstance(command, str):
|
|
221
|
+
command_text.append("$ ", style="magenta")
|
|
222
|
+
command_text.append(command, style="white")
|
|
223
|
+
else:
|
|
224
|
+
command_text.append("$ ", style="magenta")
|
|
225
|
+
command_text.append("(no shell command provided)", style="dim")
|
|
226
|
+
|
|
227
|
+
content = command_text
|
|
228
|
+
|
|
229
|
+
shell_name = metadata.get("shell_name") or "shell"
|
|
230
|
+
shell_path = metadata.get("shell_path")
|
|
231
|
+
if shell_path:
|
|
232
|
+
bottom_items.append(str(shell_path))
|
|
233
|
+
|
|
234
|
+
right_parts: list[str] = []
|
|
235
|
+
if shell_path and shell_path != shell_name:
|
|
236
|
+
right_parts.append(f"{shell_name} ({shell_path})")
|
|
237
|
+
elif shell_name:
|
|
238
|
+
right_parts.append(shell_name)
|
|
239
|
+
|
|
240
|
+
right_info = f"[dim]{' | '.join(right_parts)}[/dim]" if right_parts else ""
|
|
241
|
+
truncate_content = False
|
|
242
|
+
|
|
243
|
+
working_dir_display = metadata.get("working_dir_display") or metadata.get("working_dir")
|
|
244
|
+
if working_dir_display:
|
|
245
|
+
bottom_items.append(f"cwd: {working_dir_display}")
|
|
246
|
+
|
|
247
|
+
timeout_seconds = metadata.get("timeout_seconds")
|
|
248
|
+
warning_interval = metadata.get("warning_interval_seconds")
|
|
249
|
+
|
|
250
|
+
if timeout_seconds and warning_interval:
|
|
251
|
+
bottom_items.append(
|
|
252
|
+
f"timeout: {timeout_seconds}s, warning every {warning_interval}s"
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
self._display.display_message(
|
|
256
|
+
content=content,
|
|
257
|
+
message_type=MessageType.TOOL_CALL,
|
|
258
|
+
name=name,
|
|
259
|
+
pre_content=pre_content,
|
|
260
|
+
right_info=right_info,
|
|
261
|
+
bottom_metadata=bottom_items,
|
|
262
|
+
highlight_index=highlight_index,
|
|
263
|
+
max_item_length=max_item_length,
|
|
264
|
+
truncate_content=truncate_content,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
async def show_tool_update(self, updated_server: str, *, agent_name: str | None = None) -> None:
|
|
268
|
+
"""Show a background tool update notification."""
|
|
269
|
+
config = self._display.config
|
|
270
|
+
if not config or not config.logger.show_tools:
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
try:
|
|
274
|
+
from prompt_toolkit.application.current import get_app
|
|
275
|
+
|
|
276
|
+
app = get_app()
|
|
277
|
+
from fast_agent.ui import notification_tracker
|
|
278
|
+
|
|
279
|
+
notification_tracker.add_tool_update(updated_server)
|
|
280
|
+
app.invalidate()
|
|
281
|
+
except Exception: # noqa: BLE001
|
|
282
|
+
if agent_name:
|
|
283
|
+
left = f"[magenta]▎[/magenta][dim magenta]▶[/dim magenta] [magenta]{agent_name}[/magenta]"
|
|
284
|
+
else:
|
|
285
|
+
left = "[magenta]▎[/magenta][dim magenta]▶[/dim magenta]"
|
|
286
|
+
|
|
287
|
+
right = f"[dim]{updated_server}[/dim]"
|
|
288
|
+
self._display._create_combined_separator_status(left, right)
|
|
289
|
+
|
|
290
|
+
message = f"Updating tools for server {updated_server}"
|
|
291
|
+
console.console.print(message, style="dim", markup=self._markup)
|
|
292
|
+
|
|
293
|
+
console.console.print()
|
|
294
|
+
console.console.print("─" * console.console.size.width, style="dim")
|
|
295
|
+
console.console.print()
|
|
296
|
+
|
|
297
|
+
@staticmethod
|
|
298
|
+
def summarize_skybridge_configs(
|
|
299
|
+
configs: Mapping[str, "SkybridgeServerConfig"] | None,
|
|
300
|
+
) -> tuple[list[dict[str, Any]], list[str]]:
|
|
301
|
+
"""Convert Skybridge configs into display-ready structures."""
|
|
302
|
+
server_rows: list[dict[str, Any]] = []
|
|
303
|
+
warnings: list[str] = []
|
|
304
|
+
warning_seen: set[str] = set()
|
|
305
|
+
|
|
306
|
+
if not configs:
|
|
307
|
+
return server_rows, warnings
|
|
308
|
+
|
|
309
|
+
def add_warning(message: str) -> None:
|
|
310
|
+
formatted = message.strip()
|
|
311
|
+
if not formatted:
|
|
312
|
+
return
|
|
313
|
+
if formatted not in warning_seen:
|
|
314
|
+
warnings.append(formatted)
|
|
315
|
+
warning_seen.add(formatted)
|
|
316
|
+
|
|
317
|
+
for server_name in sorted(configs.keys()):
|
|
318
|
+
config = configs.get(server_name)
|
|
319
|
+
if not config:
|
|
320
|
+
continue
|
|
321
|
+
resources = list(config.ui_resources or [])
|
|
322
|
+
has_skybridge_signal = bool(
|
|
323
|
+
config.enabled or resources or config.tools or config.warnings
|
|
324
|
+
)
|
|
325
|
+
if not has_skybridge_signal:
|
|
326
|
+
continue
|
|
327
|
+
|
|
328
|
+
valid_resource_count = sum(1 for resource in resources if resource.is_skybridge)
|
|
329
|
+
|
|
330
|
+
server_rows.append(
|
|
331
|
+
{
|
|
332
|
+
"server_name": server_name,
|
|
333
|
+
"config": config,
|
|
334
|
+
"resources": resources,
|
|
335
|
+
"valid_resource_count": valid_resource_count,
|
|
336
|
+
"total_resource_count": len(resources),
|
|
337
|
+
"active_tools": [
|
|
338
|
+
{
|
|
339
|
+
"name": tool.display_name,
|
|
340
|
+
"template": str(tool.template_uri) if tool.template_uri else None,
|
|
341
|
+
}
|
|
342
|
+
for tool in config.tools
|
|
343
|
+
if tool.is_valid
|
|
344
|
+
],
|
|
345
|
+
"enabled": config.enabled,
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
for warning in config.warnings:
|
|
350
|
+
message = warning.strip()
|
|
351
|
+
if not message:
|
|
352
|
+
continue
|
|
353
|
+
if not message.startswith(server_name):
|
|
354
|
+
message = f"{server_name} {message}"
|
|
355
|
+
add_warning(message)
|
|
356
|
+
|
|
357
|
+
return server_rows, warnings
|
|
358
|
+
|
|
359
|
+
def show_skybridge_summary(
|
|
360
|
+
self,
|
|
361
|
+
agent_name: str,
|
|
362
|
+
configs: Mapping[str, "SkybridgeServerConfig"] | None,
|
|
363
|
+
) -> None:
|
|
364
|
+
"""Display aggregated Skybridge status."""
|
|
365
|
+
server_rows, warnings = self.summarize_skybridge_configs(configs)
|
|
366
|
+
|
|
367
|
+
if not server_rows and not warnings:
|
|
368
|
+
return
|
|
369
|
+
|
|
370
|
+
heading = "[dim]OpenAI Apps SDK ([/dim][cyan]skybridge[/cyan][dim]) detected:[/dim]"
|
|
371
|
+
console.console.print()
|
|
372
|
+
console.console.print(heading, markup=self._markup)
|
|
373
|
+
|
|
374
|
+
if not server_rows:
|
|
375
|
+
console.console.print("[dim] ● none detected[/dim]", markup=self._markup)
|
|
376
|
+
else:
|
|
377
|
+
for row in server_rows:
|
|
378
|
+
server_name = row["server_name"]
|
|
379
|
+
resource_count = row["valid_resource_count"]
|
|
380
|
+
tool_infos = row["active_tools"]
|
|
381
|
+
enabled = row["enabled"]
|
|
382
|
+
|
|
383
|
+
tool_count = len(tool_infos)
|
|
384
|
+
tool_word = "tool" if tool_count == 1 else "tools"
|
|
385
|
+
resource_word = (
|
|
386
|
+
"skybridge resource" if resource_count == 1 else "skybridge resources"
|
|
387
|
+
)
|
|
388
|
+
tool_segment = f"[cyan]{tool_count}[/cyan][dim] {tool_word}[/dim]"
|
|
389
|
+
resource_segment = f"[cyan]{resource_count}[/cyan][dim] {resource_word}[/dim]"
|
|
390
|
+
name_style = "cyan" if enabled else "yellow"
|
|
391
|
+
status_suffix = "" if enabled else "[dim] (issues detected)[/dim]"
|
|
392
|
+
|
|
393
|
+
console.console.print(
|
|
394
|
+
f"[dim] ● [/dim][{name_style}]{server_name}[/{name_style}]{status_suffix}"
|
|
395
|
+
f"[dim] — [/dim]{tool_segment}[dim], [/dim]{resource_segment}",
|
|
396
|
+
markup=self._markup,
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
if tool_infos:
|
|
400
|
+
for tool in tool_infos:
|
|
401
|
+
template_info = (
|
|
402
|
+
f" [dim]({tool['template']})[/dim]" if tool["template"] else ""
|
|
403
|
+
)
|
|
404
|
+
console.console.print(
|
|
405
|
+
f"[dim] · [/dim]{tool['name']}{template_info}", markup=self._markup
|
|
406
|
+
)
|
|
407
|
+
else:
|
|
408
|
+
console.console.print("[dim] · no active tools[/dim]", markup=self._markup)
|
|
409
|
+
|
|
410
|
+
if warnings:
|
|
411
|
+
console.console.print()
|
|
412
|
+
console.console.print(
|
|
413
|
+
"[yellow]Warnings[/yellow]",
|
|
414
|
+
markup=self._markup,
|
|
415
|
+
)
|
|
416
|
+
for warning in warnings:
|
|
417
|
+
console.console.print(f"[yellow]- {warning}[/yellow]", markup=self._markup)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fast-agent-mcp
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.18
|
|
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
|
|
@@ -261,6 +261,14 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
|
|
|
261
261
|
|
|
262
262
|
Model support is comprehensive with native support for Anthropic, OpenAI and Google providers as well as Azure, Ollama, Deepseek and dozens of others via TensorZero. Structured Outputs, PDF and Vision support is simple to use and well tested. Passthrough and Playback LLMs enable rapid development and test of Python glue-code for your applications.
|
|
263
263
|
|
|
264
|
+
Recent features include:
|
|
265
|
+
- Agent Skills (SKILL.md)
|
|
266
|
+
- MCP-UI Support |
|
|
267
|
+
- OpenAI Apps SDK (Skybridge)
|
|
268
|
+
- Shell Mode
|
|
269
|
+
- Advanced MCP Transport Diagnsotics
|
|
270
|
+
- MCP Elicitations
|
|
271
|
+
|
|
264
272
|
<img width="800" alt="MCP Transport Diagnostics" src="https://github.com/user-attachments/assets/e26472de-58d9-4726-8bdd-01eb407414cf" />
|
|
265
273
|
|
|
266
274
|
|
|
@@ -4,14 +4,14 @@ fast_agent/constants.py,sha256=3M07UrFW7ueA0QNAy7JJRXcYDzpv76EGF_08b8ADcig,662
|
|
|
4
4
|
fast_agent/context.py,sha256=Mt6AFuUR1anR6yOw1R9ZIuEQzFi82mvEfLwjKiP0IiM,9362
|
|
5
5
|
fast_agent/context_dependent.py,sha256=KU1eydVBoIt4bYOZroqxDgE1AUexDaZi7hurE26QsF4,1584
|
|
6
6
|
fast_agent/event_progress.py,sha256=iTGlD-tAG3n_mLnUr7h03nPMSZK8piyLeaA-IB9erBw,2064
|
|
7
|
-
fast_agent/interfaces.py,sha256=
|
|
7
|
+
fast_agent/interfaces.py,sha256=A01ibxAB9yejqYtZL-K_PJKZPuWsjlpu4_5JaUIBTag,7044
|
|
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=dashrBG95dhK-54KMXKBGhQgDrgZ30L-wDnhSf1wIYQ,1956
|
|
12
12
|
fast_agent/agents/llm_agent.py,sha256=k29Zhl4lrfAi4YSF9_406KluFf7_IQVT0Fj_tA0rbGI,11737
|
|
13
13
|
fast_agent/agents/llm_decorator.py,sha256=riTrgX8L9blrrqncRL6Osc_IFKSs1XOLkOtjr6kVAFg,30377
|
|
14
|
-
fast_agent/agents/mcp_agent.py,sha256=
|
|
14
|
+
fast_agent/agents/mcp_agent.py,sha256=lc3DgFwuCyStjFGtPBLmbeCsrOPCFWnlerGJD11o4LQ,45668
|
|
15
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
|
|
@@ -22,13 +22,14 @@ fast_agent/agents/workflow/parallel_agent.py,sha256=DlJXDURAfx-WBF297tKBLfH93gDF
|
|
|
22
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=OWuKPFEeZRco6j5VA3IvtwTvZ351pDGxuO6rAiOTFNI,2588
|
|
25
|
-
fast_agent/cli/constants.py,sha256=
|
|
26
|
-
fast_agent/cli/main.py,sha256=
|
|
25
|
+
fast_agent/cli/constants.py,sha256=xLxQKuQzbv3Qkd6CB5wNwyDqyHBvdx97PZfsoK7-b4o,672
|
|
26
|
+
fast_agent/cli/main.py,sha256=yXglgZuQrThhqK3EgVstwpU3YRUf2-RWIDXDb6rQ66s,4650
|
|
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
29
|
fast_agent/cli/commands/check_config.py,sha256=Iy5MHsRXqRcFLN-0Gs20jA3DqT-gN1VE9WtKuWlxJ9M,32597
|
|
30
|
-
fast_agent/cli/commands/go.py,sha256=
|
|
30
|
+
fast_agent/cli/commands/go.py,sha256=f0CrNkjzuIWWewUnCGeMWcO-93PdhyOqq5n3a-8cWVM,19005
|
|
31
31
|
fast_agent/cli/commands/quickstart.py,sha256=UOTqAbaVGLECHkTvpUNQ41PWXssqCijVvrqh30YUqnM,20624
|
|
32
|
+
fast_agent/cli/commands/serve.py,sha256=KU9QsP9MQVKV5eOrt8eBGi9gyx_Y20oaEwurDuWAc0k,4427
|
|
32
33
|
fast_agent/cli/commands/server_helpers.py,sha256=Nuded8sZb4Rybwoq5LbXXUgwtJZg-OO04xhmPUp6e98,4073
|
|
33
34
|
fast_agent/cli/commands/setup.py,sha256=n5hVjXkKTmuiW8-0ezItVcMHJ92W6NlE2JOGCYiKw0A,6388
|
|
34
35
|
fast_agent/cli/commands/url_parser.py,sha256=v9KoprPBEEST5Fo7qXgbW50GC5vMpxFteKqAT6mFkdI,5991
|
|
@@ -39,7 +40,7 @@ fast_agent/core/direct_decorators.py,sha256=Z8zM1Ep9THEiuNzlxW-WmQDm7x4JF0wn4xO2
|
|
|
39
40
|
fast_agent/core/direct_factory.py,sha256=SYYVtEqPQh7ElvAVC_445a5pZkKstM0RhKNGZ2CJQT8,18338
|
|
40
41
|
fast_agent/core/error_handling.py,sha256=tZkO8LnXO-qf6jD8a12Pv5fD4NhnN1Ag5_tJ6DwbXjg,631
|
|
41
42
|
fast_agent/core/exceptions.py,sha256=ENAD_qGG67foxy6vDkIvc-lgopIUQy6O7zvNPpPXaQg,2289
|
|
42
|
-
fast_agent/core/fastagent.py,sha256=
|
|
43
|
+
fast_agent/core/fastagent.py,sha256=u9TBdQxBlyV3OhZ5gfOB2TucdI3xI2xsEObW-c1WTdA,39865
|
|
43
44
|
fast_agent/core/prompt.py,sha256=qNUFlK3KtU7leYysYUglzBYQnEYiXu__iR_T8189zc0,203
|
|
44
45
|
fast_agent/core/validation.py,sha256=cesQeT8jfLlPqew6S9bq8ZJqde7ViVQXHF9fhAnyOHI,11950
|
|
45
46
|
fast_agent/core/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -62,9 +63,9 @@ fast_agent/human_input/types.py,sha256=3Zz89yIt8SuDAVAaRy-r4Vw0-M6AWahwbqQ0yOcoe
|
|
|
62
63
|
fast_agent/llm/__init__.py,sha256=MCsrkfnTQXYvn0SofJ-JFmp1l1jX_eidgvegbWbgpsw,184
|
|
63
64
|
fast_agent/llm/fastagent_llm.py,sha256=uGbuXTZlxKjjvG5VMfInK-asLtowqIdY4yP48HkJagI,27698
|
|
64
65
|
fast_agent/llm/memory.py,sha256=7mpoWxxFzRLgtU6IUs7TISH6yPe9eAwHAwRdete8mKo,9417
|
|
65
|
-
fast_agent/llm/model_database.py,sha256=
|
|
66
|
-
fast_agent/llm/model_factory.py,sha256=
|
|
67
|
-
fast_agent/llm/model_info.py,sha256=
|
|
66
|
+
fast_agent/llm/model_database.py,sha256=0g8SifdlxueQZLa-p8ptJa6u1vRApZm1CbmIaU1Mvoc,13161
|
|
67
|
+
fast_agent/llm/model_factory.py,sha256=eQhRavl7G7eu6lpfcPQjAfLX2eKsfDKjlM80Q3eeGDg,13382
|
|
68
|
+
fast_agent/llm/model_info.py,sha256=eASLZ9_bClF7_2eOTmkNDG63yQoJHHtKDii9ZzT2a6o,3534
|
|
68
69
|
fast_agent/llm/prompt_utils.py,sha256=1WU67G-BFqftja5I8FKPMMzsvDk1K_1jDi9A9kkFdOg,4899
|
|
69
70
|
fast_agent/llm/provider_key_manager.py,sha256=O8jhoqzLgMbY57TbJxztNwElbsQPC0GMIwgiaz_5SuQ,3455
|
|
70
71
|
fast_agent/llm/provider_types.py,sha256=JyJoyyCI3htgX9VCvvyz2Lx9fBQtdrLbXma0oc9vfsw,1185
|
|
@@ -81,14 +82,14 @@ fast_agent/llm/provider/anthropic/multipart_converter_anthropic.py,sha256=szHqhd
|
|
|
81
82
|
fast_agent/llm/provider/bedrock/bedrock_utils.py,sha256=mqWCCeB1gUQSL2KRUMqpFjvHZ0ZTJugCsd5YOrx6U30,7750
|
|
82
83
|
fast_agent/llm/provider/bedrock/llm_bedrock.py,sha256=Yl3luBfgM4wNGuMpPN9yg8DGHr_ncfYg0EemvKi2Rxc,100199
|
|
83
84
|
fast_agent/llm/provider/google/google_converter.py,sha256=cGb2ty_uBgdATa0Nib_BzvEbWCpBf3Mwzu9pMxMziA8,17599
|
|
84
|
-
fast_agent/llm/provider/google/llm_google_native.py,sha256=
|
|
85
|
+
fast_agent/llm/provider/google/llm_google_native.py,sha256=LcrM1ywDHFUFYxHCWKtBwlySJKTQWrtRMJM0fp14pqc,29101
|
|
85
86
|
fast_agent/llm/provider/openai/llm_aliyun.py,sha256=ti7VHTpwl0AG3ytwBERpDzVtacvCfamKnl2bAnTE96s,1213
|
|
86
87
|
fast_agent/llm/provider/openai/llm_azure.py,sha256=dePpuOf7yD4-zQc1PEHm4yaVznrZe9RaIz7nxsbZhlU,6061
|
|
87
88
|
fast_agent/llm/provider/openai/llm_deepseek.py,sha256=aAMX7pd1qDfl54Z9pLvJTVYETc4yKKMRYrEMiPIhd7w,3762
|
|
88
89
|
fast_agent/llm/provider/openai/llm_generic.py,sha256=O_mmu3o9LeAZ6Kp405I-GfwrS8AuVkyX3tT6aCDCfLY,1168
|
|
89
90
|
fast_agent/llm/provider/openai/llm_google_oai.py,sha256=u1yZVeDds9z2hvydz_kUpFe2RANTNwEtlPgB-OEmgrY,1095
|
|
90
91
|
fast_agent/llm/provider/openai/llm_groq.py,sha256=trNSy3T94_fJWAhVn51iESP_J7sQh_23ufVegKKNHBs,5247
|
|
91
|
-
fast_agent/llm/provider/openai/llm_openai.py,sha256=
|
|
92
|
+
fast_agent/llm/provider/openai/llm_openai.py,sha256=Ql3XgAKD9iNePVrspfLlITjgWzAbsdG-8UYU3lpRkJo,41583
|
|
92
93
|
fast_agent/llm/provider/openai/llm_openrouter.py,sha256=RBTUkNBRqE8WoucCoVnXP5GhnMwc2tiRacXbMHVf1xM,1943
|
|
93
94
|
fast_agent/llm/provider/openai/llm_tensorzero_openai.py,sha256=bG1paNw-OWf0SUGfHvhx1SJ1C-nn_sDZkFVJ_e3kJYc,5457
|
|
94
95
|
fast_agent/llm/provider/openai/llm_xai.py,sha256=fEyO9XlU3Ef1a-cXdJl0Qe-FmE562cA-UJOGvzqLO6M,1375
|
|
@@ -135,7 +136,7 @@ fast_agent/mcp/prompts/prompt_load.py,sha256=1KixVXpkML3_kY3vC59AlMfcBXQVESrII24
|
|
|
135
136
|
fast_agent/mcp/prompts/prompt_server.py,sha256=ZuUFqYfiYYE8yTXw0qagGWkZkelQgETGBpzUIdIhLXc,20174
|
|
136
137
|
fast_agent/mcp/prompts/prompt_template.py,sha256=SAklXs9wujYqqEWv5vzRI_cdjSmGnWlDmPLZ5qkXZO4,15695
|
|
137
138
|
fast_agent/mcp/server/__init__.py,sha256=AJFNzdmuHPRL3jqFhDVDJste_zYE_KJ3gGYDsbghvl0,156
|
|
138
|
-
fast_agent/mcp/server/agent_server.py,sha256=
|
|
139
|
+
fast_agent/mcp/server/agent_server.py,sha256=svO0_RwJX1thRRfciLXkbLUFLokkzw5VspGIs5Ias40,25555
|
|
139
140
|
fast_agent/resources/examples/data-analysis/analysis-campaign.py,sha256=SnDQm_e_cm0IZEKdWizUedXxpIWWj-5K70wmcM1Tw2Y,7277
|
|
140
141
|
fast_agent/resources/examples/data-analysis/analysis.py,sha256=0W1dN3SAx-RxEKoH3shAq42HxglEz9hc8BadGYmnwAk,2653
|
|
141
142
|
fast_agent/resources/examples/data-analysis/fastagent.config.yaml,sha256=ini94PHyJCfgpjcjHKMMbGuHs6LIj46F1NwY0ll5HVk,1609
|
|
@@ -191,31 +192,35 @@ fast_agent/resources/setup/fastagent.config.yaml,sha256=sTLPhq6PV6fsFYQPum6TDFFY
|
|
|
191
192
|
fast_agent/resources/setup/fastagent.secrets.yaml.example,sha256=ht-i2_SpAyeXG2OnG_vOA1n7gRsGIInxp9g5Nio-jpI,1038
|
|
192
193
|
fast_agent/resources/setup/pyproject.toml.tmpl,sha256=SxyVPXbtD67yFOx9wIrzq6Yxo4W2PkSR1rrnPkmpjwA,478
|
|
193
194
|
fast_agent/skills/__init__.py,sha256=3BaJ4be9MtYIglPJoCd2yUxdj86iDMTP-ljGCcSjfKM,200
|
|
194
|
-
fast_agent/skills/registry.py,sha256=
|
|
195
|
+
fast_agent/skills/registry.py,sha256=K8dbjSIoSZav-Z0_PZceng3eKAyD8bI3w8O1Z0LfBiM,7615
|
|
195
196
|
fast_agent/tools/elicitation.py,sha256=8FaNvuN__LAM328VSJ5T4Bg3m8auHraqYvIYv6Eh4KU,13464
|
|
196
|
-
fast_agent/tools/shell_runtime.py,sha256=
|
|
197
|
+
fast_agent/tools/shell_runtime.py,sha256=T9gIpPSWbteDjIWPS3fhGPz09whkqVGKt4FpisHRd9Y,17940
|
|
197
198
|
fast_agent/types/__init__.py,sha256=y-53m-C4drf4Rx8Bbnk_GAhko9LdNYCyRUWya8e0mos,1004
|
|
198
199
|
fast_agent/types/llm_stop_reason.py,sha256=bWe97OfhALUe8uQeAQOnTdPlYzJiabIfo8u38kPgj3Q,2293
|
|
199
200
|
fast_agent/ui/__init__.py,sha256=MXxTQjFdF7mI_3JHxBPd-aoZYLlxV_-51-Trqgv5-3w,1104
|
|
200
201
|
fast_agent/ui/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
|
|
201
|
-
fast_agent/ui/console_display.py,sha256=
|
|
202
|
+
fast_agent/ui/console_display.py,sha256=VzB_bvGvtq2RyAID9xlxo1JNF8cKeeYwObSTsyZlCEQ,40470
|
|
202
203
|
fast_agent/ui/elicitation_form.py,sha256=QieYhLnRwBfwu7ochQ8RotKRTkH8UoSJ1GkA0Mc1zaU,32893
|
|
203
204
|
fast_agent/ui/elicitation_style.py,sha256=rS0qSS5c6if97STud4jKahs0HLvh9I6MVL1swDyCvck,3943
|
|
204
|
-
fast_agent/ui/enhanced_prompt.py,sha256=
|
|
205
|
+
fast_agent/ui/enhanced_prompt.py,sha256=FvmRvEPf5KJMeMAYi_KDUiccm82H288Y6D7NRubmP8s,52722
|
|
205
206
|
fast_agent/ui/history_display.py,sha256=5vgH9FcIwG2u2BCGvwLcZPBTokPs_LY_P1-0EQsal0o,19618
|
|
206
207
|
fast_agent/ui/interactive_prompt.py,sha256=1DQDhwEm6ZdUw0avUmg_o17IVunzCZTm6RZIPNRvHFE,52381
|
|
207
|
-
fast_agent/ui/
|
|
208
|
+
fast_agent/ui/markdown_helpers.py,sha256=r42hbwiGxYA1Xwf5o_BoP0k8d52aT_eZ_x6xNfDuCWU,3497
|
|
209
|
+
fast_agent/ui/markdown_truncator.py,sha256=1MFQ64WwL8lWDmnoswjHmz2X-bDwG9Uu_jFf0hmchdU,42071
|
|
208
210
|
fast_agent/ui/mcp_display.py,sha256=pRFbYdTYci0AIl98NJO4v6cwZ-EW4FNa8PP4yKhmYrU,30798
|
|
209
211
|
fast_agent/ui/mcp_ui_utils.py,sha256=hV7z-yHX86BgdH6CMmN5qyOUjyiegQXLJOa5n5A1vQs,8476
|
|
210
212
|
fast_agent/ui/mermaid_utils.py,sha256=MpcRyVCPMTwU1XeIxnyFg0fQLjcyXZduWRF8NhEqvXE,5332
|
|
213
|
+
fast_agent/ui/message_primitives.py,sha256=0w5QTGjG409YBsDADZfk7F78JbiucpjURj3MYn7-Pqk,1211
|
|
211
214
|
fast_agent/ui/notification_tracker.py,sha256=-hiBwR47SdnwhvrGIXcgsVaqMlMudmrKAf9Xi_E5Eok,5850
|
|
212
215
|
fast_agent/ui/plain_text_truncator.py,sha256=mx24CuxHq8Vy2r7IGOmGRhVkEZHyyWNsy8ZU0m3YxdA,2326
|
|
213
216
|
fast_agent/ui/progress_display.py,sha256=hajDob65PttiJ2mPS6FsCtnmTcnyvDWGn-UqQboXqkQ,361
|
|
214
217
|
fast_agent/ui/rich_progress.py,sha256=s0HAaZHR3R7ubqtV20SX64RmkwvGCLXuJ8y29VjVKZs,7870
|
|
218
|
+
fast_agent/ui/streaming.py,sha256=SNLGx6s8xuRikxi6vNxnDCgQQKqFJ5rbTKU9ixnzmY0,22190
|
|
215
219
|
fast_agent/ui/streaming_buffer.py,sha256=e-zwVUVBOQ_mKyHgLiTXFmShGs4DNQRZ9BZZwWgXoWM,16648
|
|
220
|
+
fast_agent/ui/tool_display.py,sha256=DK6kA8MBjxq8qpK1WLv7kFKAfOtEOfY5rtQ8t4XeM0s,16111
|
|
216
221
|
fast_agent/ui/usage_display.py,sha256=ltJpn_sDzo8PDNSXWx-QdEUbQWUnhmajCItNt5mA5rM,7285
|
|
217
|
-
fast_agent_mcp-0.3.
|
|
218
|
-
fast_agent_mcp-0.3.
|
|
219
|
-
fast_agent_mcp-0.3.
|
|
220
|
-
fast_agent_mcp-0.3.
|
|
221
|
-
fast_agent_mcp-0.3.
|
|
222
|
+
fast_agent_mcp-0.3.18.dist-info/METADATA,sha256=UluPke36Pp1VhO8z8hmPIlC-MjqN94xO6N02HF3EWbU,32259
|
|
223
|
+
fast_agent_mcp-0.3.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
224
|
+
fast_agent_mcp-0.3.18.dist-info/entry_points.txt,sha256=i6Ujja9J-hRxttOKqTYdbYP_tyaS4gLHg53vupoCSsg,199
|
|
225
|
+
fast_agent_mcp-0.3.18.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
|
|
226
|
+
fast_agent_mcp-0.3.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|