agentirc-cli 4.1.1__tar.gz → 4.1.2__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 (307) hide show
  1. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/CHANGELOG.md +7 -0
  2. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/PKG-INFO +1 -1
  3. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/agent_runner.py +4 -0
  4. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/daemon.py +6 -0
  5. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/agent_runner.py +4 -0
  6. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/daemon.py +6 -0
  7. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/agent_runner.py +4 -0
  8. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/daemon.py +6 -0
  9. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/daemon.py +9 -0
  10. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/pyproject.toml +1 -1
  11. agentirc_cli-4.1.2/tests/test_mention_target_cleanup.py +135 -0
  12. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/uv.lock +1 -1
  13. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.claude/skills/pr-review/SKILL.md +0 -0
  14. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.claude/skills/run-tests/SKILL.md +0 -0
  15. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.claude/skills/run-tests/scripts/test.sh +0 -0
  16. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.flake8 +0 -0
  17. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.github/workflows/pages.yml +0 -0
  18. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.github/workflows/publish.yml +0 -0
  19. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.github/workflows/security-checks.yml +0 -0
  20. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.github/workflows/tests.yml +0 -0
  21. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.gitignore +0 -0
  22. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.markdownlint-cli2.yaml +0 -0
  23. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.pr_agent.toml +0 -0
  24. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.pre-commit-config.yaml +0 -0
  25. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/.pylintrc +0 -0
  26. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/CLAUDE.md +0 -0
  27. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/CNAME +0 -0
  28. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/Gemfile +0 -0
  29. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/Gemfile.lock +0 -0
  30. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/LICENSE +0 -0
  31. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/README.md +0 -0
  32. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/SECURITY.md +0 -0
  33. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/_config.yml +0 -0
  34. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/_sass/color_schemes/anthropic.scss +0 -0
  35. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/_sass/custom/custom.scss +0 -0
  36. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/__init__.py +0 -0
  37. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/__main__.py +0 -0
  38. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/__init__.py +0 -0
  39. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/bot.py +0 -0
  40. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/bot_manager.py +0 -0
  41. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/config.py +0 -0
  42. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/http_listener.py +0 -0
  43. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/template_engine.py +0 -0
  44. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/bots/virtual_client.py +0 -0
  45. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/__init__.py +0 -0
  46. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/_helpers.py +0 -0
  47. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/agent.py +0 -0
  48. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/bot.py +0 -0
  49. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/channel.py +0 -0
  50. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/mesh.py +0 -0
  51. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/server.py +0 -0
  52. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/cli/skills.py +0 -0
  53. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/__init__.py +0 -0
  54. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/__init__.py +0 -0
  55. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/config.py +0 -0
  56. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/ipc.py +0 -0
  57. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/irc_transport.py +0 -0
  58. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/message_buffer.py +0 -0
  59. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/skill/SKILL.md +0 -0
  60. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/skill/__init__.py +0 -0
  61. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/skill/irc_client.py +0 -0
  62. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/socket_server.py +0 -0
  63. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/supervisor.py +0 -0
  64. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/acp/webhook.py +0 -0
  65. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/__init__.py +0 -0
  66. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/__main__.py +0 -0
  67. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/agent_runner.py +0 -0
  68. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/config.py +0 -0
  69. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/daemon.py +0 -0
  70. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/ipc.py +0 -0
  71. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/irc_transport.py +0 -0
  72. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/message_buffer.py +0 -0
  73. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/skill/SKILL.md +0 -0
  74. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/skill/__init__.py +0 -0
  75. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/skill/irc_client.py +0 -0
  76. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/socket_server.py +0 -0
  77. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/supervisor.py +0 -0
  78. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/claude/webhook.py +0 -0
  79. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/__init__.py +0 -0
  80. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/config.py +0 -0
  81. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/ipc.py +0 -0
  82. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/irc_transport.py +0 -0
  83. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/message_buffer.py +0 -0
  84. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/skill/SKILL.md +0 -0
  85. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/skill/__init__.py +0 -0
  86. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/skill/irc_client.py +0 -0
  87. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/socket_server.py +0 -0
  88. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/supervisor.py +0 -0
  89. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/codex/webhook.py +0 -0
  90. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/__init__.py +0 -0
  91. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/config.py +0 -0
  92. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/ipc.py +0 -0
  93. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/irc_transport.py +0 -0
  94. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/message_buffer.py +0 -0
  95. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/skill/SKILL.md +0 -0
  96. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/skill/__init__.py +0 -0
  97. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/skill/irc_client.py +0 -0
  98. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/socket_server.py +0 -0
  99. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/supervisor.py +0 -0
  100. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/clients/copilot/webhook.py +0 -0
  101. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/__init__.py +0 -0
  102. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/app.py +0 -0
  103. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/client.py +0 -0
  104. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/commands.py +0 -0
  105. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/widgets/__init__.py +0 -0
  106. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/widgets/chat.py +0 -0
  107. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/widgets/info_panel.py +0 -0
  108. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/console/widgets/sidebar.py +0 -0
  109. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/credentials.py +0 -0
  110. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/learn_prompt.py +0 -0
  111. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/mesh_config.py +0 -0
  112. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/observer.py +0 -0
  113. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/overview/__init__.py +0 -0
  114. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/overview/collector.py +0 -0
  115. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/overview/model.py +0 -0
  116. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/overview/renderer_text.py +0 -0
  117. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/overview/renderer_web.py +0 -0
  118. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/overview/web/style.css +0 -0
  119. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/persistence.py +0 -0
  120. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/pidfile.py +0 -0
  121. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/__init__.py +0 -0
  122. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/commands.py +0 -0
  123. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/extensions/federation.md +0 -0
  124. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/extensions/history.md +0 -0
  125. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/extensions/icons.md +0 -0
  126. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/extensions/rooms.md +0 -0
  127. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/extensions/tags.md +0 -0
  128. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/extensions/threads.md +0 -0
  129. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/message.py +0 -0
  130. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/protocol-index.md +0 -0
  131. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/protocol/replies.py +0 -0
  132. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/__init__.py +0 -0
  133. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/__main__.py +0 -0
  134. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/channel.py +0 -0
  135. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/client.py +0 -0
  136. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/config.py +0 -0
  137. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/ircd.py +0 -0
  138. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/remote_client.py +0 -0
  139. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/room_store.py +0 -0
  140. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/rooms_util.py +0 -0
  141. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/server_link.py +0 -0
  142. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/skill.py +0 -0
  143. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/skills/__init__.py +0 -0
  144. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/skills/history.py +0 -0
  145. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/skills/icon.py +0 -0
  146. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/skills/rooms.py +0 -0
  147. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/skills/threads.py +0 -0
  148. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/server/thread_store.py +0 -0
  149. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/culture/skills/culture/SKILL.md +0 -0
  150. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/agent-lifecycle.md +0 -0
  151. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/agentic-self-learn.md +0 -0
  152. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/agent-client.md +0 -0
  153. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/agent-harness-spec.md +0 -0
  154. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/design.md +0 -0
  155. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/harness-conformance.md +0 -0
  156. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/index.md +0 -0
  157. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/layer1-core-irc.md +0 -0
  158. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/layer2-attention.md +0 -0
  159. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/layer3-skills.md +0 -0
  160. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/layer4-federation.md +0 -0
  161. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/layer5-agent-harness.md +0 -0
  162. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/server-architecture.md +0 -0
  163. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/architecture/threads.md +0 -0
  164. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/channel-polling.md +0 -0
  165. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/acp/overview.md +0 -0
  166. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/configuration.md +0 -0
  167. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/context-management.md +0 -0
  168. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/irc-tools.md +0 -0
  169. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/overview.md +0 -0
  170. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/setup.md +0 -0
  171. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/supervisor.md +0 -0
  172. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/claude/webhooks.md +0 -0
  173. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/configuration.md +0 -0
  174. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/context-management.md +0 -0
  175. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/irc-tools.md +0 -0
  176. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/overview.md +0 -0
  177. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/setup.md +0 -0
  178. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/supervisor.md +0 -0
  179. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/codex/webhooks.md +0 -0
  180. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/configuration.md +0 -0
  181. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/context-management.md +0 -0
  182. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/irc-tools.md +0 -0
  183. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/overview.md +0 -0
  184. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/setup.md +0 -0
  185. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/supervisor.md +0 -0
  186. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/clients/copilot/webhooks.md +0 -0
  187. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/culture-cli.md +0 -0
  188. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/getting-started.md +0 -0
  189. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/index.md +0 -0
  190. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/SECURITY.md +0 -0
  191. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/bots.md +0 -0
  192. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/ci.md +0 -0
  193. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/cli.md +0 -0
  194. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/docs-site.md +0 -0
  195. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/index.md +0 -0
  196. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/ops-tooling.md +0 -0
  197. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/overview.md +0 -0
  198. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/operations/publishing.md +0 -0
  199. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  200. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/rooms.md +0 -0
  201. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/server-rename.md +0 -0
  202. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  203. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  204. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  205. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  206. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  207. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  208. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  209. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -0
  210. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
  211. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  212. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  213. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  214. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  215. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  216. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  217. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  218. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  219. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -0
  220. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -0
  221. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
  222. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
  223. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/01-pair-programming.md +0 -0
  224. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/02-code-review-ensemble.md +0 -0
  225. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/03-cross-server-delegation.md +0 -0
  226. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/04-knowledge-propagation.md +0 -0
  227. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/05-the-observer.md +0 -0
  228. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/06-cross-server-ops.md +0 -0
  229. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/07-supervisor-intervention.md +0 -0
  230. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/08-apps-as-agents.md +0 -0
  231. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/09-research-swarm.md +0 -0
  232. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases/10-agent-lifecycle.md +0 -0
  233. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/use-cases-index.md +0 -0
  234. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/docs/what-is-culture.md +0 -0
  235. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/README.md +0 -0
  236. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/config.py +0 -0
  237. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/ipc.py +0 -0
  238. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/irc_transport.py +0 -0
  239. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/message_buffer.py +0 -0
  240. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/skill/SKILL.md +0 -0
  241. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/skill/irc_client.py +0 -0
  242. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/socket_server.py +0 -0
  243. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/packages/agent-harness/webhook.py +0 -0
  244. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  245. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  246. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  247. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  248. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/sonar-project.properties +0 -0
  249. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/__init__.py +0 -0
  250. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/conftest.py +0 -0
  251. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_acp_daemon.py +0 -0
  252. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_agent_runner.py +0 -0
  253. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_bot.py +0 -0
  254. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_bot_config.py +0 -0
  255. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_bot_manager.py +0 -0
  256. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_bots_integration.py +0 -0
  257. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_channel.py +0 -0
  258. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_codex_daemon.py +0 -0
  259. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_connection.py +0 -0
  260. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_console_client.py +0 -0
  261. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_console_commands.py +0 -0
  262. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_console_connection.py +0 -0
  263. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_console_icons.py +0 -0
  264. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_console_integration.py +0 -0
  265. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_copilot_daemon.py +0 -0
  266. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_daemon.py +0 -0
  267. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_daemon_config.py +0 -0
  268. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_daemon_ipc.py +0 -0
  269. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_discovery.py +0 -0
  270. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_federation.py +0 -0
  271. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_history.py +0 -0
  272. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_http_listener.py +0 -0
  273. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_integration_layer5.py +0 -0
  274. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_ipc.py +0 -0
  275. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_irc_transport.py +0 -0
  276. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_link_reconnect.py +0 -0
  277. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_mention_alias.py +0 -0
  278. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_mentions.py +0 -0
  279. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_mesh_config.py +0 -0
  280. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_message.py +0 -0
  281. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_message_buffer.py +0 -0
  282. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_messaging.py +0 -0
  283. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_modes.py +0 -0
  284. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_overview_cli.py +0 -0
  285. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_overview_collector.py +0 -0
  286. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_overview_model.py +0 -0
  287. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_overview_renderer.py +0 -0
  288. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_overview_web.py +0 -0
  289. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_persistence.py +0 -0
  290. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_pidfile.py +0 -0
  291. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_poll_loop.py +0 -0
  292. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_room_persistence.py +0 -0
  293. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_rooms.py +0 -0
  294. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_rooms_federation.py +0 -0
  295. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_rooms_integration.py +0 -0
  296. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_server_icon_skill.py +0 -0
  297. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_setup_update_cli.py +0 -0
  298. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_skill_client.py +0 -0
  299. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_skills.py +0 -0
  300. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_socket_server.py +0 -0
  301. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_supervisor.py +0 -0
  302. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_template_engine.py +0 -0
  303. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_thread_buffer.py +0 -0
  304. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_threads.py +0 -0
  305. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_virtual_client.py +0 -0
  306. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_wait_for_port.py +0 -0
  307. {agentirc_cli-4.1.1 → agentirc_cli-4.1.2}/tests/test_webhook.py +0 -0
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
+ ## [4.1.2] - 2026-04-06
8
+
9
+
10
+ ### Fixed
11
+
12
+ - Clean up _mention_targets deque on prompt failure to prevent misrouted responses
13
+
7
14
  ## [4.1.1] - 2026-04-06
8
15
 
9
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 4.1.1
3
+ Version: 4.1.2
4
4
  Summary: Legacy alias for culture — install culture instead
5
5
  Project-URL: Homepage, https://github.com/OriNachum/culture
6
6
  Author: Ori Nachum
@@ -33,6 +33,7 @@ class ACPAgentRunner:
33
33
  system_prompt: str = "",
34
34
  on_exit: Callable[[int], Awaitable[None]] | None = None,
35
35
  on_message: Callable[[dict[str, Any]], Awaitable[None]] | None = None,
36
+ on_turn_error: Callable[[], Awaitable[None]] | None = None,
36
37
  ) -> None:
37
38
  self.model = model
38
39
  self.directory = directory
@@ -40,6 +41,7 @@ class ACPAgentRunner:
40
41
  self.system_prompt = system_prompt
41
42
  self.on_exit = on_exit
42
43
  self.on_message = on_message
44
+ self.on_turn_error = on_turn_error
43
45
 
44
46
  self._isolated_home: str | None = None
45
47
  self._process: asyncio.subprocess.Process | None = None
@@ -384,6 +386,8 @@ class ACPAgentRunner:
384
386
 
385
387
  except Exception:
386
388
  logger.exception("ACP turn error")
389
+ if self.on_turn_error:
390
+ await self.on_turn_error()
387
391
  finally:
388
392
  self._busy = False
389
393
 
@@ -318,6 +318,11 @@ class ACPDaemon:
318
318
  # Agent runner helpers
319
319
  # ------------------------------------------------------------------
320
320
 
321
+ async def _on_turn_error(self) -> None:
322
+ """Clean up stale relay target when a prompt fails."""
323
+ if self._mention_targets:
324
+ self._mention_targets.popleft()
325
+
321
326
  async def _start_agent_runner(self) -> None:
322
327
  self._agent_runner = ACPAgentRunner(
323
328
  model=self.agent.model,
@@ -326,6 +331,7 @@ class ACPDaemon:
326
331
  system_prompt=self._build_system_prompt(),
327
332
  on_exit=self._on_agent_exit,
328
333
  on_message=self._on_agent_message,
334
+ on_turn_error=self._on_turn_error,
329
335
  )
330
336
  # Absorb the system prompt response without relaying to IRC
331
337
  self._mention_targets.append(None)
@@ -23,12 +23,14 @@ class CodexAgentRunner:
23
23
  system_prompt: str = "",
24
24
  on_exit: Callable[[int], Awaitable[None]] | None = None,
25
25
  on_message: Callable[[dict[str, Any]], Awaitable[None]] | None = None,
26
+ on_turn_error: Callable[[], Awaitable[None]] | None = None,
26
27
  ) -> None:
27
28
  self.model = model
28
29
  self.directory = directory
29
30
  self.system_prompt = system_prompt
30
31
  self.on_exit = on_exit
31
32
  self.on_message = on_message
33
+ self.on_turn_error = on_turn_error
32
34
 
33
35
  self._isolated_home: str | None = None
34
36
  self._process: asyncio.subprocess.Process | None = None
@@ -318,6 +320,8 @@ class CodexAgentRunner:
318
320
 
319
321
  except Exception:
320
322
  logger.exception("Codex turn error")
323
+ if self.on_turn_error:
324
+ await self.on_turn_error()
321
325
 
322
326
  except asyncio.CancelledError:
323
327
  raise
@@ -293,6 +293,11 @@ class CodexDaemon:
293
293
  # Agent runner helpers
294
294
  # ------------------------------------------------------------------
295
295
 
296
+ async def _on_turn_error(self) -> None:
297
+ """Clean up stale relay target when a prompt fails."""
298
+ if self._mention_targets:
299
+ self._mention_targets.popleft()
300
+
296
301
  async def _start_agent_runner(self) -> None:
297
302
  self._agent_runner = CodexAgentRunner(
298
303
  model=self.agent.model,
@@ -300,6 +305,7 @@ class CodexDaemon:
300
305
  system_prompt=self._build_system_prompt(),
301
306
  on_exit=self._on_agent_exit,
302
307
  on_message=self._on_agent_message,
308
+ on_turn_error=self._on_turn_error,
303
309
  )
304
310
  await self._agent_runner.start()
305
311
  logger.info("CodexAgentRunner started for %s", self.agent.nick)
@@ -23,6 +23,7 @@ class CopilotAgentRunner:
23
23
  skill_directories: list[str] | None = None,
24
24
  on_exit: Callable[[int], Awaitable[None]] | None = None,
25
25
  on_message: Callable[[dict[str, Any]], Awaitable[None]] | None = None,
26
+ on_turn_error: Callable[[], Awaitable[None]] | None = None,
26
27
  ) -> None:
27
28
  self.model = model
28
29
  self.directory = directory
@@ -30,6 +31,7 @@ class CopilotAgentRunner:
30
31
  self.skill_directories = skill_directories or []
31
32
  self.on_exit = on_exit
32
33
  self.on_message = on_message
34
+ self.on_turn_error = on_turn_error
33
35
 
34
36
  self._isolated_home: str | None = None
35
37
  self._client: Any = None
@@ -158,6 +160,8 @@ class CopilotAgentRunner:
158
160
 
159
161
  except Exception:
160
162
  logger.exception("Copilot session turn error")
163
+ if self.on_turn_error:
164
+ await self.on_turn_error()
161
165
  if not self._stopping:
162
166
  self._running = False
163
167
  if self.on_exit:
@@ -293,6 +293,11 @@ class CopilotDaemon:
293
293
  # Agent runner helpers
294
294
  # ------------------------------------------------------------------
295
295
 
296
+ async def _on_turn_error(self) -> None:
297
+ """Clean up stale relay target when a prompt fails."""
298
+ if self._mention_targets:
299
+ self._mention_targets.popleft()
300
+
296
301
  async def _start_agent_runner(self) -> None:
297
302
  # Resolve installed skill path for the Copilot session
298
303
  skill_dirs: list[str] = []
@@ -307,6 +312,7 @@ class CopilotDaemon:
307
312
  skill_directories=skill_dirs,
308
313
  on_exit=self._on_agent_exit,
309
314
  on_message=self._on_agent_message,
315
+ on_turn_error=self._on_turn_error,
310
316
  )
311
317
  await self._agent_runner.start()
312
318
  logger.info("CopilotAgentRunner started for %s", self.agent.nick)
@@ -258,6 +258,15 @@ class AgentDaemon:
258
258
  except Exception:
259
259
  logger.exception("Poll loop error")
260
260
 
261
+ async def _on_turn_error(self) -> None:
262
+ """Clean up stale relay target when a prompt fails.
263
+
264
+ Wire this as the ``on_turn_error`` callback on your agent runner so
265
+ the ``_mention_targets`` deque stays in sync with the prompt queue.
266
+ """
267
+ if self._mention_targets:
268
+ self._mention_targets.popleft()
269
+
261
270
  def _on_mention(self, target: str, sender: str, text: str) -> None:
262
271
  """Called when the agent is @mentioned. Sends prompt to runner.
263
272
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentirc-cli"
3
- version = "4.1.1"
3
+ version = "4.1.2"
4
4
  description = "Legacy alias for culture — install culture instead"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -0,0 +1,135 @@
1
+ """Tests for _mention_targets deque cleanup on prompt failure.
2
+
3
+ When a prompt fails (timeout, error), the corresponding _mention_targets
4
+ entry must be cleaned up so that future responses route correctly.
5
+ """
6
+
7
+ import asyncio
8
+ import tempfile
9
+ from unittest.mock import AsyncMock, MagicMock
10
+
11
+ import pytest
12
+
13
+ from culture.clients.acp.config import (
14
+ AgentConfig,
15
+ DaemonConfig,
16
+ ServerConnConfig,
17
+ )
18
+ from culture.clients.acp.daemon import ACPDaemon
19
+
20
+
21
+ def _make_daemon(server_port: int) -> ACPDaemon:
22
+ config = DaemonConfig(
23
+ server=ServerConnConfig(host="127.0.0.1", port=server_port),
24
+ poll_interval=0,
25
+ )
26
+ agent = AgentConfig(
27
+ nick="testserv-bot",
28
+ directory="/tmp",
29
+ channels=["#general"],
30
+ acp_command=["echo"],
31
+ )
32
+ sock_dir = tempfile.mkdtemp()
33
+ return ACPDaemon(config, agent, socket_dir=sock_dir, skip_agent=True)
34
+
35
+
36
+ def _inject_fake_runner(daemon):
37
+ """Inject a fake agent runner that records prompts."""
38
+ runner = MagicMock()
39
+ runner.is_running.return_value = True
40
+ runner.send_prompt = AsyncMock()
41
+ runner.stop = AsyncMock()
42
+ daemon._agent_runner = runner
43
+ return runner
44
+
45
+
46
+ @pytest.mark.asyncio
47
+ async def test_on_turn_error_pops_stale_target(server):
48
+ """_on_turn_error should pop the front entry from _mention_targets."""
49
+ daemon = _make_daemon(server.config.port)
50
+ await daemon.start()
51
+
52
+ # Simulate: poll enqueued a target, then the prompt failed
53
+ daemon._mention_targets.append("#general")
54
+ daemon._mention_targets.append("#code-review")
55
+ assert len(daemon._mention_targets) == 2
56
+
57
+ await daemon._on_turn_error()
58
+ assert len(daemon._mention_targets) == 1
59
+ assert daemon._mention_targets[0] == "#code-review"
60
+
61
+ await daemon.stop()
62
+
63
+
64
+ @pytest.mark.asyncio
65
+ async def test_on_turn_error_empty_deque_is_safe(server):
66
+ """_on_turn_error should be a no-op on an empty deque."""
67
+ daemon = _make_daemon(server.config.port)
68
+ await daemon.start()
69
+
70
+ assert len(daemon._mention_targets) == 0
71
+ await daemon._on_turn_error() # should not raise
72
+ assert len(daemon._mention_targets) == 0
73
+
74
+ await daemon.stop()
75
+
76
+
77
+ @pytest.mark.asyncio
78
+ async def test_relay_routes_correctly_after_error_cleanup(server, make_client):
79
+ """After a failed prompt is cleaned up, the next response should route correctly."""
80
+ daemon = _make_daemon(server.config.port)
81
+ await daemon.start()
82
+ _inject_fake_runner(daemon)
83
+ await asyncio.sleep(0.5)
84
+
85
+ # Simulate: system prompt enqueued None, then timed out and was cleaned up
86
+ daemon._mention_targets.append(None)
87
+ await daemon._on_turn_error() # cleans up None
88
+
89
+ # Now simulate a real mention that succeeds
90
+ daemon._mention_targets.append("#general")
91
+
92
+ # Simulate agent response
93
+ sent_messages = []
94
+ original_send = daemon._transport.send_privmsg
95
+
96
+ async def capture_send(target, text):
97
+ sent_messages.append((target, text))
98
+ await original_send(target, text)
99
+
100
+ daemon._transport.send_privmsg = capture_send
101
+
102
+ msg = {
103
+ "type": "assistant",
104
+ "content": [{"type": "text", "text": "Hello from bot!"}],
105
+ }
106
+ await daemon._relay_response_to_irc(msg)
107
+
108
+ assert len(sent_messages) == 1
109
+ assert sent_messages[0][0] == "#general"
110
+ assert "Hello from bot!" in sent_messages[0][1]
111
+ assert len(daemon._mention_targets) == 0
112
+
113
+ await daemon.stop()
114
+
115
+
116
+ @pytest.mark.asyncio
117
+ async def test_multiple_errors_drain_deque_correctly(server):
118
+ """Multiple consecutive errors should each pop one entry."""
119
+ daemon = _make_daemon(server.config.port)
120
+ await daemon.start()
121
+
122
+ # Simulate 3 failed prompts
123
+ daemon._mention_targets.append(None) # system prompt
124
+ daemon._mention_targets.append("#general") # poll 1
125
+ daemon._mention_targets.append("#general") # poll 2
126
+
127
+ await daemon._on_turn_error() # pops None
128
+ await daemon._on_turn_error() # pops #general
129
+ assert len(daemon._mention_targets) == 1
130
+ assert daemon._mention_targets[0] == "#general"
131
+
132
+ await daemon._on_turn_error() # pops last #general
133
+ assert len(daemon._mention_targets) == 0
134
+
135
+ await daemon.stop()
@@ -561,7 +561,7 @@ wheels = [
561
561
 
562
562
  [[package]]
563
563
  name = "culture"
564
- version = "4.1.1"
564
+ version = "4.1.2"
565
565
  source = { editable = "." }
566
566
  dependencies = [
567
567
  { name = "aiohttp" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes