fast-agent-mcp 0.3.3__py3-none-any.whl → 0.3.5__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/__init__.py +6 -3
  2. fast_agent/agents/__init__.py +63 -14
  3. fast_agent/cli/__main__.py +8 -5
  4. fast_agent/cli/commands/auth.py +370 -0
  5. fast_agent/cli/commands/check_config.py +54 -3
  6. fast_agent/cli/commands/go.py +1 -1
  7. fast_agent/cli/commands/quickstart.py +3 -1
  8. fast_agent/cli/commands/server_helpers.py +10 -2
  9. fast_agent/cli/commands/setup.py +3 -2
  10. fast_agent/cli/constants.py +1 -1
  11. fast_agent/cli/main.py +3 -1
  12. fast_agent/config.py +63 -8
  13. fast_agent/core/__init__.py +38 -37
  14. fast_agent/core/direct_factory.py +1 -1
  15. fast_agent/mcp/mcp_connection_manager.py +21 -3
  16. fast_agent/mcp/oauth_client.py +481 -0
  17. fast_agent/mcp/ui_agent.py +1 -1
  18. fast_agent/resources/examples/data-analysis/analysis-campaign.py +1 -1
  19. fast_agent/resources/examples/data-analysis/analysis.py +1 -1
  20. fast_agent/resources/examples/mcp/elicitations/forms_demo.py +1 -1
  21. fast_agent/resources/examples/mcp/elicitations/game_character.py +1 -1
  22. fast_agent/resources/examples/mcp/elicitations/tool_call.py +1 -1
  23. fast_agent/resources/examples/mcp/state-transfer/agent_one.py +1 -1
  24. fast_agent/resources/examples/mcp/state-transfer/agent_two.py +1 -1
  25. fast_agent/resources/examples/researcher/researcher-eval.py +1 -1
  26. fast_agent/resources/examples/researcher/researcher-imp.py +1 -1
  27. fast_agent/resources/examples/researcher/researcher.py +1 -1
  28. fast_agent/resources/examples/tensorzero/agent.py +1 -1
  29. fast_agent/resources/examples/tensorzero/image_demo.py +1 -1
  30. fast_agent/resources/examples/tensorzero/simple_agent.py +1 -1
  31. fast_agent/resources/examples/workflows/chaining.py +1 -1
  32. fast_agent/resources/examples/workflows/evaluator.py +1 -1
  33. fast_agent/resources/examples/workflows/human_input.py +1 -1
  34. fast_agent/resources/examples/workflows/orchestrator.py +1 -1
  35. fast_agent/resources/examples/workflows/parallel.py +1 -1
  36. fast_agent/resources/examples/workflows/router.py +1 -1
  37. fast_agent/resources/setup/agent.py +1 -1
  38. fast_agent/resources/setup/fastagent.config.yaml +2 -2
  39. fast_agent/ui/mcp_ui_utils.py +12 -1
  40. {fast_agent_mcp-0.3.3.dist-info → fast_agent_mcp-0.3.5.dist-info}/METADATA +40 -3
  41. {fast_agent_mcp-0.3.3.dist-info → fast_agent_mcp-0.3.5.dist-info}/RECORD +44 -42
  42. {fast_agent_mcp-0.3.3.dist-info → fast_agent_mcp-0.3.5.dist-info}/WHEEL +0 -0
  43. {fast_agent_mcp-0.3.3.dist-info → fast_agent_mcp-0.3.5.dist-info}/entry_points.txt +0 -0
  44. {fast_agent_mcp-0.3.3.dist-info → fast_agent_mcp-0.3.5.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,481 @@
1
+ """
2
+ OAuth v2.1 integration helpers for MCP client transports.
3
+
4
+ Provides token storage (in-memory and OS keyring), a local callback server
5
+ with paste-URL fallback, and a builder for OAuthClientProvider that can be
6
+ passed to SSE/HTTP transports as the `auth` parameter.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import threading
12
+ import time
13
+ from dataclasses import dataclass
14
+ from http.server import BaseHTTPRequestHandler, HTTPServer
15
+ from typing import TYPE_CHECKING, Any, Callable
16
+ from urllib.parse import parse_qs, urlparse
17
+
18
+ from mcp.client.auth import OAuthClientProvider, TokenStorage
19
+ from mcp.shared.auth import (
20
+ OAuthClientInformationFull,
21
+ OAuthClientMetadata,
22
+ OAuthToken,
23
+ )
24
+ from pydantic import AnyUrl
25
+
26
+ from fast_agent.core.logging.logger import get_logger
27
+ from fast_agent.ui import console
28
+
29
+ if TYPE_CHECKING:
30
+ from fast_agent.config import MCPServerSettings
31
+
32
+ logger = get_logger(__name__)
33
+
34
+
35
+ class InMemoryTokenStorage(TokenStorage):
36
+ """Non-persistent token storage (process memory only)."""
37
+
38
+ def __init__(self) -> None:
39
+ self._tokens: OAuthToken | None = None
40
+ self._client_info: OAuthClientInformationFull | None = None
41
+
42
+ async def get_tokens(self) -> OAuthToken | None:
43
+ return self._tokens
44
+
45
+ async def set_tokens(self, tokens: OAuthToken) -> None:
46
+ self._tokens = tokens
47
+
48
+ async def get_client_info(self) -> OAuthClientInformationFull | None:
49
+ return self._client_info
50
+
51
+ async def set_client_info(self, client_info: OAuthClientInformationFull) -> None:
52
+ self._client_info = client_info
53
+
54
+
55
+ @dataclass
56
+ class _CallbackResult:
57
+ authorization_code: str | None = None
58
+ state: str | None = None
59
+ error: str | None = None
60
+
61
+
62
+ class _CallbackHandler(BaseHTTPRequestHandler):
63
+ """HTTP handler to capture OAuth callback query params."""
64
+
65
+ def __init__(self, *args, result: _CallbackResult, expected_path: str, **kwargs):
66
+ self._result = result
67
+ self._expected_path = expected_path.rstrip("/") or "/callback"
68
+ super().__init__(*args, **kwargs)
69
+
70
+ def do_GET(self) -> None: # noqa: N802 - http.server signature
71
+ parsed = urlparse(self.path)
72
+
73
+ # Only accept the configured callback path
74
+ if (parsed.path.rstrip("/") or "/callback") != self._expected_path:
75
+ self.send_response(404)
76
+ self.end_headers()
77
+ return
78
+
79
+ params = parse_qs(parsed.query)
80
+ if "code" in params:
81
+ self._result.authorization_code = params["code"][0]
82
+ self._result.state = params.get("state", [None])[0]
83
+ self.send_response(200)
84
+ self.send_header("Content-Type", "text/html")
85
+ self.end_headers()
86
+ self.wfile.write(
87
+ b"""
88
+ <html><body>
89
+ <h1>Authorization Successful</h1>
90
+ <p>You can close this window.</p>
91
+ <script>setTimeout(() => window.close(), 1000);</script>
92
+ </body></html>
93
+ """
94
+ )
95
+ elif "error" in params:
96
+ self._result.error = params["error"][0]
97
+ self.send_response(400)
98
+ self.send_header("Content-Type", "text/html")
99
+ self.end_headers()
100
+ self.wfile.write(
101
+ f"""
102
+ <html><body>
103
+ <h1>Authorization Failed</h1>
104
+ <p>Error: {self._result.error}</p>
105
+ </body></html>
106
+ """.encode()
107
+ )
108
+ else:
109
+ self.send_response(404)
110
+ self.end_headers()
111
+
112
+ def log_message(self, fmt: str, *args: Any) -> None: # silence default logging
113
+ return
114
+
115
+
116
+ class _CallbackServer:
117
+ """Simple background HTTP server to receive a single OAuth callback."""
118
+
119
+ def __init__(self, port: int, path: str) -> None:
120
+ self._port = port
121
+ self._path = path.rstrip("/") or "/callback"
122
+ self._result = _CallbackResult()
123
+ self._server: HTTPServer | None = None
124
+ self._thread: threading.Thread | None = None
125
+
126
+ def _make_handler(self) -> Callable[..., BaseHTTPRequestHandler]:
127
+ result = self._result
128
+ expected_path = self._path
129
+
130
+ def handler(*args, **kwargs):
131
+ return _CallbackHandler(*args, result=result, expected_path=expected_path, **kwargs)
132
+
133
+ return handler
134
+
135
+ def start(self) -> None:
136
+ self._server = HTTPServer(("localhost", self._port), self._make_handler())
137
+ self._thread = threading.Thread(target=self._server.serve_forever, daemon=True)
138
+ self._thread.start()
139
+ logger.info(f"OAuth callback server listening on http://localhost:{self._port}{self._path}")
140
+
141
+ def stop(self) -> None:
142
+ if self._server:
143
+ try:
144
+ self._server.shutdown()
145
+ self._server.server_close()
146
+ except Exception:
147
+ pass
148
+ if self._thread:
149
+ self._thread.join(timeout=1)
150
+
151
+ def wait(self, timeout_seconds: int = 300) -> tuple[str, str | None]:
152
+ start = time.time()
153
+ while time.time() - start < timeout_seconds:
154
+ if self._result.authorization_code:
155
+ return self._result.authorization_code, self._result.state
156
+ if self._result.error:
157
+ raise RuntimeError(f"OAuth error: {self._result.error}")
158
+ time.sleep(0.1)
159
+ raise TimeoutError("Timeout waiting for OAuth callback")
160
+
161
+
162
+ def _derive_base_server_url(url: str | None) -> str | None:
163
+ """Derive the base server URL for OAuth discovery from an MCP endpoint URL.
164
+
165
+ - Strips a trailing "/mcp" or "/sse" path segment
166
+ - Ignores query and fragment parts entirely
167
+ """
168
+ if not url:
169
+ return None
170
+ try:
171
+ from urllib.parse import urlparse, urlunparse
172
+
173
+ parsed = urlparse(url)
174
+ # Normalize path without trailing slash
175
+ path = parsed.path or ""
176
+ path = path[:-1] if path.endswith("/") else path
177
+ # Remove one trailing segment if it is mcp or sse
178
+ for suffix in ("/mcp", "/sse"):
179
+ if path.endswith(suffix):
180
+ path = path[: -len(suffix)]
181
+ break
182
+ # Ensure path is at least '/'
183
+ if not path:
184
+ path = "/"
185
+ # Rebuild URL without query/fragment
186
+ clean = parsed._replace(path=path, params="", query="", fragment="")
187
+ base = urlunparse(clean)
188
+ # Drop trailing slash except for root
189
+ if base.endswith("/") and base.count("/") > 2:
190
+ base = base[:-1]
191
+ return base
192
+ except Exception:
193
+ return url
194
+
195
+
196
+ def compute_server_identity(server_config: MCPServerSettings) -> str:
197
+ """Compute a stable identity for token storage.
198
+
199
+ Prefer the normalized base server URL; fall back to configured name, then 'default'.
200
+ """
201
+ base = _derive_base_server_url(server_config.url)
202
+ if base:
203
+ return base
204
+ if server_config.name:
205
+ return server_config.name
206
+ return "default"
207
+
208
+
209
+ def keyring_has_token(server_config: MCPServerSettings) -> bool:
210
+ """Check if keyring has a token stored for this server."""
211
+ try:
212
+ import keyring
213
+
214
+ identity = compute_server_identity(server_config)
215
+ token_key = f"oauth:tokens:{identity}"
216
+ return keyring.get_password("fast-agent-mcp", token_key) is not None
217
+ except Exception:
218
+ return False
219
+
220
+
221
+ async def _print_authorization_link(auth_url: str) -> None:
222
+ """Emit a clickable authorization link using rich console markup."""
223
+ console.console.print("[bold]Open this link to authorize:[/bold]", markup=True)
224
+ console.console.print(f"[link={auth_url}]{auth_url}[/link]")
225
+ logger.info("OAuth authorization URL emitted to console")
226
+
227
+
228
+ class KeyringTokenStorage(TokenStorage):
229
+ """Token storage backed by the OS keychain using 'keyring'."""
230
+
231
+ def __init__(self, service_name: str, server_identity: str) -> None:
232
+ self._service = service_name
233
+ self._identity = server_identity
234
+
235
+ @property
236
+ def _token_key(self) -> str:
237
+ return f"oauth:tokens:{self._identity}"
238
+
239
+ @property
240
+ def _client_key(self) -> str:
241
+ return f"oauth:client_info:{self._identity}"
242
+
243
+ async def get_tokens(self) -> OAuthToken | None:
244
+ try:
245
+ import keyring
246
+
247
+ payload = keyring.get_password(self._service, self._token_key)
248
+ if not payload:
249
+ return None
250
+ return OAuthToken.model_validate_json(payload)
251
+ except Exception:
252
+ return None
253
+
254
+ async def set_tokens(self, tokens: OAuthToken) -> None:
255
+ try:
256
+ import keyring
257
+
258
+ keyring.set_password(self._service, self._token_key, tokens.model_dump_json())
259
+ # Update index
260
+ add_identity_to_index(self._service, self._identity)
261
+ except Exception:
262
+ pass
263
+
264
+ async def get_client_info(self) -> OAuthClientInformationFull | None:
265
+ try:
266
+ import keyring
267
+
268
+ payload = keyring.get_password(self._service, self._client_key)
269
+ if not payload:
270
+ return None
271
+ return OAuthClientInformationFull.model_validate_json(payload)
272
+ except Exception:
273
+ return None
274
+
275
+ async def set_client_info(self, client_info: OAuthClientInformationFull) -> None:
276
+ try:
277
+ import keyring
278
+
279
+ keyring.set_password(self._service, self._client_key, client_info.model_dump_json())
280
+ except Exception:
281
+ pass
282
+
283
+
284
+ # --- Keyring index helpers (to enable cross-platform token enumeration) ---
285
+
286
+ def _index_username() -> str:
287
+ return "oauth:index"
288
+
289
+
290
+ def _read_index(service: str) -> set[str]:
291
+ try:
292
+ import json
293
+
294
+ import keyring
295
+
296
+ raw = keyring.get_password(service, _index_username())
297
+ if not raw:
298
+ return set()
299
+ data = json.loads(raw)
300
+ if isinstance(data, list):
301
+ return set([str(x) for x in data])
302
+ return set()
303
+ except Exception:
304
+ return set()
305
+
306
+
307
+ def _write_index(service: str, identities: set[str]) -> None:
308
+ try:
309
+ import json
310
+
311
+ import keyring
312
+
313
+ payload = json.dumps(sorted(list(identities)))
314
+ keyring.set_password(service, _index_username(), payload)
315
+ except Exception:
316
+ pass
317
+
318
+
319
+ def add_identity_to_index(service: str, identity: str) -> None:
320
+ identities = _read_index(service)
321
+ if identity not in identities:
322
+ identities.add(identity)
323
+ _write_index(service, identities)
324
+
325
+
326
+ def remove_identity_from_index(service: str, identity: str) -> None:
327
+ identities = _read_index(service)
328
+ if identity in identities:
329
+ identities.remove(identity)
330
+ _write_index(service, identities)
331
+
332
+
333
+ def list_keyring_tokens(service: str = "fast-agent-mcp") -> list[str]:
334
+ """List identities with stored tokens in keyring (using our index).
335
+
336
+ Returns only identities that currently have a corresponding token entry.
337
+ """
338
+ try:
339
+ import keyring
340
+
341
+ identities = _read_index(service)
342
+ present: list[str] = []
343
+ for ident in sorted(identities):
344
+ tok_key = f"oauth:tokens:{ident}"
345
+ if keyring.get_password(service, tok_key):
346
+ present.append(ident)
347
+ return present
348
+ except Exception:
349
+ return []
350
+
351
+
352
+ def clear_keyring_token(identity: str, service: str = "fast-agent-mcp") -> bool:
353
+ """Remove token+client info for identity and update the index.
354
+
355
+ Returns True if anything was removed.
356
+ """
357
+ removed = False
358
+ try:
359
+ import keyring
360
+
361
+ tok_key = f"oauth:tokens:{identity}"
362
+ cli_key = f"oauth:client_info:{identity}"
363
+ try:
364
+ keyring.delete_password(service, tok_key)
365
+ removed = True
366
+ except Exception:
367
+ pass
368
+ try:
369
+ keyring.delete_password(service, cli_key)
370
+ removed = True or removed
371
+ except Exception:
372
+ pass
373
+ if removed:
374
+ remove_identity_from_index(service, identity)
375
+ except Exception:
376
+ return False
377
+ return removed
378
+
379
+
380
+ def build_oauth_provider(server_config: MCPServerSettings) -> OAuthClientProvider | None:
381
+ """
382
+ Build an OAuthClientProvider for the given server config if applicable.
383
+
384
+ Returns None for unsupported transports, or when disabled via config.
385
+ """
386
+ # Only for SSE/HTTP transports
387
+ if server_config.transport not in ("sse", "http"):
388
+ return None
389
+
390
+ # Determine if OAuth should be enabled. Default to True if no auth block provided
391
+ enable_oauth = True
392
+ redirect_port = 3030
393
+ redirect_path = "/callback"
394
+ scope_value: str | None = None
395
+ persist_mode: str = "keyring"
396
+
397
+ if server_config.auth is not None:
398
+ try:
399
+ enable_oauth = getattr(server_config.auth, "oauth", True)
400
+ redirect_port = getattr(server_config.auth, "redirect_port", 3030)
401
+ redirect_path = getattr(server_config.auth, "redirect_path", "/callback")
402
+ scope_field = getattr(server_config.auth, "scope", None)
403
+ persist_mode = getattr(server_config.auth, "persist", "keyring")
404
+ if isinstance(scope_field, list):
405
+ scope_value = " ".join(scope_field)
406
+ elif isinstance(scope_field, str):
407
+ scope_value = scope_field
408
+ except Exception:
409
+ logger.debug("Malformed auth configuration; using defaults.")
410
+
411
+ if not enable_oauth:
412
+ return None
413
+
414
+ base_url = _derive_base_server_url(server_config.url)
415
+ if not base_url:
416
+ # No usable URL -> cannot build provider
417
+ return None
418
+
419
+ # Construct client metadata with minimal defaults
420
+ redirect_uri = f"http://localhost:{redirect_port}{redirect_path}"
421
+ metadata_kwargs: dict[str, Any] = {
422
+ "client_name": "fast-agent",
423
+ "redirect_uris": [AnyUrl(redirect_uri)],
424
+ "grant_types": ["authorization_code", "refresh_token"],
425
+ "response_types": ["code"],
426
+ }
427
+ if scope_value:
428
+ metadata_kwargs["scope"] = scope_value
429
+
430
+ client_metadata = OAuthClientMetadata.model_validate(metadata_kwargs)
431
+
432
+ # Local callback server handler
433
+ async def _redirect_handler(authorization_url: str) -> None:
434
+ await _print_authorization_link(authorization_url)
435
+
436
+ async def _callback_handler() -> tuple[str, str | None]:
437
+ # Try local HTTP capture first
438
+ try:
439
+ server = _CallbackServer(port=redirect_port, path=redirect_path)
440
+ server.start()
441
+ try:
442
+ code, state = server.wait(timeout_seconds=300)
443
+ return code, state
444
+ finally:
445
+ server.stop()
446
+ except Exception as e:
447
+ # Fallback to paste-URL flow
448
+ logger.info(f"OAuth local callback server unavailable, fallback to paste flow: {e}")
449
+ try:
450
+ import sys
451
+
452
+ print("Paste the full callback URL after authorization:", file=sys.stderr)
453
+ callback_url = input("Callback URL: ").strip()
454
+ except Exception as ee:
455
+ raise RuntimeError(f"Failed to read callback URL from user: {ee}")
456
+
457
+ params = parse_qs(urlparse(callback_url).query)
458
+ code = params.get("code", [None])[0]
459
+ state = params.get("state", [None])[0]
460
+ if not code:
461
+ raise RuntimeError("Callback URL missing authorization code")
462
+ return code, state
463
+
464
+ # Choose storage
465
+ storage: TokenStorage
466
+ if persist_mode == "keyring":
467
+ identity = compute_server_identity(server_config)
468
+ # Update index on write via storage methods; creation here doesn't modify index yet.
469
+ storage = KeyringTokenStorage(service_name="fast-agent-mcp", server_identity=identity)
470
+ else:
471
+ storage = InMemoryTokenStorage()
472
+
473
+ provider = OAuthClientProvider(
474
+ server_url=base_url,
475
+ client_metadata=client_metadata,
476
+ storage=storage,
477
+ redirect_handler=_redirect_handler,
478
+ callback_handler=_callback_handler,
479
+ )
480
+
481
+ return provider
@@ -9,7 +9,7 @@ from __future__ import annotations
9
9
 
10
10
  from typing import TYPE_CHECKING, Any
11
11
 
12
- from fast_agent.agents.mcp_agent import McpAgent
12
+ from fast_agent.agents import McpAgent
13
13
  from fast_agent.mcp.ui_mixin import McpUIMixin
14
14
 
15
15
  if TYPE_CHECKING:
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
  from fast_agent.llm.fastagent_llm import RequestParams
5
5
 
6
6
  # Create the application
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # Create the application
6
6
  fast = FastAgent("Data Analysis (Roots)")
@@ -13,7 +13,7 @@ import asyncio
13
13
  from rich.console import Console
14
14
  from rich.panel import Panel
15
15
 
16
- from fast_agent.core.fastagent import FastAgent
16
+ from fast_agent import FastAgent
17
17
  from fast_agent.mcp.helpers.content_helpers import get_resource_text
18
18
 
19
19
  fast = FastAgent("Elicitation Forms Demo", quiet=True)
@@ -14,7 +14,7 @@ from game_character_handler import game_character_elicitation_handler
14
14
  from rich.console import Console
15
15
  from rich.panel import Panel
16
16
 
17
- from fast_agent.core.fastagent import FastAgent
17
+ from fast_agent import FastAgent
18
18
  from fast_agent.mcp.helpers.content_helpers import get_resource_text
19
19
 
20
20
  fast = FastAgent("Game Character Creator", quiet=True)
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # Create the application
6
6
  fast = FastAgent("fast-agent example")
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # Create the application
6
6
  fast = FastAgent("fast-agent agent_one (mcp server)")
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # Create the application
6
6
  fast = FastAgent("fast-agent agent_two (mcp client)")
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  agents = FastAgent(name="Researcher Agent (EO)")
6
6
 
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  agents = FastAgent(name="Enhanced Researcher")
6
6
 
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # from rich import print
6
6
 
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
  from fast_agent.llm.request_params import RequestParams
5
5
 
6
6
  # Explicitly provide the path to the config file in the current directory
@@ -6,7 +6,7 @@ from typing import List, Union
6
6
 
7
7
  from mcp.types import ImageContent, TextContent
8
8
 
9
- from fast_agent.core.fastagent import FastAgent
9
+ from fast_agent import FastAgent
10
10
  from fast_agent.core.prompt import Prompt
11
11
  from fast_agent.llm.request_params import RequestParams
12
12
 
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  CONFIG_FILE = "fastagent.config.yaml"
6
6
  fast = FastAgent("fast-agent example", config_path=CONFIG_FILE, ignore_unknown_args=True)
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # Create the application
6
6
  fast = FastAgent("Agent Chaining")
@@ -4,7 +4,7 @@ This demonstrates creating an optimizer and evaluator to iteratively improve con
4
4
 
5
5
  import asyncio
6
6
 
7
- from fast_agent.core.fastagent import FastAgent
7
+ from fast_agent import FastAgent
8
8
 
9
9
  # Create the application
10
10
  fast = FastAgent("Evaluator-Optimizer")
@@ -4,7 +4,7 @@ Agent which demonstrates Human Input tool
4
4
 
5
5
  import asyncio
6
6
 
7
- from fast_agent.core.fastagent import FastAgent
7
+ from fast_agent import FastAgent
8
8
 
9
9
  # Create the application
10
10
  fast = FastAgent("Human Input")
@@ -4,7 +4,7 @@ This demonstrates creating multiple agents and an orchestrator to coordinate the
4
4
 
5
5
  import asyncio
6
6
 
7
- from fast_agent.core.fastagent import FastAgent
7
+ from fast_agent import FastAgent
8
8
 
9
9
  # Create the application
10
10
  fast = FastAgent("Orchestrator-Workers")
@@ -5,7 +5,7 @@ Parallel Workflow showing Fan Out and Fan In agents, using different models
5
5
  import asyncio
6
6
  from pathlib import Path
7
7
 
8
- from fast_agent.core.fastagent import FastAgent
8
+ from fast_agent import FastAgent
9
9
  from fast_agent.core.prompt import Prompt
10
10
 
11
11
  # Create the application
@@ -9,7 +9,7 @@ import asyncio
9
9
 
10
10
  from rich.console import Console
11
11
 
12
- from fast_agent.core.fastagent import FastAgent
12
+ from fast_agent import FastAgent
13
13
 
14
14
  # Create the application
15
15
  fast = FastAgent(
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from fast_agent.core.fastagent import FastAgent
3
+ from fast_agent import FastAgent
4
4
 
5
5
  # Create the application
6
6
  fast = FastAgent("fast-agent example")