blaxel 0.1.21rc69__py3-none-any.whl → 0.2.0__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.
- blaxel/__init__.py +6 -3
- blaxel/core/__init__.py +44 -0
- blaxel/core/agents/__init__.py +115 -0
- blaxel/{authentication → core/authentication}/apikey.py +1 -0
- blaxel/{authentication → core/authentication}/clientcredentials.py +6 -2
- blaxel/{client → core/client}/api/agents/create_agent.py +1 -1
- blaxel/{client → core/client}/api/agents/update_agent.py +1 -1
- blaxel/{client → core/client}/api/compute/create_sandbox.py +1 -1
- blaxel/{client → core/client}/api/compute/create_sandbox_preview.py +1 -1
- blaxel/{client → core/client}/api/compute/create_sandbox_preview_token.py +1 -1
- blaxel/{client → core/client}/api/compute/update_sandbox.py +1 -1
- blaxel/{client → core/client}/api/compute/update_sandbox_preview.py +1 -1
- blaxel/{client → core/client}/api/functions/create_function.py +1 -1
- blaxel/{client → core/client}/api/functions/update_function.py +1 -1
- blaxel/{client → core/client}/api/integrations/create_integration_connection.py +1 -1
- blaxel/{client → core/client}/api/integrations/update_integration_connection.py +1 -1
- blaxel/{client → core/client}/api/jobs/create_job.py +1 -1
- blaxel/{client → core/client}/api/jobs/update_job.py +1 -1
- blaxel/{client → core/client}/api/knowledgebases/create_knowledgebase.py +1 -1
- blaxel/{client → core/client}/api/knowledgebases/update_knowledgebase.py +1 -1
- blaxel/{client → core/client}/api/models/create_model.py +1 -1
- blaxel/{client → core/client}/api/models/update_model.py +1 -1
- blaxel/{client → core/client}/api/policies/create_policy.py +1 -1
- blaxel/{client → core/client}/api/policies/update_policy.py +1 -1
- blaxel/{client → core/client}/api/service_accounts/create_api_key_for_service_account.py +1 -1
- blaxel/{client → core/client}/api/service_accounts/create_workspace_service_account.py +1 -1
- blaxel/{client → core/client}/api/service_accounts/update_workspace_service_account.py +1 -1
- blaxel/{client → core/client}/api/workspaces/check_workspace_availability.py +1 -1
- blaxel/{client → core/client}/api/workspaces/create_worspace.py +1 -1
- blaxel/{client → core/client}/api/workspaces/invite_workspace_user.py +1 -1
- blaxel/{client → core/client}/api/workspaces/update_workspace.py +1 -1
- blaxel/{client → core/client}/api/workspaces/update_workspace_user_role.py +1 -1
- blaxel/{client → core/client}/models/__init__.py +18 -0
- blaxel/{client → core/client}/models/agent.py +1 -1
- blaxel/{client → core/client}/models/agent_spec.py +2 -2
- blaxel/core/client/models/billable_time_metric.py +70 -0
- blaxel/{client → core/client}/models/core_spec.py +1 -1
- blaxel/{client → core/client}/models/function.py +1 -1
- blaxel/{client → core/client}/models/function_schema_properties.py +1 -1
- blaxel/{client → core/client}/models/function_spec.py +2 -2
- blaxel/{client → core/client}/models/integration.py +2 -2
- blaxel/{client → core/client}/models/integration_endpoints.py +1 -1
- blaxel/{client → core/client}/models/job.py +1 -1
- blaxel/{client → core/client}/models/job_spec.py +1 -1
- blaxel/{client → core/client}/models/jobs_chart_value.py +2 -2
- blaxel/{client → core/client}/models/knowledgebase.py +1 -1
- blaxel/{client → core/client}/models/location_response.py +1 -1
- blaxel/core/client/models/logs_response.py +63 -0
- blaxel/core/client/models/logs_response_data.py +99 -0
- blaxel/core/client/models/memory_allocation_by_name.py +70 -0
- blaxel/{client → core/client}/models/metadata.py +9 -0
- blaxel/{client → core/client}/models/model.py +1 -1
- blaxel/{client → core/client}/models/model_spec.py +1 -1
- blaxel/{client → core/client}/models/policy_spec.py +2 -2
- blaxel/core/client/models/resource.py +79 -0
- blaxel/core/client/models/resource_log_chart.py +133 -0
- blaxel/core/client/models/resource_log_response.py +83 -0
- blaxel/{client → core/client}/models/resource_metrics.py +27 -3
- blaxel/core/client/models/resource_trace.py +97 -0
- blaxel/{client → core/client}/models/runtime.py +1 -1
- blaxel/{client → core/client}/models/sandbox.py +1 -1
- blaxel/{client → core/client}/models/sandbox_definition.py +1 -1
- blaxel/{client → core/client}/models/sandbox_spec.py +1 -1
- blaxel/{client → core/client}/models/store_agent.py +1 -1
- blaxel/{client → core/client}/models/store_configuration.py +1 -1
- blaxel/{client → core/client}/models/template.py +1 -1
- blaxel/core/client/models/websocket_message.py +106 -0
- blaxel/core/common/__init__.py +6 -0
- blaxel/core/common/autoload.py +21 -0
- blaxel/{common → core/common}/internal.py +34 -62
- blaxel/core/common/logger.py +131 -0
- blaxel/{jobs → core/jobs}/__init__.py +41 -61
- blaxel/core/mcp/__init__.py +4 -0
- blaxel/{mcp → core/mcp}/client.py +26 -15
- blaxel/{mcp → core/mcp}/server.py +12 -37
- blaxel/core/models/__init__.py +52 -0
- blaxel/core/sandbox/__init__.py +29 -0
- blaxel/core/sandbox/action.py +79 -0
- blaxel/{sandbox → core/sandbox}/client/api/filesystem/put_filesystem_path.py +1 -1
- blaxel/{sandbox → core/sandbox}/client/api/network/post_network_process_pid_monitor.py +1 -1
- blaxel/core/sandbox/client/api/process/__init__.py +0 -0
- blaxel/{sandbox → core/sandbox}/client/api/process/delete_process_identifier_kill.py +0 -26
- blaxel/{sandbox → core/sandbox}/client/api/process/post_process.py +1 -1
- blaxel/{sandbox → core/sandbox}/client/models/__init__.py +2 -2
- blaxel/{sandbox → core/sandbox}/client/models/directory.py +2 -2
- blaxel/{sandbox → core/sandbox}/client/models/process_request.py +25 -1
- blaxel/core/sandbox/client/models/process_request_env.py +49 -0
- blaxel/core/sandbox/filesystem.py +280 -0
- blaxel/core/sandbox/network.py +10 -0
- blaxel/{sandbox → core/sandbox}/preview.py +45 -17
- blaxel/core/sandbox/process.py +159 -0
- blaxel/{sandbox → core/sandbox}/sandbox.py +62 -5
- blaxel/core/sandbox/session.py +124 -0
- blaxel/core/sandbox/types.py +103 -0
- blaxel/{tools → core/tools}/__init__.py +63 -91
- blaxel/crewai/__init__.py +4 -0
- blaxel/{models/crewai.py → crewai/model.py} +4 -2
- blaxel/crewai/py.typed +0 -0
- blaxel/crewai/tools.py +26 -0
- blaxel/googleadk/__init__.py +4 -0
- blaxel/{models/googleadk.py → googleadk/model.py} +8 -2
- blaxel/googleadk/py.typed +0 -0
- blaxel/googleadk/tools.py +72 -0
- blaxel/langgraph/__init__.py +4 -0
- blaxel/{models/langchain.py → langgraph/model.py} +8 -4
- blaxel/langgraph/py.typed +0 -0
- blaxel/{tools/langchain.py → langgraph/tools.py} +7 -3
- blaxel/livekit/__init__.py +4 -0
- blaxel/{models/livekit.py → livekit/model.py} +7 -1
- blaxel/livekit/py.typed +0 -0
- blaxel/{tools/livekit.py → livekit/tools.py} +8 -1
- blaxel/llamaindex/__init__.py +4 -0
- blaxel/{models/llamaindex.py → llamaindex/model.py} +6 -3
- blaxel/llamaindex/py.typed +0 -0
- blaxel/{tools/llamaindex.py → llamaindex/tools.py} +7 -4
- blaxel/openai/__init__.py +4 -0
- blaxel/{models/openai.py → openai/model.py} +4 -2
- blaxel/openai/py.typed +0 -0
- blaxel/{tools/openai.py → openai/tools.py} +7 -3
- blaxel/pydantic/__init__.py +4 -0
- blaxel/{models/custom/pydantic → pydantic/custom}/gemini.py +0 -1
- blaxel/{models/pydantic.py → pydantic/model.py} +6 -4
- blaxel/pydantic/py.typed +0 -0
- blaxel/{tools/pydantic.py → pydantic/tools.py} +6 -3
- blaxel/telemetry/__init__.py +6 -0
- blaxel/telemetry/instrumentation/blaxel_core.py +125 -0
- blaxel/telemetry/instrumentation/blaxel_langgraph.py +99 -0
- blaxel/telemetry/instrumentation/blaxel_langgraph_gemini.py +346 -0
- blaxel/telemetry/instrumentation/blaxel_llamaindex.py +85 -0
- blaxel/telemetry/instrumentation/map.py +62 -0
- blaxel/telemetry/instrumentation/utils.py +74 -0
- blaxel/{common → telemetry/log}/logger.py +6 -12
- blaxel/{instrumentation → telemetry}/manager.py +20 -12
- blaxel/telemetry/py.typed +0 -0
- blaxel/{instrumentation → telemetry}/span.py +12 -1
- blaxel-0.2.0.dist-info/METADATA +224 -0
- blaxel-0.2.0.dist-info/RECORD +408 -0
- blaxel/agents/__init__.py +0 -135
- blaxel/common/autoload.py +0 -9
- blaxel/instrumentation/map.py +0 -49
- blaxel/mcp/__init__.py +0 -3
- blaxel/models/__init__.py +0 -104
- blaxel/sandbox/base.py +0 -68
- blaxel/sandbox/client/models/process_kill_request.py +0 -60
- blaxel/sandbox/filesystem.py +0 -104
- blaxel/sandbox/process.py +0 -56
- blaxel/tools/crewai.py +0 -22
- blaxel/tools/googleadk.py +0 -66
- blaxel-0.1.21rc69.dist-info/METADATA +0 -169
- blaxel-0.1.21rc69.dist-info/RECORD +0 -370
- /blaxel/{authentication → core/authentication}/__init__.py +0 -0
- /blaxel/{authentication → core/authentication}/devicemode.py +0 -0
- /blaxel/{authentication → core/authentication}/oauth.py +0 -0
- /blaxel/{authentication → core/authentication}/types.py +0 -0
- /blaxel/{cache → core/cache}/__init__.py +0 -0
- /blaxel/{cache → core/cache}/cache.py +0 -0
- /blaxel/{client → core/client}/__init__.py +0 -0
- /blaxel/{client → core/client}/api/__init__.py +0 -0
- /blaxel/{client → core/client}/api/agents/__init__.py +0 -0
- /blaxel/{client → core/client}/api/agents/delete_agent.py +0 -0
- /blaxel/{client → core/client}/api/agents/get_agent.py +0 -0
- /blaxel/{client → core/client}/api/agents/list_agent_revisions.py +0 -0
- /blaxel/{client → core/client}/api/agents/list_agents.py +0 -0
- /blaxel/{client → core/client}/api/compute/__init__.py +0 -0
- /blaxel/{client → core/client}/api/compute/delete_sandbox.py +0 -0
- /blaxel/{client → core/client}/api/compute/delete_sandbox_preview.py +0 -0
- /blaxel/{client → core/client}/api/compute/delete_sandbox_preview_token.py +0 -0
- /blaxel/{client → core/client}/api/compute/get_sandbox.py +0 -0
- /blaxel/{client → core/client}/api/compute/get_sandbox_preview.py +0 -0
- /blaxel/{client → core/client}/api/compute/list_sandbox_preview_tokens.py +0 -0
- /blaxel/{client → core/client}/api/compute/list_sandbox_previews.py +0 -0
- /blaxel/{client → core/client}/api/compute/list_sandboxes.py +0 -0
- /blaxel/{client → core/client}/api/compute/start_sandbox.py +0 -0
- /blaxel/{client → core/client}/api/compute/stop_sandbox.py +0 -0
- /blaxel/{client → core/client}/api/configurations/__init__.py +0 -0
- /blaxel/{client → core/client}/api/configurations/get_configuration.py +0 -0
- /blaxel/{client → core/client}/api/default/__init__.py +0 -0
- /blaxel/{client → core/client}/api/default/get_template.py +0 -0
- /blaxel/{client → core/client}/api/default/list_mcp_hub_definitions.py +0 -0
- /blaxel/{client → core/client}/api/default/list_sandbox_hub_definitions.py +0 -0
- /blaxel/{client → core/client}/api/functions/__init__.py +0 -0
- /blaxel/{client → core/client}/api/functions/delete_function.py +0 -0
- /blaxel/{client → core/client}/api/functions/get_function.py +0 -0
- /blaxel/{client → core/client}/api/functions/list_function_revisions.py +0 -0
- /blaxel/{client → core/client}/api/functions/list_functions.py +0 -0
- /blaxel/{client → core/client}/api/integrations/__init__.py +0 -0
- /blaxel/{client → core/client}/api/integrations/delete_integration_connection.py +0 -0
- /blaxel/{client → core/client}/api/integrations/get_integration.py +0 -0
- /blaxel/{client → core/client}/api/integrations/get_integration_connection.py +0 -0
- /blaxel/{client → core/client}/api/integrations/get_integration_connection_model.py +0 -0
- /blaxel/{client → core/client}/api/integrations/get_integration_connection_model_endpoint_configurations.py +0 -0
- /blaxel/{client → core/client}/api/integrations/list_integration_connection_models.py +0 -0
- /blaxel/{client → core/client}/api/integrations/list_integration_connections.py +0 -0
- /blaxel/{client → core/client}/api/invitations/__init__.py +0 -0
- /blaxel/{client → core/client}/api/invitations/list_all_pending_invitations.py +0 -0
- /blaxel/{client → core/client}/api/jobs/__init__.py +0 -0
- /blaxel/{client → core/client}/api/jobs/delete_job.py +0 -0
- /blaxel/{client → core/client}/api/jobs/get_job.py +0 -0
- /blaxel/{client → core/client}/api/jobs/list_job_revisions.py +0 -0
- /blaxel/{client → core/client}/api/jobs/list_jobs.py +0 -0
- /blaxel/{client → core/client}/api/knowledgebases/__init__.py +0 -0
- /blaxel/{client → core/client}/api/knowledgebases/delete_knowledgebase.py +0 -0
- /blaxel/{client → core/client}/api/knowledgebases/get_knowledgebase.py +0 -0
- /blaxel/{client → core/client}/api/knowledgebases/list_knowledgebase_revisions.py +0 -0
- /blaxel/{client → core/client}/api/knowledgebases/list_knowledgebases.py +0 -0
- /blaxel/{client → core/client}/api/locations/__init__.py +0 -0
- /blaxel/{client → core/client}/api/locations/list_locations.py +0 -0
- /blaxel/{client → core/client}/api/models/__init__.py +0 -0
- /blaxel/{client → core/client}/api/models/delete_model.py +0 -0
- /blaxel/{client → core/client}/api/models/get_model.py +0 -0
- /blaxel/{client → core/client}/api/models/list_model_revisions.py +0 -0
- /blaxel/{client → core/client}/api/models/list_models.py +0 -0
- /blaxel/{client → core/client}/api/policies/__init__.py +0 -0
- /blaxel/{client → core/client}/api/policies/delete_policy.py +0 -0
- /blaxel/{client → core/client}/api/policies/get_policy.py +0 -0
- /blaxel/{client → core/client}/api/policies/list_policies.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/__init__.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/create_private_cluster.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/delete_private_cluster.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/get_private_cluster.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/get_private_cluster_health.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/list_private_clusters.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/update_private_cluster.py +0 -0
- /blaxel/{client → core/client}/api/privateclusters/update_private_cluster_health.py +0 -0
- /blaxel/{client → core/client}/api/service_accounts/__init__.py +0 -0
- /blaxel/{client → core/client}/api/service_accounts/delete_api_key_for_service_account.py +0 -0
- /blaxel/{client → core/client}/api/service_accounts/delete_workspace_service_account.py +0 -0
- /blaxel/{client → core/client}/api/service_accounts/get_workspace_service_accounts.py +0 -0
- /blaxel/{client → core/client}/api/service_accounts/list_api_keys_for_service_account.py +0 -0
- /blaxel/{client → core/client}/api/templates/__init__.py +0 -0
- /blaxel/{client → core/client}/api/templates/list_templates.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/__init__.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/accept_workspace_invitation.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/decline_workspace_invitation.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/delete_workspace.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/get_workspace.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/leave_workspace.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/list_workspace_users.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/list_workspaces.py +0 -0
- /blaxel/{client → core/client}/api/workspaces/remove_workspace_user.py +0 -0
- /blaxel/{client → core/client}/client.py +0 -0
- /blaxel/{client → core/client}/errors.py +0 -0
- /blaxel/{client → core/client}/models/acl.py +0 -0
- /blaxel/{client → core/client}/models/api_key.py +0 -0
- /blaxel/{client → core/client}/models/check_workspace_availability_body.py +0 -0
- /blaxel/{client → core/client}/models/configuration.py +0 -0
- /blaxel/{client → core/client}/models/continent.py +0 -0
- /blaxel/{client → core/client}/models/core_event.py +0 -0
- /blaxel/{client → core/client}/models/core_spec_configurations.py +0 -0
- /blaxel/{client → core/client}/models/country.py +0 -0
- /blaxel/{client → core/client}/models/create_api_key_for_service_account_body.py +0 -0
- /blaxel/{client → core/client}/models/create_workspace_service_account_body.py +0 -0
- /blaxel/{client → core/client}/models/create_workspace_service_account_response_200.py +0 -0
- /blaxel/{client → core/client}/models/delete_sandbox_preview_token_response_200.py +0 -0
- /blaxel/{client → core/client}/models/delete_workspace_service_account_response_200.py +0 -0
- /blaxel/{client → core/client}/models/entrypoint.py +0 -0
- /blaxel/{client → core/client}/models/entrypoint_env.py +0 -0
- /blaxel/{client → core/client}/models/flavor.py +0 -0
- /blaxel/{client → core/client}/models/form.py +0 -0
- /blaxel/{client → core/client}/models/form_config.py +0 -0
- /blaxel/{client → core/client}/models/form_oauth.py +0 -0
- /blaxel/{client → core/client}/models/form_secrets.py +0 -0
- /blaxel/{client → core/client}/models/function_kit.py +0 -0
- /blaxel/{client → core/client}/models/function_schema.py +0 -0
- /blaxel/{client → core/client}/models/function_schema_not.py +0 -0
- /blaxel/{client → core/client}/models/function_schema_or_bool.py +0 -0
- /blaxel/{client → core/client}/models/get_workspace_service_accounts_response_200_item.py +0 -0
- /blaxel/{client → core/client}/models/histogram_bucket.py +0 -0
- /blaxel/{client → core/client}/models/histogram_stats.py +0 -0
- /blaxel/{client → core/client}/models/integration_additional_infos.py +0 -0
- /blaxel/{client → core/client}/models/integration_connection.py +0 -0
- /blaxel/{client → core/client}/models/integration_connection_spec.py +0 -0
- /blaxel/{client → core/client}/models/integration_connection_spec_config.py +0 -0
- /blaxel/{client → core/client}/models/integration_connection_spec_secret.py +0 -0
- /blaxel/{client → core/client}/models/integration_endpoint.py +0 -0
- /blaxel/{client → core/client}/models/integration_endpoint_token.py +0 -0
- /blaxel/{client → core/client}/models/integration_headers.py +0 -0
- /blaxel/{client → core/client}/models/integration_model.py +0 -0
- /blaxel/{client → core/client}/models/integration_organization.py +0 -0
- /blaxel/{client → core/client}/models/integration_query_params.py +0 -0
- /blaxel/{client → core/client}/models/integration_repository.py +0 -0
- /blaxel/{client → core/client}/models/invite_workspace_user_body.py +0 -0
- /blaxel/{client → core/client}/models/job_execution_config.py +0 -0
- /blaxel/{client → core/client}/models/job_metrics.py +0 -0
- /blaxel/{client → core/client}/models/job_metrics_executions_chart.py +0 -0
- /blaxel/{client → core/client}/models/job_metrics_executions_total.py +0 -0
- /blaxel/{client → core/client}/models/job_metrics_tasks_chart.py +0 -0
- /blaxel/{client → core/client}/models/job_metrics_tasks_total.py +0 -0
- /blaxel/{client → core/client}/models/jobs_chart.py +0 -0
- /blaxel/{client → core/client}/models/jobs_executions.py +0 -0
- /blaxel/{client → core/client}/models/jobs_network_chart.py +0 -0
- /blaxel/{client → core/client}/models/jobs_success_failed_chart.py +0 -0
- /blaxel/{client → core/client}/models/jobs_tasks.py +0 -0
- /blaxel/{client → core/client}/models/jobs_total.py +0 -0
- /blaxel/{client → core/client}/models/knowledgebase_spec.py +0 -0
- /blaxel/{client → core/client}/models/knowledgebase_spec_options.py +0 -0
- /blaxel/{client → core/client}/models/last_n_requests_metric.py +0 -0
- /blaxel/{client → core/client}/models/latency_metric.py +0 -0
- /blaxel/{client → core/client}/models/mcp_definition.py +0 -0
- /blaxel/{client → core/client}/models/mcp_definition_entrypoint.py +0 -0
- /blaxel/{client → core/client}/models/mcp_definition_form.py +0 -0
- /blaxel/{client → core/client}/models/memory_allocation_metric.py +0 -0
- /blaxel/{client → core/client}/models/metadata_labels.py +0 -0
- /blaxel/{client → core/client}/models/metric.py +0 -0
- /blaxel/{client → core/client}/models/metrics.py +0 -0
- /blaxel/{client → core/client}/models/metrics_models.py +0 -0
- /blaxel/{client → core/client}/models/metrics_request_total_per_code.py +0 -0
- /blaxel/{client → core/client}/models/metrics_rps_per_code.py +0 -0
- /blaxel/{client → core/client}/models/model_private_cluster.py +0 -0
- /blaxel/{client → core/client}/models/o_auth.py +0 -0
- /blaxel/{client → core/client}/models/owner_fields.py +0 -0
- /blaxel/{client → core/client}/models/pending_invitation.py +0 -0
- /blaxel/{client → core/client}/models/pending_invitation_accept.py +0 -0
- /blaxel/{client → core/client}/models/pending_invitation_render.py +0 -0
- /blaxel/{client → core/client}/models/pending_invitation_render_invited_by.py +0 -0
- /blaxel/{client → core/client}/models/pending_invitation_render_workspace.py +0 -0
- /blaxel/{client → core/client}/models/pending_invitation_workspace_details.py +0 -0
- /blaxel/{client → core/client}/models/pod_template_spec.py +0 -0
- /blaxel/{client → core/client}/models/policy.py +0 -0
- /blaxel/{client → core/client}/models/policy_location.py +0 -0
- /blaxel/{client → core/client}/models/policy_max_tokens.py +0 -0
- /blaxel/{client → core/client}/models/port.py +0 -0
- /blaxel/{client → core/client}/models/preview.py +0 -0
- /blaxel/{client → core/client}/models/preview_metadata.py +0 -0
- /blaxel/{client → core/client}/models/preview_spec.py +0 -0
- /blaxel/{client → core/client}/models/preview_spec_request_headers.py +0 -0
- /blaxel/{client → core/client}/models/preview_spec_response_headers.py +0 -0
- /blaxel/{client → core/client}/models/preview_token.py +0 -0
- /blaxel/{client → core/client}/models/preview_token_metadata.py +0 -0
- /blaxel/{client → core/client}/models/preview_token_spec.py +0 -0
- /blaxel/{client → core/client}/models/private_cluster.py +0 -0
- /blaxel/{client → core/client}/models/private_location.py +0 -0
- /blaxel/{client → core/client}/models/repository.py +0 -0
- /blaxel/{client → core/client}/models/request_duration_over_time_metric.py +0 -0
- /blaxel/{client → core/client}/models/request_duration_over_time_metrics.py +0 -0
- /blaxel/{client → core/client}/models/request_total_by_origin_metric.py +0 -0
- /blaxel/{client → core/client}/models/request_total_by_origin_metric_request_total_by_origin.py +0 -0
- /blaxel/{client → core/client}/models/request_total_by_origin_metric_request_total_by_origin_and_code.py +0 -0
- /blaxel/{client → core/client}/models/request_total_metric.py +0 -0
- /blaxel/{client → core/client}/models/request_total_metric_request_total_per_code.py +0 -0
- /blaxel/{client → core/client}/models/request_total_metric_rps_per_code.py +0 -0
- /blaxel/{client → core/client}/models/request_total_response_data.py +0 -0
- /blaxel/{client → core/client}/models/resource_log.py +0 -0
- /blaxel/{client → core/client}/models/resource_metrics_request_total_per_code.py +0 -0
- /blaxel/{client → core/client}/models/resource_metrics_request_total_per_code_previous.py +0 -0
- /blaxel/{client → core/client}/models/resource_metrics_rps_per_code.py +0 -0
- /blaxel/{client → core/client}/models/resource_metrics_rps_per_code_previous.py +0 -0
- /blaxel/{client → core/client}/models/revision_configuration.py +0 -0
- /blaxel/{client → core/client}/models/revision_metadata.py +0 -0
- /blaxel/{client → core/client}/models/runtime_configuration.py +0 -0
- /blaxel/{client → core/client}/models/runtime_startup_probe.py +0 -0
- /blaxel/{client → core/client}/models/serverless_config.py +0 -0
- /blaxel/{client → core/client}/models/serverless_config_configuration.py +0 -0
- /blaxel/{client → core/client}/models/spec_configuration.py +0 -0
- /blaxel/{client → core/client}/models/start_sandbox.py +0 -0
- /blaxel/{client → core/client}/models/stop_sandbox.py +0 -0
- /blaxel/{client → core/client}/models/store_agent_labels.py +0 -0
- /blaxel/{client → core/client}/models/store_configuration_option.py +0 -0
- /blaxel/{client → core/client}/models/template_variable.py +0 -0
- /blaxel/{client → core/client}/models/time_fields.py +0 -0
- /blaxel/{client → core/client}/models/time_to_first_token_over_time_metrics.py +0 -0
- /blaxel/{client → core/client}/models/token_rate_metric.py +0 -0
- /blaxel/{client → core/client}/models/token_rate_metrics.py +0 -0
- /blaxel/{client → core/client}/models/token_total_metric.py +0 -0
- /blaxel/{client → core/client}/models/trace_ids_response.py +0 -0
- /blaxel/{client → core/client}/models/trigger.py +0 -0
- /blaxel/{client → core/client}/models/trigger_configuration.py +0 -0
- /blaxel/{client → core/client}/models/update_workspace_service_account_body.py +0 -0
- /blaxel/{client → core/client}/models/update_workspace_service_account_response_200.py +0 -0
- /blaxel/{client → core/client}/models/update_workspace_user_role_body.py +0 -0
- /blaxel/{client → core/client}/models/websocket_channel.py +0 -0
- /blaxel/{client → core/client}/models/workspace.py +0 -0
- /blaxel/{client → core/client}/models/workspace_labels.py +0 -0
- /blaxel/{client → core/client}/models/workspace_runtime.py +0 -0
- /blaxel/{client → core/client}/models/workspace_user.py +0 -0
- /blaxel/{client → core/client}/py.typed +0 -0
- /blaxel/{client → core/client}/types.py +0 -0
- /blaxel/{common → core/common}/env.py +0 -0
- /blaxel/{common → core/common}/settings.py +0 -0
- /blaxel/{sandbox/client/api/filesystem/__init__.py → core/py.typed} +0 -0
- /blaxel/{sandbox → core/sandbox}/client/__init__.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/__init__.py +0 -0
- /blaxel/{sandbox/client/api/network → core/sandbox/client/api/filesystem}/__init__.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/filesystem/delete_filesystem_path.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/filesystem/get_filesystem_path.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/filesystem/get_watch_filesystem_path.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/filesystem/get_ws_watch_filesystem_path.py +0 -0
- /blaxel/{sandbox/client/api/process → core/sandbox/client/api/network}/__init__.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/network/delete_network_process_pid_monitor.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/network/get_network_process_pid_ports.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/process/delete_process_identifier.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/process/get_process.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/process/get_process_identifier.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/process/get_process_identifier_logs.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/process/get_process_identifier_logs_stream.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/api/process/get_ws_process_identifier_logs_stream.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/client.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/errors.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/delete_network_process_pid_monitor_response_200.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/error_response.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/file.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/file_request.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/file_with_content.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/get_network_process_pid_ports_response_200.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/port_monitor_request.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/post_network_process_pid_monitor_response_200.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/process_logs.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/process_response.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/process_response_status.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/subdirectory.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/models/success_response.py +0 -0
- /blaxel/{sandbox → core/sandbox}/client/py.typed +0 -0
- /blaxel/{sandbox → core/sandbox}/client/types.py +0 -0
- /blaxel/{tools → core/tools}/common.py +0 -0
- /blaxel/{tools → core/tools}/types.py +0 -0
- /blaxel/{models/custom/langchain → langgraph/custom}/gemini.py +0 -0
- /blaxel/{models/custom/llamaindex → llamaindex/custom}/cohere.py +0 -0
- /blaxel/{instrumentation → telemetry}/exporters.py +0 -0
- /blaxel/{instrumentation → telemetry/log}/log.py +0 -0
- {blaxel-0.1.21rc69.dist-info → blaxel-0.2.0.dist-info}/WHEEL +0 -0
- {blaxel-0.1.21rc69.dist-info → blaxel-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,29 +1,30 @@
|
|
1
1
|
import hashlib
|
2
|
-
import os
|
3
2
|
from logging import getLogger
|
4
3
|
from typing import Optional
|
4
|
+
|
5
5
|
from .env import env
|
6
6
|
|
7
7
|
logger = getLogger(__name__)
|
8
8
|
|
9
|
+
|
9
10
|
def get_alphanumeric_limited_hash(input_str, max_size=48):
|
10
11
|
"""
|
11
12
|
Create an alphanumeric hash using MD5 that can be reproduced in Go, TypeScript, and Python.
|
12
|
-
|
13
|
+
|
13
14
|
Args:
|
14
15
|
input_str (str): The input string to hash
|
15
16
|
max_size (int): The maximum length of the returned hash
|
16
|
-
|
17
|
+
|
17
18
|
Returns:
|
18
19
|
str: An alphanumeric hash of the input string, limited to max_size
|
19
20
|
"""
|
20
21
|
# Calculate MD5 hash and convert to hexadecimal
|
21
|
-
hash_hex = hashlib.md5(input_str.encode(
|
22
|
-
|
22
|
+
hash_hex = hashlib.md5(input_str.encode("utf-8")).hexdigest()
|
23
|
+
|
23
24
|
# Limit to max_size
|
24
25
|
if len(hash_hex) > max_size:
|
25
26
|
return hash_hex[:max_size]
|
26
|
-
|
27
|
+
|
27
28
|
return hash_hex
|
28
29
|
|
29
30
|
|
@@ -43,103 +44,74 @@ def get_global_unique_hash(workspace: str, type: str, name: str) -> str:
|
|
43
44
|
hash = get_alphanumeric_limited_hash(global_unique_name, 48)
|
44
45
|
return hash
|
45
46
|
|
46
|
-
class Agent:
|
47
|
-
def __init__(self, agent_name: str, workspace: str, run_internal_protocol: str, run_internal_hostname: str):
|
48
|
-
self.agent_name = agent_name
|
49
|
-
self.workspace = workspace
|
50
|
-
self.run_internal_protocol = run_internal_protocol
|
51
|
-
self.run_internal_hostname = run_internal_hostname
|
52
|
-
|
53
|
-
@property
|
54
|
-
def internal_url(self) -> str:
|
55
|
-
"""
|
56
|
-
Generate the internal URL for the agent using a unique hash.
|
57
|
-
|
58
|
-
Returns:
|
59
|
-
The internal URL as a string
|
60
|
-
"""
|
61
|
-
hash_value = get_global_unique_hash(
|
62
|
-
self.workspace,
|
63
|
-
"agent",
|
64
|
-
self.agent_name
|
65
|
-
)
|
66
|
-
return f"{self.run_internal_protocol}://{hash_value}.{self.run_internal_hostname}"
|
67
|
-
|
68
|
-
@property
|
69
|
-
def forced_url(self) -> Optional[str]:
|
70
|
-
"""
|
71
|
-
Check for a forced URL in environment variables.
|
72
|
-
|
73
|
-
Returns:
|
74
|
-
The forced URL if found in environment variables, None otherwise
|
75
|
-
"""
|
76
|
-
env_var = self.agent_name.replace("-", "_").upper()
|
77
|
-
env_key = f"BL_AGENT_{env_var}_URL"
|
78
|
-
return os.environ.get(env_key)
|
79
47
|
|
80
48
|
def pluralize(type_str: str) -> str:
|
81
49
|
"""
|
82
50
|
Convert a string to its plural form following English pluralization rules.
|
83
|
-
|
51
|
+
|
84
52
|
Args:
|
85
53
|
type_str: The input string to pluralize
|
86
|
-
|
54
|
+
|
87
55
|
Returns:
|
88
56
|
The pluralized form of the input string
|
89
57
|
"""
|
90
58
|
word = type_str.lower()
|
91
59
|
|
92
60
|
# Words ending in s, ss, sh, ch, x, z - add 'es'
|
93
|
-
if (
|
94
|
-
word.endswith(
|
95
|
-
|
61
|
+
if (
|
62
|
+
word.endswith("s")
|
63
|
+
or word.endswith("ss")
|
64
|
+
or word.endswith("sh")
|
65
|
+
or word.endswith("ch")
|
66
|
+
or word.endswith("x")
|
67
|
+
or word.endswith("z")
|
68
|
+
):
|
69
|
+
return type_str + "es"
|
96
70
|
|
97
71
|
# Words ending in consonant + y - change y to ies
|
98
|
-
if word.endswith(
|
72
|
+
if word.endswith("y") and len(word) > 1:
|
99
73
|
before_y = word[-2]
|
100
|
-
if before_y not in
|
101
|
-
return type_str[:-1] +
|
74
|
+
if before_y not in "aeiou":
|
75
|
+
return type_str[:-1] + "ies"
|
102
76
|
|
103
77
|
# Words ending in f or fe - change to ves
|
104
|
-
if word.endswith(
|
105
|
-
return type_str[:-1] +
|
106
|
-
if word.endswith(
|
107
|
-
return type_str[:-2] +
|
78
|
+
if word.endswith("f"):
|
79
|
+
return type_str[:-1] + "ves"
|
80
|
+
if word.endswith("fe"):
|
81
|
+
return type_str[:-2] + "ves"
|
108
82
|
|
109
83
|
# Words ending in consonant + o - add 'es'
|
110
|
-
if word.endswith(
|
84
|
+
if word.endswith("o") and len(word) > 1:
|
111
85
|
before_o = word[-2]
|
112
|
-
if before_o not in
|
113
|
-
return type_str +
|
86
|
+
if before_o not in "aeiou":
|
87
|
+
return type_str + "es"
|
114
88
|
|
115
89
|
# Default case - just add 's'
|
116
|
-
return type_str +
|
90
|
+
return type_str + "s"
|
117
91
|
|
118
92
|
|
119
93
|
def get_forced_url(type_str: str, name: str) -> Optional[str]:
|
120
94
|
"""
|
121
95
|
Check for forced URLs in environment variables using both plural and singular forms.
|
122
|
-
|
96
|
+
|
123
97
|
Args:
|
124
98
|
type_str: The type identifier
|
125
99
|
name: The name identifier
|
126
|
-
|
100
|
+
|
127
101
|
Returns:
|
128
102
|
The forced URL if found in environment variables, None otherwise
|
129
103
|
"""
|
130
104
|
plural_type = pluralize(type_str)
|
131
105
|
env_var = name.replace("-", "_").upper()
|
132
|
-
|
106
|
+
|
133
107
|
# BL_FUNCTIONS_NAME_URL (plural form)
|
134
108
|
plural_env_key = f"BL_{plural_type.upper()}_{env_var}_URL"
|
135
109
|
if env[plural_env_key] is not None:
|
136
110
|
return env[plural_env_key]
|
137
|
-
|
111
|
+
|
138
112
|
# BL_FUNCTION_NAME_URL (singular form)
|
139
113
|
singular_env_key = f"BL_{type_str.upper()}_{env_var}_URL"
|
140
114
|
if env[singular_env_key] is not None:
|
141
115
|
return env[singular_env_key]
|
142
|
-
|
143
|
-
return None
|
144
|
-
|
145
116
|
|
117
|
+
return None
|
@@ -0,0 +1,131 @@
|
|
1
|
+
"""
|
2
|
+
This module provides a custom colored formatter for logging and an initialization function
|
3
|
+
to set up logging configurations for Blaxel applications.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import json
|
7
|
+
import logging
|
8
|
+
import os
|
9
|
+
|
10
|
+
try:
|
11
|
+
from opentelemetry.trace import get_current_span
|
12
|
+
|
13
|
+
HAS_OPENTELEMETRY = True
|
14
|
+
except ImportError:
|
15
|
+
HAS_OPENTELEMETRY = False
|
16
|
+
|
17
|
+
def get_current_span():
|
18
|
+
"""Fallback function when opentelemetry is not available."""
|
19
|
+
return None
|
20
|
+
|
21
|
+
|
22
|
+
class JsonFormatter(logging.Formatter):
|
23
|
+
"""
|
24
|
+
A logger compatible with standard json logging.
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(self):
|
28
|
+
super().__init__()
|
29
|
+
self.trace_id_name = os.environ.get("BL_LOGGER_TRACE_ID", "trace_id")
|
30
|
+
self.span_id_name = os.environ.get("BL_LOGGER_SPAN_ID", "span_id")
|
31
|
+
self.labels_name = os.environ.get("BL_LOGGER_LABELS", "labels")
|
32
|
+
self.trace_id_prefix = os.environ.get("BL_LOGGER_TRACE_ID_PREFIX", "")
|
33
|
+
self.span_id_prefix = os.environ.get("BL_LOGGER_SPAN_ID_PREFIX", "")
|
34
|
+
self.task_index = os.environ.get("BL_TASK_KEY", "TASK_INDEX")
|
35
|
+
self.task_prefix = os.environ.get("BL_TASK_PREFIX", "")
|
36
|
+
self.execution_key = os.environ.get("BL_EXECUTION_KEY", "BL_EXECUTION_ID")
|
37
|
+
self.execution_prefix = os.environ.get("BL_EXECUTION_PREFIX", "")
|
38
|
+
|
39
|
+
def format(self, record):
|
40
|
+
"""
|
41
|
+
Formats the log record by converting it to a JSON object with trace context and environment variables.
|
42
|
+
"""
|
43
|
+
log_entry = {
|
44
|
+
"message": record.getMessage(),
|
45
|
+
"severity": record.levelname,
|
46
|
+
self.labels_name: {},
|
47
|
+
}
|
48
|
+
|
49
|
+
# Get current active span - equivalent to trace.getActiveSpan() in JS
|
50
|
+
if HAS_OPENTELEMETRY:
|
51
|
+
current_span = get_current_span()
|
52
|
+
|
53
|
+
# Check if span exists and has valid context (equivalent to 'if (currentSpan)' in JS)
|
54
|
+
if current_span and current_span.get_span_context().is_valid:
|
55
|
+
span_context = current_span.get_span_context()
|
56
|
+
# Format trace_id and span_id as hex strings (like JS does)
|
57
|
+
trace_id_hex = format(span_context.trace_id, "032x")
|
58
|
+
span_id_hex = format(span_context.span_id, "016x")
|
59
|
+
|
60
|
+
log_entry[self.trace_id_name] = f"{self.trace_id_prefix}{trace_id_hex}"
|
61
|
+
log_entry[self.span_id_name] = f"{self.span_id_prefix}{span_id_hex}"
|
62
|
+
|
63
|
+
# Add task ID if available
|
64
|
+
task_id = os.environ.get(self.task_index)
|
65
|
+
if task_id:
|
66
|
+
log_entry[self.labels_name]["blaxel-task"] = f"{self.task_prefix}{task_id}"
|
67
|
+
|
68
|
+
# Add execution ID if available
|
69
|
+
execution_id = os.environ.get(self.execution_key)
|
70
|
+
if execution_id:
|
71
|
+
log_entry[self.labels_name]["blaxel-execution"] = (
|
72
|
+
f"{self.execution_prefix}{execution_id.split('-')[-1]}"
|
73
|
+
)
|
74
|
+
|
75
|
+
return json.dumps(log_entry)
|
76
|
+
|
77
|
+
|
78
|
+
class ColoredFormatter(logging.Formatter):
|
79
|
+
"""
|
80
|
+
A custom logging formatter that adds ANSI color codes to log levels for enhanced readability.
|
81
|
+
|
82
|
+
Attributes:
|
83
|
+
COLORS (dict): A mapping of log level names to their corresponding ANSI color codes.
|
84
|
+
"""
|
85
|
+
|
86
|
+
COLORS = {
|
87
|
+
"DEBUG": "\033[1;36m", # Cyan
|
88
|
+
"INFO": "\033[1;32m", # Green
|
89
|
+
"WARNING": "\033[1;33m", # Yellow
|
90
|
+
"ERROR": "\033[1;31m", # Red
|
91
|
+
"CRITICAL": "\033[1;41m", # Red background
|
92
|
+
}
|
93
|
+
|
94
|
+
def format(self, record):
|
95
|
+
"""
|
96
|
+
Formats the log record by adding color codes based on the log level.
|
97
|
+
|
98
|
+
Parameters:
|
99
|
+
record (LogRecord): The log record to format.
|
100
|
+
|
101
|
+
Returns:
|
102
|
+
str: The formatted log message with appropriate color codes.
|
103
|
+
"""
|
104
|
+
n_spaces = len("CRITICAL") - len(record.levelname)
|
105
|
+
tab = " " * n_spaces
|
106
|
+
color = self.COLORS.get(record.levelname, "\033[0m")
|
107
|
+
record.levelname = f"{color}{record.levelname}\033[0m:{tab}"
|
108
|
+
return super().format(record)
|
109
|
+
|
110
|
+
|
111
|
+
def init_logger(log_level: str):
|
112
|
+
"""
|
113
|
+
Initializes the logging configuration for Blaxel.
|
114
|
+
|
115
|
+
This function clears existing handlers for specific loggers, sets up a colored formatter,
|
116
|
+
and configures the root logger with the specified log level.
|
117
|
+
|
118
|
+
Parameters:
|
119
|
+
log_level (str): The logging level to set (e.g., "DEBUG", "INFO").
|
120
|
+
"""
|
121
|
+
# Disable urllib3 logging
|
122
|
+
logging.getLogger("urllib3").setLevel(logging.CRITICAL)
|
123
|
+
logging.getLogger("httpx").setLevel(logging.CRITICAL)
|
124
|
+
handler = logging.StreamHandler()
|
125
|
+
|
126
|
+
logger_type = os.environ.get("BL_LOGGER", "http")
|
127
|
+
if logger_type == "json":
|
128
|
+
handler.setFormatter(JsonFormatter())
|
129
|
+
else:
|
130
|
+
handler.setFormatter(ColoredFormatter("%(levelname)s %(name)s - %(message)s"))
|
131
|
+
logging.basicConfig(level=log_level, handlers=[handler])
|
@@ -8,14 +8,13 @@ from typing import Any, Awaitable, Callable, Dict
|
|
8
8
|
import requests
|
9
9
|
|
10
10
|
from ..client import client
|
11
|
-
from ..common.internal import
|
11
|
+
from ..common.internal import get_forced_url, get_global_unique_hash
|
12
12
|
from ..common.settings import settings
|
13
|
-
from ..instrumentation.span import SpanManager
|
14
13
|
|
15
14
|
|
16
15
|
class BlJobWrapper:
|
17
16
|
def get_arguments(self) -> Dict[str, Any]:
|
18
|
-
if not os.getenv(
|
17
|
+
if not os.getenv("BL_EXECUTION_DATA_URL"):
|
19
18
|
parser = argparse.ArgumentParser()
|
20
19
|
# Parse known args, ignore unknown
|
21
20
|
args, unknown = parser.parse_known_args()
|
@@ -24,18 +23,18 @@ class BlJobWrapper:
|
|
24
23
|
# Add unknown args to dict
|
25
24
|
for i in range(0, len(unknown), 2):
|
26
25
|
if i + 1 < len(unknown):
|
27
|
-
key = unknown[i].lstrip(
|
26
|
+
key = unknown[i].lstrip("-")
|
28
27
|
args_dict[key] = unknown[i + 1]
|
29
28
|
return args_dict
|
30
29
|
|
31
|
-
response = requests.get(os.getenv(
|
30
|
+
response = requests.get(os.getenv("BL_EXECUTION_DATA_URL"))
|
32
31
|
data = response.json()
|
33
|
-
tasks = data.get(
|
32
|
+
tasks = data.get("tasks", [])
|
34
33
|
return tasks[self.index] if self.index < len(tasks) else {}
|
35
34
|
|
36
35
|
@property
|
37
36
|
def index_key(self) -> str:
|
38
|
-
return os.getenv(
|
37
|
+
return os.getenv("BL_TASK_KEY", "TASK_INDEX")
|
39
38
|
|
40
39
|
@property
|
41
40
|
def index(self) -> int:
|
@@ -55,14 +54,13 @@ class BlJobWrapper:
|
|
55
54
|
else:
|
56
55
|
func(**parsed_args)
|
57
56
|
except Exception as error:
|
58
|
-
print(
|
57
|
+
print("Job execution failed:", error, file=sys.stderr)
|
59
58
|
sys.exit(1)
|
60
59
|
|
61
60
|
|
62
|
-
|
63
|
-
|
64
61
|
logger = getLogger(__name__)
|
65
62
|
|
63
|
+
|
66
64
|
class BlJob:
|
67
65
|
def __init__(self, name: str):
|
68
66
|
self.name = name
|
@@ -97,73 +95,55 @@ class BlJob:
|
|
97
95
|
return self.external_url
|
98
96
|
|
99
97
|
def call(self, url, input_data, headers: dict = {}, params: dict = {}):
|
100
|
-
body = {
|
101
|
-
"tasks": input_data
|
102
|
-
}
|
98
|
+
body = {"tasks": input_data}
|
103
99
|
|
104
100
|
return client.get_httpx_client().post(
|
105
|
-
url+"/executions",
|
106
|
-
headers={
|
107
|
-
'Content-Type': 'application/json',
|
108
|
-
**headers
|
109
|
-
},
|
101
|
+
url + "/executions",
|
102
|
+
headers={"Content-Type": "application/json", **headers},
|
110
103
|
json=body,
|
111
|
-
params=params
|
104
|
+
params=params,
|
112
105
|
)
|
113
106
|
|
114
107
|
async def acall(self, url, input_data, headers: dict = {}, params: dict = {}):
|
115
108
|
logger.debug(f"Job Calling: {self.name}")
|
116
|
-
body = {
|
117
|
-
"tasks": input_data
|
118
|
-
}
|
109
|
+
body = {"tasks": input_data}
|
119
110
|
|
120
111
|
return await client.get_async_httpx_client().post(
|
121
|
-
url+"/executions",
|
122
|
-
headers={
|
123
|
-
'Content-Type': 'application/json',
|
124
|
-
**headers
|
125
|
-
},
|
112
|
+
url + "/executions",
|
113
|
+
headers={"Content-Type": "application/json", **headers},
|
126
114
|
json=body,
|
127
|
-
params=params
|
115
|
+
params=params,
|
128
116
|
)
|
129
117
|
|
130
118
|
def run(self, input: Any, headers: dict = {}, params: dict = {}) -> str:
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
119
|
+
logger.debug(f"Job Calling: {self.name}")
|
120
|
+
response = self.call(self.url, input, headers, params)
|
121
|
+
if response.status_code >= 400:
|
122
|
+
if not self.fallback_url:
|
123
|
+
raise Exception(
|
124
|
+
f"Job {self.name} returned status code {response.status_code} with body {response.text}"
|
125
|
+
)
|
126
|
+
response = self.call(self.fallback_url, input, headers, params)
|
138
127
|
if response.status_code >= 400:
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
if response.status_code >= 400:
|
144
|
-
span.set_attribute("job.run.error", response.text)
|
145
|
-
raise Exception(f"Job {self.name} returned status code {response.status_code} with body {response.text}")
|
146
|
-
span.set_attribute("job.run.result", response.text)
|
147
|
-
return response.text
|
128
|
+
raise Exception(
|
129
|
+
f"Job {self.name} returned status code {response.status_code} with body {response.text}"
|
130
|
+
)
|
131
|
+
return response.text
|
148
132
|
|
149
133
|
async def arun(self, input: Any, headers: dict = {}, params: dict = {}) -> Awaitable[str]:
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
134
|
+
logger.debug(f"Job Calling: {self.name}")
|
135
|
+
response = await self.acall(self.url, input, headers, params)
|
136
|
+
if response.status_code >= 400:
|
137
|
+
if not self.fallback_url:
|
138
|
+
raise Exception(
|
139
|
+
f"Job {self.name} returned status code {response.status_code} with body {response.text}"
|
140
|
+
)
|
141
|
+
response = await self.acall(self.fallback_url, input, headers, params)
|
157
142
|
if response.status_code >= 400:
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
if response.status_code >= 400:
|
163
|
-
span.set_attribute("job.run.error", response.text)
|
164
|
-
raise Exception(f"Job {self.name} returned status code {response.status_code} with body {response.text}")
|
165
|
-
span.set_attribute("job.run.result", response.text)
|
166
|
-
return response.text
|
143
|
+
raise Exception(
|
144
|
+
f"Job {self.name} returned status code {response.status_code} with body {response.text}"
|
145
|
+
)
|
146
|
+
return response.text
|
167
147
|
|
168
148
|
def __str__(self):
|
169
149
|
return f"Job {self.name}"
|
@@ -172,9 +152,9 @@ class BlJob:
|
|
172
152
|
return self.__str__()
|
173
153
|
|
174
154
|
|
175
|
-
|
176
155
|
def bl_job(name: str):
|
177
156
|
return BlJob(name)
|
178
157
|
|
158
|
+
|
179
159
|
# Create a singleton instance
|
180
160
|
bl_start_job = BlJobWrapper()
|
@@ -7,11 +7,13 @@ import anyio
|
|
7
7
|
import mcp.types as types
|
8
8
|
from anyio.abc import TaskStatus
|
9
9
|
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
|
10
|
-
from
|
11
|
-
from websockets.client import
|
10
|
+
from mcp.shared.message import SessionMessage
|
11
|
+
from websockets.asyncio.client import ClientConnection
|
12
|
+
from websockets.asyncio.client import connect as ws_connect
|
12
13
|
|
13
14
|
logger = logging.getLogger(__name__)
|
14
15
|
|
16
|
+
|
15
17
|
def remove_request_params(url: str) -> str:
|
16
18
|
return urljoin(url, urlparse(url).path)
|
17
19
|
|
@@ -27,11 +29,11 @@ async def websocket_client(
|
|
27
29
|
|
28
30
|
The `timeout` parameter controls connection timeout.
|
29
31
|
"""
|
30
|
-
read_stream: MemoryObjectReceiveStream[
|
31
|
-
read_stream_writer: MemoryObjectSendStream[
|
32
|
+
read_stream: MemoryObjectReceiveStream[SessionMessage | Exception]
|
33
|
+
read_stream_writer: MemoryObjectSendStream[SessionMessage | Exception]
|
32
34
|
|
33
|
-
write_stream: MemoryObjectSendStream[
|
34
|
-
write_stream_reader: MemoryObjectReceiveStream[
|
35
|
+
write_stream: MemoryObjectSendStream[SessionMessage]
|
36
|
+
write_stream_reader: MemoryObjectReceiveStream[SessionMessage]
|
35
37
|
|
36
38
|
read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
|
37
39
|
write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
|
@@ -44,11 +46,14 @@ async def websocket_client(
|
|
44
46
|
ws_url = url.replace("http://", "ws://").replace("https://", "wss://")
|
45
47
|
logger.debug(f"Connecting to WebSocket endpoint: {remove_request_params(ws_url)}")
|
46
48
|
|
47
|
-
|
49
|
+
# Use different parameters based on websockets version
|
50
|
+
connection_kwargs = {"additional_headers": headers, "open_timeout": timeout}
|
51
|
+
|
52
|
+
async with ws_connect(ws_url, **connection_kwargs) as websocket:
|
48
53
|
logger.debug("WebSocket connection established")
|
49
54
|
|
50
55
|
async def ws_reader(
|
51
|
-
websocket:
|
56
|
+
websocket: ClientConnection,
|
52
57
|
task_status: TaskStatus[None] = anyio.TASK_STATUS_IGNORED,
|
53
58
|
):
|
54
59
|
try:
|
@@ -56,9 +61,13 @@ async def websocket_client(
|
|
56
61
|
async for message in websocket:
|
57
62
|
logger.debug(f"Received WebSocket message: {message}")
|
58
63
|
try:
|
59
|
-
parsed_message = types.JSONRPCMessage.model_validate_json(
|
64
|
+
parsed_message = types.JSONRPCMessage.model_validate_json(
|
65
|
+
message
|
66
|
+
)
|
60
67
|
logger.debug(f"Received server message: {parsed_message}")
|
61
|
-
await read_stream_writer.send(
|
68
|
+
await read_stream_writer.send(
|
69
|
+
SessionMessage(message=parsed_message)
|
70
|
+
)
|
62
71
|
except Exception as exc:
|
63
72
|
logger.error(f"Error parsing server message: {exc}")
|
64
73
|
await read_stream_writer.send(exc)
|
@@ -68,13 +77,15 @@ async def websocket_client(
|
|
68
77
|
finally:
|
69
78
|
await read_stream_writer.aclose()
|
70
79
|
|
71
|
-
async def ws_writer(websocket:
|
80
|
+
async def ws_writer(websocket: ClientConnection):
|
72
81
|
try:
|
73
82
|
async with write_stream_reader:
|
74
|
-
async for
|
75
|
-
logger.debug(
|
83
|
+
async for session_message in write_stream_reader:
|
84
|
+
logger.debug(
|
85
|
+
f"Sending client message: {session_message.message}"
|
86
|
+
)
|
76
87
|
await websocket.send(
|
77
|
-
message.model_dump_json(
|
88
|
+
session_message.message.model_dump_json(
|
78
89
|
by_alias=True,
|
79
90
|
exclude_none=True,
|
80
91
|
)
|
@@ -107,4 +118,4 @@ async def websocket_client(
|
|
107
118
|
finally:
|
108
119
|
# Ensure streams are closed even if task group setup fails or GeneratorExit is caught
|
109
120
|
await read_stream_writer.aclose()
|
110
|
-
await write_stream.aclose()
|
121
|
+
await write_stream.aclose()
|