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
@@ -8,6 +8,7 @@ module Runtype
8
8
 
9
9
  RUNTIME = "runtime"
10
10
  LEGACY = "legacy"
11
+ EXTERNAL = "external"
11
12
  end
12
13
  end
13
14
  end
@@ -21,6 +21,11 @@ module Runtype
21
21
  )
22
22
  end
23
23
 
24
+ # @return [Runtype::AgentAliases::Client]
25
+ def agent_aliases
26
+ @agent_aliases ||= Runtype::AgentAliases::Client.new(client: @raw_client)
27
+ end
28
+
24
29
  # @return [Runtype::AgentVersions::Client]
25
30
  def agent_versions
26
31
  @agent_versions ||= Runtype::AgentVersions::Client.new(client: @raw_client)
@@ -31,11 +36,6 @@ module Runtype
31
36
  @agents ||= Runtype::Agents::Client.new(client: @raw_client)
32
37
  end
33
38
 
34
- # @return [Runtype::AgentAliases::Client]
35
- def agent_aliases
36
- @agent_aliases ||= Runtype::AgentAliases::Client.new(client: @raw_client)
37
- end
38
-
39
39
  # @return [Runtype::Analytics::Client]
40
40
  def analytics
41
41
  @analytics ||= Runtype::Analytics::Client.new(client: @raw_client)
@@ -12,7 +12,10 @@ module Runtype
12
12
 
13
13
  # Send a message for a browser client-token chat session. The request streams flow/agent events over Server-Sent
14
14
  # Events. `turnId` and `submitMode` are optional and let newer Persona clients suppress stale interrupted
15
- # responses; older clients can omit both fields.
15
+ # responses; older clients can omit both fields. Opt-in `join` accepts exactly one new user message whose `id`
16
+ # equals `turnId` for visitor-owned native durable agents. A new execution streams SSE; joining an existing
17
+ # execution returns a 202 delivery receipt without replacing its response. Retry with the same turn and message
18
+ # IDs.
16
19
  #
17
20
  # @param request_options [Hash]
18
21
  # @param params [Runtype::ClientRuntime::Types::PostV1ClientChatRequest]
@@ -180,6 +183,120 @@ module Runtype
180
183
  end
181
184
  end
182
185
 
186
+ # Cancel the specified execution without starting a replacement. Pending inputs become not applied. Requires the
187
+ # exact visitor and session bound to the conversation.
188
+ #
189
+ # @param request_options [Hash]
190
+ # @param params [Hash]
191
+ # @option request_options [String] :base_url
192
+ # @option request_options [Hash{String => Object}] :additional_headers
193
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
194
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
195
+ # @option request_options [Integer] :timeout_in_seconds
196
+ # @option params [String] :conversation_id
197
+ # @option params [String] :execution_id
198
+ # @option params [String] :session_id
199
+ # @option params [String] :visitor_token
200
+ # @option params [String, nil] :identity_proof
201
+ #
202
+ # @example
203
+ # client.client_runtime.stop_a_native_durable_client_execution(
204
+ # conversation_id: "conversationId",
205
+ # execution_id: "executionId",
206
+ # session_id: "sessionId",
207
+ # visitor_token: "x-visitor-token"
208
+ # )
209
+ #
210
+ # @return [Runtype::ClientRuntime::Types::PostV1ClientConversationsConversationIDExecutionsExecutionIDCancelResponse]
211
+ def stop_a_native_durable_client_execution(request_options: {}, **params)
212
+ params = Runtype::Internal::Types::Utils.normalize_keys(params)
213
+ query_params = {}
214
+ query_params["sessionId"] = params[:session_id] if params.key?(:session_id)
215
+
216
+ headers = {}
217
+ headers["x-visitor-token"] = params[:visitor_token] if params[:visitor_token]
218
+ headers["x-identity-proof"] = params[:identity_proof] if params[:identity_proof]
219
+
220
+ request = Runtype::Internal::JSON::Request.new(
221
+ base_url: request_options[:base_url],
222
+ method: "POST",
223
+ path: "v1/client/conversations/#{URI.encode_uri_component(params[:conversation_id].to_s)}/executions/#{URI.encode_uri_component(params[:execution_id].to_s)}/cancel",
224
+ headers: headers,
225
+ query: query_params,
226
+ request_options: request_options
227
+ )
228
+ begin
229
+ response = @client.send(request)
230
+ rescue Net::HTTPRequestTimeout
231
+ raise Runtype::Errors::TimeoutError
232
+ end
233
+ code = response.code.to_i
234
+ if code.between?(200, 299)
235
+ Runtype::ClientRuntime::Types::PostV1ClientConversationsConversationIDExecutionsExecutionIDCancelResponse.load(response.body)
236
+ else
237
+ error_class = Runtype::Errors::ResponseError.subclass_for_code(code)
238
+ raise error_class.new(response.body, code: code)
239
+ end
240
+ end
241
+
242
+ # Read whether a joined message is pending, applied, settled, or not applied. Requires the exact visitor and
243
+ # session bound to this conversation.
244
+ #
245
+ # @param request_options [Hash]
246
+ # @param params [Hash]
247
+ # @option request_options [String] :base_url
248
+ # @option request_options [Hash{String => Object}] :additional_headers
249
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
250
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
251
+ # @option request_options [Integer] :timeout_in_seconds
252
+ # @option params [String] :conversation_id
253
+ # @option params [String] :execution_id
254
+ # @option params [String] :delivery_id
255
+ # @option params [String] :session_id
256
+ # @option params [String] :visitor_token
257
+ # @option params [String, nil] :identity_proof
258
+ #
259
+ # @example
260
+ # client.client_runtime.read_a_live_input_delivery_receipt(
261
+ # conversation_id: "conversationId",
262
+ # execution_id: "executionId",
263
+ # delivery_id: "deliveryId",
264
+ # session_id: "sessionId",
265
+ # visitor_token: "x-visitor-token"
266
+ # )
267
+ #
268
+ # @return [Runtype::Types::ClientInputDeliveryReceipt]
269
+ def read_a_live_input_delivery_receipt(request_options: {}, **params)
270
+ params = Runtype::Internal::Types::Utils.normalize_keys(params)
271
+ query_params = {}
272
+ query_params["sessionId"] = params[:session_id] if params.key?(:session_id)
273
+
274
+ headers = {}
275
+ headers["x-visitor-token"] = params[:visitor_token] if params[:visitor_token]
276
+ headers["x-identity-proof"] = params[:identity_proof] if params[:identity_proof]
277
+
278
+ request = Runtype::Internal::JSON::Request.new(
279
+ base_url: request_options[:base_url],
280
+ method: "GET",
281
+ path: "v1/client/conversations/#{URI.encode_uri_component(params[:conversation_id].to_s)}/executions/#{URI.encode_uri_component(params[:execution_id].to_s)}/deliveries/#{URI.encode_uri_component(params[:delivery_id].to_s)}",
282
+ headers: headers,
283
+ query: query_params,
284
+ request_options: request_options
285
+ )
286
+ begin
287
+ response = @client.send(request)
288
+ rescue Net::HTTPRequestTimeout
289
+ raise Runtype::Errors::TimeoutError
290
+ end
291
+ code = response.code.to_i
292
+ if code.between?(200, 299)
293
+ Runtype::Types::ClientInputDeliveryReceipt.load(response.body)
294
+ else
295
+ error_class = Runtype::Errors::ResponseError.subclass_for_code(code)
296
+ raise error_class.new(response.body, code: code)
297
+ end
298
+ end
299
+
183
300
  # Return a single conversation with its message transcript. Answers 404 (never 403) for a conversation the caller
184
301
  # does not own, so the route cannot be used to probe for other visitors' conversations. Every response carries
185
302
  # `X-History-Identity-Status` (`not_provided` | `admitted` | `ignored`) reporting what the server did with a
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module ClientRuntime
5
+ module Types
6
+ class GetV1ClientConversationsConversationIDExecutionsExecutionIDDeliveriesDeliveryIDRequest < Internal::Types::Model
7
+ field :conversation_id, -> { String }, optional: false, nullable: false, api_name: "conversationId"
8
+
9
+ field :execution_id, -> { String }, optional: false, nullable: false, api_name: "executionId"
10
+
11
+ field :delivery_id, -> { String }, optional: false, nullable: false, api_name: "deliveryId"
12
+
13
+ field :session_id, -> { String }, optional: false, nullable: false, api_name: "sessionId"
14
+
15
+ field :visitor_token, -> { String }, optional: false, nullable: false, api_name: "x-visitor-token"
16
+
17
+ field :identity_proof, -> { String }, optional: true, nullable: false, api_name: "x-identity-proof"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -8,6 +8,7 @@ module Runtype
8
8
 
9
9
  NORMAL = "normal"
10
10
  INTERRUPT = "interrupt"
11
+ JOIN = "join"
11
12
  end
12
13
  end
13
14
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module ClientRuntime
5
+ module Types
6
+ class PostV1ClientConversationsConversationIDExecutionsExecutionIDCancelRequest < Internal::Types::Model
7
+ field :conversation_id, -> { String }, optional: false, nullable: false, api_name: "conversationId"
8
+
9
+ field :execution_id, -> { String }, optional: false, nullable: false, api_name: "executionId"
10
+
11
+ field :session_id, -> { String }, optional: false, nullable: false, api_name: "sessionId"
12
+
13
+ field :visitor_token, -> { String }, optional: false, nullable: false, api_name: "x-visitor-token"
14
+
15
+ field :identity_proof, -> { String }, optional: true, nullable: false, api_name: "x-identity-proof"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module ClientRuntime
5
+ module Types
6
+ class PostV1ClientConversationsConversationIDExecutionsExecutionIDCancelResponse < Internal::Types::Model
7
+ field :accepted, -> { Internal::Types::Boolean }, optional: false, nullable: false
8
+
9
+ field :execution_id, -> { String }, optional: false, nullable: false, api_name: "executionId"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,6 +7,8 @@ module Runtype
7
7
  # streaming behavior.
8
8
  class PostV1ClientInitResponseDurableRecovery < Internal::Types::Model
9
9
  field :enabled, -> { Internal::Types::Boolean }, optional: false, nullable: false
10
+
11
+ field :join, -> { Internal::Types::Boolean }, optional: true, nullable: false
10
12
  end
11
13
  end
12
14
  end
@@ -40,6 +40,10 @@ module Runtype
40
40
 
41
41
  field :session_idle_timeout_minutes, -> { Integer }, optional: false, nullable: true, api_name: "sessionIdleTimeoutMinutes"
42
42
 
43
+ field :target_alias, -> { String }, optional: false, nullable: true, api_name: "targetAlias"
44
+
45
+ field :target_version_id, -> { String }, optional: false, nullable: true, api_name: "targetVersionId"
46
+
43
47
  field :token_hint, -> { String }, optional: false, nullable: true, api_name: "tokenHint"
44
48
 
45
49
  field :token_prefix, -> { String }, optional: false, nullable: false, api_name: "tokenPrefix"
@@ -40,6 +40,10 @@ module Runtype
40
40
 
41
41
  field :session_idle_timeout_minutes, -> { Integer }, optional: false, nullable: true, api_name: "sessionIdleTimeoutMinutes"
42
42
 
43
+ field :target_alias, -> { String }, optional: false, nullable: true, api_name: "targetAlias"
44
+
45
+ field :target_version_id, -> { String }, optional: false, nullable: true, api_name: "targetVersionId"
46
+
43
47
  field :token_hint, -> { String }, optional: false, nullable: true, api_name: "tokenHint"
44
48
 
45
49
  field :token_prefix, -> { String }, optional: false, nullable: false, api_name: "tokenPrefix"
@@ -24,6 +24,10 @@ module Runtype
24
24
 
25
25
  field :pin_to_version, -> { String }, optional: false, nullable: true, api_name: "pinToVersion"
26
26
 
27
+ field :target_alias, -> { String }, optional: false, nullable: true, api_name: "targetAlias"
28
+
29
+ field :target_version_id, -> { String }, optional: false, nullable: true, api_name: "targetVersionId"
30
+
27
31
  field :token_hint, -> { String }, optional: false, nullable: true, api_name: "tokenHint"
28
32
 
29
33
  field :token_prefix, -> { String }, optional: false, nullable: false, api_name: "tokenPrefix"
@@ -29,6 +29,10 @@ module Runtype
29
29
  field :rate_limit_per_minute, -> { Integer }, optional: true, nullable: false, api_name: "rateLimitPerMinute"
30
30
 
31
31
  field :session_idle_timeout_minutes, -> { Integer }, optional: true, nullable: false, api_name: "sessionIdleTimeoutMinutes"
32
+
33
+ field :target_alias, -> { String }, optional: true, nullable: false, api_name: "targetAlias"
34
+
35
+ field :target_version_id, -> { String }, optional: true, nullable: false, api_name: "targetVersionId"
32
36
  end
33
37
  end
34
38
  end
@@ -40,6 +40,10 @@ module Runtype
40
40
 
41
41
  field :session_idle_timeout_minutes, -> { Integer }, optional: false, nullable: true, api_name: "sessionIdleTimeoutMinutes"
42
42
 
43
+ field :target_alias, -> { String }, optional: false, nullable: true, api_name: "targetAlias"
44
+
45
+ field :target_version_id, -> { String }, optional: false, nullable: true, api_name: "targetVersionId"
46
+
43
47
  field :token_hint, -> { String }, optional: false, nullable: true, api_name: "tokenHint"
44
48
 
45
49
  field :token_prefix, -> { String }, optional: false, nullable: false, api_name: "tokenPrefix"
@@ -29,6 +29,10 @@ module Runtype
29
29
  field :rate_limit_per_minute, -> { Integer }, optional: true, nullable: false, api_name: "rateLimitPerMinute"
30
30
 
31
31
  field :session_idle_timeout_minutes, -> { Integer }, optional: true, nullable: false, api_name: "sessionIdleTimeoutMinutes"
32
+
33
+ field :target_alias, -> { String }, optional: true, nullable: false, api_name: "targetAlias"
34
+
35
+ field :target_version_id, -> { String }, optional: true, nullable: false, api_name: "targetVersionId"
32
36
  end
33
37
  end
34
38
  end
@@ -40,6 +40,10 @@ module Runtype
40
40
 
41
41
  field :session_idle_timeout_minutes, -> { Integer }, optional: false, nullable: true, api_name: "sessionIdleTimeoutMinutes"
42
42
 
43
+ field :target_alias, -> { String }, optional: false, nullable: true, api_name: "targetAlias"
44
+
45
+ field :target_version_id, -> { String }, optional: false, nullable: true, api_name: "targetVersionId"
46
+
43
47
  field :token_hint, -> { String }, optional: false, nullable: true, api_name: "tokenHint"
44
48
 
45
49
  field :token_prefix, -> { String }, optional: false, nullable: false, api_name: "tokenPrefix"
@@ -148,21 +148,39 @@ module Runtype
148
148
  # @example
149
149
  # client.conversations.update_a_conversation(
150
150
  # id: "id",
151
+ # agent_id: "agent_01j9r4x0h7f9k4b2n8t6q3m5cd",
151
152
  # messages: [{
152
- # content: "Help me write a function",
153
- # id: "msg_1",
153
+ # content: "Book me a table for two at 7pm.",
154
154
  # role: "user"
155
155
  # }, {
156
- # content: "Sure! What kind of function would you like?",
157
- # id: "msg_2",
156
+ # content: "",
157
+ # role: "assistant",
158
+ # tool_calls: [{
159
+ # args: {
160
+ # partySize: 2,
161
+ # time: "19:00"
162
+ # },
163
+ # tool_call_id: "call_9",
164
+ # tool_name: "create_reservation"
165
+ # }]
166
+ # }, {
167
+ # content: "",
168
+ # role: "tool",
169
+ # tool_results: [{
170
+ # result: {
171
+ # confirmed: true,
172
+ # reservationId: "res_44"
173
+ # },
174
+ # tool_call_id: "call_9",
175
+ # tool_name: "create_reservation"
176
+ # }]
177
+ # }, {
178
+ # content: "Booked. Your table for two is confirmed for 7pm.",
158
179
  # role: "assistant"
159
180
  # }],
160
- # metadata: {
161
- # topic: "programming"
162
- # },
163
- # model_id: "claude-sonnet-4-5",
164
- # system_prompt: "You are a coding assistant.",
165
- # title: "Updated Chat Title"
181
+ # source: {
182
+ # system: "custom"
183
+ # }
166
184
  # )
167
185
  #
168
186
  # @return [Runtype::Conversations::Types::PutV1ConversationsIDResponse]
@@ -8,7 +8,9 @@ module Runtype
8
8
 
9
9
  field :id, -> { String }, optional: false, nullable: false
10
10
 
11
- field :messages, -> { Internal::Types::Array[Internal::Types::Hash[String, Object]] }, optional: false, nullable: false
11
+ field :imported, -> { Internal::Types::Boolean }, optional: true, nullable: false
12
+
13
+ field :messages, -> { Internal::Types::Array[Runtype::Types::ConversationTranscriptMessage] }, optional: false, nullable: false
12
14
 
13
15
  field :metadata, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
14
16
 
@@ -4,12 +4,18 @@ module Runtype
4
4
  module Conversations
5
5
  module Types
6
6
  class PostV1ConversationsRequest < Internal::Types::Model
7
+ field :agent_id, -> { String }, optional: true, nullable: false, api_name: "agentId"
8
+
9
+ field :messages, -> { Internal::Types::Array[Runtype::Types::ConversationTranscriptMessage] }, optional: true, nullable: false
10
+
7
11
  field :metadata, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
8
12
 
9
13
  field :model_id, -> { String }, optional: true, nullable: false, api_name: "modelId"
10
14
 
11
15
  field :owner_id, -> { String }, optional: true, nullable: false, api_name: "ownerId"
12
16
 
17
+ field :source, -> { Runtype::Types::ConversationSource }, optional: true, nullable: false
18
+
13
19
  field :system_prompt, -> { String }, optional: true, nullable: false, api_name: "systemPrompt"
14
20
 
15
21
  field :title, -> { String }, optional: true, nullable: false
@@ -8,7 +8,9 @@ module Runtype
8
8
 
9
9
  field :id, -> { String }, optional: false, nullable: false
10
10
 
11
- field :messages, -> { Internal::Types::Array[Internal::Types::Hash[String, Object]] }, optional: false, nullable: false
11
+ field :imported, -> { Internal::Types::Boolean }, optional: true, nullable: false
12
+
13
+ field :messages, -> { Internal::Types::Array[Runtype::Types::ConversationTranscriptMessage] }, optional: false, nullable: false
12
14
 
13
15
  field :metadata, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
14
16
 
@@ -6,7 +6,11 @@ module Runtype
6
6
  class PutV1ConversationsIDRequest < Internal::Types::Model
7
7
  field :id, -> { String }, optional: false, nullable: false
8
8
 
9
- field :messages, -> { Internal::Types::Array[Runtype::Conversations::Types::PutV1ConversationsIDRequestMessagesItem] }, optional: true, nullable: false
9
+ field :agent_id, -> { String }, optional: true, nullable: false, api_name: "agentId"
10
+
11
+ field :messages, -> { Internal::Types::Array[Runtype::Types::ConversationTranscriptMessage] }, optional: true, nullable: false
12
+
13
+ field :messages_mode, -> { Runtype::Conversations::Types::PutV1ConversationsIDRequestMessagesMode }, optional: true, nullable: false, api_name: "messagesMode"
10
14
 
11
15
  field :metadata, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
12
16
 
@@ -14,6 +18,8 @@ module Runtype
14
18
 
15
19
  field :owner_id, -> { String }, optional: true, nullable: false, api_name: "ownerId"
16
20
 
21
+ field :source, -> { Runtype::Types::ConversationSource }, optional: true, nullable: false
22
+
17
23
  field :system_prompt, -> { String }, optional: true, nullable: false, api_name: "systemPrompt"
18
24
 
19
25
  field :title, -> { String }, optional: true, nullable: false
@@ -3,11 +3,11 @@
3
3
  module Runtype
4
4
  module Conversations
5
5
  module Types
6
- module PutV1ConversationsIDRequestMessagesItemContentOneItemAssetRefRefKind
6
+ module PutV1ConversationsIDRequestMessagesMode
7
7
  extend Runtype::Internal::Types::Enum
8
8
 
9
- IMAGE = "image"
10
- FILE = "file"
9
+ REPLACE = "replace"
10
+ APPEND = "append"
11
11
  end
12
12
  end
13
13
  end
@@ -8,7 +8,9 @@ module Runtype
8
8
 
9
9
  field :id, -> { String }, optional: false, nullable: false
10
10
 
11
- field :messages, -> { Internal::Types::Array[Internal::Types::Hash[String, Object]] }, optional: false, nullable: false
11
+ field :imported, -> { Internal::Types::Boolean }, optional: true, nullable: false
12
+
13
+ field :messages, -> { Internal::Types::Array[Runtype::Types::ConversationTranscriptMessage] }, optional: false, nullable: false
12
14
 
13
15
  field :metadata, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
14
16
 
@@ -13,9 +13,11 @@ module Runtype
13
13
  # Main dispatch endpoint for flow and agent execution with record resolution. Supports streaming via SSE or
14
14
  # synchronous JSON responses. Send the RFC 7240 `Prefer: respond-async` header to receive a durable execution
15
15
  # handle immediately, then poll its status URL for completion. A saved agent may run on the durable session lane;
16
- # the admission headers `x-runtype-concurrency` (reject, supersede, queue), `x-runtype-coalesce` (true) and
17
- # `idempotency-key` then apply exactly as on `POST /v1/agents/{id}/execute`, and are ignored for a turn that
18
- # resolves to the in-process lane.
16
+ # the admission headers `x-runtype-concurrency` (reject, supersede, queue, join), `x-runtype-coalesce` (true) and
17
+ # `idempotency-key` then apply exactly as on `POST /v1/agents/{id}/execute`, and are ignored for in-process
18
+ # execution except join, which fails explicitly on unsupported lanes. Join accepts only new user-message deltas,
19
+ # preserves the active execution configuration and authority, and returns a deliveryId with a deliveryStatusUrl.
20
+ # Prefer: respond-async with join returns a native delivery receipt without queuing an HTTP replay.
19
21
  #
20
22
  # @param request_options [Hash]
21
23
  # @param params [Runtype::Dispatch::Types::PostV1DispatchRequest]
@@ -18,6 +18,8 @@ module Runtype
18
18
 
19
19
  field :flow, -> { Runtype::Dispatch::Types::PostV1DispatchRequestOneFlow }, optional: true, nullable: false
20
20
 
21
+ field :history, -> { Runtype::Dispatch::Types::PostV1DispatchRequestOneHistory }, optional: true, nullable: false
22
+
21
23
  field :identity_proof, -> { Runtype::Dispatch::Types::PostV1DispatchRequestOneIdentityProof }, optional: true, nullable: false, api_name: "identityProof"
22
24
 
23
25
  field :inputs, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
@@ -8,6 +8,8 @@ module Runtype
8
8
 
9
9
  field :inject_summary, -> { Internal::Types::Boolean }, optional: true, nullable: false, api_name: "injectSummary"
10
10
 
11
+ field :pointer_scope, -> { Runtype::Dispatch::Types::PostV1DispatchRequestOneAgentMemoryPointerScope }, optional: true, nullable: false, api_name: "pointerScope"
12
+
11
13
  field :profile_template, -> { String }, optional: true, nullable: false, api_name: "profileTemplate"
12
14
  end
13
15
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module Dispatch
5
+ module Types
6
+ module PostV1DispatchRequestOneAgentMemoryPointerScope
7
+ extend Runtype::Internal::Types::Enum
8
+
9
+ SHARED = "shared"
10
+ ALIAS = "alias"
11
+ VERSION = "version"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module Dispatch
5
+ module Types
6
+ module PostV1DispatchRequestOneHistory
7
+ extend Runtype::Internal::Types::Enum
8
+
9
+ INLINE = "inline"
10
+ STORED = "stored"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -7,6 +7,10 @@ module Runtype
7
7
  field :content, -> { Runtype::Dispatch::Types::PostV1DispatchRequestOneMessagesItemContent }, optional: false, nullable: false
8
8
 
9
9
  field :role, -> { Runtype::Dispatch::Types::PostV1DispatchRequestOneMessagesItemRole }, optional: false, nullable: false
10
+
11
+ field :tool_calls, -> { Internal::Types::Array[Runtype::Dispatch::Types::PostV1DispatchRequestOneMessagesItemToolCallsItem] }, optional: true, nullable: false, api_name: "toolCalls"
12
+
13
+ field :tool_results, -> { Internal::Types::Array[Runtype::Dispatch::Types::PostV1DispatchRequestOneMessagesItemToolResultsItem] }, optional: true, nullable: false, api_name: "toolResults"
10
14
  end
11
15
  end
12
16
  end
@@ -9,6 +9,7 @@ module Runtype
9
9
  SYSTEM = "system"
10
10
  USER = "user"
11
11
  ASSISTANT = "assistant"
12
+ TOOL = "tool"
12
13
  end
13
14
  end
14
15
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module Dispatch
5
+ module Types
6
+ class PostV1DispatchRequestOneMessagesItemToolCallsItem < Internal::Types::Model
7
+ field :args, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
8
+
9
+ field :provider_options, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false, api_name: "providerOptions"
10
+
11
+ field :tool_call_id, -> { String }, optional: false, nullable: false, api_name: "toolCallId"
12
+
13
+ field :tool_name, -> { String }, optional: false, nullable: false, api_name: "toolName"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module Dispatch
5
+ module Types
6
+ class PostV1DispatchRequestOneMessagesItemToolResultsItem < Internal::Types::Model
7
+ field :provider_options, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false, api_name: "providerOptions"
8
+
9
+ field :result, -> { Object }, optional: true, nullable: false
10
+
11
+ field :tool_call_id, -> { String }, optional: false, nullable: false, api_name: "toolCallId"
12
+
13
+ field :tool_name, -> { String }, optional: false, nullable: false, api_name: "toolName"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -18,6 +18,8 @@ module Runtype
18
18
 
19
19
  field :flow, -> { Runtype::Dispatch::Types::PostV1DispatchRequestZeroFlow }, optional: false, nullable: false
20
20
 
21
+ field :history, -> { Runtype::Dispatch::Types::PostV1DispatchRequestZeroHistory }, optional: true, nullable: false
22
+
21
23
  field :identity_proof, -> { Runtype::Dispatch::Types::PostV1DispatchRequestZeroIdentityProof }, optional: true, nullable: false, api_name: "identityProof"
22
24
 
23
25
  field :inputs, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
@@ -8,6 +8,8 @@ module Runtype
8
8
 
9
9
  field :inject_summary, -> { Internal::Types::Boolean }, optional: true, nullable: false, api_name: "injectSummary"
10
10
 
11
+ field :pointer_scope, -> { Runtype::Dispatch::Types::PostV1DispatchRequestZeroAgentMemoryPointerScope }, optional: true, nullable: false, api_name: "pointerScope"
12
+
11
13
  field :profile_template, -> { String }, optional: true, nullable: false, api_name: "profileTemplate"
12
14
  end
13
15
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Runtype
4
+ module Dispatch
5
+ module Types
6
+ module PostV1DispatchRequestZeroAgentMemoryPointerScope
7
+ extend Runtype::Internal::Types::Enum
8
+
9
+ SHARED = "shared"
10
+ ALIAS = "alias"
11
+ VERSION = "version"
12
+ end
13
+ end
14
+ end
15
+ end