stackgen-sdk 0.4.0rc20__tar.gz → 0.4.0rc22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/PKG-INFO +1 -1
  2. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/_http.py +91 -5
  3. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/_version.py +2 -2
  4. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/ask.py +13 -0
  5. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/resources.py +29 -4
  6. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/subscribe.py +11 -6
  7. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/transient.py +30 -7
  8. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/webhook_ops.py +10 -1
  9. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/config.py +47 -1
  10. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/.gitignore +0 -0
  11. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/README.md +0 -0
  12. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/pyproject.toml +0 -0
  13. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/__init__.py +0 -0
  14. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/__init__.py +0 -0
  15. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/audit.py +0 -0
  16. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/integration_secrets.py +0 -0
  17. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/models.py +0 -0
  18. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/namespace.py +0 -0
  19. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/run_status.py +0 -0
  20. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/runs.py +0 -0
  21. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/sessions.py +0 -0
  22. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/steer.py +0 -0
  23. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/subscribe_frames.py +0 -0
  24. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/webhook.py +0 -0
  25. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/workflow_builder.py +0 -0
  26. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/aiden/workflow_publish.py +0 -0
  27. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/cli.py +0 -0
  28. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/client.py +0 -0
  29. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/errors.py +0 -0
  30. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/.openapi-generator/FILES +0 -0
  31. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/.openapi-generator/VERSION +0 -0
  32. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/.openapi-generator-ignore +0 -0
  33. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/__init__.py +0 -0
  34. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/api/__init__.py +0 -0
  35. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/api/aiden_api.py +0 -0
  36. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/api/sre_api.py +0 -0
  37. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/api/vault_api.py +0 -0
  38. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/api_client.py +0 -0
  39. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/api_response.py +0 -0
  40. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/configuration.py +0 -0
  41. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/exceptions.py +0 -0
  42. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/__init__.py +0 -0
  43. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/activate_break_glass_request.py +0 -0
  44. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_app_mcp_binding.py +0 -0
  45. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_health_check.py +0 -0
  46. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_health_response.py +0 -0
  47. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_info.py +0 -0
  48. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_lifecycle_status.py +0 -0
  49. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_model_config.py +0 -0
  50. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_schedule.py +0 -0
  51. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/agent_status.py +0 -0
  52. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_analysis_status.py +0 -0
  53. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_attention.py +0 -0
  54. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_categorization_summary.py +0 -0
  55. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_role.py +0 -0
  56. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_sort_by.py +0 -0
  57. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_status.py +0 -0
  58. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_summary.py +0 -0
  59. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_sync_run_status.py +0 -0
  60. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/alert_v1.py +0 -0
  61. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/approval_item.py +0 -0
  62. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/artifact_info.py +0 -0
  63. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ask_execution_mode.py +0 -0
  64. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ask_guild_request.py +0 -0
  65. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ask_guild_route_decision.py +0 -0
  66. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ask_guild_route_response.py +0 -0
  67. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ask_guild_start_response.py +0 -0
  68. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/attach_policy_request.py +0 -0
  69. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/audit_event.py +0 -0
  70. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/audit_event_list_response.py +0 -0
  71. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/audit_facets.py +0 -0
  72. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/auto_approve_tool_rule.py +0 -0
  73. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/autonomy_budget_config.py +0 -0
  74. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/autonomy_budget_snapshot.py +0 -0
  75. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/autonomy_budget_tier.py +0 -0
  76. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/autonomy_budget_tier_reason.py +0 -0
  77. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/break_glass_state.py +0 -0
  78. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/candidate_type.py +0 -0
  79. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/chat_channel_selector.py +0 -0
  80. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/chat_subscription.py +0 -0
  81. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/chat_subscription_list_response.py +0 -0
  82. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/chat_subscription_target_type.py +0 -0
  83. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/chat_subscription_trigger_type.py +0 -0
  84. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/combining_algorithm.py +0 -0
  85. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/combining_algorithm_request.py +0 -0
  86. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/container_image.py +0 -0
  87. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/cost_band.py +0 -0
  88. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_chat_subscription_request.py +0 -0
  89. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_document_request.py +0 -0
  90. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_knowledge_base_request.py +0 -0
  91. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_policy_request.py +0 -0
  92. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_remote_runner_request.py +0 -0
  93. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_remote_runner_response.py +0 -0
  94. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_schedule_request.py +0 -0
  95. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_skill_companion_file.py +0 -0
  96. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_skill_request.py +0 -0
  97. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/create_webhook_request.py +0 -0
  98. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/dag_edge.py +0 -0
  99. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/dag_node.py +0 -0
  100. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/diary_compression.py +0 -0
  101. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/diary_config.py +0 -0
  102. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/discovered_tool.py +0 -0
  103. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/document_ingest_status.py +0 -0
  104. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/document_ingest_workflow_status.py +0 -0
  105. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/document_processing_status.py +0 -0
  106. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/duration_band.py +0 -0
  107. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/entity_ref.py +0 -0
  108. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/error_response.py +0 -0
  109. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/eval_config.py +0 -0
  110. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/evaluate_policy_request.py +0 -0
  111. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/evaluate_policy_response.py +0 -0
  112. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/execution_list_item.py +0 -0
  113. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/execution_meta.py +0 -0
  114. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/execution_structured_output.py +0 -0
  115. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/execution_tool_call.py +0 -0
  116. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/execution_tool_call_list.py +0 -0
  117. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/external_secret_reference.py +0 -0
  118. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/fork_session_request.py +0 -0
  119. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/git_config.py +0 -0
  120. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/guild_integration.py +0 -0
  121. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/guild_json_error.py +0 -0
  122. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/guild_platform_config.py +0 -0
  123. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/hal_guard_config.py +0 -0
  124. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/health_check_status.py +0 -0
  125. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/hitl_config.py +0 -0
  126. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ingested_document.py +0 -0
  127. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/ingested_document1.py +0 -0
  128. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_availability_reason.py +0 -0
  129. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_availability_status.py +0 -0
  130. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_mcp_auth_promotion.py +0 -0
  131. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_remote_runner.py +0 -0
  132. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_scope.py +0 -0
  133. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_sidecar_launch.py +0 -0
  134. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_test_result.py +0 -0
  135. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/integration_type_info.py +0 -0
  136. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigate_alert_request.py +0 -0
  137. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigate_response.py +0 -0
  138. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation.py +0 -0
  139. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_evidence.py +0 -0
  140. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_evidence_kind.py +0 -0
  141. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_evidence_source.py +0 -0
  142. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_hypothesis.py +0 -0
  143. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_plain_summary.py +0 -0
  144. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_prior_incident.py +0 -0
  145. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_recommended_next_step.py +0 -0
  146. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_ref.py +0 -0
  147. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_status.py +0 -0
  148. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_structured_hypothesis_entry.py +0 -0
  149. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_structured_limitation_entry.py +0 -0
  150. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_structured_rca.py +0 -0
  151. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/investigation_triage_metadata.py +0 -0
  152. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/judge_execution_request.py +0 -0
  153. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/key_definition_type.py +0 -0
  154. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/knowledge_base.py +0 -0
  155. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/knowledge_config.py +0 -0
  156. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/knowledge_item.py +0 -0
  157. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/knowledge_item_backend.py +0 -0
  158. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/knowledge_item_operation.py +0 -0
  159. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/knowledge_type.py +0 -0
  160. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/list_alerts_response.py +0 -0
  161. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/list_investigations_response.py +0 -0
  162. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/list_remote_runner_tasks_response.py +0 -0
  163. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/list_remote_runners_response.py +0 -0
  164. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/llm_provider_type.py +0 -0
  165. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/metadata.py +0 -0
  166. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config.py +0 -0
  167. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_circuit_breaker.py +0 -0
  168. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_concurrency.py +0 -0
  169. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_context_mode.py +0 -0
  170. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_context_mode_per_tool_value.py +0 -0
  171. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_metrics.py +0 -0
  172. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_rate_limit.py +0 -0
  173. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_retry.py +0 -0
  174. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_sanitize.py +0 -0
  175. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_timeout.py +0 -0
  176. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_tracing.py +0 -0
  177. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/middleware_config_validation.py +0 -0
  178. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/model_pricing.py +0 -0
  179. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/model_provider_config.py +0 -0
  180. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/navigation_mode.py +0 -0
  181. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/o_auth_support.py +0 -0
  182. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/owner_type.py +0 -0
  183. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/pagination.py +0 -0
  184. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/persona_variant_config.py +0 -0
  185. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/pii_redaction_config.py +0 -0
  186. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/pii_regex_rule.py +0 -0
  187. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy.py +0 -0
  188. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input.py +0 -0
  189. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_agent.py +0 -0
  190. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_approver.py +0 -0
  191. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_environment.py +0 -0
  192. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_principal.py +0 -0
  193. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_project_membership.py +0 -0
  194. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_requester.py +0 -0
  195. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_input_tool.py +0 -0
  196. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_evaluation_outcome.py +0 -0
  197. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/policy_type.py +0 -0
  198. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/qualified_candidate.py +0 -0
  199. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/rca_config.py +0 -0
  200. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/reasoning_effort_setting.py +0 -0
  201. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/register_agent_request.py +0 -0
  202. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/registered_model.py +0 -0
  203. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/remote_runner_info.py +0 -0
  204. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/remote_runner_task_info.py +0 -0
  205. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/resolve_approval_request.py +0 -0
  206. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/run_workflow_request.py +0 -0
  207. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/run_workflow_response.py +0 -0
  208. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/runbook_config.py +0 -0
  209. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/runner_capability.py +0 -0
  210. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/runner_status.py +0 -0
  211. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/runtime_approval_binding.py +0 -0
  212. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/runtime_approval_item.py +0 -0
  213. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/scan_finding.py +0 -0
  214. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/schedule_history.py +0 -0
  215. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/schedule_run_list_response.py +0 -0
  216. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/schedule_run_status.py +0 -0
  217. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/schedule_source.py +0 -0
  218. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/schedule_target_type.py +0 -0
  219. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/secret.py +0 -0
  220. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/secret_sub_category.py +0 -0
  221. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session.py +0 -0
  222. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_activity_status.py +0 -0
  223. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_export.py +0 -0
  224. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_export_part.py +0 -0
  225. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_export_part_kind.py +0 -0
  226. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_list_response.py +0 -0
  227. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_responder_kind.py +0 -0
  228. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/session_summary.py +0 -0
  229. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/sidecar_health_probes.py +0 -0
  230. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/signal_severity.py +0 -0
  231. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/skill.py +0 -0
  232. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/skill_file.py +0 -0
  233. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/skill_summary.py +0 -0
  234. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/stage_binding.py +0 -0
  235. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/stage_expectation.py +0 -0
  236. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/start_ask_guild200_response.py +0 -0
  237. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/start_chat_json_body.py +0 -0
  238. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/start_chat_response.py +0 -0
  239. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/subagent_spawn_contract.py +0 -0
  240. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/supported_formats.py +0 -0
  241. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/supported_formats_keys_inner.py +0 -0
  242. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/sync_response.py +0 -0
  243. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/task_error_category.py +0 -0
  244. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/task_status.py +0 -0
  245. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/terminate_session_response.py +0 -0
  246. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/toggle_chat_subscription_request.py +0 -0
  247. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/trace_dag_response.py +0 -0
  248. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/trigger_schedule202_response.py +0 -0
  249. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/trigger_webhook202_response.py +0 -0
  250. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/update_agent_request.py +0 -0
  251. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/update_chat_subscription_request.py +0 -0
  252. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/update_secret_by_id_request.py +0 -0
  253. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/upsert_integration_request.py +0 -0
  254. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/version_status.py +0 -0
  255. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/webhook.py +0 -0
  256. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/webhook_run.py +0 -0
  257. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/webhook_run_detail.py +0 -0
  258. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/webhook_run_list_response.py +0 -0
  259. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow.py +0 -0
  260. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_metadata.py +0 -0
  261. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_output_contract.py +0 -0
  262. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_run_expectations.py +0 -0
  263. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_stage.py +0 -0
  264. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_tool_middleware.py +0 -0
  265. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_tool_middleware_circuit_breaker.py +0 -0
  266. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_tool_middleware_concurrency.py +0 -0
  267. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_trigger.py +0 -0
  268. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/models/workflow_trigger_type.py +0 -0
  269. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/generated/rest.py +0 -0
  270. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/logging.py +0 -0
  271. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/orgs/__init__.py +0 -0
  272. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/orgs/namespace.py +0 -0
  273. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/sre/__init__.py +0 -0
  274. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/sre/namespace.py +0 -0
  275. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/vault/__init__.py +0 -0
  276. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/vault/metadata.py +0 -0
  277. {stackgen_sdk-0.4.0rc20 → stackgen_sdk-0.4.0rc22}/src/stackgen/vault/namespace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stackgen-sdk
3
- Version: 0.4.0rc20
3
+ Version: 0.4.0rc22
4
4
  Summary: StackGen SDK — Aiden, SRE, and Vault from one client
5
5
  Project-URL: Homepage, https://appcd-dev.github.io/stackgen-sdk/
6
6
  Project-URL: Documentation, https://appcd-dev.github.io/stackgen-sdk/
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import json
6
+ import os
6
7
  import socket
7
8
  import ssl
8
9
  import time
@@ -34,9 +35,40 @@ def _is_timeout_failure(err: BaseException) -> bool:
34
35
  return "timed out" in text
35
36
 
36
37
 
38
+ DEFAULT_TRANSIENT_RETRY_BUDGET_MS = 120_000
39
+ TRANSIENT_RETRY_MAX_BACKOFF_SECONDS = 15.0
40
+
41
+
37
42
  def is_retryable_http_status(status: int) -> bool:
38
- """GET statuses that self-heal: rate limit and any 5xx (rollout blips, gateway errors)."""
39
- return status == 429 or 500 <= status <= 599
43
+ """Statuses that self-heal: rate limit and any 5xx (rollout blips, gateway errors)."""
44
+ return status == 429 or status == 499 or 500 <= status <= 599
45
+
46
+
47
+ def is_gateway_outage_status(status: int) -> bool:
48
+ """Gateway / edge outage statuses that get a time-budgeted retry."""
49
+ return status in (502, 503, 504)
50
+
51
+
52
+ def resolve_transient_retry_budget_ms(override: float | int | None = None) -> int:
53
+ """Resolve the gateway-outage retry budget (ms)."""
54
+ if override is not None:
55
+ value = float(override)
56
+ if value < 0 or value != value: # NaN check
57
+ raise ValueError("transient_retry_budget_ms must be a non-negative number")
58
+ return int(value)
59
+ raw = os.environ.get("STACKGEN_TRANSIENT_RETRY_BUDGET_MS", "").strip()
60
+ if raw:
61
+ try:
62
+ parsed = float(raw)
63
+ except ValueError:
64
+ parsed = -1
65
+ if parsed >= 0:
66
+ return int(parsed)
67
+ return DEFAULT_TRANSIENT_RETRY_BUDGET_MS
68
+
69
+
70
+ def is_idempotent_http_method(method: str) -> bool:
71
+ return method.upper() in {"GET", "HEAD", "PUT", "DELETE"}
40
72
 
41
73
 
42
74
  def is_transient_http_error(err: BaseException) -> bool:
@@ -48,6 +80,15 @@ def is_transient_http_error(err: BaseException) -> bool:
48
80
  return is_retryable_http_status(err.status_code)
49
81
 
50
82
 
83
+ def is_gateway_outage_error(err: BaseException) -> bool:
84
+ """True for gateway 502/503/504 or statusless transport HttpError."""
85
+ if not isinstance(err, HttpError):
86
+ return False
87
+ if err.status_code is None:
88
+ return True
89
+ return is_gateway_outage_status(err.status_code)
90
+
91
+
51
92
  def http_status_snippet(err: BaseException | None) -> str:
52
93
  """Label fragment for TimeoutError / subscribe snippets."""
53
94
  if isinstance(err, HttpError) and err.status_code is not None:
@@ -71,8 +112,13 @@ def request(
71
112
  expect_json: bool = True,
72
113
  retries: int = 3,
73
114
  timeout_seconds: float | None = None,
115
+ transient_retry_budget_ms: float | int | None = None,
74
116
  ) -> Any:
75
- """Bearer HTTP call with bounded retries on transient GET failures.
117
+ """Bearer HTTP call with retries on transient failures for idempotent methods.
118
+
119
+ Gateway 502/503/504 and network errors retry until
120
+ ``transient_retry_budget_ms`` elapses (default 120s). Other retryable
121
+ statuses use the short ``retries`` attempt budget. POST/PATCH fail fast.
76
122
 
77
123
  ``timeout_seconds`` is an optional per-call abort budget. When the deadline
78
124
  expires, raises :class:`~stackgen.errors.TimeoutError`. Omit to wait until
@@ -82,11 +128,33 @@ def request(
82
128
  not isinstance(timeout_seconds, (int, float)) or timeout_seconds <= 0
83
129
  ):
84
130
  raise ValueError("timeout_seconds must be a positive number of seconds")
131
+ method = method.upper()
132
+ budget_ms = resolve_transient_retry_budget_ms(transient_retry_budget_ms)
133
+ idempotent = is_idempotent_http_method(method)
85
134
  headers = {"Authorization": f"Bearer {token}"}
86
135
  if content_type:
87
136
  headers["Content-Type"] = content_type
88
137
 
138
+ started = time.monotonic()
89
139
  attempt = 0
140
+ announced_outage = False
141
+
142
+ def within_outage_budget() -> bool:
143
+ return budget_ms > 0 and (time.monotonic() - started) * 1000 < budget_ms
144
+
145
+ def announce_outage(status: object) -> None:
146
+ nonlocal announced_outage
147
+ if announced_outage:
148
+ return
149
+ announced_outage = True
150
+ log_http_retry(
151
+ method,
152
+ url,
153
+ status=f"outage:{status}",
154
+ attempt=attempt,
155
+ retries=retries,
156
+ )
157
+
90
158
  while True:
91
159
  attempt += 1
92
160
  log_http_request(method, url, attempt=attempt)
@@ -107,7 +175,18 @@ def request(
107
175
  except urllib.error.HTTPError as err:
108
176
  detail = err.read().decode("utf-8", errors="replace")
109
177
  log_http_response(method, url, status=err.code, attempt=attempt)
110
- if method == "GET" and is_retryable_http_status(err.code) and attempt < retries:
178
+ if (
179
+ idempotent
180
+ and is_gateway_outage_status(err.code)
181
+ and within_outage_budget()
182
+ ):
183
+ announce_outage(err.code)
184
+ log_http_retry(
185
+ method, url, status=err.code, attempt=attempt, retries=retries
186
+ )
187
+ time.sleep(min(2**min(attempt, 4), TRANSIENT_RETRY_MAX_BACKOFF_SECONDS))
188
+ continue
189
+ if idempotent and is_retryable_http_status(err.code) and attempt < retries:
111
190
  log_http_retry(
112
191
  method, url, status=err.code, attempt=attempt, retries=retries
113
192
  )
@@ -128,7 +207,14 @@ def request(
128
207
  if isinstance(err, (socket.timeout, TimeoutError)):
129
208
  raise HttpError(f"{method} {url} -> {err}") from err
130
209
  log_http_response(method, url, status=None, attempt=attempt)
131
- if method == "GET" and attempt < retries:
210
+ if idempotent and within_outage_budget():
211
+ announce_outage("network_error")
212
+ log_http_retry(
213
+ method, url, status="network_error", attempt=attempt, retries=retries
214
+ )
215
+ time.sleep(min(2**min(attempt, 4), TRANSIENT_RETRY_MAX_BACKOFF_SECONDS))
216
+ continue
217
+ if idempotent and attempt < retries:
132
218
  log_http_retry(
133
219
  method, url, status="network_error", attempt=attempt, retries=retries
134
220
  )
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.4.0rc20'
22
- __version_tuple__ = version_tuple = (0, 4, 0, 'rc20')
21
+ __version__ = version = '0.4.0rc22'
22
+ __version_tuple__ = version_tuple = (0, 4, 0, 'rc22')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -147,6 +147,19 @@ class AskArtifactJourney:
147
147
  "Ask requires additional inputs before execution can start: "
148
148
  f"{inputs_required}"
149
149
  )
150
+ agent = ""
151
+ for ref in entity_refs or []:
152
+ if isinstance(ref, dict) and ref.get("type") == "agent":
153
+ agent = str(ref.get("name") or "")
154
+ break
155
+ self._config.emit_session_started(
156
+ {
157
+ "kind": "ask",
158
+ "session_id": data.get("session_id") or data.get("sessionId"),
159
+ "trace_id": data.get("trace_id") or data.get("traceId"),
160
+ "agent": agent or None,
161
+ }
162
+ )
150
163
  return data
151
164
 
152
165
  def wait_for_execution(self, trace_id: str) -> dict[str, Any]:
@@ -58,7 +58,11 @@ class AidenResources:
58
58
  )
59
59
 
60
60
  def _get(self, path: str, params: dict[str, Any] | None = None) -> Any:
61
- return _http.request(self._url(path, params), self._config.api_token)
61
+ return _http.request(
62
+ self._url(path, params),
63
+ self._config.api_token,
64
+ transient_retry_budget_ms=self._config.transient_retry_budget_ms,
65
+ )
62
66
 
63
67
  def _send(
64
68
  self,
@@ -67,7 +71,10 @@ class AidenResources:
67
71
  body: Any | None = None,
68
72
  params: dict[str, Any] | None = None,
69
73
  ) -> Any:
70
- kwargs: dict[str, Any] = {"method": method}
74
+ kwargs: dict[str, Any] = {
75
+ "method": method,
76
+ "transient_retry_budget_ms": self._config.transient_retry_budget_ms,
77
+ }
71
78
  if body is not None:
72
79
  kwargs["body"] = json.dumps(body).encode("utf-8")
73
80
  kwargs["content_type"] = "application/json"
@@ -330,10 +337,19 @@ class AidenResources:
330
337
  return _http.as_list(self._get("/tools", params))
331
338
 
332
339
  def start_agent_chat(self, agent_name: str, body: dict[str, Any]) -> dict[str, Any]:
333
- return _as_object(
340
+ record = _as_object(
334
341
  self._send(f"/agents/{agent_name}/chat/start", "POST", body),
335
342
  "startAgentChat",
336
343
  )
344
+ self._config.emit_session_started(
345
+ {
346
+ "kind": "chat",
347
+ "session_id": record.get("session_id") or record.get("sessionId"),
348
+ "trace_id": record.get("trace_id") or record.get("traceId"),
349
+ "agent": agent_name,
350
+ }
351
+ )
352
+ return record
337
353
 
338
354
  def list_chat_subscriptions(self, **params: Any) -> list[dict[str, Any]]:
339
355
  return _http.as_list(self._get("/platforms/chat/subscriptions", params))
@@ -391,9 +407,18 @@ class AidenResources:
391
407
  return _as_object(self._send(f"/workflows/{name}", "DELETE"), "deleteWorkflow")
392
408
 
393
409
  def run_workflow(self, name: str, body: dict[str, Any] | None = None) -> dict[str, Any]:
394
- return _as_object(
410
+ record = _as_object(
395
411
  self._send(f"/workflows/{name}/run", "POST", body or {}), "runWorkflow"
396
412
  )
413
+ self._config.emit_session_started(
414
+ {
415
+ "kind": "workflow",
416
+ "session_id": record.get("session_id") or record.get("sessionId"),
417
+ "trace_id": record.get("trace_id") or record.get("traceId"),
418
+ "name": name,
419
+ }
420
+ )
421
+ return record
397
422
 
398
423
  def create_knowledge_base(self, body: dict[str, Any]) -> dict[str, Any]:
399
424
  return _as_object(
@@ -59,16 +59,21 @@ class ExecutionSubscribe:
59
59
  chunks: list[str] = []
60
60
  reconnects = 0
61
61
  last_open_failure = ""
62
+ outage_budget_ms = int(getattr(self._config, "transient_retry_budget_ms", 0) or 0)
63
+
64
+ def can_reconnect(count: int) -> bool:
65
+ elapsed_ms = (time.monotonic() - started) * 1000
66
+ return count < SUBSCRIBE_RECONNECT_MAX or (
67
+ outage_budget_ms > 0 and elapsed_ms < outage_budget_ms
68
+ )
62
69
 
63
70
  while remaining_ms() > 100:
64
71
  opened = self._open_stream(trace_id, remaining_ms())
65
72
  if opened["kind"] == "http":
66
73
  label = transient_status_label(opened["status"])
67
74
  last_open_failure = label
68
- if (
69
- not is_transient_status(opened["status"])
70
- or reconnects >= SUBSCRIBE_RECONNECT_MAX
71
- ):
75
+ status = opened["status"]
76
+ if not is_transient_status(status) or not can_reconnect(reconnects):
72
77
  return self._fail_open(event_count, reconnects, label)
73
78
  reconnects += 1
74
79
  _log.warning(
@@ -83,7 +88,7 @@ class ExecutionSubscribe:
83
88
  if opened["kind"] == "network":
84
89
  label = transient_status_label(network=True)
85
90
  last_open_failure = label
86
- if reconnects >= SUBSCRIBE_RECONNECT_MAX:
91
+ if not can_reconnect(reconnects):
87
92
  return self._fail_open(event_count, reconnects, label)
88
93
  reconnects += 1
89
94
  _log.warning(
@@ -114,7 +119,7 @@ class ExecutionSubscribe:
114
119
  raise SdkTimeoutError(
115
120
  "subscribeExecution", int(timeout_ms / 1000)
116
121
  )
117
- if pass_result["dropped"] and reconnects < SUBSCRIBE_RECONNECT_MAX:
122
+ if pass_result["dropped"] and can_reconnect(reconnects):
118
123
  reconnects += 1
119
124
  continue
120
125
  break
@@ -8,6 +8,9 @@ Domain rules (not HTTP mechanics):
8
8
  - Only *idempotent* mutations may use :func:`retry_idempotent_op`. Today that
9
9
  is ``terminate_session`` (Guild persists cancel intent; empty sessions return
10
10
  200). Webhook/workflow starts are *not* idempotent — do not retry them here.
11
+ - Gateway 502/503/504 (and statusless transport errors) keep retrying until
12
+ the configured outage budget elapses; other transient statuses stay on the
13
+ short attempt budget so application 500s remain fail-fast.
11
14
  """
12
15
 
13
16
  from __future__ import annotations
@@ -23,7 +26,7 @@ T = TypeVar("T")
23
26
  # How many times a subscribe stream may reopen after EOF or a blip fetch.
24
27
  SUBSCRIBE_RECONNECT_MAX = 3
25
28
 
26
- # Bounded attempts for an idempotent mutation (terminate).
29
+ # Bounded attempts for an idempotent mutation (terminate) on non-gateway blips.
27
30
  IDEMPOTENT_MUTATION_ATTEMPTS = 3
28
31
 
29
32
  # Backoff base (seconds) between idempotent mutation attempts: 0.5, 1.0, …
@@ -52,22 +55,42 @@ def retry_idempotent_op(
52
55
  *,
53
56
  attempts: int = IDEMPOTENT_MUTATION_ATTEMPTS,
54
57
  backoff_seconds: float = IDEMPOTENT_MUTATION_BACKOFF_SECONDS,
58
+ budget_ms: float | int | None = None,
55
59
  sleep: Callable[[float], None] | None = None,
56
60
  ) -> T:
57
- """Run an idempotent operation with bounded retries on transient failures.
61
+ """Run an idempotent operation with retries on transient failures.
58
62
 
59
- Fail fast on non-transient errors. Callers must only pass ops that are safe
60
- to repeat (e.g. terminate_session).
63
+ Gateway outages (502/503/504 / transport) retry until ``budget_ms`` elapses.
64
+ Other transient statuses use the short attempt budget. Fail fast on
65
+ non-transient errors. Callers must only pass ops that are safe to repeat
66
+ (e.g. terminate_session).
61
67
  """
62
68
  sleeper = sleep or time.sleep
69
+ budget = _http.resolve_transient_retry_budget_ms(budget_ms)
70
+ started = time.monotonic()
63
71
  last_err: BaseException | None = None
64
- for attempt in range(1, attempts + 1):
72
+ attempt = 0
73
+ while True:
74
+ attempt += 1
65
75
  try:
66
76
  return op()
67
77
  except Exception as err:
68
78
  last_err = err
69
- if not is_transient_failure(err) or attempt >= attempts:
79
+ if not is_transient_failure(err):
70
80
  raise
71
- sleeper(backoff_seconds * attempt)
81
+ outage = _http.is_gateway_outage_error(err)
82
+ within_budget = budget > 0 and (time.monotonic() - started) * 1000 < budget
83
+ if outage and within_budget:
84
+ sleeper(
85
+ min(
86
+ backoff_seconds * attempt,
87
+ _http.TRANSIENT_RETRY_MAX_BACKOFF_SECONDS,
88
+ )
89
+ )
90
+ continue
91
+ if not outage and attempt < attempts:
92
+ sleeper(backoff_seconds * attempt)
93
+ continue
94
+ raise
72
95
  assert last_err is not None
73
96
  raise last_err
@@ -61,6 +61,13 @@ class WebhookOps:
61
61
  )
62
62
  if not isinstance(data, dict):
63
63
  raise StackgenError(f"unexpected trigger payload: {data!r}")
64
+ self._config.emit_session_started(
65
+ {
66
+ "kind": "webhook",
67
+ "session_id": data.get("session_id") or data.get("sessionId"),
68
+ "trace_id": data.get("trace_id") or data.get("traceId"),
69
+ }
70
+ )
64
71
  return data
65
72
 
66
73
  def get_webhook_run(self, webhook_id: str, invocation_id: str) -> dict[str, Any]:
@@ -289,7 +296,9 @@ class WebhookOps:
289
296
  raise StackgenError(f"unexpected terminate session payload: {data!r}")
290
297
  return data
291
298
 
292
- return retry_idempotent_op(once)
299
+ return retry_idempotent_op(
300
+ once, budget_ms=self._config.transient_retry_budget_ms
301
+ )
293
302
 
294
303
  def start_workflow_run(
295
304
  self,
@@ -2,8 +2,15 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import logging
5
6
  import os
6
- from dataclasses import dataclass
7
+ from collections.abc import Callable
8
+ from dataclasses import dataclass, field
9
+ from typing import Any
10
+
11
+ from stackgen._http import resolve_transient_retry_budget_ms
12
+
13
+ _log = logging.getLogger("stackgen")
7
14
 
8
15
 
9
16
  @dataclass(frozen=True)
@@ -16,6 +23,12 @@ class StackgenConfig:
16
23
 
17
24
  ``log_level`` enables the ``stackgen`` logger (``debug`` / ``info`` /
18
25
  ``warn`` / ``error`` / ``silent``). Also set via ``STACKGEN_LOG_LEVEL``.
26
+
27
+ ``transient_retry_budget_ms`` rides out gateway 502/503/504 on idempotent
28
+ calls (default 120s; override with ``STACKGEN_TRANSIENT_RETRY_BUDGET_MS``).
29
+
30
+ ``on_session_started`` is called after Ask/chat/workflow/webhook starts
31
+ with ``kind``, ``session_id``, and ``trace_id`` when present.
19
32
  """
20
33
 
21
34
  base_url: str
@@ -27,6 +40,10 @@ class StackgenConfig:
27
40
  output_path: str = "session-report.md"
28
41
  poll_interval_seconds: int = 5
29
42
  timeout_seconds: int = 1800
43
+ transient_retry_budget_ms: int = field(
44
+ default_factory=lambda: resolve_transient_retry_budget_ms()
45
+ )
46
+ on_session_started: Callable[[dict[str, Any]], None] | None = None
30
47
  log_level: str = ""
31
48
 
32
49
  def __post_init__(self) -> None:
@@ -36,6 +53,35 @@ class StackgenConfig:
36
53
 
37
54
  configure_logging(level)
38
55
 
56
+ def emit_session_started(self, info: dict[str, Any]) -> None:
57
+ """Log and forward a session/trace start."""
58
+ session_id = str(info.get("session_id") or "").strip()
59
+ trace_id = str(info.get("trace_id") or "").strip()
60
+ if not session_id and not trace_id:
61
+ return
62
+ kind = str(info.get("kind") or "").strip() or "unknown"
63
+ agent = str(info.get("agent") or "").strip()
64
+ name = str(info.get("name") or "").strip()
65
+ bits = [f"kind={kind}"]
66
+ if session_id:
67
+ bits.append(f"session_id={session_id}")
68
+ if trace_id:
69
+ bits.append(f"trace_id={trace_id}")
70
+ if agent:
71
+ bits.append(f"agent={agent}")
72
+ if name:
73
+ bits.append(f"name={name}")
74
+ _log.info("session started %s", " ".join(bits))
75
+ if self.on_session_started is not None:
76
+ payload = {
77
+ **info,
78
+ "session_id": session_id or None,
79
+ "trace_id": trace_id or None,
80
+ "agent": agent or None,
81
+ "name": name or None,
82
+ }
83
+ self.on_session_started(payload)
84
+
39
85
  def mothership(self) -> str:
40
86
  """Normalized mothership URL without trailing slash or ``/guild``."""
41
87
  base = self.base_url.rstrip("/")