flock-core 0.5.0b28__py3-none-any.whl → 0.5.56b0__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 flock-core might be problematic. Click here for more details.
- flock/__init__.py +12 -217
- flock/agent.py +678 -0
- flock/api/themes.py +71 -0
- flock/artifacts.py +79 -0
- flock/cli.py +75 -0
- flock/components.py +173 -0
- flock/dashboard/__init__.py +28 -0
- flock/dashboard/collector.py +283 -0
- flock/dashboard/events.py +182 -0
- flock/dashboard/launcher.py +230 -0
- flock/dashboard/service.py +537 -0
- flock/dashboard/websocket.py +235 -0
- flock/engines/__init__.py +6 -0
- flock/engines/dspy_engine.py +856 -0
- flock/examples.py +128 -0
- flock/{core/util → helper}/cli_helper.py +4 -3
- flock/{core/logging → logging}/__init__.py +2 -3
- flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
- flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
- flock/{core/logging → logging}/formatters/themed_formatter.py +69 -115
- flock/{core/logging → logging}/logging.py +77 -61
- flock/{core/logging → logging}/telemetry.py +20 -26
- flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
- flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +6 -9
- flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
- flock/{core/logging → logging}/trace_and_logged.py +20 -24
- flock/mcp/__init__.py +91 -0
- flock/{core/mcp/mcp_client.py → mcp/client.py} +103 -154
- flock/{core/mcp/mcp_config.py → mcp/config.py} +62 -117
- flock/mcp/manager.py +255 -0
- flock/mcp/servers/sse/__init__.py +1 -1
- flock/mcp/servers/sse/flock_sse_server.py +11 -53
- flock/mcp/servers/stdio/__init__.py +1 -1
- flock/mcp/servers/stdio/flock_stdio_server.py +8 -48
- flock/mcp/servers/streamable_http/flock_streamable_http_server.py +17 -62
- flock/mcp/servers/websockets/flock_websocket_server.py +7 -40
- flock/{core/mcp/flock_mcp_tool.py → mcp/tool.py} +16 -26
- flock/mcp/types/__init__.py +42 -0
- flock/{core/mcp → mcp}/types/callbacks.py +9 -15
- flock/{core/mcp → mcp}/types/factories.py +7 -6
- flock/{core/mcp → mcp}/types/handlers.py +13 -18
- flock/{core/mcp → mcp}/types/types.py +70 -74
- flock/{core/mcp → mcp}/util/helpers.py +1 -1
- flock/orchestrator.py +645 -0
- flock/registry.py +148 -0
- flock/runtime.py +262 -0
- flock/service.py +140 -0
- flock/store.py +69 -0
- flock/subscription.py +111 -0
- flock/themes/andromeda.toml +1 -1
- flock/themes/apple-system-colors.toml +1 -1
- flock/themes/arcoiris.toml +1 -1
- flock/themes/atomonelight.toml +1 -1
- flock/themes/ayu copy.toml +1 -1
- flock/themes/ayu-light.toml +1 -1
- flock/themes/belafonte-day.toml +1 -1
- flock/themes/belafonte-night.toml +1 -1
- flock/themes/blulocodark.toml +1 -1
- flock/themes/breeze.toml +1 -1
- flock/themes/broadcast.toml +1 -1
- flock/themes/brogrammer.toml +1 -1
- flock/themes/builtin-dark.toml +1 -1
- flock/themes/builtin-pastel-dark.toml +1 -1
- flock/themes/catppuccin-latte.toml +1 -1
- flock/themes/catppuccin-macchiato.toml +1 -1
- flock/themes/catppuccin-mocha.toml +1 -1
- flock/themes/cga.toml +1 -1
- flock/themes/chalk.toml +1 -1
- flock/themes/ciapre.toml +1 -1
- flock/themes/coffee-theme.toml +1 -1
- flock/themes/cyberpunkscarletprotocol.toml +1 -1
- flock/themes/dark+.toml +1 -1
- flock/themes/darkermatrix.toml +1 -1
- flock/themes/darkside.toml +1 -1
- flock/themes/desert.toml +1 -1
- flock/themes/django.toml +1 -1
- flock/themes/djangosmooth.toml +1 -1
- flock/themes/doomone.toml +1 -1
- flock/themes/dotgov.toml +1 -1
- flock/themes/dracula+.toml +1 -1
- flock/themes/duckbones.toml +1 -1
- flock/themes/encom.toml +1 -1
- flock/themes/espresso.toml +1 -1
- flock/themes/everblush.toml +1 -1
- flock/themes/fairyfloss.toml +1 -1
- flock/themes/fideloper.toml +1 -1
- flock/themes/fishtank.toml +1 -1
- flock/themes/flexoki-light.toml +1 -1
- flock/themes/floraverse.toml +1 -1
- flock/themes/framer.toml +1 -1
- flock/themes/galizur.toml +1 -1
- flock/themes/github.toml +1 -1
- flock/themes/grass.toml +1 -1
- flock/themes/grey-green.toml +1 -1
- flock/themes/gruvboxlight.toml +1 -1
- flock/themes/guezwhoz.toml +1 -1
- flock/themes/harper.toml +1 -1
- flock/themes/hax0r-blue.toml +1 -1
- flock/themes/hopscotch.256.toml +1 -1
- flock/themes/ic-green-ppl.toml +1 -1
- flock/themes/iceberg-dark.toml +1 -1
- flock/themes/japanesque.toml +1 -1
- flock/themes/jubi.toml +1 -1
- flock/themes/kibble.toml +1 -1
- flock/themes/kolorit.toml +1 -1
- flock/themes/kurokula.toml +1 -1
- flock/themes/materialdesigncolors.toml +1 -1
- flock/themes/matrix.toml +1 -1
- flock/themes/mellifluous.toml +1 -1
- flock/themes/midnight-in-mojave.toml +1 -1
- flock/themes/monokai-remastered.toml +1 -1
- flock/themes/monokai-soda.toml +1 -1
- flock/themes/neon.toml +1 -1
- flock/themes/neopolitan.toml +1 -1
- flock/themes/nord-light.toml +1 -1
- flock/themes/ocean.toml +1 -1
- flock/themes/onehalfdark.toml +1 -1
- flock/themes/onehalflight.toml +1 -1
- flock/themes/palenighthc.toml +1 -1
- flock/themes/paulmillr.toml +1 -1
- flock/themes/pencildark.toml +1 -1
- flock/themes/pnevma.toml +1 -1
- flock/themes/purple-rain.toml +1 -1
- flock/themes/purplepeter.toml +1 -1
- flock/themes/raycast-dark.toml +1 -1
- flock/themes/red-sands.toml +1 -1
- flock/themes/relaxed.toml +1 -1
- flock/themes/retro.toml +1 -1
- flock/themes/rose-pine.toml +1 -1
- flock/themes/royal.toml +1 -1
- flock/themes/ryuuko.toml +1 -1
- flock/themes/sakura.toml +1 -1
- flock/themes/scarlet-protocol.toml +1 -1
- flock/themes/seoulbones-dark.toml +1 -1
- flock/themes/shades-of-purple.toml +1 -1
- flock/themes/smyck.toml +1 -1
- flock/themes/softserver.toml +1 -1
- flock/themes/solarized-darcula.toml +1 -1
- flock/themes/square.toml +1 -1
- flock/themes/sugarplum.toml +1 -1
- flock/themes/thayer-bright.toml +1 -1
- flock/themes/tokyonight.toml +1 -1
- flock/themes/tomorrow.toml +1 -1
- flock/themes/ubuntu.toml +1 -1
- flock/themes/ultradark.toml +1 -1
- flock/themes/ultraviolent.toml +1 -1
- flock/themes/unikitty.toml +1 -1
- flock/themes/urple.toml +1 -1
- flock/themes/vesper.toml +1 -1
- flock/themes/vimbones.toml +1 -1
- flock/themes/wildcherry.toml +1 -1
- flock/themes/wilmersdorf.toml +1 -1
- flock/themes/wryan.toml +1 -1
- flock/themes/xcodedarkhc.toml +1 -1
- flock/themes/xcodelight.toml +1 -1
- flock/themes/zenbones-light.toml +1 -1
- flock/themes/zenwritten-dark.toml +1 -1
- flock/utilities.py +301 -0
- flock/{components/utility → utility}/output_utility_component.py +68 -53
- flock/visibility.py +107 -0
- flock_core-0.5.56b0.dist-info/METADATA +747 -0
- flock_core-0.5.56b0.dist-info/RECORD +398 -0
- flock_core-0.5.56b0.dist-info/entry_points.txt +2 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/licenses/LICENSE +1 -1
- flock/adapter/__init__.py +0 -14
- flock/adapter/azure_adapter.py +0 -68
- flock/adapter/chroma_adapter.py +0 -73
- flock/adapter/faiss_adapter.py +0 -97
- flock/adapter/pinecone_adapter.py +0 -51
- flock/adapter/vector_base.py +0 -47
- flock/cli/assets/release_notes.md +0 -140
- flock/cli/config.py +0 -8
- flock/cli/constants.py +0 -36
- flock/cli/create_agent.py +0 -1
- flock/cli/create_flock.py +0 -280
- flock/cli/execute_flock.py +0 -620
- flock/cli/load_agent.py +0 -1
- flock/cli/load_examples.py +0 -1
- flock/cli/load_flock.py +0 -192
- flock/cli/load_release_notes.py +0 -20
- flock/cli/loaded_flock_cli.py +0 -254
- flock/cli/manage_agents.py +0 -459
- flock/cli/registry_management.py +0 -889
- flock/cli/runner.py +0 -41
- flock/cli/settings.py +0 -857
- flock/cli/utils.py +0 -135
- flock/cli/view_results.py +0 -29
- flock/cli/yaml_editor.py +0 -396
- flock/components/__init__.py +0 -30
- flock/components/evaluation/__init__.py +0 -9
- flock/components/evaluation/declarative_evaluation_component.py +0 -606
- flock/components/routing/__init__.py +0 -15
- flock/components/routing/conditional_routing_component.py +0 -494
- flock/components/routing/default_routing_component.py +0 -103
- flock/components/routing/llm_routing_component.py +0 -206
- flock/components/utility/__init__.py +0 -22
- flock/components/utility/example_utility_component.py +0 -250
- flock/components/utility/feedback_utility_component.py +0 -206
- flock/components/utility/memory_utility_component.py +0 -550
- flock/components/utility/metrics_utility_component.py +0 -700
- flock/config.py +0 -61
- flock/core/__init__.py +0 -110
- flock/core/agent/__init__.py +0 -16
- flock/core/agent/default_agent.py +0 -216
- flock/core/agent/flock_agent_components.py +0 -104
- flock/core/agent/flock_agent_execution.py +0 -101
- flock/core/agent/flock_agent_integration.py +0 -260
- flock/core/agent/flock_agent_lifecycle.py +0 -186
- flock/core/agent/flock_agent_serialization.py +0 -381
- flock/core/api/__init__.py +0 -10
- flock/core/api/custom_endpoint.py +0 -45
- flock/core/api/endpoints.py +0 -254
- flock/core/api/main.py +0 -162
- flock/core/api/models.py +0 -97
- flock/core/api/run_store.py +0 -224
- flock/core/api/runner.py +0 -44
- flock/core/api/service.py +0 -214
- flock/core/component/__init__.py +0 -15
- flock/core/component/agent_component_base.py +0 -309
- flock/core/component/evaluation_component.py +0 -62
- flock/core/component/routing_component.py +0 -74
- flock/core/component/utility_component.py +0 -69
- flock/core/config/flock_agent_config.py +0 -58
- flock/core/config/scheduled_agent_config.py +0 -40
- flock/core/context/context.py +0 -213
- flock/core/context/context_manager.py +0 -37
- flock/core/context/context_vars.py +0 -10
- flock/core/evaluation/utils.py +0 -396
- flock/core/execution/batch_executor.py +0 -369
- flock/core/execution/evaluation_executor.py +0 -438
- flock/core/execution/local_executor.py +0 -31
- flock/core/execution/opik_executor.py +0 -103
- flock/core/execution/temporal_executor.py +0 -164
- flock/core/flock.py +0 -634
- flock/core/flock_agent.py +0 -336
- flock/core/flock_factory.py +0 -613
- flock/core/flock_scheduler.py +0 -166
- flock/core/flock_server_manager.py +0 -136
- flock/core/interpreter/python_interpreter.py +0 -689
- flock/core/mcp/__init__.py +0 -1
- flock/core/mcp/flock_mcp_server.py +0 -680
- flock/core/mcp/mcp_client_manager.py +0 -201
- flock/core/mcp/types/__init__.py +0 -1
- flock/core/mixin/dspy_integration.py +0 -403
- flock/core/mixin/prompt_parser.py +0 -125
- flock/core/orchestration/__init__.py +0 -15
- flock/core/orchestration/flock_batch_processor.py +0 -94
- flock/core/orchestration/flock_evaluator.py +0 -113
- flock/core/orchestration/flock_execution.py +0 -295
- flock/core/orchestration/flock_initialization.py +0 -149
- flock/core/orchestration/flock_server_manager.py +0 -67
- flock/core/orchestration/flock_web_server.py +0 -117
- flock/core/registry/__init__.py +0 -45
- flock/core/registry/agent_registry.py +0 -69
- flock/core/registry/callable_registry.py +0 -139
- flock/core/registry/component_discovery.py +0 -142
- flock/core/registry/component_registry.py +0 -64
- flock/core/registry/config_mapping.py +0 -64
- flock/core/registry/decorators.py +0 -137
- flock/core/registry/registry_hub.py +0 -205
- flock/core/registry/server_registry.py +0 -57
- flock/core/registry/type_registry.py +0 -86
- flock/core/serialization/__init__.py +0 -13
- flock/core/serialization/callable_registry.py +0 -52
- flock/core/serialization/flock_serializer.py +0 -832
- flock/core/serialization/json_encoder.py +0 -41
- flock/core/serialization/secure_serializer.py +0 -175
- flock/core/serialization/serializable.py +0 -342
- flock/core/serialization/serialization_utils.py +0 -412
- flock/core/util/file_path_utils.py +0 -223
- flock/core/util/hydrator.py +0 -309
- flock/core/util/input_resolver.py +0 -164
- flock/core/util/loader.py +0 -59
- flock/core/util/splitter.py +0 -219
- flock/di.py +0 -27
- flock/platform/docker_tools.py +0 -49
- flock/platform/jaeger_install.py +0 -86
- flock/webapp/__init__.py +0 -1
- flock/webapp/app/__init__.py +0 -0
- flock/webapp/app/api/__init__.py +0 -0
- flock/webapp/app/api/agent_management.py +0 -241
- flock/webapp/app/api/execution.py +0 -709
- flock/webapp/app/api/flock_management.py +0 -129
- flock/webapp/app/api/registry_viewer.py +0 -30
- flock/webapp/app/chat.py +0 -665
- flock/webapp/app/config.py +0 -104
- flock/webapp/app/dependencies.py +0 -117
- flock/webapp/app/main.py +0 -1070
- flock/webapp/app/middleware.py +0 -113
- flock/webapp/app/models_ui.py +0 -7
- flock/webapp/app/services/__init__.py +0 -0
- flock/webapp/app/services/feedback_file_service.py +0 -363
- flock/webapp/app/services/flock_service.py +0 -337
- flock/webapp/app/services/sharing_models.py +0 -81
- flock/webapp/app/services/sharing_store.py +0 -762
- flock/webapp/app/templates/theme_mapper.html +0 -326
- flock/webapp/app/theme_mapper.py +0 -812
- flock/webapp/app/utils.py +0 -85
- flock/webapp/run.py +0 -215
- flock/webapp/static/css/chat.css +0 -301
- flock/webapp/static/css/components.css +0 -167
- flock/webapp/static/css/header.css +0 -39
- flock/webapp/static/css/layout.css +0 -46
- flock/webapp/static/css/sidebar.css +0 -127
- flock/webapp/static/css/two-pane.css +0 -48
- flock/webapp/templates/base.html +0 -200
- flock/webapp/templates/chat.html +0 -152
- flock/webapp/templates/chat_settings.html +0 -19
- flock/webapp/templates/flock_editor.html +0 -16
- flock/webapp/templates/index.html +0 -12
- flock/webapp/templates/partials/_agent_detail_form.html +0 -93
- flock/webapp/templates/partials/_agent_list.html +0 -18
- flock/webapp/templates/partials/_agent_manager_view.html +0 -51
- flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
- flock/webapp/templates/partials/_chat_container.html +0 -15
- flock/webapp/templates/partials/_chat_messages.html +0 -57
- flock/webapp/templates/partials/_chat_settings_form.html +0 -85
- flock/webapp/templates/partials/_create_flock_form.html +0 -50
- flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
- flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
- flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
- flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
- flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
- flock/webapp/templates/partials/_env_vars_table.html +0 -23
- flock/webapp/templates/partials/_execution_form.html +0 -118
- flock/webapp/templates/partials/_execution_view_container.html +0 -28
- flock/webapp/templates/partials/_flock_file_list.html +0 -23
- flock/webapp/templates/partials/_flock_properties_form.html +0 -52
- flock/webapp/templates/partials/_flock_upload_form.html +0 -16
- flock/webapp/templates/partials/_header_flock_status.html +0 -5
- flock/webapp/templates/partials/_load_manager_view.html +0 -49
- flock/webapp/templates/partials/_registry_table.html +0 -25
- flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
- flock/webapp/templates/partials/_results_display.html +0 -78
- flock/webapp/templates/partials/_settings_env_content.html +0 -9
- flock/webapp/templates/partials/_settings_theme_content.html +0 -14
- flock/webapp/templates/partials/_settings_view.html +0 -36
- flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
- flock/webapp/templates/partials/_share_link_snippet.html +0 -35
- flock/webapp/templates/partials/_sidebar.html +0 -74
- flock/webapp/templates/partials/_streaming_results_container.html +0 -195
- flock/webapp/templates/partials/_structured_data_view.html +0 -40
- flock/webapp/templates/partials/_theme_preview.html +0 -36
- flock/webapp/templates/registry_viewer.html +0 -84
- flock/webapp/templates/shared_run_page.html +0 -140
- flock/workflow/__init__.py +0 -0
- flock/workflow/activities.py +0 -196
- flock/workflow/agent_activities.py +0 -24
- flock/workflow/agent_execution_activity.py +0 -202
- flock/workflow/flock_workflow.py +0 -214
- flock/workflow/temporal_config.py +0 -96
- flock/workflow/temporal_setup.py +0 -68
- flock_core-0.5.0b28.dist-info/METADATA +0 -274
- flock_core-0.5.0b28.dist-info/RECORD +0 -561
- flock_core-0.5.0b28.dist-info/entry_points.txt +0 -2
- /flock/{core/logging → logging}/formatters/themes.py +0 -0
- /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
- /flock/{core/mcp → mcp}/util/__init__.py +0 -0
- {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/WHEEL +0 -0
|
@@ -11,16 +11,13 @@ from contextlib import (
|
|
|
11
11
|
)
|
|
12
12
|
from datetime import timedelta
|
|
13
13
|
from typing import (
|
|
14
|
+
TYPE_CHECKING,
|
|
14
15
|
Any,
|
|
15
16
|
)
|
|
16
17
|
|
|
17
18
|
import httpx
|
|
18
19
|
from anyio import ClosedResourceError
|
|
19
|
-
from
|
|
20
|
-
MemoryObjectReceiveStream,
|
|
21
|
-
MemoryObjectSendStream,
|
|
22
|
-
)
|
|
23
|
-
from cachetools import TTLCache, cached
|
|
20
|
+
from cachetools import TTLCache
|
|
24
21
|
from mcp import (
|
|
25
22
|
ClientSession,
|
|
26
23
|
InitializeResult,
|
|
@@ -36,16 +33,10 @@ from pydantic import (
|
|
|
36
33
|
Field,
|
|
37
34
|
)
|
|
38
35
|
|
|
39
|
-
from flock.
|
|
40
|
-
from flock.
|
|
41
|
-
from flock.
|
|
42
|
-
from flock.
|
|
43
|
-
default_flock_mcp_list_roots_callback_factory,
|
|
44
|
-
default_flock_mcp_logging_callback_factory,
|
|
45
|
-
default_flock_mcp_message_handler_callback_factory,
|
|
46
|
-
default_flock_mcp_sampling_callback_factory,
|
|
47
|
-
)
|
|
48
|
-
from flock.core.mcp.types.types import (
|
|
36
|
+
from flock.logging.logging import get_logger
|
|
37
|
+
from flock.mcp.config import FlockMCPConfiguration
|
|
38
|
+
from flock.mcp.tool import FlockMCPTool
|
|
39
|
+
from flock.mcp.types import (
|
|
49
40
|
FlockListRootsMCPCallback,
|
|
50
41
|
FlockLoggingMCPCallback,
|
|
51
42
|
FlockMessageHandlerMCPCallback,
|
|
@@ -53,7 +44,21 @@ from flock.core.mcp.types.types import (
|
|
|
53
44
|
MCPRoot,
|
|
54
45
|
ServerParameters,
|
|
55
46
|
)
|
|
56
|
-
from flock.
|
|
47
|
+
from flock.mcp.types.factories import (
|
|
48
|
+
default_flock_mcp_list_roots_callback_factory,
|
|
49
|
+
default_flock_mcp_logging_callback_factory,
|
|
50
|
+
default_flock_mcp_message_handler_callback_factory,
|
|
51
|
+
default_flock_mcp_sampling_callback_factory,
|
|
52
|
+
)
|
|
53
|
+
from flock.mcp.util.helpers import cache_key_generator
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if TYPE_CHECKING:
|
|
57
|
+
from anyio.streams.memory import (
|
|
58
|
+
MemoryObjectReceiveStream,
|
|
59
|
+
MemoryObjectSendStream,
|
|
60
|
+
)
|
|
61
|
+
|
|
57
62
|
|
|
58
63
|
logger = get_logger("mcp.client")
|
|
59
64
|
tracer = trace.get_tracer(__name__)
|
|
@@ -71,9 +76,7 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
71
76
|
"""
|
|
72
77
|
|
|
73
78
|
# --- Properties ---
|
|
74
|
-
config: FlockMCPConfiguration = Field(
|
|
75
|
-
..., description="The config for this client instance."
|
|
76
|
-
)
|
|
79
|
+
config: FlockMCPConfiguration = Field(..., description="The config for this client instance.")
|
|
77
80
|
|
|
78
81
|
tool_cache: TTLCache | None = Field(
|
|
79
82
|
default=None,
|
|
@@ -154,9 +157,7 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
154
157
|
def __getattr__(self, name: str):
|
|
155
158
|
# return an async function that auto-reconnects, then calls through.
|
|
156
159
|
async def _method(*args, **kwargs):
|
|
157
|
-
with tracer.start_as_current_span(
|
|
158
|
-
"session_proxy.__getattr__"
|
|
159
|
-
) as span:
|
|
160
|
+
with tracer.start_as_current_span("session_proxy.__getattr__") as span:
|
|
160
161
|
client = self._client
|
|
161
162
|
cfg = client.config
|
|
162
163
|
max_tries = cfg.connection_config.max_retries or 1
|
|
@@ -170,18 +171,14 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
170
171
|
await client._ensure_connected()
|
|
171
172
|
try:
|
|
172
173
|
# delegate the real session
|
|
173
|
-
return await getattr(client.client_session, name)(
|
|
174
|
-
*args, **kwargs
|
|
175
|
-
)
|
|
174
|
+
return await getattr(client.client_session, name)(*args, **kwargs)
|
|
176
175
|
except McpError as e:
|
|
177
176
|
# only retry on a transport timeout
|
|
178
177
|
if e.error.code == httpx.codes.REQUEST_TIMEOUT:
|
|
179
178
|
kind = "timeout"
|
|
180
179
|
else:
|
|
181
180
|
# application-level MCP error -> give up immediately
|
|
182
|
-
logger.error
|
|
183
|
-
f"MCP error in session.{name}: {e.error}"
|
|
184
|
-
)
|
|
181
|
+
logger.exception(f"MCP error in session.{name}: {e.error}")
|
|
185
182
|
return None
|
|
186
183
|
except (BrokenPipeError, ClosedResourceError) as e:
|
|
187
184
|
kind = type(e).__name__
|
|
@@ -199,9 +196,7 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
199
196
|
try:
|
|
200
197
|
await client.disconnect()
|
|
201
198
|
except Exception as e:
|
|
202
|
-
logger.warning(
|
|
203
|
-
f"Error tearing down stale session: {e}"
|
|
204
|
-
)
|
|
199
|
+
logger.warning(f"Error tearing down stale session: {e}")
|
|
205
200
|
span.record_exception(e)
|
|
206
201
|
return None
|
|
207
202
|
|
|
@@ -213,13 +208,14 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
213
208
|
await client.disconnect()
|
|
214
209
|
await client._connect()
|
|
215
210
|
except Exception as e:
|
|
216
|
-
logger.
|
|
211
|
+
logger.exception(f"Reconnect failed: {e}")
|
|
217
212
|
span.record_exception(e)
|
|
218
213
|
|
|
219
214
|
# Exponential backoff + 10% jitter
|
|
220
215
|
delay = base_delay ** (2 ** (attempt - 1))
|
|
221
216
|
delay += random.uniform(0, delay * 0.1)
|
|
222
217
|
await asyncio.sleep(delay)
|
|
218
|
+
return None
|
|
223
219
|
|
|
224
220
|
return _method
|
|
225
221
|
|
|
@@ -262,10 +258,7 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
262
258
|
)
|
|
263
259
|
|
|
264
260
|
# Check if roots are specified in the config:
|
|
265
|
-
if
|
|
266
|
-
not self.current_roots
|
|
267
|
-
and self.config.connection_config.mount_points
|
|
268
|
-
):
|
|
261
|
+
if not self.current_roots and self.config.connection_config.mount_points:
|
|
269
262
|
# That means that the roots are set in the config
|
|
270
263
|
self.current_roots = self.config.connection_config.mount_points
|
|
271
264
|
|
|
@@ -296,55 +289,39 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
296
289
|
# set up callbacks
|
|
297
290
|
if not self.logging_callback:
|
|
298
291
|
if not self.config.callback_config.logging_callback:
|
|
299
|
-
self.logging_callback = (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
logger=logger,
|
|
303
|
-
)
|
|
292
|
+
self.logging_callback = default_flock_mcp_logging_callback_factory(
|
|
293
|
+
associated_client=self,
|
|
294
|
+
logger=logger,
|
|
304
295
|
)
|
|
305
296
|
else:
|
|
306
|
-
self.logging_callback =
|
|
307
|
-
self.config.callback_config.logging_callback
|
|
308
|
-
)
|
|
297
|
+
self.logging_callback = self.config.callback_config.logging_callback
|
|
309
298
|
|
|
310
299
|
if not self.message_handler:
|
|
311
300
|
if not self.config.callback_config.message_handler:
|
|
312
|
-
self.message_handler = (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
logger=logger,
|
|
316
|
-
)
|
|
301
|
+
self.message_handler = default_flock_mcp_message_handler_callback_factory(
|
|
302
|
+
associated_client=self,
|
|
303
|
+
logger=logger,
|
|
317
304
|
)
|
|
318
305
|
else:
|
|
319
|
-
self.message_handler =
|
|
320
|
-
self.config.callback_config.message_handler
|
|
321
|
-
)
|
|
306
|
+
self.message_handler = self.config.callback_config.message_handler
|
|
322
307
|
|
|
323
308
|
if not self.list_roots_callback:
|
|
324
309
|
if not self.config.callback_config.list_roots_callback:
|
|
325
|
-
self.list_roots_callback = (
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
logger=logger,
|
|
329
|
-
)
|
|
310
|
+
self.list_roots_callback = default_flock_mcp_list_roots_callback_factory(
|
|
311
|
+
associated_client=self,
|
|
312
|
+
logger=logger,
|
|
330
313
|
)
|
|
331
314
|
else:
|
|
332
|
-
self.list_roots_callback =
|
|
333
|
-
self.config.callback_config.list_roots_callback
|
|
334
|
-
)
|
|
315
|
+
self.list_roots_callback = self.config.callback_config.list_roots_callback
|
|
335
316
|
|
|
336
317
|
if not self.sampling_callback:
|
|
337
318
|
if not self.config.callback_config.sampling_callback:
|
|
338
|
-
self.sampling_callback = (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
logger=logger,
|
|
342
|
-
)
|
|
319
|
+
self.sampling_callback = default_flock_mcp_sampling_callback_factory(
|
|
320
|
+
associated_client=self,
|
|
321
|
+
logger=logger,
|
|
343
322
|
)
|
|
344
323
|
else:
|
|
345
|
-
self.sampling_callback =
|
|
346
|
-
self.config.callback_config.sampling_callback
|
|
347
|
-
)
|
|
324
|
+
self.sampling_callback = self.config.callback_config.sampling_callback
|
|
348
325
|
|
|
349
326
|
@property
|
|
350
327
|
def session(self) -> _SessionProxy:
|
|
@@ -377,58 +354,57 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
377
354
|
) -> list[FlockMCPTool]:
|
|
378
355
|
"""Gets a list of available tools from the server."""
|
|
379
356
|
|
|
380
|
-
|
|
381
|
-
async def _get_tools_cached(
|
|
382
|
-
agent_id: str,
|
|
383
|
-
run_id: str,
|
|
384
|
-
) -> list[FlockMCPTool]:
|
|
385
|
-
if not self.config.feature_config.tools_enabled:
|
|
386
|
-
return []
|
|
387
|
-
|
|
388
|
-
async def _get_tools_internal() -> list[FlockMCPTool]:
|
|
389
|
-
# TODO: Crash
|
|
390
|
-
response: ListToolsResult = await self.session.list_tools()
|
|
391
|
-
flock_tools = []
|
|
392
|
-
|
|
393
|
-
for tool in response.tools:
|
|
394
|
-
converted_tool = FlockMCPTool.from_mcp_tool(
|
|
395
|
-
tool,
|
|
396
|
-
agent_id=agent_id,
|
|
397
|
-
run_id=run_id,
|
|
398
|
-
)
|
|
399
|
-
if converted_tool:
|
|
400
|
-
flock_tools.append(converted_tool)
|
|
401
|
-
return flock_tools
|
|
357
|
+
cache_key = cache_key_generator(agent_id, run_id)
|
|
402
358
|
|
|
403
|
-
|
|
359
|
+
# Check cache first
|
|
360
|
+
if cache_key in self.tool_cache:
|
|
361
|
+
return self.tool_cache[cache_key]
|
|
404
362
|
|
|
405
|
-
|
|
363
|
+
if not self.config.feature_config.tools_enabled:
|
|
364
|
+
result = []
|
|
365
|
+
self.tool_cache[cache_key] = result
|
|
366
|
+
return result
|
|
367
|
+
|
|
368
|
+
async def _get_tools_internal() -> list[FlockMCPTool]:
|
|
369
|
+
# TODO: Crash
|
|
370
|
+
response: ListToolsResult = await self.session.list_tools()
|
|
371
|
+
flock_tools = []
|
|
372
|
+
|
|
373
|
+
for tool in response.tools:
|
|
374
|
+
converted_tool = FlockMCPTool.from_mcp_tool(
|
|
375
|
+
tool,
|
|
376
|
+
agent_id=agent_id,
|
|
377
|
+
run_id=run_id,
|
|
378
|
+
)
|
|
379
|
+
if converted_tool:
|
|
380
|
+
flock_tools.append(converted_tool)
|
|
381
|
+
return flock_tools
|
|
382
|
+
|
|
383
|
+
result = await _get_tools_internal()
|
|
384
|
+
self.tool_cache[cache_key] = result
|
|
385
|
+
return result
|
|
406
386
|
|
|
407
387
|
async def call_tool(
|
|
408
388
|
self, agent_id: str, run_id: str, name: str, arguments: dict[str, Any]
|
|
409
389
|
) -> CallToolResult:
|
|
410
390
|
"""Call a tool via the MCP Protocol on the client's server."""
|
|
411
391
|
|
|
412
|
-
|
|
413
|
-
async def _call_tool_cached(
|
|
414
|
-
agent_id: str, run_id: str, name: str, arguments: dict[str, Any]
|
|
415
|
-
) -> CallToolResult:
|
|
416
|
-
async def _call_tool_internal(
|
|
417
|
-
name: str, arguments: dict[str, Any]
|
|
418
|
-
) -> CallToolResult:
|
|
419
|
-
logger.debug(
|
|
420
|
-
f"Calling tool '{name}' with arguments {arguments}"
|
|
421
|
-
)
|
|
422
|
-
return await self.session.call_tool(
|
|
423
|
-
name=name,
|
|
424
|
-
arguments=arguments,
|
|
425
|
-
)
|
|
392
|
+
cache_key = cache_key_generator(agent_id, run_id, name, arguments)
|
|
426
393
|
|
|
427
|
-
|
|
394
|
+
# Check cache first
|
|
395
|
+
if cache_key in self.tool_result_cache:
|
|
396
|
+
return self.tool_result_cache[cache_key]
|
|
428
397
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
398
|
+
async def _call_tool_internal(name: str, arguments: dict[str, Any]) -> CallToolResult:
|
|
399
|
+
logger.debug(f"Calling tool '{name}' with arguments {arguments}")
|
|
400
|
+
return await self.session.call_tool(
|
|
401
|
+
name=name,
|
|
402
|
+
arguments=arguments,
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
result = await _call_tool_internal(name=name, arguments=arguments)
|
|
406
|
+
self.tool_result_cache[cache_key] = result
|
|
407
|
+
return result
|
|
432
408
|
|
|
433
409
|
async def get_server_name(self) -> str:
|
|
434
410
|
"""Return the server_name.
|
|
@@ -465,33 +441,23 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
465
441
|
async with self.lock:
|
|
466
442
|
if self.tool_cache:
|
|
467
443
|
self.tool_cache.clear()
|
|
468
|
-
logger.debug(
|
|
469
|
-
f"Invalidated tool_cache for server '{self.config.name}'"
|
|
470
|
-
)
|
|
444
|
+
logger.debug(f"Invalidated tool_cache for server '{self.config.name}'")
|
|
471
445
|
|
|
472
446
|
async def invalidate_resource_list_cache(self) -> None:
|
|
473
447
|
"""Invalidate the entries in the resource list cache."""
|
|
474
|
-
logger.debug(
|
|
475
|
-
f"Invalidating resource_list_cache for server '{self.config.name}'"
|
|
476
|
-
)
|
|
448
|
+
logger.debug(f"Invalidating resource_list_cache for server '{self.config.name}'")
|
|
477
449
|
async with self.lock:
|
|
478
450
|
if self.resource_list_cache:
|
|
479
451
|
self.resource_list_cache.clear()
|
|
480
|
-
logger.debug(
|
|
481
|
-
f"Invalidated resource_list_cache for server '{self.config.name}'"
|
|
482
|
-
)
|
|
452
|
+
logger.debug(f"Invalidated resource_list_cache for server '{self.config.name}'")
|
|
483
453
|
|
|
484
454
|
async def invalidate_resource_contents_cache(self) -> None:
|
|
485
455
|
"""Invalidate the entries in the resource contents cache."""
|
|
486
|
-
logger.debug(
|
|
487
|
-
f"Invalidating resource_contents_cache for server '{self.config.name}'."
|
|
488
|
-
)
|
|
456
|
+
logger.debug(f"Invalidating resource_contents_cache for server '{self.config.name}'.")
|
|
489
457
|
async with self.lock:
|
|
490
458
|
if self.resource_contents_cache:
|
|
491
459
|
self.resource_contents_cache.clear()
|
|
492
|
-
logger.debug(
|
|
493
|
-
f"Invalidated resource_contents_cache for server '{self.config.name}'"
|
|
494
|
-
)
|
|
460
|
+
logger.debug(f"Invalidated resource_contents_cache for server '{self.config.name}'")
|
|
495
461
|
|
|
496
462
|
async def invalidate_resource_contents_cache_entry(self, key: str) -> None:
|
|
497
463
|
"""Invalidate a single entry in the resource contents cache."""
|
|
@@ -531,8 +497,7 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
531
497
|
await cm.__aexit__(None, None, None)
|
|
532
498
|
except Exception as e:
|
|
533
499
|
logger.debug(
|
|
534
|
-
f"Suppressed transport-ctx exit error "
|
|
535
|
-
f"for server '{self.config.name}': {e!r}"
|
|
500
|
+
f"Suppressed transport-ctx exit error for server '{self.config.name}': {e!r}"
|
|
536
501
|
)
|
|
537
502
|
|
|
538
503
|
async def _create_session(self) -> None:
|
|
@@ -548,42 +513,29 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
548
513
|
server_params = self.config.connection_config.connection_parameters
|
|
549
514
|
|
|
550
515
|
# Single Hook
|
|
551
|
-
transport_ctx = await self.create_transport(
|
|
552
|
-
server_params, self.additional_params
|
|
553
|
-
)
|
|
516
|
+
transport_ctx = await self.create_transport(server_params, self.additional_params)
|
|
554
517
|
safe_transport = self._safe_transport_ctx(transport_ctx)
|
|
555
518
|
result = await stack.enter_async_context(safe_transport)
|
|
556
519
|
|
|
557
520
|
# support old (read, write) or new (read, write, get_sesssion_id_callback)
|
|
558
521
|
read: MemoryObjectReceiveStream | None = None
|
|
559
522
|
write: MemoryObjectSendStream | None = None
|
|
560
|
-
get_session_id_callback: GetSessionIdCallback | None = None
|
|
561
523
|
if isinstance(result, tuple) and len(result) == 2:
|
|
562
524
|
# old type
|
|
563
525
|
read, write = result
|
|
564
|
-
get_session_id_callback = None
|
|
565
526
|
elif isinstance(result, tuple) and len(result) == 3:
|
|
566
527
|
# new type
|
|
567
|
-
read, write,
|
|
528
|
+
read, write, _get_session_id_callback = result
|
|
568
529
|
else:
|
|
569
|
-
raise RuntimeError(
|
|
570
|
-
f"create_transport returned unexpected tuple of {result}"
|
|
571
|
-
)
|
|
530
|
+
raise RuntimeError(f"create_transport returned unexpected tuple of {result}")
|
|
572
531
|
|
|
573
532
|
if read is None or write is None:
|
|
574
|
-
raise RuntimeError(
|
|
575
|
-
f"create_transport did not create any read or write streams."
|
|
576
|
-
)
|
|
533
|
+
raise RuntimeError("create_transport did not create any read or write streams.")
|
|
577
534
|
|
|
578
535
|
read_timeout = self.config.connection_config.read_timeout_seconds
|
|
579
536
|
|
|
580
|
-
if
|
|
581
|
-
self.additional_params
|
|
582
|
-
and "read_timeout_seconds" in self.additional_params
|
|
583
|
-
):
|
|
584
|
-
read_timeout = self.additional_params.get(
|
|
585
|
-
"read_timeout_seconds", read_timeout
|
|
586
|
-
)
|
|
537
|
+
if self.additional_params and "read_timeout_seconds" in self.additional_params:
|
|
538
|
+
read_timeout = self.additional_params.get("read_timeout_seconds", read_timeout)
|
|
587
539
|
|
|
588
540
|
timeout_seconds = (
|
|
589
541
|
read_timeout
|
|
@@ -622,11 +574,10 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
622
574
|
)
|
|
623
575
|
return self.client_session
|
|
624
576
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
await self._create_session()
|
|
577
|
+
logger.debug(
|
|
578
|
+
f"Client Session for Server '{self.config.name}' does not exist yet. Connecting..."
|
|
579
|
+
)
|
|
580
|
+
await self._create_session()
|
|
630
581
|
|
|
631
582
|
if not self.connected_server_capabilities:
|
|
632
583
|
# This means we never asked the server to initialize the connection.
|
|
@@ -636,9 +587,7 @@ class FlockMCPClient(BaseModel, ABC):
|
|
|
636
587
|
async def _perform_initial_handshake(self) -> None:
|
|
637
588
|
"""Tell the server who we are, what capabilities we have, and what roots we're interested in."""
|
|
638
589
|
# 1) do the LSP-style initialize handshake
|
|
639
|
-
logger.debug(
|
|
640
|
-
f"Performing intialize handshake with server '{self.config.name}'"
|
|
641
|
-
)
|
|
590
|
+
logger.debug(f"Performing intialize handshake with server '{self.config.name}'")
|
|
642
591
|
init: InitializeResult = await self.client_session.initialize()
|
|
643
592
|
|
|
644
593
|
self.connected_server_capabilities = init
|