anthropic 2.1.0 → 2.3.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 +57 -0
- data/README.md +2 -2
- data/lib/anthropic/client.rb +9 -1
- data/lib/anthropic/helpers/bedrock/client.rb +11 -3
- data/lib/anthropic/helpers/bedrock/mantle_client.rb +5 -0
- data/lib/anthropic/helpers/google_cloud/client.rb +9 -25
- data/lib/anthropic/helpers/refusal_fallback.rb +1 -2
- data/lib/anthropic/helpers/stainless_helper_header.rb +4 -2
- data/lib/anthropic/helpers/threads/beta_message_thread.rb +635 -0
- data/lib/anthropic/helpers/tools/runner.rb +79 -11
- data/lib/anthropic/helpers/vertex/client.rb +5 -0
- data/lib/anthropic/internal/report_page_cursor.rb +2 -2
- data/lib/anthropic/internal/tracing.rb +22 -0
- data/lib/anthropic/internal/transport/base_client.rb +16 -2
- data/lib/anthropic/models/anthropic_beta.rb +9 -0
- data/lib/anthropic/models/beta/beta_code_execution_tool_20260120.rb +10 -2
- data/lib/anthropic/models/beta/beta_code_execution_tool_result_block_content.rb +5 -1
- data/lib/anthropic/models/beta/beta_code_execution_tool_result_block_param_content.rb +1 -1
- data/lib/anthropic/models/beta/beta_encrypted_code_execution_result_block.rb +9 -1
- data/lib/anthropic/models/beta/beta_encrypted_code_execution_result_block_param.rb +2 -1
- data/lib/anthropic/models/beta/beta_message_thread_param.rb +61 -0
- data/lib/anthropic/models/beta/beta_response_tool_union.rb +5 -1
- data/lib/anthropic/models/beta/beta_skill_params.rb +1 -1
- data/lib/anthropic/models/beta/beta_thread_continue_params.rb +29 -0
- data/lib/anthropic/models/beta/beta_thread_create_params.rb +21 -0
- data/lib/anthropic/models/beta/beta_tool_union.rb +5 -1
- data/lib/anthropic/models/beta/environments/beta_self_hosted_work_heartbeat_response.rb +7 -2
- data/lib/anthropic/models/beta/environments/beta_self_hosted_work_queue_stats.rb +2 -4
- data/lib/anthropic/models/beta/message_count_tokens_params.rb +5 -1
- data/lib/anthropic/models/beta/message_create_params.rb +13 -1
- data/lib/anthropic/models/beta/messages/batch_create_params.rb +13 -1
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_cost_group.rb +271 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_cost_group_by.rb +40 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_cost_item.rb +57 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_cost_metrics.rb +57 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_cost_order_by.rb +22 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_usage_group.rb +247 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_usage_group_by.rb +38 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_usage_item.rb +57 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_usage_metrics.rb +79 -0
- data/lib/anthropic/models/beta/organization/analytics/beta_analytics_usage_order_by.rb +24 -0
- data/lib/anthropic/models/beta/organization/analytics/cost_list_params.rb +360 -0
- data/lib/anthropic/models/beta/organization/analytics/usage_list_params.rb +353 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_actor.rb +81 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_actor_type.rb +22 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_api_actor.rb +27 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_federated_actor.rb +42 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_federated_actor_aws_provider.rb +35 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_federated_actor_azure_provider.rb +27 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_federated_actor_gcp_provider.rb +27 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_federated_actor_oidc_provider.rb +27 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_federated_actor_provider.rb +72 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_grouped_cost_type.rb +21 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_report_user_actor.rb +65 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_service_account_actor.rb +27 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_service_tier.rb +23 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_speed.rb +19 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_time_bucket_width.rb +20 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_usage_cost_inference_geo.rb +19 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_usage_cost_product_filter.rb +34 -0
- data/lib/anthropic/models/beta/organization/beta_analytics_usage_cost_sort_order.rb +19 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_default_setting_source.rb +21 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_guest_policy.rb +63 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_guest_policy_allow.rb +21 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_guest_policy_channel_only.rb +21 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_guest_policy_restrict.rb +21 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_setting_source.rb +87 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_setting_sources.rb +72 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_settings.rb +70 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_settings_create.rb +67 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_settings_update.rb +67 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_channel_identifiers.rb +37 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_channel_setting_source.rb +29 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_default_setting_source.rb +22 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_grid_channel_setting_source.rb +31 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_parent_channel_setting_source.rb +30 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_workspace_identifiers.rb +23 -0
- data/lib/anthropic/models/beta/organization/beta_claude_tag_slack_workspace_setting_source.rb +29 -0
- data/lib/anthropic/models/beta/organization/beta_external_key.rb +3 -3
- data/lib/anthropic/models/beta/organization/beta_organization_rate_limit.rb +2 -1
- data/lib/anthropic/models/beta/organization/beta_plugin.rb +12 -6
- data/lib/anthropic/models/beta/organization/beta_plugin_content_scan.rb +11 -5
- data/lib/anthropic/models/beta/organization/claude_tag/beta_claude_tag_bundle.rb +66 -0
- data/lib/anthropic/models/beta/organization/claude_tag/beta_claude_tag_deleted_slack_channel.rb +32 -0
- data/lib/anthropic/models/beta/organization/claude_tag/beta_claude_tag_slack_channel.rb +87 -0
- data/lib/anthropic/models/beta/organization/claude_tag/beta_claude_tag_slack_workspace.rb +86 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundle_list_params.rb +49 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundle_retrieve_params.rb +41 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_bundle_target.rb +76 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_bundle_target_create.rb +70 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_deleted_bundle_target.rb +34 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_channel_bundle_target.rb +57 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_channel_bundle_target_create.rb +38 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_workspace_bundle_target.rb +57 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_workspace_bundle_target_create.rb +38 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/target_create_params.rb +43 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/target_delete_params.rb +53 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/target_list_params.rb +59 -0
- data/lib/anthropic/models/beta/organization/claude_tag/bundles/target_retrieve_params.rb +53 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_channel_create_params.rb +50 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_channel_delete_params.rb +41 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_channel_list_params.rb +79 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_channel_retrieve_params.rb +52 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_channel_update_params.rb +49 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_workspace_list_params.rb +70 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_workspace_retrieve_params.rb +52 -0
- data/lib/anthropic/models/beta/organization/claude_tag/slack_workspace_update_params.rb +49 -0
- data/lib/anthropic/models/beta/organization/workspaces/beta_workspace_rate_limit.rb +2 -1
- data/lib/anthropic/models/code_execution_tool_20260120.rb +10 -2
- data/lib/anthropic/models/code_execution_tool_result_block_content.rb +5 -1
- data/lib/anthropic/models/code_execution_tool_result_block_param_content.rb +1 -1
- data/lib/anthropic/models/encrypted_code_execution_result_block.rb +9 -1
- data/lib/anthropic/models/encrypted_code_execution_result_block_param.rb +2 -1
- data/lib/anthropic/models/message_count_tokens_tool.rb +5 -1
- data/lib/anthropic/models/organization/external_key.rb +3 -3
- data/lib/anthropic/models/organization/organization_rate_limit.rb +2 -1
- data/lib/anthropic/models/organization/workspaces/workspace_rate_limit.rb +2 -1
- data/lib/anthropic/models/skill_params.rb +1 -1
- data/lib/anthropic/models/tool_union.rb +5 -1
- data/lib/anthropic/resources/beta/agents/versions.rb +2 -1
- data/lib/anthropic/resources/beta/agents.rb +10 -5
- data/lib/anthropic/resources/beta/deployment_runs.rb +4 -2
- data/lib/anthropic/resources/beta/deployments.rb +16 -8
- data/lib/anthropic/resources/beta/dreams.rb +10 -5
- data/lib/anthropic/resources/beta/environments/work.rb +16 -8
- data/lib/anthropic/resources/beta/environments.rb +12 -6
- data/lib/anthropic/resources/beta/files.rb +10 -5
- data/lib/anthropic/resources/beta/memory_stores/memories.rb +10 -5
- data/lib/anthropic/resources/beta/memory_stores/memory_versions.rb +6 -11
- data/lib/anthropic/resources/beta/memory_stores.rb +12 -6
- data/lib/anthropic/resources/beta/messages/batches.rb +12 -6
- data/lib/anthropic/resources/beta/messages.rb +84 -7
- data/lib/anthropic/resources/beta/models.rb +4 -2
- data/lib/anthropic/resources/beta/organization/analytics/apps/chat/projects.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics/artifacts.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics/connectors.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics/cost.rb +176 -0
- data/lib/anthropic/resources/beta/organization/analytics/cost_report.rb +14 -6
- data/lib/anthropic/resources/beta/organization/analytics/plugins.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics/skills.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics/summaries.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics/usage.rb +177 -0
- data/lib/anthropic/resources/beta/organization/analytics/usage_report.rb +11 -3
- data/lib/anthropic/resources/beta/organization/analytics/user_cost_report.rb +17 -9
- data/lib/anthropic/resources/beta/organization/analytics/user_usage_report.rb +17 -9
- data/lib/anthropic/resources/beta/organization/analytics/users.rb +2 -1
- data/lib/anthropic/resources/beta/organization/analytics.rb +8 -0
- data/lib/anthropic/resources/beta/organization/api_keys.rb +6 -3
- data/lib/anthropic/resources/beta/organization/claude_tag/bundles/targets.rb +204 -0
- data/lib/anthropic/resources/beta/organization/claude_tag/bundles.rb +102 -0
- data/lib/anthropic/resources/beta/organization/claude_tag/slack_channels.rb +263 -0
- data/lib/anthropic/resources/beta/organization/claude_tag/slack_workspaces.rb +162 -0
- data/lib/anthropic/resources/beta/organization/claude_tag.rb +31 -0
- data/lib/anthropic/resources/beta/organization/compliance_settings.rb +4 -2
- data/lib/anthropic/resources/beta/organization/external_keys.rb +12 -6
- data/lib/anthropic/resources/beta/organization/federation/issuers.rb +10 -5
- data/lib/anthropic/resources/beta/organization/federation/rules/workspaces.rb +6 -3
- data/lib/anthropic/resources/beta/organization/federation/rules.rb +10 -5
- data/lib/anthropic/resources/beta/organization/invites.rb +8 -4
- data/lib/anthropic/resources/beta/organization/plugin_marketplaces.rb +16 -11
- data/lib/anthropic/resources/beta/organization/plugins/installation_settings.rb +6 -11
- data/lib/anthropic/resources/beta/organization/plugins/shares.rb +2 -1
- data/lib/anthropic/resources/beta/organization/plugins/versions.rb +8 -4
- data/lib/anthropic/resources/beta/organization/plugins.rb +22 -14
- data/lib/anthropic/resources/beta/organization/rate_limits.rb +2 -1
- data/lib/anthropic/resources/beta/organization/rbac_groups/members.rb +6 -3
- data/lib/anthropic/resources/beta/organization/rbac_groups.rb +10 -5
- data/lib/anthropic/resources/beta/organization/rbac_roles/permissions.rb +2 -1
- data/lib/anthropic/resources/beta/organization/rbac_roles.rb +4 -2
- data/lib/anthropic/resources/beta/organization/service_accounts/workspaces.rb +6 -3
- data/lib/anthropic/resources/beta/organization/service_accounts.rb +10 -5
- data/lib/anthropic/resources/beta/organization/spend_limits/effective.rb +2 -1
- data/lib/anthropic/resources/beta/organization/spend_limits/increase_requests.rb +8 -4
- data/lib/anthropic/resources/beta/organization/spend_limits.rb +8 -4
- data/lib/anthropic/resources/beta/organization/telemetry_destinations/workspaces.rb +6 -3
- data/lib/anthropic/resources/beta/organization/telemetry_destinations.rb +12 -6
- data/lib/anthropic/resources/beta/organization/users.rb +8 -4
- data/lib/anthropic/resources/beta/organization/webhooks.rb +12 -9
- data/lib/anthropic/resources/beta/organization/workspaces/members.rb +10 -5
- data/lib/anthropic/resources/beta/organization/workspaces/rate_limits.rb +4 -6
- data/lib/anthropic/resources/beta/organization/workspaces/service_accounts.rb +10 -5
- data/lib/anthropic/resources/beta/organization/workspaces.rb +10 -5
- data/lib/anthropic/resources/beta/organization.rb +6 -1
- data/lib/anthropic/resources/beta/sessions/events.rb +6 -3
- data/lib/anthropic/resources/beta/sessions/resources.rb +10 -5
- data/lib/anthropic/resources/beta/sessions/threads/events.rb +4 -2
- data/lib/anthropic/resources/beta/sessions/threads.rb +6 -3
- data/lib/anthropic/resources/beta/sessions.rb +12 -6
- data/lib/anthropic/resources/beta/skills/versions.rb +10 -5
- data/lib/anthropic/resources/beta/skills.rb +8 -4
- data/lib/anthropic/resources/beta/tunnels/certificates.rb +8 -4
- data/lib/anthropic/resources/beta/tunnels.rb +12 -6
- data/lib/anthropic/resources/beta/user_profiles/action_urls.rb +2 -1
- data/lib/anthropic/resources/beta/user_profiles.rb +12 -6
- data/lib/anthropic/resources/beta/vaults/credentials.rb +14 -7
- data/lib/anthropic/resources/beta/vaults.rb +12 -6
- data/lib/anthropic/version.rb +1 -1
- data/lib/anthropic.rb +83 -0
- data/rbi/anthropic/client.rbi +5 -0
- data/rbi/anthropic/helpers/bedrock/client.rbi +5 -0
- data/rbi/anthropic/helpers/bedrock/mantle_client.rbi +5 -0
- data/rbi/anthropic/helpers/google_cloud/client.rbi +0 -4
- data/rbi/anthropic/helpers/threads/beta_message_thread.rbi +100 -0
- data/rbi/anthropic/helpers/vertex/client.rbi +5 -0
- data/rbi/anthropic/internal/tracing.rbi +32 -0
- data/rbi/anthropic/internal/transport/base_client.rbi +5 -1
- data/rbi/anthropic/internal/type/base_page.rbi +2 -0
- data/rbi/anthropic/internal/type/base_stream.rbi +2 -0
- data/rbi/anthropic/internal/type/request_parameters.rbi +4 -0
- data/rbi/anthropic/models/anthropic_beta.rbi +15 -0
- data/rbi/anthropic/models/beta/beta_code_execution_tool_20260120.rbi +10 -2
- data/rbi/anthropic/models/beta/beta_encrypted_code_execution_result_block.rbi +9 -1
- data/rbi/anthropic/models/beta/beta_encrypted_code_execution_result_block_param.rbi +2 -1
- data/rbi/anthropic/models/beta/beta_message_thread_param.rbi +80 -0
- data/rbi/anthropic/models/beta/beta_skill_params.rbi +1 -1
- data/rbi/anthropic/models/beta/beta_thread_continue_params.rbi +43 -0
- data/rbi/anthropic/models/beta/beta_thread_create_params.rbi +31 -0
- data/rbi/anthropic/models/beta/environments/beta_self_hosted_work_heartbeat_response.rbi +4 -2
- data/rbi/anthropic/models/beta/environments/beta_self_hosted_work_queue_stats.rbi +2 -4
- data/rbi/anthropic/models/beta/message_create_params.rbi +37 -0
- data/rbi/anthropic/models/beta/messages/batch_create_params.rbi +37 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_cost_group.rbi +439 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_cost_group_by.rbi +140 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_cost_item.rbi +110 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_cost_metrics.rbi +79 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_cost_order_by.rbi +50 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_usage_group.rbi +399 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_usage_group_by.rbi +130 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_usage_item.rbi +110 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_usage_metrics.rbi +120 -0
- data/rbi/anthropic/models/beta/organization/analytics/beta_analytics_usage_order_by.rbi +60 -0
- data/rbi/anthropic/models/beta/organization/analytics/cost_list_params.rbi +624 -0
- data/rbi/anthropic/models/beta/organization/analytics/usage_list_params.rbi +612 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_actor.rbi +134 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_actor_type.rbi +54 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_api_actor.rbi +40 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_federated_actor.rbi +75 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_federated_actor_aws_provider.rbi +54 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_federated_actor_azure_provider.rbi +42 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_federated_actor_gcp_provider.rbi +42 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_federated_actor_oidc_provider.rbi +42 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_federated_actor_provider.rbi +107 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_grouped_cost_type.rbi +53 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_report_user_actor.rbi +94 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_service_account_actor.rbi +42 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_service_tier.rbi +63 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_speed.rbi +40 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_time_bucket_width.rbi +48 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_usage_cost_inference_geo.rbi +43 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_usage_cost_product_filter.rbi +98 -0
- data/rbi/anthropic/models/beta/organization/beta_analytics_usage_cost_sort_order.rbi +43 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_default_setting_source.rbi +31 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_guest_policy.rbi +87 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_guest_policy_allow.rbi +31 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_guest_policy_channel_only.rbi +31 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_guest_policy_restrict.rbi +31 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_setting_source.rbi +115 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_setting_sources.rbi +178 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_settings.rbi +108 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_settings_create.rbi +110 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_settings_update.rbi +110 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_channel_identifiers.rbi +50 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_channel_setting_source.rbi +43 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_default_setting_source.rbi +32 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_grid_channel_setting_source.rbi +67 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_parent_channel_setting_source.rbi +44 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_workspace_identifiers.rbi +36 -0
- data/rbi/anthropic/models/beta/organization/beta_claude_tag_slack_workspace_setting_source.rbi +43 -0
- data/rbi/anthropic/models/beta/organization/beta_external_key.rbi +4 -4
- data/rbi/anthropic/models/beta/organization/beta_organization_rate_limit.rbi +4 -2
- data/rbi/anthropic/models/beta/organization/beta_plugin.rbi +20 -8
- data/rbi/anthropic/models/beta/organization/beta_plugin_content_scan.rbi +15 -6
- data/rbi/anthropic/models/beta/organization/claude_tag/beta_claude_tag_bundle.rbi +87 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/beta_claude_tag_deleted_slack_channel.rbi +41 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/beta_claude_tag_slack_channel.rbi +154 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/beta_claude_tag_slack_workspace.rbi +151 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundle_list_params.rbi +92 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundle_retrieve_params.rbi +78 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_bundle_target.rbi +102 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_bundle_target_create.rbi +92 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_deleted_bundle_target.rbi +43 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_channel_bundle_target.rbi +78 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_channel_bundle_target_create.rbi +51 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_workspace_bundle_target.rbi +78 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_workspace_bundle_target_create.rbi +51 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/target_create_params.rbi +82 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/target_delete_params.rbi +94 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/target_list_params.rbi +104 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/bundles/target_retrieve_params.rbi +94 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_channel_create_params.rbi +118 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_channel_delete_params.rbi +78 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_channel_list_params.rbi +134 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_channel_retrieve_params.rbi +95 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_channel_update_params.rbi +100 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_workspace_list_params.rbi +124 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_workspace_retrieve_params.rbi +95 -0
- data/rbi/anthropic/models/beta/organization/claude_tag/slack_workspace_update_params.rbi +100 -0
- data/rbi/anthropic/models/beta/organization/workspaces/beta_workspace_rate_limit.rbi +4 -2
- data/rbi/anthropic/models/code_execution_tool_20260120.rbi +10 -2
- data/rbi/anthropic/models/encrypted_code_execution_result_block.rbi +9 -1
- data/rbi/anthropic/models/encrypted_code_execution_result_block_param.rbi +2 -1
- data/rbi/anthropic/models/organization/external_key.rbi +4 -4
- data/rbi/anthropic/models/organization/organization_rate_limit.rbi +4 -2
- data/rbi/anthropic/models/organization/workspaces/workspace_rate_limit.rbi +4 -2
- data/rbi/anthropic/models/skill_params.rbi +1 -1
- data/rbi/anthropic/resources/beta/messages.rbi +191 -0
- data/rbi/anthropic/resources/beta/organization/analytics/cost.rbi +245 -0
- data/rbi/anthropic/resources/beta/organization/analytics/cost_report.rbi +12 -5
- data/rbi/anthropic/resources/beta/organization/analytics/usage.rbi +240 -0
- data/rbi/anthropic/resources/beta/organization/analytics/usage_report.rbi +9 -2
- data/rbi/anthropic/resources/beta/organization/analytics/user_cost_report.rbi +14 -7
- data/rbi/anthropic/resources/beta/organization/analytics/user_usage_report.rbi +14 -7
- data/rbi/anthropic/resources/beta/organization/analytics.rbi +10 -0
- data/rbi/anthropic/resources/beta/organization/claude_tag/bundles/targets.rbi +140 -0
- data/rbi/anthropic/resources/beta/organization/claude_tag/bundles.rbi +75 -0
- data/rbi/anthropic/resources/beta/organization/claude_tag/slack_channels.rbi +203 -0
- data/rbi/anthropic/resources/beta/organization/claude_tag/slack_workspaces.rbi +123 -0
- data/rbi/anthropic/resources/beta/organization/claude_tag.rbi +37 -0
- data/rbi/anthropic/resources/beta/organization/plugin_marketplaces.rbi +6 -6
- data/rbi/anthropic/resources/beta/organization/plugins.rbi +12 -9
- data/rbi/anthropic/resources/beta/organization.rbi +3 -0
- data/rbi/lib/anthropic/helpers/stainless_helper_header.rbi +2 -0
- data/sig/anthropic/client.rbs +2 -0
- data/sig/anthropic/helpers/bedrock/client.rbs +2 -0
- data/sig/anthropic/helpers/google_cloud/client.rbs +0 -2
- data/sig/anthropic/helpers/threads/beta_message_thread.rbs +40 -0
- data/sig/anthropic/helpers/tools/runner.rbs +40 -0
- data/sig/anthropic/helpers/vertex/client.rbs +2 -0
- data/sig/anthropic/internal/tracing.rbs +16 -0
- data/sig/anthropic/internal/transport/base_client.rbs +3 -0
- data/sig/anthropic/internal/type/request_parameters.rbs +2 -0
- data/sig/anthropic/models/anthropic_beta.rbs +6 -0
- data/sig/anthropic/models/beta/beta_message_thread_param.rbs +40 -0
- data/sig/anthropic/models/beta/beta_thread_continue_params.rbs +20 -0
- data/sig/anthropic/models/beta/beta_thread_create_params.rbs +17 -0
- data/sig/anthropic/models/beta/message_create_params.rbs +5 -0
- data/sig/anthropic/models/beta/messages/batch_create_params.rbs +5 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_cost_group.rbs +126 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_cost_group_by.rbs +60 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_cost_item.rbs +41 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_cost_metrics.rbs +41 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_cost_order_by.rbs +21 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_usage_group.rbs +116 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_usage_group_by.rbs +56 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_usage_item.rbs +41 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_usage_metrics.rbs +56 -0
- data/sig/anthropic/models/beta/organization/analytics/beta_analytics_usage_order_by.rbs +28 -0
- data/sig/anthropic/models/beta/organization/analytics/cost_list_params.rbs +188 -0
- data/sig/anthropic/models/beta/organization/analytics/usage_list_params.rbs +188 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_actor.rbs +67 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_actor_type.rbs +21 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_api_actor.rbs +19 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_federated_actor.rbs +34 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_federated_actor_aws_provider.rbs +30 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_federated_actor_azure_provider.rbs +20 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_federated_actor_gcp_provider.rbs +20 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_federated_actor_oidc_provider.rbs +20 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_federated_actor_provider.rbs +60 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_grouped_cost_type.rbs +21 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_report_user_actor.rbs +44 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_service_account_actor.rbs +26 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_service_tier.rbs +28 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_speed.rbs +18 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_time_bucket_width.rbs +19 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_usage_cost_inference_geo.rbs +18 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_usage_cost_product_filter.rbs +40 -0
- data/sig/anthropic/models/beta/organization/beta_analytics_usage_cost_sort_order.rbs +18 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_default_setting_source.rbs +17 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_guest_policy.rbs +45 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_guest_policy_allow.rbs +17 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_guest_policy_channel_only.rbs +17 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_guest_policy_restrict.rbs +17 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_setting_source.rbs +73 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_setting_sources.rbs +44 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_settings.rbs +44 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_settings_create.rbs +44 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_settings_update.rbs +44 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_channel_identifiers.rbs +20 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_channel_setting_source.rbs +23 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_default_setting_source.rbs +18 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_grid_channel_setting_source.rbs +29 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_parent_channel_setting_source.rbs +26 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_workspace_identifiers.rbs +18 -0
- data/sig/anthropic/models/beta/organization/beta_claude_tag_slack_workspace_setting_source.rbs +23 -0
- data/sig/anthropic/models/beta/organization/claude_tag/beta_claude_tag_bundle.rbs +51 -0
- data/sig/anthropic/models/beta/organization/claude_tag/beta_claude_tag_deleted_slack_channel.rbs +22 -0
- data/sig/anthropic/models/beta/organization/claude_tag/beta_claude_tag_slack_channel.rbs +56 -0
- data/sig/anthropic/models/beta/organization/claude_tag/beta_claude_tag_slack_workspace.rbs +56 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundle_list_params.rbs +50 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundle_retrieve_params.rbs +41 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_bundle_target.rbs +54 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_bundle_target_create.rbs +48 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_deleted_bundle_target.rbs +27 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_channel_bundle_target.rbs +43 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_channel_bundle_target_create.rbs +27 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_workspace_bundle_target.rbs +43 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/beta_claude_tag_slack_workspace_bundle_target_create.rbs +30 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/target_create_params.rbs +43 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/target_delete_params.rbs +48 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/target_list_params.rbs +57 -0
- data/sig/anthropic/models/beta/organization/claude_tag/bundles/target_retrieve_params.rbs +48 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_channel_create_params.rbs +50 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_channel_delete_params.rbs +38 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_channel_list_params.rbs +69 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_channel_retrieve_params.rbs +48 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_channel_update_params.rbs +46 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_workspace_list_params.rbs +64 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_workspace_retrieve_params.rbs +48 -0
- data/sig/anthropic/models/beta/organization/claude_tag/slack_workspace_update_params.rbs +46 -0
- data/sig/anthropic/resources/beta/messages.rbs +33 -0
- data/sig/anthropic/resources/beta/organization/analytics/cost.rbs +46 -0
- data/sig/anthropic/resources/beta/organization/analytics/usage.rbs +46 -0
- data/sig/anthropic/resources/beta/organization/analytics.rbs +4 -0
- data/sig/anthropic/resources/beta/organization/claude_tag/bundles/targets.rbs +44 -0
- data/sig/anthropic/resources/beta/organization/claude_tag/bundles.rbs +28 -0
- data/sig/anthropic/resources/beta/organization/claude_tag/slack_channels.rbs +50 -0
- data/sig/anthropic/resources/beta/organization/claude_tag/slack_workspaces.rbs +36 -0
- data/sig/anthropic/resources/beta/organization/claude_tag.rbs +17 -0
- data/sig/anthropic/resources/beta/organization.rbs +2 -0
- metadata +252 -2
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Anthropic
|
|
4
|
+
module Helpers
|
|
5
|
+
module Threads
|
|
6
|
+
# A conversation that the API keeps between requests, so that each turn sends only the
|
|
7
|
+
# messages that are new. Create one with `client.beta.messages.thread(...)`.
|
|
8
|
+
#
|
|
9
|
+
# A thread runs one turn at a time and is not safe for concurrent use.
|
|
10
|
+
class BetaMessageThread
|
|
11
|
+
THREADS_BETA = Anthropic::Models::AnthropicBeta::MESSAGE_THREADS_2026_08_12.to_s
|
|
12
|
+
NOT_FOUND_ERROR_CODE = "thread_not_found"
|
|
13
|
+
# A `continue` rejected with one of these is sent again as a `create`.
|
|
14
|
+
REPLAY_ERROR_CODES = Set[NOT_FOUND_ERROR_CODE, "thread_already_continued", "thread_continue_in_flight"].freeze
|
|
15
|
+
UNSUPPORTED_REQUEST_ERROR_CODE = "thread_unsupported_request"
|
|
16
|
+
UNSUPPORTED_REQUEST_BEHAVIORS = Set[:error, :continue_unthreaded].freeze
|
|
17
|
+
|
|
18
|
+
# How the next turn relates to what the API holds. It is always exactly one of these.
|
|
19
|
+
#
|
|
20
|
+
# The next turn starts a new thread with the whole history. `after_not_found` is whether it
|
|
21
|
+
# does so because the API answered a `continue` with `thread_not_found`.
|
|
22
|
+
Create = Data.define(:after_not_found) do
|
|
23
|
+
def initialize(after_not_found: false) = super
|
|
24
|
+
end
|
|
25
|
+
# The next turn continues from `previous_message_id` and sends what follows the recorded
|
|
26
|
+
# messages. `created_with` is the `system` and `tools` that the API keeps for the thread.
|
|
27
|
+
# `after_not_found` is that of the `Create` the thread began with, until a `continue` succeeds.
|
|
28
|
+
Continue = Data.define(:previous_message_id, :created_with, :after_not_found)
|
|
29
|
+
# Every turn sends the whole history and no `thread`.
|
|
30
|
+
Unthreaded = Data.define
|
|
31
|
+
|
|
32
|
+
# One message of the history, as the API receives it and frozen.
|
|
33
|
+
Entry = Data.define(:param, :reply_id, :partial) do
|
|
34
|
+
# @param message [Anthropic::Models::Beta::BetaUserMessageParam, Anthropic::Models::Beta::BetaAssistantMessageParam, Anthropic::Models::Beta::BetaSystemMessageParam, Anthropic::Models::Beta::BetaMessage, Hash{Symbol=>Object}]
|
|
35
|
+
def self.given(message) = build(message, reply_id: nil, partial: false)
|
|
36
|
+
|
|
37
|
+
# @param reply [Anthropic::Models::Beta::BetaMessage] a reply that a turn of the thread received
|
|
38
|
+
# @param partial [Boolean] whether its stream ended before `message_stop`
|
|
39
|
+
def self.received(reply, partial: false) = build(reply, reply_id: reply.id, partial:)
|
|
40
|
+
|
|
41
|
+
def self.build(message, **)
|
|
42
|
+
message = {role: :assistant, content: message.content} if message.is_a?(Anthropic::Models::Beta::BetaMessage)
|
|
43
|
+
param = Anthropic::Internal::Type::Converter.dump(Anthropic::Models::Beta::BetaMessageParam, message)
|
|
44
|
+
new(param: Anthropic::Internal::Util.deep_frozen_copy(param), **)
|
|
45
|
+
end
|
|
46
|
+
private_class_method :new, :[], :build
|
|
47
|
+
|
|
48
|
+
# A typed message or block has its `role` or `type` last, and a Hash has it where the caller put it.
|
|
49
|
+
#
|
|
50
|
+
# @return [Hash{String=>Object}] two messages are sent alike exactly when these are equal
|
|
51
|
+
def wire = JSON.parse(param.to_json)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# One request of a turn: the params for `create`, its `system_` and `tools` as given and as
|
|
55
|
+
# sent, and the classes that its reply parses into.
|
|
56
|
+
Request = Data.define(:params, :create_only, :created_with, :tools, :models)
|
|
57
|
+
|
|
58
|
+
private_constant :THREADS_BETA,
|
|
59
|
+
:NOT_FOUND_ERROR_CODE,
|
|
60
|
+
:REPLAY_ERROR_CODES,
|
|
61
|
+
:UNSUPPORTED_REQUEST_ERROR_CODE,
|
|
62
|
+
:UNSUPPORTED_REQUEST_BEHAVIORS,
|
|
63
|
+
:Create,
|
|
64
|
+
:Continue,
|
|
65
|
+
:Unthreaded,
|
|
66
|
+
:Entry,
|
|
67
|
+
:Request
|
|
68
|
+
|
|
69
|
+
# The whole history: every message that was sent, every reply, and the messages staged
|
|
70
|
+
# for the next turn.
|
|
71
|
+
#
|
|
72
|
+
# @return [Array<Hash{Symbol=>Object}>] frozen
|
|
73
|
+
def messages = @history.map(&:param).freeze
|
|
74
|
+
|
|
75
|
+
# The reply the next turn continues from, or `nil` when the next turn starts a new thread.
|
|
76
|
+
#
|
|
77
|
+
# @return [String, nil]
|
|
78
|
+
def previous_message_id = @anchor.is_a?(Continue) ? @anchor.previous_message_id : nil
|
|
79
|
+
|
|
80
|
+
# What `client.beta.messages.thread` takes to create a thread that behaves the same, with
|
|
81
|
+
# `messages` set to the whole history.
|
|
82
|
+
#
|
|
83
|
+
# @return [Hash{Symbol=>Object}] a frozen copy
|
|
84
|
+
def params
|
|
85
|
+
options = @request_options.empty? ? {} : {request_options: @request_options}
|
|
86
|
+
given = {**@fields, **options, unsupported_request_behavior: @unsupported_request_behavior}
|
|
87
|
+
Anthropic::Internal::Util.deep_frozen_copy(given).merge(messages:).freeze
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Stages messages for the next turn without sending them.
|
|
91
|
+
#
|
|
92
|
+
# @param messages [Array<Anthropic::Models::Beta::BetaUserMessageParam, Anthropic::Models::Beta::BetaAssistantMessageParam, Anthropic::Models::Beta::BetaSystemMessageParam, Anthropic::Models::Beta::BetaMessage, Hash{Symbol=>Object}>]
|
|
93
|
+
#
|
|
94
|
+
# @return [void]
|
|
95
|
+
def append(*messages)
|
|
96
|
+
messages.each { @history << Entry.given(_1) unless repeats_last_reply?(_1) }
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Changes the thread's request fields for every later turn, where `nil` removes a field. It
|
|
101
|
+
# sends no request. `system_` and `tools` cannot change once a turn has created the thread.
|
|
102
|
+
#
|
|
103
|
+
# @param params [Hash{Symbol=>Object}]
|
|
104
|
+
#
|
|
105
|
+
# @raise [ArgumentError] if `messages`, `thread` or `stream` is given
|
|
106
|
+
#
|
|
107
|
+
# @return [void]
|
|
108
|
+
def update(**params)
|
|
109
|
+
fields, options = split_params(params)
|
|
110
|
+
reject_key!(fields, :messages, "Use `#append` to add messages to a message thread.")
|
|
111
|
+
|
|
112
|
+
@fields = overlay(@fields, fields)
|
|
113
|
+
@request_options = overlay(@request_options, options)
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Returns a new, independent thread with this thread's history and request fields. It sends
|
|
118
|
+
# no request.
|
|
119
|
+
#
|
|
120
|
+
# @return [Anthropic::Helpers::Threads::BetaMessageThread]
|
|
121
|
+
def fork = dup.tap(&:start_new_thread)
|
|
122
|
+
|
|
123
|
+
# Creates a tool runner that runs over this thread. It sends no request.
|
|
124
|
+
#
|
|
125
|
+
# @param max_iterations [Integer, nil]
|
|
126
|
+
#
|
|
127
|
+
# @return [Anthropic::Helpers::Tools::Runner]
|
|
128
|
+
def tool_runner(max_iterations: nil)
|
|
129
|
+
# As in `#start_turn`.
|
|
130
|
+
history = @history.last&.partial ? @history[...-1] : @history
|
|
131
|
+
Anthropic::Helpers::Tools::Runner.new(
|
|
132
|
+
@client,
|
|
133
|
+
# The runner's params are those of its requests, and the thread applies its own behavior.
|
|
134
|
+
params: {**params.except(:unsupported_request_behavior), messages: history.map(&:param)},
|
|
135
|
+
max_iterations:,
|
|
136
|
+
thread: self
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Sends the messages staged with {#append}, followed by `messages`, as one turn and returns
|
|
141
|
+
# the reply. `params` takes the keywords of {#update} and applies to this turn only.
|
|
142
|
+
#
|
|
143
|
+
# @param messages [Array<Anthropic::Models::Beta::BetaUserMessageParam, Anthropic::Models::Beta::BetaAssistantMessageParam, Anthropic::Models::Beta::BetaSystemMessageParam, Anthropic::Models::Beta::BetaMessage, Hash{Symbol=>Object}>]
|
|
144
|
+
#
|
|
145
|
+
# @param params [Hash{Symbol=>Object}]
|
|
146
|
+
#
|
|
147
|
+
# @raise [Anthropic::Errors::Error] if another turn is in progress on this thread, or if
|
|
148
|
+
# the turn continues the thread and changes `system_` or `tools`
|
|
149
|
+
#
|
|
150
|
+
# @return [Anthropic::Models::Beta::BetaMessage]
|
|
151
|
+
def send_message(*messages, **params)
|
|
152
|
+
overrides = start_turn(messages, params)
|
|
153
|
+
begin
|
|
154
|
+
request, reply = send_request(*overrides) { @client.beta.messages.create(_1) }
|
|
155
|
+
parse_reply!(reply, request)
|
|
156
|
+
record_reply(request, reply)
|
|
157
|
+
reply
|
|
158
|
+
ensure
|
|
159
|
+
end_turn
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Sends the next turn like {#send_message} and returns the stream of the reply. The turn is
|
|
164
|
+
# in progress until the stream ends or is closed.
|
|
165
|
+
#
|
|
166
|
+
# @param messages [Array<Anthropic::Models::Beta::BetaUserMessageParam, Anthropic::Models::Beta::BetaAssistantMessageParam, Anthropic::Models::Beta::BetaSystemMessageParam, Anthropic::Models::Beta::BetaMessage, Hash{Symbol=>Object}>]
|
|
167
|
+
#
|
|
168
|
+
# @param params [Hash{Symbol=>Object}]
|
|
169
|
+
#
|
|
170
|
+
# @raise [Anthropic::Errors::Error] if another turn is in progress on this thread, or if
|
|
171
|
+
# the turn continues the thread and changes `system_` or `tools`
|
|
172
|
+
#
|
|
173
|
+
# @return [Anthropic::Streaming::MessageStream]
|
|
174
|
+
def stream(*messages, **params)
|
|
175
|
+
overrides = start_turn(messages, params)
|
|
176
|
+
begin
|
|
177
|
+
request, raw_stream = send_request(*overrides) { @client.beta.messages.stream_raw(_1) }
|
|
178
|
+
stream = Stream.new(raw_stream:, thread: self, request:)
|
|
179
|
+
ensure
|
|
180
|
+
end_turn if stream.nil?
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# @api private
|
|
185
|
+
#
|
|
186
|
+
# Replaces the request fields, the request options and the history. `messages` that begin
|
|
187
|
+
# with the recorded messages keep the thread, and the rest is staged. Any other list is
|
|
188
|
+
# staged as a whole and starts a new thread.
|
|
189
|
+
#
|
|
190
|
+
# @param params [Hash{Symbol=>Object}]
|
|
191
|
+
#
|
|
192
|
+
# @return [void]
|
|
193
|
+
def replace_params(params)
|
|
194
|
+
check_idle!
|
|
195
|
+
fields, options = split_params(params)
|
|
196
|
+
history = fields.delete(:messages).to_a.map { Entry.given(_1) }
|
|
197
|
+
if history.first(recorded.length).map(&:wire) == recorded.map(&:wire)
|
|
198
|
+
history[0, recorded.length] = recorded
|
|
199
|
+
else
|
|
200
|
+
start_new_thread
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
@fields = fields
|
|
204
|
+
@request_options = options
|
|
205
|
+
@history = history
|
|
206
|
+
nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# @api private
|
|
210
|
+
#
|
|
211
|
+
# The messages after the first `count` and after the reply to those, if one was recorded.
|
|
212
|
+
# As in {#append}, the last reply appended again does not count.
|
|
213
|
+
#
|
|
214
|
+
# @param count [Integer]
|
|
215
|
+
#
|
|
216
|
+
# @return [Array<Hash{Symbol=>Object}>]
|
|
217
|
+
def appended_after(count)
|
|
218
|
+
rest = @history.drop(count)
|
|
219
|
+
rest.shift unless rest.first&.reply_id.nil?
|
|
220
|
+
last_reply = @history.first(count).reverse_each.find { _1.param[:role].to_s == "assistant" }
|
|
221
|
+
rest.reject { _1.wire == last_reply&.wire }.map(&:param)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# @api private
|
|
225
|
+
#
|
|
226
|
+
# Makes the next turn start a new thread with the whole history.
|
|
227
|
+
#
|
|
228
|
+
# @return [void]
|
|
229
|
+
def start_new_thread
|
|
230
|
+
@anchor = Create.new unless @anchor.is_a?(Unthreaded)
|
|
231
|
+
nil
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# @api private
|
|
235
|
+
#
|
|
236
|
+
# A `continue` leaves out `system` and `tools`, so the API cannot reject a change.
|
|
237
|
+
#
|
|
238
|
+
# @param params [Hash{Symbol=>Object}]
|
|
239
|
+
#
|
|
240
|
+
# @raise [Anthropic::Errors::Error] if a next turn with `params` continues the thread and
|
|
241
|
+
# changes `system_` or `tools`
|
|
242
|
+
#
|
|
243
|
+
# @return [void]
|
|
244
|
+
def check_create_only_fields!(params)
|
|
245
|
+
refuse_change!(create_only_fields(wire_request(params.slice(:system, :system_, :tools)).first))
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# @api private
|
|
249
|
+
#
|
|
250
|
+
# Ends the turn in progress with `reply`, from which the next turn continues. The API may
|
|
251
|
+
# hold a refused turn, which a `continue` cannot remove, so such a turn ends with no reply
|
|
252
|
+
# and the next turn starts a new thread.
|
|
253
|
+
#
|
|
254
|
+
# @param request [Request]
|
|
255
|
+
#
|
|
256
|
+
# @param reply [Anthropic::Models::Beta::BetaMessage]
|
|
257
|
+
#
|
|
258
|
+
# @return [void]
|
|
259
|
+
def record_reply(request, reply)
|
|
260
|
+
if reply.stop_reason == Anthropic::Models::Beta::BetaStopReason::REFUSAL
|
|
261
|
+
start_new_thread
|
|
262
|
+
return end_turn
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
@history.insert(@turn, Entry.received(reply))
|
|
266
|
+
unless @anchor.is_a?(Unthreaded)
|
|
267
|
+
@anchor = Continue.new(
|
|
268
|
+
previous_message_id: reply.id,
|
|
269
|
+
created_with: request.created_with,
|
|
270
|
+
after_not_found: @anchor.is_a?(Create) && @anchor.after_not_found
|
|
271
|
+
)
|
|
272
|
+
# What the turn that created the thread sent is the thread's from then on.
|
|
273
|
+
@fields = {**@fields.except(:system_, :tools), **request.create_only}
|
|
274
|
+
# A thread keeps one model, so the API does not hold a reply that a fallback model wrote.
|
|
275
|
+
start_new_thread if reply.usage.iterations.to_a.any? { _1 in {type: :fallback_message} }
|
|
276
|
+
end
|
|
277
|
+
adopt_container(reply)
|
|
278
|
+
@turn = nil
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# @api private
|
|
282
|
+
#
|
|
283
|
+
# Ends a turn whose stream ended after `message_start` and before `message_stop`. The API
|
|
284
|
+
# holds either the whole reply or none of it, so the next turn starts a new thread.
|
|
285
|
+
#
|
|
286
|
+
# @param reply [Anthropic::Models::Beta::BetaMessage, nil] the part of the reply worth keeping
|
|
287
|
+
#
|
|
288
|
+
# @return [void]
|
|
289
|
+
def record_partial_reply(reply)
|
|
290
|
+
@history.insert(@turn, Entry.received(reply, partial: true)) unless reply.nil?
|
|
291
|
+
start_new_thread
|
|
292
|
+
@turn = nil
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# @api private
|
|
296
|
+
#
|
|
297
|
+
# Ends the turn in progress, if any, with no reply. The thread takes back the messages that
|
|
298
|
+
# were passed to the call.
|
|
299
|
+
#
|
|
300
|
+
# @return [void]
|
|
301
|
+
def end_turn
|
|
302
|
+
@history.slice!(@turn - @passed, @passed) unless @turn.nil?
|
|
303
|
+
@turn = nil
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# @api private
|
|
307
|
+
#
|
|
308
|
+
# @param client [Anthropic::Client]
|
|
309
|
+
#
|
|
310
|
+
# @param params [Hash{Symbol=>Object}] the fields of `create`, with `messages` as the seed
|
|
311
|
+
#
|
|
312
|
+
# @param unsupported_request_behavior [Symbol] `:error` or `:continue_unthreaded`
|
|
313
|
+
def initialize(client, params:, unsupported_request_behavior: :error)
|
|
314
|
+
unless UNSUPPORTED_REQUEST_BEHAVIORS.include?(unsupported_request_behavior)
|
|
315
|
+
raise ArgumentError.new(
|
|
316
|
+
"`unsupported_request_behavior` must be `:error` or `:continue_unthreaded`, " \
|
|
317
|
+
"got #{unsupported_request_behavior.inspect}"
|
|
318
|
+
)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
@client = client
|
|
322
|
+
@unsupported_request_behavior = unsupported_request_behavior
|
|
323
|
+
@fields, @request_options = split_params(params)
|
|
324
|
+
@history = @fields.delete(:messages).to_a.map { Entry.given(_1) }
|
|
325
|
+
@anchor = Create.new
|
|
326
|
+
# The index in the history at which the reply of the turn in progress goes, `nil` when none is.
|
|
327
|
+
@turn = nil
|
|
328
|
+
# How many of the messages before that index were passed to the call that started the turn.
|
|
329
|
+
@passed = 0
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
private
|
|
333
|
+
|
|
334
|
+
def initialize_copy(source)
|
|
335
|
+
super
|
|
336
|
+
@history = @history.dup
|
|
337
|
+
@turn = nil
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# @return [Array(Hash{Symbol=>Object}, Hash{Symbol=>Object})] the fields and the request options
|
|
341
|
+
def split_params(params)
|
|
342
|
+
fields = params.to_h.transform_keys(&:to_sym)
|
|
343
|
+
reject_key!(fields, :thread, "The message thread sets `thread` for each request itself.")
|
|
344
|
+
reject_key!(fields, :stream, "Use `#stream` to stream a turn of a message thread.")
|
|
345
|
+
# `create` takes the system prompt as `system_`; one name keeps an override from sending both.
|
|
346
|
+
fields[:system_] = fields.delete(:system) if fields.key?(:system)
|
|
347
|
+
|
|
348
|
+
options = Anthropic::Internal::Util.coerce_hash!(fields.delete(:request_options)).to_h
|
|
349
|
+
[fields, options.transform_keys(&:to_sym)]
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def reject_key!(fields, key, hint)
|
|
353
|
+
raise ArgumentError.new("`#{key}` cannot be given here. #{hint}") if fields.key?(key)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def overlay(base, overrides)
|
|
357
|
+
overrides.each_with_object(base.dup) do |(key, value), merged|
|
|
358
|
+
value.nil? ? merged.delete(key) : merged.store(key, value)
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def repeats_last_reply?(message)
|
|
363
|
+
last = @history.last
|
|
364
|
+
return false if last&.reply_id.nil?
|
|
365
|
+
return message.id == last.reply_id if message.is_a?(Anthropic::Models::Beta::BetaMessage)
|
|
366
|
+
|
|
367
|
+
Entry.given(message).wire == last.wire
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def check_idle!
|
|
371
|
+
return if @turn.nil?
|
|
372
|
+
|
|
373
|
+
raise Anthropic::Errors::Error.new(
|
|
374
|
+
"Another turn is in progress on this message thread. Wait for it to end, or close its stream."
|
|
375
|
+
)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# @return [Array(Hash{Symbol=>Object}, Hash{Symbol=>Object})] the turn's fields and request options
|
|
379
|
+
def start_turn(messages, params)
|
|
380
|
+
check_idle!
|
|
381
|
+
fields, options = split_params(params)
|
|
382
|
+
reject_key!(fields, :messages, "Pass the messages of a turn as positional arguments.")
|
|
383
|
+
|
|
384
|
+
staged = @history.length
|
|
385
|
+
append(*messages)
|
|
386
|
+
@passed = @history.length - staged
|
|
387
|
+
# With nothing after it, a partial reply gives way to the whole reply of the same turn.
|
|
388
|
+
@history.pop if @history.last&.partial
|
|
389
|
+
@turn = @history.length
|
|
390
|
+
[fields, options]
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
# Sends the request of the turn in progress, and again for as long as the thread recovers
|
|
394
|
+
# from an error that rejected it.
|
|
395
|
+
#
|
|
396
|
+
# @return [Array(Request, Object)] the request that went through and what the block returned
|
|
397
|
+
def send_request(fields, options)
|
|
398
|
+
loop do
|
|
399
|
+
request = plan_request(fields, options)
|
|
400
|
+
begin
|
|
401
|
+
return [request, yield(request.params)]
|
|
402
|
+
rescue Anthropic::Errors::APIStatusError => e
|
|
403
|
+
raise unless recovers_from?(e)
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# @return [Request]
|
|
409
|
+
def plan_request(fields, options)
|
|
410
|
+
fields = overlay(@fields, fields)
|
|
411
|
+
wire, tools, models = wire_request(fields)
|
|
412
|
+
refuse_change!(created_with = create_only_fields(wire))
|
|
413
|
+
create_only = fields.slice(:system_, :tools)
|
|
414
|
+
# Sent as schemas, because `create` names another beta for a class. The thread reads the reply.
|
|
415
|
+
fields = {**fields.except(:output_format), **wire.slice(:tools, :output_config, :output_format)}
|
|
416
|
+
betas = [*fields[:betas], THREADS_BETA].uniq(&:to_s)
|
|
417
|
+
|
|
418
|
+
params =
|
|
419
|
+
case @anchor
|
|
420
|
+
in Create
|
|
421
|
+
{**fields, betas:, thread: {type: :create}, messages: whole_history}
|
|
422
|
+
in Continue[previous_message_id:]
|
|
423
|
+
thread = {type: :continue, previous_message_id:}
|
|
424
|
+
{**fields.except(:system_, :tools), betas:, thread:, messages: messages.drop(recorded.length)}
|
|
425
|
+
in Unthreaded
|
|
426
|
+
{**fields, messages: whole_history}
|
|
427
|
+
end
|
|
428
|
+
options = overlay(@request_options, options)
|
|
429
|
+
headers = options[:extra_headers].to_h
|
|
430
|
+
helpers = StainlessHelperHeader.merged_value(headers, StainlessHelperHeader::MESSAGE_THREAD)
|
|
431
|
+
params[:request_options] = {**options, extra_headers: {**headers, StainlessHelperHeader::HEADER => helpers}}
|
|
432
|
+
|
|
433
|
+
Request.new(params:, create_only:, created_with:, tools:, models:)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# The messages that were sent and answered: those up to the last reply that a turn received.
|
|
437
|
+
#
|
|
438
|
+
# @return [Array<Entry>]
|
|
439
|
+
def recorded = @history.take((@history.rindex(&:reply_id) || -1) + 1)
|
|
440
|
+
|
|
441
|
+
# The history as a request that sends all of it carries it. The cache breakpoints of the
|
|
442
|
+
# recorded messages add up over the turns, so those messages go without them. The other
|
|
443
|
+
# messages go as given.
|
|
444
|
+
#
|
|
445
|
+
# @return [Array<Hash{Symbol=>Object}>]
|
|
446
|
+
def whole_history
|
|
447
|
+
sent_before = recorded.map { without_cache_control(_1.param) }
|
|
448
|
+
sent_before + messages.drop(sent_before.length)
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
# Enters only the keys that lead to a marker. Any other value may hold any key, so it is kept whole.
|
|
452
|
+
def without_cache_control(value)
|
|
453
|
+
return value unless value.is_a?(Hash)
|
|
454
|
+
|
|
455
|
+
value.except(:cache_control, "cache_control").to_h do |key, nested|
|
|
456
|
+
next [key, nested] unless %w[content source tool definition tool_references].include?(key.to_s)
|
|
457
|
+
|
|
458
|
+
[key, nested.is_a?(Array) ? nested.map { without_cache_control(_1) } : without_cache_control(nested)]
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# @return [Array(Hash{Symbol=>Object}, Hash{String=>Class}, Hash{String=>Class})] the request
|
|
463
|
+
# as the API would receive it, and the classes that its tool inputs and output parse into
|
|
464
|
+
def wire_request(fields)
|
|
465
|
+
wire, = Anthropic::Models::Beta::MessageCreateParams.dump_request(fields)
|
|
466
|
+
tools, models = Anthropic::Helpers::Messages.distill_input_schema_models!(wire, strict: nil, is_beta: true)
|
|
467
|
+
[wire, tools, models]
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
def create_only_fields(wire) = {system_: wire[:system], tools: wire[:tools]}.transform_values(&:to_json)
|
|
471
|
+
|
|
472
|
+
def refuse_change!(created_with)
|
|
473
|
+
return if !@anchor.is_a?(Continue) || created_with == @anchor.created_with
|
|
474
|
+
|
|
475
|
+
changed = created_with.reject { |field, value| value == @anchor.created_with[field] }.keys
|
|
476
|
+
message =
|
|
477
|
+
"Cannot change #{changed.map { "`#{_1}`" }.join(' and ')} on a thread: the server keeps the " \
|
|
478
|
+
"`system_` and `tools` the thread was created with. To change them, start a new thread from " \
|
|
479
|
+
"`thread.params`."
|
|
480
|
+
if changed.include?(:tools)
|
|
481
|
+
message +=
|
|
482
|
+
" To add or remove tools on this thread, send `tool_addition` or `tool_removal` blocks in a " \
|
|
483
|
+
"`system` message."
|
|
484
|
+
end
|
|
485
|
+
raise Anthropic::Errors::Error.new(message)
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
# Sets `parsed` on the content blocks of `reply`, as `create` does for a request that holds
|
|
489
|
+
# the classes to parse them into.
|
|
490
|
+
def parse_reply!(reply, request)
|
|
491
|
+
reply.content.to_a.each_with_index do |block, index|
|
|
492
|
+
parsed =
|
|
493
|
+
begin
|
|
494
|
+
case block
|
|
495
|
+
in Anthropic::Models::Beta::BetaToolUseBlock[type: :tool_use] if (tool = request.tools[block.name])
|
|
496
|
+
Anthropic::Internal::Type::Converter.coerce(tool, block.input)
|
|
497
|
+
in Anthropic::Models::Beta::BetaTextBlock if (model = request.models.first&.last)
|
|
498
|
+
Anthropic::Internal::Type::Converter.coerce(model, JSON.parse(block.text, symbolize_names: true))
|
|
499
|
+
else
|
|
500
|
+
next
|
|
501
|
+
end
|
|
502
|
+
rescue StandardError => e
|
|
503
|
+
{error: e.message}
|
|
504
|
+
end
|
|
505
|
+
reply.content[index] = Anthropic::Internal::Type::Converter.coerce(block.class, {**block.to_h, parsed:})
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
# Container-bound server tools reject a request that leaves out the container the turn
|
|
510
|
+
# before it ran in, so its id is sent on later turns unless the caller named one.
|
|
511
|
+
def adopt_container(reply)
|
|
512
|
+
id = reply.container&.id
|
|
513
|
+
return if id.nil? || id.empty?
|
|
514
|
+
|
|
515
|
+
case (pinned = @fields[:container])
|
|
516
|
+
in nil
|
|
517
|
+
@fields = {**@fields, container: id}
|
|
518
|
+
in Hash | Anthropic::Internal::Type::BaseModel if pinned.to_h.transform_keys(&:to_sym)[:id].nil?
|
|
519
|
+
@fields = {**@fields, container: {**pinned.to_h, id:}}
|
|
520
|
+
else
|
|
521
|
+
nil
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# Whether the turn should be sent again because the API rejected its `thread` in a way the
|
|
526
|
+
# thread has now adjusted for.
|
|
527
|
+
def recovers_from?(error)
|
|
528
|
+
body = error.body
|
|
529
|
+
code = body.is_a?(Hash) ? body.dig(:error, :details, :error_code) : nil
|
|
530
|
+
unsupported = code == UNSUPPORTED_REQUEST_ERROR_CODE
|
|
531
|
+
not_found = code == NOT_FOUND_ERROR_CODE
|
|
532
|
+
# The API may be unable to store a conversation whose new thread it does not hold either.
|
|
533
|
+
unsupported ||= not_found && @anchor.is_a?(Continue) && @anchor.after_not_found
|
|
534
|
+
|
|
535
|
+
case @anchor
|
|
536
|
+
in Create | Continue if unsupported && @unsupported_request_behavior == :continue_unthreaded
|
|
537
|
+
@anchor = Unthreaded.new
|
|
538
|
+
in Continue if REPLAY_ERROR_CODES.include?(code)
|
|
539
|
+
@anchor = Create.new(after_not_found: not_found)
|
|
540
|
+
else
|
|
541
|
+
return false
|
|
542
|
+
end
|
|
543
|
+
true
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# @api private
|
|
547
|
+
#
|
|
548
|
+
# The stream of one turn. It tells the thread how the turn ended.
|
|
549
|
+
class Stream < Anthropic::Helpers::Streaming::MessageStream
|
|
550
|
+
# Ends the stream. When the reply has started and `message_stop` has not arrived, the
|
|
551
|
+
# thread records the part of the reply that arrived.
|
|
552
|
+
#
|
|
553
|
+
# @return [void]
|
|
554
|
+
def close
|
|
555
|
+
finish
|
|
556
|
+
@raw_stream.close
|
|
557
|
+
super
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
# @param raw_stream [Anthropic::Internal::Type::BaseStream]
|
|
561
|
+
#
|
|
562
|
+
# @param thread [Anthropic::Helpers::Threads::BetaMessageThread]
|
|
563
|
+
#
|
|
564
|
+
# @param request [Request]
|
|
565
|
+
def initialize(raw_stream:, thread:, request:)
|
|
566
|
+
@thread = thread
|
|
567
|
+
@request = request
|
|
568
|
+
@ended = false
|
|
569
|
+
@snapshot = nil
|
|
570
|
+
@finished_blocks = 0
|
|
571
|
+
super(raw_stream:, tools: request.tools, models: request.models)
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
private
|
|
575
|
+
|
|
576
|
+
def iterator
|
|
577
|
+
events = super
|
|
578
|
+
@iterator = Anthropic::Internal::Util.chain_fused(events) do |y|
|
|
579
|
+
events.each(&y)
|
|
580
|
+
ensure
|
|
581
|
+
finish
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
def build_events(event:, message_snapshot:)
|
|
586
|
+
@snapshot = message_snapshot
|
|
587
|
+
case event.type
|
|
588
|
+
in :content_block_stop
|
|
589
|
+
@finished_blocks += 1
|
|
590
|
+
in :message_stop unless @ended
|
|
591
|
+
@ended = true
|
|
592
|
+
@thread.record_reply(@request, message_snapshot)
|
|
593
|
+
else
|
|
594
|
+
nil
|
|
595
|
+
end
|
|
596
|
+
super
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
# Tells the thread, once, that the stream ended before `message_stop`.
|
|
600
|
+
def finish
|
|
601
|
+
return if @ended
|
|
602
|
+
|
|
603
|
+
@ended = true
|
|
604
|
+
case @snapshot
|
|
605
|
+
in nil
|
|
606
|
+
@thread.end_turn
|
|
607
|
+
in {stop_reason: Anthropic::Models::Beta::BetaStopReason::REFUSAL}
|
|
608
|
+
@thread.record_reply(@request, @snapshot)
|
|
609
|
+
else
|
|
610
|
+
@thread.record_partial_reply(partial_reply)
|
|
611
|
+
end
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
# The part of the reply worth keeping: the content blocks that finished, and the block
|
|
615
|
+
# after them if it is a text block with text. Any other unfinished block is dropped,
|
|
616
|
+
# because its input or signature is incomplete.
|
|
617
|
+
#
|
|
618
|
+
# @return [Anthropic::Models::Beta::BetaMessage, nil]
|
|
619
|
+
def partial_reply
|
|
620
|
+
content = @snapshot.content.to_a.first(@finished_blocks)
|
|
621
|
+
open = @snapshot.content.to_a[@finished_blocks]
|
|
622
|
+
content << open if open&.type == :text && !open.text.empty?
|
|
623
|
+
return nil if content.empty?
|
|
624
|
+
|
|
625
|
+
Anthropic::Internal::Type::Converter.coerce(
|
|
626
|
+
Anthropic::Models::Beta::BetaMessage,
|
|
627
|
+
{**@snapshot.to_h, content:}
|
|
628
|
+
)
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
private_constant :Stream
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
end
|