agentirc-cli 4.4.0__tar.gz → 4.4.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.
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/CHANGELOG.md +26 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/CLAUDE.md +1 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/PKG-INFO +5 -5
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/README.md +4 -4
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/agent.py +5 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/display.py +2 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/ipc.py +1 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/agent_runner.py +23 -3
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/config.py +67 -38
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/daemon.py +48 -5
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/irc_transport.py +4 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/config.py +107 -74
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/daemon.py +17 -2
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/irc_transport.py +4 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/agent_runner.py +21 -7
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/config.py +64 -37
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/daemon.py +48 -5
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/irc_transport.py +4 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/agent_runner.py +5 -3
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/config.py +64 -37
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/daemon.py +48 -5
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/irc_transport.py +4 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/channel-polling.md +1 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/acp/overview.md +2 -1
- agentirc_cli-4.4.2/docs/clients/acp/system-prompt.md +183 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/configuration.md +4 -4
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/overview.md +3 -2
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/setup.md +2 -2
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/configuration.md +9 -8
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/setup.md +1 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/index.md +3 -3
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +5 -5
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +1 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +3 -3
- agentirc_cli-4.4.2/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +165 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/daemon.py +39 -5
- agentirc_cli-4.4.2/packages/agent-harness/irc_transport.py +238 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/pyproject.toml +1 -1
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_acp_daemon.py +61 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_archive.py +167 -0
- agentirc_cli-4.4.2/tests/test_codex_daemon.py +252 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_copilot_daemon.py +106 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_daemon_config.py +90 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_mention_alias.py +29 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_mention_target_cleanup.py +6 -6
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/uv.lock +1 -1
- agentirc_cli-4.4.0/packages/agent-harness/irc_transport.py +0 -229
- agentirc_cli-4.4.0/tests/test_codex_daemon.py +0 -96
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.claude/skills/pr-review/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.claude/skills/run-tests/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.flake8 +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.github/workflows/pages.yml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.github/workflows/publish.yml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.github/workflows/security-checks.yml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.github/workflows/tests.yml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.gitignore +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.markdownlint-cli2.yaml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.pr_agent.toml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.pre-commit-config.yaml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/.pylintrc +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/CNAME +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/Gemfile +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/Gemfile.lock +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/LICENSE +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/SECURITY.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/_config.yml +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/_sass/color_schemes/anthropic.scss +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/_sass/custom/custom.scss +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/__main__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/aio.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/bot.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/bot_manager.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/config.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/http_listener.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/template_engine.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/bots/virtual_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/bot.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/channel.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/mesh.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/constants.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/formatting.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/mesh.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/shared/process.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/cli/skills.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/message_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/skill/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/socket_server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/supervisor.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/acp/webhook.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/__main__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/agent_runner.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/message_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/skill/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/socket_server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/supervisor.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/claude/webhook.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/message_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/skill/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/socket_server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/supervisor.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/codex/webhook.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/message_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/skill/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/socket_server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/supervisor.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/clients/copilot/webhook.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/app.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/commands.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/widgets/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/widgets/chat.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/widgets/info_panel.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/console/widgets/sidebar.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/credentials.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/formatting.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/learn_prompt.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/mesh_config.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/observer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/overview/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/overview/collector.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/overview/model.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/overview/renderer_text.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/overview/renderer_web.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/overview/web/style.css +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/persistence.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/pidfile.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/commands.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/extensions/federation.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/extensions/history.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/extensions/icons.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/extensions/rooms.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/extensions/tags.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/extensions/threads.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/message.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/protocol-index.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/protocol/replies.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/__main__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/channel.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/config.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/history_store.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/ircd.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/remote_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/room_store.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/rooms_util.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/server_link.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/skill.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/skills/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/skills/history.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/skills/icon.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/skills/rooms.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/skills/threads.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/server/thread_store.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/culture/skills/culture/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/agent-lifecycle.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/agentic-self-learn.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/agent-client.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/agent-harness-spec.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/harness-conformance.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/index.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/layer1-core-irc.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/layer2-attention.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/layer3-skills.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/layer4-federation.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/layer5-agent-harness.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/server-architecture.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/architecture/threads.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/configuration.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/context-management.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/irc-tools.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/overview.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/setup.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/supervisor.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/claude/webhooks.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/context-management.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/irc-tools.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/supervisor.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/codex/webhooks.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/context-management.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/irc-tools.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/overview.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/supervisor.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/clients/copilot/webhooks.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/culture-cli.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/getting-started.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/SECURITY.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/bots.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/ci.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/cli.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/docs-site.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/index.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/ops-tooling.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/overview.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/operations/publishing.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/persistent-history.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/resources/github-copilot-sdk-instructions.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/rooms.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/server-rename.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/01-pair-programming.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/02-code-review-ensemble.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/03-cross-server-delegation.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/04-knowledge-propagation.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/05-the-observer.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/06-cross-server-ops.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/07-supervisor-intervention.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/08-apps-as-agents.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/09-research-swarm.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases/10-agent-lifecycle.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/use-cases-index.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/docs/what-is-culture.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/README.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/config.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/message_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/socket_server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/packages/agent-harness/webhook.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/plugins/claude-code/skills/culture/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/plugins/claude-code/skills/irc/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/sonar-project.properties +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/__init__.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/conftest.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_agent_runner.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_bot.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_bot_config.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_bot_manager.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_bots_integration.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_channel.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_connection.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_console_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_console_commands.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_console_connection.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_console_icons.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_console_integration.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_daemon.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_daemon_ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_discovery.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_federation.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_history.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_http_listener.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_integration_layer5.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_ipc.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_irc_transport.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_link_reconnect.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_mentions.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_mesh_config.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_message.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_message_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_messaging.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_modes.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_overview_cli.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_overview_collector.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_overview_model.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_overview_renderer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_overview_web.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_persistence.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_pidfile.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_poll_loop.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_room_persistence.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_rooms.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_rooms_federation.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_rooms_integration.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_server_icon_skill.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_setup_update_cli.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_skill_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_skills.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_socket_server.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_supervisor.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_template_engine.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_thread_buffer.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_threads.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_virtual_client.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_wait_for_port.py +0 -0
- {agentirc_cli-4.4.0 → agentirc_cli-4.4.2}/tests/test_webhook.py +0 -0
|
@@ -4,6 +4,32 @@ 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.4.2] - 2026-04-08
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Codex/copilot: preserve HOME for auth tokens instead of isolating (#159)
|
|
13
|
+
- Codex: fix turn sync race condition causing concatenated rapid-mention responses (#165)
|
|
14
|
+
- All backends: sleep scheduler no longer overrides manual pause (#162)
|
|
15
|
+
- All backends: poll loop filters @mention messages to prevent duplicate responses (#160)
|
|
16
|
+
- All backends: turn errors now send feedback to IRC channel (#163)
|
|
17
|
+
- All backends: consecutive turn failure circuit breaker pauses agent after 3 failures (#164)
|
|
18
|
+
- Status query response verified not leaking to IRC channel (#161)
|
|
19
|
+
|
|
20
|
+
## [4.4.1] - 2026-04-07
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Config save operations no longer strip backend-specific fields like acp_command (#150)
|
|
26
|
+
- Agent status detail uses cached description by default, --full for live query; IPC deadline increased to 15s (#152)
|
|
27
|
+
- DMs now activate agents — _detect_and_fire_mention handles direct messages in all backends (#153)
|
|
28
|
+
- ACP agent runner preserves HOME/XDG_CONFIG_HOME for auth tokens; warns on authMethods, fails fast on session creation failure (#154)
|
|
29
|
+
- _coerce_to_acp_agent now copies the icon field (#155)
|
|
30
|
+
- _make_backend_config passes supervisor, poll_interval, sleep_start, sleep_end to non-claude backends (#156)
|
|
31
|
+
- ACP load_config strips unknown fields, matching claude/codex/copilot pattern (#157)
|
|
32
|
+
|
|
7
33
|
## [4.4.0] - 2026-04-07
|
|
8
34
|
|
|
9
35
|
|
|
@@ -11,7 +11,7 @@ Design spec: `docs/superpowers/specs/2026-03-19-agentirc-design.md`
|
|
|
11
11
|
## Package Management
|
|
12
12
|
|
|
13
13
|
- **External packages:** Managed in `pyproject.toml`, installed with `uv`
|
|
14
|
-
- **Internal packages:** Written in `packages/` folder. Internal packages are NOT installed as dependencies — they are
|
|
14
|
+
- **Internal packages:** Written in `packages/` folder. Internal packages are NOT installed as dependencies — they are reflected into target projects as native code, placed in the correct folder and location as if written directly in the target project.
|
|
15
15
|
|
|
16
16
|
## Assimilai Pattern
|
|
17
17
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentirc-cli
|
|
3
|
-
Version: 4.4.
|
|
3
|
+
Version: 4.4.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
|
|
@@ -60,7 +60,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
|
|
|
60
60
|
|
|
61
61
|
| | |
|
|
62
62
|
|---|---|
|
|
63
|
-
| 🎓 **
|
|
63
|
+
| 🎓 **Reflective Lifecycle** | Introduce → Educate → Join → Mentor → Promote. Members develop through real work, not configuration. |
|
|
64
64
|
| 🌐 **Connected Worlds** | Link cultures across machines. Members see each other without a central controller. |
|
|
65
65
|
| 🧭 **Mentorship** | A guide watches for drift, spiraling, and stalling — whispers corrections when needed. |
|
|
66
66
|
| 🤝 **Open Membership** | Claude, Codex, Copilot, or any ACP agent. All are welcome. |
|
|
@@ -84,7 +84,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
|
|
|
84
84
|
| **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + escalation timeouts | Retry limits + fallback agents |
|
|
85
85
|
| **Observability** | Live web dashboard + any IRC client | Web dashboard + Slack/Discord/webhook alerts | CLI commands (metrics partially mocked) |
|
|
86
86
|
| **Self-organization** | Tag-driven room membership | Orchestrator assigns issues to workers | ML-based routing with learning pipeline |
|
|
87
|
-
| **Philosophy** | Simple,
|
|
87
|
+
| **Philosophy** | Simple, reflective, transparent | Parallel coding coordinator — isolation via worktrees | Enterprise-complex (130+ skills, vector DB, Q-learning) |
|
|
88
88
|
|
|
89
89
|
---
|
|
90
90
|
|
|
@@ -138,9 +138,9 @@ Members on any machine see each other in `#general`. @mentions cross boundaries.
|
|
|
138
138
|
|
|
139
139
|
---
|
|
140
140
|
|
|
141
|
-
##
|
|
141
|
+
## Reflective Development
|
|
142
142
|
|
|
143
|
-
Culture follows the **
|
|
143
|
+
Culture follows the **Reflective Development** paradigm — agents develop by reflecting on real work, not by configuration. Documentation flows back as context. Code reflects from reference to implementation. The lifecycle is continuous, not graduated:
|
|
144
144
|
|
|
145
145
|
👋 **Introduce** → 🎓 **Educate** → 🤝 **Join** → 🧭 **Mentor** → ⭐ **Promote**
|
|
146
146
|
|
|
@@ -36,7 +36,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
|
|
|
36
36
|
|
|
37
37
|
| | |
|
|
38
38
|
|---|---|
|
|
39
|
-
| 🎓 **
|
|
39
|
+
| 🎓 **Reflective Lifecycle** | Introduce → Educate → Join → Mentor → Promote. Members develop through real work, not configuration. |
|
|
40
40
|
| 🌐 **Connected Worlds** | Link cultures across machines. Members see each other without a central controller. |
|
|
41
41
|
| 🧭 **Mentorship** | A guide watches for drift, spiraling, and stalling — whispers corrections when needed. |
|
|
42
42
|
| 🤝 **Open Membership** | Claude, Codex, Copilot, or any ACP agent. All are welcome. |
|
|
@@ -60,7 +60,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
|
|
|
60
60
|
| **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + escalation timeouts | Retry limits + fallback agents |
|
|
61
61
|
| **Observability** | Live web dashboard + any IRC client | Web dashboard + Slack/Discord/webhook alerts | CLI commands (metrics partially mocked) |
|
|
62
62
|
| **Self-organization** | Tag-driven room membership | Orchestrator assigns issues to workers | ML-based routing with learning pipeline |
|
|
63
|
-
| **Philosophy** | Simple,
|
|
63
|
+
| **Philosophy** | Simple, reflective, transparent | Parallel coding coordinator — isolation via worktrees | Enterprise-complex (130+ skills, vector DB, Q-learning) |
|
|
64
64
|
|
|
65
65
|
---
|
|
66
66
|
|
|
@@ -114,9 +114,9 @@ Members on any machine see each other in `#general`. @mentions cross boundaries.
|
|
|
114
114
|
|
|
115
115
|
---
|
|
116
116
|
|
|
117
|
-
##
|
|
117
|
+
## Reflective Development
|
|
118
118
|
|
|
119
|
-
Culture follows the **
|
|
119
|
+
Culture follows the **Reflective Development** paradigm — agents develop by reflecting on real work, not by configuration. Documentation flows back as context. Code reflects from reference to implementation. The lifecycle is continuous, not graduated:
|
|
120
120
|
|
|
121
121
|
👋 **Introduce** → 🎓 **Educate** → 🤝 **Join** → 🧭 **Mentor** → ⭐ **Promote**
|
|
122
122
|
|
|
@@ -455,8 +455,12 @@ def _make_backend_config(config: DaemonConfig, backend_daemon_config_cls):
|
|
|
455
455
|
"""Build a backend-specific DaemonConfig from the base config."""
|
|
456
456
|
return backend_daemon_config_cls(
|
|
457
457
|
server=config.server,
|
|
458
|
+
supervisor=config.supervisor,
|
|
458
459
|
webhooks=config.webhooks,
|
|
459
460
|
buffer_size=config.buffer_size,
|
|
461
|
+
poll_interval=config.poll_interval,
|
|
462
|
+
sleep_start=config.sleep_start,
|
|
463
|
+
sleep_end=config.sleep_end,
|
|
460
464
|
agents=config.agents,
|
|
461
465
|
)
|
|
462
466
|
|
|
@@ -484,6 +488,7 @@ def _coerce_to_acp_agent(agent: AgentConfig):
|
|
|
484
488
|
model=agent.model,
|
|
485
489
|
system_prompt=agent.system_prompt,
|
|
486
490
|
tags=agent.tags,
|
|
491
|
+
icon=agent.icon,
|
|
487
492
|
)
|
|
488
493
|
|
|
489
494
|
|
|
@@ -37,7 +37,8 @@ def print_agent_detail(agent, config_path: str, args: argparse.Namespace) -> Non
|
|
|
37
37
|
print(f" PID: {pid or '-'}")
|
|
38
38
|
|
|
39
39
|
if status == "running":
|
|
40
|
-
|
|
40
|
+
query = getattr(args, "full", False)
|
|
41
|
+
resp = asyncio.run(ipc_request(agent_socket_path(agent.nick), "status", query=query))
|
|
41
42
|
if resp and resp.get("ok"):
|
|
42
43
|
data = resp.get("data", {})
|
|
43
44
|
print(f" Activity: {data.get('description', 'nothing')}")
|
|
@@ -31,7 +31,7 @@ async def ipc_request(socket_path: str, msg_type: str, **kwargs) -> dict | None:
|
|
|
31
31
|
writer.write(encode_message(req))
|
|
32
32
|
await writer.drain()
|
|
33
33
|
loop = asyncio.get_running_loop()
|
|
34
|
-
deadline = loop.time() +
|
|
34
|
+
deadline = loop.time() + 15.0
|
|
35
35
|
while True:
|
|
36
36
|
remaining = deadline - loop.time()
|
|
37
37
|
if remaining <= 0:
|
|
@@ -70,11 +70,12 @@ class ACPAgentRunner:
|
|
|
70
70
|
"""Start the ACP agent as a subprocess and initialize a session."""
|
|
71
71
|
self._stopping = False
|
|
72
72
|
|
|
73
|
-
# Isolate
|
|
73
|
+
# Isolate data/state dirs to prevent session interference, but
|
|
74
|
+
# preserve HOME and XDG_CONFIG_HOME so the agent finds auth tokens.
|
|
74
75
|
self._isolated_home = tempfile.mkdtemp(prefix="culture-acp-")
|
|
75
76
|
isolated_env = dict(os.environ)
|
|
76
|
-
isolated_env["
|
|
77
|
-
isolated_env.
|
|
77
|
+
isolated_env["XDG_DATA_HOME"] = os.path.join(self._isolated_home, ".local", "share")
|
|
78
|
+
isolated_env["XDG_STATE_HOME"] = os.path.join(self._isolated_home, ".local", "state")
|
|
78
79
|
|
|
79
80
|
cmd_label = " ".join(self.acp_command)
|
|
80
81
|
try:
|
|
@@ -108,6 +109,18 @@ class ACPAgentRunner:
|
|
|
108
109
|
)
|
|
109
110
|
logger.info("ACP initialized (%s): %s", cmd_label, resp)
|
|
110
111
|
|
|
112
|
+
# Log available auth methods as a hint
|
|
113
|
+
init_result = resp.get("result", {})
|
|
114
|
+
auth_methods = init_result.get("authMethods", [])
|
|
115
|
+
if auth_methods:
|
|
116
|
+
descriptions = [m.get("description", m.get("id", "unknown")) for m in auth_methods]
|
|
117
|
+
logger.warning(
|
|
118
|
+
"ACP agent (%s) reports auth methods: %s. "
|
|
119
|
+
"If prompts fail, configure auth tokens.",
|
|
120
|
+
cmd_label,
|
|
121
|
+
", ".join(descriptions),
|
|
122
|
+
)
|
|
123
|
+
|
|
111
124
|
# Create a session with model selection
|
|
112
125
|
session_params = {
|
|
113
126
|
"cwd": self.directory,
|
|
@@ -120,6 +133,13 @@ class ACPAgentRunner:
|
|
|
120
133
|
logger.info("ACP session/new raw response: %s", json.dumps(resp)[:500])
|
|
121
134
|
result = resp.get("result", {})
|
|
122
135
|
self._session_id = result.get("sessionId")
|
|
136
|
+
if not self._session_id:
|
|
137
|
+
# Session creation failed — likely auth or model issue
|
|
138
|
+
error = resp.get("error", {})
|
|
139
|
+
error_msg = error.get("message", "unknown error")
|
|
140
|
+
if auth_methods:
|
|
141
|
+
error_msg += f". Auth may be required: {', '.join(descriptions)}"
|
|
142
|
+
raise RuntimeError(f"ACP agent ({cmd_label}) session creation failed: {error_msg}")
|
|
123
143
|
self._running = True
|
|
124
144
|
logger.info("ACP session started (%s): %s", cmd_label, self._session_id)
|
|
125
145
|
|
|
@@ -93,8 +93,10 @@ def load_config(path: str | Path) -> DaemonConfig:
|
|
|
93
93
|
webhooks = WebhookConfig(**raw.get("webhooks", {}))
|
|
94
94
|
|
|
95
95
|
agents = []
|
|
96
|
+
known_agent_fields = {f.name for f in AgentConfig.__dataclass_fields__.values()}
|
|
96
97
|
for agent_raw in raw.get("agents", []):
|
|
97
|
-
|
|
98
|
+
filtered = {k: v for k, v in agent_raw.items() if k in known_agent_fields}
|
|
99
|
+
agents.append(AgentConfig(**filtered))
|
|
98
100
|
|
|
99
101
|
return DaemonConfig(
|
|
100
102
|
server=server,
|
|
@@ -157,6 +159,32 @@ def save_config(path: str | Path, config: DaemonConfig) -> None:
|
|
|
157
159
|
raise
|
|
158
160
|
|
|
159
161
|
|
|
162
|
+
def _load_raw_yaml(path: str | Path) -> dict:
|
|
163
|
+
"""Load raw YAML from a config file, returning empty dict if missing."""
|
|
164
|
+
path = Path(path)
|
|
165
|
+
if not path.exists():
|
|
166
|
+
return {}
|
|
167
|
+
with open(path) as f:
|
|
168
|
+
return yaml.safe_load(f) or {}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _save_raw_yaml(path: str | Path, raw: dict) -> None:
|
|
172
|
+
"""Write raw YAML dict atomically."""
|
|
173
|
+
path = Path(path)
|
|
174
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
175
|
+
fd, tmp_path = tempfile.mkstemp(dir=str(path.parent), suffix=".yaml.tmp")
|
|
176
|
+
try:
|
|
177
|
+
with os.fdopen(fd, "w") as f:
|
|
178
|
+
yaml.dump(raw, f, default_flow_style=False, sort_keys=False)
|
|
179
|
+
os.replace(tmp_path, str(path))
|
|
180
|
+
except BaseException:
|
|
181
|
+
try:
|
|
182
|
+
os.unlink(tmp_path)
|
|
183
|
+
except OSError:
|
|
184
|
+
pass
|
|
185
|
+
raise
|
|
186
|
+
|
|
187
|
+
|
|
160
188
|
def add_agent_to_config(
|
|
161
189
|
path: str | Path,
|
|
162
190
|
agent: AgentConfig,
|
|
@@ -166,20 +194,21 @@ def add_agent_to_config(
|
|
|
166
194
|
|
|
167
195
|
If server_name is provided, updates config.server.name.
|
|
168
196
|
Raises ValueError if an agent with the same nick already exists.
|
|
197
|
+
Operates on raw YAML to preserve backend-specific fields.
|
|
169
198
|
"""
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if server_name is not None:
|
|
173
|
-
config.server.name = server_name
|
|
199
|
+
raw = _load_raw_yaml(path)
|
|
200
|
+
agents = raw.setdefault("agents", [])
|
|
174
201
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if existing.nick == agent.nick:
|
|
202
|
+
for existing in agents:
|
|
203
|
+
if existing.get("nick") == agent.nick:
|
|
178
204
|
raise ValueError(f"Agent with nick {agent.nick!r} already exists in config")
|
|
179
205
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
206
|
+
if server_name is not None:
|
|
207
|
+
raw.setdefault("server", {})["name"] = server_name
|
|
208
|
+
|
|
209
|
+
agents.append(asdict(agent))
|
|
210
|
+
_save_raw_yaml(path, raw)
|
|
211
|
+
return load_config(path)
|
|
183
212
|
|
|
184
213
|
|
|
185
214
|
def rename_server(
|
|
@@ -189,23 +218,26 @@ def rename_server(
|
|
|
189
218
|
"""Rename the server and update all agent nick prefixes.
|
|
190
219
|
|
|
191
220
|
Returns (old_name, [(old_nick, new_nick), ...]).
|
|
221
|
+
Operates on raw YAML to preserve backend-specific fields.
|
|
192
222
|
"""
|
|
193
|
-
|
|
194
|
-
|
|
223
|
+
raw = _load_raw_yaml(path)
|
|
224
|
+
server = raw.get("server", {})
|
|
225
|
+
old_name = server.get("name", ServerConnConfig().name)
|
|
195
226
|
|
|
196
227
|
if old_name == new_name:
|
|
197
228
|
return old_name, []
|
|
198
229
|
|
|
199
|
-
|
|
230
|
+
agents = raw.get("agents", [])
|
|
200
231
|
prefix = f"{old_name}-"
|
|
201
232
|
plan: list[tuple[int, str, str]] = []
|
|
202
|
-
for i,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
233
|
+
for i, agent_raw in enumerate(agents):
|
|
234
|
+
nick = agent_raw.get("nick", "")
|
|
235
|
+
if nick.startswith(prefix):
|
|
236
|
+
new_nick = f"{new_name}-{nick[len(prefix):]}"
|
|
237
|
+
plan.append((i, nick, new_nick))
|
|
206
238
|
|
|
207
239
|
planned_nicks = {new_nick for _, _, new_nick in plan}
|
|
208
|
-
existing_nicks = {a.nick for a in
|
|
240
|
+
existing_nicks = {a.get("nick", "") for a in agents} - {old for _, old, _ in plan}
|
|
209
241
|
collisions = planned_nicks & existing_nicks
|
|
210
242
|
if collisions:
|
|
211
243
|
raise ValueError(
|
|
@@ -213,14 +245,15 @@ def rename_server(
|
|
|
213
245
|
f"duplicate nick(s): {', '.join(sorted(collisions))}"
|
|
214
246
|
)
|
|
215
247
|
|
|
216
|
-
|
|
248
|
+
server["name"] = new_name
|
|
249
|
+
raw["server"] = server
|
|
217
250
|
|
|
218
251
|
renamed: list[tuple[str, str]] = []
|
|
219
252
|
for i, old_nick, new_nick in plan:
|
|
220
|
-
|
|
253
|
+
agents[i]["nick"] = new_nick
|
|
221
254
|
renamed.append((old_nick, new_nick))
|
|
222
255
|
|
|
223
|
-
|
|
256
|
+
_save_raw_yaml(path, raw)
|
|
224
257
|
return old_name, renamed
|
|
225
258
|
|
|
226
259
|
|
|
@@ -232,19 +265,19 @@ def rename_agent(
|
|
|
232
265
|
"""Rename an agent's nick in the config.
|
|
233
266
|
|
|
234
267
|
Raises ValueError if old_nick is not found or new_nick already exists.
|
|
268
|
+
Operates on raw YAML to preserve backend-specific fields.
|
|
235
269
|
"""
|
|
236
|
-
|
|
270
|
+
raw = _load_raw_yaml(path)
|
|
271
|
+
agents = raw.get("agents", [])
|
|
237
272
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if agent.nick == new_nick:
|
|
273
|
+
for agent_raw in agents:
|
|
274
|
+
if agent_raw.get("nick") == new_nick:
|
|
241
275
|
raise ValueError(f"Agent with nick {new_nick!r} already exists in config")
|
|
242
276
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
save_config(path, config)
|
|
277
|
+
for agent_raw in agents:
|
|
278
|
+
if agent_raw.get("nick") == old_nick:
|
|
279
|
+
agent_raw["nick"] = new_nick
|
|
280
|
+
_save_raw_yaml(path, raw)
|
|
248
281
|
return
|
|
249
282
|
|
|
250
283
|
raise ValueError(f"Agent {old_nick!r} not found in config")
|
|
@@ -260,18 +293,14 @@ def remove_agent(
|
|
|
260
293
|
agents that the typed schema would strip.
|
|
261
294
|
Raises ValueError if the agent is not found.
|
|
262
295
|
"""
|
|
263
|
-
|
|
264
|
-
if not
|
|
296
|
+
raw = _load_raw_yaml(path)
|
|
297
|
+
if not raw:
|
|
265
298
|
raise ValueError(f"Agent {nick!r} not found in config")
|
|
266
299
|
|
|
267
|
-
with open(path) as f:
|
|
268
|
-
raw = yaml.safe_load(f) or {}
|
|
269
|
-
|
|
270
300
|
agents = raw.get("agents", [])
|
|
271
301
|
for i, agent_raw in enumerate(agents):
|
|
272
302
|
if agent_raw.get("nick") == nick:
|
|
273
303
|
agents.pop(i)
|
|
274
|
-
|
|
275
|
-
yaml.dump(raw, f, default_flow_style=False, sort_keys=False)
|
|
304
|
+
_save_raw_yaml(path, raw)
|
|
276
305
|
return
|
|
277
306
|
raise ValueError(f"Agent {nick!r} not found in config")
|
|
@@ -13,6 +13,7 @@ import asyncio
|
|
|
13
13
|
import datetime
|
|
14
14
|
import logging
|
|
15
15
|
import os
|
|
16
|
+
import re
|
|
16
17
|
import time
|
|
17
18
|
from collections import deque
|
|
18
19
|
|
|
@@ -37,6 +38,7 @@ _ERR_MISSING_CHANNEL_THREAD_MSG = "Missing 'channel', 'thread', or 'message'"
|
|
|
37
38
|
MAX_CRASH_COUNT = 3
|
|
38
39
|
CRASH_WINDOW_SECONDS = 300
|
|
39
40
|
CRASH_RESTART_DELAY = 5
|
|
41
|
+
MAX_CONSECUTIVE_TURN_FAILURES = 3
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
class ACPDaemon:
|
|
@@ -74,9 +76,11 @@ class ACPDaemon:
|
|
|
74
76
|
# Crash-recovery state
|
|
75
77
|
self._crash_times: list[float] = []
|
|
76
78
|
self._circuit_open = False
|
|
79
|
+
self._consecutive_turn_failures: int = 0
|
|
77
80
|
|
|
78
81
|
# Pause/sleep state
|
|
79
82
|
self._paused: bool = False
|
|
83
|
+
self._manually_paused: bool = False
|
|
80
84
|
self._last_activation: float | None = None
|
|
81
85
|
|
|
82
86
|
# Status query state — for asking the agent what it's doing
|
|
@@ -270,7 +274,7 @@ class ACPDaemon:
|
|
|
270
274
|
if should_sleep and not self._paused:
|
|
271
275
|
self._paused = True
|
|
272
276
|
logger.info("Sleep schedule: pausing %s", self.agent.nick)
|
|
273
|
-
elif not should_sleep and self._paused:
|
|
277
|
+
elif not should_sleep and self._paused and not self._manually_paused:
|
|
274
278
|
self._paused = False
|
|
275
279
|
logger.info("Sleep schedule: resuming %s", self.agent.nick)
|
|
276
280
|
except asyncio.CancelledError:
|
|
@@ -300,6 +304,17 @@ class ACPDaemon:
|
|
|
300
304
|
|
|
301
305
|
def _send_channel_poll(self, channel) -> None:
|
|
302
306
|
msgs = self._buffer.read(channel)
|
|
307
|
+
if not msgs:
|
|
308
|
+
return
|
|
309
|
+
# Filter out messages that @mention this agent (already handled by _on_mention)
|
|
310
|
+
nick = self.agent.nick
|
|
311
|
+
short = nick.split("-", 1)[1] if "-" in nick else None
|
|
312
|
+
msgs = [
|
|
313
|
+
m
|
|
314
|
+
for m in msgs
|
|
315
|
+
if not re.search(rf"@{re.escape(nick)}\b", m.text)
|
|
316
|
+
and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
|
|
317
|
+
]
|
|
303
318
|
if not msgs:
|
|
304
319
|
return
|
|
305
320
|
lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
|
|
@@ -330,10 +345,35 @@ class ACPDaemon:
|
|
|
330
345
|
# Agent runner helpers
|
|
331
346
|
# ------------------------------------------------------------------
|
|
332
347
|
|
|
333
|
-
def _on_turn_error(self) -> None:
|
|
334
|
-
"""
|
|
348
|
+
async def _on_turn_error(self) -> None:
|
|
349
|
+
"""Send error feedback to IRC and clean up stale relay target."""
|
|
335
350
|
if self._mention_targets:
|
|
336
|
-
self._mention_targets.popleft()
|
|
351
|
+
relay_target = self._mention_targets.popleft()
|
|
352
|
+
if self._transport and relay_target:
|
|
353
|
+
await self._transport.send_privmsg(
|
|
354
|
+
relay_target,
|
|
355
|
+
"Sorry, I encountered an error processing your request.",
|
|
356
|
+
)
|
|
357
|
+
self._consecutive_turn_failures += 1
|
|
358
|
+
if self._consecutive_turn_failures >= MAX_CONSECUTIVE_TURN_FAILURES:
|
|
359
|
+
self._paused = True
|
|
360
|
+
self._manually_paused = True
|
|
361
|
+
logger.error(
|
|
362
|
+
"Agent %s paused after %d consecutive turn failures",
|
|
363
|
+
self.agent.nick,
|
|
364
|
+
self._consecutive_turn_failures,
|
|
365
|
+
)
|
|
366
|
+
if self._webhook:
|
|
367
|
+
await self._webhook.fire(
|
|
368
|
+
AlertEvent(
|
|
369
|
+
event_type="agent_spiraling",
|
|
370
|
+
nick=self.agent.nick,
|
|
371
|
+
message=(
|
|
372
|
+
f"Agent {self.agent.nick} paused after "
|
|
373
|
+
f"{self._consecutive_turn_failures} consecutive turn failures."
|
|
374
|
+
),
|
|
375
|
+
)
|
|
376
|
+
)
|
|
337
377
|
|
|
338
378
|
async def _start_agent_runner(self) -> None:
|
|
339
379
|
self._agent_runner = ACPAgentRunner(
|
|
@@ -475,6 +515,7 @@ class ACPDaemon:
|
|
|
475
515
|
|
|
476
516
|
async def _on_agent_message(self, msg: dict) -> None:
|
|
477
517
|
"""Relay agent text to IRC and feed to supervisor."""
|
|
518
|
+
self._consecutive_turn_failures = 0
|
|
478
519
|
await self._relay_response_to_irc(msg)
|
|
479
520
|
|
|
480
521
|
if self._supervisor:
|
|
@@ -621,11 +662,13 @@ class ACPDaemon:
|
|
|
621
662
|
|
|
622
663
|
def _ipc_pause(self, req_id: str, msg: dict) -> dict:
|
|
623
664
|
self._paused = True
|
|
624
|
-
|
|
665
|
+
self._manually_paused = True
|
|
666
|
+
logger.info("Agent %s paused (manual)", self.agent.nick)
|
|
625
667
|
return make_response(req_id, ok=True)
|
|
626
668
|
|
|
627
669
|
def _ipc_resume(self, req_id: str, msg: dict) -> dict:
|
|
628
670
|
self._paused = False
|
|
671
|
+
self._manually_paused = False
|
|
629
672
|
logger.info("Agent %s resumed", self.agent.nick)
|
|
630
673
|
# NOTE: Catch-up on missed messages is not yet implemented.
|
|
631
674
|
# IRCTransport does not process HISTORY responses into the buffer.
|
|
@@ -213,6 +213,10 @@ class IRCTransport:
|
|
|
213
213
|
"""Check if the message mentions this agent and fire the callback."""
|
|
214
214
|
if not self.on_mention:
|
|
215
215
|
return
|
|
216
|
+
# DMs always activate (target is the agent's own nick)
|
|
217
|
+
if target == self.nick:
|
|
218
|
+
self.on_mention(target, sender, text)
|
|
219
|
+
return
|
|
216
220
|
short = self.nick.split("-", 1)[1] if "-" in self.nick else None
|
|
217
221
|
if re.search(rf"@{re.escape(self.nick)}\b", text) or (
|
|
218
222
|
short and re.search(rf"@{re.escape(short)}\b", text)
|