kernel 0.59.0__tar.gz → 0.60.0__tar.gz

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.
Files changed (318) hide show
  1. kernel-0.60.0/.release-please-manifest.json +3 -0
  2. {kernel-0.59.0 → kernel-0.60.0}/CHANGELOG.md +16 -0
  3. {kernel-0.59.0 → kernel-0.60.0}/PKG-INFO +1 -1
  4. kernel-0.60.0/examples/browser_telemetry.py +32 -0
  5. {kernel-0.59.0 → kernel-0.60.0}/pyproject.toml +1 -1
  6. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_streaming.py +6 -1
  7. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_version.py +1 -1
  8. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/lib/browser_routing/routing.py +1 -1
  9. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/api_keys.py +27 -0
  10. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browser_pools.py +12 -12
  11. kernel-0.60.0/src/kernel/types/api_key_list_params.py +27 -0
  12. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_update_params.py +8 -8
  13. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_api_keys.py +6 -0
  14. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_browser_pools.py +2 -10
  15. {kernel-0.59.0 → kernel-0.60.0}/tests/test_browser_routing.py +23 -1
  16. {kernel-0.59.0 → kernel-0.60.0}/tests/test_streaming.py +26 -0
  17. kernel-0.59.0/.release-please-manifest.json +0 -3
  18. kernel-0.59.0/src/kernel/types/api_key_list_params.py +0 -15
  19. {kernel-0.59.0 → kernel-0.60.0}/.gitignore +0 -0
  20. {kernel-0.59.0 → kernel-0.60.0}/CONTRIBUTING.md +0 -0
  21. {kernel-0.59.0 → kernel-0.60.0}/LICENSE +0 -0
  22. {kernel-0.59.0 → kernel-0.60.0}/README.md +0 -0
  23. {kernel-0.59.0 → kernel-0.60.0}/SECURITY.md +0 -0
  24. {kernel-0.59.0 → kernel-0.60.0}/api.md +0 -0
  25. {kernel-0.59.0 → kernel-0.60.0}/bin/check-release-environment +0 -0
  26. {kernel-0.59.0 → kernel-0.60.0}/bin/publish-pypi +0 -0
  27. {kernel-0.59.0 → kernel-0.60.0}/examples/.keep +0 -0
  28. {kernel-0.59.0 → kernel-0.60.0}/examples/browser_routing.py +0 -0
  29. {kernel-0.59.0 → kernel-0.60.0}/noxfile.py +0 -0
  30. {kernel-0.59.0 → kernel-0.60.0}/release-please-config.json +0 -0
  31. {kernel-0.59.0 → kernel-0.60.0}/requirements-dev.lock +0 -0
  32. {kernel-0.59.0 → kernel-0.60.0}/requirements.lock +0 -0
  33. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/__init__.py +0 -0
  34. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_base_client.py +0 -0
  35. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_client.py +0 -0
  36. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_compat.py +0 -0
  37. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_constants.py +0 -0
  38. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_exceptions.py +0 -0
  39. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_files.py +0 -0
  40. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_models.py +0 -0
  41. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_qs.py +0 -0
  42. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_resource.py +0 -0
  43. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_response.py +0 -0
  44. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_types.py +0 -0
  45. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/__init__.py +0 -0
  46. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_compat.py +0 -0
  47. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_datetime_parse.py +0 -0
  48. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_json.py +0 -0
  49. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_logs.py +0 -0
  50. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_path.py +0 -0
  51. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_proxy.py +0 -0
  52. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_reflection.py +0 -0
  53. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_resources_proxy.py +0 -0
  54. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_streams.py +0 -0
  55. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_sync.py +0 -0
  56. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_transform.py +0 -0
  57. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_typing.py +0 -0
  58. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/_utils/_utils.py +0 -0
  59. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/app_framework.py +0 -0
  60. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/lib/.keep +0 -0
  61. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/lib/browser_routing/__init__.py +0 -0
  62. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/lib/browser_routing/raw_http.py +0 -0
  63. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/lib/browser_routing/util.py +0 -0
  64. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/pagination.py +0 -0
  65. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/py.typed +0 -0
  66. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/__init__.py +0 -0
  67. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/apps.py +0 -0
  68. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/auth/__init__.py +0 -0
  69. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/auth/auth.py +0 -0
  70. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/auth/connections.py +0 -0
  71. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/__init__.py +0 -0
  72. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/browsers.py +0 -0
  73. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/computer.py +0 -0
  74. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/fs/__init__.py +0 -0
  75. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/fs/fs.py +0 -0
  76. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/fs/watch.py +0 -0
  77. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/logs.py +0 -0
  78. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/playwright.py +0 -0
  79. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/process.py +0 -0
  80. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/replays.py +0 -0
  81. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/browsers/telemetry.py +0 -0
  82. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/credential_providers.py +0 -0
  83. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/credentials.py +0 -0
  84. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/deployments.py +0 -0
  85. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/extensions.py +0 -0
  86. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/invocations.py +0 -0
  87. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/profiles.py +0 -0
  88. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/projects/__init__.py +0 -0
  89. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/projects/limits.py +0 -0
  90. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/projects/projects.py +0 -0
  91. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/resources/proxies.py +0 -0
  92. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/__init__.py +0 -0
  93. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/api_key.py +0 -0
  94. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/api_key_create_params.py +0 -0
  95. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/api_key_update_params.py +0 -0
  96. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/app_list_params.py +0 -0
  97. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/app_list_response.py +0 -0
  98. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/__init__.py +0 -0
  99. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/connection_create_params.py +0 -0
  100. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/connection_follow_response.py +0 -0
  101. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/connection_list_params.py +0 -0
  102. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/connection_login_params.py +0 -0
  103. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/connection_submit_params.py +0 -0
  104. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/connection_update_params.py +0 -0
  105. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/login_response.py +0 -0
  106. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/managed_auth.py +0 -0
  107. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/auth/submit_fields_response.py +0 -0
  108. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_create_params.py +0 -0
  109. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_create_response.py +0 -0
  110. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_curl_params.py +0 -0
  111. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_curl_response.py +0 -0
  112. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_list_params.py +0 -0
  113. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_list_response.py +0 -0
  114. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_load_extensions_params.py +0 -0
  115. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool.py +0 -0
  116. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_acquire_params.py +0 -0
  117. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_acquire_response.py +0 -0
  118. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_create_params.py +0 -0
  119. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_delete_params.py +0 -0
  120. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_list_response.py +0 -0
  121. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_ref.py +0 -0
  122. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_pool_release_params.py +0 -0
  123. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_retrieve_params.py +0 -0
  124. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_retrieve_response.py +0 -0
  125. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_update_params.py +0 -0
  126. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_update_response.py +0 -0
  127. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browser_usage.py +0 -0
  128. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/__init__.py +0 -0
  129. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_call_stack.py +0 -0
  130. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_console_error_event.py +0 -0
  131. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_console_log_event.py +0 -0
  132. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_event_context.py +0 -0
  133. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_event_source.py +0 -0
  134. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_http_headers.py +0 -0
  135. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_interaction_click_event.py +0 -0
  136. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_interaction_key_event.py +0 -0
  137. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_interaction_scroll_settled_event.py +0 -0
  138. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_monitor_disconnected_event.py +0 -0
  139. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_monitor_init_failed_event.py +0 -0
  140. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_monitor_reconnect_failed_event.py +0 -0
  141. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_monitor_reconnected_event.py +0 -0
  142. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_monitor_screenshot_event.py +0 -0
  143. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_network_idle_event.py +0 -0
  144. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_network_loading_failed_event.py +0 -0
  145. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_network_request_event.py +0 -0
  146. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_network_response_event.py +0 -0
  147. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_dom_content_loaded_event.py +0 -0
  148. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_layout_settled_event.py +0 -0
  149. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_layout_shift_event.py +0 -0
  150. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_lcp_event.py +0 -0
  151. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_load_event.py +0 -0
  152. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_navigation_event.py +0 -0
  153. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_navigation_settled_event.py +0 -0
  154. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_page_tab_opened_event.py +0 -0
  155. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_telemetry_categories_config.py +0 -0
  156. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_telemetry_categories_config_param.py +0 -0
  157. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_telemetry_category_config.py +0 -0
  158. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_telemetry_category_config_param.py +0 -0
  159. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_telemetry_config.py +0 -0
  160. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/browser_telemetry_event.py +0 -0
  161. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_batch_params.py +0 -0
  162. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_capture_screenshot_params.py +0 -0
  163. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_click_mouse_params.py +0 -0
  164. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_drag_mouse_params.py +0 -0
  165. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_get_mouse_position_response.py +0 -0
  166. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_move_mouse_params.py +0 -0
  167. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_press_key_params.py +0 -0
  168. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_read_clipboard_response.py +0 -0
  169. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_scroll_params.py +0 -0
  170. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_set_cursor_visibility_params.py +0 -0
  171. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_set_cursor_visibility_response.py +0 -0
  172. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_type_text_params.py +0 -0
  173. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/computer_write_clipboard_params.py +0 -0
  174. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_create_directory_params.py +0 -0
  175. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_delete_directory_params.py +0 -0
  176. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_delete_file_params.py +0 -0
  177. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_download_dir_zip_params.py +0 -0
  178. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_file_info_params.py +0 -0
  179. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_file_info_response.py +0 -0
  180. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_list_files_params.py +0 -0
  181. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_list_files_response.py +0 -0
  182. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_move_params.py +0 -0
  183. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_read_file_params.py +0 -0
  184. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_set_file_permissions_params.py +0 -0
  185. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_upload_params.py +0 -0
  186. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_upload_zip_params.py +0 -0
  187. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/f_write_file_params.py +0 -0
  188. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/fs/__init__.py +0 -0
  189. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/fs/watch_events_response.py +0 -0
  190. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/fs/watch_start_params.py +0 -0
  191. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/fs/watch_start_response.py +0 -0
  192. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/log_stream_params.py +0 -0
  193. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/playwright_execute_params.py +0 -0
  194. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/playwright_execute_response.py +0 -0
  195. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_exec_params.py +0 -0
  196. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_exec_response.py +0 -0
  197. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_kill_params.py +0 -0
  198. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_kill_response.py +0 -0
  199. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_resize_params.py +0 -0
  200. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_resize_response.py +0 -0
  201. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_spawn_params.py +0 -0
  202. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_spawn_response.py +0 -0
  203. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_status_response.py +0 -0
  204. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_stdin_params.py +0 -0
  205. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_stdin_response.py +0 -0
  206. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/process_stdout_stream_response.py +0 -0
  207. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/replay_list_response.py +0 -0
  208. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/replay_start_params.py +0 -0
  209. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/replay_start_response.py +0 -0
  210. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/browsers/telemetry_stream_response.py +0 -0
  211. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/created_api_key.py +0 -0
  212. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential.py +0 -0
  213. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_create_params.py +0 -0
  214. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_list_params.py +0 -0
  215. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider.py +0 -0
  216. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider_create_params.py +0 -0
  217. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider_item.py +0 -0
  218. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider_list_items_response.py +0 -0
  219. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider_list_response.py +0 -0
  220. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider_test_result.py +0 -0
  221. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_provider_update_params.py +0 -0
  222. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_totp_code_response.py +0 -0
  223. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/credential_update_params.py +0 -0
  224. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_create_params.py +0 -0
  225. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_create_response.py +0 -0
  226. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_follow_params.py +0 -0
  227. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_follow_response.py +0 -0
  228. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_list_params.py +0 -0
  229. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_list_response.py +0 -0
  230. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_retrieve_response.py +0 -0
  231. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/deployment_state_event.py +0 -0
  232. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/extension_download_from_chrome_store_params.py +0 -0
  233. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/extension_list_response.py +0 -0
  234. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/extension_upload_params.py +0 -0
  235. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/extension_upload_response.py +0 -0
  236. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_create_params.py +0 -0
  237. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_create_response.py +0 -0
  238. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_follow_params.py +0 -0
  239. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_follow_response.py +0 -0
  240. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_list_browsers_response.py +0 -0
  241. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_list_params.py +0 -0
  242. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_list_response.py +0 -0
  243. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_retrieve_response.py +0 -0
  244. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_state_event.py +0 -0
  245. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_update_params.py +0 -0
  246. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/invocation_update_response.py +0 -0
  247. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/profile.py +0 -0
  248. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/profile_create_params.py +0 -0
  249. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/profile_list_params.py +0 -0
  250. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/project.py +0 -0
  251. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/project_create_params.py +0 -0
  252. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/project_list_params.py +0 -0
  253. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/project_update_params.py +0 -0
  254. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/projects/__init__.py +0 -0
  255. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/projects/limit_update_params.py +0 -0
  256. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/projects/project_limits.py +0 -0
  257. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/proxy_check_params.py +0 -0
  258. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/proxy_check_response.py +0 -0
  259. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/proxy_create_params.py +0 -0
  260. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/proxy_create_response.py +0 -0
  261. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/proxy_list_response.py +0 -0
  262. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/proxy_retrieve_response.py +0 -0
  263. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/__init__.py +0 -0
  264. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/app_action.py +0 -0
  265. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/browser_extension.py +0 -0
  266. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/browser_profile.py +0 -0
  267. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/browser_viewport.py +0 -0
  268. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/error_detail.py +0 -0
  269. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/error_event.py +0 -0
  270. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/error_model.py +0 -0
  271. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/heartbeat_event.py +0 -0
  272. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared/log_event.py +0 -0
  273. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared_params/__init__.py +0 -0
  274. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared_params/browser_extension.py +0 -0
  275. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared_params/browser_profile.py +0 -0
  276. {kernel-0.59.0 → kernel-0.60.0}/src/kernel/types/shared_params/browser_viewport.py +0 -0
  277. {kernel-0.59.0 → kernel-0.60.0}/tests/__init__.py +0 -0
  278. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/__init__.py +0 -0
  279. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/auth/__init__.py +0 -0
  280. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/auth/test_connections.py +0 -0
  281. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/__init__.py +0 -0
  282. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/fs/__init__.py +0 -0
  283. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/fs/test_watch.py +0 -0
  284. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_computer.py +0 -0
  285. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_fs.py +0 -0
  286. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_logs.py +0 -0
  287. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_playwright.py +0 -0
  288. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_process.py +0 -0
  289. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_replays.py +0 -0
  290. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/browsers/test_telemetry.py +0 -0
  291. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/projects/__init__.py +0 -0
  292. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/projects/test_limits.py +0 -0
  293. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_apps.py +0 -0
  294. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_browsers.py +0 -0
  295. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_credential_providers.py +0 -0
  296. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_credentials.py +0 -0
  297. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_deployments.py +0 -0
  298. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_extensions.py +0 -0
  299. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_invocations.py +0 -0
  300. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_profiles.py +0 -0
  301. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_projects.py +0 -0
  302. {kernel-0.59.0 → kernel-0.60.0}/tests/api_resources/test_proxies.py +0 -0
  303. {kernel-0.59.0 → kernel-0.60.0}/tests/conftest.py +0 -0
  304. {kernel-0.59.0 → kernel-0.60.0}/tests/sample_file.txt +0 -0
  305. {kernel-0.59.0 → kernel-0.60.0}/tests/test_client.py +0 -0
  306. {kernel-0.59.0 → kernel-0.60.0}/tests/test_extract_files.py +0 -0
  307. {kernel-0.59.0 → kernel-0.60.0}/tests/test_files.py +0 -0
  308. {kernel-0.59.0 → kernel-0.60.0}/tests/test_models.py +0 -0
  309. {kernel-0.59.0 → kernel-0.60.0}/tests/test_qs.py +0 -0
  310. {kernel-0.59.0 → kernel-0.60.0}/tests/test_required_args.py +0 -0
  311. {kernel-0.59.0 → kernel-0.60.0}/tests/test_response.py +0 -0
  312. {kernel-0.59.0 → kernel-0.60.0}/tests/test_transform.py +0 -0
  313. {kernel-0.59.0 → kernel-0.60.0}/tests/test_utils/test_datetime_parse.py +0 -0
  314. {kernel-0.59.0 → kernel-0.60.0}/tests/test_utils/test_json.py +0 -0
  315. {kernel-0.59.0 → kernel-0.60.0}/tests/test_utils/test_path.py +0 -0
  316. {kernel-0.59.0 → kernel-0.60.0}/tests/test_utils/test_proxy.py +0 -0
  317. {kernel-0.59.0 → kernel-0.60.0}/tests/test_utils/test_typing.py +0 -0
  318. {kernel-0.59.0 → kernel-0.60.0}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.60.0"
3
+ }
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.60.0 (2026-06-03)
4
+
5
+ Full Changelog: [v0.59.0...v0.60.0](https://github.com/kernel/kernel-python-sdk/compare/v0.59.0...v0.60.0)
6
+
7
+ ### Features
8
+
9
+ * Add API-backed API key management endpoints ([55bd31e](https://github.com/kernel/kernel-python-sdk/commit/55bd31edfed74f3bc4b08f83e07448e2e53378b0))
10
+ * **examples:** add browser-telemetry example ([4c29993](https://github.com/kernel/kernel-python-sdk/commit/4c29993cdda50fcde19ee7bf696a268cd8b0eb0b))
11
+ * Fix browser pool update schema ([903fe13](https://github.com/kernel/kernel-python-sdk/commit/903fe13b84242acea9c27bc451c16fb5cd58e40c))
12
+ * route browser telemetry directly to the VM by default ([cb50725](https://github.com/kernel/kernel-python-sdk/commit/cb5072516416627ffde7198900484c46dda5b9dc))
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **streaming:** don't dispatch empty SSE keepalive comment frames ([a0ee2b2](https://github.com/kernel/kernel-python-sdk/commit/a0ee2b2653c581839be11bb29be5b68166e80658))
18
+
3
19
  ## 0.59.0 (2026-06-03)
4
20
 
5
21
  Full Changelog: [v0.58.0...v0.59.0](https://github.com/kernel/kernel-python-sdk/compare/v0.58.0...v0.59.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kernel
3
- Version: 0.59.0
3
+ Version: 0.60.0
4
4
  Summary: The official Python library for the kernel API
5
5
  Project-URL: Homepage, https://github.com/kernel/kernel-python-sdk
6
6
  Project-URL: Repository, https://github.com/kernel/kernel-python-sdk
@@ -0,0 +1,32 @@
1
+ """Example: stream live browser telemetry events from a session."""
2
+
3
+ from kernel import Kernel
4
+
5
+
6
+ def main() -> None:
7
+ client = Kernel()
8
+
9
+ # Enable telemetry capture when creating the browser.
10
+ browser = client.browsers.create(telemetry={"enabled": True})
11
+
12
+ try:
13
+ # Telemetry is a default direct-to-VM routing subresource, so the stream
14
+ # connects straight to the browser VM automatically.
15
+ stream = client.browsers.telemetry.stream(browser.session_id)
16
+
17
+ # Make a few browser activity calls to generate events. The "api" telemetry
18
+ # category emits an event per VM API call, so events arrive within ~1s.
19
+ for _ in range(3):
20
+ client.browsers.curl(browser.session_id, url="https://example.com", method="GET")
21
+
22
+ # Print a few events, then stop so we don't wait on the 15s keepalive.
23
+ for count, message in enumerate(stream, start=1):
24
+ print(message.seq, message.event.type)
25
+ if count >= 3:
26
+ break
27
+ finally:
28
+ client.browsers.delete_by_id(browser.session_id)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ main()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kernel"
3
- version = "0.59.0"
3
+ version = "0.60.0"
4
4
  description = "The official Python library for the kernel API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -251,7 +251,12 @@ class SSEDecoder:
251
251
  # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501
252
252
 
253
253
  if not line:
254
- if not self._event and not self._data and not self._last_event_id and self._retry is None:
254
+ # Whether to dispatch depends only on what was set in the *current* block. last_event_id
255
+ # is sticky across events (per the SSE spec, it is intentionally not reset below), so it
256
+ # must not be part of this check -- otherwise, once any event carries an id, every
257
+ # subsequent comment-only block (e.g. a ``:\n\n`` keepalive) would dispatch an empty
258
+ # event, which then fails to JSON-decode in the typed Stream wrapper.
259
+ if not self._event and not self._data and self._retry is None:
255
260
  return None
256
261
 
257
262
  sse = ServerSentEvent(
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "kernel"
4
- __version__ = "0.59.0" # x-release-please-version
4
+ __version__ = "0.60.0" # x-release-please-version
@@ -41,7 +41,7 @@ _BROWSER_POOL_RELEASE_PATH = re.compile(r"^/(?:v\d+/)?browser_pools/[^/]+/releas
41
41
  def browser_routing_config_from_env() -> BrowserRoutingConfig:
42
42
  raw = os.environ.get("KERNEL_BROWSER_ROUTING_SUBRESOURCES")
43
43
  if raw is None:
44
- return BrowserRoutingConfig(subresources=("curl",))
44
+ return BrowserRoutingConfig(subresources=("curl", "telemetry"))
45
45
  if raw.strip() == "":
46
46
  return BrowserRoutingConfig()
47
47
 
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from typing import Optional
6
+ from typing_extensions import Literal
6
7
 
7
8
  import httpx
8
9
 
@@ -171,6 +172,9 @@ class APIKeysResource(SyncAPIResource):
171
172
  *,
172
173
  limit: int | Omit = omit,
173
174
  offset: int | Omit = omit,
175
+ query: str | Omit = omit,
176
+ sort_by: Literal["created_at", "name", "expires_at"] | Omit = omit,
177
+ sort_direction: Literal["asc", "desc"] | Omit = omit,
174
178
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
175
179
  # The extra values given here take precedence over values defined on the client or passed to this method.
176
180
  extra_headers: Headers | None = None,
@@ -187,6 +191,13 @@ class APIKeysResource(SyncAPIResource):
187
191
 
188
192
  offset: Number of results to skip
189
193
 
194
+ query: Case-insensitive substring match against API key name, creator, and project. API
195
+ key identifiers and masked keys match by exact value or prefix.
196
+
197
+ sort_by: Field to sort API keys by.
198
+
199
+ sort_direction: Sort direction for API keys.
200
+
190
201
  extra_headers: Send extra headers
191
202
 
192
203
  extra_query: Add additional query parameters to the request
@@ -207,6 +218,9 @@ class APIKeysResource(SyncAPIResource):
207
218
  {
208
219
  "limit": limit,
209
220
  "offset": offset,
221
+ "query": query,
222
+ "sort_by": sort_by,
223
+ "sort_direction": sort_direction,
210
224
  },
211
225
  api_key_list_params.APIKeyListParams,
212
226
  ),
@@ -395,6 +409,9 @@ class AsyncAPIKeysResource(AsyncAPIResource):
395
409
  *,
396
410
  limit: int | Omit = omit,
397
411
  offset: int | Omit = omit,
412
+ query: str | Omit = omit,
413
+ sort_by: Literal["created_at", "name", "expires_at"] | Omit = omit,
414
+ sort_direction: Literal["asc", "desc"] | Omit = omit,
398
415
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
399
416
  # The extra values given here take precedence over values defined on the client or passed to this method.
400
417
  extra_headers: Headers | None = None,
@@ -411,6 +428,13 @@ class AsyncAPIKeysResource(AsyncAPIResource):
411
428
 
412
429
  offset: Number of results to skip
413
430
 
431
+ query: Case-insensitive substring match against API key name, creator, and project. API
432
+ key identifiers and masked keys match by exact value or prefix.
433
+
434
+ sort_by: Field to sort API keys by.
435
+
436
+ sort_direction: Sort direction for API keys.
437
+
414
438
  extra_headers: Send extra headers
415
439
 
416
440
  extra_query: Add additional query parameters to the request
@@ -431,6 +455,9 @@ class AsyncAPIKeysResource(AsyncAPIResource):
431
455
  {
432
456
  "limit": limit,
433
457
  "offset": offset,
458
+ "query": query,
459
+ "sort_by": sort_by,
460
+ "sort_direction": sort_direction,
434
461
  },
435
462
  api_key_list_params.APIKeyListParams,
436
463
  ),
@@ -206,7 +206,6 @@ class BrowserPoolsResource(SyncAPIResource):
206
206
  self,
207
207
  id_or_name: str,
208
208
  *,
209
- size: int,
210
209
  chrome_policy: Dict[str, object] | Omit = omit,
211
210
  discard_all_idle: bool | Omit = omit,
212
211
  extensions: Iterable[BrowserExtension] | Omit = omit,
@@ -216,6 +215,7 @@ class BrowserPoolsResource(SyncAPIResource):
216
215
  name: str | Omit = omit,
217
216
  profile: BrowserProfile | Omit = omit,
218
217
  proxy_id: str | Omit = omit,
218
+ size: int | Omit = omit,
219
219
  start_url: str | Omit = omit,
220
220
  stealth: bool | Omit = omit,
221
221
  timeout_seconds: int | Omit = omit,
@@ -231,10 +231,6 @@ class BrowserPoolsResource(SyncAPIResource):
231
231
  Updates the configuration used to create browsers in the pool.
232
232
 
233
233
  Args:
234
- size: Number of browsers to maintain in the pool. The maximum size is determined by
235
- your organization's pooled sessions limit (the sum of all pool sizes cannot
236
- exceed your limit).
237
-
238
234
  chrome_policy: Custom Chrome enterprise policy overrides applied to all browsers in this pool.
239
235
  Keys are Chrome enterprise policy names; values must match their expected types.
240
236
  Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
@@ -261,6 +257,10 @@ class BrowserPoolsResource(SyncAPIResource):
261
257
  proxy_id: Optional proxy to associate to the browser session. Must reference a proxy
262
258
  belonging to the caller's org.
263
259
 
260
+ size: Number of browsers to maintain in the pool. The maximum size is determined by
261
+ your organization's pooled sessions limit (the sum of all pool sizes cannot
262
+ exceed your limit).
263
+
264
264
  start_url: Optional URL to navigate to when a new browser is warmed into the pool.
265
265
  Best-effort: failures to navigate do not fail pool fill. Only applied to
266
266
  newly-warmed browsers; browsers reused via release/acquire keep whatever URL the
@@ -300,7 +300,6 @@ class BrowserPoolsResource(SyncAPIResource):
300
300
  path_template("/browser_pools/{id_or_name}", id_or_name=id_or_name),
301
301
  body=maybe_transform(
302
302
  {
303
- "size": size,
304
303
  "chrome_policy": chrome_policy,
305
304
  "discard_all_idle": discard_all_idle,
306
305
  "extensions": extensions,
@@ -310,6 +309,7 @@ class BrowserPoolsResource(SyncAPIResource):
310
309
  "name": name,
311
310
  "profile": profile,
312
311
  "proxy_id": proxy_id,
312
+ "size": size,
313
313
  "start_url": start_url,
314
314
  "stealth": stealth,
315
315
  "timeout_seconds": timeout_seconds,
@@ -684,7 +684,6 @@ class AsyncBrowserPoolsResource(AsyncAPIResource):
684
684
  self,
685
685
  id_or_name: str,
686
686
  *,
687
- size: int,
688
687
  chrome_policy: Dict[str, object] | Omit = omit,
689
688
  discard_all_idle: bool | Omit = omit,
690
689
  extensions: Iterable[BrowserExtension] | Omit = omit,
@@ -694,6 +693,7 @@ class AsyncBrowserPoolsResource(AsyncAPIResource):
694
693
  name: str | Omit = omit,
695
694
  profile: BrowserProfile | Omit = omit,
696
695
  proxy_id: str | Omit = omit,
696
+ size: int | Omit = omit,
697
697
  start_url: str | Omit = omit,
698
698
  stealth: bool | Omit = omit,
699
699
  timeout_seconds: int | Omit = omit,
@@ -709,10 +709,6 @@ class AsyncBrowserPoolsResource(AsyncAPIResource):
709
709
  Updates the configuration used to create browsers in the pool.
710
710
 
711
711
  Args:
712
- size: Number of browsers to maintain in the pool. The maximum size is determined by
713
- your organization's pooled sessions limit (the sum of all pool sizes cannot
714
- exceed your limit).
715
-
716
712
  chrome_policy: Custom Chrome enterprise policy overrides applied to all browsers in this pool.
717
713
  Keys are Chrome enterprise policy names; values must match their expected types.
718
714
  Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
@@ -739,6 +735,10 @@ class AsyncBrowserPoolsResource(AsyncAPIResource):
739
735
  proxy_id: Optional proxy to associate to the browser session. Must reference a proxy
740
736
  belonging to the caller's org.
741
737
 
738
+ size: Number of browsers to maintain in the pool. The maximum size is determined by
739
+ your organization's pooled sessions limit (the sum of all pool sizes cannot
740
+ exceed your limit).
741
+
742
742
  start_url: Optional URL to navigate to when a new browser is warmed into the pool.
743
743
  Best-effort: failures to navigate do not fail pool fill. Only applied to
744
744
  newly-warmed browsers; browsers reused via release/acquire keep whatever URL the
@@ -778,7 +778,6 @@ class AsyncBrowserPoolsResource(AsyncAPIResource):
778
778
  path_template("/browser_pools/{id_or_name}", id_or_name=id_or_name),
779
779
  body=await async_maybe_transform(
780
780
  {
781
- "size": size,
782
781
  "chrome_policy": chrome_policy,
783
782
  "discard_all_idle": discard_all_idle,
784
783
  "extensions": extensions,
@@ -788,6 +787,7 @@ class AsyncBrowserPoolsResource(AsyncAPIResource):
788
787
  "name": name,
789
788
  "profile": profile,
790
789
  "proxy_id": proxy_id,
790
+ "size": size,
791
791
  "start_url": start_url,
792
792
  "stealth": stealth,
793
793
  "timeout_seconds": timeout_seconds,
@@ -0,0 +1,27 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing_extensions import Literal, TypedDict
6
+
7
+ __all__ = ["APIKeyListParams"]
8
+
9
+
10
+ class APIKeyListParams(TypedDict, total=False):
11
+ limit: int
12
+ """Maximum number of results to return"""
13
+
14
+ offset: int
15
+ """Number of results to skip"""
16
+
17
+ query: str
18
+ """Case-insensitive substring match against API key name, creator, and project.
19
+
20
+ API key identifiers and masked keys match by exact value or prefix.
21
+ """
22
+
23
+ sort_by: Literal["created_at", "name", "expires_at"]
24
+ """Field to sort API keys by."""
25
+
26
+ sort_direction: Literal["asc", "desc"]
27
+ """Sort direction for API keys."""
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from typing import Dict, Iterable
6
- from typing_extensions import Required, TypedDict
6
+ from typing_extensions import TypedDict
7
7
 
8
8
  from .shared_params.browser_profile import BrowserProfile
9
9
  from .shared_params.browser_viewport import BrowserViewport
@@ -13,13 +13,6 @@ __all__ = ["BrowserPoolUpdateParams"]
13
13
 
14
14
 
15
15
  class BrowserPoolUpdateParams(TypedDict, total=False):
16
- size: Required[int]
17
- """Number of browsers to maintain in the pool.
18
-
19
- The maximum size is determined by your organization's pooled sessions limit (the
20
- sum of all pool sizes cannot exceed your limit).
21
- """
22
-
23
16
  chrome_policy: Dict[str, object]
24
17
  """Custom Chrome enterprise policy overrides applied to all browsers in this pool.
25
18
 
@@ -68,6 +61,13 @@ class BrowserPoolUpdateParams(TypedDict, total=False):
68
61
  Must reference a proxy belonging to the caller's org.
69
62
  """
70
63
 
64
+ size: int
65
+ """Number of browsers to maintain in the pool.
66
+
67
+ The maximum size is determined by your organization's pooled sessions limit (the
68
+ sum of all pool sizes cannot exceed your limit).
69
+ """
70
+
71
71
  start_url: str
72
72
  """Optional URL to navigate to when a new browser is warmed into the pool.
73
73
 
@@ -162,6 +162,9 @@ class TestAPIKeys:
162
162
  api_key = client.api_keys.list(
163
163
  limit=100,
164
164
  offset=0,
165
+ query="query",
166
+ sort_by="created_at",
167
+ sort_direction="asc",
165
168
  )
166
169
  assert_matches_type(SyncOffsetPagination[APIKey], api_key, path=["response"])
167
170
 
@@ -379,6 +382,9 @@ class TestAsyncAPIKeys:
379
382
  api_key = await async_client.api_keys.list(
380
383
  limit=100,
381
384
  offset=0,
385
+ query="query",
386
+ sort_by="created_at",
387
+ sort_direction="asc",
382
388
  )
383
389
  assert_matches_type(AsyncOffsetPagination[APIKey], api_key, path=["response"])
384
390
 
@@ -135,7 +135,6 @@ class TestBrowserPools:
135
135
  def test_method_update(self, client: Kernel) -> None:
136
136
  browser_pool = client.browser_pools.update(
137
137
  id_or_name="id_or_name",
138
- size=10,
139
138
  )
140
139
  assert_matches_type(BrowserPool, browser_pool, path=["response"])
141
140
 
@@ -144,7 +143,6 @@ class TestBrowserPools:
144
143
  def test_method_update_with_all_params(self, client: Kernel) -> None:
145
144
  browser_pool = client.browser_pools.update(
146
145
  id_or_name="id_or_name",
147
- size=10,
148
146
  chrome_policy={"foo": "bar"},
149
147
  discard_all_idle=False,
150
148
  extensions=[
@@ -163,6 +161,7 @@ class TestBrowserPools:
163
161
  "save_changes": True,
164
162
  },
165
163
  proxy_id="proxy_id",
164
+ size=10,
166
165
  start_url="https://example.com",
167
166
  stealth=True,
168
167
  timeout_seconds=60,
@@ -179,7 +178,6 @@ class TestBrowserPools:
179
178
  def test_raw_response_update(self, client: Kernel) -> None:
180
179
  response = client.browser_pools.with_raw_response.update(
181
180
  id_or_name="id_or_name",
182
- size=10,
183
181
  )
184
182
 
185
183
  assert response.is_closed is True
@@ -192,7 +190,6 @@ class TestBrowserPools:
192
190
  def test_streaming_response_update(self, client: Kernel) -> None:
193
191
  with client.browser_pools.with_streaming_response.update(
194
192
  id_or_name="id_or_name",
195
- size=10,
196
193
  ) as response:
197
194
  assert not response.is_closed
198
195
  assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -208,7 +205,6 @@ class TestBrowserPools:
208
205
  with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
209
206
  client.browser_pools.with_raw_response.update(
210
207
  id_or_name="",
211
- size=10,
212
208
  )
213
209
 
214
210
  @pytest.mark.skip(reason="Mock server tests are disabled")
@@ -559,7 +555,6 @@ class TestAsyncBrowserPools:
559
555
  async def test_method_update(self, async_client: AsyncKernel) -> None:
560
556
  browser_pool = await async_client.browser_pools.update(
561
557
  id_or_name="id_or_name",
562
- size=10,
563
558
  )
564
559
  assert_matches_type(BrowserPool, browser_pool, path=["response"])
565
560
 
@@ -568,7 +563,6 @@ class TestAsyncBrowserPools:
568
563
  async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> None:
569
564
  browser_pool = await async_client.browser_pools.update(
570
565
  id_or_name="id_or_name",
571
- size=10,
572
566
  chrome_policy={"foo": "bar"},
573
567
  discard_all_idle=False,
574
568
  extensions=[
@@ -587,6 +581,7 @@ class TestAsyncBrowserPools:
587
581
  "save_changes": True,
588
582
  },
589
583
  proxy_id="proxy_id",
584
+ size=10,
590
585
  start_url="https://example.com",
591
586
  stealth=True,
592
587
  timeout_seconds=60,
@@ -603,7 +598,6 @@ class TestAsyncBrowserPools:
603
598
  async def test_raw_response_update(self, async_client: AsyncKernel) -> None:
604
599
  response = await async_client.browser_pools.with_raw_response.update(
605
600
  id_or_name="id_or_name",
606
- size=10,
607
601
  )
608
602
 
609
603
  assert response.is_closed is True
@@ -616,7 +610,6 @@ class TestAsyncBrowserPools:
616
610
  async def test_streaming_response_update(self, async_client: AsyncKernel) -> None:
617
611
  async with async_client.browser_pools.with_streaming_response.update(
618
612
  id_or_name="id_or_name",
619
- size=10,
620
613
  ) as response:
621
614
  assert not response.is_closed
622
615
  assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -632,7 +625,6 @@ class TestAsyncBrowserPools:
632
625
  with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
633
626
  await async_client.browser_pools.with_raw_response.update(
634
627
  id_or_name="",
635
- size=10,
636
628
  )
637
629
 
638
630
  @pytest.mark.skip(reason="Mock server tests are disabled")
@@ -97,6 +97,28 @@ def test_browser_request_uses_curl_raw() -> None:
97
97
  assert request.url.params.get("jwt") == "token-abc"
98
98
 
99
99
 
100
+ @respx.mock
101
+ def test_telemetry_stream_routes_directly_to_vm(monkeypatch: pytest.MonkeyPatch) -> None:
102
+ monkeypatch.setenv("KERNEL_BROWSER_ROUTING_SUBRESOURCES", "telemetry")
103
+ route = respx.get("http://browser-session.test/browser/kernel/telemetry/stream").mock(
104
+ return_value=httpx.Response(
105
+ 200,
106
+ headers={"content-type": "text/event-stream"},
107
+ content=b'id: 1\ndata: {"category":"api"}\n\n',
108
+ )
109
+ )
110
+ with Kernel(base_url=base_url, api_key=api_key, _strict_response_validation=True) as client:
111
+ _cache_browser(client)
112
+ stream = client.browsers.telemetry.stream("sess-1")
113
+ stream.close()
114
+
115
+ assert route.called
116
+ request = cast(httpx.Request, cast(Any, route.calls[0]).request)
117
+ assert request.url.path == "/browser/kernel/telemetry/stream"
118
+ assert request.url.params.get("jwt") == "token-abc"
119
+ assert request.headers.get("Authorization") is None
120
+
121
+
100
122
  @respx.mock
101
123
  def test_browser_request_params_cannot_override_target_url_or_jwt() -> None:
102
124
  route = respx.get("http://browser-session.test/browser/kernel/curl/raw").mock(
@@ -315,7 +337,7 @@ def test_browser_route_from_browser_requires_base_url_and_jwt() -> None:
315
337
 
316
338
  def test_browser_routing_config_from_env_defaults_to_curl(monkeypatch: pytest.MonkeyPatch) -> None:
317
339
  monkeypatch.delenv("KERNEL_BROWSER_ROUTING_SUBRESOURCES", raising=False)
318
- assert browser_routing_config_from_env().subresources == ("curl",)
340
+ assert browser_routing_config_from_env().subresources == ("curl", "telemetry")
319
341
 
320
342
 
321
343
  def test_browser_routing_config_from_env_empty_string_disables_routing(monkeypatch: pytest.MonkeyPatch) -> None:
@@ -26,6 +26,32 @@ async def test_basic(sync: bool, client: Kernel, async_client: AsyncKernel) -> N
26
26
  await assert_empty_iter(iterator)
27
27
 
28
28
 
29
+ @pytest.mark.asyncio
30
+ @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
31
+ async def test_keepalive_comment_after_event_with_id(sync: bool, client: Kernel, async_client: AsyncKernel) -> None:
32
+ # A ``:`` comment frame (the server's SSE keepalive) that arrives after an event which set an
33
+ # id must be ignored, not dispatched as an empty event. last_event_id is sticky, so this is a
34
+ # regression guard against it leaking an undecodable empty frame into the typed stream.
35
+ def body() -> Iterator[bytes]:
36
+ yield b"id: 1\n"
37
+ yield b'data: {"foo":true}\n'
38
+ yield b"\n"
39
+ yield b":\n"
40
+ yield b"\n"
41
+ yield b'data: {"bar":false}\n'
42
+ yield b"\n"
43
+
44
+ iterator = make_event_iterator(content=body(), sync=sync, client=client, async_client=async_client)
45
+
46
+ sse = await iter_next(iterator)
47
+ assert sse.json() == {"foo": True}
48
+
49
+ sse = await iter_next(iterator)
50
+ assert sse.json() == {"bar": False}
51
+
52
+ await assert_empty_iter(iterator)
53
+
54
+
29
55
  @pytest.mark.asyncio
30
56
  @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
31
57
  async def test_data_missing_event(sync: bool, client: Kernel, async_client: AsyncKernel) -> None:
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.59.0"
3
- }
@@ -1,15 +0,0 @@
1
- # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- from __future__ import annotations
4
-
5
- from typing_extensions import TypedDict
6
-
7
- __all__ = ["APIKeyListParams"]
8
-
9
-
10
- class APIKeyListParams(TypedDict, total=False):
11
- limit: int
12
- """Maximum number of results to return"""
13
-
14
- offset: int
15
- """Number of results to skip"""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes