fast-agent-mcp 0.4.7__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.
- fast_agent/__init__.py +183 -0
- fast_agent/acp/__init__.py +19 -0
- fast_agent/acp/acp_aware_mixin.py +304 -0
- fast_agent/acp/acp_context.py +437 -0
- fast_agent/acp/content_conversion.py +136 -0
- fast_agent/acp/filesystem_runtime.py +427 -0
- fast_agent/acp/permission_store.py +269 -0
- fast_agent/acp/server/__init__.py +5 -0
- fast_agent/acp/server/agent_acp_server.py +1472 -0
- fast_agent/acp/slash_commands.py +1050 -0
- fast_agent/acp/terminal_runtime.py +408 -0
- fast_agent/acp/tool_permission_adapter.py +125 -0
- fast_agent/acp/tool_permissions.py +474 -0
- fast_agent/acp/tool_progress.py +814 -0
- fast_agent/agents/__init__.py +85 -0
- fast_agent/agents/agent_types.py +64 -0
- fast_agent/agents/llm_agent.py +350 -0
- fast_agent/agents/llm_decorator.py +1139 -0
- fast_agent/agents/mcp_agent.py +1337 -0
- fast_agent/agents/tool_agent.py +271 -0
- fast_agent/agents/workflow/agents_as_tools_agent.py +849 -0
- fast_agent/agents/workflow/chain_agent.py +212 -0
- fast_agent/agents/workflow/evaluator_optimizer.py +380 -0
- fast_agent/agents/workflow/iterative_planner.py +652 -0
- fast_agent/agents/workflow/maker_agent.py +379 -0
- fast_agent/agents/workflow/orchestrator_models.py +218 -0
- fast_agent/agents/workflow/orchestrator_prompts.py +248 -0
- fast_agent/agents/workflow/parallel_agent.py +250 -0
- fast_agent/agents/workflow/router_agent.py +353 -0
- fast_agent/cli/__init__.py +0 -0
- fast_agent/cli/__main__.py +73 -0
- fast_agent/cli/commands/acp.py +159 -0
- fast_agent/cli/commands/auth.py +404 -0
- fast_agent/cli/commands/check_config.py +783 -0
- fast_agent/cli/commands/go.py +514 -0
- fast_agent/cli/commands/quickstart.py +557 -0
- fast_agent/cli/commands/serve.py +143 -0
- fast_agent/cli/commands/server_helpers.py +114 -0
- fast_agent/cli/commands/setup.py +174 -0
- fast_agent/cli/commands/url_parser.py +190 -0
- fast_agent/cli/constants.py +40 -0
- fast_agent/cli/main.py +115 -0
- fast_agent/cli/terminal.py +24 -0
- fast_agent/config.py +798 -0
- fast_agent/constants.py +41 -0
- fast_agent/context.py +279 -0
- fast_agent/context_dependent.py +50 -0
- fast_agent/core/__init__.py +92 -0
- fast_agent/core/agent_app.py +448 -0
- fast_agent/core/core_app.py +137 -0
- fast_agent/core/direct_decorators.py +784 -0
- fast_agent/core/direct_factory.py +620 -0
- fast_agent/core/error_handling.py +27 -0
- fast_agent/core/exceptions.py +90 -0
- fast_agent/core/executor/__init__.py +0 -0
- fast_agent/core/executor/executor.py +280 -0
- fast_agent/core/executor/task_registry.py +32 -0
- fast_agent/core/executor/workflow_signal.py +324 -0
- fast_agent/core/fastagent.py +1186 -0
- fast_agent/core/logging/__init__.py +5 -0
- fast_agent/core/logging/events.py +138 -0
- fast_agent/core/logging/json_serializer.py +164 -0
- fast_agent/core/logging/listeners.py +309 -0
- fast_agent/core/logging/logger.py +278 -0
- fast_agent/core/logging/transport.py +481 -0
- fast_agent/core/prompt.py +9 -0
- fast_agent/core/prompt_templates.py +183 -0
- fast_agent/core/validation.py +326 -0
- fast_agent/event_progress.py +62 -0
- fast_agent/history/history_exporter.py +49 -0
- fast_agent/human_input/__init__.py +47 -0
- fast_agent/human_input/elicitation_handler.py +123 -0
- fast_agent/human_input/elicitation_state.py +33 -0
- fast_agent/human_input/form_elements.py +59 -0
- fast_agent/human_input/form_fields.py +256 -0
- fast_agent/human_input/simple_form.py +113 -0
- fast_agent/human_input/types.py +40 -0
- fast_agent/interfaces.py +310 -0
- fast_agent/llm/__init__.py +9 -0
- fast_agent/llm/cancellation.py +22 -0
- fast_agent/llm/fastagent_llm.py +931 -0
- fast_agent/llm/internal/passthrough.py +161 -0
- fast_agent/llm/internal/playback.py +129 -0
- fast_agent/llm/internal/silent.py +41 -0
- fast_agent/llm/internal/slow.py +38 -0
- fast_agent/llm/memory.py +275 -0
- fast_agent/llm/model_database.py +490 -0
- fast_agent/llm/model_factory.py +388 -0
- fast_agent/llm/model_info.py +102 -0
- fast_agent/llm/prompt_utils.py +155 -0
- fast_agent/llm/provider/anthropic/anthropic_utils.py +84 -0
- fast_agent/llm/provider/anthropic/cache_planner.py +56 -0
- fast_agent/llm/provider/anthropic/llm_anthropic.py +796 -0
- fast_agent/llm/provider/anthropic/multipart_converter_anthropic.py +462 -0
- fast_agent/llm/provider/bedrock/bedrock_utils.py +218 -0
- fast_agent/llm/provider/bedrock/llm_bedrock.py +2207 -0
- fast_agent/llm/provider/bedrock/multipart_converter_bedrock.py +84 -0
- fast_agent/llm/provider/google/google_converter.py +466 -0
- fast_agent/llm/provider/google/llm_google_native.py +681 -0
- fast_agent/llm/provider/openai/llm_aliyun.py +31 -0
- fast_agent/llm/provider/openai/llm_azure.py +143 -0
- fast_agent/llm/provider/openai/llm_deepseek.py +76 -0
- fast_agent/llm/provider/openai/llm_generic.py +35 -0
- fast_agent/llm/provider/openai/llm_google_oai.py +32 -0
- fast_agent/llm/provider/openai/llm_groq.py +42 -0
- fast_agent/llm/provider/openai/llm_huggingface.py +85 -0
- fast_agent/llm/provider/openai/llm_openai.py +1195 -0
- fast_agent/llm/provider/openai/llm_openai_compatible.py +138 -0
- fast_agent/llm/provider/openai/llm_openrouter.py +45 -0
- fast_agent/llm/provider/openai/llm_tensorzero_openai.py +128 -0
- fast_agent/llm/provider/openai/llm_xai.py +38 -0
- fast_agent/llm/provider/openai/multipart_converter_openai.py +561 -0
- fast_agent/llm/provider/openai/openai_multipart.py +169 -0
- fast_agent/llm/provider/openai/openai_utils.py +67 -0
- fast_agent/llm/provider/openai/responses.py +133 -0
- fast_agent/llm/provider_key_manager.py +139 -0
- fast_agent/llm/provider_types.py +34 -0
- fast_agent/llm/request_params.py +61 -0
- fast_agent/llm/sampling_converter.py +98 -0
- fast_agent/llm/stream_types.py +9 -0
- fast_agent/llm/usage_tracking.py +445 -0
- fast_agent/mcp/__init__.py +56 -0
- fast_agent/mcp/common.py +26 -0
- fast_agent/mcp/elicitation_factory.py +84 -0
- fast_agent/mcp/elicitation_handlers.py +164 -0
- fast_agent/mcp/gen_client.py +83 -0
- fast_agent/mcp/helpers/__init__.py +36 -0
- fast_agent/mcp/helpers/content_helpers.py +352 -0
- fast_agent/mcp/helpers/server_config_helpers.py +25 -0
- fast_agent/mcp/hf_auth.py +147 -0
- fast_agent/mcp/interfaces.py +92 -0
- fast_agent/mcp/logger_textio.py +108 -0
- fast_agent/mcp/mcp_agent_client_session.py +411 -0
- fast_agent/mcp/mcp_aggregator.py +2175 -0
- fast_agent/mcp/mcp_connection_manager.py +723 -0
- fast_agent/mcp/mcp_content.py +262 -0
- fast_agent/mcp/mime_utils.py +108 -0
- fast_agent/mcp/oauth_client.py +509 -0
- fast_agent/mcp/prompt.py +159 -0
- fast_agent/mcp/prompt_message_extended.py +155 -0
- fast_agent/mcp/prompt_render.py +84 -0
- fast_agent/mcp/prompt_serialization.py +580 -0
- fast_agent/mcp/prompts/__init__.py +0 -0
- fast_agent/mcp/prompts/__main__.py +7 -0
- fast_agent/mcp/prompts/prompt_constants.py +18 -0
- fast_agent/mcp/prompts/prompt_helpers.py +238 -0
- fast_agent/mcp/prompts/prompt_load.py +186 -0
- fast_agent/mcp/prompts/prompt_server.py +552 -0
- fast_agent/mcp/prompts/prompt_template.py +438 -0
- fast_agent/mcp/resource_utils.py +215 -0
- fast_agent/mcp/sampling.py +200 -0
- fast_agent/mcp/server/__init__.py +4 -0
- fast_agent/mcp/server/agent_server.py +613 -0
- fast_agent/mcp/skybridge.py +44 -0
- fast_agent/mcp/sse_tracking.py +287 -0
- fast_agent/mcp/stdio_tracking_simple.py +59 -0
- fast_agent/mcp/streamable_http_tracking.py +309 -0
- fast_agent/mcp/tool_execution_handler.py +137 -0
- fast_agent/mcp/tool_permission_handler.py +88 -0
- fast_agent/mcp/transport_tracking.py +634 -0
- fast_agent/mcp/types.py +24 -0
- fast_agent/mcp/ui_agent.py +48 -0
- fast_agent/mcp/ui_mixin.py +209 -0
- fast_agent/mcp_server_registry.py +89 -0
- fast_agent/py.typed +0 -0
- fast_agent/resources/examples/data-analysis/analysis-campaign.py +189 -0
- fast_agent/resources/examples/data-analysis/analysis.py +68 -0
- fast_agent/resources/examples/data-analysis/fastagent.config.yaml +41 -0
- fast_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +1471 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +297 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
- fast_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
- fast_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
- fast_agent/resources/examples/mcp/elicitations/forms_demo.py +107 -0
- fast_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
- fast_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
- fast_agent/resources/examples/mcp/elicitations/tool_call.py +21 -0
- fast_agent/resources/examples/mcp/state-transfer/agent_one.py +18 -0
- fast_agent/resources/examples/mcp/state-transfer/agent_two.py +18 -0
- fast_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +27 -0
- fast_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +15 -0
- fast_agent/resources/examples/researcher/fastagent.config.yaml +61 -0
- fast_agent/resources/examples/researcher/researcher-eval.py +53 -0
- fast_agent/resources/examples/researcher/researcher-imp.py +189 -0
- fast_agent/resources/examples/researcher/researcher.py +36 -0
- fast_agent/resources/examples/tensorzero/.env.sample +2 -0
- fast_agent/resources/examples/tensorzero/Makefile +31 -0
- fast_agent/resources/examples/tensorzero/README.md +56 -0
- fast_agent/resources/examples/tensorzero/agent.py +35 -0
- fast_agent/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- fast_agent/resources/examples/tensorzero/demo_images/crab.png +0 -0
- fast_agent/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- fast_agent/resources/examples/tensorzero/docker-compose.yml +105 -0
- fast_agent/resources/examples/tensorzero/fastagent.config.yaml +19 -0
- fast_agent/resources/examples/tensorzero/image_demo.py +67 -0
- fast_agent/resources/examples/tensorzero/mcp_server/Dockerfile +25 -0
- fast_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
- fast_agent/resources/examples/tensorzero/mcp_server/mcp_server.py +31 -0
- fast_agent/resources/examples/tensorzero/mcp_server/pyproject.toml +11 -0
- fast_agent/resources/examples/tensorzero/simple_agent.py +25 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
- fast_agent/resources/examples/workflows/agents_as_tools_extended.py +73 -0
- fast_agent/resources/examples/workflows/agents_as_tools_simple.py +50 -0
- fast_agent/resources/examples/workflows/chaining.py +37 -0
- fast_agent/resources/examples/workflows/evaluator.py +77 -0
- fast_agent/resources/examples/workflows/fastagent.config.yaml +26 -0
- fast_agent/resources/examples/workflows/graded_report.md +89 -0
- fast_agent/resources/examples/workflows/human_input.py +28 -0
- fast_agent/resources/examples/workflows/maker.py +156 -0
- fast_agent/resources/examples/workflows/orchestrator.py +70 -0
- fast_agent/resources/examples/workflows/parallel.py +56 -0
- fast_agent/resources/examples/workflows/router.py +69 -0
- fast_agent/resources/examples/workflows/short_story.md +13 -0
- fast_agent/resources/examples/workflows/short_story.txt +19 -0
- fast_agent/resources/setup/.gitignore +30 -0
- fast_agent/resources/setup/agent.py +28 -0
- fast_agent/resources/setup/fastagent.config.yaml +65 -0
- fast_agent/resources/setup/fastagent.secrets.yaml.example +38 -0
- fast_agent/resources/setup/pyproject.toml.tmpl +23 -0
- fast_agent/skills/__init__.py +9 -0
- fast_agent/skills/registry.py +235 -0
- fast_agent/tools/elicitation.py +369 -0
- fast_agent/tools/shell_runtime.py +402 -0
- fast_agent/types/__init__.py +59 -0
- fast_agent/types/conversation_summary.py +294 -0
- fast_agent/types/llm_stop_reason.py +78 -0
- fast_agent/types/message_search.py +249 -0
- fast_agent/ui/__init__.py +38 -0
- fast_agent/ui/console.py +59 -0
- fast_agent/ui/console_display.py +1080 -0
- fast_agent/ui/elicitation_form.py +946 -0
- fast_agent/ui/elicitation_style.py +59 -0
- fast_agent/ui/enhanced_prompt.py +1400 -0
- fast_agent/ui/history_display.py +734 -0
- fast_agent/ui/interactive_prompt.py +1199 -0
- fast_agent/ui/markdown_helpers.py +104 -0
- fast_agent/ui/markdown_truncator.py +1004 -0
- fast_agent/ui/mcp_display.py +857 -0
- fast_agent/ui/mcp_ui_utils.py +235 -0
- fast_agent/ui/mermaid_utils.py +169 -0
- fast_agent/ui/message_primitives.py +50 -0
- fast_agent/ui/notification_tracker.py +205 -0
- fast_agent/ui/plain_text_truncator.py +68 -0
- fast_agent/ui/progress_display.py +10 -0
- fast_agent/ui/rich_progress.py +195 -0
- fast_agent/ui/streaming.py +774 -0
- fast_agent/ui/streaming_buffer.py +449 -0
- fast_agent/ui/tool_display.py +422 -0
- fast_agent/ui/usage_display.py +204 -0
- fast_agent/utils/__init__.py +5 -0
- fast_agent/utils/reasoning_stream_parser.py +77 -0
- fast_agent/utils/time.py +22 -0
- fast_agent/workflow_telemetry.py +261 -0
- fast_agent_mcp-0.4.7.dist-info/METADATA +788 -0
- fast_agent_mcp-0.4.7.dist-info/RECORD +261 -0
- fast_agent_mcp-0.4.7.dist-info/WHEEL +4 -0
- fast_agent_mcp-0.4.7.dist-info/entry_points.txt +7 -0
- fast_agent_mcp-0.4.7.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Model database for LLM parameters.
|
|
3
|
+
|
|
4
|
+
This module provides a centralized lookup for model parameters including
|
|
5
|
+
context windows, max output tokens, and supported tokenization types.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ModelParameters(BaseModel):
|
|
14
|
+
"""Configuration parameters for a specific model"""
|
|
15
|
+
|
|
16
|
+
context_window: int
|
|
17
|
+
"""Maximum context window size in tokens"""
|
|
18
|
+
|
|
19
|
+
max_output_tokens: int
|
|
20
|
+
"""Maximum output tokens the model can generate"""
|
|
21
|
+
|
|
22
|
+
tokenizes: list[str]
|
|
23
|
+
"""List of supported content types for tokenization"""
|
|
24
|
+
|
|
25
|
+
json_mode: None | str = "schema"
|
|
26
|
+
"""Structured output style. 'schema', 'object' or None for unsupported """
|
|
27
|
+
|
|
28
|
+
reasoning: None | str = None
|
|
29
|
+
"""Reasoning output style. 'tags' if enclosed in <thinking> tags, 'none' if not used"""
|
|
30
|
+
|
|
31
|
+
stream_mode: Literal["openai", "manual"] = "openai"
|
|
32
|
+
"""Determines how streaming deltas should be processed."""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ModelDatabase:
|
|
36
|
+
"""Centralized model configuration database"""
|
|
37
|
+
|
|
38
|
+
# Common parameter sets
|
|
39
|
+
OPENAI_MULTIMODAL = ["text/plain", "image/jpeg", "image/png", "image/webp", "application/pdf"]
|
|
40
|
+
OPENAI_VISION = ["text/plain", "image/jpeg", "image/png", "image/webp"]
|
|
41
|
+
ANTHROPIC_MULTIMODAL = [
|
|
42
|
+
"text/plain",
|
|
43
|
+
"image/jpeg",
|
|
44
|
+
"image/png",
|
|
45
|
+
"image/webp",
|
|
46
|
+
"application/pdf",
|
|
47
|
+
]
|
|
48
|
+
GOOGLE_MULTIMODAL = [
|
|
49
|
+
"text/plain",
|
|
50
|
+
"image/jpeg",
|
|
51
|
+
"image/png",
|
|
52
|
+
"image/webp",
|
|
53
|
+
"image/gif",
|
|
54
|
+
"application/pdf",
|
|
55
|
+
# Audio formats
|
|
56
|
+
"audio/wav",
|
|
57
|
+
"audio/mpeg", # Official MP3 MIME type
|
|
58
|
+
"audio/mp3", # Common alias
|
|
59
|
+
"audio/aac",
|
|
60
|
+
"audio/ogg",
|
|
61
|
+
"audio/flac",
|
|
62
|
+
"audio/webm",
|
|
63
|
+
# Video formats (MP4, AVI, FLV, MOV, MPEG, MPG, WebM)
|
|
64
|
+
"video/mp4",
|
|
65
|
+
"video/x-msvideo", # AVI
|
|
66
|
+
"video/x-flv", # FLV
|
|
67
|
+
"video/quicktime", # MOV
|
|
68
|
+
"video/mpeg", # MPEG, MPG
|
|
69
|
+
"video/webm",
|
|
70
|
+
]
|
|
71
|
+
QWEN_MULTIMODAL = ["text/plain", "image/jpeg", "image/png", "image/webp"]
|
|
72
|
+
XAI_VISION = ["text/plain", "image/jpeg", "image/png", "image/webp"]
|
|
73
|
+
TEXT_ONLY = ["text/plain"]
|
|
74
|
+
|
|
75
|
+
# Common parameter configurations
|
|
76
|
+
OPENAI_STANDARD = ModelParameters(
|
|
77
|
+
context_window=128000, max_output_tokens=16384, tokenizes=OPENAI_MULTIMODAL
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
OPENAI_4_1_STANDARD = ModelParameters(
|
|
81
|
+
context_window=1047576, max_output_tokens=32768, tokenizes=OPENAI_MULTIMODAL
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
OPENAI_O_SERIES = ModelParameters(
|
|
85
|
+
context_window=200000,
|
|
86
|
+
max_output_tokens=100000,
|
|
87
|
+
tokenizes=OPENAI_VISION,
|
|
88
|
+
reasoning="openai",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
ANTHROPIC_LEGACY = ModelParameters(
|
|
92
|
+
context_window=200000, max_output_tokens=4096, tokenizes=ANTHROPIC_MULTIMODAL
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
ANTHROPIC_35_SERIES = ModelParameters(
|
|
96
|
+
context_window=200000, max_output_tokens=8192, tokenizes=ANTHROPIC_MULTIMODAL
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# TODO--- TO USE 64,000 NEED TO SUPPORT STREAMING
|
|
100
|
+
ANTHROPIC_37_SERIES = ModelParameters(
|
|
101
|
+
context_window=200000, max_output_tokens=16384, tokenizes=ANTHROPIC_MULTIMODAL
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
QWEN_STANDARD = ModelParameters(
|
|
105
|
+
context_window=32000,
|
|
106
|
+
max_output_tokens=8192,
|
|
107
|
+
tokenizes=QWEN_MULTIMODAL,
|
|
108
|
+
json_mode="object",
|
|
109
|
+
)
|
|
110
|
+
QWEN3_REASONER = ModelParameters(
|
|
111
|
+
context_window=131072,
|
|
112
|
+
max_output_tokens=16384,
|
|
113
|
+
tokenizes=TEXT_ONLY,
|
|
114
|
+
json_mode="object",
|
|
115
|
+
reasoning="tags",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
FAST_AGENT_STANDARD = ModelParameters(
|
|
119
|
+
context_window=1000000, max_output_tokens=100000, tokenizes=TEXT_ONLY
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
OPENAI_4_1_SERIES = ModelParameters(
|
|
123
|
+
context_window=1047576, max_output_tokens=32768, tokenizes=OPENAI_MULTIMODAL
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
OPENAI_4O_SERIES = ModelParameters(
|
|
127
|
+
context_window=128000, max_output_tokens=16384, tokenizes=OPENAI_VISION
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
OPENAI_O3_SERIES = ModelParameters(
|
|
131
|
+
context_window=200000,
|
|
132
|
+
max_output_tokens=100000,
|
|
133
|
+
tokenizes=OPENAI_MULTIMODAL,
|
|
134
|
+
reasoning="openai",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
OPENAI_O3_MINI_SERIES = ModelParameters(
|
|
138
|
+
context_window=200000,
|
|
139
|
+
max_output_tokens=100000,
|
|
140
|
+
tokenizes=TEXT_ONLY,
|
|
141
|
+
reasoning="openai",
|
|
142
|
+
)
|
|
143
|
+
OPENAI_GPT_OSS_SERIES = ModelParameters(
|
|
144
|
+
context_window=131072,
|
|
145
|
+
max_output_tokens=32766,
|
|
146
|
+
tokenizes=TEXT_ONLY,
|
|
147
|
+
json_mode="object",
|
|
148
|
+
reasoning="gpt_oss",
|
|
149
|
+
)
|
|
150
|
+
OPENAI_GPT_5 = ModelParameters(
|
|
151
|
+
context_window=400000,
|
|
152
|
+
max_output_tokens=128000,
|
|
153
|
+
tokenizes=OPENAI_MULTIMODAL,
|
|
154
|
+
reasoning="openai",
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
ANTHROPIC_OPUS_4_VERSIONED = ModelParameters(
|
|
158
|
+
context_window=200000, max_output_tokens=32000, tokenizes=ANTHROPIC_MULTIMODAL
|
|
159
|
+
)
|
|
160
|
+
ANTHROPIC_SONNET_4_VERSIONED = ModelParameters(
|
|
161
|
+
context_window=200000, max_output_tokens=64000, tokenizes=ANTHROPIC_MULTIMODAL
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
DEEPSEEK_CHAT_STANDARD = ModelParameters(
|
|
165
|
+
context_window=65536, max_output_tokens=8192, tokenizes=TEXT_ONLY
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
DEEPSEEK_REASONER = ModelParameters(
|
|
169
|
+
context_window=65536, max_output_tokens=32768, tokenizes=TEXT_ONLY
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
DEEPSEEK_DISTILL = ModelParameters(
|
|
173
|
+
context_window=131072,
|
|
174
|
+
max_output_tokens=131072,
|
|
175
|
+
tokenizes=TEXT_ONLY,
|
|
176
|
+
json_mode="object",
|
|
177
|
+
reasoning="tags",
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
GEMINI_STANDARD = ModelParameters(
|
|
181
|
+
context_window=1_048_576, max_output_tokens=65_536, tokenizes=GOOGLE_MULTIMODAL
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
GEMINI_2_FLASH = ModelParameters(
|
|
185
|
+
context_window=1_048_576, max_output_tokens=8192, tokenizes=GOOGLE_MULTIMODAL
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# 31/08/25 switched to object mode (even though groq says schema supported and used to work..)
|
|
189
|
+
KIMI_MOONSHOT = ModelParameters(
|
|
190
|
+
context_window=262144,
|
|
191
|
+
max_output_tokens=16384,
|
|
192
|
+
tokenizes=TEXT_ONLY,
|
|
193
|
+
json_mode="object",
|
|
194
|
+
)
|
|
195
|
+
KIMI_MOONSHOT_THINKING = ModelParameters(
|
|
196
|
+
context_window=262144,
|
|
197
|
+
max_output_tokens=16384,
|
|
198
|
+
tokenizes=TEXT_ONLY,
|
|
199
|
+
json_mode="object",
|
|
200
|
+
reasoning="reasoning_content",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# FIXME: xAI has not documented the max output tokens for Grok 4. Using Grok 3 as a placeholder. Will need to update when available (if ever)
|
|
204
|
+
GROK_4 = ModelParameters(context_window=256000, max_output_tokens=16385, tokenizes=TEXT_ONLY)
|
|
205
|
+
|
|
206
|
+
GROK_4_VLM = ModelParameters(
|
|
207
|
+
context_window=2000000, max_output_tokens=16385, tokenizes=XAI_VISION
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Source for Grok 3 max output: https://www.reddit.com/r/grok/comments/1j7209p/exploring_grok_3_beta_output_capacity_a_simple/
|
|
211
|
+
# xAI does not document Grok 3 max output tokens, using the above source as a reference.
|
|
212
|
+
GROK_3 = ModelParameters(context_window=131072, max_output_tokens=16385, tokenizes=TEXT_ONLY)
|
|
213
|
+
|
|
214
|
+
# H U G G I N G F A C E - max output tokens are not documented, using 16k as a reasonable default
|
|
215
|
+
GLM_46 = ModelParameters(
|
|
216
|
+
context_window=202752,
|
|
217
|
+
max_output_tokens=8192,
|
|
218
|
+
tokenizes=TEXT_ONLY,
|
|
219
|
+
json_mode="object",
|
|
220
|
+
reasoning="reasoning_content",
|
|
221
|
+
stream_mode="manual",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
HF_PROVIDER_DEEPSEEK31 = ModelParameters(
|
|
225
|
+
context_window=163_800, max_output_tokens=8192, tokenizes=TEXT_ONLY
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
HF_PROVIDER_DEEPSEEK32 = ModelParameters(
|
|
229
|
+
context_window=163_800,
|
|
230
|
+
max_output_tokens=8192,
|
|
231
|
+
tokenizes=TEXT_ONLY,
|
|
232
|
+
reasoning="gpt_oss",
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
HF_PROVIDER_QWEN3_NEXT = ModelParameters(
|
|
236
|
+
context_window=262_000, max_output_tokens=8192, tokenizes=TEXT_ONLY
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
# Model configuration database
|
|
240
|
+
# KEEP ALL LOWER CASE KEYS
|
|
241
|
+
MODELS: dict[str, ModelParameters] = {
|
|
242
|
+
# internal models
|
|
243
|
+
"passthrough": FAST_AGENT_STANDARD,
|
|
244
|
+
"silent": FAST_AGENT_STANDARD,
|
|
245
|
+
"playback": FAST_AGENT_STANDARD,
|
|
246
|
+
"slow": FAST_AGENT_STANDARD,
|
|
247
|
+
# aliyun models
|
|
248
|
+
"qwen-turbo": QWEN_STANDARD,
|
|
249
|
+
"qwen-plus": QWEN_STANDARD,
|
|
250
|
+
"qwen-max": QWEN_STANDARD,
|
|
251
|
+
"qwen-long": ModelParameters(
|
|
252
|
+
context_window=10000000, max_output_tokens=8192, tokenizes=TEXT_ONLY
|
|
253
|
+
),
|
|
254
|
+
# OpenAI Models (vanilla aliases and versioned)
|
|
255
|
+
"gpt-4.1": OPENAI_4_1_SERIES,
|
|
256
|
+
"gpt-4.1-mini": OPENAI_4_1_SERIES,
|
|
257
|
+
"gpt-4.1-nano": OPENAI_4_1_SERIES,
|
|
258
|
+
"gpt-4.1-2025-04-14": OPENAI_4_1_SERIES,
|
|
259
|
+
"gpt-4.1-mini-2025-04-14": OPENAI_4_1_SERIES,
|
|
260
|
+
"gpt-4.1-nano-2025-04-14": OPENAI_4_1_SERIES,
|
|
261
|
+
"gpt-4o": OPENAI_4O_SERIES,
|
|
262
|
+
"gpt-4o-2024-11-20": OPENAI_4O_SERIES,
|
|
263
|
+
"gpt-4o-mini-2024-07-18": OPENAI_4O_SERIES,
|
|
264
|
+
"o1": OPENAI_O_SERIES,
|
|
265
|
+
"o1-2024-12-17": OPENAI_O_SERIES,
|
|
266
|
+
"o3": OPENAI_O3_SERIES,
|
|
267
|
+
"o3-pro": ModelParameters(
|
|
268
|
+
context_window=200_000, max_output_tokens=100_000, tokenizes=TEXT_ONLY
|
|
269
|
+
),
|
|
270
|
+
"o3-mini": OPENAI_O3_MINI_SERIES,
|
|
271
|
+
"o4-mini": OPENAI_O3_SERIES,
|
|
272
|
+
"o3-2025-04-16": OPENAI_O3_SERIES,
|
|
273
|
+
"o3-mini-2025-01-31": OPENAI_O3_MINI_SERIES,
|
|
274
|
+
"o4-mini-2025-04-16": OPENAI_O3_SERIES,
|
|
275
|
+
"gpt-5": OPENAI_GPT_5,
|
|
276
|
+
"gpt-5-mini": OPENAI_GPT_5,
|
|
277
|
+
"gpt-5-nano": OPENAI_GPT_5,
|
|
278
|
+
"gpt-5.1": OPENAI_GPT_5,
|
|
279
|
+
"gpt-5.1-mini": OPENAI_GPT_5, # pre-emptive
|
|
280
|
+
"gpt-5.1-nano": OPENAI_GPT_5, # pre-emptive
|
|
281
|
+
# Anthropic Models
|
|
282
|
+
"claude-3-haiku": ANTHROPIC_35_SERIES,
|
|
283
|
+
"claude-3-haiku-20240307": ANTHROPIC_LEGACY,
|
|
284
|
+
"claude-3-sonnet": ANTHROPIC_LEGACY,
|
|
285
|
+
"claude-3-opus": ANTHROPIC_LEGACY,
|
|
286
|
+
"claude-3-opus-20240229": ANTHROPIC_LEGACY,
|
|
287
|
+
"claude-3-opus-latest": ANTHROPIC_LEGACY,
|
|
288
|
+
"claude-3-5-haiku": ANTHROPIC_35_SERIES,
|
|
289
|
+
"claude-3-5-haiku-20241022": ANTHROPIC_35_SERIES,
|
|
290
|
+
"claude-3-5-haiku-latest": ANTHROPIC_35_SERIES,
|
|
291
|
+
"claude-3-sonnet-20240229": ANTHROPIC_LEGACY,
|
|
292
|
+
"claude-3-5-sonnet": ANTHROPIC_35_SERIES,
|
|
293
|
+
"claude-3-5-sonnet-20240620": ANTHROPIC_35_SERIES,
|
|
294
|
+
"claude-3-5-sonnet-20241022": ANTHROPIC_35_SERIES,
|
|
295
|
+
"claude-3-5-sonnet-latest": ANTHROPIC_35_SERIES,
|
|
296
|
+
"claude-3-7-sonnet": ANTHROPIC_37_SERIES,
|
|
297
|
+
"claude-3-7-sonnet-20250219": ANTHROPIC_37_SERIES,
|
|
298
|
+
"claude-3-7-sonnet-latest": ANTHROPIC_37_SERIES,
|
|
299
|
+
"claude-sonnet-4-0": ANTHROPIC_SONNET_4_VERSIONED,
|
|
300
|
+
"claude-sonnet-4-20250514": ANTHROPIC_SONNET_4_VERSIONED,
|
|
301
|
+
"claude-sonnet-4-5": ANTHROPIC_SONNET_4_VERSIONED,
|
|
302
|
+
"claude-sonnet-4-5-20250929": ANTHROPIC_SONNET_4_VERSIONED,
|
|
303
|
+
"claude-opus-4-0": ANTHROPIC_OPUS_4_VERSIONED,
|
|
304
|
+
"claude-opus-4-1": ANTHROPIC_OPUS_4_VERSIONED,
|
|
305
|
+
"claude-opus-4-5": ANTHROPIC_OPUS_4_VERSIONED,
|
|
306
|
+
"claude-opus-4-20250514": ANTHROPIC_OPUS_4_VERSIONED,
|
|
307
|
+
"claude-haiku-4-5-20251001": ANTHROPIC_SONNET_4_VERSIONED,
|
|
308
|
+
"claude-haiku-4-5": ANTHROPIC_SONNET_4_VERSIONED,
|
|
309
|
+
# DeepSeek Models
|
|
310
|
+
"deepseek-chat": DEEPSEEK_CHAT_STANDARD,
|
|
311
|
+
# Google Gemini Models (vanilla aliases and versioned)
|
|
312
|
+
"gemini-2.0-flash": GEMINI_2_FLASH,
|
|
313
|
+
"gemini-2.5-flash-preview": GEMINI_STANDARD,
|
|
314
|
+
"gemini-2.5-pro-preview": GEMINI_STANDARD,
|
|
315
|
+
"gemini-2.5-flash-preview-05-20": GEMINI_STANDARD,
|
|
316
|
+
"gemini-2.5-pro-preview-05-06": GEMINI_STANDARD,
|
|
317
|
+
"gemini-2.5-pro": GEMINI_STANDARD,
|
|
318
|
+
"gemini-2.5-flash-preview-09-2025": GEMINI_STANDARD,
|
|
319
|
+
"gemini-2.5-flash": GEMINI_STANDARD,
|
|
320
|
+
"gemini-3-pro-preview": GEMINI_STANDARD,
|
|
321
|
+
# xAI Grok Models
|
|
322
|
+
"grok-4-fast-reasoning": GROK_4_VLM,
|
|
323
|
+
"grok-4-fast-non-reasoning": GROK_4_VLM,
|
|
324
|
+
"grok-4": GROK_4,
|
|
325
|
+
"grok-4-0709": GROK_4,
|
|
326
|
+
"grok-3": GROK_3,
|
|
327
|
+
"grok-3-mini": GROK_3,
|
|
328
|
+
"grok-3-fast": GROK_3,
|
|
329
|
+
"grok-3-mini-fast": GROK_3,
|
|
330
|
+
"moonshotai/kimi-k2": KIMI_MOONSHOT,
|
|
331
|
+
"moonshotai/kimi-k2-instruct-0905": KIMI_MOONSHOT,
|
|
332
|
+
"moonshotai/kimi-k2-thinking": KIMI_MOONSHOT_THINKING,
|
|
333
|
+
"moonshotai/kimi-k2-thinking-0905": KIMI_MOONSHOT_THINKING,
|
|
334
|
+
"qwen/qwen3-32b": QWEN3_REASONER,
|
|
335
|
+
"deepseek-r1-distill-llama-70b": DEEPSEEK_DISTILL,
|
|
336
|
+
"openai/gpt-oss-120b": OPENAI_GPT_OSS_SERIES, # https://cookbook.openai.com/articles/openai-harmony
|
|
337
|
+
"openai/gpt-oss-20b": OPENAI_GPT_OSS_SERIES, # tool/reasoning interleave guidance
|
|
338
|
+
"zai-org/glm-4.6": GLM_46,
|
|
339
|
+
"minimaxai/minimax-m2": GLM_46,
|
|
340
|
+
"qwen/qwen3-next-80b-a3b-instruct": HF_PROVIDER_QWEN3_NEXT,
|
|
341
|
+
"deepseek-ai/deepseek-v3.1": HF_PROVIDER_DEEPSEEK31,
|
|
342
|
+
"deepseek-ai/deepseek-v3.2-exp": HF_PROVIDER_DEEPSEEK32,
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
@classmethod
|
|
346
|
+
def get_model_params(cls, model: str) -> ModelParameters | None:
|
|
347
|
+
"""Get model parameters for a given model name"""
|
|
348
|
+
if not model:
|
|
349
|
+
return None
|
|
350
|
+
|
|
351
|
+
normalized = cls.normalize_model_name(model)
|
|
352
|
+
return cls.MODELS.get(normalized)
|
|
353
|
+
|
|
354
|
+
@classmethod
|
|
355
|
+
def normalize_model_name(cls, model: str) -> str:
|
|
356
|
+
"""Normalize model specs (provider/effort/aliases) to a ModelDatabase key.
|
|
357
|
+
|
|
358
|
+
This intentionally delegates to ModelFactory parsing where possible rather than
|
|
359
|
+
re-implementing model string semantics in the database layer.
|
|
360
|
+
"""
|
|
361
|
+
from fast_agent.core.exceptions import ModelConfigError
|
|
362
|
+
from fast_agent.llm.model_factory import ModelFactory
|
|
363
|
+
from fast_agent.llm.provider_types import Provider
|
|
364
|
+
|
|
365
|
+
model_spec = (model or "").strip()
|
|
366
|
+
if not model_spec:
|
|
367
|
+
return ""
|
|
368
|
+
|
|
369
|
+
# If it's already a known key, keep it as-is (after casing/whitespace normalization).
|
|
370
|
+
direct_key = model_spec.lower()
|
|
371
|
+
if direct_key in cls.MODELS:
|
|
372
|
+
return direct_key
|
|
373
|
+
|
|
374
|
+
# Apply aliases first (case-insensitive).
|
|
375
|
+
aliased = ModelFactory.MODEL_ALIASES.get(model_spec)
|
|
376
|
+
if not aliased:
|
|
377
|
+
aliased = ModelFactory.MODEL_ALIASES.get(model_spec.lower())
|
|
378
|
+
if aliased:
|
|
379
|
+
model_spec = aliased
|
|
380
|
+
direct_key = model_spec.strip().lower()
|
|
381
|
+
if direct_key in cls.MODELS:
|
|
382
|
+
return direct_key
|
|
383
|
+
|
|
384
|
+
# Parse known spec formats to strip provider prefixes and reasoning effort.
|
|
385
|
+
try:
|
|
386
|
+
parsed = ModelFactory.parse_model_string(model_spec)
|
|
387
|
+
model_spec = parsed.model_name
|
|
388
|
+
|
|
389
|
+
# HF uses `model:provider` for routing; the suffix is not part of the model id.
|
|
390
|
+
if parsed.provider == Provider.HUGGINGFACE and ":" in model_spec:
|
|
391
|
+
model_spec = model_spec.rsplit(":", 1)[0]
|
|
392
|
+
except ModelConfigError:
|
|
393
|
+
# Best-effort fallback: keep original spec if it can't be parsed.
|
|
394
|
+
pass
|
|
395
|
+
|
|
396
|
+
# If parsing failed, still support common "model:route" forms by stripping the suffix
|
|
397
|
+
# only when the base resolves to a known database key.
|
|
398
|
+
if ":" in model_spec:
|
|
399
|
+
base = model_spec.rsplit(":", 1)[0].strip().lower()
|
|
400
|
+
if base in cls.MODELS:
|
|
401
|
+
return base
|
|
402
|
+
|
|
403
|
+
return model_spec.strip().lower()
|
|
404
|
+
|
|
405
|
+
@classmethod
|
|
406
|
+
def get_context_window(cls, model: str) -> int | None:
|
|
407
|
+
"""Get context window size for a model"""
|
|
408
|
+
params = cls.get_model_params(model)
|
|
409
|
+
return params.context_window if params else None
|
|
410
|
+
|
|
411
|
+
@classmethod
|
|
412
|
+
def get_max_output_tokens(cls, model: str) -> int | None:
|
|
413
|
+
"""Get maximum output tokens for a model"""
|
|
414
|
+
params = cls.get_model_params(model)
|
|
415
|
+
return params.max_output_tokens if params else None
|
|
416
|
+
|
|
417
|
+
@classmethod
|
|
418
|
+
def get_tokenizes(cls, model: str) -> list[str] | None:
|
|
419
|
+
"""Get supported tokenization types for a model"""
|
|
420
|
+
params = cls.get_model_params(model)
|
|
421
|
+
return params.tokenizes if params else None
|
|
422
|
+
|
|
423
|
+
@classmethod
|
|
424
|
+
def supports_mime(cls, model: str, mime_type: str) -> bool:
|
|
425
|
+
"""
|
|
426
|
+
Return True if the given model supports the provided MIME type.
|
|
427
|
+
|
|
428
|
+
Normalizes common aliases (e.g., image/jpg->image/jpeg, document/pdf->application/pdf)
|
|
429
|
+
and also accepts bare extensions like "pdf" or "png".
|
|
430
|
+
"""
|
|
431
|
+
from fast_agent.mcp.mime_utils import normalize_mime_type
|
|
432
|
+
|
|
433
|
+
tokenizes = cls.get_tokenizes(model) or []
|
|
434
|
+
|
|
435
|
+
# Normalize the candidate and the database entries to lowercase
|
|
436
|
+
normalized_supported = [t.lower() for t in tokenizes]
|
|
437
|
+
|
|
438
|
+
# Handle wildcard inputs like "image/*" quickly
|
|
439
|
+
mt = (mime_type or "").strip().lower()
|
|
440
|
+
if mt.endswith("/*") and "/" in mt:
|
|
441
|
+
prefix = mt.split("/", 1)[0] + "/"
|
|
442
|
+
return any(s.startswith(prefix) for s in normalized_supported)
|
|
443
|
+
|
|
444
|
+
normalized = normalize_mime_type(mime_type)
|
|
445
|
+
if not normalized:
|
|
446
|
+
return False
|
|
447
|
+
|
|
448
|
+
return normalized.lower() in normalized_supported
|
|
449
|
+
|
|
450
|
+
@classmethod
|
|
451
|
+
def supports_any_mime(cls, model: str, mime_types: list[str]) -> bool:
|
|
452
|
+
"""Return True if the model supports any of the provided MIME types."""
|
|
453
|
+
return any(cls.supports_mime(model, m) for m in mime_types)
|
|
454
|
+
|
|
455
|
+
@classmethod
|
|
456
|
+
def get_json_mode(cls, model: str) -> str | None:
|
|
457
|
+
"""Get supported json mode (structured output) for a model"""
|
|
458
|
+
params = cls.get_model_params(model)
|
|
459
|
+
return params.json_mode if params else None
|
|
460
|
+
|
|
461
|
+
@classmethod
|
|
462
|
+
def get_reasoning(cls, model: str) -> str | None:
|
|
463
|
+
"""Get supported reasoning output style for a model"""
|
|
464
|
+
params = cls.get_model_params(model)
|
|
465
|
+
return params.reasoning if params else None
|
|
466
|
+
|
|
467
|
+
@classmethod
|
|
468
|
+
def get_stream_mode(cls, model: str | None) -> Literal["openai", "manual"]:
|
|
469
|
+
"""Return preferred streaming accumulation strategy for a model."""
|
|
470
|
+
if not model:
|
|
471
|
+
return "openai"
|
|
472
|
+
|
|
473
|
+
params = cls.get_model_params(model)
|
|
474
|
+
return params.stream_mode if params else "openai"
|
|
475
|
+
|
|
476
|
+
@classmethod
|
|
477
|
+
def get_default_max_tokens(cls, model: str) -> int:
|
|
478
|
+
"""Get default max_tokens for RequestParams based on model"""
|
|
479
|
+
if not model:
|
|
480
|
+
return 2048 # Fallback when no model specified
|
|
481
|
+
|
|
482
|
+
params = cls.get_model_params(model)
|
|
483
|
+
if params:
|
|
484
|
+
return params.max_output_tokens
|
|
485
|
+
return 2048 # Fallback for unknown models
|
|
486
|
+
|
|
487
|
+
@classmethod
|
|
488
|
+
def list_models(cls) -> list[str]:
|
|
489
|
+
"""List all available model names"""
|
|
490
|
+
return list(cls.MODELS.keys())
|