geny-executor 2.70.0__tar.gz → 2.71.0__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 (794) hide show
  1. {geny_executor-2.70.0 → geny_executor-2.71.0}/PKG-INFO +1 -1
  2. {geny_executor-2.70.0 → geny_executor-2.71.0}/pyproject.toml +1 -1
  3. geny_executor-2.71.0/src/geny_executor/llm_client/_failover.py +373 -0
  4. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/anthropic.py +1 -0
  5. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/base.py +71 -0
  6. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/claude_code_tokens.py +16 -3
  7. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/google.py +1 -0
  8. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/openai.py +1 -0
  9. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/responses_wire.py +1 -0
  10. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/router.py +57 -8
  11. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_account_load_balancing.py +38 -0
  12. geny_executor-2.71.0/tests/unit/test_cooldown_policy.py +198 -0
  13. geny_executor-2.71.0/tests/unit/test_images_a_model_cannot_see.py +146 -0
  14. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_client_capabilities.py +5 -0
  15. geny_executor-2.70.0/src/geny_executor/llm_client/_failover.py +0 -186
  16. {geny_executor-2.70.0 → geny_executor-2.71.0}/.gitignore +0 -0
  17. {geny_executor-2.70.0 → geny_executor-2.71.0}/LICENSE +0 -0
  18. {geny_executor-2.70.0 → geny_executor-2.71.0}/NOTICE +0 -0
  19. {geny_executor-2.70.0 → geny_executor-2.71.0}/README.md +0 -0
  20. {geny_executor-2.70.0 → geny_executor-2.71.0}/README_ko.md +0 -0
  21. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/__init__.py +0 -0
  22. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/audio/__init__.py +0 -0
  23. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/audio/stt/__init__.py +0 -0
  24. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/audio/stt/openai_compatible.py +0 -0
  25. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/audio/stt/provider.py +0 -0
  26. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/audio/stt/registry.py +0 -0
  27. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/channels/__init__.py +0 -0
  28. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/channels/built_in.py +0 -0
  29. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/channels/factory.py +0 -0
  30. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/channels/send_message_channel.py +0 -0
  31. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/channels/user_file_channel.py +0 -0
  32. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/__init__.py +0 -0
  33. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/artifact.py +0 -0
  34. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/builder.py +0 -0
  35. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/compaction.py +0 -0
  36. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/config.py +0 -0
  37. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/context_prune.py +0 -0
  38. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/diff.py +0 -0
  39. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/environment.py +0 -0
  40. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/environment_control.py +0 -0
  41. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/errors.py +0 -0
  42. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/introspection.py +0 -0
  43. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/manifest_factory.py +0 -0
  44. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/message_repair.py +0 -0
  45. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/mutation.py +0 -0
  46. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/pipeline.py +0 -0
  47. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/presets.py +0 -0
  48. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/result.py +0 -0
  49. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/schema.py +0 -0
  50. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/shared_keys.py +0 -0
  51. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/slot.py +0 -0
  52. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/snapshot.py +0 -0
  53. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/stage.py +0 -0
  54. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/state.py +0 -0
  55. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/core/token_estimate.py +0 -0
  56. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/__init__.py +0 -0
  57. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/runner.py +0 -0
  58. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/store_abc.py +0 -0
  59. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/store_impl/__init__.py +0 -0
  60. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/store_impl/file_backed.py +0 -0
  61. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/store_impl/in_memory.py +0 -0
  62. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/cron/types.py +0 -0
  63. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/events/__init__.py +0 -0
  64. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/events/bus.py +0 -0
  65. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/events/catalog.py +0 -0
  66. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/events/types.py +0 -0
  67. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/__init__.py +0 -0
  68. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/adapter.py +0 -0
  69. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/discord.py +0 -0
  70. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/factory.py +0 -0
  71. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/runner.py +0 -0
  72. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/slack.py +0 -0
  73. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/telegram.py +0 -0
  74. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/types.py +0 -0
  75. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/gateway/ws_base.py +0 -0
  76. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/__init__.py +0 -0
  77. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/ab_test.py +0 -0
  78. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/cost.py +0 -0
  79. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/models.py +0 -0
  80. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/monitor.py +0 -0
  81. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/replay.py +0 -0
  82. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/history/service.py +0 -0
  83. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/hooks/__init__.py +0 -0
  84. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/hooks/config.py +0 -0
  85. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/hooks/events.py +0 -0
  86. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/hooks/runner.py +0 -0
  87. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/__init__.py +0 -0
  88. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/_sandbox_handle.py +0 -0
  89. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/codex.py +0 -0
  90. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/credentials.py +0 -0
  91. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/local_probe.py +0 -0
  92. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/model_discovery.py +0 -0
  93. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/openai_compatible.py +0 -0
  94. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/profiles.py +0 -0
  95. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/registry.py +0 -0
  96. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/text_tool_protocol.py +0 -0
  97. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/translators/__init__.py +0 -0
  98. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/translators/_canonical.py +0 -0
  99. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/types.py +0 -0
  100. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/llm_client/vllm.py +0 -0
  101. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/__init__.py +0 -0
  102. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/_locks.py +0 -0
  103. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/_offload.py +0 -0
  104. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/_progressive.py +0 -0
  105. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/composite/__init__.py +0 -0
  106. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/composite/handles.py +0 -0
  107. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/composite/provider.py +0 -0
  108. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/composite/routing.py +0 -0
  109. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/composite/snapshot.py +0 -0
  110. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/__init__.py +0 -0
  111. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/client.py +0 -0
  112. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/google.py +0 -0
  113. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/local.py +0 -0
  114. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/openai.py +0 -0
  115. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/openai_compatible.py +0 -0
  116. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/registry.py +0 -0
  117. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/embedding/voyage.py +0 -0
  118. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/factory.py +0 -0
  119. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/facts.py +0 -0
  120. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/graph_rank.py +0 -0
  121. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/presets.py +0 -0
  122. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/provider.py +0 -0
  123. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/__init__.py +0 -0
  124. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/ephemeral.py +0 -0
  125. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/__init__.py +0 -0
  126. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/config.py +0 -0
  127. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/frontmatter.py +0 -0
  128. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/graph_edges.py +0 -0
  129. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/index_store.py +0 -0
  130. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/layout.py +0 -0
  131. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/ltm_store.py +0 -0
  132. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/notes_store.py +0 -0
  133. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/provider.py +0 -0
  134. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/snapshot.py +0 -0
  135. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/stm_store.py +0 -0
  136. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/timezone.py +0 -0
  137. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/file/vector_store.py +0 -0
  138. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/__init__.py +0 -0
  139. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/config.py +0 -0
  140. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/connection.py +0 -0
  141. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/index_store.py +0 -0
  142. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/ltm_store.py +0 -0
  143. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/notes_store.py +0 -0
  144. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/provider.py +0 -0
  145. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/schema.py +0 -0
  146. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/snapshot.py +0 -0
  147. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/stm_store.py +0 -0
  148. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/providers/sql/vector_store.py +0 -0
  149. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/retriever.py +0 -0
  150. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/rollup.py +0 -0
  151. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/strategy.py +0 -0
  152. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/vector/__init__.py +0 -0
  153. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/memory/vector/qdrant_store.py +0 -0
  154. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/notifications/__init__.py +0 -0
  155. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/notifications/registry.py +0 -0
  156. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/permission/__init__.py +0 -0
  157. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/permission/loader.py +0 -0
  158. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/permission/matrix.py +0 -0
  159. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/permission/types.py +0 -0
  160. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/py.typed +0 -0
  161. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/runtime/__init__.py +0 -0
  162. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/runtime/task_executors.py +0 -0
  163. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/runtime/task_runner.py +0 -0
  164. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/security/__init__.py +0 -0
  165. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/security/import_validator.py +0 -0
  166. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/security/script_sandbox.py +0 -0
  167. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/session/__init__.py +0 -0
  168. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/session/freshness.py +0 -0
  169. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/session/manager.py +0 -0
  170. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/session/persistence.py +0 -0
  171. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/session/session.py +0 -0
  172. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/settings/__init__.py +0 -0
  173. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/settings/loader.py +0 -0
  174. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/settings/section_registry.py +0 -0
  175. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/__init__.py +0 -0
  176. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/batch/SKILL.md +0 -0
  177. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/debug/SKILL.md +0 -0
  178. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/environment/REFERENCE.md +0 -0
  179. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/environment/SKILL.md +0 -0
  180. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/loop/SKILL.md +0 -0
  181. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/lorem-ipsum/SKILL.md +0 -0
  182. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/simplify/SKILL.md +0 -0
  183. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/skillify/SKILL.md +0 -0
  184. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/stuck/SKILL.md +0 -0
  185. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/tool-builder/REFERENCE.md +0 -0
  186. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/tool-builder/SKILL.md +0 -0
  187. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled/verify/SKILL.md +0 -0
  188. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/bundled_skills.py +0 -0
  189. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/fork.py +0 -0
  190. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/frontmatter.py +0 -0
  191. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/loader.py +0 -0
  192. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/mcp_bridge.py +0 -0
  193. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/path_match.py +0 -0
  194. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/registry.py +0 -0
  195. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/shell_blocks.py +0 -0
  196. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/skill_tool.py +0 -0
  197. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/types.py +0 -0
  198. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/skills/watcher.py +0 -0
  199. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/__init__.py +0 -0
  200. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/__init__.py +0 -0
  201. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/_helpers.py +0 -0
  202. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/cancel.py +0 -0
  203. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/clear.py +0 -0
  204. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/compact.py +0 -0
  205. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/config.py +0 -0
  206. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/context.py +0 -0
  207. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/cost.py +0 -0
  208. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/help.py +0 -0
  209. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/memory.py +0 -0
  210. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/model.py +0 -0
  211. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/preset_info.py +0 -0
  212. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/status.py +0 -0
  213. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/built_in/tasks.py +0 -0
  214. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/md_template.py +0 -0
  215. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/parser.py +0 -0
  216. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/registry.py +0 -0
  217. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/slash_commands/types.py +0 -0
  218. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/__init__.py +0 -0
  219. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/__init__.py +0 -0
  220. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/artifact/__init__.py +0 -0
  221. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/artifact/default/__init__.py +0 -0
  222. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/artifact/default/normalizers.py +0 -0
  223. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/artifact/default/stage.py +0 -0
  224. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/artifact/default/validators.py +0 -0
  225. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/interface.py +0 -0
  226. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/normalizers.py +0 -0
  227. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/stage.py +0 -0
  228. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/types.py +0 -0
  229. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s01_input/validators.py +0 -0
  230. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/__init__.py +0 -0
  231. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/artifact/__init__.py +0 -0
  232. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/artifact/default/__init__.py +0 -0
  233. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/artifact/default/compactors.py +0 -0
  234. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/artifact/default/retrievers.py +0 -0
  235. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/artifact/default/stage.py +0 -0
  236. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/artifact/default/strategies.py +0 -0
  237. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/compactors.py +0 -0
  238. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/interface.py +0 -0
  239. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/retrievers.py +0 -0
  240. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/stage.py +0 -0
  241. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/strategies.py +0 -0
  242. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s02_context/types.py +0 -0
  243. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/__init__.py +0 -0
  244. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/artifact/__init__.py +0 -0
  245. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/artifact/default/__init__.py +0 -0
  246. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/artifact/default/builders.py +0 -0
  247. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/artifact/default/stage.py +0 -0
  248. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/builders.py +0 -0
  249. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/interface.py +0 -0
  250. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/persona/__init__.py +0 -0
  251. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/persona/builder.py +0 -0
  252. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/persona/provider.py +0 -0
  253. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s03_system/stage.py +0 -0
  254. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/__init__.py +0 -0
  255. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/artifact/__init__.py +0 -0
  256. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/artifact/default/__init__.py +0 -0
  257. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/artifact/default/guards.py +0 -0
  258. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/artifact/default/stage.py +0 -0
  259. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/guards.py +0 -0
  260. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/interface.py +0 -0
  261. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/stage.py +0 -0
  262. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s04_guard/types.py +0 -0
  263. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/__init__.py +0 -0
  264. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/artifact/__init__.py +0 -0
  265. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/artifact/default/__init__.py +0 -0
  266. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/artifact/default/stage.py +0 -0
  267. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/artifact/default/strategies.py +0 -0
  268. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/interface.py +0 -0
  269. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/stage.py +0 -0
  270. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s05_cache/strategies.py +0 -0
  271. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/__init__.py +0 -0
  272. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/_translate.py +0 -0
  273. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/__init__.py +0 -0
  274. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/default/__init__.py +0 -0
  275. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/default/providers.py +0 -0
  276. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/default/retry.py +0 -0
  277. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/default/router.py +0 -0
  278. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/default/stage.py +0 -0
  279. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/default/tool_loop.py +0 -0
  280. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/google/__init__.py +0 -0
  281. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/google/providers.py +0 -0
  282. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/openai/__init__.py +0 -0
  283. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/artifact/openai/providers.py +0 -0
  284. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/interface.py +0 -0
  285. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/providers.py +0 -0
  286. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/retry.py +0 -0
  287. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/stage.py +0 -0
  288. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s06_api/types.py +0 -0
  289. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/__init__.py +0 -0
  290. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/artifact/__init__.py +0 -0
  291. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/artifact/default/__init__.py +0 -0
  292. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/artifact/default/pricing.py +0 -0
  293. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/artifact/default/stage.py +0 -0
  294. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/artifact/default/trackers.py +0 -0
  295. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/interface.py +0 -0
  296. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/pricing.py +0 -0
  297. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/stage.py +0 -0
  298. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s07_token/trackers.py +0 -0
  299. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/__init__.py +0 -0
  300. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/artifact/default/__init__.py +0 -0
  301. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/artifact/default/budget.py +0 -0
  302. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/artifact/default/processors.py +0 -0
  303. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/artifact/default/stage.py +0 -0
  304. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/interface.py +0 -0
  305. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/processors.py +0 -0
  306. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/stage.py +0 -0
  307. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s08_think/types.py +0 -0
  308. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/__init__.py +0 -0
  309. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/artifact/default/__init__.py +0 -0
  310. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/artifact/default/parsers.py +0 -0
  311. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/artifact/default/signals.py +0 -0
  312. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/artifact/default/stage.py +0 -0
  313. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/interface.py +0 -0
  314. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/parsers.py +0 -0
  315. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/signals.py +0 -0
  316. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/stage.py +0 -0
  317. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s09_parse/types.py +0 -0
  318. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/__init__.py +0 -0
  319. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/artifact/__init__.py +0 -0
  320. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/artifact/default/__init__.py +0 -0
  321. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/artifact/default/executors.py +0 -0
  322. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/artifact/default/routers.py +0 -0
  323. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/artifact/default/stage.py +0 -0
  324. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/dispatcher.py +0 -0
  325. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/executors.py +0 -0
  326. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/interface.py +0 -0
  327. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/persistence.py +0 -0
  328. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/routers.py +0 -0
  329. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/stage.py +0 -0
  330. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/state_mutation.py +0 -0
  331. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s10_tool/streaming.py +0 -0
  332. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s11_tool_review/__init__.py +0 -0
  333. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s11_tool_review/artifact/__init__.py +0 -0
  334. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s11_tool_review/artifact/default/__init__.py +0 -0
  335. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s11_tool_review/artifact/default/reviewers.py +0 -0
  336. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s11_tool_review/artifact/default/stage.py +0 -0
  337. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s11_tool_review/interface.py +0 -0
  338. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/__init__.py +0 -0
  339. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/artifact/__init__.py +0 -0
  340. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/artifact/default/__init__.py +0 -0
  341. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/artifact/default/orchestrators.py +0 -0
  342. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/artifact/default/stage.py +0 -0
  343. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/interface.py +0 -0
  344. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/orchestrators.py +0 -0
  345. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/persistent_subagent.py +0 -0
  346. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/stage.py +0 -0
  347. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/subagent_catalog.py +0 -0
  348. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/subagent_type.py +0 -0
  349. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s12_agent/types.py +0 -0
  350. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/__init__.py +0 -0
  351. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/artifact/__init__.py +0 -0
  352. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/artifact/default/__init__.py +0 -0
  353. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/artifact/default/file_backed_registry.py +0 -0
  354. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/artifact/default/policies.py +0 -0
  355. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/artifact/default/registry.py +0 -0
  356. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/artifact/default/stage.py +0 -0
  357. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/interface.py +0 -0
  358. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s13_task_registry/types.py +0 -0
  359. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/__init__.py +0 -0
  360. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/artifact/__init__.py +0 -0
  361. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/artifact/adaptive/__init__.py +0 -0
  362. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/artifact/adaptive/strategy.py +0 -0
  363. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/artifact/default/__init__.py +0 -0
  364. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/artifact/default/stage.py +0 -0
  365. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/artifact/default/strategies.py +0 -0
  366. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/interface.py +0 -0
  367. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/stage.py +0 -0
  368. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/strategies.py +0 -0
  369. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s14_evaluate/types.py +0 -0
  370. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/__init__.py +0 -0
  371. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/artifact/__init__.py +0 -0
  372. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/artifact/default/__init__.py +0 -0
  373. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/artifact/default/requesters.py +0 -0
  374. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/artifact/default/stage.py +0 -0
  375. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/artifact/default/timeouts.py +0 -0
  376. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/interface.py +0 -0
  377. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s15_hitl/types.py +0 -0
  378. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/__init__.py +0 -0
  379. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/artifact/__init__.py +0 -0
  380. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/artifact/default/__init__.py +0 -0
  381. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/artifact/default/controllers.py +0 -0
  382. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/artifact/default/stage.py +0 -0
  383. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/controllers.py +0 -0
  384. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/interface.py +0 -0
  385. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s16_loop/stage.py +0 -0
  386. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/__init__.py +0 -0
  387. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/artifact/__init__.py +0 -0
  388. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/artifact/default/__init__.py +0 -0
  389. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/artifact/default/emitters.py +0 -0
  390. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/artifact/default/stage.py +0 -0
  391. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/emitters.py +0 -0
  392. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/interface.py +0 -0
  393. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/stage.py +0 -0
  394. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s17_emit/types.py +0 -0
  395. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/__init__.py +0 -0
  396. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/_dehydrate.py +0 -0
  397. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/artifact/__init__.py +0 -0
  398. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/artifact/default/__init__.py +0 -0
  399. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/artifact/default/persistence.py +0 -0
  400. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/artifact/default/stage.py +0 -0
  401. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/artifact/default/strategies.py +0 -0
  402. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/insight.py +0 -0
  403. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/interface.py +0 -0
  404. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/persistence.py +0 -0
  405. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/stage.py +0 -0
  406. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s18_memory/strategies.py +0 -0
  407. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/__init__.py +0 -0
  408. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/artifact/__init__.py +0 -0
  409. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/artifact/default/__init__.py +0 -0
  410. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/artifact/default/importance.py +0 -0
  411. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/artifact/default/stage.py +0 -0
  412. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/artifact/default/summarizers.py +0 -0
  413. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/frequency_policy.py +0 -0
  414. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/interface.py +0 -0
  415. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s19_summarize/types.py +0 -0
  416. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/__init__.py +0 -0
  417. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/artifact/__init__.py +0 -0
  418. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/artifact/default/__init__.py +0 -0
  419. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/artifact/default/frequencies.py +0 -0
  420. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/artifact/default/persisters.py +0 -0
  421. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/artifact/default/stage.py +0 -0
  422. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/interface.py +0 -0
  423. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/restore.py +0 -0
  424. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s20_persist/types.py +0 -0
  425. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/__init__.py +0 -0
  426. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/artifact/__init__.py +0 -0
  427. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/artifact/default/__init__.py +0 -0
  428. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/artifact/default/formatters.py +0 -0
  429. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/artifact/default/multi_format.py +0 -0
  430. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/artifact/default/stage.py +0 -0
  431. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/formatters.py +0 -0
  432. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/interface.py +0 -0
  433. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/stages/s21_yield/stage.py +0 -0
  434. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/__init__.py +0 -0
  435. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/_sandbox.py +0 -0
  436. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/_ssh.py +0 -0
  437. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/adhoc.py +0 -0
  438. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/base.py +0 -0
  439. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/__init__.py +0 -0
  440. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/_path_guard.py +0 -0
  441. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/_ssh_store.py +0 -0
  442. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/_web_search_backends.py +0 -0
  443. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/agent_tool.py +0 -0
  444. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/ask_user_question_tool.py +0 -0
  445. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/atlassian_tools.py +0 -0
  446. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/audio_tools.py +0 -0
  447. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/bash_tool.py +0 -0
  448. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/browser_tools.py +0 -0
  449. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/cron_tools.py +0 -0
  450. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/dev_tools.py +0 -0
  451. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/doc_tools.py +0 -0
  452. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/edit_tool.py +0 -0
  453. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/env_tools.py +0 -0
  454. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/glob_tool.py +0 -0
  455. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/google_tools.py +0 -0
  456. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/grep_tool.py +0 -0
  457. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/mcp_wrapper_tools.py +0 -0
  458. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/notebook_edit_tool.py +0 -0
  459. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/operator_tools.py +0 -0
  460. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/plan_mode_tools.py +0 -0
  461. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/push_notification_tool.py +0 -0
  462. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/read_tool.py +0 -0
  463. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/sandbox_exec_tool.py +0 -0
  464. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/send_message_tool.py +0 -0
  465. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/ssh_tools.py +0 -0
  466. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/subagent_tools.py +0 -0
  467. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/task_tools.py +0 -0
  468. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/todo_write_tool.py +0 -0
  469. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/tool_search_tool.py +0 -0
  470. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/web_fetch_tool.py +0 -0
  471. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/web_search_tool.py +0 -0
  472. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/workspace_tools.py +0 -0
  473. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/worktree_tools.py +0 -0
  474. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/built_in/write_tool.py +0 -0
  475. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/composer.py +0 -0
  476. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/errors.py +0 -0
  477. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/__init__.py +0 -0
  478. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/adapter.py +0 -0
  479. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/credentials.py +0 -0
  480. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/errors.py +0 -0
  481. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/manager.py +0 -0
  482. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/oauth.py +0 -0
  483. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/state.py +0 -0
  484. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/mcp/uri.py +0 -0
  485. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/plugin.py +0 -0
  486. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/provider.py +0 -0
  487. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/providers.py +0 -0
  488. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/registry.py +0 -0
  489. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/sandbox.py +0 -0
  490. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/scope.py +0 -0
  491. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/tools/stage_binding.py +0 -0
  492. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/workspace/__init__.py +0 -0
  493. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/workspace/stack.py +0 -0
  494. {geny_executor-2.70.0 → geny_executor-2.71.0}/src/geny_executor/workspace/types.py +0 -0
  495. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/__init__.py +0 -0
  496. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/_fixtures/__init__.py +0 -0
  497. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/_fixtures/fake_echo_cli.py +0 -0
  498. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/_fixtures/geny_manifest_layout.json +0 -0
  499. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/_fixtures/manifest_entries.py +0 -0
  500. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/__init__.py +0 -0
  501. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/conftest.py +0 -0
  502. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/fixtures/__init__.py +0 -0
  503. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/fixtures/adapter/__init__.py +0 -0
  504. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/fixtures/adapter/adapter.py +0 -0
  505. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c1_six_layer_retrieval.py +0 -0
  506. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c2_execution_recording.py +0 -0
  507. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c3_reflection_and_promotion.py +0 -0
  508. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c4_rest_coverage.py +0 -0
  509. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c5_embedding_migration.py +0 -0
  510. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c6_session_resume.py +0 -0
  511. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_c7_adapter_parity.py +0 -0
  512. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/completeness/test_spec_loads.py +0 -0
  513. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/__init__.py +0 -0
  514. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/memory_provider_contract.py +0 -0
  515. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_embedding_clients.py +0 -0
  516. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_error_codes_stability.py +0 -0
  517. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_embedding_credentials.py +0 -0
  518. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_auto_vector.py +0 -0
  519. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_composite.py +0 -0
  520. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_composite_routing.py +0 -0
  521. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_curated_global.py +0 -0
  522. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_ephemeral.py +0 -0
  523. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_factory.py +0 -0
  524. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_file.py +0 -0
  525. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_file_layout.py +0 -0
  526. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_file_vector.py +0 -0
  527. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_sql.py +0 -0
  528. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_sql_dialect.py +0 -0
  529. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_sql_schema.py +0 -0
  530. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_provider_sql_vector.py +0 -0
  531. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_memory_vector_breaker.py +0 -0
  532. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/contract/test_stage_uniformity.py +0 -0
  533. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/integration/test_cycle_ab_cross_import.py +0 -0
  534. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/integration/test_integration.py +0 -0
  535. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/__init__.py +0 -0
  536. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/__init__.py +0 -0
  537. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/harness.py +0 -0
  538. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/test_anthropic.py +0 -0
  539. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/test_google.py +0 -0
  540. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/test_local_providers.py +0 -0
  541. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/test_openai.py +0 -0
  542. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/conformance/test_vllm.py +0 -0
  543. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/live/__init__.py +0 -0
  544. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/live/test_live_canaries.py +0 -0
  545. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/__init__.py +0 -0
  546. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_anthropic_build_kwargs.py +0 -0
  547. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_anthropic_classify.py +0 -0
  548. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_base_client.py +0 -0
  549. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_credentials.py +0 -0
  550. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_google_classify.py +0 -0
  551. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_local_probe.py +0 -0
  552. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_local_tool_repair.py +0 -0
  553. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_openai_client.py +0 -0
  554. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/llm_client/unit/test_profiles.py +0 -0
  555. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/memory/test_note_delete_propagation.py +0 -0
  556. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/__init__.py +0 -0
  557. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_account_router.py +0 -0
  558. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_adaptive_model_router.py +0 -0
  559. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_adaptive_router_configure.py +0 -0
  560. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_adaptive_thinking_budget.py +0 -0
  561. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_adhoc_providers.py +0 -0
  562. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_agent_tool.py +0 -0
  563. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_api_timeout_kwarg.py +0 -0
  564. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_artifact_metadata.py +0 -0
  565. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_ask_user_question_tool.py +0 -0
  566. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_atlassian_tools.py +0 -0
  567. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_attach_llm_client_guard.py +0 -0
  568. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_audio_tools.py +0 -0
  569. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_binary_classify_manifest.py +0 -0
  570. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_browser_doc_tools.py +0 -0
  571. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_budget_compaction_recovery.py +0 -0
  572. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_built_in_autoregister.py +0 -0
  573. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_builtin_capabilities.py +0 -0
  574. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_builtin_channels.py +0 -0
  575. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_builtin_features.py +0 -0
  576. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_cache_prefix_key.py +0 -0
  577. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_cancellation.py +0 -0
  578. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_claude_code_token_client.py +0 -0
  579. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_cli_stream_limit.py +0 -0
  580. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_codex_responses_client.py +0 -0
  581. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_compaction_stm_watermark.py +0 -0
  582. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_composite_set_hooks.py +0 -0
  583. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_concurrent_runs.py +0 -0
  584. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_config_liveness.py +0 -0
  585. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_conversation_is_portable.py +0 -0
  586. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_core_deferred_tools.py +0 -0
  587. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_cron_runner.py +0 -0
  588. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_cron_store.py +0 -0
  589. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_cron_tools.py +0 -0
  590. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_deterministic_prune_pass.py +0 -0
  591. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_dev_tools.py +0 -0
  592. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_diff_order_keyed.py +0 -0
  593. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_dispatch_context_carries_the_sandbox.py +0 -0
  594. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_dynamic_persona_builder.py +0 -0
  595. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_embedding_error_classification.py +0 -0
  596. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_embedding_loop_safety.py +0 -0
  597. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_embedding_openai_compatible.py +0 -0
  598. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_errors_categories.py +0 -0
  599. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_evaluation_chain.py +0 -0
  600. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_evaluation_chain_configure.py +0 -0
  601. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_event_catalog.py +0 -0
  602. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_event_channel_unification.py +0 -0
  603. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_event_correlation.py +0 -0
  604. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_external_tool_resolution.py +0 -0
  605. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_failover_classification.py +0 -0
  606. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_forge_tool.py +0 -0
  607. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_fork_multi_provider.py +0 -0
  608. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_from_manifest_strict_validation.py +0 -0
  609. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_gateway.py +0 -0
  610. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_gateway_ws.py +0 -0
  611. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_geny_prod_manifest_repro.py +0 -0
  612. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_graph_edges.py +0 -0
  613. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_graph_rank.py +0 -0
  614. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_guard_fail_fast.py +0 -0
  615. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_hierarchical_sidecars.py +0 -0
  616. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_hook_gate_split.py +0 -0
  617. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_hook_in_process.py +0 -0
  618. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_hook_runner.py +0 -0
  619. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_hook_taxonomy.py +0 -0
  620. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_hooks_and_shared_keys.py +0 -0
  621. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_host_selections_resolve.py +0 -0
  622. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_identity_card_and_pinned.py +0 -0
  623. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_index_list_categories.py +0 -0
  624. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_index_render_vault_map.py +0 -0
  625. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_index_sidecar_coalescing.py +0 -0
  626. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_interaction_fields.py +0 -0
  627. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_internal_agentic_loop.py +0 -0
  628. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_introspection.py +0 -0
  629. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_client_base.py +0 -0
  630. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_client_registry.py +0 -0
  631. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_client_request_types.py +0 -0
  632. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_client_state.py +0 -0
  633. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_compactor_selfwire.py +0 -0
  634. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_llm_summary_compactor.py +0 -0
  635. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_lock_cancel_leak.py +0 -0
  636. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_loop_agnostic_lock.py +0 -0
  637. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_factory.py +0 -0
  638. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_from_dict_hygiene.py +0 -0
  639. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_memory_wiring.py +0 -0
  640. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_provider_validation.py +0 -0
  641. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_subagents_memory_sections.py +0 -0
  642. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_v2.py +0 -0
  643. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_manifest_v3_migration.py +0 -0
  644. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_annotations_attach.py +0 -0
  645. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_credential_store.py +0 -0
  646. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_fsm.py +0 -0
  647. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_lifecycle.py +0 -0
  648. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_namespace.py +0 -0
  649. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_oauth.py +0 -0
  650. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_prompts_skills_bridge.py +0 -0
  651. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_resource_retriever.py +0 -0
  652. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_uri.py +0 -0
  653. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_mcp_wrapper_tools.py +0 -0
  654. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_memory_aware_retriever.py +0 -0
  655. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_memory_facts.py +0 -0
  656. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_memory_hooks_after_callbacks.py +0 -0
  657. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_memory_metadata_extension.py +0 -0
  658. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_memory_rollup.py +0 -0
  659. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_model_discovery.py +0 -0
  660. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_model_overrides.py +0 -0
  661. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_multi_dim_budget_configure.py +0 -0
  662. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_multi_dim_budget_controller.py +0 -0
  663. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_multi_format_yield.py +0 -0
  664. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_multi_provider.py +0 -0
  665. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_multimodal.py +0 -0
  666. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_note_graph_queries.py +0 -0
  667. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_notebook_edit_tool.py +0 -0
  668. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_notes_load_pinned.py +0 -0
  669. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_notes_store_offloop_scan.py +0 -0
  670. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_one_path_vocabulary.py +0 -0
  671. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_openai_responses_routing.py +0 -0
  672. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_operator_tools.py +0 -0
  673. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_ordered_emitter_chain.py +0 -0
  674. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_permission_matrix.py +0 -0
  675. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_permission_mode_promotions.py +0 -0
  676. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_permission_posture.py +0 -0
  677. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_persistent_subagent.py +0 -0
  678. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase1_foundation.py +0 -0
  679. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase1_pipeline.py +0 -0
  680. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase2_agent_loop.py +0 -0
  681. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase2_tools.py +0 -0
  682. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase3_context_memory.py +0 -0
  683. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase4_think_agent_evaluate.py +0 -0
  684. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase5_emit_presets_mcp.py +0 -0
  685. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase5_environment.py +0 -0
  686. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase6_history.py +0 -0
  687. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase6_integration.py +0 -0
  688. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase7_security.py +0 -0
  689. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase9a_preset_regen.py +0 -0
  690. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_phase9a_scaffolding.py +0 -0
  691. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_pipeline_aclose.py +0 -0
  692. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_pipeline_attach_runtime.py +0 -0
  693. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_pipeline_events_tap.py +0 -0
  694. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_pipeline_from_manifest.py +0 -0
  695. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_pipeline_hook_lifecycle.py +0 -0
  696. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_pipeline_session_runtime.py +0 -0
  697. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_plan_mode_tools.py +0 -0
  698. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_primary_provider_and_build_reports.py +0 -0
  699. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_progressive_disclosure.py +0 -0
  700. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_provider_driven_strategy.py +0 -0
  701. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_push_notification_tool.py +0 -0
  702. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_qdrant_vector_store.py +0 -0
  703. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_refresh_backlinks_extension.py +0 -0
  704. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_refresh_runtime_and_run_lock.py +0 -0
  705. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_resolve_model_config.py +0 -0
  706. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_restore_bad_strategy_config.py +0 -0
  707. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_reviewer_policy_configure.py +0 -0
  708. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_runtime_task_runner.py +0 -0
  709. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s06_chunk_forwarding.py +0 -0
  710. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s06_provider_selection.py +0 -0
  711. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s13_file_backed_registry.py +0 -0
  712. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s13_task_registry_output.py +0 -0
  713. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s19_frequency_policy.py +0 -0
  714. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9b1_tool_review.py +0 -0
  715. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9b2_task_registry.py +0 -0
  716. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9b3_hitl.py +0 -0
  717. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9b4_summarize.py +0 -0
  718. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9b5_persist.py +0 -0
  719. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9c1_pipeline_resume.py +0 -0
  720. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_s9c2_restore_state.py +0 -0
  721. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_sandbox_exec_tool.py +0 -0
  722. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_sandbox_path_mapping.py +0 -0
  723. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_sandbox_tools.py +0 -0
  724. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_security_hardening.py +0 -0
  725. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_self_modifying_env.py +0 -0
  726. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_send_message_tool.py +0 -0
  727. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_settings_loader.py +0 -0
  728. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_level3_resources.py +0 -0
  729. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_1.py +0 -0
  730. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_2.py +0 -0
  731. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_3.py +0 -0
  732. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_4_bundled.py +0 -0
  733. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_5_fork.py +0 -0
  734. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_6_killer.py +0 -0
  735. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_phase_10_7_watcher.py +0 -0
  736. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_richer_schema.py +0 -0
  737. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skill_tool.py +0 -0
  738. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_skills_foundation.py +0 -0
  739. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_slash_built_in_control.py +0 -0
  740. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_slash_built_in_introspection.py +0 -0
  741. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_slash_commands.py +0 -0
  742. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_slash_md_template.py +0 -0
  743. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_sql_stm_session_scope.py +0 -0
  744. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_ssh_tools.py +0 -0
  745. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_stage10_ask_hitl.py +0 -0
  746. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_stage10_hook_wiring.py +0 -0
  747. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_stage10_partition_executor.py +0 -0
  748. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_stage10_permission_matrix.py +0 -0
  749. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_stage19_session_summary.py +0 -0
  750. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_state_mutation_wiring.py +0 -0
  751. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_state_shared_and_local.py +0 -0
  752. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_stm_append_event.py +0 -0
  753. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_storage_growth_caps.py +0 -0
  754. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_strategy_config_roundtrip.py +0 -0
  755. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_streaming_tool_executor.py +0 -0
  756. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_structured_output_parser.py +0 -0
  757. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_structured_reflection.py +0 -0
  758. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_catalog.py +0 -0
  759. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_credential_propagation.py +0 -0
  760. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_descriptor.py +0 -0
  761. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_manifest_compile.py +0 -0
  762. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_orchestrator_zero_arg.py +0 -0
  763. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_parallel.py +0 -0
  764. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_pipeline_lifecycle.py +0 -0
  765. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_subagent_type_orchestrator.py +0 -0
  766. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_task_tools.py +0 -0
  767. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_text_tool_protocol.py +0 -0
  768. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_todo_write_tool.py +0 -0
  769. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_abc_uplift.py +0 -0
  770. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_call_events.py +0 -0
  771. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_errors.py +0 -0
  772. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_lifecycle_hooks.py +0 -0
  773. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_pair_repair.py +0 -0
  774. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_plugins.py +0 -0
  775. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_provider.py +0 -0
  776. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_result_persistence.py +0 -0
  777. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_results_end_the_turn.py +0 -0
  778. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_search_tool.py +0 -0
  779. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_tool_stage_max_concurrency.py +0 -0
  780. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_ttft_cache_overhaul.py +0 -0
  781. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_ttft_critical_path.py +0 -0
  782. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_ttft_warmup_streaming.py +0 -0
  783. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_turn_boundary_state.py +0 -0
  784. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_validate_manifest.py +0 -0
  785. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_vault_map_drill.py +0 -0
  786. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_web_fetch_tool.py +0 -0
  787. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_web_search_backends.py +0 -0
  788. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_web_search_tool.py +0 -0
  789. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_workspace.py +0 -0
  790. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_workspace_propagation.py +0 -0
  791. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_workspace_tools.py +0 -0
  792. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_workspace_tools_integration.py +0 -0
  793. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_worktree_tools.py +0 -0
  794. {geny_executor-2.70.0 → geny_executor-2.71.0}/tests/unit/test_write_hook_carries_the_note.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: geny-executor
3
- Version: 2.70.0
3
+ Version: 2.71.0
4
4
  Summary: Harness-engineered agent pipeline library — one 21-stage architecture, many model accounts behind one conversation
5
5
  Project-URL: Homepage, https://github.com/CocoRoF/geny-executor
6
6
  Project-URL: Repository, https://github.com/CocoRoF/geny-executor
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "geny-executor"
7
- version = "2.70.0"
7
+ version = "2.71.0"
8
8
  description = "Harness-engineered agent pipeline library — one 21-stage architecture, many model accounts behind one conversation"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -0,0 +1,373 @@
1
+ """Account cool-downs and failure classification for multi-account routing.
2
+
3
+ A route is a list of accounts. When one of them fails in a way another
4
+ account could survive — a usage limit, a dead login, an outage — the router
5
+ moves on and marks that account cooling so every other agent in the process
6
+ skips it too. This module owns that shared, process-wide state and the
7
+ classification that decides whether a failure is worth failing over at all.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import re
13
+ from datetime import datetime
14
+ import time
15
+ from typing import Any, Callable, Mapping, Optional
16
+
17
+ from geny_executor.core.errors import APIError, ErrorCategory
18
+
19
+ Notify = Callable[[dict[str, Any]], None]
20
+
21
+ # ── cooldowns (process-wide, keyed by account) ────────────────────────
22
+ # A pool across agents: when one agent's turn exhausts an account, another
23
+ # agent routed to the same account should not walk into the same wall.
24
+ _COOLDOWN: dict[str, tuple[float, str]] = {}
25
+
26
+ RATE_LIMIT_COOLDOWN_S = 15 * 60
27
+ AUTH_COOLDOWN_S = 5 * 60
28
+ SERVER_COOLDOWN_S = 60
29
+
30
+ #: What a bench costs when there is nowhere else to go. Benching the ONLY
31
+ #: account for fifteen minutes does not protect a quota — it just stops the
32
+ #: user working. A transient throttle gets a short sit-down instead, and the
33
+ #: turn after it either succeeds or benches again.
34
+ SOLE_ACCOUNT_COOLDOWN_S = 60
35
+
36
+ #: A rate limit on one model says nothing about its siblings: the metered
37
+ #: APIs enforce requests/tokens per minute PER MODEL, so a 429 on opus leaves
38
+ #: haiku on the same key usable. Keyed (account, model) alongside the
39
+ #: credential-wide bench.
40
+ _MODEL_COOLDOWN: dict[tuple[str, str], tuple[float, str]] = {}
41
+
42
+ #: …but only where that is true. A subscription plan meters the ACCOUNT: when
43
+ #: Claude Code or a ChatGPT plan says "usage limit reached", every model on
44
+ #: that login is out, and benching just the one that happened to be asked
45
+ #: would send the next turn straight into the same wall on a sibling.
46
+ PER_MODEL_RATE_LIMITS = frozenset({"anthropic", "openai", "google", "vllm"})
47
+
48
+
49
+ def rate_limit_is_per_model(provider: str) -> bool:
50
+ """True when a 429 from *provider* is about the model, not the account."""
51
+ return provider in PER_MODEL_RATE_LIMITS
52
+
53
+
54
+ def cool_down(account_id: str, seconds: float, reason: str) -> None:
55
+ if account_id:
56
+ _COOLDOWN[account_id] = (time.time() + max(1.0, seconds), reason)
57
+
58
+
59
+ def cooling(account_id: str) -> Optional[tuple[float, str]]:
60
+ entry = _COOLDOWN.get(account_id)
61
+ if entry is None:
62
+ return None
63
+ if entry[0] <= time.time():
64
+ _COOLDOWN.pop(account_id, None)
65
+ return None
66
+ return entry
67
+
68
+
69
+ def clear_cooldown(account_id: str) -> None:
70
+ """Lift every bench on this account — credential-wide and per model.
71
+
72
+ One call, because "this account is fine now" is one fact; leaving a model
73
+ bench behind after clearing the account is how a recovered account stays
74
+ half-benched with nothing to explain it.
75
+ """
76
+ _COOLDOWN.pop(account_id, None)
77
+ clear_model_cooldowns(account_id)
78
+
79
+
80
+ # ── load (process-wide, keyed by account) ─────────────────────────────
81
+ # Cooldowns answer "who is broken". This answers "whose turn is it".
82
+ # A route of several healthy accounts used to send EVERY turn to the
83
+ # first one until it hit its cap — failover, which only reacts once an
84
+ # account is already exhausted. For subscription plans that is backwards:
85
+ # the point of holding two logins is that neither reaches its limit.
86
+ #
87
+ # Process-wide for the same reason cooldowns are: sibling agents share
88
+ # the accounts, so a per-client counter would let three agents each
89
+ # "balance" onto the same first account.
90
+ _LAST_USED: dict[str, float] = {}
91
+
92
+
93
+ def mark_used(account_id: str) -> None:
94
+ if account_id:
95
+ _LAST_USED[account_id] = time.time()
96
+
97
+
98
+ def last_used(account_id: str) -> float:
99
+ """When this account last answered; 0.0 if never (so it goes first)."""
100
+ return _LAST_USED.get(account_id, 0.0)
101
+
102
+
103
+ def snapshot() -> dict[str, dict[str, Any]]:
104
+ """Everything currently benched, keyed by account.
105
+
106
+ Model benches belong here too. This is the one view of "what cannot
107
+ answer right now" — the host renders it, and callers clear from it — so
108
+ a bench that does not appear is a bench nobody can see or lift.
109
+ """
110
+ now = time.time()
111
+ out: dict[str, dict[str, Any]] = {}
112
+ for account, (until, reason) in list(_COOLDOWN.items()):
113
+ if until > now:
114
+ out[account] = {
115
+ "until": until,
116
+ "remaining": round(until - now),
117
+ "reason": reason,
118
+ "scope": "account",
119
+ }
120
+ for (account, model), (until, reason) in list(_MODEL_COOLDOWN.items()):
121
+ if until <= now:
122
+ continue
123
+ entry = out.setdefault(
124
+ account,
125
+ {"until": until, "remaining": round(until - now), "reason": reason, "scope": "model"},
126
+ )
127
+ models = entry.setdefault("models", {})
128
+ models[model] = {"until": until, "remaining": round(until - now), "reason": reason}
129
+ if entry.get("scope") == "model" and until > entry["until"]:
130
+ entry["until"] = until
131
+ entry["remaining"] = round(until - now)
132
+ return out
133
+
134
+
135
+ # ── error classification ──────────────────────────────────────────────
136
+ #: "This account cannot answer right now, and another one might."
137
+ #:
138
+ #: Rate limits and spend caps are the same thing to a router: the account is
139
+ #: alive, the request is fine, and the next hop should take it. Keeping them
140
+ #: apart cost a production turn — a Claude subscription answered
141
+ #: ``You've hit your monthly spend limit``, which matched none of the
142
+ #: rate-limit wording, was classified as a bad request, and failed the turn
143
+ #: outright while a working OpenAI account sat next in the route.
144
+ _RATE_HINTS = re.compile(
145
+ r"rate.?limit|usage limit|limit reached|quota|too many requests|429|"
146
+ r"resets? (at|in)|out of (extra )?usage|overloaded|capacity|"
147
+ # spend caps, credit exhaustion, billing stops — an empty wallet is a
148
+ # limit, and the fallback exists for exactly this
149
+ r"spend limit|spending limit|credit balance|insufficient[_ ]quota|"
150
+ r"billing|payment required|402",
151
+ re.I,
152
+ )
153
+ _AUTH_HINTS = re.compile(
154
+ r"not logged in|please run /login|invalid api key|unauthori[sz]ed|401|"
155
+ r"oauth token (has )?expired|authentication|invalid_grant|token_expired|"
156
+ r"refresh token|login required|forbidden|403",
157
+ re.I,
158
+ )
159
+
160
+
161
+ def classify_text(message: str, status: Optional[int] = None) -> ErrorCategory:
162
+ if status == 429 or (status is None and _RATE_HINTS.search(message or "")):
163
+ return ErrorCategory.RATE_LIMITED
164
+ if status in (401, 403) or (status is None and _AUTH_HINTS.search(message or "")):
165
+ return ErrorCategory.AUTH
166
+ if status is not None and status >= 500:
167
+ return ErrorCategory.SERVER_ERROR
168
+ if status is not None and 400 <= status < 500:
169
+ return ErrorCategory.BAD_REQUEST
170
+ return ErrorCategory.UNKNOWN
171
+
172
+
173
+ def api_error(message: str, category: ErrorCategory, status: Optional[int] = None) -> APIError:
174
+ return APIError(message, category=category, status_code=status)
175
+
176
+
177
+ def category_of(exc: BaseException) -> ErrorCategory:
178
+ try:
179
+ import httpx
180
+
181
+ if isinstance(exc, httpx.TimeoutException):
182
+ return ErrorCategory.TIMEOUT
183
+ if isinstance(exc, httpx.TransportError):
184
+ return ErrorCategory.NETWORK
185
+ except Exception:
186
+ pass
187
+ if isinstance(exc, (ConnectionError, TimeoutError)):
188
+ return ErrorCategory.NETWORK if isinstance(exc, ConnectionError) else ErrorCategory.TIMEOUT
189
+ if isinstance(exc, APIError):
190
+ cat = exc.category
191
+ if cat in (ErrorCategory.UNKNOWN, ErrorCategory.CLI_PROTOCOL_ERROR):
192
+ refined = classify_text(str(exc), getattr(exc, "status_code", None))
193
+ if refined != ErrorCategory.UNKNOWN:
194
+ return refined
195
+ if cat == ErrorCategory.CLI_AUTH_FAILED:
196
+ return ErrorCategory.AUTH
197
+ return cat
198
+ status = getattr(exc, "status_code", None) or getattr(
199
+ getattr(exc, "response", None), "status_code", None
200
+ )
201
+ return classify_text(str(exc), status if isinstance(status, int) else None)
202
+
203
+
204
+ #: failures where retrying the SAME route cannot help once every hop has
205
+ #: failed — a usage limit or a dead login does not recover in seconds
206
+ EXHAUSTED_TERMINAL = {
207
+ ErrorCategory.RATE_LIMITED,
208
+ ErrorCategory.AUTH,
209
+ ErrorCategory.CLI_NOT_FOUND,
210
+ ErrorCategory.CLI_AUTH_FAILED,
211
+ }
212
+
213
+ #: failures where another account/model may well succeed
214
+ FAILOVER = {
215
+ ErrorCategory.RATE_LIMITED,
216
+ ErrorCategory.AUTH,
217
+ ErrorCategory.SERVER_ERROR,
218
+ ErrorCategory.NETWORK,
219
+ ErrorCategory.TIMEOUT,
220
+ ErrorCategory.CLI_NOT_FOUND,
221
+ ErrorCategory.CLI_TIMEOUT,
222
+ }
223
+
224
+
225
+ def cooldown_for(category: ErrorCategory, *, sole_account: bool = False) -> float:
226
+ """How long to bench an account for this kind of failure.
227
+
228
+ ``sole_account`` caps a transient throttle: with nothing to rotate to, a
229
+ long bench is not protection, it is downtime. A dead login is exempt —
230
+ waiting cannot fix it and retrying it every minute only spams the vendor.
231
+ """
232
+ if category == ErrorCategory.RATE_LIMITED:
233
+ base = RATE_LIMIT_COOLDOWN_S
234
+ elif category in (ErrorCategory.AUTH, ErrorCategory.CLI_NOT_FOUND):
235
+ return AUTH_COOLDOWN_S
236
+ else:
237
+ base = SERVER_COOLDOWN_S
238
+ return min(base, SOLE_ACCOUNT_COOLDOWN_S) if sole_account else base
239
+
240
+
241
+ # ── when the provider tells us when to come back ──────────────────────
242
+ # A blind fifteen minutes is a guess in both directions: too short and the
243
+ # next turn walks into the same wall, too long and a recovered account sits
244
+ # idle. Providers usually say. Take the answer when they do.
245
+
246
+ _RETRY_IN = re.compile(
247
+ r"(?:try|retry|available|come back|again)\b[^.\n]{0,24}?\bin\s+"
248
+ r"(\d+(?:\.\d+)?)\s*(second|sec|minute|min|hour|hr|day|s|m|h|d)s?\b",
249
+ re.I,
250
+ )
251
+ _RETRY_AFTER = re.compile(r"retry[-_ ]?after[\s:=]+(\d+(?:\.\d+)?)", re.I)
252
+ _UNIT_S = {
253
+ "s": 1,
254
+ "sec": 1,
255
+ "second": 1,
256
+ "m": 60,
257
+ "min": 60,
258
+ "minute": 60,
259
+ "h": 3600,
260
+ "hr": 3600,
261
+ "hour": 3600,
262
+ "d": 86400,
263
+ "day": 86400,
264
+ }
265
+
266
+
267
+ def _absolute(value: Any) -> Optional[float]:
268
+ """Epoch seconds from epoch-s, epoch-ms or ISO-8601; ``None`` otherwise."""
269
+ if value is None or value == "":
270
+ return None
271
+ if isinstance(value, bool):
272
+ return None
273
+ if isinstance(value, (int, float)):
274
+ number = float(value)
275
+ if number <= 0:
276
+ return None
277
+ return number / 1000.0 if number > 1_000_000_000_000 else number
278
+ if isinstance(value, str):
279
+ raw = value.strip()
280
+ if not raw:
281
+ return None
282
+ try:
283
+ number = float(raw)
284
+ return number / 1000.0 if number > 1_000_000_000_000 else number
285
+ except ValueError:
286
+ pass
287
+ try:
288
+ return datetime.fromisoformat(raw.replace("Z", "+00:00")).timestamp()
289
+ except ValueError:
290
+ return None
291
+ return None
292
+
293
+
294
+ def reset_at_from(
295
+ message: str = "", *, fields: Optional[Mapping[str, Any]] = None
296
+ ) -> Optional[float]:
297
+ """When the provider says this account is usable again, as epoch seconds.
298
+
299
+ Reads, in order of authority: an explicit field the provider sent
300
+ (``reset_at`` / ``resets_at`` / ``retry_after`` and their spellings), then
301
+ the error text — vendors put it there far more often than in a field
302
+ ("try again in 42 seconds", "retry-after: 90"). Returns ``None`` when
303
+ nothing says, and the caller falls back to a category default.
304
+ """
305
+ for key in ("reset_at", "resets_at", "resetAt", "retry_until", "reset_time"):
306
+ found = _absolute((fields or {}).get(key))
307
+ if found is not None:
308
+ return found
309
+ for key in ("retry_after", "retryAfter", "retry-after"):
310
+ raw = (fields or {}).get(key)
311
+ try:
312
+ seconds = float(raw) # type: ignore[arg-type]
313
+ except (TypeError, ValueError):
314
+ continue
315
+ if seconds > 0:
316
+ return time.time() + seconds
317
+
318
+ text = message or ""
319
+ match = _RETRY_AFTER.search(text)
320
+ if match:
321
+ return time.time() + float(match.group(1))
322
+ match = _RETRY_IN.search(text)
323
+ if match:
324
+ unit = _UNIT_S.get(match.group(2).lower())
325
+ if unit:
326
+ return time.time() + float(match.group(1)) * unit
327
+ return None
328
+
329
+
330
+ # ── model-scoped cooldowns ────────────────────────────────────────────
331
+
332
+
333
+ def cool_down_model(account_id: str, model: str, until: float, reason: str) -> None:
334
+ """Bench one model on this account, leaving its siblings usable."""
335
+ if account_id and model and until > time.time():
336
+ _MODEL_COOLDOWN[(account_id, model)] = (until, reason)
337
+
338
+
339
+ def model_cooling(account_id: str, model: Optional[str]) -> Optional[tuple[float, str]]:
340
+ """The active model bench blocking this hop, or ``None``.
341
+
342
+ A caller that does not name a model stays conservative: ANY active model
343
+ bench on the account blocks it, because an unscoped route could land on
344
+ the very model that just failed.
345
+ """
346
+ now = time.time()
347
+ if model:
348
+ entry = _MODEL_COOLDOWN.get((account_id, model))
349
+ if entry is None:
350
+ return None
351
+ if entry[0] <= now:
352
+ _MODEL_COOLDOWN.pop((account_id, model), None)
353
+ return None
354
+ return entry
355
+ live = [
356
+ v for (acct, _m), v in list(_MODEL_COOLDOWN.items()) if acct == account_id and v[0] > now
357
+ ]
358
+ return max(live, key=lambda v: v[0]) if live else None
359
+
360
+
361
+ def clear_model_cooldowns(account_id: str) -> None:
362
+ for key in [k for k in _MODEL_COOLDOWN if k[0] == account_id]:
363
+ _MODEL_COOLDOWN.pop(key, None)
364
+
365
+
366
+ def strip_cache_markers(value: Any) -> Any:
367
+ """Deep copy without Anthropic `cache_control` keys — they are an
368
+ Anthropic extension and other wires may reject them."""
369
+ if isinstance(value, dict):
370
+ return {k: strip_cache_markers(v) for k, v in value.items() if k != "cache_control"}
371
+ if isinstance(value, list):
372
+ return [strip_cache_markers(v) for v in value]
373
+ return value
@@ -282,6 +282,7 @@ class AnthropicClient(BaseClient):
282
282
  capabilities = ClientCapabilities(
283
283
  supports_thinking=True,
284
284
  supports_tools=True,
285
+ supports_vision=True,
285
286
  supports_streaming=True,
286
287
  supports_tool_choice=True,
287
288
  supports_stop_sequences=True,
@@ -86,6 +86,18 @@ class ClientCapabilities:
86
86
  supports_top_k: bool = False
87
87
  supports_system_prompt: bool = True
88
88
 
89
+ #: The model can SEE an image in the conversation. Declared per client
90
+ #: because a conversation outlives the model answering it: an image sent
91
+ #: to Claude can be replayed to a text-only local model on the next turn,
92
+ #: and an undeclared image is one the wire rejects with the turn already
93
+ #: half spent. Default False — a backend that can see says so.
94
+ supports_vision: bool = False
95
+
96
+ #: …and can see one returned by a TOOL, not only one the user attached.
97
+ #: Separate because some backends accept multimodal user messages and
98
+ #: reject list-type tool content outright.
99
+ supports_vision_tool_results: bool = True
100
+
89
101
  # --- Extended capabilities (CLI backends + JSON schema + sessions) ---
90
102
 
91
103
  #: JSON-schema / json_object structured-output support.
@@ -273,9 +285,68 @@ class BaseClient(ABC):
273
285
  tools=tools,
274
286
  tool_choice=tool_choice,
275
287
  )
288
+ self._lower_unseeable_images(request)
276
289
 
277
290
  return request
278
291
 
292
+ # ── images a backend cannot see ──────────────────────────────────
293
+ def _lower_unseeable_images(self, request: APIRequest) -> None:
294
+ """Replace image blocks this client cannot see with a note saying so.
295
+
296
+ A conversation outlives the model answering it: an image attached
297
+ while Claude was answering can reach a text-only local model on the
298
+ very next turn, through a failover or a model switch. Three things
299
+ could happen there, and only one of them is honest —
300
+
301
+ * send it anyway: the wire rejects the request and the turn dies
302
+ for a reason the user cannot act on;
303
+ * strip it silently: the model answers confidently about a picture
304
+ it never received;
305
+ * say an image was here and could not be shown, which is what this
306
+ does, alongside a ``llm_client.field_dropped`` event so the host
307
+ can say so too.
308
+ """
309
+ caps = self.capabilities
310
+ if caps.supports_vision and caps.supports_vision_tool_results:
311
+ return
312
+
313
+ lowered = 0
314
+ for message in request.messages:
315
+ content = message.get("content")
316
+ if not isinstance(content, list):
317
+ continue
318
+ in_tool_result = any(
319
+ isinstance(b, dict) and b.get("type") == "tool_result" for b in content
320
+ )
321
+ allowed = (
322
+ caps.supports_vision and caps.supports_vision_tool_results
323
+ if in_tool_result
324
+ else caps.supports_vision
325
+ )
326
+ if allowed:
327
+ continue
328
+ replaced: list[Any] = []
329
+ for block in content:
330
+ if isinstance(block, dict) and block.get("type") == "image":
331
+ lowered += 1
332
+ replaced.append(
333
+ {
334
+ "type": "text",
335
+ "text": "[an image was attached here; this model cannot see images]",
336
+ }
337
+ )
338
+ else:
339
+ replaced.append(block)
340
+ message["content"] = replaced
341
+
342
+ if lowered:
343
+ self._emit_unsupported("image")
344
+ logger.info(
345
+ "%s cannot see images — %d replaced with a placeholder",
346
+ self.provider,
347
+ lowered,
348
+ )
349
+
279
350
  # Maps a ``capabilities.drops`` entry to the APIRequest attribute that
280
351
  # carries it. Keyed by the *declaration* vocabulary (ModelConfig field
281
352
  # names — ``thinking_enabled``, not ``thinking``) because that is what
@@ -46,7 +46,7 @@ import shutil
46
46
  import tempfile
47
47
  import time
48
48
  from pathlib import Path
49
- from typing import Any, AsyncIterator, Dict, List, Optional
49
+ from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Optional
50
50
 
51
51
  from geny_executor.core.errors import APIError, ErrorCategory
52
52
  from geny_executor.core.state import TokenUsage
@@ -56,6 +56,9 @@ from geny_executor.llm_client.types import APIRequest, APIResponse, ContentBlock
56
56
  from geny_executor.llm_client import text_tool_protocol as tp
57
57
  from geny_executor.llm_client._failover import Notify, classify_text
58
58
 
59
+ if TYPE_CHECKING: # the SDK is a runtime dep; this keeps import cost off the hot path
60
+ from claude_agent_sdk.types import EffortLevel
61
+
59
62
  logger = logging.getLogger(__name__)
60
63
 
61
64
  #: auth channels the CLI honours from the environment — stripped from the
@@ -136,6 +139,15 @@ def child_env(
136
139
  _EFFORTS = ("low", "medium", "high", "xhigh", "max")
137
140
 
138
141
 
142
+ def _effort_literal(effort: Optional[str]) -> Optional[EffortLevel]:
143
+ """``effort_for`` answers a plain string; the SDK's field is a Literal.
144
+
145
+ Narrow rather than cast: an effort the SDK does not know is dropped,
146
+ not smuggled past the type checker into a rejected request.
147
+ """
148
+ return effort if effort in _EFFORTS else None # type: ignore[return-value]
149
+
150
+
139
151
  def effort_for(request: APIRequest, fixed: Optional[str]) -> Optional[str]:
140
152
  if fixed in _EFFORTS:
141
153
  return fixed
@@ -157,6 +169,7 @@ class ClaudeCodeTokenClient(BaseClient):
157
169
  capabilities = ClientCapabilities(
158
170
  supports_thinking=True,
159
171
  supports_tools=True,
172
+ supports_vision=True,
160
173
  supports_streaming=True,
161
174
  supports_tool_choice=False,
162
175
  supports_stop_sequences=False,
@@ -350,7 +363,7 @@ class ClaudeCodeTokenClient(BaseClient):
350
363
  env=env,
351
364
  cli_path=self._binary,
352
365
  max_buffer_size=_stream_limit(),
353
- effort=effort_for(request, self._effort),
366
+ effort=_effort_literal(effort_for(request, self._effort)),
354
367
  stderr=stderr_lines.append,
355
368
  )
356
369
 
@@ -519,7 +532,7 @@ class ClaudeCodeTokenClient(BaseClient):
519
532
  ),
520
533
  }
521
534
 
522
- def _as_api_error(self, exc: BaseException, stderr_lines: list[str]) -> APIError:
535
+ def _as_api_error(self, exc: Exception, stderr_lines: list[str]) -> APIError:
523
536
  """Map an SDK failure onto this library's error vocabulary.
524
537
 
525
538
  The SDK raises typed errors, which is the point of using it: a
@@ -36,6 +36,7 @@ class GoogleClient(BaseClient):
36
36
  capabilities = ClientCapabilities(
37
37
  supports_thinking=False,
38
38
  supports_tools=True,
39
+ supports_vision=True,
39
40
  supports_streaming=True,
40
41
  supports_tool_choice=True,
41
42
  supports_stop_sequences=True,
@@ -121,6 +121,7 @@ class OpenAIClient(BaseClient):
121
121
  capabilities = ClientCapabilities(
122
122
  supports_thinking=True,
123
123
  supports_tools=True,
124
+ supports_vision=True,
124
125
  supports_streaming=True,
125
126
  supports_tool_choice=True,
126
127
  supports_stop_sequences=True,
@@ -42,6 +42,7 @@ EFFORTS = {"none", "minimal", "low", "medium", "high", "xhigh", "max"}
42
42
  RESPONSES_CAPABILITIES = ClientCapabilities(
43
43
  supports_thinking=True,
44
44
  supports_tools=True,
45
+ supports_vision=True,
45
46
  supports_streaming=True,
46
47
  supports_tool_choice=False,
47
48
  supports_stop_sequences=False,