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
flock/webapp/app/middleware.py
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# Custom middleware for handling proxy headers
|
|
3
|
-
from starlette.middleware.base import BaseHTTPMiddleware
|
|
4
|
-
from starlette.requests import Request as StarletteRequest
|
|
5
|
-
|
|
6
|
-
#from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
|
|
7
|
-
|
|
8
|
-
class ProxyHeadersMiddleware(BaseHTTPMiddleware):
|
|
9
|
-
"""Middleware to handle proxy headers for HTTPS detection.
|
|
10
|
-
This ensures url_for() generates HTTPS URLs when behind an HTTPS proxy.
|
|
11
|
-
"""
|
|
12
|
-
def __init__(self, app, force_https: bool = False):
|
|
13
|
-
super().__init__(app)
|
|
14
|
-
self.force_https = force_https
|
|
15
|
-
|
|
16
|
-
async def dispatch(self, request: StarletteRequest, call_next):
|
|
17
|
-
import json
|
|
18
|
-
import logging
|
|
19
|
-
logger = logging.getLogger(__name__)
|
|
20
|
-
|
|
21
|
-
# Log original scheme and relevant headers for debugging
|
|
22
|
-
original_scheme = request.scope.get("scheme", "unknown")
|
|
23
|
-
original_host = request.headers.get("host")
|
|
24
|
-
logger.info(f"ProxyHeadersMiddleware - Original scheme: {original_scheme}, Host: {original_host}, URL: {request.url}")
|
|
25
|
-
|
|
26
|
-
# If force_https is enabled, always use HTTPS
|
|
27
|
-
if self.force_https:
|
|
28
|
-
request.scope["scheme"] = "https"
|
|
29
|
-
logger.info("ProxyHeadersMiddleware - Force HTTPS enabled, setting scheme to https")
|
|
30
|
-
else:
|
|
31
|
-
# Check for common proxy headers that indicate HTTPS
|
|
32
|
-
forwarded_proto = request.headers.get("x-forwarded-proto")
|
|
33
|
-
forwarded_scheme = request.headers.get("x-forwarded-scheme")
|
|
34
|
-
forwarded_host = request.headers.get("x-forwarded-host")
|
|
35
|
-
cloudflare_proto = request.headers.get("cf-visitor")
|
|
36
|
-
forwarded_ssl = request.headers.get("x-forwarded-ssl")
|
|
37
|
-
front_end_https = request.headers.get("front-end-https")
|
|
38
|
-
|
|
39
|
-
# Log proxy headers for debugging
|
|
40
|
-
proxy_headers = {
|
|
41
|
-
"x-forwarded-proto": forwarded_proto,
|
|
42
|
-
"x-forwarded-scheme": forwarded_scheme,
|
|
43
|
-
"x-forwarded-host": forwarded_host,
|
|
44
|
-
"cf-visitor": cloudflare_proto,
|
|
45
|
-
"x-forwarded-ssl": forwarded_ssl,
|
|
46
|
-
"front-end-https": front_end_https,
|
|
47
|
-
"x-forwarded-for": request.headers.get("x-forwarded-for"),
|
|
48
|
-
"host": request.headers.get("host")
|
|
49
|
-
}
|
|
50
|
-
logger.info(f"ProxyHeadersMiddleware - Proxy headers: {proxy_headers}")
|
|
51
|
-
|
|
52
|
-
scheme_updated = False
|
|
53
|
-
|
|
54
|
-
# Handle X-Forwarded-Proto header (most common)
|
|
55
|
-
if forwarded_proto:
|
|
56
|
-
request.scope["scheme"] = forwarded_proto.lower()
|
|
57
|
-
scheme_updated = True
|
|
58
|
-
logger.info(f"ProxyHeadersMiddleware - Updated scheme from X-Forwarded-Proto: {forwarded_proto}")
|
|
59
|
-
|
|
60
|
-
# Handle X-Forwarded-Scheme header
|
|
61
|
-
elif forwarded_scheme:
|
|
62
|
-
request.scope["scheme"] = forwarded_scheme.lower()
|
|
63
|
-
scheme_updated = True
|
|
64
|
-
logger.info(f"ProxyHeadersMiddleware - Updated scheme from X-Forwarded-Scheme: {forwarded_scheme}")
|
|
65
|
-
|
|
66
|
-
# Handle X-Forwarded-SSL header (on/off)
|
|
67
|
-
elif forwarded_ssl and forwarded_ssl.lower() == "on":
|
|
68
|
-
request.scope["scheme"] = "https"
|
|
69
|
-
scheme_updated = True
|
|
70
|
-
logger.info(f"ProxyHeadersMiddleware - Updated scheme from X-Forwarded-SSL: on -> https")
|
|
71
|
-
|
|
72
|
-
# Handle Front-End-Https header (on/off)
|
|
73
|
-
elif front_end_https and front_end_https.lower() == "on":
|
|
74
|
-
request.scope["scheme"] = "https"
|
|
75
|
-
scheme_updated = True
|
|
76
|
-
logger.info(f"ProxyHeadersMiddleware - Updated scheme from Front-End-Https: on -> https")
|
|
77
|
-
|
|
78
|
-
# Handle Cloudflare's CF-Visitor header (JSON format)
|
|
79
|
-
elif cloudflare_proto:
|
|
80
|
-
try:
|
|
81
|
-
visitor_info = json.loads(cloudflare_proto)
|
|
82
|
-
if visitor_info.get("scheme"):
|
|
83
|
-
request.scope["scheme"] = visitor_info["scheme"].lower()
|
|
84
|
-
scheme_updated = True
|
|
85
|
-
logger.info(f"ProxyHeadersMiddleware - Updated scheme from CF-Visitor: {visitor_info['scheme']}")
|
|
86
|
-
except (json.JSONDecodeError, KeyError) as e:
|
|
87
|
-
logger.warning(f"ProxyHeadersMiddleware - Failed to parse CF-Visitor header: {e}")
|
|
88
|
-
|
|
89
|
-
if not scheme_updated:
|
|
90
|
-
logger.info("ProxyHeadersMiddleware - No proxy headers found, keeping original scheme")
|
|
91
|
-
|
|
92
|
-
# Handle X-Forwarded-Host for proper host handling
|
|
93
|
-
forwarded_host = request.headers.get("x-forwarded-host")
|
|
94
|
-
if forwarded_host:
|
|
95
|
-
# Update the server scope to reflect the original host
|
|
96
|
-
request.scope["server"] = (forwarded_host, 443 if request.scope.get("scheme") == "https" else 80)
|
|
97
|
-
logger.info(f"ProxyHeadersMiddleware - Updated host from X-Forwarded-Host: {forwarded_host}")
|
|
98
|
-
|
|
99
|
-
# Handle X-Forwarded-For for client IP (optional but good practice)
|
|
100
|
-
forwarded_for = request.headers.get("x-forwarded-for")
|
|
101
|
-
if forwarded_for:
|
|
102
|
-
# Take the first IP in the chain (the original client)
|
|
103
|
-
client_ip = forwarded_for.split(",")[0].strip()
|
|
104
|
-
request.scope["client"] = (client_ip, request.scope.get("client", ["", 0])[1])
|
|
105
|
-
|
|
106
|
-
# Log final scheme and reconstructed URL
|
|
107
|
-
final_scheme = request.scope.get("scheme")
|
|
108
|
-
final_server = request.scope.get("server", ("unknown", 0))
|
|
109
|
-
logger.info(f"ProxyHeadersMiddleware - Final scheme: {final_scheme}, server: {final_server}")
|
|
110
|
-
logger.info(f"ProxyHeadersMiddleware - Reconstructed URL would be: {final_scheme}://{final_server[0]}{request.url.path}")
|
|
111
|
-
|
|
112
|
-
response = await call_next(request)
|
|
113
|
-
return response
|
flock/webapp/app/models_ui.py
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Pydantic models specific to UI interactions, if needed.
|
|
2
|
-
# For MVP, we might not need many here, as we'll primarily pass basic dicts to flock_service.
|
|
3
|
-
# Example:
|
|
4
|
-
# from pydantic import BaseModel
|
|
5
|
-
# class SaveFlockRequest(BaseModel):
|
|
6
|
-
# current_flock_json: str # Or a more structured model if preferred
|
|
7
|
-
# new_filename: str
|
|
File without changes
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
"""Methods for creating Feedback-File Downloads."""
|
|
2
|
-
import csv
|
|
3
|
-
import tempfile
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from werkzeug.utils import secure_filename
|
|
7
|
-
from fastapi import Request
|
|
8
|
-
from fastapi.responses import FileResponse
|
|
9
|
-
|
|
10
|
-
from flock.webapp.app.services.sharing_store import SharedLinkStoreInterface
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
async def create_xlsx_feedback_file_for_agent(
|
|
14
|
-
request: Request,
|
|
15
|
-
store: SharedLinkStoreInterface,
|
|
16
|
-
agent_name: str,
|
|
17
|
-
) -> FileResponse:
|
|
18
|
-
"""Creates an XLSX-File containing all feedback-entries for a single agent."""
|
|
19
|
-
from flock.core.flock import Flock
|
|
20
|
-
|
|
21
|
-
current_flock_instance: Flock | None = getattr(
|
|
22
|
-
request.app.state, "flock_instance", None
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
if not current_flock_instance:
|
|
26
|
-
from fastapi import HTTPException
|
|
27
|
-
|
|
28
|
-
raise HTTPException(
|
|
29
|
-
status_code=400,
|
|
30
|
-
detail="No Flock loaded to download feedback for"
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
all_agent_names = list(current_flock_instance.agents.keys())
|
|
34
|
-
|
|
35
|
-
if not all_agent_names:
|
|
36
|
-
from fastapi import HTTPException
|
|
37
|
-
|
|
38
|
-
raise HTTPException(
|
|
39
|
-
status_code=400,
|
|
40
|
-
detail="No agents found in the current Flock"
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
all_records = await store.get_all_feedback_records_for_agent(
|
|
44
|
-
agent_name=agent_name
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
temp_dir = tempfile.gettempdir()
|
|
48
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
49
|
-
safe_agent_name = secure_filename(agent_name)
|
|
50
|
-
xlsx_filename = f"flock_feedback_{safe_agent_name}_{timestamp}.xlsx"
|
|
51
|
-
xlsx_path = Path(temp_dir) / xlsx_filename
|
|
52
|
-
headers = [
|
|
53
|
-
"feedback_id",
|
|
54
|
-
"share_id",
|
|
55
|
-
"context_type",
|
|
56
|
-
"reason",
|
|
57
|
-
"expected_response",
|
|
58
|
-
"actual_response",
|
|
59
|
-
"created_at",
|
|
60
|
-
"flock_name",
|
|
61
|
-
"agent_name",
|
|
62
|
-
"flock_definition",
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
return await _write_xlsx_file(
|
|
66
|
-
records=all_records,
|
|
67
|
-
path=xlsx_path,
|
|
68
|
-
filename=xlsx_filename,
|
|
69
|
-
headers=headers,
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
async def create_xlsx_feedback_file(
|
|
73
|
-
request: Request,
|
|
74
|
-
store: SharedLinkStoreInterface
|
|
75
|
-
) -> FileResponse:
|
|
76
|
-
"""Creates an XLSX-File containing all feddback-entries for all agents."""
|
|
77
|
-
from flock.core.flock import Flock
|
|
78
|
-
|
|
79
|
-
current_flock_instance: Flock | None = getattr(
|
|
80
|
-
request.app.state, "flock_instance", None
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
if not current_flock_instance:
|
|
84
|
-
# If no flock is loaded, return an error response
|
|
85
|
-
from fastapi import HTTPException
|
|
86
|
-
|
|
87
|
-
raise HTTPException(
|
|
88
|
-
status_code=400,
|
|
89
|
-
detail="No Flock loaded to download feedback for"
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
# Get all agent names from the current flock
|
|
93
|
-
all_agent_names = list(current_flock_instance.agents.keys())
|
|
94
|
-
|
|
95
|
-
if not all_agent_names:
|
|
96
|
-
|
|
97
|
-
from fastapi import HTTPException
|
|
98
|
-
|
|
99
|
-
raise HTTPException(
|
|
100
|
-
status_code=400,
|
|
101
|
-
detail="No agents found in the current Flock"
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
all_records = []
|
|
105
|
-
for agent_name in all_agent_names:
|
|
106
|
-
agent_records = await store.get_all_feedback_records_for_agent(
|
|
107
|
-
agent_name=agent_name,
|
|
108
|
-
)
|
|
109
|
-
all_records.extend(agent_records)
|
|
110
|
-
|
|
111
|
-
temp_dir = tempfile.gettempdir()
|
|
112
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
113
|
-
xlsx_filename = f"flock_feedback_all_agents_{timestamp}.xlsx"
|
|
114
|
-
xlsx_path = Path(temp_dir) / xlsx_filename
|
|
115
|
-
headers = [
|
|
116
|
-
"feedback_id",
|
|
117
|
-
"share_id",
|
|
118
|
-
"context_type",
|
|
119
|
-
"reason",
|
|
120
|
-
"expected_response",
|
|
121
|
-
"actual_response",
|
|
122
|
-
"created_at",
|
|
123
|
-
"flock_name",
|
|
124
|
-
"agent_name",
|
|
125
|
-
"flock_definition",
|
|
126
|
-
]
|
|
127
|
-
|
|
128
|
-
return await _write_xlsx_file(
|
|
129
|
-
records=all_records,
|
|
130
|
-
path=xlsx_path,
|
|
131
|
-
filename=xlsx_filename,
|
|
132
|
-
headers=headers,
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
async def create_csv_feedback_file_for_agent(
|
|
137
|
-
request: Request,
|
|
138
|
-
store: SharedLinkStoreInterface,
|
|
139
|
-
agent_name: str,
|
|
140
|
-
separator: str = ",",
|
|
141
|
-
) -> FileResponse:
|
|
142
|
-
"""Creates a CSV-File filled with the feedback-records for a single agent."""
|
|
143
|
-
from flock.core.flock import Flock
|
|
144
|
-
|
|
145
|
-
current_flock_instance: Flock | None = getattr(
|
|
146
|
-
request.app.state, "flock_instance", None
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
if not current_flock_instance:
|
|
150
|
-
# If no flock is loaded, return an error response
|
|
151
|
-
from fastapi import HTTPException
|
|
152
|
-
|
|
153
|
-
raise HTTPException(
|
|
154
|
-
status_code=400,
|
|
155
|
-
detail="No Flock loaded to download feedback for"
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
# Get all agent names from the current flock
|
|
160
|
-
all_agent_names = list(current_flock_instance.agents.keys())
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if not all_agent_names:
|
|
164
|
-
|
|
165
|
-
from fastapi import HTTPException
|
|
166
|
-
|
|
167
|
-
raise HTTPException(
|
|
168
|
-
status_code=400,
|
|
169
|
-
detail="No agents found in the current Flock"
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
all_records = await store.get_all_feedback_records_for_agent(
|
|
173
|
-
agent_name=agent_name
|
|
174
|
-
)
|
|
175
|
-
temp_dir = tempfile.gettempdir()
|
|
176
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
177
|
-
safe_agent_name = secure_filename(agent_name)
|
|
178
|
-
csv_filename = f"flock_feedback_{safe_agent_name}_{timestamp}.csv"
|
|
179
|
-
csv_path = Path(temp_dir) / csv_filename
|
|
180
|
-
headers = [
|
|
181
|
-
"feedback_id",
|
|
182
|
-
"share_id",
|
|
183
|
-
"context_type",
|
|
184
|
-
"reason",
|
|
185
|
-
"expected_response",
|
|
186
|
-
"actual_response",
|
|
187
|
-
"created_at",
|
|
188
|
-
"flock_name",
|
|
189
|
-
"agent_name",
|
|
190
|
-
"flock_definition",
|
|
191
|
-
]
|
|
192
|
-
return await _write_csv_file(
|
|
193
|
-
records=all_records,
|
|
194
|
-
path=csv_path,
|
|
195
|
-
headers=headers,
|
|
196
|
-
separator=separator,
|
|
197
|
-
filename=csv_filename,
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
async def create_csv_feedback_file(
|
|
202
|
-
request: Request,
|
|
203
|
-
store: SharedLinkStoreInterface,
|
|
204
|
-
separator: str = ",",
|
|
205
|
-
|
|
206
|
-
) -> FileResponse:
|
|
207
|
-
"""Creates a CSV-File filled with the feedback-records for all agents."""
|
|
208
|
-
from flock.core.flock import Flock
|
|
209
|
-
|
|
210
|
-
current_flock_instance: Flock | None = getattr(
|
|
211
|
-
request.app.state, "flock_instance", None
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
if not current_flock_instance:
|
|
215
|
-
# If no flock is loaded, return an error response
|
|
216
|
-
from fastapi import HTTPException
|
|
217
|
-
|
|
218
|
-
raise HTTPException(
|
|
219
|
-
status_code=400,
|
|
220
|
-
detail="No Flock loaded to download feedback for"
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
# Get all agent names from the current flock
|
|
224
|
-
all_agent_names = list(current_flock_instance.agents.keys())
|
|
225
|
-
|
|
226
|
-
if not all_agent_names:
|
|
227
|
-
|
|
228
|
-
from fastapi import HTTPException
|
|
229
|
-
|
|
230
|
-
raise HTTPException(
|
|
231
|
-
status_code=400,
|
|
232
|
-
detail="No agents found in the current Flock"
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
all_records = []
|
|
236
|
-
for agent_name in all_agent_names:
|
|
237
|
-
records_for_agent = await store.get_all_feedback_records_for_agent(
|
|
238
|
-
agent_name=agent_name
|
|
239
|
-
)
|
|
240
|
-
all_records.extend(records_for_agent)
|
|
241
|
-
|
|
242
|
-
temp_dir = tempfile.gettempdir()
|
|
243
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
244
|
-
csv_filename = f"flock_feedback_all_agents_{timestamp}.csv"
|
|
245
|
-
csv_path = Path(temp_dir) / csv_filename
|
|
246
|
-
headers = [
|
|
247
|
-
"feedback_id",
|
|
248
|
-
"share_id",
|
|
249
|
-
"context_type",
|
|
250
|
-
"reason",
|
|
251
|
-
"expected_response",
|
|
252
|
-
"actual_response",
|
|
253
|
-
"created_at",
|
|
254
|
-
"flock_name",
|
|
255
|
-
"agent_name",
|
|
256
|
-
"flock_definition",
|
|
257
|
-
]
|
|
258
|
-
|
|
259
|
-
return await _write_csv_file(
|
|
260
|
-
records=all_records,
|
|
261
|
-
path=csv_path,
|
|
262
|
-
headers=headers,
|
|
263
|
-
filename=csv_filename,
|
|
264
|
-
separator=separator,
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
async def _write_xlsx_file(
|
|
268
|
-
records: list[dict],
|
|
269
|
-
headers: list,
|
|
270
|
-
path: str | Path,
|
|
271
|
-
filename: str,
|
|
272
|
-
) -> FileResponse:
|
|
273
|
-
"""Writes an xlsx-file with the specified records."""
|
|
274
|
-
try:
|
|
275
|
-
import pandas as pd
|
|
276
|
-
|
|
277
|
-
# Convert records to a format suitable for
|
|
278
|
-
# pandas DataFrame
|
|
279
|
-
data_rows = []
|
|
280
|
-
for record in records:
|
|
281
|
-
row_data = {}
|
|
282
|
-
for header in headers:
|
|
283
|
-
value = getattr(record, header, None)
|
|
284
|
-
# Convert datetime to string for excel
|
|
285
|
-
if header == "created_at" and value:
|
|
286
|
-
row_data[header] = (
|
|
287
|
-
value.isoformat()
|
|
288
|
-
if isinstance(value, datetime)
|
|
289
|
-
else str(value)
|
|
290
|
-
)
|
|
291
|
-
else:
|
|
292
|
-
row_data[header] = str(value) if value is not None else ""
|
|
293
|
-
data_rows.append(row_data)
|
|
294
|
-
|
|
295
|
-
# Create DataFrame and write to Excel
|
|
296
|
-
df = pd.DataFrame(data_rows)
|
|
297
|
-
df.to_excel(str(path), index=False)
|
|
298
|
-
|
|
299
|
-
return FileResponse(
|
|
300
|
-
path=str(path),
|
|
301
|
-
filename=filename,
|
|
302
|
-
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
303
|
-
headers={
|
|
304
|
-
"Content-Disposition": f"attachment; filename={filename}"
|
|
305
|
-
}
|
|
306
|
-
)
|
|
307
|
-
|
|
308
|
-
except Exception:
|
|
309
|
-
from fastapi import HTTPException
|
|
310
|
-
|
|
311
|
-
raise HTTPException(
|
|
312
|
-
status_code=500,
|
|
313
|
-
detail="Unable to create feedback Excel file"
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
async def _write_csv_file(
|
|
317
|
-
records: list[dict],
|
|
318
|
-
path: str | Path,
|
|
319
|
-
filename: str,
|
|
320
|
-
headers: list,
|
|
321
|
-
separator: str = ","
|
|
322
|
-
) -> FileResponse:
|
|
323
|
-
"""Writes a CSV_File with the specified records."""
|
|
324
|
-
try:
|
|
325
|
-
with open(path, "w", newline="", encoding="utf-8") as csvfile:
|
|
326
|
-
writer = csv.DictWriter(
|
|
327
|
-
csvfile,
|
|
328
|
-
fieldnames=headers,
|
|
329
|
-
delimiter=separator
|
|
330
|
-
)
|
|
331
|
-
writer.writeheader()
|
|
332
|
-
for record in records:
|
|
333
|
-
# Convert the Pydantic model
|
|
334
|
-
# to dict and ensure all fields are present
|
|
335
|
-
row_data = {}
|
|
336
|
-
for header in headers:
|
|
337
|
-
value = getattr(record, header, None)
|
|
338
|
-
# Convert datetime to ISO string for CSV
|
|
339
|
-
if header == "created_at" and value:
|
|
340
|
-
row_data[header] = (
|
|
341
|
-
value.isoformat()
|
|
342
|
-
if isinstance(value, datetime)
|
|
343
|
-
else str(value)
|
|
344
|
-
)
|
|
345
|
-
else:
|
|
346
|
-
row_data[header] = str(value) if value is not None else ""
|
|
347
|
-
writer.writerow(row_data)
|
|
348
|
-
|
|
349
|
-
return FileResponse(
|
|
350
|
-
path=str(path),
|
|
351
|
-
filename=filename,
|
|
352
|
-
media_type="text/csv",
|
|
353
|
-
headers={
|
|
354
|
-
"Content-Disposition": f"attachment; filename={filename}"
|
|
355
|
-
}
|
|
356
|
-
)
|
|
357
|
-
except Exception:
|
|
358
|
-
from fastapi import HTTPException
|
|
359
|
-
|
|
360
|
-
raise HTTPException(
|
|
361
|
-
status_code=500,
|
|
362
|
-
detail="Unable to create feedback-file"
|
|
363
|
-
)
|