blaxel 0.2.31rc120__py3-none-any.whl → 0.2.32__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 +3 -3
- blaxel/core/agents/__init__.py +16 -7
- blaxel/core/authentication/__init__.py +2 -1
- blaxel/core/authentication/devicemode.py +9 -1
- blaxel/core/authentication/oauth.py +13 -6
- blaxel/core/authentication/types.py +1 -0
- blaxel/core/cache/cache.py +10 -3
- blaxel/core/client/api/agents/create_agent.py +5 -5
- blaxel/core/client/api/agents/delete_agent.py +5 -5
- blaxel/core/client/api/agents/get_agent.py +4 -4
- blaxel/core/client/api/agents/list_agent_revisions.py +8 -6
- blaxel/core/client/api/agents/list_agents.py +5 -5
- blaxel/core/client/api/agents/update_agent.py +5 -5
- blaxel/core/client/api/compute/create_sandbox.py +5 -5
- blaxel/core/client/api/compute/create_sandbox_preview.py +5 -5
- blaxel/core/client/api/compute/create_sandbox_preview_token.py +5 -5
- blaxel/core/client/api/compute/delete_sandbox.py +5 -5
- blaxel/core/client/api/compute/delete_sandbox_preview.py +5 -5
- blaxel/core/client/api/compute/delete_sandbox_preview_token.py +11 -7
- blaxel/core/client/api/compute/get_sandbox.py +4 -4
- blaxel/core/client/api/compute/get_sandbox_preview.py +5 -5
- blaxel/core/client/api/compute/list_sandbox_preview_tokens.py +5 -5
- blaxel/core/client/api/compute/list_sandbox_previews.py +5 -5
- blaxel/core/client/api/compute/list_sandboxes.py +5 -5
- blaxel/core/client/api/compute/update_sandbox.py +5 -5
- blaxel/core/client/api/compute/update_sandbox_preview.py +5 -5
- blaxel/core/client/api/configurations/get_configuration.py +5 -5
- blaxel/core/client/api/customdomains/create_custom_domain.py +5 -5
- blaxel/core/client/api/customdomains/delete_custom_domain.py +5 -5
- blaxel/core/client/api/customdomains/get_custom_domain.py +5 -5
- blaxel/core/client/api/customdomains/list_custom_domains.py +5 -5
- blaxel/core/client/api/customdomains/update_custom_domain.py +5 -5
- blaxel/core/client/api/customdomains/verify_custom_domain.py +5 -5
- blaxel/core/client/api/default/get_template.py +5 -5
- blaxel/core/client/api/default/list_mcp_hub_definitions.py +5 -5
- blaxel/core/client/api/default/list_sandbox_hub_definitions.py +11 -7
- blaxel/core/client/api/functions/create_function.py +5 -5
- blaxel/core/client/api/functions/delete_function.py +5 -5
- blaxel/core/client/api/functions/get_function.py +4 -4
- blaxel/core/client/api/functions/list_function_revisions.py +8 -6
- blaxel/core/client/api/functions/list_functions.py +5 -5
- blaxel/core/client/api/functions/update_function.py +5 -5
- blaxel/core/client/api/images/cleanup_images.py +8 -6
- blaxel/core/client/api/images/delete_image.py +4 -4
- blaxel/core/client/api/images/delete_image_tag.py +4 -4
- blaxel/core/client/api/images/get_image.py +5 -5
- blaxel/core/client/api/images/list_images.py +5 -5
- blaxel/core/client/api/integrations/create_integration_connection.py +5 -5
- blaxel/core/client/api/integrations/delete_integration_connection.py +5 -5
- blaxel/core/client/api/integrations/get_integration.py +5 -5
- blaxel/core/client/api/integrations/get_integration_connection.py +5 -5
- blaxel/core/client/api/integrations/get_integration_connection_model.py +3 -3
- blaxel/core/client/api/integrations/get_integration_connection_model_endpoint_configurations.py +3 -3
- blaxel/core/client/api/integrations/list_integration_connection_models.py +3 -3
- blaxel/core/client/api/integrations/list_integration_connections.py +11 -7
- blaxel/core/client/api/integrations/update_integration_connection.py +5 -5
- blaxel/core/client/api/invitations/list_all_pending_invitations.py +7 -5
- blaxel/core/client/api/jobs/create_job.py +5 -5
- blaxel/core/client/api/jobs/create_job_execution.py +7 -5
- blaxel/core/client/api/jobs/delete_job.py +5 -5
- blaxel/core/client/api/jobs/delete_job_execution.py +7 -5
- blaxel/core/client/api/jobs/get_job.py +4 -4
- blaxel/core/client/api/jobs/get_job_execution.py +7 -5
- blaxel/core/client/api/jobs/list_job_executions.py +10 -6
- blaxel/core/client/api/jobs/list_job_revisions.py +8 -6
- blaxel/core/client/api/jobs/list_jobs.py +5 -5
- blaxel/core/client/api/jobs/update_job.py +5 -5
- blaxel/core/client/api/locations/list_locations.py +8 -6
- blaxel/core/client/api/models/create_model.py +5 -5
- blaxel/core/client/api/models/delete_model.py +5 -5
- blaxel/core/client/api/models/get_model.py +5 -5
- blaxel/core/client/api/models/list_model_revisions.py +8 -6
- blaxel/core/client/api/models/list_models.py +5 -5
- blaxel/core/client/api/models/update_model.py +5 -5
- blaxel/core/client/api/policies/create_policy.py +5 -5
- blaxel/core/client/api/policies/delete_policy.py +5 -5
- blaxel/core/client/api/policies/get_policy.py +5 -5
- blaxel/core/client/api/policies/list_policies.py +5 -5
- blaxel/core/client/api/policies/update_policy.py +5 -5
- blaxel/core/client/api/public_ipslist/list_public_ips.py +5 -5
- blaxel/core/client/api/service_accounts/create_api_key_for_service_account.py +5 -5
- blaxel/core/client/api/service_accounts/create_workspace_service_account.py +11 -7
- blaxel/core/client/api/service_accounts/delete_api_key_for_service_account.py +3 -3
- blaxel/core/client/api/service_accounts/delete_workspace_service_account.py +11 -7
- blaxel/core/client/api/service_accounts/get_workspace_service_accounts.py +8 -6
- blaxel/core/client/api/service_accounts/list_api_keys_for_service_account.py +5 -5
- blaxel/core/client/api/service_accounts/update_workspace_service_account.py +11 -7
- blaxel/core/client/api/templates/list_templates.py +5 -5
- blaxel/core/client/api/volume_templates/create_volume_template.py +4 -4
- blaxel/core/client/api/volume_templates/delete_volume_template.py +5 -5
- blaxel/core/client/api/volume_templates/delete_volume_template_version.py +4 -4
- blaxel/core/client/api/volume_templates/get_volume_template.py +5 -5
- blaxel/core/client/api/volume_templates/list_volume_templates.py +8 -6
- blaxel/core/client/api/volume_templates/update_volume_template.py +4 -4
- blaxel/core/client/api/volumes/create_volume.py +5 -5
- blaxel/core/client/api/volumes/delete_volume.py +5 -5
- blaxel/core/client/api/volumes/get_volume.py +5 -5
- blaxel/core/client/api/volumes/list_volumes.py +5 -5
- blaxel/core/client/api/workspaces/accept_workspace_invitation.py +10 -6
- blaxel/core/client/api/workspaces/check_workspace_availability.py +5 -5
- blaxel/core/client/api/workspaces/create_workspace.py +5 -5
- blaxel/core/client/api/workspaces/decline_workspace_invitation.py +5 -5
- blaxel/core/client/api/workspaces/delete_workspace.py +5 -5
- blaxel/core/client/api/workspaces/get_workspace.py +5 -5
- blaxel/core/client/api/workspaces/invite_workspace_user.py +10 -6
- blaxel/core/client/api/workspaces/leave_workspace.py +4 -4
- blaxel/core/client/api/workspaces/list_workspace_users.py +5 -5
- blaxel/core/client/api/workspaces/list_workspaces.py +5 -5
- blaxel/core/client/api/workspaces/remove_workspace_user.py +3 -3
- blaxel/core/client/api/workspaces/update_workspace.py +5 -5
- blaxel/core/client/api/workspaces/update_workspace_user_role.py +10 -6
- blaxel/core/client/client.py +5 -19
- blaxel/core/client/models/acl.py +3 -3
- blaxel/core/client/models/agent.py +12 -5
- blaxel/core/client/models/agent_spec.py +22 -7
- blaxel/core/client/models/api_key.py +6 -6
- blaxel/core/client/models/billable_time_metric.py +3 -4
- blaxel/core/client/models/check_workspace_availability_body.py +1 -1
- blaxel/core/client/models/cleanup_images_response_200.py +1 -1
- blaxel/core/client/models/configuration.py +2 -3
- blaxel/core/client/models/continent.py +2 -2
- blaxel/core/client/models/core_event.py +3 -3
- blaxel/core/client/models/core_spec.py +14 -5
- blaxel/core/client/models/core_spec_configurations.py +1 -2
- blaxel/core/client/models/country.py +2 -2
- blaxel/core/client/models/create_api_key_for_service_account_body.py +1 -1
- blaxel/core/client/models/create_job_execution_request.py +4 -5
- blaxel/core/client/models/create_job_execution_request_tasks_item.py +1 -1
- blaxel/core/client/models/create_job_execution_response.py +4 -5
- blaxel/core/client/models/create_job_execution_response_tasks_item.py +1 -1
- blaxel/core/client/models/create_workspace_service_account_body.py +1 -1
- blaxel/core/client/models/create_workspace_service_account_response_200.py +1 -1
- blaxel/core/client/models/custom_domain.py +6 -3
- blaxel/core/client/models/custom_domain_metadata.py +6 -7
- blaxel/core/client/models/custom_domain_spec.py +10 -7
- blaxel/core/client/models/custom_domain_spec_txt_records.py +1 -1
- blaxel/core/client/models/delete_sandbox_preview_token_response_200.py +1 -1
- blaxel/core/client/models/delete_volume_template_version_response_200.py +6 -3
- blaxel/core/client/models/delete_workspace_service_account_response_200.py +1 -1
- blaxel/core/client/models/entrypoint.py +4 -3
- blaxel/core/client/models/entrypoint_env.py +1 -1
- blaxel/core/client/models/expiration_policy.py +2 -2
- blaxel/core/client/models/flavor.py +2 -2
- blaxel/core/client/models/form.py +6 -3
- blaxel/core/client/models/form_config.py +1 -1
- blaxel/core/client/models/form_oauth.py +1 -1
- blaxel/core/client/models/form_secrets.py +1 -1
- blaxel/core/client/models/function.py +12 -5
- blaxel/core/client/models/function_spec.py +17 -6
- blaxel/core/client/models/get_workspace_service_accounts_response_200_item.py +1 -1
- blaxel/core/client/models/histogram_bucket.py +1 -1
- blaxel/core/client/models/histogram_stats.py +1 -1
- blaxel/core/client/models/image.py +6 -3
- blaxel/core/client/models/image_metadata.py +6 -6
- blaxel/core/client/models/image_spec.py +1 -2
- blaxel/core/client/models/image_tag.py +3 -3
- blaxel/core/client/models/integration.py +12 -5
- blaxel/core/client/models/integration_additional_infos.py +1 -1
- blaxel/core/client/models/integration_connection.py +6 -3
- blaxel/core/client/models/integration_connection_spec.py +1 -2
- blaxel/core/client/models/integration_connection_spec_config.py +1 -1
- blaxel/core/client/models/integration_connection_spec_secret.py +1 -1
- blaxel/core/client/models/integration_endpoint.py +9 -6
- blaxel/core/client/models/integration_endpoint_token.py +1 -1
- blaxel/core/client/models/integration_endpoints.py +1 -3
- blaxel/core/client/models/integration_headers.py +1 -1
- blaxel/core/client/models/integration_model.py +1 -1
- blaxel/core/client/models/integration_organization.py +2 -2
- blaxel/core/client/models/integration_query_params.py +1 -1
- blaxel/core/client/models/integration_repository.py +2 -2
- blaxel/core/client/models/invite_workspace_user_body.py +1 -1
- blaxel/core/client/models/job.py +12 -5
- blaxel/core/client/models/job_execution.py +6 -3
- blaxel/core/client/models/job_execution_config.py +3 -3
- blaxel/core/client/models/job_execution_metadata.py +7 -7
- blaxel/core/client/models/job_execution_spec.py +1 -2
- blaxel/core/client/models/job_execution_stats.py +1 -1
- blaxel/core/client/models/job_execution_task.py +6 -3
- blaxel/core/client/models/job_execution_task_condition.py +3 -3
- blaxel/core/client/models/job_execution_task_metadata.py +6 -6
- blaxel/core/client/models/job_execution_task_spec.py +2 -2
- blaxel/core/client/models/job_metrics.py +15 -12
- blaxel/core/client/models/job_metrics_executions_total.py +1 -1
- blaxel/core/client/models/job_metrics_tasks_total.py +1 -1
- blaxel/core/client/models/job_spec.py +17 -6
- blaxel/core/client/models/jobs_chart_value.py +1 -1
- blaxel/core/client/models/jobs_network_chart.py +1 -2
- blaxel/core/client/models/jobs_success_failed_chart.py +11 -4
- blaxel/core/client/models/jobs_total.py +1 -1
- blaxel/core/client/models/last_n_requests_metric.py +4 -4
- blaxel/core/client/models/latency_metric.py +10 -7
- blaxel/core/client/models/location_response.py +1 -2
- blaxel/core/client/models/logs_response.py +1 -1
- blaxel/core/client/models/logs_response_data.py +4 -4
- blaxel/core/client/models/mcp_definition.py +11 -8
- blaxel/core/client/models/mcp_definition_entrypoint.py +1 -1
- blaxel/core/client/models/mcp_definition_form.py +1 -1
- blaxel/core/client/models/memory_allocation_by_name.py +1 -1
- blaxel/core/client/models/memory_allocation_metric.py +2 -2
- blaxel/core/client/models/metadata.py +6 -7
- blaxel/core/client/models/metadata_labels.py +1 -1
- blaxel/core/client/models/metric.py +2 -2
- blaxel/core/client/models/metrics.py +24 -11
- blaxel/core/client/models/metrics_models.py +1 -1
- blaxel/core/client/models/metrics_request_total_per_code.py +1 -1
- blaxel/core/client/models/metrics_rps_per_code.py +1 -1
- blaxel/core/client/models/model.py +12 -5
- blaxel/core/client/models/model_spec.py +14 -5
- blaxel/core/client/models/o_auth.py +2 -2
- blaxel/core/client/models/owner_fields.py +3 -3
- blaxel/core/client/models/pending_invitation.py +6 -6
- blaxel/core/client/models/pending_invitation_accept.py +6 -3
- blaxel/core/client/models/pending_invitation_render.py +14 -7
- blaxel/core/client/models/pending_invitation_render_invited_by.py +1 -1
- blaxel/core/client/models/pending_invitation_render_workspace.py +2 -2
- blaxel/core/client/models/pending_invitation_workspace_details.py +1 -1
- blaxel/core/client/models/pod_template_spec.py +1 -1
- blaxel/core/client/models/policy.py +6 -3
- blaxel/core/client/models/policy_location.py +2 -2
- blaxel/core/client/models/policy_max_tokens.py +5 -3
- blaxel/core/client/models/policy_spec.py +15 -8
- blaxel/core/client/models/port.py +1 -1
- blaxel/core/client/models/preview.py +6 -3
- blaxel/core/client/models/preview_metadata.py +8 -8
- blaxel/core/client/models/preview_spec.py +5 -6
- blaxel/core/client/models/preview_spec_request_headers.py +1 -1
- blaxel/core/client/models/preview_spec_response_headers.py +1 -1
- blaxel/core/client/models/preview_token.py +6 -3
- blaxel/core/client/models/preview_token_metadata.py +4 -4
- blaxel/core/client/models/preview_token_spec.py +2 -2
- blaxel/core/client/models/private_location.py +1 -1
- blaxel/core/client/models/public_ip.py +3 -3
- blaxel/core/client/models/public_ips.py +1 -2
- blaxel/core/client/models/region.py +2 -2
- blaxel/core/client/models/repository.py +2 -2
- blaxel/core/client/models/request_duration_over_time_metric.py +1 -1
- blaxel/core/client/models/request_duration_over_time_metrics.py +4 -3
- blaxel/core/client/models/request_total_by_origin_metric.py +23 -10
- blaxel/core/client/models/request_total_by_origin_metric_request_total_by_origin.py +1 -1
- blaxel/core/client/models/request_total_by_origin_metric_request_total_by_origin_and_code.py +1 -1
- blaxel/core/client/models/request_total_metric.py +14 -7
- blaxel/core/client/models/request_total_metric_request_total_per_code.py +1 -1
- blaxel/core/client/models/request_total_metric_rps_per_code.py +1 -1
- blaxel/core/client/models/request_total_response_data.py +5 -5
- blaxel/core/client/models/resource.py +6 -4
- blaxel/core/client/models/resource_log.py +1 -1
- blaxel/core/client/models/resource_log_chart.py +1 -1
- blaxel/core/client/models/resource_log_response.py +2 -2
- blaxel/core/client/models/resource_metrics.py +95 -40
- blaxel/core/client/models/resource_metrics_request_total_per_code.py +1 -1
- blaxel/core/client/models/resource_metrics_request_total_per_code_previous.py +1 -1
- blaxel/core/client/models/resource_metrics_rps_per_code.py +1 -1
- blaxel/core/client/models/resource_metrics_rps_per_code_previous.py +1 -1
- blaxel/core/client/models/resource_trace.py +5 -5
- blaxel/core/client/models/revision_configuration.py +3 -3
- blaxel/core/client/models/revision_metadata.py +5 -5
- blaxel/core/client/models/runtime.py +9 -10
- blaxel/core/client/models/runtime_configuration.py +1 -1
- blaxel/core/client/models/runtime_startup_probe.py +1 -1
- blaxel/core/client/models/sandbox.py +13 -6
- blaxel/core/client/models/sandbox_definition.py +3 -4
- blaxel/core/client/models/sandbox_lifecycle.py +2 -3
- blaxel/core/client/models/sandbox_metrics.py +1 -1
- blaxel/core/client/models/sandbox_spec.py +25 -8
- blaxel/core/client/models/serverless_config.py +4 -5
- blaxel/core/client/models/serverless_config_configuration.py +1 -1
- blaxel/core/client/models/spec_configuration.py +1 -1
- blaxel/core/client/models/start_sandbox.py +6 -3
- blaxel/core/client/models/stop_sandbox.py +6 -3
- blaxel/core/client/models/store_agent.py +6 -7
- blaxel/core/client/models/store_agent_labels.py +1 -1
- blaxel/core/client/models/store_configuration.py +7 -6
- blaxel/core/client/models/store_configuration_option.py +2 -2
- blaxel/core/client/models/template.py +6 -7
- blaxel/core/client/models/template_variable.py +1 -1
- blaxel/core/client/models/time_fields.py +3 -3
- blaxel/core/client/models/time_to_first_token_over_time_metrics.py +7 -4
- blaxel/core/client/models/token_rate_metric.py +3 -3
- blaxel/core/client/models/token_rate_metrics.py +4 -5
- blaxel/core/client/models/token_total_metric.py +13 -7
- blaxel/core/client/models/trace_ids_response.py +1 -1
- blaxel/core/client/models/trigger.py +2 -3
- blaxel/core/client/models/trigger_configuration.py +4 -5
- blaxel/core/client/models/trigger_configuration_task.py +1 -1
- blaxel/core/client/models/update_workspace_service_account_body.py +1 -1
- blaxel/core/client/models/update_workspace_service_account_response_200.py +1 -1
- blaxel/core/client/models/update_workspace_user_role_body.py +1 -1
- blaxel/core/client/models/volume.py +13 -6
- blaxel/core/client/models/volume_attachment.py +3 -3
- blaxel/core/client/models/volume_spec.py +2 -2
- blaxel/core/client/models/volume_state.py +2 -2
- blaxel/core/client/models/volume_template.py +6 -3
- blaxel/core/client/models/volume_template_spec.py +2 -2
- blaxel/core/client/models/volume_template_state.py +6 -4
- blaxel/core/client/models/volume_template_version.py +4 -4
- blaxel/core/client/models/websocket_channel.py +4 -4
- blaxel/core/client/models/websocket_message.py +3 -3
- blaxel/core/client/models/workspace.py +13 -10
- blaxel/core/client/models/workspace_labels.py +1 -1
- blaxel/core/client/models/workspace_runtime.py +1 -1
- blaxel/core/client/models/workspace_user.py +1 -1
- blaxel/core/client/response_interceptor.py +3 -1
- blaxel/core/common/autoload.py +9 -11
- blaxel/core/common/env.py +10 -8
- blaxel/core/common/settings.py +7 -5
- blaxel/core/common/webhook.py +0 -1
- blaxel/core/jobs/__init__.py +13 -3
- blaxel/core/mcp/client.py +8 -2
- blaxel/core/mcp/server.py +8 -2
- blaxel/core/models/__init__.py +6 -5
- blaxel/core/sandbox/__init__.py +1 -1
- blaxel/core/sandbox/client/api/codegen/get_codegen_reranking_path.py +10 -6
- blaxel/core/sandbox/client/api/fastapply/put_codegen_fastapply_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/delete_filesystem_multipart_upload_id_abort.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/delete_filesystem_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/delete_filesystem_tree_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_content_search_path.py +7 -5
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_find_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_multipart.py +4 -4
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_multipart_upload_id_parts.py +4 -4
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_path.py +4 -4
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_search_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_tree_path.py +4 -4
- blaxel/core/sandbox/client/api/filesystem/get_watch_filesystem_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/post_filesystem_multipart_initiate_path.py +4 -4
- blaxel/core/sandbox/client/api/filesystem/post_filesystem_multipart_upload_id_complete.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/put_filesystem_multipart_upload_id_part.py +4 -4
- blaxel/core/sandbox/client/api/filesystem/put_filesystem_path.py +10 -6
- blaxel/core/sandbox/client/api/filesystem/put_filesystem_tree_path.py +4 -4
- blaxel/core/sandbox/client/api/network/delete_network_process_pid_monitor.py +4 -4
- blaxel/core/sandbox/client/api/network/get_network_process_pid_ports.py +4 -4
- blaxel/core/sandbox/client/api/network/post_network_process_pid_monitor.py +4 -4
- blaxel/core/sandbox/client/api/process/delete_process_identifier.py +10 -6
- blaxel/core/sandbox/client/api/process/delete_process_identifier_kill.py +10 -6
- blaxel/core/sandbox/client/api/process/get_process.py +8 -6
- blaxel/core/sandbox/client/api/process/get_process_identifier.py +10 -6
- blaxel/core/sandbox/client/api/process/get_process_identifier_logs.py +10 -6
- blaxel/core/sandbox/client/api/process/get_process_identifier_logs_stream.py +10 -6
- blaxel/core/sandbox/client/api/process/post_process.py +10 -6
- blaxel/core/sandbox/client/api/root/delete.py +5 -5
- blaxel/core/sandbox/client/api/root/get.py +5 -5
- blaxel/core/sandbox/client/api/root/options.py +5 -5
- blaxel/core/sandbox/client/api/root/patch.py +5 -5
- blaxel/core/sandbox/client/api/root/post.py +5 -5
- blaxel/core/sandbox/client/api/root/put.py +5 -5
- blaxel/core/sandbox/client/client.py +3 -1
- blaxel/core/sandbox/client/models/apply_edit_request.py +2 -2
- blaxel/core/sandbox/client/models/apply_edit_response.py +3 -3
- blaxel/core/sandbox/client/models/content_search_match.py +1 -1
- blaxel/core/sandbox/client/models/content_search_response.py +1 -1
- blaxel/core/sandbox/client/models/delete_network_process_pid_monitor_response_200.py +1 -1
- blaxel/core/sandbox/client/models/directory.py +1 -1
- blaxel/core/sandbox/client/models/error_response.py +1 -1
- blaxel/core/sandbox/client/models/file.py +2 -2
- blaxel/core/sandbox/client/models/file_request.py +2 -2
- blaxel/core/sandbox/client/models/file_with_content.py +2 -2
- blaxel/core/sandbox/client/models/filesystem_multipart_upload.py +3 -3
- blaxel/core/sandbox/client/models/filesystem_multipart_upload_parts.py +4 -2
- blaxel/core/sandbox/client/models/filesystem_uploaded_part.py +3 -3
- blaxel/core/sandbox/client/models/find_match.py +2 -2
- blaxel/core/sandbox/client/models/find_response.py +1 -1
- blaxel/core/sandbox/client/models/fuzzy_search_match.py +2 -2
- blaxel/core/sandbox/client/models/fuzzy_search_response.py +1 -1
- blaxel/core/sandbox/client/models/get_network_process_pid_ports_response_200.py +1 -1
- blaxel/core/sandbox/client/models/multipart_complete_request.py +1 -1
- blaxel/core/sandbox/client/models/multipart_initiate_request.py +1 -1
- blaxel/core/sandbox/client/models/multipart_initiate_response.py +2 -2
- blaxel/core/sandbox/client/models/multipart_list_parts_response.py +2 -2
- blaxel/core/sandbox/client/models/multipart_list_uploads_response.py +1 -1
- blaxel/core/sandbox/client/models/multipart_part_info.py +2 -2
- blaxel/core/sandbox/client/models/multipart_upload_part_response.py +2 -2
- blaxel/core/sandbox/client/models/port_monitor_request.py +1 -1
- blaxel/core/sandbox/client/models/post_network_process_pid_monitor_response_200.py +1 -1
- blaxel/core/sandbox/client/models/process_logs.py +1 -1
- blaxel/core/sandbox/client/models/process_request.py +6 -6
- blaxel/core/sandbox/client/models/process_request_env.py +1 -1
- blaxel/core/sandbox/client/models/process_response.py +8 -8
- blaxel/core/sandbox/client/models/put_filesystem_multipart_upload_id_part_body.py +1 -1
- blaxel/core/sandbox/client/models/ranked_file.py +1 -1
- blaxel/core/sandbox/client/models/reranking_response.py +1 -1
- blaxel/core/sandbox/client/models/subdirectory.py +1 -1
- blaxel/core/sandbox/client/models/success_response.py +1 -1
- blaxel/core/sandbox/client/models/tree_request.py +1 -1
- blaxel/core/sandbox/client/models/tree_request_files.py +1 -1
- blaxel/core/sandbox/client/models/welcome_response.py +1 -1
- blaxel/core/sandbox/default/__init__.py +0 -1
- blaxel/core/sandbox/default/action.py +3 -3
- blaxel/core/sandbox/default/codegen.py +2 -4
- blaxel/core/sandbox/default/filesystem.py +38 -82
- blaxel/core/sandbox/default/interpreter.py +17 -10
- blaxel/core/sandbox/default/preview.py +6 -2
- blaxel/core/sandbox/default/process.py +20 -11
- blaxel/core/sandbox/default/sandbox.py +24 -14
- blaxel/core/sandbox/sync/__init__.py +0 -2
- blaxel/core/sandbox/sync/action.py +2 -3
- blaxel/core/sandbox/sync/codegen.py +1 -5
- blaxel/core/sandbox/sync/filesystem.py +17 -6
- blaxel/core/sandbox/sync/interpreter.py +10 -6
- blaxel/core/sandbox/sync/network.py +0 -2
- blaxel/core/sandbox/sync/preview.py +76 -33
- blaxel/core/sandbox/sync/process.py +27 -12
- blaxel/core/sandbox/sync/sandbox.py +30 -18
- blaxel/core/sandbox/sync/session.py +6 -4
- blaxel/core/sandbox/types.py +2 -1
- blaxel/core/tools/__init__.py +30 -6
- blaxel/core/tools/common.py +1 -1
- blaxel/core/tools/types.py +2 -1
- blaxel/crewai/model.py +20 -5
- blaxel/googleadk/__init__.py +1 -1
- blaxel/googleadk/tools.py +3 -5
- blaxel/langgraph/custom/gemini.py +126 -133
- blaxel/langgraph/model.py +54 -50
- blaxel/langgraph/tools.py +9 -3
- blaxel/llamaindex/custom/cohere.py +25 -16
- blaxel/llamaindex/model.py +44 -57
- blaxel/llamaindex/tools.py +2 -3
- blaxel/pydantic/custom/gemini.py +3 -3
- blaxel/pydantic/tools.py +2 -4
- blaxel/telemetry/exporters.py +10 -3
- blaxel/telemetry/instrumentation/blaxel_langgraph.py +4 -2
- blaxel/telemetry/instrumentation/blaxel_langgraph_gemini.py +22 -5
- blaxel/telemetry/instrumentation/utils.py +3 -3
- blaxel/telemetry/log/log.py +2 -3
- blaxel/telemetry/log/logger.py +21 -15
- blaxel/telemetry/span.py +10 -6
- {blaxel-0.2.31rc120.dist-info → blaxel-0.2.32.dist-info}/METADATA +2 -2
- blaxel-0.2.32.dist-info/RECORD +506 -0
- blaxel/core/client/api/compute/start_sandbox.py +0 -157
- blaxel/core/client/api/compute/stop_sandbox.py +0 -157
- blaxel-0.2.31rc120.dist-info/RECORD +0 -508
- {blaxel-0.2.31rc120.dist-info → blaxel-0.2.32.dist-info}/WHEEL +0 -0
- {blaxel-0.2.31rc120.dist-info → blaxel-0.2.32.dist-info}/licenses/LICENSE +0 -0
|
@@ -47,11 +47,11 @@ class SandboxFileSystem(SandboxAction):
|
|
|
47
47
|
path = self.format_path(path)
|
|
48
48
|
|
|
49
49
|
# Calculate content size in bytes
|
|
50
|
-
content_size = len(content.encode(
|
|
50
|
+
content_size = len(content.encode("utf-8"))
|
|
51
51
|
|
|
52
52
|
# Use multipart upload for large files
|
|
53
53
|
if content_size > MULTIPART_THRESHOLD:
|
|
54
|
-
content_bytes = content.encode(
|
|
54
|
+
content_bytes = content.encode("utf-8")
|
|
55
55
|
return await self._upload_with_multipart(path, content_bytes, "0644")
|
|
56
56
|
|
|
57
57
|
# Use regular upload for small files
|
|
@@ -66,7 +66,9 @@ class SandboxFileSystem(SandboxAction):
|
|
|
66
66
|
finally:
|
|
67
67
|
await response.aclose()
|
|
68
68
|
|
|
69
|
-
async def write_binary(
|
|
69
|
+
async def write_binary(
|
|
70
|
+
self, path: str, content: Union[bytes, bytearray, str]
|
|
71
|
+
) -> SuccessResponse:
|
|
70
72
|
"""Write binary content to a file.
|
|
71
73
|
|
|
72
74
|
Args:
|
|
@@ -96,7 +98,11 @@ class SandboxFileSystem(SandboxAction):
|
|
|
96
98
|
|
|
97
99
|
# Prepare multipart form data
|
|
98
100
|
files = {
|
|
99
|
-
"file": (
|
|
101
|
+
"file": (
|
|
102
|
+
"binary-file.bin",
|
|
103
|
+
binary_file,
|
|
104
|
+
"application/octet-stream",
|
|
105
|
+
),
|
|
100
106
|
}
|
|
101
107
|
data = {"permissions": "0644", "path": path}
|
|
102
108
|
|
|
@@ -109,7 +115,7 @@ class SandboxFileSystem(SandboxAction):
|
|
|
109
115
|
try:
|
|
110
116
|
content_bytes = await response.aread()
|
|
111
117
|
if not response.is_success:
|
|
112
|
-
error_text = content_bytes.decode(
|
|
118
|
+
error_text = content_bytes.decode("utf-8", errors="ignore")
|
|
113
119
|
raise Exception(f"Failed to write binary: {response.status_code} {error_text}")
|
|
114
120
|
return SuccessResponse.from_dict(json.loads(content_bytes))
|
|
115
121
|
finally:
|
|
@@ -246,18 +252,18 @@ class SandboxFileSystem(SandboxAction):
|
|
|
246
252
|
FindResponse with matching files/directories
|
|
247
253
|
"""
|
|
248
254
|
path = self.format_path(path)
|
|
249
|
-
|
|
255
|
+
|
|
250
256
|
params = {}
|
|
251
257
|
if type is not None:
|
|
252
|
-
params[
|
|
258
|
+
params["type"] = type
|
|
253
259
|
if patterns is not None and len(patterns) > 0:
|
|
254
|
-
params[
|
|
260
|
+
params["patterns"] = ",".join(patterns)
|
|
255
261
|
if max_results is not None:
|
|
256
|
-
params[
|
|
262
|
+
params["maxResults"] = max_results
|
|
257
263
|
if exclude_dirs is not None and len(exclude_dirs) > 0:
|
|
258
|
-
params[
|
|
264
|
+
params["excludeDirs"] = ",".join(exclude_dirs)
|
|
259
265
|
if exclude_hidden is not None:
|
|
260
|
-
params[
|
|
266
|
+
params["excludeHidden"] = exclude_hidden
|
|
261
267
|
|
|
262
268
|
url = f"{self.url}/filesystem-find/{path}"
|
|
263
269
|
headers = {**settings.headers, **self.sandbox_config.headers}
|
|
@@ -267,8 +273,9 @@ class SandboxFileSystem(SandboxAction):
|
|
|
267
273
|
try:
|
|
268
274
|
data = json.loads(await response.aread())
|
|
269
275
|
self.handle_response_error(response)
|
|
270
|
-
|
|
276
|
+
|
|
271
277
|
from ..client.models.find_response import FindResponse
|
|
278
|
+
|
|
272
279
|
return FindResponse.from_dict(data)
|
|
273
280
|
finally:
|
|
274
281
|
await response.aclose()
|
|
@@ -298,18 +305,18 @@ class SandboxFileSystem(SandboxAction):
|
|
|
298
305
|
ContentSearchResponse with matching lines
|
|
299
306
|
"""
|
|
300
307
|
path = self.format_path(path)
|
|
301
|
-
|
|
302
|
-
params = {
|
|
308
|
+
|
|
309
|
+
params = {"query": query}
|
|
303
310
|
if case_sensitive is not None:
|
|
304
|
-
params[
|
|
311
|
+
params["caseSensitive"] = case_sensitive
|
|
305
312
|
if context_lines is not None:
|
|
306
|
-
params[
|
|
313
|
+
params["contextLines"] = context_lines
|
|
307
314
|
if max_results is not None:
|
|
308
|
-
params[
|
|
315
|
+
params["maxResults"] = max_results
|
|
309
316
|
if file_pattern is not None:
|
|
310
|
-
params[
|
|
317
|
+
params["filePattern"] = file_pattern
|
|
311
318
|
if exclude_dirs is not None and len(exclude_dirs) > 0:
|
|
312
|
-
params[
|
|
319
|
+
params["excludeDirs"] = ",".join(exclude_dirs)
|
|
313
320
|
|
|
314
321
|
url = f"{self.url}/filesystem-content-search/{path}"
|
|
315
322
|
headers = {**settings.headers, **self.sandbox_config.headers}
|
|
@@ -319,58 +326,15 @@ class SandboxFileSystem(SandboxAction):
|
|
|
319
326
|
try:
|
|
320
327
|
data = json.loads(await response.aread())
|
|
321
328
|
self.handle_response_error(response)
|
|
322
|
-
|
|
323
|
-
from ..client.models.content_search_response import
|
|
329
|
+
|
|
330
|
+
from ..client.models.content_search_response import (
|
|
331
|
+
ContentSearchResponse,
|
|
332
|
+
)
|
|
333
|
+
|
|
324
334
|
return ContentSearchResponse.from_dict(data)
|
|
325
335
|
finally:
|
|
326
336
|
await response.aclose()
|
|
327
337
|
|
|
328
|
-
async def find(
|
|
329
|
-
self,
|
|
330
|
-
path: str,
|
|
331
|
-
type: str | None = None,
|
|
332
|
-
patterns: List[str] | None = None,
|
|
333
|
-
max_results: int | None = None,
|
|
334
|
-
exclude_dirs: List[str] | None = None,
|
|
335
|
-
exclude_hidden: bool | None = None,
|
|
336
|
-
):
|
|
337
|
-
"""Find files and directories.
|
|
338
|
-
|
|
339
|
-
Args:
|
|
340
|
-
path: Path to search in
|
|
341
|
-
type: Type of search ('file' or 'directory')
|
|
342
|
-
patterns: File patterns to include (e.g., ['*.py', '*.json'])
|
|
343
|
-
max_results: Maximum number of results to return
|
|
344
|
-
exclude_dirs: Directory names to skip
|
|
345
|
-
exclude_hidden: Exclude hidden files and directories
|
|
346
|
-
|
|
347
|
-
Returns:
|
|
348
|
-
FindResponse with matching files/directories
|
|
349
|
-
"""
|
|
350
|
-
path = self.format_path(path)
|
|
351
|
-
|
|
352
|
-
params = {}
|
|
353
|
-
if type is not None:
|
|
354
|
-
params['type'] = type
|
|
355
|
-
if patterns is not None and len(patterns) > 0:
|
|
356
|
-
params['patterns'] = ','.join(patterns)
|
|
357
|
-
if max_results is not None:
|
|
358
|
-
params['maxResults'] = max_results
|
|
359
|
-
if exclude_dirs is not None and len(exclude_dirs) > 0:
|
|
360
|
-
params['excludeDirs'] = ','.join(exclude_dirs)
|
|
361
|
-
if exclude_hidden is not None:
|
|
362
|
-
params['excludeHidden'] = exclude_hidden
|
|
363
|
-
|
|
364
|
-
url = f"{self.url}/filesystem-find/{path}"
|
|
365
|
-
headers = {**settings.headers, **self.sandbox_config.headers}
|
|
366
|
-
|
|
367
|
-
async with self.get_client() as client_instance:
|
|
368
|
-
response = await client_instance.get(url, params=params, headers=headers)
|
|
369
|
-
self.handle_response_error(response)
|
|
370
|
-
|
|
371
|
-
from ..client.models.find_response import FindResponse
|
|
372
|
-
return FindResponse.from_dict(response.json())
|
|
373
|
-
|
|
374
338
|
async def cp(self, source: str, destination: str, max_wait: int = 180000) -> CopyResponse:
|
|
375
339
|
"""Copy files or directories using the cp command.
|
|
376
340
|
|
|
@@ -383,9 +347,7 @@ class SandboxFileSystem(SandboxAction):
|
|
|
383
347
|
raise Exception("Process instance not available. Cannot execute cp command.")
|
|
384
348
|
|
|
385
349
|
# Execute cp -r command
|
|
386
|
-
process = await self.process.exec({
|
|
387
|
-
"command": f"cp -r {source} {destination}"
|
|
388
|
-
})
|
|
350
|
+
process = await self.process.exec({"command": f"cp -r {source} {destination}"})
|
|
389
351
|
|
|
390
352
|
# Wait for process to complete
|
|
391
353
|
process = await self.process.wait(process.pid, max_wait=max_wait, interval=100)
|
|
@@ -395,11 +357,7 @@ class SandboxFileSystem(SandboxAction):
|
|
|
395
357
|
logs = process.logs if hasattr(process, "logs") else "Unknown error"
|
|
396
358
|
raise Exception(f"Could not copy {source} to {destination} cause: {logs}")
|
|
397
359
|
|
|
398
|
-
return CopyResponse(
|
|
399
|
-
message="Files copied",
|
|
400
|
-
source=source,
|
|
401
|
-
destination=destination
|
|
402
|
-
)
|
|
360
|
+
return CopyResponse(message="Files copied", source=source, destination=destination)
|
|
403
361
|
|
|
404
362
|
def watch(
|
|
405
363
|
self,
|
|
@@ -496,7 +454,9 @@ class SandboxFileSystem(SandboxAction):
|
|
|
496
454
|
return path
|
|
497
455
|
|
|
498
456
|
# Multipart upload helper methods
|
|
499
|
-
async def _initiate_multipart_upload(
|
|
457
|
+
async def _initiate_multipart_upload(
|
|
458
|
+
self, path: str, permissions: str = "0644"
|
|
459
|
+
) -> Dict[str, Any]:
|
|
500
460
|
"""Initiate a multipart upload session."""
|
|
501
461
|
path = self.format_path(path)
|
|
502
462
|
url = f"{self.url}/filesystem-multipart/initiate/{path}"
|
|
@@ -512,9 +472,7 @@ class SandboxFileSystem(SandboxAction):
|
|
|
512
472
|
finally:
|
|
513
473
|
await response.aclose()
|
|
514
474
|
|
|
515
|
-
async def _upload_part(
|
|
516
|
-
self, upload_id: str, part_number: int, data: bytes
|
|
517
|
-
) -> Dict[str, Any]:
|
|
475
|
+
async def _upload_part(self, upload_id: str, part_number: int, data: bytes) -> Dict[str, Any]:
|
|
518
476
|
"""Upload a single part of a multipart upload."""
|
|
519
477
|
url = f"{self.url}/filesystem-multipart/{upload_id}/part"
|
|
520
478
|
headers = {**settings.headers, **self.sandbox_config.headers}
|
|
@@ -524,9 +482,7 @@ class SandboxFileSystem(SandboxAction):
|
|
|
524
482
|
files = {"file": ("part", io.BytesIO(data), "application/octet-stream")}
|
|
525
483
|
|
|
526
484
|
client = self.get_client()
|
|
527
|
-
response = await client.put(
|
|
528
|
-
url, files=files, params=params, headers=headers
|
|
529
|
-
)
|
|
485
|
+
response = await client.put(url, files=files, params=params, headers=headers)
|
|
530
486
|
try:
|
|
531
487
|
data = json.loads(await response.aread())
|
|
532
488
|
self.handle_response_error(response)
|
|
@@ -17,7 +17,9 @@ class CodeInterpreter(SandboxInstance):
|
|
|
17
17
|
DEFAULT_PORTS = [
|
|
18
18
|
{"name": "jupyter", "target": 8888, "protocol": "HTTP"},
|
|
19
19
|
]
|
|
20
|
-
DEFAULT_LIFECYCLE = {
|
|
20
|
+
DEFAULT_LIFECYCLE = {
|
|
21
|
+
"expirationPolicies": [{"type": "ttl-idle", "value": "30m", "action": "delete"}]
|
|
22
|
+
}
|
|
21
23
|
|
|
22
24
|
@classmethod
|
|
23
25
|
async def get(cls, sandbox_name: str) -> CodeInterpreter:
|
|
@@ -148,11 +150,15 @@ class CodeInterpreter(SandboxInstance):
|
|
|
148
150
|
elif data_type == "stdout":
|
|
149
151
|
execution.logs.stdout.append(data["text"])
|
|
150
152
|
if on_stdout:
|
|
151
|
-
return on_stdout(
|
|
153
|
+
return on_stdout(
|
|
154
|
+
CodeInterpreter.OutputMessage(data["text"], data.get("timestamp"), False)
|
|
155
|
+
)
|
|
152
156
|
elif data_type == "stderr":
|
|
153
157
|
execution.logs.stderr.append(data["text"])
|
|
154
158
|
if on_stderr:
|
|
155
|
-
return on_stderr(
|
|
159
|
+
return on_stderr(
|
|
160
|
+
CodeInterpreter.OutputMessage(data["text"], data.get("timestamp"), True)
|
|
161
|
+
)
|
|
156
162
|
elif data_type == "error":
|
|
157
163
|
execution.error = CodeInterpreter.ExecutionError(
|
|
158
164
|
data.get("name", ""), data.get("value"), data.get("traceback")
|
|
@@ -200,7 +206,10 @@ class CodeInterpreter(SandboxInstance):
|
|
|
200
206
|
|
|
201
207
|
client = self.process.get_client()
|
|
202
208
|
timeout_cfg = httpx.Timeout(
|
|
203
|
-
connect=connect_timeout,
|
|
209
|
+
connect=connect_timeout,
|
|
210
|
+
read=read_timeout,
|
|
211
|
+
write=write_timeout,
|
|
212
|
+
pool=pool_timeout,
|
|
204
213
|
)
|
|
205
214
|
async with client.stream(
|
|
206
215
|
"POST",
|
|
@@ -243,7 +252,7 @@ class CodeInterpreter(SandboxInstance):
|
|
|
243
252
|
on_error=on_error,
|
|
244
253
|
)
|
|
245
254
|
except json.JSONDecodeError:
|
|
246
|
-
|
|
255
|
+
# Fallback: treat as stdout text-only message
|
|
247
256
|
execution.logs.stdout.append(decoded)
|
|
248
257
|
if on_stdout:
|
|
249
258
|
on_stdout(CodeInterpreter.OutputMessage(decoded, None, False))
|
|
@@ -271,10 +280,10 @@ class CodeInterpreter(SandboxInstance):
|
|
|
271
280
|
try:
|
|
272
281
|
# Always read response body first
|
|
273
282
|
body_bytes = await response.aread()
|
|
274
|
-
|
|
283
|
+
|
|
275
284
|
if response.status_code >= 400:
|
|
276
285
|
try:
|
|
277
|
-
body_text = body_bytes.decode(
|
|
286
|
+
body_text = body_bytes.decode("utf-8", errors="ignore")
|
|
278
287
|
except Exception:
|
|
279
288
|
body_text = "<unavailable>"
|
|
280
289
|
method = getattr(response.request, "method", "UNKNOWN")
|
|
@@ -287,10 +296,8 @@ class CodeInterpreter(SandboxInstance):
|
|
|
287
296
|
)
|
|
288
297
|
self.logger.debug(details)
|
|
289
298
|
raise RuntimeError(details)
|
|
290
|
-
|
|
299
|
+
|
|
291
300
|
data = json.loads(body_bytes)
|
|
292
301
|
return CodeInterpreter.Context.from_json(data)
|
|
293
302
|
finally:
|
|
294
303
|
await response.aclose()
|
|
295
|
-
|
|
296
|
-
|
|
@@ -15,11 +15,15 @@ from ...client.api.compute.delete_sandbox_preview import (
|
|
|
15
15
|
from ...client.api.compute.delete_sandbox_preview_token import (
|
|
16
16
|
asyncio as delete_sandbox_preview_token,
|
|
17
17
|
)
|
|
18
|
-
from ...client.api.compute.get_sandbox_preview import
|
|
18
|
+
from ...client.api.compute.get_sandbox_preview import (
|
|
19
|
+
asyncio as get_sandbox_preview,
|
|
20
|
+
)
|
|
19
21
|
from ...client.api.compute.list_sandbox_preview_tokens import (
|
|
20
22
|
asyncio as list_sandbox_preview_tokens,
|
|
21
23
|
)
|
|
22
|
-
from ...client.api.compute.list_sandbox_previews import
|
|
24
|
+
from ...client.api.compute.list_sandbox_previews import (
|
|
25
|
+
asyncio as list_sandbox_previews,
|
|
26
|
+
)
|
|
23
27
|
from ...client.client import client
|
|
24
28
|
from ...client.models import (
|
|
25
29
|
Preview,
|
|
@@ -15,7 +15,9 @@ class SandboxProcess(SandboxAction):
|
|
|
15
15
|
super().__init__(sandbox_config)
|
|
16
16
|
|
|
17
17
|
def stream_logs(
|
|
18
|
-
self,
|
|
18
|
+
self,
|
|
19
|
+
process_name: str,
|
|
20
|
+
options: Dict[str, Callable[[str], None]] | None = None,
|
|
19
21
|
) -> Dict[str, Callable[[], None]]:
|
|
20
22
|
"""Stream logs from a process with automatic reconnection and deduplication."""
|
|
21
23
|
if options is None:
|
|
@@ -111,7 +113,9 @@ class SandboxProcess(SandboxAction):
|
|
|
111
113
|
return {"close": close}
|
|
112
114
|
|
|
113
115
|
def _stream_logs(
|
|
114
|
-
self,
|
|
116
|
+
self,
|
|
117
|
+
identifier: str,
|
|
118
|
+
options: Dict[str, Callable[[str], None]] | None = None,
|
|
115
119
|
) -> Dict[str, Callable[[], None]]:
|
|
116
120
|
"""Private method to stream logs from a process with callbacks for different output types."""
|
|
117
121
|
if options is None:
|
|
@@ -175,7 +179,8 @@ class SandboxProcess(SandboxAction):
|
|
|
175
179
|
return {"close": close}
|
|
176
180
|
|
|
177
181
|
async def exec(
|
|
178
|
-
self,
|
|
182
|
+
self,
|
|
183
|
+
process: Union[ProcessRequest, ProcessRequestWithLog, Dict[str, Any]],
|
|
179
184
|
) -> Union[ProcessResponse, ProcessResponseWithLog]:
|
|
180
185
|
"""Execute a process in the sandbox."""
|
|
181
186
|
on_log = None
|
|
@@ -187,11 +192,6 @@ class SandboxProcess(SandboxAction):
|
|
|
187
192
|
if "on_log" in process:
|
|
188
193
|
on_log = process["on_log"]
|
|
189
194
|
del process["on_log"]
|
|
190
|
-
if "wait_for_completion" in process:
|
|
191
|
-
process["waitForCompletion"] = process["wait_for_completion"]
|
|
192
|
-
if "wait_for_ports" in process:
|
|
193
|
-
process["waitForPorts"] = process["wait_for_ports"]
|
|
194
|
-
del process["wait_for_ports"]
|
|
195
195
|
process = ProcessRequest.from_dict(process)
|
|
196
196
|
|
|
197
197
|
# Store original wait_for_completion setting
|
|
@@ -200,13 +200,14 @@ class SandboxProcess(SandboxAction):
|
|
|
200
200
|
# Always start process without wait_for_completion to avoid server-side blocking
|
|
201
201
|
if should_wait_for_completion and on_log is not None:
|
|
202
202
|
process.wait_for_completion = False
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
client = self.get_client()
|
|
205
205
|
response = await client.post("/process", json=process.to_dict())
|
|
206
206
|
try:
|
|
207
207
|
content_bytes = await response.aread()
|
|
208
208
|
self.handle_response_error(response)
|
|
209
209
|
import json
|
|
210
|
+
|
|
210
211
|
response_data = json.loads(content_bytes) if content_bytes else None
|
|
211
212
|
result = ProcessResponse.from_dict(response_data)
|
|
212
213
|
finally:
|
|
@@ -227,7 +228,8 @@ class SandboxProcess(SandboxAction):
|
|
|
227
228
|
if on_log is not None:
|
|
228
229
|
stream_control = self._stream_logs(result.pid, {"on_log": on_log})
|
|
229
230
|
return ProcessResponseWithLog(
|
|
230
|
-
result,
|
|
231
|
+
result,
|
|
232
|
+
lambda: stream_control["close"]() if stream_control else None,
|
|
231
233
|
)
|
|
232
234
|
|
|
233
235
|
return result
|
|
@@ -255,6 +257,7 @@ class SandboxProcess(SandboxAction):
|
|
|
255
257
|
|
|
256
258
|
async def get(self, identifier: str) -> ProcessResponse:
|
|
257
259
|
import json
|
|
260
|
+
|
|
258
261
|
client = self.get_client()
|
|
259
262
|
response = await client.get(f"/process/{identifier}")
|
|
260
263
|
try:
|
|
@@ -266,6 +269,7 @@ class SandboxProcess(SandboxAction):
|
|
|
266
269
|
|
|
267
270
|
async def list(self) -> list[ProcessResponse]:
|
|
268
271
|
import json
|
|
272
|
+
|
|
269
273
|
client = self.get_client()
|
|
270
274
|
response = await client.get("/process")
|
|
271
275
|
try:
|
|
@@ -277,6 +281,7 @@ class SandboxProcess(SandboxAction):
|
|
|
277
281
|
|
|
278
282
|
async def stop(self, identifier: str) -> SuccessResponse:
|
|
279
283
|
import json
|
|
284
|
+
|
|
280
285
|
client = self.get_client()
|
|
281
286
|
response = await client.delete(f"/process/{identifier}")
|
|
282
287
|
try:
|
|
@@ -288,6 +293,7 @@ class SandboxProcess(SandboxAction):
|
|
|
288
293
|
|
|
289
294
|
async def kill(self, identifier: str) -> SuccessResponse:
|
|
290
295
|
import json
|
|
296
|
+
|
|
291
297
|
client = self.get_client()
|
|
292
298
|
response = await client.delete(f"/process/{identifier}/kill")
|
|
293
299
|
try:
|
|
@@ -298,9 +304,12 @@ class SandboxProcess(SandboxAction):
|
|
|
298
304
|
await response.aclose()
|
|
299
305
|
|
|
300
306
|
async def logs(
|
|
301
|
-
self,
|
|
307
|
+
self,
|
|
308
|
+
identifier: str,
|
|
309
|
+
log_type: Literal["stdout", "stderr", "all"] = "all",
|
|
302
310
|
) -> str:
|
|
303
311
|
import json
|
|
312
|
+
|
|
304
313
|
client = self.get_client()
|
|
305
314
|
response = await client.get(f"/process/{identifier}/logs")
|
|
306
315
|
try:
|
|
@@ -105,26 +105,32 @@ class SandboxInstance:
|
|
|
105
105
|
or "expires" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
|
|
106
106
|
or "region" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
|
|
107
107
|
or "lifecycle" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
|
|
108
|
-
or "snapshot_enabled"
|
|
108
|
+
or "snapshot_enabled"
|
|
109
|
+
in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
|
|
109
110
|
)
|
|
110
111
|
)
|
|
111
112
|
):
|
|
113
|
+
config: SandboxCreateConfiguration
|
|
112
114
|
if sandbox is None:
|
|
113
|
-
|
|
115
|
+
config = SandboxCreateConfiguration()
|
|
114
116
|
elif isinstance(sandbox, dict) and not isinstance(sandbox, Sandbox):
|
|
115
|
-
|
|
117
|
+
config = SandboxCreateConfiguration.from_dict(sandbox)
|
|
118
|
+
elif isinstance(sandbox, SandboxCreateConfiguration):
|
|
119
|
+
config = sandbox
|
|
120
|
+
else:
|
|
121
|
+
raise ValueError(f"Unexpected sandbox type: {type(sandbox)}")
|
|
116
122
|
|
|
117
123
|
# Set defaults if not provided
|
|
118
|
-
name =
|
|
119
|
-
image =
|
|
120
|
-
memory =
|
|
121
|
-
ports =
|
|
122
|
-
envs =
|
|
123
|
-
volumes =
|
|
124
|
-
ttl =
|
|
125
|
-
expires =
|
|
126
|
-
region =
|
|
127
|
-
lifecycle =
|
|
124
|
+
name = config.name or default_name
|
|
125
|
+
image = config.image or default_image
|
|
126
|
+
memory = config.memory or default_memory
|
|
127
|
+
ports = config._normalize_ports() or UNSET
|
|
128
|
+
envs = config._normalize_envs() or UNSET
|
|
129
|
+
volumes = config._normalize_volumes() or UNSET
|
|
130
|
+
ttl = config.ttl
|
|
131
|
+
expires = config.expires
|
|
132
|
+
region = config.region
|
|
133
|
+
lifecycle = config.lifecycle
|
|
128
134
|
# snapshot_enabled = sandbox.snapshot_enabled
|
|
129
135
|
|
|
130
136
|
# Create full Sandbox object
|
|
@@ -132,7 +138,11 @@ class SandboxInstance:
|
|
|
132
138
|
metadata=Metadata(name=name),
|
|
133
139
|
spec=SandboxSpec(
|
|
134
140
|
runtime=Runtime(
|
|
135
|
-
image=image,
|
|
141
|
+
image=image,
|
|
142
|
+
memory=memory,
|
|
143
|
+
ports=ports,
|
|
144
|
+
envs=envs,
|
|
145
|
+
generation="mk3",
|
|
136
146
|
),
|
|
137
147
|
volumes=volumes,
|
|
138
148
|
),
|
|
@@ -51,7 +51,8 @@ class SyncSandboxAction:
|
|
|
51
51
|
def get_client(self) -> httpx.Client:
|
|
52
52
|
if self.sandbox_config.force_url:
|
|
53
53
|
return httpx.Client(
|
|
54
|
-
base_url=self.sandbox_config.force_url,
|
|
54
|
+
base_url=self.sandbox_config.force_url,
|
|
55
|
+
headers=self.sandbox_config.headers,
|
|
55
56
|
)
|
|
56
57
|
return httpx.Client(
|
|
57
58
|
base_url=self.url,
|
|
@@ -61,5 +62,3 @@ class SyncSandboxAction:
|
|
|
61
62
|
def handle_response_error(self, response: httpx.Response):
|
|
62
63
|
if not response.is_success:
|
|
63
64
|
raise ResponseError(response)
|
|
64
|
-
|
|
65
|
-
|
|
@@ -20,9 +20,7 @@ class SyncSandboxCodegen(SyncSandboxAction):
|
|
|
20
20
|
def __init__(self, sandbox_config: SandboxConfiguration):
|
|
21
21
|
super().__init__(sandbox_config)
|
|
22
22
|
|
|
23
|
-
def fastapply(
|
|
24
|
-
self, path: str, code_edit: str, model: str | None = None
|
|
25
|
-
) -> ApplyEditResponse:
|
|
23
|
+
def fastapply(self, path: str, code_edit: str, model: str | None = None) -> ApplyEditResponse:
|
|
26
24
|
body = ApplyEditRequest(code_edit=code_edit, model=model)
|
|
27
25
|
client = Client(
|
|
28
26
|
base_url=self.url,
|
|
@@ -66,5 +64,3 @@ class SyncSandboxCodegen(SyncSandboxAction):
|
|
|
66
64
|
if isinstance(response, ErrorResponse):
|
|
67
65
|
raise Exception(f"Reranking failed: {response}")
|
|
68
66
|
return response
|
|
69
|
-
|
|
70
|
-
|
|
@@ -61,7 +61,11 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
61
61
|
return self._upload_with_multipart(path, content, "0644")
|
|
62
62
|
binary_file = io.BytesIO(content)
|
|
63
63
|
files = {
|
|
64
|
-
"file": (
|
|
64
|
+
"file": (
|
|
65
|
+
"binary-file.bin",
|
|
66
|
+
binary_file,
|
|
67
|
+
"application/octet-stream",
|
|
68
|
+
),
|
|
65
69
|
}
|
|
66
70
|
data = {"permissions": "0644", "path": path}
|
|
67
71
|
url = f"{self.url}/filesystem/{path}"
|
|
@@ -195,7 +199,10 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
195
199
|
name=file_event_data.get("name", ""),
|
|
196
200
|
content=file_event_data.get("content"),
|
|
197
201
|
)
|
|
198
|
-
if options.get("with_content") and file_event.op in [
|
|
202
|
+
if options.get("with_content") and file_event.op in [
|
|
203
|
+
"CREATE",
|
|
204
|
+
"WRITE",
|
|
205
|
+
]:
|
|
199
206
|
try:
|
|
200
207
|
file_path = file_event.path
|
|
201
208
|
if file_path.endswith("/"):
|
|
@@ -244,7 +251,9 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
244
251
|
self.handle_response_error(response)
|
|
245
252
|
return response.json()
|
|
246
253
|
|
|
247
|
-
def _complete_multipart_upload(
|
|
254
|
+
def _complete_multipart_upload(
|
|
255
|
+
self, upload_id: str, parts: List[Dict[str, Any]]
|
|
256
|
+
) -> SuccessResponse:
|
|
248
257
|
url = f"{self.url}/filesystem-multipart/{upload_id}/complete"
|
|
249
258
|
headers = {**settings.headers, **self.sandbox_config.headers}
|
|
250
259
|
body = {"parts": parts}
|
|
@@ -261,7 +270,9 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
261
270
|
if not response.is_success:
|
|
262
271
|
logger.warning(f"Failed to abort multipart upload: {response.status_code}")
|
|
263
272
|
|
|
264
|
-
def _upload_with_multipart(
|
|
273
|
+
def _upload_with_multipart(
|
|
274
|
+
self, path: str, data: bytes, permissions: str = "0644"
|
|
275
|
+
) -> SuccessResponse:
|
|
265
276
|
init_response = self._initiate_multipart_upload(path, permissions)
|
|
266
277
|
upload_id = init_response.get("uploadId")
|
|
267
278
|
if not upload_id:
|
|
@@ -274,8 +285,10 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
274
285
|
for i in range(0, num_parts, MAX_PARALLEL_UPLOADS):
|
|
275
286
|
threads = []
|
|
276
287
|
results: Dict[int, Dict[str, Any]] = {}
|
|
288
|
+
|
|
277
289
|
def make_upload(part_number: int, chunk: bytes):
|
|
278
290
|
results[part_number] = self._upload_part(upload_id, part_number, chunk)
|
|
291
|
+
|
|
279
292
|
for j in range(MAX_PARALLEL_UPLOADS):
|
|
280
293
|
if i + j >= num_parts:
|
|
281
294
|
break
|
|
@@ -298,5 +311,3 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
298
311
|
except Exception as abort_error:
|
|
299
312
|
logger.warning(f"Failed to abort multipart upload: {abort_error}")
|
|
300
313
|
raise error
|
|
301
|
-
|
|
302
|
-
|
|
@@ -15,7 +15,9 @@ class SyncCodeInterpreter(SyncSandboxInstance):
|
|
|
15
15
|
DEFAULT_PORTS = [
|
|
16
16
|
{"name": "jupyter", "target": 8888, "protocol": "HTTP"},
|
|
17
17
|
]
|
|
18
|
-
DEFAULT_LIFECYCLE = {
|
|
18
|
+
DEFAULT_LIFECYCLE = {
|
|
19
|
+
"expirationPolicies": [{"type": "ttl-idle", "value": "30m", "action": "delete"}]
|
|
20
|
+
}
|
|
19
21
|
|
|
20
22
|
@classmethod
|
|
21
23
|
def get(cls, sandbox_name: str) -> "SyncCodeInterpreter":
|
|
@@ -221,7 +223,10 @@ class SyncCodeInterpreter(SyncSandboxInstance):
|
|
|
221
223
|
# Use the process client to inherit base_url and headers
|
|
222
224
|
with self.process.get_client() as client:
|
|
223
225
|
timeout_cfg = httpx.Timeout(
|
|
224
|
-
connect=connect_timeout,
|
|
226
|
+
connect=connect_timeout,
|
|
227
|
+
read=read_timeout,
|
|
228
|
+
write=write_timeout,
|
|
229
|
+
pool=pool_timeout,
|
|
225
230
|
)
|
|
226
231
|
with client.stream(
|
|
227
232
|
"POST",
|
|
@@ -238,7 +243,9 @@ class SyncCodeInterpreter(SyncSandboxInstance):
|
|
|
238
243
|
if not line:
|
|
239
244
|
continue
|
|
240
245
|
try:
|
|
241
|
-
decoded =
|
|
246
|
+
decoded = (
|
|
247
|
+
line.decode() if isinstance(line, bytes | bytearray) else str(line)
|
|
248
|
+
)
|
|
242
249
|
except Exception:
|
|
243
250
|
decoded = str(line)
|
|
244
251
|
try:
|
|
@@ -270,7 +277,6 @@ class SyncCodeInterpreter(SyncSandboxInstance):
|
|
|
270
277
|
if cwd:
|
|
271
278
|
data["cwd"] = cwd
|
|
272
279
|
|
|
273
|
-
|
|
274
280
|
with self.process.get_client() as client:
|
|
275
281
|
response = client.post(
|
|
276
282
|
"/port/8888/contexts",
|
|
@@ -283,5 +289,3 @@ class SyncCodeInterpreter(SyncSandboxInstance):
|
|
|
283
289
|
raise RuntimeError(details)
|
|
284
290
|
data = response.json()
|
|
285
291
|
return SyncCodeInterpreter.Context.from_json(data)
|
|
286
|
-
|
|
287
|
-
|