geny-executor 2.48.2__tar.gz → 2.49.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 (765) hide show
  1. {geny_executor-2.48.2 → geny_executor-2.49.0}/PKG-INFO +4 -1
  2. {geny_executor-2.48.2 → geny_executor-2.49.0}/pyproject.toml +7 -1
  3. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/client.py +89 -1
  4. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/google.py +41 -34
  5. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/openai.py +44 -44
  6. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/provider.py +15 -2
  7. geny_executor-2.49.0/src/geny_executor/tools/_ssh.py +215 -0
  8. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/__init__.py +20 -0
  9. geny_executor-2.49.0/src/geny_executor/tools/built_in/_ssh_store.py +146 -0
  10. geny_executor-2.49.0/src/geny_executor/tools/built_in/ssh_tools.py +359 -0
  11. geny_executor-2.49.0/tests/unit/test_embedding_loop_safety.py +167 -0
  12. geny_executor-2.49.0/tests/unit/test_ssh_tools.py +205 -0
  13. {geny_executor-2.48.2 → geny_executor-2.49.0}/.gitignore +0 -0
  14. {geny_executor-2.48.2 → geny_executor-2.49.0}/LICENSE +0 -0
  15. {geny_executor-2.48.2 → geny_executor-2.49.0}/NOTICE +0 -0
  16. {geny_executor-2.48.2 → geny_executor-2.49.0}/README.md +0 -0
  17. {geny_executor-2.48.2 → geny_executor-2.49.0}/README_ko.md +0 -0
  18. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/__init__.py +0 -0
  19. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/channels/__init__.py +0 -0
  20. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/channels/built_in.py +0 -0
  21. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/channels/factory.py +0 -0
  22. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/channels/send_message_channel.py +0 -0
  23. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/channels/user_file_channel.py +0 -0
  24. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/__init__.py +0 -0
  25. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/artifact.py +0 -0
  26. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/builder.py +0 -0
  27. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/compaction.py +0 -0
  28. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/config.py +0 -0
  29. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/diff.py +0 -0
  30. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/environment.py +0 -0
  31. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/environment_control.py +0 -0
  32. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/errors.py +0 -0
  33. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/introspection.py +0 -0
  34. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/manifest_factory.py +0 -0
  35. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/mutation.py +0 -0
  36. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/pipeline.py +0 -0
  37. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/presets.py +0 -0
  38. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/result.py +0 -0
  39. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/schema.py +0 -0
  40. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/shared_keys.py +0 -0
  41. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/slot.py +0 -0
  42. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/snapshot.py +0 -0
  43. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/stage.py +0 -0
  44. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/state.py +0 -0
  45. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/core/token_estimate.py +0 -0
  46. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/__init__.py +0 -0
  47. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/runner.py +0 -0
  48. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/store_abc.py +0 -0
  49. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/store_impl/__init__.py +0 -0
  50. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/store_impl/file_backed.py +0 -0
  51. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/store_impl/in_memory.py +0 -0
  52. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/cron/types.py +0 -0
  53. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/events/__init__.py +0 -0
  54. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/events/bus.py +0 -0
  55. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/events/catalog.py +0 -0
  56. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/events/types.py +0 -0
  57. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/__init__.py +0 -0
  58. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/adapter.py +0 -0
  59. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/discord.py +0 -0
  60. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/factory.py +0 -0
  61. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/runner.py +0 -0
  62. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/slack.py +0 -0
  63. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/telegram.py +0 -0
  64. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/types.py +0 -0
  65. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/gateway/ws_base.py +0 -0
  66. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/__init__.py +0 -0
  67. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/ab_test.py +0 -0
  68. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/cost.py +0 -0
  69. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/models.py +0 -0
  70. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/monitor.py +0 -0
  71. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/replay.py +0 -0
  72. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/history/service.py +0 -0
  73. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/hooks/__init__.py +0 -0
  74. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/hooks/config.py +0 -0
  75. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/hooks/events.py +0 -0
  76. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/hooks/runner.py +0 -0
  77. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/__init__.py +0 -0
  78. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/_cli_runtime.py +0 -0
  79. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/anthropic.py +0 -0
  80. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/base.py +0 -0
  81. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/claude_code.py +0 -0
  82. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/credentials.py +0 -0
  83. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/google.py +0 -0
  84. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/local_probe.py +0 -0
  85. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/model_discovery.py +0 -0
  86. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/openai.py +0 -0
  87. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/openai_compatible.py +0 -0
  88. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/profiles.py +0 -0
  89. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/registry.py +0 -0
  90. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/translators/__init__.py +0 -0
  91. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/translators/_canonical.py +0 -0
  92. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/translators/_cli.py +0 -0
  93. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/types.py +0 -0
  94. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/llm_client/vllm.py +0 -0
  95. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/__init__.py +0 -0
  96. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/_locks.py +0 -0
  97. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/_progressive.py +0 -0
  98. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/composite/__init__.py +0 -0
  99. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/composite/handles.py +0 -0
  100. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/composite/provider.py +0 -0
  101. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/composite/routing.py +0 -0
  102. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/composite/snapshot.py +0 -0
  103. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/__init__.py +0 -0
  104. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/local.py +0 -0
  105. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/registry.py +0 -0
  106. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/embedding/voyage.py +0 -0
  107. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/factory.py +0 -0
  108. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/facts.py +0 -0
  109. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/graph_rank.py +0 -0
  110. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/presets.py +0 -0
  111. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/provider.py +0 -0
  112. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/__init__.py +0 -0
  113. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/ephemeral.py +0 -0
  114. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/__init__.py +0 -0
  115. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/config.py +0 -0
  116. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/frontmatter.py +0 -0
  117. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/graph_edges.py +0 -0
  118. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/index_store.py +0 -0
  119. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/layout.py +0 -0
  120. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/ltm_store.py +0 -0
  121. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/notes_store.py +0 -0
  122. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/snapshot.py +0 -0
  123. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/stm_store.py +0 -0
  124. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/timezone.py +0 -0
  125. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/file/vector_store.py +0 -0
  126. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/__init__.py +0 -0
  127. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/config.py +0 -0
  128. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/connection.py +0 -0
  129. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/index_store.py +0 -0
  130. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/ltm_store.py +0 -0
  131. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/notes_store.py +0 -0
  132. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/provider.py +0 -0
  133. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/schema.py +0 -0
  134. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/snapshot.py +0 -0
  135. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/stm_store.py +0 -0
  136. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/providers/sql/vector_store.py +0 -0
  137. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/retriever.py +0 -0
  138. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/rollup.py +0 -0
  139. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/strategy.py +0 -0
  140. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/vector/__init__.py +0 -0
  141. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/memory/vector/qdrant_store.py +0 -0
  142. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/notifications/__init__.py +0 -0
  143. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/notifications/registry.py +0 -0
  144. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/permission/__init__.py +0 -0
  145. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/permission/loader.py +0 -0
  146. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/permission/matrix.py +0 -0
  147. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/permission/types.py +0 -0
  148. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/py.typed +0 -0
  149. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/runtime/__init__.py +0 -0
  150. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/runtime/task_executors.py +0 -0
  151. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/runtime/task_runner.py +0 -0
  152. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/security/__init__.py +0 -0
  153. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/security/import_validator.py +0 -0
  154. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/security/script_sandbox.py +0 -0
  155. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/session/__init__.py +0 -0
  156. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/session/freshness.py +0 -0
  157. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/session/manager.py +0 -0
  158. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/session/persistence.py +0 -0
  159. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/session/session.py +0 -0
  160. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/settings/__init__.py +0 -0
  161. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/settings/loader.py +0 -0
  162. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/settings/section_registry.py +0 -0
  163. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/__init__.py +0 -0
  164. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/batch/SKILL.md +0 -0
  165. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/debug/SKILL.md +0 -0
  166. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/environment/REFERENCE.md +0 -0
  167. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/environment/SKILL.md +0 -0
  168. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/loop/SKILL.md +0 -0
  169. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/lorem-ipsum/SKILL.md +0 -0
  170. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/simplify/SKILL.md +0 -0
  171. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/skillify/SKILL.md +0 -0
  172. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/stuck/SKILL.md +0 -0
  173. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/tool-builder/REFERENCE.md +0 -0
  174. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/tool-builder/SKILL.md +0 -0
  175. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled/verify/SKILL.md +0 -0
  176. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/bundled_skills.py +0 -0
  177. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/fork.py +0 -0
  178. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/frontmatter.py +0 -0
  179. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/loader.py +0 -0
  180. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/mcp_bridge.py +0 -0
  181. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/path_match.py +0 -0
  182. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/registry.py +0 -0
  183. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/shell_blocks.py +0 -0
  184. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/skill_tool.py +0 -0
  185. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/types.py +0 -0
  186. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/skills/watcher.py +0 -0
  187. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/__init__.py +0 -0
  188. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/__init__.py +0 -0
  189. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/_helpers.py +0 -0
  190. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/cancel.py +0 -0
  191. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/clear.py +0 -0
  192. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/compact.py +0 -0
  193. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/config.py +0 -0
  194. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/context.py +0 -0
  195. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/cost.py +0 -0
  196. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/help.py +0 -0
  197. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/memory.py +0 -0
  198. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/model.py +0 -0
  199. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/preset_info.py +0 -0
  200. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/status.py +0 -0
  201. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/built_in/tasks.py +0 -0
  202. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/md_template.py +0 -0
  203. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/parser.py +0 -0
  204. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/registry.py +0 -0
  205. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/slash_commands/types.py +0 -0
  206. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/__init__.py +0 -0
  207. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/__init__.py +0 -0
  208. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/artifact/__init__.py +0 -0
  209. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/artifact/default/__init__.py +0 -0
  210. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/artifact/default/normalizers.py +0 -0
  211. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/artifact/default/stage.py +0 -0
  212. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/artifact/default/validators.py +0 -0
  213. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/interface.py +0 -0
  214. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/normalizers.py +0 -0
  215. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/stage.py +0 -0
  216. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/types.py +0 -0
  217. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s01_input/validators.py +0 -0
  218. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/__init__.py +0 -0
  219. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/artifact/__init__.py +0 -0
  220. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/artifact/default/__init__.py +0 -0
  221. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/artifact/default/compactors.py +0 -0
  222. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/artifact/default/retrievers.py +0 -0
  223. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/artifact/default/stage.py +0 -0
  224. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/artifact/default/strategies.py +0 -0
  225. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/compactors.py +0 -0
  226. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/interface.py +0 -0
  227. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/retrievers.py +0 -0
  228. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/stage.py +0 -0
  229. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/strategies.py +0 -0
  230. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s02_context/types.py +0 -0
  231. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/__init__.py +0 -0
  232. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/artifact/__init__.py +0 -0
  233. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/artifact/default/__init__.py +0 -0
  234. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/artifact/default/builders.py +0 -0
  235. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/artifact/default/stage.py +0 -0
  236. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/builders.py +0 -0
  237. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/interface.py +0 -0
  238. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/persona/__init__.py +0 -0
  239. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/persona/builder.py +0 -0
  240. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/persona/provider.py +0 -0
  241. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s03_system/stage.py +0 -0
  242. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/__init__.py +0 -0
  243. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/artifact/__init__.py +0 -0
  244. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/artifact/default/__init__.py +0 -0
  245. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/artifact/default/guards.py +0 -0
  246. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/artifact/default/stage.py +0 -0
  247. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/guards.py +0 -0
  248. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/interface.py +0 -0
  249. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/stage.py +0 -0
  250. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s04_guard/types.py +0 -0
  251. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/__init__.py +0 -0
  252. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/artifact/__init__.py +0 -0
  253. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/artifact/default/__init__.py +0 -0
  254. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/artifact/default/stage.py +0 -0
  255. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/artifact/default/strategies.py +0 -0
  256. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/interface.py +0 -0
  257. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/stage.py +0 -0
  258. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s05_cache/strategies.py +0 -0
  259. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/__init__.py +0 -0
  260. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/_translate.py +0 -0
  261. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/__init__.py +0 -0
  262. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/default/__init__.py +0 -0
  263. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/default/providers.py +0 -0
  264. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/default/retry.py +0 -0
  265. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/default/router.py +0 -0
  266. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/default/stage.py +0 -0
  267. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/default/tool_loop.py +0 -0
  268. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/google/__init__.py +0 -0
  269. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/google/providers.py +0 -0
  270. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/openai/__init__.py +0 -0
  271. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/artifact/openai/providers.py +0 -0
  272. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/interface.py +0 -0
  273. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/providers.py +0 -0
  274. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/retry.py +0 -0
  275. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/stage.py +0 -0
  276. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s06_api/types.py +0 -0
  277. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/__init__.py +0 -0
  278. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/artifact/__init__.py +0 -0
  279. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/artifact/default/__init__.py +0 -0
  280. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/artifact/default/pricing.py +0 -0
  281. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/artifact/default/stage.py +0 -0
  282. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/artifact/default/trackers.py +0 -0
  283. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/interface.py +0 -0
  284. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/pricing.py +0 -0
  285. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/stage.py +0 -0
  286. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s07_token/trackers.py +0 -0
  287. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/__init__.py +0 -0
  288. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/artifact/default/__init__.py +0 -0
  289. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/artifact/default/budget.py +0 -0
  290. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/artifact/default/processors.py +0 -0
  291. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/artifact/default/stage.py +0 -0
  292. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/interface.py +0 -0
  293. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/processors.py +0 -0
  294. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/stage.py +0 -0
  295. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s08_think/types.py +0 -0
  296. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/__init__.py +0 -0
  297. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/artifact/default/__init__.py +0 -0
  298. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/artifact/default/parsers.py +0 -0
  299. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/artifact/default/signals.py +0 -0
  300. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/artifact/default/stage.py +0 -0
  301. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/interface.py +0 -0
  302. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/parsers.py +0 -0
  303. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/signals.py +0 -0
  304. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/stage.py +0 -0
  305. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s09_parse/types.py +0 -0
  306. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/__init__.py +0 -0
  307. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/artifact/__init__.py +0 -0
  308. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/artifact/default/__init__.py +0 -0
  309. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/artifact/default/executors.py +0 -0
  310. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/artifact/default/routers.py +0 -0
  311. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/artifact/default/stage.py +0 -0
  312. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/dispatcher.py +0 -0
  313. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/executors.py +0 -0
  314. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/interface.py +0 -0
  315. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/persistence.py +0 -0
  316. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/routers.py +0 -0
  317. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/stage.py +0 -0
  318. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/state_mutation.py +0 -0
  319. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s10_tool/streaming.py +0 -0
  320. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s11_tool_review/__init__.py +0 -0
  321. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s11_tool_review/artifact/__init__.py +0 -0
  322. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s11_tool_review/artifact/default/__init__.py +0 -0
  323. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s11_tool_review/artifact/default/reviewers.py +0 -0
  324. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s11_tool_review/artifact/default/stage.py +0 -0
  325. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s11_tool_review/interface.py +0 -0
  326. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/__init__.py +0 -0
  327. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/artifact/__init__.py +0 -0
  328. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/artifact/default/__init__.py +0 -0
  329. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/artifact/default/orchestrators.py +0 -0
  330. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/artifact/default/stage.py +0 -0
  331. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/interface.py +0 -0
  332. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/orchestrators.py +0 -0
  333. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/persistent_subagent.py +0 -0
  334. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/stage.py +0 -0
  335. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/subagent_catalog.py +0 -0
  336. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/subagent_type.py +0 -0
  337. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s12_agent/types.py +0 -0
  338. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/__init__.py +0 -0
  339. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/artifact/__init__.py +0 -0
  340. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/artifact/default/__init__.py +0 -0
  341. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/artifact/default/file_backed_registry.py +0 -0
  342. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/artifact/default/policies.py +0 -0
  343. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/artifact/default/registry.py +0 -0
  344. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/artifact/default/stage.py +0 -0
  345. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/interface.py +0 -0
  346. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s13_task_registry/types.py +0 -0
  347. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/__init__.py +0 -0
  348. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/artifact/__init__.py +0 -0
  349. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/artifact/adaptive/__init__.py +0 -0
  350. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/artifact/adaptive/strategy.py +0 -0
  351. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/artifact/default/__init__.py +0 -0
  352. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/artifact/default/stage.py +0 -0
  353. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/artifact/default/strategies.py +0 -0
  354. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/interface.py +0 -0
  355. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/stage.py +0 -0
  356. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/strategies.py +0 -0
  357. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s14_evaluate/types.py +0 -0
  358. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/__init__.py +0 -0
  359. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/artifact/__init__.py +0 -0
  360. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/artifact/default/__init__.py +0 -0
  361. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/artifact/default/requesters.py +0 -0
  362. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/artifact/default/stage.py +0 -0
  363. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/artifact/default/timeouts.py +0 -0
  364. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/interface.py +0 -0
  365. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s15_hitl/types.py +0 -0
  366. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/__init__.py +0 -0
  367. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/artifact/__init__.py +0 -0
  368. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/artifact/default/__init__.py +0 -0
  369. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/artifact/default/controllers.py +0 -0
  370. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/artifact/default/stage.py +0 -0
  371. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/controllers.py +0 -0
  372. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/interface.py +0 -0
  373. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s16_loop/stage.py +0 -0
  374. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/__init__.py +0 -0
  375. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/artifact/__init__.py +0 -0
  376. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/artifact/default/__init__.py +0 -0
  377. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/artifact/default/emitters.py +0 -0
  378. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/artifact/default/stage.py +0 -0
  379. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/emitters.py +0 -0
  380. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/interface.py +0 -0
  381. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/stage.py +0 -0
  382. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s17_emit/types.py +0 -0
  383. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/__init__.py +0 -0
  384. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/_dehydrate.py +0 -0
  385. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/artifact/__init__.py +0 -0
  386. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/artifact/default/__init__.py +0 -0
  387. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/artifact/default/persistence.py +0 -0
  388. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/artifact/default/stage.py +0 -0
  389. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/artifact/default/strategies.py +0 -0
  390. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/insight.py +0 -0
  391. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/interface.py +0 -0
  392. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/persistence.py +0 -0
  393. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/stage.py +0 -0
  394. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s18_memory/strategies.py +0 -0
  395. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/__init__.py +0 -0
  396. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/artifact/__init__.py +0 -0
  397. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/artifact/default/__init__.py +0 -0
  398. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/artifact/default/importance.py +0 -0
  399. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/artifact/default/stage.py +0 -0
  400. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/artifact/default/summarizers.py +0 -0
  401. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/frequency_policy.py +0 -0
  402. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/interface.py +0 -0
  403. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s19_summarize/types.py +0 -0
  404. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/__init__.py +0 -0
  405. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/artifact/__init__.py +0 -0
  406. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/artifact/default/__init__.py +0 -0
  407. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/artifact/default/frequencies.py +0 -0
  408. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/artifact/default/persisters.py +0 -0
  409. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/artifact/default/stage.py +0 -0
  410. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/interface.py +0 -0
  411. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/restore.py +0 -0
  412. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s20_persist/types.py +0 -0
  413. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/__init__.py +0 -0
  414. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/artifact/__init__.py +0 -0
  415. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/artifact/default/__init__.py +0 -0
  416. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/artifact/default/formatters.py +0 -0
  417. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/artifact/default/multi_format.py +0 -0
  418. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/artifact/default/stage.py +0 -0
  419. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/formatters.py +0 -0
  420. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/interface.py +0 -0
  421. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/stages/s21_yield/stage.py +0 -0
  422. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/__init__.py +0 -0
  423. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/_sandbox.py +0 -0
  424. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/adhoc.py +0 -0
  425. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/base.py +0 -0
  426. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/_path_guard.py +0 -0
  427. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/_web_search_backends.py +0 -0
  428. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/agent_tool.py +0 -0
  429. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/ask_user_question_tool.py +0 -0
  430. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/bash_tool.py +0 -0
  431. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/browser_tools.py +0 -0
  432. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/cron_tools.py +0 -0
  433. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/dev_tools.py +0 -0
  434. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/doc_tools.py +0 -0
  435. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/edit_tool.py +0 -0
  436. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/env_tools.py +0 -0
  437. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/glob_tool.py +0 -0
  438. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/google_tools.py +0 -0
  439. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/grep_tool.py +0 -0
  440. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/mcp_wrapper_tools.py +0 -0
  441. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/notebook_edit_tool.py +0 -0
  442. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/operator_tools.py +0 -0
  443. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/plan_mode_tools.py +0 -0
  444. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/push_notification_tool.py +0 -0
  445. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/read_tool.py +0 -0
  446. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/sandbox_exec_tool.py +0 -0
  447. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/send_message_tool.py +0 -0
  448. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/subagent_tools.py +0 -0
  449. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/task_tools.py +0 -0
  450. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/todo_write_tool.py +0 -0
  451. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/tool_search_tool.py +0 -0
  452. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/web_fetch_tool.py +0 -0
  453. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/web_search_tool.py +0 -0
  454. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/workspace_tools.py +0 -0
  455. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/worktree_tools.py +0 -0
  456. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/built_in/write_tool.py +0 -0
  457. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/composer.py +0 -0
  458. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/errors.py +0 -0
  459. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/__init__.py +0 -0
  460. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/adapter.py +0 -0
  461. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/credentials.py +0 -0
  462. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/errors.py +0 -0
  463. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/manager.py +0 -0
  464. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/oauth.py +0 -0
  465. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/state.py +0 -0
  466. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/mcp/uri.py +0 -0
  467. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/plugin.py +0 -0
  468. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/provider.py +0 -0
  469. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/providers.py +0 -0
  470. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/registry.py +0 -0
  471. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/sandbox.py +0 -0
  472. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/scope.py +0 -0
  473. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/tools/stage_binding.py +0 -0
  474. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/workspace/__init__.py +0 -0
  475. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/workspace/stack.py +0 -0
  476. {geny_executor-2.48.2 → geny_executor-2.49.0}/src/geny_executor/workspace/types.py +0 -0
  477. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/__init__.py +0 -0
  478. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/_fixtures/__init__.py +0 -0
  479. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/_fixtures/fake_claude.py +0 -0
  480. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/_fixtures/fake_echo_cli.py +0 -0
  481. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/_fixtures/geny_manifest_layout.json +0 -0
  482. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/_fixtures/manifest_entries.py +0 -0
  483. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/__init__.py +0 -0
  484. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/conftest.py +0 -0
  485. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/fixtures/__init__.py +0 -0
  486. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/fixtures/adapter/__init__.py +0 -0
  487. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/fixtures/adapter/adapter.py +0 -0
  488. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c1_six_layer_retrieval.py +0 -0
  489. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c2_execution_recording.py +0 -0
  490. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c3_reflection_and_promotion.py +0 -0
  491. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c4_rest_coverage.py +0 -0
  492. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c5_embedding_migration.py +0 -0
  493. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c6_session_resume.py +0 -0
  494. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_c7_adapter_parity.py +0 -0
  495. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/completeness/test_spec_loads.py +0 -0
  496. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/__init__.py +0 -0
  497. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/memory_provider_contract.py +0 -0
  498. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_embedding_clients.py +0 -0
  499. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_error_codes_stability.py +0 -0
  500. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_embedding_credentials.py +0 -0
  501. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_auto_vector.py +0 -0
  502. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_composite.py +0 -0
  503. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_composite_routing.py +0 -0
  504. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_curated_global.py +0 -0
  505. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_ephemeral.py +0 -0
  506. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_factory.py +0 -0
  507. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_file.py +0 -0
  508. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_file_layout.py +0 -0
  509. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_file_vector.py +0 -0
  510. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_sql.py +0 -0
  511. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_sql_dialect.py +0 -0
  512. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_sql_schema.py +0 -0
  513. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_provider_sql_vector.py +0 -0
  514. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_memory_vector_breaker.py +0 -0
  515. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/contract/test_stage_uniformity.py +0 -0
  516. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/integration/test_cycle_ab_cross_import.py +0 -0
  517. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/integration/test_integration.py +0 -0
  518. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/__init__.py +0 -0
  519. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/__init__.py +0 -0
  520. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/harness.py +0 -0
  521. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/test_anthropic.py +0 -0
  522. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/test_claude_code_cli.py +0 -0
  523. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/test_google.py +0 -0
  524. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/test_local_providers.py +0 -0
  525. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/test_openai.py +0 -0
  526. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/conformance/test_vllm.py +0 -0
  527. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/__init__.py +0 -0
  528. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/cli-2.1.149-json.json +0 -0
  529. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/cli-2.1.149-json.meta +0 -0
  530. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/cli-2.1.149-stream.jsonl +0 -0
  531. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/cli-2.1.149-stream.meta +0 -0
  532. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/cli-2.1.162-stream.jsonl +0 -0
  533. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/cli-2.1.162-stream.meta +0 -0
  534. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/golden/test_golden_replay.py +0 -0
  535. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/live/__init__.py +0 -0
  536. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/live/test_live_canaries.py +0 -0
  537. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/__init__.py +0 -0
  538. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_anthropic_build_kwargs.py +0 -0
  539. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_anthropic_classify.py +0 -0
  540. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_base_client.py +0 -0
  541. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_claude_code.py +0 -0
  542. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_cli_cancellation.py +0 -0
  543. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_cli_event_forwarding.py +0 -0
  544. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_cli_runtime.py +0 -0
  545. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_container_runner.py +0 -0
  546. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_credentials.py +0 -0
  547. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_google_classify.py +0 -0
  548. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_local_probe.py +0 -0
  549. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_local_tool_repair.py +0 -0
  550. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_openai_client.py +0 -0
  551. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_profiles.py +0 -0
  552. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/llm_client/unit/test_translators_cli_claude_code.py +0 -0
  553. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/__init__.py +0 -0
  554. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_adaptive_model_router.py +0 -0
  555. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_adaptive_router_configure.py +0 -0
  556. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_adaptive_thinking_budget.py +0 -0
  557. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_adhoc_providers.py +0 -0
  558. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_agent_tool.py +0 -0
  559. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_api_timeout_kwarg.py +0 -0
  560. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_artifact_metadata.py +0 -0
  561. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_ask_user_question_tool.py +0 -0
  562. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_attach_llm_client_guard.py +0 -0
  563. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_binary_classify_manifest.py +0 -0
  564. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_browser_doc_tools.py +0 -0
  565. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_budget_compaction_recovery.py +0 -0
  566. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_built_in_autoregister.py +0 -0
  567. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_builtin_capabilities.py +0 -0
  568. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_builtin_channels.py +0 -0
  569. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_builtin_features.py +0 -0
  570. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_cache_prefix_key.py +0 -0
  571. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_cancellation.py +0 -0
  572. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_claude_code_nonstream_prompt.py +0 -0
  573. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_claude_code_vision_wire.py +0 -0
  574. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_cli_mcp_passthrough.py +0 -0
  575. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_composite_set_hooks.py +0 -0
  576. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_concurrent_runs.py +0 -0
  577. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_config_liveness.py +0 -0
  578. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_core_deferred_tools.py +0 -0
  579. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_cron_runner.py +0 -0
  580. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_cron_store.py +0 -0
  581. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_cron_tools.py +0 -0
  582. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_dev_tools.py +0 -0
  583. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_diff_order_keyed.py +0 -0
  584. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_dynamic_persona_builder.py +0 -0
  585. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_embedding_error_classification.py +0 -0
  586. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_errors_categories.py +0 -0
  587. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_evaluation_chain.py +0 -0
  588. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_evaluation_chain_configure.py +0 -0
  589. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_event_catalog.py +0 -0
  590. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_event_channel_unification.py +0 -0
  591. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_event_correlation.py +0 -0
  592. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_external_tool_resolution.py +0 -0
  593. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_forge_tool.py +0 -0
  594. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_fork_multi_provider.py +0 -0
  595. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_from_manifest_strict_validation.py +0 -0
  596. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_gateway.py +0 -0
  597. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_gateway_ws.py +0 -0
  598. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_geny_prod_manifest_repro.py +0 -0
  599. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_graph_edges.py +0 -0
  600. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_graph_rank.py +0 -0
  601. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_guard_fail_fast.py +0 -0
  602. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_hierarchical_sidecars.py +0 -0
  603. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_hook_gate_split.py +0 -0
  604. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_hook_in_process.py +0 -0
  605. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_hook_runner.py +0 -0
  606. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_hook_taxonomy.py +0 -0
  607. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_hooks_and_shared_keys.py +0 -0
  608. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_host_selections_resolve.py +0 -0
  609. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_index_list_categories.py +0 -0
  610. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_index_render_vault_map.py +0 -0
  611. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_interaction_fields.py +0 -0
  612. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_internal_agentic_loop.py +0 -0
  613. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_introspection.py +0 -0
  614. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_client_base.py +0 -0
  615. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_client_capabilities.py +0 -0
  616. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_client_registry.py +0 -0
  617. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_client_request_types.py +0 -0
  618. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_client_state.py +0 -0
  619. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_compactor_selfwire.py +0 -0
  620. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_llm_summary_compactor.py +0 -0
  621. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_loop_agnostic_lock.py +0 -0
  622. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_factory.py +0 -0
  623. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_from_dict_hygiene.py +0 -0
  624. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_memory_wiring.py +0 -0
  625. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_provider_validation.py +0 -0
  626. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_subagents_memory_sections.py +0 -0
  627. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_v2.py +0 -0
  628. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_manifest_v3_migration.py +0 -0
  629. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_annotations_attach.py +0 -0
  630. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_credential_store.py +0 -0
  631. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_fsm.py +0 -0
  632. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_lifecycle.py +0 -0
  633. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_namespace.py +0 -0
  634. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_oauth.py +0 -0
  635. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_prompts_skills_bridge.py +0 -0
  636. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_resource_retriever.py +0 -0
  637. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_uri.py +0 -0
  638. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_mcp_wrapper_tools.py +0 -0
  639. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_memory_aware_retriever.py +0 -0
  640. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_memory_facts.py +0 -0
  641. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_memory_hooks_after_callbacks.py +0 -0
  642. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_memory_metadata_extension.py +0 -0
  643. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_memory_rollup.py +0 -0
  644. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_model_discovery.py +0 -0
  645. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_model_overrides.py +0 -0
  646. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_multi_dim_budget_configure.py +0 -0
  647. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_multi_dim_budget_controller.py +0 -0
  648. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_multi_format_yield.py +0 -0
  649. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_multi_provider.py +0 -0
  650. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_multimodal.py +0 -0
  651. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_note_graph_queries.py +0 -0
  652. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_notebook_edit_tool.py +0 -0
  653. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_notes_load_pinned.py +0 -0
  654. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_operator_tools.py +0 -0
  655. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_ordered_emitter_chain.py +0 -0
  656. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_permission_matrix.py +0 -0
  657. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_permission_mode_promotions.py +0 -0
  658. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_permission_posture.py +0 -0
  659. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_persistent_subagent.py +0 -0
  660. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase1_foundation.py +0 -0
  661. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase1_pipeline.py +0 -0
  662. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase2_agent_loop.py +0 -0
  663. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase2_tools.py +0 -0
  664. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase3_context_memory.py +0 -0
  665. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase4_think_agent_evaluate.py +0 -0
  666. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase5_emit_presets_mcp.py +0 -0
  667. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase5_environment.py +0 -0
  668. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase6_history.py +0 -0
  669. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase6_integration.py +0 -0
  670. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase7_security.py +0 -0
  671. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase9a_preset_regen.py +0 -0
  672. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_phase9a_scaffolding.py +0 -0
  673. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_pipeline_aclose.py +0 -0
  674. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_pipeline_attach_runtime.py +0 -0
  675. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_pipeline_events_tap.py +0 -0
  676. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_pipeline_from_manifest.py +0 -0
  677. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_pipeline_hook_lifecycle.py +0 -0
  678. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_pipeline_session_runtime.py +0 -0
  679. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_plan_mode_tools.py +0 -0
  680. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_primary_provider_and_build_reports.py +0 -0
  681. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_progressive_disclosure.py +0 -0
  682. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_provider_driven_strategy.py +0 -0
  683. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_push_notification_tool.py +0 -0
  684. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_qdrant_vector_store.py +0 -0
  685. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_refresh_backlinks_extension.py +0 -0
  686. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_refresh_runtime_and_run_lock.py +0 -0
  687. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_resolve_model_config.py +0 -0
  688. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_restore_bad_strategy_config.py +0 -0
  689. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_reviewer_policy_configure.py +0 -0
  690. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_runtime_task_runner.py +0 -0
  691. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s06_chunk_forwarding.py +0 -0
  692. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s06_provider_selection.py +0 -0
  693. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s13_file_backed_registry.py +0 -0
  694. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s13_task_registry_output.py +0 -0
  695. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s19_frequency_policy.py +0 -0
  696. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9b1_tool_review.py +0 -0
  697. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9b2_task_registry.py +0 -0
  698. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9b3_hitl.py +0 -0
  699. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9b4_summarize.py +0 -0
  700. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9b5_persist.py +0 -0
  701. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9c1_pipeline_resume.py +0 -0
  702. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_s9c2_restore_state.py +0 -0
  703. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_sandbox_attach.py +0 -0
  704. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_sandbox_exec_tool.py +0 -0
  705. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_sandbox_tools.py +0 -0
  706. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_self_modifying_env.py +0 -0
  707. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_send_message_tool.py +0 -0
  708. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_settings_loader.py +0 -0
  709. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_level3_resources.py +0 -0
  710. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_1.py +0 -0
  711. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_2.py +0 -0
  712. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_3.py +0 -0
  713. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_4_bundled.py +0 -0
  714. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_5_fork.py +0 -0
  715. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_6_killer.py +0 -0
  716. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_phase_10_7_watcher.py +0 -0
  717. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_richer_schema.py +0 -0
  718. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skill_tool.py +0 -0
  719. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_skills_foundation.py +0 -0
  720. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_slash_built_in_control.py +0 -0
  721. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_slash_built_in_introspection.py +0 -0
  722. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_slash_commands.py +0 -0
  723. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_slash_md_template.py +0 -0
  724. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_stage10_ask_hitl.py +0 -0
  725. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_stage10_hook_wiring.py +0 -0
  726. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_stage10_partition_executor.py +0 -0
  727. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_stage10_permission_matrix.py +0 -0
  728. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_stage19_session_summary.py +0 -0
  729. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_state_mutation_wiring.py +0 -0
  730. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_state_shared_and_local.py +0 -0
  731. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_stm_append_event.py +0 -0
  732. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_strategy_config_roundtrip.py +0 -0
  733. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_streaming_tool_executor.py +0 -0
  734. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_structured_output_parser.py +0 -0
  735. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_structured_reflection.py +0 -0
  736. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_catalog.py +0 -0
  737. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_credential_propagation.py +0 -0
  738. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_descriptor.py +0 -0
  739. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_manifest_compile.py +0 -0
  740. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_orchestrator_zero_arg.py +0 -0
  741. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_parallel.py +0 -0
  742. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_pipeline_lifecycle.py +0 -0
  743. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_subagent_type_orchestrator.py +0 -0
  744. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_task_tools.py +0 -0
  745. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_todo_write_tool.py +0 -0
  746. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_abc_uplift.py +0 -0
  747. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_call_events.py +0 -0
  748. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_errors.py +0 -0
  749. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_lifecycle_hooks.py +0 -0
  750. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_plugins.py +0 -0
  751. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_provider.py +0 -0
  752. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_result_persistence.py +0 -0
  753. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_search_tool.py +0 -0
  754. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_tool_stage_max_concurrency.py +0 -0
  755. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_turn_boundary_state.py +0 -0
  756. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_validate_manifest.py +0 -0
  757. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_vault_map_drill.py +0 -0
  758. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_web_fetch_tool.py +0 -0
  759. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_web_search_backends.py +0 -0
  760. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_web_search_tool.py +0 -0
  761. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_workspace.py +0 -0
  762. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_workspace_propagation.py +0 -0
  763. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_workspace_tools.py +0 -0
  764. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_workspace_tools_integration.py +0 -0
  765. {geny_executor-2.48.2 → geny_executor-2.49.0}/tests/unit/test_worktree_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geny-executor
3
- Version: 2.48.2
3
+ Version: 2.49.0
4
4
  Summary: Harness-engineered agent pipeline library with 21-stage dual-abstraction architecture, built on the Anthropic API
5
5
  Project-URL: Homepage, https://github.com/CocoRoF/geny-executor
6
6
  Project-URL: Repository, https://github.com/CocoRoF/geny-executor
@@ -40,6 +40,7 @@ Requires-Dist: websockets>=12.0
40
40
  Provides-Extra: browser
41
41
  Requires-Dist: an-web>=0.9.1; (python_version >= '3.12') and extra == 'browser'
42
42
  Provides-Extra: dev
43
+ Requires-Dist: asyncssh>=2.14; extra == 'dev'
43
44
  Requires-Dist: mypy>=1.10; extra == 'dev'
44
45
  Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
45
46
  Requires-Dist: pytest-cov>=5.0; extra == 'dev'
@@ -49,6 +50,8 @@ Provides-Extra: docs
49
50
  Requires-Dist: edit2docs>=0.6.0; extra == 'docs'
50
51
  Provides-Extra: qdrant
51
52
  Requires-Dist: qdrant-client>=1.12.0; extra == 'qdrant'
53
+ Provides-Extra: ssh
54
+ Requires-Dist: asyncssh>=2.14; extra == 'ssh'
52
55
  Description-Content-Type: text/markdown
53
56
 
54
57
  # geny-executor
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "geny-executor"
7
- version = "2.48.2"
7
+ version = "2.49.0"
8
8
  description = "Harness-engineered agent pipeline library with 21-stage dual-abstraction architecture, built on the Anthropic API"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -87,12 +87,18 @@ browser = [
87
87
  docs = [
88
88
  "edit2docs>=0.6.0",
89
89
  ]
90
+ # Ssh* built-ins — remote command/SFTP over SSH. Pure-async (asyncssh),
91
+ # lazy-imported so the core install stays lean.
92
+ ssh = [
93
+ "asyncssh>=2.14",
94
+ ]
90
95
  dev = [
91
96
  "pytest>=8.0",
92
97
  "pytest-asyncio>=0.24",
93
98
  "pytest-cov>=5.0",
94
99
  "ruff>=0.4.0",
95
100
  "mypy>=1.10",
101
+ "asyncssh>=2.14",
96
102
  ]
97
103
 
98
104
  [project.urls]
@@ -34,9 +34,10 @@ re-attempted the call and logged a full traceback, forever.
34
34
 
35
35
  from __future__ import annotations
36
36
 
37
+ import asyncio
37
38
  import logging
38
39
  import os
39
- from typing import List, Protocol, Sequence, runtime_checkable
40
+ from typing import List, Optional, Protocol, Sequence, runtime_checkable
40
41
 
41
42
  from geny_executor.memory.provider import CostEvent, EmbeddingDescriptor
42
43
 
@@ -148,6 +149,93 @@ def _resolve_env_api_key(provider: str, *env_vars: str) -> str:
148
149
  return ""
149
150
 
150
151
 
152
+ class _LoopBoundClientMixin:
153
+ """Loop-safe caching for httpx-backed embedding SDK clients.
154
+
155
+ An httpx-based SDK client (``AsyncOpenAI``, ``genai.Client``) binds its
156
+ transport/connection-pool to the event loop that first drives it and
157
+ cannot be reused from another loop — a later call on a different loop
158
+ raises ``RuntimeError: Event loop is closed`` / "Future attached to a
159
+ different loop". Hosts that drive memory writes through a sync→async
160
+ bridge (Geny's ``run_coro_sync``) spin a fresh, short-lived event loop
161
+ **per call**, so a single cached client would (a) fail cross-loop on
162
+ every bridged embed and (b), never being closed, leak its socket pool
163
+ once per session.
164
+
165
+ Strategy:
166
+ * Cache ONE client on the loop that first uses it — almost always the
167
+ stable server loop, where the vast majority of embeds happen
168
+ (search, the memory stage). That loop's calls reuse it, so
169
+ connection pooling is preserved.
170
+ * If the cached client's loop is found dead, drop the reference (its
171
+ transport is finalized by GC) and rebind to the current loop. An
172
+ all-bridge caller (only ever ephemeral loops) therefore rebinds
173
+ each call instead of accumulating clients.
174
+ * Any OTHER still-live loop gets a short-lived client that the caller
175
+ closes within the same call (``ephemeral=True``) — never drive one
176
+ client's transport from two loops.
177
+
178
+ Subclasses set ``self._client`` / ``self._client_loop`` /
179
+ ``self._injected_client`` in ``__init__`` and implement
180
+ ``_build_client()``. A test-injected client (``_injected_client``) is
181
+ used verbatim and never rebuilt or auto-closed — the caller owns it.
182
+ """
183
+
184
+ _client: Optional[object] = None
185
+ _client_loop: Optional[asyncio.AbstractEventLoop] = None
186
+ _injected_client: bool = False
187
+
188
+ def _build_client(self) -> object:
189
+ raise NotImplementedError
190
+
191
+ def _acquire_client(self):
192
+ """Return ``(client, ephemeral)`` bound to the CURRENT running loop.
193
+
194
+ ``ephemeral`` clients MUST be closed by the caller (see
195
+ ``_aclose_client``) before the coroutine returns.
196
+ """
197
+ if self._injected_client:
198
+ return self._client, False
199
+ loop = asyncio.get_running_loop()
200
+ cached = self._client
201
+ if cached is not None:
202
+ if self._client_loop is loop and not loop.is_closed():
203
+ return cached, False # hot path: pooled client on its loop
204
+ if self._client_loop is None or self._client_loop.is_closed():
205
+ # Cached loop is dead — drop so GC finalizes its transport,
206
+ # then rebind to this loop below.
207
+ self._client = None
208
+ self._client_loop = None
209
+ cached = None
210
+ if cached is None:
211
+ self._client = self._build_client()
212
+ self._client_loop = loop
213
+ return self._client, False
214
+ # Cache valid but bound to a different, still-live loop → ephemeral.
215
+ return self._build_client(), True
216
+
217
+ async def _aclose_client(self, client: object) -> None:
218
+ closer = getattr(client, "close", None)
219
+ if closer is None:
220
+ return
221
+ try:
222
+ result = closer()
223
+ if asyncio.iscoroutine(result):
224
+ await result
225
+ except Exception: # noqa: BLE001 — close is best-effort
226
+ logger.debug("embedding client close failed", exc_info=True)
227
+
228
+ async def _close_cached_client(self) -> None:
229
+ """Release the cached client (``close()`` surface). No-op for an
230
+ injected client — its lifetime belongs to the caller."""
231
+ client = self._client
232
+ self._client = None
233
+ self._client_loop = None
234
+ if client is None or self._injected_client:
235
+ return
236
+ await self._aclose_client(client)
237
+
238
+
151
239
  __all__ = [
152
240
  "EmbeddingClient",
153
241
  "EmbeddingError",
@@ -15,6 +15,7 @@ from typing import Any, List, Optional, Sequence
15
15
  from geny_executor.memory.embedding.client import (
16
16
  EmbeddingClient,
17
17
  EmbeddingError,
18
+ _LoopBoundClientMixin,
18
19
  _resolve_env_api_key,
19
20
  )
20
21
  from geny_executor.memory.provider import EmbeddingDescriptor
@@ -27,7 +28,7 @@ _GOOGLE_DIMS = {
27
28
  }
28
29
 
29
30
 
30
- class GoogleEmbeddingClient(EmbeddingClient):
31
+ class GoogleEmbeddingClient(_LoopBoundClientMixin, EmbeddingClient):
31
32
  """Google Generative AI embeddings."""
32
33
 
33
34
  def __init__(
@@ -45,7 +46,10 @@ class GoogleEmbeddingClient(EmbeddingClient):
45
46
  "google", "GOOGLE_API_KEY", "GEMINI_API_KEY"
46
47
  )
47
48
  self._dimension = dimension or _GOOGLE_DIMS.get(model, 0)
49
+ # Loop-safe client cache (see _LoopBoundClientMixin).
48
50
  self._client = client
51
+ self._client_loop = None
52
+ self._injected_client = client is not None
49
53
  self._descriptor = EmbeddingDescriptor(
50
54
  provider="google",
51
55
  model=model,
@@ -61,43 +65,47 @@ class GoogleEmbeddingClient(EmbeddingClient):
61
65
  async def embed(self, texts: Sequence[str]) -> List[List[float]]:
62
66
  if not texts:
63
67
  return []
64
- client = self._ensure_client()
68
+ # Loop-safe: pooled client on the stable loop, ephemeral (closed
69
+ # below) on a sync-bridge loop.
70
+ client, ephemeral = self._acquire_client()
65
71
  try:
66
- # google-genai v1: `client.aio.models.embed_content(...)`
67
- resp = await client.aio.models.embed_content(
68
- model=self._model,
69
- contents=list(texts),
70
- )
71
- except Exception as exc:
72
- raise EmbeddingError(f"google embed failed: {exc}") from exc
73
- embeds = getattr(resp, "embeddings", None)
74
- if embeds is None:
75
- raise EmbeddingError(f"google embed: missing 'embeddings' in {resp!r}")
76
- vectors: List[List[float]] = []
77
- for item in embeds:
78
- values = getattr(item, "values", None)
79
- if values is None:
80
- raise EmbeddingError(f"google embed: bad row: {item!r}")
81
- vectors.append([float(x) for x in values])
82
- if self._dimension == 0 and vectors:
83
- self._dimension = len(vectors[0])
84
- self._descriptor = EmbeddingDescriptor(
85
- provider="google",
86
- model=self._model,
87
- dimension=self._dimension,
88
- metric="cosine",
89
- api_key_present=bool(self._api_key),
90
- )
91
- return vectors
72
+ try:
73
+ # google-genai v1: `client.aio.models.embed_content(...)`
74
+ resp = await client.aio.models.embed_content(
75
+ model=self._model,
76
+ contents=list(texts),
77
+ )
78
+ except Exception as exc:
79
+ raise EmbeddingError(f"google embed failed: {exc}") from exc
80
+ embeds = getattr(resp, "embeddings", None)
81
+ if embeds is None:
82
+ raise EmbeddingError(f"google embed: missing 'embeddings' in {resp!r}")
83
+ vectors: List[List[float]] = []
84
+ for item in embeds:
85
+ values = getattr(item, "values", None)
86
+ if values is None:
87
+ raise EmbeddingError(f"google embed: bad row: {item!r}")
88
+ vectors.append([float(x) for x in values])
89
+ if self._dimension == 0 and vectors:
90
+ self._dimension = len(vectors[0])
91
+ self._descriptor = EmbeddingDescriptor(
92
+ provider="google",
93
+ model=self._model,
94
+ dimension=self._dimension,
95
+ metric="cosine",
96
+ api_key_present=bool(self._api_key),
97
+ )
98
+ return vectors
99
+ finally:
100
+ if ephemeral:
101
+ await self._aclose_client(client)
92
102
 
93
103
  async def close(self) -> None:
94
- return None
104
+ await self._close_cached_client()
95
105
 
96
106
  # ── internal ────────────────────────────────────────────────────
97
107
 
98
- def _ensure_client(self):
99
- if self._client is not None:
100
- return self._client
108
+ def _build_client(self) -> object:
101
109
  try:
102
110
  from google import genai # type: ignore
103
111
  except ImportError as exc:
@@ -105,8 +113,7 @@ class GoogleEmbeddingClient(EmbeddingClient):
105
113
  "GoogleEmbeddingClient requires `google-genai`. "
106
114
  "Install via `pip install geny-executor[google]`."
107
115
  ) from exc
108
- self._client = genai.Client(api_key=self._api_key or None)
109
- return self._client
116
+ return genai.Client(api_key=self._api_key or None)
110
117
 
111
118
 
112
119
  __all__ = ["GoogleEmbeddingClient"]
@@ -13,13 +13,13 @@ keep request bodies reasonable and allow resume on partial failures.
13
13
 
14
14
  from __future__ import annotations
15
15
 
16
- import asyncio
17
16
  import logging
18
17
  from typing import List, Optional, Sequence
19
18
 
20
19
  from geny_executor.memory.embedding.client import (
21
20
  EmbeddingClient,
22
21
  EmbeddingError,
22
+ _LoopBoundClientMixin,
23
23
  _resolve_env_api_key,
24
24
  )
25
25
  from geny_executor.memory.provider import EmbeddingDescriptor
@@ -71,7 +71,7 @@ _OPENAI_DIMS = {
71
71
  }
72
72
 
73
73
 
74
- class OpenAIEmbeddingClient(EmbeddingClient):
74
+ class OpenAIEmbeddingClient(_LoopBoundClientMixin, EmbeddingClient):
75
75
  """OpenAI embeddings via the official SDK."""
76
76
 
77
77
  def __init__(
@@ -89,7 +89,12 @@ class OpenAIEmbeddingClient(EmbeddingClient):
89
89
  # it logs a one-time migration warning (audit §2.6).
90
90
  self._api_key = api_key or _resolve_env_api_key("openai", "OPENAI_API_KEY")
91
91
  self._dimension = dimension or _OPENAI_DIMS.get(model, 0)
92
+ # Loop-safe client cache (see _LoopBoundClientMixin). A caller-
93
+ # supplied client is used verbatim (tests); otherwise lazily built
94
+ # per-loop by _build_client below.
92
95
  self._client = client
96
+ self._client_loop = None
97
+ self._injected_client = client is not None
93
98
  self._descriptor = EmbeddingDescriptor(
94
99
  provider="openai",
95
100
  model=model,
@@ -105,51 +110,47 @@ class OpenAIEmbeddingClient(EmbeddingClient):
105
110
  async def embed(self, texts: Sequence[str]) -> List[List[float]]:
106
111
  if not texts:
107
112
  return []
108
- client = self._ensure_client()
109
- out: List[List[float]] = []
110
- # Bound each input to the model's token budget so one over-long
111
- # text can never 400 the whole batch (crash-safety net).
112
- texts = [_bound_input(t) for t in texts]
113
- for i in range(0, len(texts), MAX_BATCH_SIZE):
114
- batch = list(texts[i : i + MAX_BATCH_SIZE])
115
- try:
116
- # `openai>=1.x` exposes `await client.embeddings.create(...)`
117
- resp = await client.embeddings.create(input=batch, model=self._model)
118
- except Exception as exc: # narrow is SDK-dependent
119
- raise EmbeddingError(
120
- f"openai embed failed: {exc}",
121
- category=_classify_openai_error(exc),
122
- ) from exc
123
- # SDK response: `data: List[Embedding(embedding: List[float])]`
124
- out.extend(item.embedding for item in resp.data)
125
- # Update descriptor dimension if we learned it at runtime
126
- if self._dimension == 0 and out:
127
- self._dimension = len(out[0])
128
- self._descriptor = EmbeddingDescriptor(
129
- provider="openai",
130
- model=self._model,
131
- dimension=self._dimension,
132
- metric="cosine",
133
- api_key_present=bool(self._api_key),
134
- )
135
- return out
113
+ # Loop-safe: a pooled client on the stable loop, or a short-lived
114
+ # client on an ephemeral (sync-bridge) loop that we close below.
115
+ client, ephemeral = self._acquire_client()
116
+ try:
117
+ out: List[List[float]] = []
118
+ # Bound each input to the model's token budget so one over-long
119
+ # text can never 400 the whole batch (crash-safety net).
120
+ texts = [_bound_input(t) for t in texts]
121
+ for i in range(0, len(texts), MAX_BATCH_SIZE):
122
+ batch = list(texts[i : i + MAX_BATCH_SIZE])
123
+ try:
124
+ # `openai>=1.x` exposes `await client.embeddings.create(...)`
125
+ resp = await client.embeddings.create(input=batch, model=self._model)
126
+ except Exception as exc: # narrow is SDK-dependent
127
+ raise EmbeddingError(
128
+ f"openai embed failed: {exc}",
129
+ category=_classify_openai_error(exc),
130
+ ) from exc
131
+ # SDK response: `data: List[Embedding(embedding: List[float])]`
132
+ out.extend(item.embedding for item in resp.data)
133
+ # Update descriptor dimension if we learned it at runtime
134
+ if self._dimension == 0 and out:
135
+ self._dimension = len(out[0])
136
+ self._descriptor = EmbeddingDescriptor(
137
+ provider="openai",
138
+ model=self._model,
139
+ dimension=self._dimension,
140
+ metric="cosine",
141
+ api_key_present=bool(self._api_key),
142
+ )
143
+ return out
144
+ finally:
145
+ if ephemeral:
146
+ await self._aclose_client(client)
136
147
 
137
148
  async def close(self) -> None:
138
- client = self._client
139
- if client is None:
140
- return
141
- closer = getattr(client, "close", None)
142
- if closer is None:
143
- return
144
- result = closer()
145
- if asyncio.iscoroutine(result):
146
- await result
149
+ await self._close_cached_client()
147
150
 
148
151
  # ── internal ────────────────────────────────────────────────────
149
152
 
150
- def _ensure_client(self):
151
- if self._client is not None:
152
- return self._client
153
+ def _build_client(self) -> object:
153
154
  try:
154
155
  from openai import AsyncOpenAI # type: ignore
155
156
  except ImportError as exc:
@@ -157,8 +158,7 @@ class OpenAIEmbeddingClient(EmbeddingClient):
157
158
  "OpenAIEmbeddingClient requires the `openai` package. "
158
159
  "Install via `pip install geny-executor[openai]`."
159
160
  ) from exc
160
- self._client = AsyncOpenAI(api_key=self._api_key or None)
161
- return self._client
161
+ return AsyncOpenAI(api_key=self._api_key or None)
162
162
 
163
163
 
164
164
  def _classify_openai_error(exc: Exception) -> str:
@@ -185,8 +185,21 @@ class FileMemoryProvider(MemoryProvider):
185
185
  self._initialized = True
186
186
 
187
187
  async def close(self) -> None:
188
- # All writes are flushed at op time; nothing to do.
189
- return None
188
+ # Writes are flushed at op time, so the stores need no teardown —
189
+ # but the embedding client owns an httpx connection pool (sockets)
190
+ # that must be released, or every session/restore leaks one client.
191
+ # The vector store shares THIS exact client instance (built with
192
+ # ``client=self._embedding_client``), so this is the single release
193
+ # point. Best-effort: a broken/cross-loop client must not turn
194
+ # session teardown into an error.
195
+ client = self._embedding_client
196
+ self._embedding_client = None
197
+ if client is None:
198
+ return
199
+ try:
200
+ await client.close()
201
+ except Exception: # noqa: BLE001
202
+ logger.debug("embedding client close failed during provider close", exc_info=True)
190
203
 
191
204
  # ── layer handles ───────────────────────────────────────────────
192
205
 
@@ -0,0 +1,215 @@
1
+ """Low-level SSH primitives for the built-in SSH tools.
2
+
3
+ Pure-async, built on ``asyncssh`` (native asyncio — no thread offload, so it
4
+ drops straight into a tool's ``async def execute``). Mirrors the shape of
5
+ ``tools/_sandbox.py``: small helpers that open a connection, run a command (or
6
+ transfer a file), and return a ``(rc, stdout, stderr)`` triple, with all output
7
+ shaping/truncation left to the caller.
8
+
9
+ ``asyncssh`` is an OPTIONAL dependency (extra ``ssh``). It is imported lazily so
10
+ the core install stays lean; callers get :class:`SSHUnavailableError` (a clean
11
+ install hint) when it is absent, never an ``ImportError`` at import time.
12
+
13
+ A "server" here is a plain dict — the credential record resolved by name from
14
+ the per-session store (see ``tools/built_in/_ssh_store.py``):
15
+
16
+ {"name", "host", "port"?, "user", "password"?, "private_key"?,
17
+ "passphrase"?, "description"?, "strict_host_key"?}
18
+
19
+ At least one of ``password`` / ``private_key`` must be present. The password
20
+ never leaves this module (it is fed to the transport / to ``sudo -S`` on
21
+ stdin), so the agent — which only ever passes a server *name* — never handles
22
+ it.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import asyncio
28
+ import shlex
29
+ import time
30
+ from typing import Any, Dict, Optional, Tuple
31
+
32
+
33
+ class SSHUnavailableError(RuntimeError):
34
+ """Raised when the optional ``asyncssh`` dependency is not installed."""
35
+
36
+
37
+ class SSHConfigError(ValueError):
38
+ """Raised when a server record is malformed (missing host/creds, bad key)."""
39
+
40
+
41
+ _INSTALL_HINT = (
42
+ "SSH tools require the `asyncssh` package. Install it via "
43
+ "`pip install geny-executor[ssh]`."
44
+ )
45
+
46
+
47
+ def _require_asyncssh():
48
+ try:
49
+ import asyncssh # type: ignore
50
+ except ImportError as exc: # pragma: no cover - env dependent
51
+ raise SSHUnavailableError(_INSTALL_HINT) from exc
52
+ return asyncssh
53
+
54
+
55
+ def _connect_kwargs(server: Dict[str, Any], *, connect_timeout: float) -> Tuple[str, Dict[str, Any]]:
56
+ """Build ``(host, asyncssh.connect kwargs)`` from a server record.
57
+
58
+ Host-key verification is DISABLED by default (``known_hosts=None``) so a
59
+ user's own freshly-provisioned server "just works" on first contact; set
60
+ ``strict_host_key: true`` on the record to opt back into verification.
61
+ """
62
+ asyncssh = _require_asyncssh()
63
+ host = str(server.get("host") or "").strip()
64
+ if not host:
65
+ raise SSHConfigError("server record has no 'host'")
66
+ try:
67
+ port = int(server.get("port") or 22)
68
+ except (TypeError, ValueError):
69
+ raise SSHConfigError(f"invalid 'port': {server.get('port')!r}")
70
+ username = str(server.get("user") or server.get("username") or "").strip() or None
71
+
72
+ kwargs: Dict[str, Any] = {
73
+ "port": port,
74
+ "username": username,
75
+ "connect_timeout": connect_timeout,
76
+ }
77
+ # known_hosts=None disables host-key checking; opt-in strict mode uses the
78
+ # default system known_hosts.
79
+ if not server.get("strict_host_key"):
80
+ kwargs["known_hosts"] = None
81
+
82
+ password = server.get("password") or None
83
+ private_key = server.get("private_key") or None
84
+ if private_key:
85
+ passphrase = server.get("passphrase") or None
86
+ try:
87
+ key = asyncssh.import_private_key(private_key, passphrase)
88
+ except Exception as exc: # noqa: BLE001 — surface a clean config error
89
+ raise SSHConfigError(f"invalid private_key: {exc}") from exc
90
+ kwargs["client_keys"] = [key]
91
+ if password: # allow key + password (e.g. key + sudo password)
92
+ kwargs["password"] = password
93
+ elif password:
94
+ kwargs["password"] = password
95
+ else:
96
+ raise SSHConfigError("server record has neither 'password' nor 'private_key'")
97
+
98
+ return host, kwargs
99
+
100
+
101
+ async def _open(server: Dict[str, Any], *, connect_timeout: float):
102
+ """Open an asyncssh connection for *server* (caller manages the context)."""
103
+ asyncssh = _require_asyncssh()
104
+ host, kwargs = _connect_kwargs(server, connect_timeout=connect_timeout)
105
+ return await asyncssh.connect(host, **kwargs)
106
+
107
+
108
+ def _remote_command(command: str, *, cwd: Optional[str], sudo: bool, password: Optional[str]) -> Tuple[str, Optional[str]]:
109
+ """Compose the remote command string + optional stdin (sudo password)."""
110
+ inner = command
111
+ if cwd:
112
+ inner = f"cd {shlex.quote(cwd)} && {command}"
113
+ if sudo:
114
+ # -S reads the password from stdin; -p '' suppresses the prompt so it
115
+ # can't pollute stdout. Wrap in a login shell so pipes/&&/redirs work.
116
+ remote = f"sudo -S -p '' /bin/sh -c {shlex.quote(inner)}"
117
+ return remote, (password or "") + "\n"
118
+ return inner, None
119
+
120
+
121
+ async def ssh_exec(
122
+ server: Dict[str, Any],
123
+ command: str,
124
+ *,
125
+ timeout: float = 60.0,
126
+ cwd: Optional[str] = None,
127
+ sudo: bool = False,
128
+ connect_timeout: float = 15.0,
129
+ ) -> Tuple[int, str, str]:
130
+ """Run *command* on *server*; return ``(exit_code, stdout, stderr)``.
131
+
132
+ ``sudo=True`` runs it under ``sudo -S`` with the server's stored password
133
+ fed on stdin — the agent never sees the password.
134
+ """
135
+ async with await _open(server, connect_timeout=connect_timeout) as conn:
136
+ remote, run_input = _remote_command(
137
+ command, cwd=cwd, sudo=sudo, password=server.get("password")
138
+ )
139
+ result = await asyncio.wait_for(
140
+ conn.run(remote, input=run_input, check=False), timeout=timeout
141
+ )
142
+ rc = result.exit_status
143
+ # exit_status is None on signal termination; map to 137-style non-zero.
144
+ if rc is None:
145
+ rc = 128 + int(result.exit_signal[1]) if getattr(result, "exit_signal", None) else 1
146
+ return int(rc), str(result.stdout or ""), str(result.stderr or "")
147
+
148
+
149
+ async def ssh_test_connection(
150
+ server: Dict[str, Any], *, connect_timeout: float = 15.0
151
+ ) -> Dict[str, Any]:
152
+ """Open a connection and run a trivial command to verify reachability +
153
+ auth. Returns ``{success, latency_ms, error?}`` — never raises."""
154
+ start = time.monotonic()
155
+ try:
156
+ async with await _open(server, connect_timeout=connect_timeout) as conn:
157
+ r = await asyncio.wait_for(
158
+ conn.run("echo geny-ssh-ok", check=False), timeout=connect_timeout
159
+ )
160
+ latency_ms = (time.monotonic() - start) * 1000.0
161
+ ok = (r.exit_status == 0) and ("geny-ssh-ok" in str(r.stdout or ""))
162
+ out: Dict[str, Any] = {"success": bool(ok), "latency_ms": round(latency_ms, 1)}
163
+ if not ok:
164
+ out["error"] = "connected but test command failed"
165
+ return out
166
+ except SSHUnavailableError as exc:
167
+ return {"success": False, "error": str(exc)}
168
+ except SSHConfigError as exc:
169
+ return {"success": False, "error": f"config: {exc}"}
170
+ except asyncio.TimeoutError:
171
+ return {"success": False, "error": f"timed out after {connect_timeout:.0f}s"}
172
+ except Exception as exc: # noqa: BLE001 — auth/network/etc → friendly string
173
+ return {"success": False, "error": _friendly_error(exc)}
174
+
175
+
176
+ async def sftp_put(
177
+ server: Dict[str, Any], local_path: str, remote_path: str, *, connect_timeout: float = 15.0
178
+ ) -> None:
179
+ async with await _open(server, connect_timeout=connect_timeout) as conn:
180
+ async with conn.start_sftp_client() as sftp:
181
+ await sftp.put(local_path, remote_path)
182
+
183
+
184
+ async def sftp_get(
185
+ server: Dict[str, Any], remote_path: str, local_path: str, *, connect_timeout: float = 15.0
186
+ ) -> None:
187
+ async with await _open(server, connect_timeout=connect_timeout) as conn:
188
+ async with conn.start_sftp_client() as sftp:
189
+ await sftp.get(remote_path, local_path)
190
+
191
+
192
+ def _friendly_error(exc: Exception) -> str:
193
+ """Map common asyncssh/OS errors to a short, safe message (no secrets)."""
194
+ name = type(exc).__name__
195
+ msg = str(exc).strip() or name
196
+ lowered = msg.lower()
197
+ if "permission denied" in lowered or "authentication" in lowered or name == "PermissionDenied":
198
+ return "authentication failed (check user / password / key)"
199
+ if "name or service not known" in lowered or "nodename nor servname" in lowered:
200
+ return "host not found (check host / DNS)"
201
+ if "connection refused" in lowered:
202
+ return "connection refused (is SSH listening on that host/port?)"
203
+ if "timed out" in lowered or name == "TimeoutError":
204
+ return "connection timed out"
205
+ return f"{name}: {msg}"
206
+
207
+
208
+ __all__ = [
209
+ "SSHUnavailableError",
210
+ "SSHConfigError",
211
+ "ssh_exec",
212
+ "ssh_test_connection",
213
+ "sftp_put",
214
+ "sftp_get",
215
+ ]