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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +169 -1
- data/README.md +188 -23
- data/generated/lib/runtype/agent_aliases/client.rb +202 -1
- data/generated/lib/runtype/agent_aliases/types/delete_v1agents_id_aliases_alias_bindings_request.rb +17 -0
- data/generated/lib/runtype/agent_aliases/types/delete_v1agents_id_aliases_alias_bindings_response.rb +19 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agent_aliases_request.rb +13 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agent_aliases_response.rb +11 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agent_aliases_response_data_item.rb +25 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_alias_bindings_request.rb +13 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_alias_bindings_response.rb +19 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_alias_response.rb +2 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_aliases_response_data_item.rb +2 -0
- data/generated/lib/runtype/agent_aliases/types/get_v1agents_id_deployments_response_data_item.rb +2 -0
- data/generated/lib/runtype/agent_aliases/types/post_v1agents_id_aliases_alias_rollback_response.rb +6 -0
- data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_bindings_request.rb +21 -0
- data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_bindings_response.rb +19 -0
- data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_request.rb +2 -0
- data/generated/lib/runtype/agent_aliases/types/put_v1agents_id_aliases_alias_response.rb +6 -0
- data/generated/lib/runtype/agent_versions/client.rb +13 -1
- data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_request.rb +6 -0
- data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_request_deployment.rb +11 -0
- data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_request_deployment_action.rb +14 -0
- data/generated/lib/runtype/agent_versions/types/post_v1agent_versions_agent_id_publish_response.rb +1 -1
- data/generated/lib/runtype/agents/types/post_v1agents_ensure_request_definition_config_memory.rb +2 -0
- data/generated/lib/runtype/agents/types/post_v1agents_ensure_request_definition_config_memory_pointer_scope.rb +15 -0
- data/generated/lib/runtype/agents/types/post_v1agents_id_execute_request_x_runtype_concurrency.rb +1 -0
- data/generated/lib/runtype/agents/types/post_v1agents_request_config_memory.rb +2 -0
- data/generated/lib/runtype/agents/types/post_v1agents_request_config_memory_pointer_scope.rb +15 -0
- data/generated/lib/runtype/agents/types/put_v1agents_id_request_config_memory.rb +2 -0
- data/generated/lib/runtype/agents/types/put_v1agents_id_request_config_memory_pointer_scope.rb +15 -0
- data/generated/lib/runtype/batch/types/get_v1batch_batch_id_records_record_id_steps_response_data_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/client.rb +5 -5
- data/generated/lib/runtype/client_runtime/client.rb +118 -1
- data/generated/lib/runtype/client_runtime/types/get_v1client_conversations_conversation_id_executions_execution_id_deliveries_delivery_id_request.rb +21 -0
- data/generated/lib/runtype/client_runtime/types/post_v1client_chat_request_submit_mode.rb +1 -0
- data/generated/lib/runtype/client_runtime/types/post_v1client_conversations_conversation_id_executions_execution_id_cancel_request.rb +19 -0
- data/generated/lib/runtype/client_runtime/types/post_v1client_conversations_conversation_id_executions_execution_id_cancel_response.rb +13 -0
- data/generated/lib/runtype/client_runtime/types/post_v1client_init_response_durable_recovery.rb +2 -0
- data/generated/lib/runtype/client_tokens/types/get_v1client_tokens_id_response_client_token.rb +4 -0
- data/generated/lib/runtype/client_tokens/types/get_v1client_tokens_response_client_tokens_item.rb +4 -0
- data/generated/lib/runtype/client_tokens/types/post_v1client_tokens_id_regenerate_response_client_token.rb +4 -0
- data/generated/lib/runtype/client_tokens/types/post_v1client_tokens_request.rb +4 -0
- data/generated/lib/runtype/client_tokens/types/post_v1client_tokens_response_client_token.rb +4 -0
- data/generated/lib/runtype/client_tokens/types/put_v1client_tokens_id_request.rb +4 -0
- data/generated/lib/runtype/client_tokens/types/put_v1client_tokens_id_response_client_token.rb +4 -0
- data/generated/lib/runtype/conversations/client.rb +28 -10
- data/generated/lib/runtype/conversations/types/get_v1conversations_id_response.rb +3 -1
- data/generated/lib/runtype/conversations/types/post_v1conversations_request.rb +6 -0
- data/generated/lib/runtype/conversations/types/post_v1conversations_response.rb +3 -1
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request.rb +7 -1
- 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
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_response.rb +3 -1
- data/generated/lib/runtype/dispatch/client.rb +5 -3
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one.rb +2 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_agent_memory.rb +2 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_agent_memory_pointer_scope.rb +15 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_history.rb +14 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item.rb +4 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item_role.rb +1 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item_tool_calls_item.rb +17 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_one_messages_item_tool_results_item.rb +17 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero.rb +2 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_agent_memory.rb +2 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_agent_memory_pointer_scope.rb +15 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_history.rb +14 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item.rb +4 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item_role.rb +1 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item_tool_calls_item.rb +17 -0
- data/generated/lib/runtype/dispatch/types/post_v1dispatch_request_zero_messages_item_tool_results_item.rb +17 -0
- data/generated/lib/runtype/evals/types/get_v1eval_id_results_response.rb +10 -0
- data/generated/lib/runtype/evals/types/get_v1eval_id_results_response_agent_target_resolution.rb +15 -0
- data/generated/lib/runtype/evals/types/get_v1eval_id_results_response_results_by_record_value_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/evals/types/post_v1eval_run_request.rb +2 -0
- data/generated/lib/runtype/evals/types/post_v1eval_run_request_agent.rb +15 -0
- data/generated/lib/runtype/evals/types/post_v1eval_submit_request.rb +2 -0
- data/generated/lib/runtype/evals/types/post_v1eval_submit_request_agent.rb +15 -0
- data/generated/lib/runtype/evals/types/post_v1eval_suites_id_run_request.rb +2 -0
- data/generated/lib/runtype/executions/client.rb +43 -0
- data/generated/lib/runtype/executions/types/get_v1executions_execution_id_deliveries_delivery_id_request.rb +13 -0
- data/generated/lib/runtype/flows/client.rb +3 -4
- data/generated/lib/runtype/flows/types/get_v1flows_id_step_results_response_data_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/messaging_conversations/client.rb +2 -0
- data/generated/lib/runtype/messaging_conversations/types/get_v1messaging_conversations_request.rb +2 -0
- data/generated/lib/runtype/model_configs/types/post_v1model_configs_request_settings_custom_model.rb +2 -0
- data/generated/lib/runtype/model_configs/types/post_v1model_configs_request_settings_custom_model_mid_conversation_system_messages.rb +14 -0
- data/generated/lib/runtype/model_configs/types/put_v1model_configs_id_request_settings_custom_model.rb +2 -0
- data/generated/lib/runtype/model_configs/types/put_v1model_configs_id_request_settings_custom_model_mid_conversation_system_messages.rb +14 -0
- data/generated/lib/runtype/products/client.rb +45 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_request.rb +13 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response.rb +13 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data.rb +13 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item.rb +17 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item.rb +77 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_agent_target_resolution.rb +15 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_agent_version.rb +17 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_execution_mode.rb +14 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_notification_mode.rb +15 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_pending_approval.rb +27 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_data_item_status.rb +19 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_agents_item_error.rb +11 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item.rb +19 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item.rb +15 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item_agent_mode.rb +45 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item_available_fields.rb +39 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_data_item_available_fields_metadata_schema.rb +11 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_error.rb +11 -0
- data/generated/lib/runtype/products/types/get_v1products_id_activity_response_data_surfaces_item_source.rb +14 -0
- data/generated/lib/runtype/provider_keys/types/post_v1provider_keys_id_sync_models_request_models_item.rb +2 -0
- data/generated/lib/runtype/provider_keys/types/post_v1provider_keys_id_sync_models_request_models_item_mid_conversation_system_messages.rb +14 -0
- data/generated/lib/runtype/records/types/get_v1records_id_results_response_data_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/records/types/get_v1records_id_step_results_response_data_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/schedules/types/get_v1schedules_batch_batch_id_results_response_data_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/schedules/types/get_v1schedules_runs_run_id_results_response_data_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/types/agent_deployment_promotion.rb +17 -0
- data/generated/lib/runtype/types/agent_ensure_deploy_target.rb +2 -0
- data/generated/lib/runtype/types/agent_ensure_preview_alias_limit.rb +19 -0
- data/generated/lib/runtype/types/agent_ensure_preview_alias_limit_code.rb +11 -0
- data/generated/lib/runtype/types/agent_ensure_preview_alias_limit_scope.rb +12 -0
- data/generated/lib/runtype/types/agent_pull_response_definition_config_memory.rb +2 -0
- data/generated/lib/runtype/types/agent_pull_response_definition_config_memory_pointer_scope.rb +13 -0
- data/generated/lib/runtype/types/async_dispatch_handle.rb +10 -0
- data/generated/lib/runtype/types/async_dispatch_handle_delivery_status.rb +14 -0
- data/generated/lib/runtype/types/async_dispatch_handle_status.rb +5 -0
- data/generated/lib/runtype/types/client_input_delivery_receipt.rb +19 -0
- data/generated/lib/runtype/types/client_input_delivery_receipt_status.rb +14 -0
- data/generated/lib/runtype/types/conflict_error_body_candidate_count.rb +21 -0
- data/generated/lib/runtype/types/conflict_error_body_candidate_count_code.rb +11 -0
- data/generated/lib/runtype/types/conversation_busy_error.rb +15 -0
- data/generated/lib/runtype/types/conversation_busy_error_code.rb +11 -0
- data/generated/lib/runtype/types/conversation_busy_error_phase.rb +14 -0
- data/generated/lib/runtype/types/conversation_message_author.rb +16 -0
- data/generated/lib/runtype/types/conversation_message_author_type.rb +14 -0
- data/generated/lib/runtype/types/conversation_modified_error.rb +13 -0
- data/generated/lib/runtype/types/conversation_modified_error_code.rb +11 -0
- data/generated/lib/runtype/types/conversation_source.rb +14 -0
- data/generated/lib/runtype/types/conversation_transcript_message.rb +23 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content.rb +14 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item.rb +21 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_asset_ref.rb +19 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_asset_ref_ref_kind.rb +12 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_file.rb +13 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_image.rb +11 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_reasoning.rb +11 -0
- data/generated/lib/runtype/types/conversation_transcript_message_content_one_item_text.rb +9 -0
- data/generated/lib/runtype/types/conversation_transcript_message_role.rb +14 -0
- data/generated/lib/runtype/types/conversation_transcript_message_tool_calls_item.rb +15 -0
- data/generated/lib/runtype/types/conversation_transcript_message_tool_results_item.rb +15 -0
- data/generated/lib/runtype/types/dispatch_agent_json_response.rb +12 -0
- data/generated/lib/runtype/types/dispatch_agent_json_response_delivery_status.rb +14 -0
- data/generated/lib/runtype/types/dispatch_agent_json_response_execution_mode.rb +1 -0
- data/generated/lib/runtype/types/eval_agent_selector.rb +13 -0
- data/generated/lib/runtype/types/eval_run_scores_response.rb +10 -0
- data/generated/lib/runtype/types/eval_run_scores_response_agent_target_resolution.rb +13 -0
- data/generated/lib/runtype/types/eval_run_scores_response_cases_item_execution_engine.rb +1 -0
- data/generated/lib/runtype/types/eval_suite_run_queued.rb +10 -0
- data/generated/lib/runtype/types/eval_suite_run_queued_agent_target_resolution.rb +13 -0
- data/generated/lib/runtype/types/input_delivery_receipt.rb +19 -0
- data/generated/lib/runtype/types/input_delivery_receipt_status.rb +14 -0
- data/generated/lib/runtype/types/preview_alias_limit_error.rb +21 -0
- data/generated/lib/runtype/types/preview_alias_limit_error_code.rb +11 -0
- data/generated/lib/runtype/types/preview_alias_limit_error_scope.rb +12 -0
- data/generated/lib/runtype/types/run_eval_response.rb +10 -0
- data/generated/lib/runtype/types/run_eval_response_agent_target_resolution.rb +13 -0
- data/generated/lib/runtype.rb +109 -26
- data/lib/runtype/agent_ensure.rb +68 -4
- data/lib/runtype/agent_release_aliases.rb +282 -0
- data/lib/runtype/client.rb +22 -1
- data/lib/runtype/errors.rb +14 -2
- data/lib/runtype/raw_client_timeout.rb +56 -0
- data/lib/runtype/sdk_version.rb +2 -1
- data/lib/runtype.rb +2 -0
- metadata +95 -10
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item.rb +0 -17
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content.rb +0 -15
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item.rb +0 -21
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_asset_ref.rb +0 -21
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_file.rb +0 -15
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_image.rb +0 -13
- data/generated/lib/runtype/conversations/types/put_v1conversations_id_request_messages_item_content_one_item_text.rb +0 -11
- 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
|
data/lib/runtype/client.rb
CHANGED
|
@@ -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}"
|
data/lib/runtype/errors.rb
CHANGED
|
@@ -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
|
data/lib/runtype/sdk_version.rb
CHANGED
|
@@ -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
|
-
|
|
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"
|