runtype 0.2.2 → 0.5.0

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 (181) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +169 -1
  3. data/README.md +188 -23
  4. data/generated/lib/runtype/agent_aliases/client.rb +202 -1
  5. data/generated/lib/runtype/agent_aliases/types/delete_v1agents_id_aliases_alias_bindings_request.rb +17 -0
  6. data/generated/lib/runtype/agent_aliases/types/delete_v1agents_id_aliases_alias_bindings_response.rb +19 -0
  7. data/generated/lib/runtype/agent_aliases/types/get_v1agent_aliases_request.rb +13 -0
  8. data/generated/lib/runtype/agent_aliases/types/get_v1agent_aliases_response.rb +11 -0
  9. data/generated/lib/runtype/agent_aliases/types/get_v1agent_aliases_response_data_item.rb +25 -0
  10. data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_alias_bindings_request.rb +13 -0
  11. data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_alias_bindings_response.rb +19 -0
  12. data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_alias_response.rb +2 -0
  13. data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_response_data_item.rb +2 -0
  14. data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_deployments_response_data_item.rb +2 -0
  15. data/generated/lib/runtype/agent_aliases/types/post_v1agents_id_aliases_alias_rollback_response.rb +6 -0
  16. data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_bindings_request.rb +21 -0
  17. data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_bindings_response.rb +19 -0
  18. data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_request.rb +2 -0
  19. data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_response.rb +6 -0
  20. data/generated/lib/runtype/agent_versions/client.rb +13 -1
  21. data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_request.rb +6 -0
  22. data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_request_deployment.rb +11 -0
  23. data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_request_deployment_action.rb +14 -0
  24. data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_response.rb +1 -1
  25. data/generated/lib/runtype/agents/types/post_v1agents_ensure_request_definition_config_memory.rb +2 -0
  26. data/generated/lib/runtype/agents/types/post_v1agents_ensure_request_definition_config_memory_pointer_scope.rb +15 -0
  27. data/generated/lib/runtype/agents/types/post_v1agents_id_execute_request_x_runtype_concurrency.rb +1 -0
  28. data/generated/lib/runtype/agents/types/post_v1agents_request_config_memory.rb +2 -0
  29. data/generated/lib/runtype/agents/types/post_v1agents_request_config_memory_pointer_scope.rb +15 -0
  30. data/generated/lib/runtype/agents/types/put_v1agents_id_request_config_memory.rb +2 -0
  31. data/generated/lib/runtype/agents/types/put_v1agents_id_request_config_memory_pointer_scope.rb +15 -0
  32. data/generated/lib/runtype/batch/types/get_v1batch_batch_id_records_record_id_steps_response_data_item_execution_engine.rb +1 -0
  33. data/generated/lib/runtype/client.rb +5 -5
  34. data/generated/lib/runtype/client_runtime/client.rb +118 -1
  35. data/generated/lib/runtype/client_runtime/types/get_v1client_conversations_conversation_id_executions_execution_id_deliveries_delivery_id_request.rb +21 -0
  36. data/generated/lib/runtype/client_runtime/types/post_v1client_chat_request_submit_mode.rb +1 -0
  37. data/generated/lib/runtype/client_runtime/types/post_v1client_conversations_conversation_id_executions_execution_id_cancel_request.rb +19 -0
  38. data/generated/lib/runtype/client_runtime/types/post_v1client_conversations_conversation_id_executions_execution_id_cancel_response.rb +13 -0
  39. data/generated/lib/runtype/client_runtime/types/post_v1client_init_response_durable_recovery.rb +2 -0
  40. data/generated/lib/runtype/client_tokens/types/get_v1client_tokens_id_response_client_token.rb +4 -0
  41. data/generated/lib/runtype/client_tokens/types/get_v1client_tokens_response_client_tokens_item.rb +4 -0
  42. data/generated/lib/runtype/client_tokens/types/post_v1client_tokens_id_regenerate_response_client_token.rb +4 -0
  43. data/generated/lib/runtype/client_tokens/types/post_v1client_tokens_request.rb +4 -0
  44. data/generated/lib/runtype/client_tokens/types/post_v1client_tokens_response_client_token.rb +4 -0
  45. data/generated/lib/runtype/client_tokens/types/put_v1client_tokens_id_request.rb +4 -0
  46. data/generated/lib/runtype/client_tokens/types/put_v1client_tokens_id_response_client_token.rb +4 -0
  47. data/generated/lib/runtype/conversations/client.rb +28 -10
  48. data/generated/lib/runtype/conversations/types/get_v1conversations_id_response.rb +3 -1
  49. data/generated/lib/runtype/conversations/types/post_v1conversations_request.rb +6 -0
  50. data/generated/lib/runtype/conversations/types/post_v1conversations_response.rb +3 -1
  51. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request.rb +7 -1
  52. data/generated/lib/runtype/conversations/types/{put_v1conversations_id_request_messages_item_content_one_item_asset_ref_ref_kind.rb → put_v1conversations_id_request_messages_mode.rb} +3 -3
  53. data/generated/lib/runtype/conversations/types/put_v1conversations_id_response.rb +3 -1
  54. data/generated/lib/runtype/dispatch/client.rb +5 -3
  55. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one.rb +2 -0
  56. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_agent_memory.rb +2 -0
  57. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_agent_memory_pointer_scope.rb +15 -0
  58. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_history.rb +14 -0
  59. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item.rb +4 -0
  60. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item_role.rb +1 -0
  61. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item_tool_calls_item.rb +17 -0
  62. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item_tool_results_item.rb +17 -0
  63. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero.rb +2 -0
  64. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_agent_memory.rb +2 -0
  65. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_agent_memory_pointer_scope.rb +15 -0
  66. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_history.rb +14 -0
  67. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item.rb +4 -0
  68. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item_role.rb +1 -0
  69. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item_tool_calls_item.rb +17 -0
  70. data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item_tool_results_item.rb +17 -0
  71. data/generated/lib/runtype/evals/types/get_v1eval_id_results_response.rb +10 -0
  72. data/generated/lib/runtype/evals/types/get_v1eval_id_results_response_agent_target_resolution.rb +15 -0
  73. data/generated/lib/runtype/evals/types/get_v1eval_id_results_response_results_by_record_value_item_execution_engine.rb +1 -0
  74. data/generated/lib/runtype/evals/types/post_v1eval_run_request.rb +2 -0
  75. data/generated/lib/runtype/evals/types/post_v1eval_run_request_agent.rb +15 -0
  76. data/generated/lib/runtype/evals/types/post_v1eval_submit_request.rb +2 -0
  77. data/generated/lib/runtype/evals/types/post_v1eval_submit_request_agent.rb +15 -0
  78. data/generated/lib/runtype/evals/types/post_v1eval_suites_id_run_request.rb +2 -0
  79. data/generated/lib/runtype/executions/client.rb +43 -0
  80. data/generated/lib/runtype/executions/types/get_v1executions_execution_id_deliveries_delivery_id_request.rb +13 -0
  81. data/generated/lib/runtype/flows/client.rb +3 -4
  82. data/generated/lib/runtype/flows/types/get_v1flows_id_step_results_response_data_item_execution_engine.rb +1 -0
  83. data/generated/lib/runtype/messaging_conversations/client.rb +2 -0
  84. data/generated/lib/runtype/messaging_conversations/types/get_v1messaging_conversations_request.rb +2 -0
  85. data/generated/lib/runtype/model_configs/types/post_v1model_configs_request_settings_custom_model.rb +2 -0
  86. data/generated/lib/runtype/model_configs/types/post_v1model_configs_request_settings_custom_model_mid_conversation_system_messages.rb +14 -0
  87. data/generated/lib/runtype/model_configs/types/put_v1model_configs_id_request_settings_custom_model.rb +2 -0
  88. data/generated/lib/runtype/model_configs/types/put_v1model_configs_id_request_settings_custom_model_mid_conversation_system_messages.rb +14 -0
  89. data/generated/lib/runtype/products/client.rb +45 -0
  90. data/generated/lib/runtype/products/types/get_v1products_id_activity_request.rb +13 -0
  91. data/generated/lib/runtype/products/types/get_v1products_id_activity_response.rb +13 -0
  92. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data.rb +13 -0
  93. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item.rb +17 -0
  94. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item.rb +77 -0
  95. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_agent_target_resolution.rb +15 -0
  96. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_agent_version.rb +17 -0
  97. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_execution_mode.rb +14 -0
  98. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_notification_mode.rb +15 -0
  99. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_pending_approval.rb +27 -0
  100. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_status.rb +19 -0
  101. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_error.rb +11 -0
  102. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item.rb +19 -0
  103. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item.rb +15 -0
  104. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item_agent_mode.rb +45 -0
  105. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item_available_fields.rb +39 -0
  106. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item_available_fields_metadata_schema.rb +11 -0
  107. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_error.rb +11 -0
  108. data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_source.rb +14 -0
  109. data/generated/lib/runtype/provider_keys/types/post_v1provider_keys_id_sync_models_request_models_item.rb +2 -0
  110. data/generated/lib/runtype/provider_keys/types/post_v1provider_keys_id_sync_models_request_models_item_mid_conversation_system_messages.rb +14 -0
  111. data/generated/lib/runtype/records/types/get_v1records_id_results_response_data_item_execution_engine.rb +1 -0
  112. data/generated/lib/runtype/records/types/get_v1records_id_step_results_response_data_item_execution_engine.rb +1 -0
  113. data/generated/lib/runtype/schedules/types/get_v1schedules_batch_batch_id_results_response_data_item_execution_engine.rb +1 -0
  114. data/generated/lib/runtype/schedules/types/get_v1schedules_runs_run_id_results_response_data_item_execution_engine.rb +1 -0
  115. data/generated/lib/runtype/types/agent_deployment_promotion.rb +17 -0
  116. data/generated/lib/runtype/types/agent_ensure_deploy_target.rb +2 -0
  117. data/generated/lib/runtype/types/agent_ensure_preview_alias_limit.rb +19 -0
  118. data/generated/lib/runtype/types/agent_ensure_preview_alias_limit_code.rb +11 -0
  119. data/generated/lib/runtype/types/agent_ensure_preview_alias_limit_scope.rb +12 -0
  120. data/generated/lib/runtype/types/agent_pull_response_definition_config_memory.rb +2 -0
  121. data/generated/lib/runtype/types/agent_pull_response_definition_config_memory_pointer_scope.rb +13 -0
  122. data/generated/lib/runtype/types/async_dispatch_handle.rb +10 -0
  123. data/generated/lib/runtype/types/async_dispatch_handle_delivery_status.rb +14 -0
  124. data/generated/lib/runtype/types/async_dispatch_handle_status.rb +5 -0
  125. data/generated/lib/runtype/types/client_input_delivery_receipt.rb +19 -0
  126. data/generated/lib/runtype/types/client_input_delivery_receipt_status.rb +14 -0
  127. data/generated/lib/runtype/types/conflict_error_body_candidate_count.rb +21 -0
  128. data/generated/lib/runtype/types/conflict_error_body_candidate_count_code.rb +11 -0
  129. data/generated/lib/runtype/types/conversation_busy_error.rb +15 -0
  130. data/generated/lib/runtype/types/conversation_busy_error_code.rb +11 -0
  131. data/generated/lib/runtype/types/conversation_busy_error_phase.rb +14 -0
  132. data/generated/lib/runtype/types/conversation_message_author.rb +16 -0
  133. data/generated/lib/runtype/types/conversation_message_author_type.rb +14 -0
  134. data/generated/lib/runtype/types/conversation_modified_error.rb +13 -0
  135. data/generated/lib/runtype/types/conversation_modified_error_code.rb +11 -0
  136. data/generated/lib/runtype/types/conversation_source.rb +14 -0
  137. data/generated/lib/runtype/types/conversation_transcript_message.rb +23 -0
  138. data/generated/lib/runtype/types/conversation_transcript_message_content.rb +14 -0
  139. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item.rb +21 -0
  140. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_asset_ref.rb +19 -0
  141. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_asset_ref_ref_kind.rb +12 -0
  142. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_file.rb +13 -0
  143. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_image.rb +11 -0
  144. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_reasoning.rb +11 -0
  145. data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_text.rb +9 -0
  146. data/generated/lib/runtype/types/conversation_transcript_message_role.rb +14 -0
  147. data/generated/lib/runtype/types/conversation_transcript_message_tool_calls_item.rb +15 -0
  148. data/generated/lib/runtype/types/conversation_transcript_message_tool_results_item.rb +15 -0
  149. data/generated/lib/runtype/types/dispatch_agent_json_response.rb +12 -0
  150. data/generated/lib/runtype/types/dispatch_agent_json_response_delivery_status.rb +14 -0
  151. data/generated/lib/runtype/types/dispatch_agent_json_response_execution_mode.rb +1 -0
  152. data/generated/lib/runtype/types/eval_agent_selector.rb +13 -0
  153. data/generated/lib/runtype/types/eval_run_scores_response.rb +10 -0
  154. data/generated/lib/runtype/types/eval_run_scores_response_agent_target_resolution.rb +13 -0
  155. data/generated/lib/runtype/types/eval_run_scores_response_cases_item_execution_engine.rb +1 -0
  156. data/generated/lib/runtype/types/eval_suite_run_queued.rb +10 -0
  157. data/generated/lib/runtype/types/eval_suite_run_queued_agent_target_resolution.rb +13 -0
  158. data/generated/lib/runtype/types/input_delivery_receipt.rb +19 -0
  159. data/generated/lib/runtype/types/input_delivery_receipt_status.rb +14 -0
  160. data/generated/lib/runtype/types/preview_alias_limit_error.rb +21 -0
  161. data/generated/lib/runtype/types/preview_alias_limit_error_code.rb +11 -0
  162. data/generated/lib/runtype/types/preview_alias_limit_error_scope.rb +12 -0
  163. data/generated/lib/runtype/types/run_eval_response.rb +10 -0
  164. data/generated/lib/runtype/types/run_eval_response_agent_target_resolution.rb +13 -0
  165. data/generated/lib/runtype.rb +109 -26
  166. data/lib/runtype/agent_ensure.rb +68 -4
  167. data/lib/runtype/agent_release_aliases.rb +282 -0
  168. data/lib/runtype/client.rb +22 -1
  169. data/lib/runtype/errors.rb +14 -2
  170. data/lib/runtype/raw_client_timeout.rb +56 -0
  171. data/lib/runtype/sdk_version.rb +2 -1
  172. data/lib/runtype.rb +2 -0
  173. metadata +95 -10
  174. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item.rb +0 -17
  175. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content.rb +0 -15
  176. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item.rb +0 -21
  177. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_asset_ref.rb +0 -21
  178. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_file.rb +0 -15
  179. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_image.rb +0 -13
  180. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_text.rb +0 -11
  181. data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_role.rb +0 -15
@@ -0,0 +1,282 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "socket"
5
+ require "timeout"
6
+
7
+ module Runtype
8
+ # Release aliases and deployment receipts on {Runtype::Client}. An agent runs
9
+ # an immutable version; a named mutable alias (`live`, `pr-482`) selects which
10
+ # one, and every activation appends a deployment receipt. Protocol:
11
+ # `docs/adr/0025-agent-release-aliases.md`.
12
+ module AgentReleaseAliases
13
+ # The fields a `promotion:` hash may carry, mirroring the API's strict
14
+ # `AgentDeploymentPromotion` schema (apps/api/src/routes/agents/alias-routes.ts)
15
+ # and the generated {Runtype::Types::AgentDeploymentPromotion} model.
16
+ PROMOTION_FIELDS = %i[source_agent_id source_version_id source_content_hash source_commit].freeze
17
+
18
+ # The failures one {#archive_agent_alias_everywhere} row may absorb: the
19
+ # curated API tree, plus the transport exceptions Net::HTTP raises below
20
+ # {Runtype.wrap_errors} (the same set {Runtype::Streaming::Connection}
21
+ # translates). Everything else is an SDK defect rather than a per-agent
22
+ # outcome and aborts the sweep loudly instead of becoming a failure row.
23
+ SWEEP_ISOLATED_ERRORS = [
24
+ Runtype::Error, Timeout::Error, OpenSSL::SSL::SSLError, SocketError, SystemCallError, IOError
25
+ ].freeze
26
+
27
+ # The named pointers of one agent: `live` first, then the preview aliases by
28
+ # name. Archived aliases are omitted unless asked for. Omitting `limit:`
29
+ # returns every pointer; supplying it pages through the same order.
30
+ #
31
+ # @param agent_id [String]
32
+ # @param include_archived [Boolean]
33
+ # @param limit [Integer, String, nil]
34
+ # @param cursor [String, nil] from a previous page's `nextCursor`.
35
+ # @param request_options [Hash] see {Runtype::Client#dispatch}.
36
+ # @return [Runtype::AgentAliases::Types::GetV1AgentsIDAliasesResponse]
37
+ def list_agent_aliases(agent_id, include_archived: false, limit: nil, cursor: nil, request_options: {})
38
+ params = { id: agent_id, limit: limit, cursor: cursor }.compact
39
+ params[:include_archived] = "true" if include_archived
40
+ Runtype.wrap_errors do
41
+ release_alias_client.list_release_aliases_for_an_agent(request_options: request_options, **params)
42
+ end
43
+ end
44
+
45
+ # One pointer. A missing or archived alias answers a structured 404 naming
46
+ # the alias; it never falls back to `live`.
47
+ #
48
+ # @param agent_id [String]
49
+ # @param alias_name [String] e.g. `"live"` or `"pr-482"`.
50
+ # @param include_archived [Boolean]
51
+ # @param request_options [Hash]
52
+ # @return [Runtype::AgentAliases::Types::GetV1AgentsIDAliasesAliasResponse]
53
+ # @raise [Runtype::NotFoundError] when no such alias is in scope.
54
+ def get_agent_alias(agent_id, alias_name, include_archived: false, request_options: {})
55
+ params = { id: agent_id, alias_: alias_name }
56
+ params[:include_archived] = "true" if include_archived
57
+ Runtype.wrap_errors do
58
+ release_alias_client.get_one_release_alias(request_options: request_options, **params)
59
+ end
60
+ end
61
+
62
+ # Aims one alias at one immutable version of the same agent, appending a
63
+ # deployment receipt in the same transaction. `version_id` is sent exactly as
64
+ # given: an alias is never resolved to a version client-side.
65
+ #
66
+ # @param agent_id [String]
67
+ # @param alias_name [String]
68
+ # @param version_id [String] the exact version to activate.
69
+ # @param revision [String, nil] the alias revision this activation expects,
70
+ # sent as `If-Match`; required when moving an existing `live` pointer.
71
+ # @param idempotency_key [String, nil] replays the same activation safely.
72
+ # @param reason [String, nil] recorded on the receipt.
73
+ # @param promotion [Hash, Runtype::Types::AgentDeploymentPromotion, nil] the
74
+ # source-organization ids and hashes a cross-organization promotion came
75
+ # from, e.g. `{ source_version_id: "agv_9", source_commit: sha }`, linked
76
+ # on the receipt. Provenance only: it authorizes nothing, and the
77
+ # activating credentials alone decide what the activation may do.
78
+ # @param request_options [Hash]
79
+ # @return [Runtype::AgentAliases::Types::PutV1AgentsIDAliasesAliasResponse]
80
+ # @raise [ArgumentError] when `promotion:` carries an unrecognized key.
81
+ def activate_agent_alias(agent_id, alias_name, version_id:, revision: nil, idempotency_key: nil, reason: nil,
82
+ promotion: nil, request_options: {})
83
+ params = {
84
+ id: agent_id, alias_: alias_name, version_id: version_id,
85
+ if_match: revision, idempotency_key: idempotency_key, reason: reason,
86
+ promotion: promotion_provenance(promotion)
87
+ }.compact
88
+ Runtype.wrap_errors do
89
+ release_alias_client.activate_a_version_at_a_release_alias(request_options: request_options, **params)
90
+ end
91
+ end
92
+
93
+ # Archives a preview alias: it stops resolving for new executions, keeps its
94
+ # deployment history, and does not interrupt admitted runs. The row is never
95
+ # deleted, so a later activation revives the same pointer. `live` cannot be
96
+ # archived.
97
+ #
98
+ # @param agent_id [String]
99
+ # @param alias_name [String]
100
+ # @param revision [String, nil] sent as `If-Match`.
101
+ # @param idempotency_key [String, nil]
102
+ # @param request_options [Hash]
103
+ # @return [Runtype::AgentAliases::Types::DeleteV1AgentsIDAliasesAliasResponse]
104
+ def archive_agent_alias(agent_id, alias_name, revision: nil, idempotency_key: nil, request_options: {})
105
+ params = {
106
+ id: agent_id, alias_: alias_name, if_match: revision, idempotency_key: idempotency_key
107
+ }.compact
108
+ Runtype.wrap_errors do
109
+ release_alias_client.archive_a_release_alias(request_options: request_options, **params)
110
+ end
111
+ end
112
+
113
+ # Re-aims an alias at the version recorded as `previousVersionId` on its most
114
+ # recent pointer-moving receipt, walking `steps:` receipts back, and writes a
115
+ # `rollback` receipt. Restores configuration only: external data and side
116
+ # effects are not rolled back.
117
+ #
118
+ # @param agent_id [String]
119
+ # @param alias_name [String]
120
+ # @param steps [Integer, nil] how many receipts to walk back; default 1.
121
+ # @param revision [String, nil] sent as `If-Match`.
122
+ # @param idempotency_key [String, nil]
123
+ # @param request_options [Hash]
124
+ # @return [Runtype::AgentAliases::Types::PostV1AgentsIDAliasesAliasRollbackResponse]
125
+ def rollback_agent_alias(agent_id, alias_name, steps: nil, revision: nil, idempotency_key: nil,
126
+ request_options: {})
127
+ params = {
128
+ id: agent_id, alias_: alias_name, steps: steps, if_match: revision, idempotency_key: idempotency_key
129
+ }.compact
130
+ Runtype.wrap_errors do
131
+ release_alias_client.roll_a_release_alias_back_to_its_previous_version(
132
+ request_options: request_options, **params
133
+ )
134
+ end
135
+ end
136
+
137
+ # The append-only deployment history of one agent, newest first,
138
+ # cursor-paginated. Each receipt records the pointer, the previous and new
139
+ # versions, the alias revision, the actor, provenance and the dependency
140
+ # fingerprints checked at activation.
141
+ #
142
+ # @param agent_id [String]
143
+ # @param alias_name [String, nil] narrows the history to one pointer.
144
+ # @param limit [Integer, String, nil]
145
+ # @param cursor [String, nil]
146
+ # @param request_options [Hash]
147
+ # @return [Runtype::AgentAliases::Types::GetV1AgentsIDDeploymentsResponse]
148
+ def list_agent_deployments(agent_id, alias_name: nil, limit: nil, cursor: nil, request_options: {})
149
+ params = { id: agent_id, alias_: alias_name, limit: limit, cursor: cursor }.compact
150
+ Runtype.wrap_errors do
151
+ release_alias_client.list_deployment_receipts_for_an_agent(request_options: request_options, **params)
152
+ end
153
+ end
154
+
155
+ # Every agent in the caller's organization carrying a pointer with this
156
+ # name, each with the revision to quote back as `If-Match`. This is the read
157
+ # a "pull request closed" cleanup makes before archiving each pointer; the
158
+ # per-agent list would need every agent id first. Unpaginated, and `live` is
159
+ # readable here like any other name.
160
+ #
161
+ # @param alias_name [String] e.g. `"pr-482"`.
162
+ # @param include_archived [Boolean]
163
+ # @param request_options [Hash]
164
+ # @return [Runtype::AgentAliases::Types::GetV1AgentAliasesResponse]
165
+ def list_agent_aliases_by_name(alias_name, include_archived: false, request_options: {})
166
+ params = { alias_: alias_name }
167
+ params[:include_archived] = "true" if include_archived
168
+ Runtype.wrap_errors do
169
+ release_alias_client.list_release_aliases_with_one_name_across_the_organization(
170
+ request_options: request_options, **params
171
+ )
172
+ end
173
+ end
174
+
175
+ # Archives this pointer on every agent in the organization that carries it,
176
+ # each under the revision just read, so a concurrent deploy answers 412
177
+ # instead of racing. An API refusal or transport failure on one agent is
178
+ # reported in `"failed"` and the sweep continues; any other exception is an
179
+ # SDK defect and propagates, so a broken response contract never reads as a
180
+ # completed sweep. Only active pointers are listed, so a second run archives
181
+ # nothing.
182
+ #
183
+ # @param alias_name [String]
184
+ # @param dry_run [Boolean] report what would be archived and archive nothing.
185
+ # @param request_options [Hash]
186
+ # @return [Hash] `{"alias", "archived" => [{"agentId", "agentName",
187
+ # "revision", "receiptId"}], "failed" => [{"agentId", "agentName",
188
+ # "error", "code"?}]}`, or for a dry run `{"alias", "dryRun" => true,
189
+ # "wouldArchive" => [<row>]}` carrying the listed rows unchanged.
190
+ def archive_agent_alias_everywhere(alias_name, dry_run: false, request_options: {})
191
+ rows = list_agent_aliases_by_name(alias_name, request_options: request_options).data
192
+ return { "alias" => alias_name, "dryRun" => true, "wouldArchive" => rows } if dry_run
193
+
194
+ rows.each_with_object({ "alias" => alias_name, "archived" => [], "failed" => [] }) do |row, sweep|
195
+ sweep["archived"] << archive_one_everywhere(row, alias_name, request_options)
196
+ # Wider than Runtype::Error: a DNS, TLS or connection-reset failure is
197
+ # raised by Net::HTTP and never reaches Runtype.wrap_errors, so rescuing
198
+ # the curated tree alone would abort the sweep on one bad row and leave the
199
+ # remaining pointers active — the opposite of what this method promises.
200
+ rescue *SWEEP_ISOLATED_ERRORS => e
201
+ sweep["failed"] << {
202
+ "agentId" => row.agent_id, "agentName" => row.agent_name,
203
+ "error" => e.message, "code" => alias_failure_code(e)
204
+ }.compact
205
+ end
206
+ end
207
+
208
+ private
209
+
210
+ # @return [Runtype::AgentAliases::Client] the generated sub-client these
211
+ # wrappers delegate to, with the curated error surface layered on top.
212
+ def release_alias_client
213
+ api.agent_aliases
214
+ end
215
+
216
+ # One row of an {#archive_agent_alias_everywhere} sweep. The revision and
217
+ # receipt reported are the archive response's, not the listed row's.
218
+ #
219
+ # @param row [Runtype::AgentAliases::Types::GetV1AgentAliasesResponseDataItem]
220
+ # @param alias_name [String]
221
+ # @param request_options [Hash]
222
+ # @return [Hash]
223
+ def archive_one_everywhere(row, alias_name, request_options)
224
+ archived = archive_agent_alias(
225
+ row.agent_id, alias_name, revision: row.revision.to_s, request_options: request_options
226
+ )
227
+ {
228
+ "agentId" => row.agent_id, "agentName" => row.agent_name,
229
+ "revision" => archived.revision, "receiptId" => archived.receipt_id
230
+ }
231
+ end
232
+
233
+ # The alias plane's refusal code for a failed sweep row, matching the
234
+ # TypeScript helper's `code` field. 428 carries no code of its own, so the
235
+ # one the typed error uses is supplied here.
236
+ #
237
+ # @param error [Runtype::Error]
238
+ # @return [String, nil]
239
+ def alias_failure_code(error)
240
+ body = error.respond_to?(:body) ? error.body : nil
241
+ code = body["code"] if body.is_a?(Hash)
242
+ return code.to_s if code
243
+
244
+ "alias_revision_required" if error.respond_to?(:status_code) && error.status_code == 428
245
+ end
246
+
247
+ # Normalizes `promotion:` into the wire shape. A generated
248
+ # {Runtype::Types::AgentDeploymentPromotion} passes through; a Hash may spell
249
+ # its keys either way, and an unknown key raises here rather than reaching
250
+ # the server's strict 400 — or, worse, being absorbed as an extra field on
251
+ # the generated request model. An all-nil hash is treated as omitted, the
252
+ # same reading the API gives an empty promotion object.
253
+ #
254
+ # @param promotion [Hash, Runtype::Types::AgentDeploymentPromotion, nil]
255
+ # @return [Hash, Runtype::Types::AgentDeploymentPromotion, nil]
256
+ # @raise [ArgumentError] on a non-Hash or an unrecognized key.
257
+ def promotion_provenance(promotion)
258
+ return nil if promotion.nil?
259
+ return promotion if promotion.is_a?(Runtype::Types::AgentDeploymentPromotion)
260
+
261
+ unless promotion.is_a?(Hash)
262
+ raise ArgumentError,
263
+ "promotion: needs a Hash of source ids, e.g. promotion: { source_version_id: \"agv_9\" }."
264
+ end
265
+
266
+ provenance = promotion.each_with_object({}) do |(key, value), acc|
267
+ field = promotion_field(key)
268
+ raise ArgumentError, "promotion: accepts #{PROMOTION_FIELDS.join(", ")}, not #{key.inspect}." unless field
269
+
270
+ acc[field] = value.to_s unless value.nil?
271
+ end
272
+ provenance.empty? ? nil : provenance
273
+ end
274
+
275
+ # @param key [String, Symbol] either spelling of a promotion field.
276
+ # @return [Symbol, nil] the snake_case field name, or nil when unrecognized.
277
+ def promotion_field(key)
278
+ field = key.to_s.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym
279
+ PROMOTION_FIELDS.include?(field) ? field : nil
280
+ end
281
+ end
282
+ end
@@ -26,6 +26,7 @@ module Runtype
26
26
  # clients with different keys or base URLs can coexist in one process.
27
27
  class Client
28
28
  include Runtype::AgentEnsure
29
+ include Runtype::AgentReleaseAliases
29
30
  include Runtype::LocalToolRunner
30
31
 
31
32
  # Per-operation socket timeout, in seconds. Generous by default: an
@@ -52,7 +53,10 @@ module Runtype
52
53
 
53
54
  # @param api_key [String, nil] defaults to `RUNTYPE_API_KEY`.
54
55
  # @param base_url [String] defaults to `RUNTYPE_BASE_URL`, then production.
55
- # @param timeout [Numeric, nil] per-operation socket timeout in seconds.
56
+ # @param timeout [Numeric, nil] per-operation socket timeout in seconds,
57
+ # defaulting to {DEFAULT_TIMEOUT}. Governs the dispatch and streaming
58
+ # paths and every generated resource call alike; a single call overrides
59
+ # it with `request_options: { timeout_in_seconds: n }`.
56
60
  # @param max_retries [Integer] retries for generated resource calls. The
57
61
  # dispatch paths never retry: replaying an execution would run it twice.
58
62
  # @raise [Runtype::AuthenticationError] when no API key is available.
@@ -78,6 +82,8 @@ module Runtype
78
82
  authorization: bearer_token,
79
83
  max_retries: max_retries
80
84
  )
85
+ # WORKAROUND(fern ruby generator): BaseClient takes no timeout, so seed the transport it just built.
86
+ Runtype::RawClientTimeout.apply(generated_raw_client, timeout: @timeout)
81
87
  end
82
88
 
83
89
  # Executes a flow or agent and waits for the complete JSON response.
@@ -192,6 +198,21 @@ module Runtype
192
198
 
193
199
  private
194
200
 
201
+ # The transport {#api} shares with every resource sub-client it builds.
202
+ # Read once at construction, before any sub-client has memoized it.
203
+ #
204
+ # @return [Runtype::Internal::Http::RawClient]
205
+ # @raise [Runtype::Error] when the generated core no longer holds one, which
206
+ # means the timeout can no longer be applied to generated calls.
207
+ def generated_raw_client
208
+ raw = @api.instance_variable_get(:@raw_client)
209
+ return raw if raw.is_a?(Runtype::Internal::Http::RawClient)
210
+
211
+ raise Runtype::Error,
212
+ "Runtype::BaseClient no longer exposes @raw_client, so Runtype::Client cannot apply its timeout " \
213
+ "to generated calls. Rewire Runtype::RawClientTimeout against the generated core's new shape."
214
+ end
215
+
195
216
  # @return [String]
196
217
  def bearer_token
197
218
  "Bearer #{@api_key}"
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "timeout"
4
+
3
5
  module Runtype
4
6
  # Base class for every error the overlay raises. Rescue this to catch all of
5
7
  # them regardless of which generated resource produced the failure.
@@ -28,12 +30,20 @@ module Runtype
28
30
  # Translates a Fern-generated error into the curated equivalent. Errors that
29
31
  # are not generated API errors are returned unchanged.
30
32
  #
33
+ # A socket timeout is translated too: the generated methods rescue
34
+ # `Net::HTTPRequestTimeout`, a 408 response class no socket ever raises, so
35
+ # `Net::OpenTimeout`, `Net::ReadTimeout` and `Net::WriteTimeout` reach here
36
+ # untranslated. They all descend from `Timeout::Error`, so one clause covers
37
+ # connect, read and write, matching {Runtype::Streaming::Connection}.
38
+ #
31
39
  # @param error [Exception]
32
40
  # @return [Exception]
33
41
  def self.from_generated(error)
34
42
  case error
35
43
  when Runtype::Errors::TimeoutError
36
44
  APITimeoutError.new("Request timed out")
45
+ when ::Timeout::Error
46
+ APITimeoutError.new("Request timed out: #{error.message}")
37
47
  when Runtype::Errors::ResponseError
38
48
  from_response(status: error.code, body: error.message)
39
49
  when Runtype::Errors::ApiError
@@ -235,7 +245,9 @@ module Runtype
235
245
  class APIConnectionError < Error; end
236
246
 
237
247
  # Runs a block, re-raising Fern-generated errors as their curated equivalents
238
- # so callers keep one stable rescue surface across regenerations.
248
+ # so callers keep one stable rescue surface across regenerations. A socket
249
+ # timeout raised inside a generated call is curated here too, as
250
+ # {Runtype::APITimeoutError}.
239
251
  #
240
252
  # @example
241
253
  # Runtype.wrap_errors { client.flows.list_flows }
@@ -243,7 +255,7 @@ module Runtype
243
255
  # @return [Object] whatever the block returns.
244
256
  def self.wrap_errors
245
257
  yield
246
- rescue Runtype::Errors::ApiError => e
258
+ rescue Runtype::Errors::ApiError, ::Timeout::Error => e
247
259
  raise Runtype::Error.from_generated(e)
248
260
  end
249
261
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ # Timeout handling for the Fern-generated low-level transport.
5
+ #
6
+ # `Runtype::BaseClient` accepts no timeout and builds its
7
+ # `Runtype::Internal::Http::RawClient` with the generator's 60 second default,
8
+ # so every generated resource call ignored the timeout {Runtype::Client} was
9
+ # given. {Runtype::Client} seeds that transport through {apply}, which also
10
+ # gives it the per-call `request_options[:timeout_in_seconds]` override the
11
+ # generated methods document.
12
+ module RawClientTimeout
13
+ # Sends one request under the caller's `timeout_in_seconds` when it asked
14
+ # for one, and under the client-wide timeout otherwise. The override runs
15
+ # on a copy of the transport, so a client shared across threads is never
16
+ # mutated for the duration of one call.
17
+ #
18
+ # @param request [Runtype::Internal::Http::BaseRequest]
19
+ # @return [Net::HTTPResponse]
20
+ def send(request)
21
+ seconds = RawClientTimeout.timeout_in_seconds(request)
22
+ return super if seconds.nil? || seconds == @timeout
23
+
24
+ scoped = dup
25
+ scoped.instance_variable_set(:@timeout, seconds)
26
+ # INVARIANT: the copy's own timeout equals the override, so its send takes the branch above and cannot recur.
27
+ scoped.send(request)
28
+ end
29
+
30
+ # Reads the per-request timeout off a request's options under either key
31
+ # spelling, matching {Runtype::Client}'s streaming path.
32
+ #
33
+ # @param request [Runtype::Internal::Http::BaseRequest]
34
+ # @return [Float, nil] nil when no override was asked for, or when the
35
+ # value is not a number.
36
+ def self.timeout_in_seconds(request)
37
+ options = request.respond_to?(:request_options) ? request.request_options : nil
38
+ return nil unless options.respond_to?(:[])
39
+
40
+ value = options[:timeout_in_seconds] || options["timeout_in_seconds"]
41
+ value.nil? ? nil : Float(value, exception: false)
42
+ end
43
+
44
+ # Seeds a generated transport with the client-wide timeout and gives it
45
+ # per-request override handling.
46
+ #
47
+ # @param raw_client [Runtype::Internal::Http::RawClient]
48
+ # @param timeout [Numeric] the client-wide timeout, in seconds.
49
+ # @return [Runtype::Internal::Http::RawClient] the same object.
50
+ def self.apply(raw_client, timeout:)
51
+ raw_client.instance_variable_set(:@timeout, Float(timeout))
52
+ raw_client.extend(self)
53
+ raw_client
54
+ end
55
+ end
56
+ end
@@ -8,7 +8,8 @@ module Runtype
8
8
  # generator). The generated barrel does not require that file, so nothing
9
9
  # collides today, but re-declaring it here would make the overlay's version
10
10
  # depend on generator require order.
11
- SDK_VERSION = "0.2.2"
11
+ # Mirrored from ../../package.json by scripts/sync-sdk-versions.mjs; never hand-edit.
12
+ SDK_VERSION = "0.5.0"
12
13
 
13
14
  # Outbound User-Agent identifying the SDK kind, version, and language, e.g.
14
15
  # "runtype-sdk/0.1.0 (ruby)". The `runtype-sdk/` prefix is what the API's
data/lib/runtype.rb CHANGED
@@ -25,6 +25,7 @@ require_relative "../generated/lib/runtype"
25
25
 
26
26
  require_relative "runtype/sdk_version"
27
27
  require_relative "runtype/errors"
28
+ require_relative "runtype/raw_client_timeout"
28
29
  require_relative "runtype/streaming/event"
29
30
  require_relative "runtype/streaming/line_decoder"
30
31
  require_relative "runtype/streaming/event_parser"
@@ -33,6 +34,7 @@ require_relative "runtype/streaming/event_stream"
33
34
  require_relative "runtype/canonical_json"
34
35
  require_relative "runtype/agent_definition"
35
36
  require_relative "runtype/agent_ensure"
37
+ require_relative "runtype/agent_release_aliases"
36
38
  require_relative "runtype/local_tools"
37
39
  require_relative "runtype/detached_follow"
38
40
  require_relative "runtype/local_tool_runner"