agentirc-cli 4.4.1__tar.gz → 4.4.3__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.1 → agentirc_cli-4.4.3}/CHANGELOG.md +21 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/CLAUDE.md +5 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/PKG-INFO +6 -6
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/README.md +5 -5
- agentirc_cli-4.4.3/_includes/head_custom.html +3 -0
- agentirc_cli-4.4.3/assets/images/apple-touch-icon.png +0 -0
- agentirc_cli-4.4.3/assets/images/favicon-16x16.png +0 -0
- agentirc_cli-4.4.3/assets/images/favicon-32x32.png +0 -0
- agentirc_cli-4.4.3/assets/images/favicon.ico +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/daemon.py +48 -5
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/daemon.py +17 -2
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/agent_runner.py +21 -7
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/daemon.py +48 -5
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/agent_runner.py +5 -3
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/daemon.py +48 -5
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/agent-lifecycle.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/agentic-self-learn.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/channel-polling.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/acp/overview.md +2 -1
- agentirc_cli-4.4.3/docs/clients/acp/system-prompt.md +183 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/configuration.md +4 -4
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/overview.md +3 -2
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/setup.md +2 -2
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/configuration.md +9 -8
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/setup.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/culture-cli.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/getting-started.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/index.md +6 -5
- agentirc_cli-4.4.3/docs/reflective-development.md +130 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/rooms.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +5 -5
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +1 -1
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +3 -3
- agentirc_cli-4.4.3/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +165 -0
- agentirc_cli-4.4.3/docs/superpowers/specs/2026-04-08-reflective-development-deepening-design.md +179 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases-index.md +1 -1
- agentirc_cli-4.4.3/favicon.ico +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/daemon.py +39 -5
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/pyproject.toml +1 -1
- agentirc_cli-4.4.3/tests/test_codex_daemon.py +252 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_copilot_daemon.py +106 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_mention_target_cleanup.py +6 -6
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/uv.lock +1 -1
- agentirc_cli-4.4.1/tests/test_codex_daemon.py +0 -96
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.claude/skills/pr-review/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.claude/skills/run-tests/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.flake8 +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.github/workflows/pages.yml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.github/workflows/publish.yml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.github/workflows/security-checks.yml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.github/workflows/tests.yml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.gitignore +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.markdownlint-cli2.yaml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.pr_agent.toml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.pre-commit-config.yaml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/.pylintrc +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/CNAME +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/Gemfile +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/Gemfile.lock +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/LICENSE +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/SECURITY.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/_config.yml +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/_sass/color_schemes/anthropic.scss +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/_sass/custom/custom.scss +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/__main__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/aio.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/bot.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/bot_manager.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/http_listener.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/template_engine.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/bots/virtual_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/agent.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/bot.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/channel.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/mesh.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/constants.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/display.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/formatting.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/mesh.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/shared/process.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/cli/skills.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/agent_runner.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/irc_transport.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/message_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/skill/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/socket_server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/supervisor.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/acp/webhook.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/__main__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/agent_runner.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/irc_transport.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/message_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/skill/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/socket_server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/supervisor.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/claude/webhook.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/irc_transport.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/message_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/skill/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/socket_server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/supervisor.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/codex/webhook.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/irc_transport.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/message_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/skill/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/socket_server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/supervisor.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/clients/copilot/webhook.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/app.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/commands.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/widgets/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/widgets/chat.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/widgets/info_panel.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/console/widgets/sidebar.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/credentials.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/formatting.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/learn_prompt.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/mesh_config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/observer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/overview/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/overview/collector.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/overview/model.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/overview/renderer_text.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/overview/renderer_web.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/overview/web/style.css +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/persistence.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/pidfile.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/commands.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/extensions/federation.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/extensions/history.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/extensions/icons.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/extensions/rooms.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/extensions/tags.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/extensions/threads.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/message.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/protocol-index.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/protocol/replies.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/__main__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/channel.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/history_store.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/ircd.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/remote_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/room_store.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/rooms_util.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/server_link.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/skill.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/skills/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/skills/history.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/skills/icon.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/skills/rooms.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/skills/threads.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/server/thread_store.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/culture/skills/culture/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/agent-client.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/agent-harness-spec.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/harness-conformance.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/index.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/layer1-core-irc.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/layer2-attention.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/layer3-skills.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/layer4-federation.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/layer5-agent-harness.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/server-architecture.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/architecture/threads.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/configuration.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/context-management.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/irc-tools.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/overview.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/setup.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/supervisor.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/claude/webhooks.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/context-management.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/irc-tools.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/supervisor.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/codex/webhooks.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/context-management.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/irc-tools.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/overview.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/supervisor.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/clients/copilot/webhooks.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/SECURITY.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/bots.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/ci.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/cli.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/docs-site.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/index.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/ops-tooling.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/overview.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/operations/publishing.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/persistent-history.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/resources/github-copilot-sdk-instructions.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/server-rename.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/01-pair-programming.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/02-code-review-ensemble.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/03-cross-server-delegation.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/04-knowledge-propagation.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/05-the-observer.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/06-cross-server-ops.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/07-supervisor-intervention.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/08-apps-as-agents.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/09-research-swarm.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/use-cases/10-agent-lifecycle.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/docs/what-is-culture.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/README.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/irc_transport.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/message_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/skill/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/skill/irc_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/socket_server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/packages/agent-harness/webhook.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/plugins/claude-code/skills/culture/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/plugins/claude-code/skills/irc/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/sonar-project.properties +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/__init__.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/conftest.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_acp_daemon.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_agent_runner.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_archive.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_bot.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_bot_config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_bot_manager.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_bots_integration.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_channel.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_connection.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_console_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_console_commands.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_console_connection.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_console_icons.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_console_integration.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_daemon.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_daemon_config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_daemon_ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_discovery.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_federation.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_history.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_http_listener.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_integration_layer5.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_ipc.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_irc_transport.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_link_reconnect.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_mention_alias.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_mentions.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_mesh_config.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_message.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_message_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_messaging.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_modes.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_overview_cli.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_overview_collector.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_overview_model.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_overview_renderer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_overview_web.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_persistence.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_pidfile.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_poll_loop.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_room_persistence.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_rooms.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_rooms_federation.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_rooms_integration.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_server_icon_skill.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_setup_update_cli.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_skill_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_skills.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_socket_server.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_supervisor.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_template_engine.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_thread_buffer.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_threads.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_virtual_client.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_wait_for_port.py +0 -0
- {agentirc_cli-4.4.1 → agentirc_cli-4.4.3}/tests/test_webhook.py +0 -0
|
@@ -4,6 +4,27 @@ 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.3] - 2026-04-08
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Regenerate all favicons, including `/favicon.ico` and `/assets/images/favicon.ico`, from the source image with proper cropping and optimization
|
|
12
|
+
- Reduce `/favicon.ico` from 1.4 MB to 3.5 KB and optimize `/assets/images/favicon.ico`
|
|
13
|
+
- Remove original source image (IMG_3161.png)
|
|
14
|
+
|
|
15
|
+
## [4.4.2] - 2026-04-08
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Codex/copilot: preserve HOME for auth tokens instead of isolating (#159)
|
|
21
|
+
- Codex: fix turn sync race condition causing concatenated rapid-mention responses (#165)
|
|
22
|
+
- All backends: sleep scheduler no longer overrides manual pause (#162)
|
|
23
|
+
- All backends: poll loop filters @mention messages to prevent duplicate responses (#160)
|
|
24
|
+
- All backends: turn errors now send feedback to IRC channel (#163)
|
|
25
|
+
- All backends: consecutive turn failure circuit breaker pauses agent after 3 failures (#164)
|
|
26
|
+
- Status query response verified not leaking to IRC channel (#161)
|
|
27
|
+
|
|
7
28
|
## [4.4.1] - 2026-04-07
|
|
8
29
|
|
|
9
30
|
|
|
@@ -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
|
|
|
@@ -50,6 +50,10 @@ When implementing features, write a corresponding markdown doc in `docs/` descri
|
|
|
50
50
|
|
|
51
51
|
`<server>-<agent>` (e.g., `thor-claude`, `spark-ori`). Globally unique by construction.
|
|
52
52
|
|
|
53
|
+
## Mesh Presence
|
|
54
|
+
|
|
55
|
+
When not actively working with a user, you run as `spark-culture` on the mesh — the agent daemon launched from this repo's working directory. This is your persistent identity on the network: you can observe channels, respond to mentions, and collaborate with other agents. The systemd service is `culture-agent-spark-culture.service`.
|
|
56
|
+
|
|
53
57
|
## Protocol
|
|
54
58
|
|
|
55
59
|
IRC RFC 2812 as base. Extensions use new verbs (never redefine existing commands), documented in `protocol/extensions/`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentirc-cli
|
|
3
|
-
Version: 4.4.
|
|
3
|
+
Version: 4.4.3
|
|
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,15 +138,15 @@ 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 — the work, the documentation, and the participants all reflect back on themselves. Documentation flows back as context. Code reflects from reference to implementation. Practitioners review their own output and improve the environment they work in. The lifecycle is continuous, not graduated:
|
|
144
144
|
|
|
145
145
|
👋 **Introduce** → 🎓 **Educate** → 🤝 **Join** → 🧭 **Mentor** → ⭐ **Promote**
|
|
146
146
|
|
|
147
147
|
Introduce an agent to your project, educate it until it's autonomous enough, join it to the mesh, and mentor it as things change. No agent or human ever finishes developing — the process is ongoing for every participant.
|
|
148
148
|
|
|
149
|
-
Read more: **[Agent Lifecycle](docs/agent-lifecycle.md)**
|
|
149
|
+
Read more: **[Reflective Development](docs/reflective-development.md)** · **[Agent Lifecycle](docs/agent-lifecycle.md)**
|
|
150
150
|
|
|
151
151
|
---
|
|
152
152
|
|
|
@@ -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,15 +114,15 @@ 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 — the work, the documentation, and the participants all reflect back on themselves. Documentation flows back as context. Code reflects from reference to implementation. Practitioners review their own output and improve the environment they work in. The lifecycle is continuous, not graduated:
|
|
120
120
|
|
|
121
121
|
👋 **Introduce** → 🎓 **Educate** → 🤝 **Join** → 🧭 **Mentor** → ⭐ **Promote**
|
|
122
122
|
|
|
123
123
|
Introduce an agent to your project, educate it until it's autonomous enough, join it to the mesh, and mentor it as things change. No agent or human ever finishes developing — the process is ongoing for every participant.
|
|
124
124
|
|
|
125
|
-
Read more: **[Agent Lifecycle](docs/agent-lifecycle.md)**
|
|
125
|
+
Read more: **[Reflective Development](docs/reflective-development.md)** · **[Agent Lifecycle](docs/agent-lifecycle.md)**
|
|
126
126
|
|
|
127
127
|
---
|
|
128
128
|
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<link rel="icon" type="image/png" sizes="32x32" href="{{ '/assets/images/favicon-32x32.png' | relative_url }}">
|
|
2
|
+
<link rel="icon" type="image/png" sizes="16x16" href="{{ '/assets/images/favicon-16x16.png' | relative_url }}">
|
|
3
|
+
<link rel="apple-touch-icon" sizes="180x180" href="{{ '/assets/images/apple-touch-icon.png' | relative_url }}">
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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.
|
|
@@ -4,6 +4,7 @@ import asyncio
|
|
|
4
4
|
import datetime
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
|
+
import re
|
|
7
8
|
import time
|
|
8
9
|
|
|
9
10
|
from culture.aio import maybe_await
|
|
@@ -62,6 +63,7 @@ class AgentDaemon:
|
|
|
62
63
|
|
|
63
64
|
# Pause/sleep state
|
|
64
65
|
self._paused: bool = False
|
|
66
|
+
self._manually_paused: bool = False
|
|
65
67
|
self._last_activation: float | None = None
|
|
66
68
|
|
|
67
69
|
# Status query state — for asking the agent what it's doing
|
|
@@ -236,7 +238,7 @@ class AgentDaemon:
|
|
|
236
238
|
if should_sleep and not self._paused:
|
|
237
239
|
self._paused = True
|
|
238
240
|
logger.info("Sleep schedule: pausing %s", self.agent.nick)
|
|
239
|
-
elif not should_sleep and self._paused:
|
|
241
|
+
elif not should_sleep and self._paused and not self._manually_paused:
|
|
240
242
|
self._paused = False
|
|
241
243
|
logger.info("Sleep schedule: resuming %s", self.agent.nick)
|
|
242
244
|
except asyncio.CancelledError:
|
|
@@ -256,6 +258,17 @@ class AgentDaemon:
|
|
|
256
258
|
continue
|
|
257
259
|
for channel in self.agent.channels:
|
|
258
260
|
msgs = self._buffer.read(channel)
|
|
261
|
+
if not msgs:
|
|
262
|
+
continue
|
|
263
|
+
# Filter out messages that @mention this agent (already handled)
|
|
264
|
+
nick = self.agent.nick
|
|
265
|
+
short = nick.split("-", 1)[1] if "-" in nick else None
|
|
266
|
+
msgs = [
|
|
267
|
+
m
|
|
268
|
+
for m in msgs
|
|
269
|
+
if not re.search(rf"@{re.escape(nick)}\b", m.text)
|
|
270
|
+
and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
|
|
271
|
+
]
|
|
259
272
|
if not msgs:
|
|
260
273
|
continue
|
|
261
274
|
lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
|
|
@@ -542,11 +555,13 @@ class AgentDaemon:
|
|
|
542
555
|
|
|
543
556
|
def _ipc_pause(self, req_id: str, msg: dict) -> dict:
|
|
544
557
|
self._paused = True
|
|
545
|
-
|
|
558
|
+
self._manually_paused = True
|
|
559
|
+
logger.info("Agent %s paused (manual)", self.agent.nick)
|
|
546
560
|
return make_response(req_id, ok=True)
|
|
547
561
|
|
|
548
562
|
def _ipc_resume(self, req_id: str, msg: dict) -> dict:
|
|
549
563
|
self._paused = False
|
|
564
|
+
self._manually_paused = False
|
|
550
565
|
logger.info("Agent %s resumed", self.agent.nick)
|
|
551
566
|
# NOTE: Catch-up on missed messages is not yet implemented.
|
|
552
567
|
# IRCTransport does not process HISTORY responses into the buffer.
|
|
@@ -46,6 +46,8 @@ class CodexAgentRunner:
|
|
|
46
46
|
self._request_id = 0
|
|
47
47
|
self._pending: dict[int, asyncio.Future] = {}
|
|
48
48
|
self._accumulated_text = ""
|
|
49
|
+
self._turn_done: asyncio.Event = asyncio.Event()
|
|
50
|
+
self._turn_done.set() # Initially not busy
|
|
49
51
|
|
|
50
52
|
def is_running(self) -> bool:
|
|
51
53
|
return self._running
|
|
@@ -58,12 +60,12 @@ class CodexAgentRunner:
|
|
|
58
60
|
"""Start codex app-server as a subprocess and initialize a thread."""
|
|
59
61
|
self._stopping = False
|
|
60
62
|
|
|
61
|
-
# Isolate
|
|
63
|
+
# Isolate data/state dirs to prevent session interference, but
|
|
64
|
+
# preserve HOME and XDG_CONFIG_HOME so codex finds auth tokens.
|
|
62
65
|
self._isolated_home = tempfile.mkdtemp(prefix="culture-codex-")
|
|
63
66
|
isolated_env = dict(os.environ)
|
|
64
|
-
isolated_env["
|
|
65
|
-
isolated_env.
|
|
66
|
-
isolated_env.pop("XDG_CONFIG_HOME", None)
|
|
67
|
+
isolated_env["XDG_DATA_HOME"] = os.path.join(self._isolated_home, ".local", "share")
|
|
68
|
+
isolated_env["XDG_STATE_HOME"] = os.path.join(self._isolated_home, ".local", "state")
|
|
67
69
|
|
|
68
70
|
try:
|
|
69
71
|
# Spawn codex app-server in stdio mode
|
|
@@ -298,12 +300,17 @@ class CodexAgentRunner:
|
|
|
298
300
|
elif method == "turn/completed":
|
|
299
301
|
self._busy = False
|
|
300
302
|
await self._flush_accumulated_text()
|
|
303
|
+
self._turn_done.set()
|
|
301
304
|
|
|
302
305
|
elif method in self._APPROVAL_METHODS:
|
|
303
306
|
await self._auto_approve(msg)
|
|
304
307
|
|
|
305
308
|
elif method == "error":
|
|
306
309
|
logger.error("Codex error: %s", params)
|
|
310
|
+
self._busy = False
|
|
311
|
+
self._turn_done.set()
|
|
312
|
+
if self.on_turn_error:
|
|
313
|
+
await maybe_await(self.on_turn_error())
|
|
307
314
|
|
|
308
315
|
async def _flush_accumulated_text(self) -> None:
|
|
309
316
|
"""Fire on_message with any accumulated text and reset the buffer."""
|
|
@@ -328,6 +335,7 @@ class CodexAgentRunner:
|
|
|
328
335
|
|
|
329
336
|
async def _execute_single_turn(self, text: str) -> None:
|
|
330
337
|
"""Send one turn request and wait for completion."""
|
|
338
|
+
self._turn_done.clear()
|
|
331
339
|
try:
|
|
332
340
|
await self._send_request(
|
|
333
341
|
"turn/start",
|
|
@@ -336,11 +344,17 @@ class CodexAgentRunner:
|
|
|
336
344
|
"input": [{"type": "text", "text": text}],
|
|
337
345
|
},
|
|
338
346
|
)
|
|
339
|
-
# Wait for turn
|
|
340
|
-
|
|
341
|
-
await
|
|
347
|
+
# Wait for turn/completed notification via the event
|
|
348
|
+
async with asyncio.timeout(300):
|
|
349
|
+
await self._turn_done.wait()
|
|
350
|
+
except asyncio.TimeoutError:
|
|
351
|
+
logger.warning("Codex turn timed out after 300s")
|
|
352
|
+
self._turn_done.set()
|
|
353
|
+
if self.on_turn_error:
|
|
354
|
+
await maybe_await(self.on_turn_error())
|
|
342
355
|
except Exception:
|
|
343
356
|
logger.exception("Codex turn error")
|
|
357
|
+
self._turn_done.set()
|
|
344
358
|
if self.on_turn_error:
|
|
345
359
|
await maybe_await(self.on_turn_error())
|
|
346
360
|
|
|
@@ -10,6 +10,7 @@ import asyncio
|
|
|
10
10
|
import datetime
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
|
+
import re
|
|
13
14
|
import time
|
|
14
15
|
from collections import deque
|
|
15
16
|
|
|
@@ -34,6 +35,7 @@ _ERR_MISSING_CHANNEL_THREAD_MSG = "Missing 'channel', 'thread', or 'message'"
|
|
|
34
35
|
MAX_CRASH_COUNT = 3
|
|
35
36
|
CRASH_WINDOW_SECONDS = 300
|
|
36
37
|
CRASH_RESTART_DELAY = 5
|
|
38
|
+
MAX_CONSECUTIVE_TURN_FAILURES = 3
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
class CodexDaemon:
|
|
@@ -71,9 +73,11 @@ class CodexDaemon:
|
|
|
71
73
|
# Crash-recovery state
|
|
72
74
|
self._crash_times: list[float] = []
|
|
73
75
|
self._circuit_open = False
|
|
76
|
+
self._consecutive_turn_failures: int = 0
|
|
74
77
|
|
|
75
78
|
# Pause/sleep state
|
|
76
79
|
self._paused: bool = False
|
|
80
|
+
self._manually_paused: bool = False
|
|
77
81
|
self._last_activation: float | None = None
|
|
78
82
|
|
|
79
83
|
# Status query state — for asking the agent what it's doing
|
|
@@ -245,7 +249,7 @@ class CodexDaemon:
|
|
|
245
249
|
if should_sleep and not self._paused:
|
|
246
250
|
self._paused = True
|
|
247
251
|
logger.info("Sleep schedule: pausing %s", self.agent.nick)
|
|
248
|
-
elif not should_sleep and self._paused:
|
|
252
|
+
elif not should_sleep and self._paused and not self._manually_paused:
|
|
249
253
|
self._paused = False
|
|
250
254
|
logger.info("Sleep schedule: resuming %s", self.agent.nick)
|
|
251
255
|
except asyncio.CancelledError:
|
|
@@ -275,6 +279,17 @@ class CodexDaemon:
|
|
|
275
279
|
|
|
276
280
|
def _send_channel_poll(self, channel) -> None:
|
|
277
281
|
msgs = self._buffer.read(channel)
|
|
282
|
+
if not msgs:
|
|
283
|
+
return
|
|
284
|
+
# Filter out messages that @mention this agent (already handled by _on_mention)
|
|
285
|
+
nick = self.agent.nick
|
|
286
|
+
short = nick.split("-", 1)[1] if "-" in nick else None
|
|
287
|
+
msgs = [
|
|
288
|
+
m
|
|
289
|
+
for m in msgs
|
|
290
|
+
if not re.search(rf"@{re.escape(nick)}\b", m.text)
|
|
291
|
+
and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
|
|
292
|
+
]
|
|
278
293
|
if not msgs:
|
|
279
294
|
return
|
|
280
295
|
lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
|
|
@@ -305,10 +320,35 @@ class CodexDaemon:
|
|
|
305
320
|
# Agent runner helpers
|
|
306
321
|
# ------------------------------------------------------------------
|
|
307
322
|
|
|
308
|
-
def _on_turn_error(self) -> None:
|
|
309
|
-
"""
|
|
323
|
+
async def _on_turn_error(self) -> None:
|
|
324
|
+
"""Send error feedback to IRC and clean up stale relay target."""
|
|
310
325
|
if self._mention_targets:
|
|
311
|
-
self._mention_targets.popleft()
|
|
326
|
+
relay_target = self._mention_targets.popleft()
|
|
327
|
+
if self._transport and relay_target:
|
|
328
|
+
await self._transport.send_privmsg(
|
|
329
|
+
relay_target,
|
|
330
|
+
"Sorry, I encountered an error processing your request.",
|
|
331
|
+
)
|
|
332
|
+
self._consecutive_turn_failures += 1
|
|
333
|
+
if self._consecutive_turn_failures >= MAX_CONSECUTIVE_TURN_FAILURES:
|
|
334
|
+
self._paused = True
|
|
335
|
+
self._manually_paused = True
|
|
336
|
+
logger.error(
|
|
337
|
+
"Agent %s paused after %d consecutive turn failures",
|
|
338
|
+
self.agent.nick,
|
|
339
|
+
self._consecutive_turn_failures,
|
|
340
|
+
)
|
|
341
|
+
if self._webhook:
|
|
342
|
+
await self._webhook.fire(
|
|
343
|
+
AlertEvent(
|
|
344
|
+
event_type="agent_spiraling",
|
|
345
|
+
nick=self.agent.nick,
|
|
346
|
+
message=(
|
|
347
|
+
f"Agent {self.agent.nick} paused after "
|
|
348
|
+
f"{self._consecutive_turn_failures} consecutive turn failures."
|
|
349
|
+
),
|
|
350
|
+
)
|
|
351
|
+
)
|
|
312
352
|
|
|
313
353
|
async def _start_agent_runner(self) -> None:
|
|
314
354
|
self._agent_runner = CodexAgentRunner(
|
|
@@ -443,6 +483,7 @@ class CodexDaemon:
|
|
|
443
483
|
|
|
444
484
|
async def _on_agent_message(self, msg: dict) -> None:
|
|
445
485
|
"""Relay agent text to IRC and feed to supervisor."""
|
|
486
|
+
self._consecutive_turn_failures = 0
|
|
446
487
|
await self._relay_response_to_irc(msg)
|
|
447
488
|
|
|
448
489
|
if self._supervisor:
|
|
@@ -581,11 +622,13 @@ class CodexDaemon:
|
|
|
581
622
|
|
|
582
623
|
def _ipc_pause(self, req_id: str, msg: dict) -> dict:
|
|
583
624
|
self._paused = True
|
|
584
|
-
|
|
625
|
+
self._manually_paused = True
|
|
626
|
+
logger.info("Agent %s paused (manual)", self.agent.nick)
|
|
585
627
|
return make_response(req_id, ok=True)
|
|
586
628
|
|
|
587
629
|
def _ipc_resume(self, req_id: str, msg: dict) -> dict:
|
|
588
630
|
self._paused = False
|
|
631
|
+
self._manually_paused = False
|
|
589
632
|
logger.info("Agent %s resumed", self.agent.nick)
|
|
590
633
|
# NOTE: Catch-up on missed messages is not yet implemented.
|
|
591
634
|
# IRCTransport does not process HISTORY responses into the buffer.
|
|
@@ -58,10 +58,12 @@ class CopilotAgentRunner:
|
|
|
58
58
|
# Lazy import — github-copilot-sdk is only needed at runtime
|
|
59
59
|
from copilot import CopilotClient, PermissionHandler, SubprocessConfig
|
|
60
60
|
|
|
61
|
-
# Isolate
|
|
61
|
+
# Isolate data/state dirs to prevent session interference, but
|
|
62
|
+
# preserve HOME and XDG_CONFIG_HOME so copilot finds auth tokens.
|
|
62
63
|
self._isolated_home = tempfile.mkdtemp(prefix="culture-copilot-")
|
|
63
|
-
isolated_env =
|
|
64
|
-
isolated_env.
|
|
64
|
+
isolated_env = dict(os.environ)
|
|
65
|
+
isolated_env["XDG_DATA_HOME"] = os.path.join(self._isolated_home, ".local", "share")
|
|
66
|
+
isolated_env["XDG_STATE_HOME"] = os.path.join(self._isolated_home, ".local", "state")
|
|
65
67
|
|
|
66
68
|
try:
|
|
67
69
|
# Create and start the CopilotClient (spawns copilot CLI process)
|
|
@@ -10,6 +10,7 @@ import asyncio
|
|
|
10
10
|
import datetime
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
|
+
import re
|
|
13
14
|
import time
|
|
14
15
|
from collections import deque
|
|
15
16
|
|
|
@@ -34,6 +35,7 @@ _ERR_MISSING_CHANNEL_THREAD_MSG = "Missing 'channel', 'thread', or 'message'"
|
|
|
34
35
|
MAX_CRASH_COUNT = 3
|
|
35
36
|
CRASH_WINDOW_SECONDS = 300
|
|
36
37
|
CRASH_RESTART_DELAY = 5
|
|
38
|
+
MAX_CONSECUTIVE_TURN_FAILURES = 3
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
class CopilotDaemon:
|
|
@@ -71,9 +73,11 @@ class CopilotDaemon:
|
|
|
71
73
|
# Crash-recovery state
|
|
72
74
|
self._crash_times: list[float] = []
|
|
73
75
|
self._circuit_open = False
|
|
76
|
+
self._consecutive_turn_failures: int = 0
|
|
74
77
|
|
|
75
78
|
# Pause/sleep state
|
|
76
79
|
self._paused: bool = False
|
|
80
|
+
self._manually_paused: bool = False
|
|
77
81
|
self._last_activation: float | None = None
|
|
78
82
|
|
|
79
83
|
# Status query state — for asking the agent what it's doing
|
|
@@ -245,7 +249,7 @@ class CopilotDaemon:
|
|
|
245
249
|
if should_sleep and not self._paused:
|
|
246
250
|
self._paused = True
|
|
247
251
|
logger.info("Sleep schedule: pausing %s", self.agent.nick)
|
|
248
|
-
elif not should_sleep and self._paused:
|
|
252
|
+
elif not should_sleep and self._paused and not self._manually_paused:
|
|
249
253
|
self._paused = False
|
|
250
254
|
logger.info("Sleep schedule: resuming %s", self.agent.nick)
|
|
251
255
|
except asyncio.CancelledError:
|
|
@@ -275,6 +279,17 @@ class CopilotDaemon:
|
|
|
275
279
|
|
|
276
280
|
def _send_channel_poll(self, channel) -> None:
|
|
277
281
|
msgs = self._buffer.read(channel)
|
|
282
|
+
if not msgs:
|
|
283
|
+
return
|
|
284
|
+
# Filter out messages that @mention this agent (already handled by _on_mention)
|
|
285
|
+
nick = self.agent.nick
|
|
286
|
+
short = nick.split("-", 1)[1] if "-" in nick else None
|
|
287
|
+
msgs = [
|
|
288
|
+
m
|
|
289
|
+
for m in msgs
|
|
290
|
+
if not re.search(rf"@{re.escape(nick)}\b", m.text)
|
|
291
|
+
and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
|
|
292
|
+
]
|
|
278
293
|
if not msgs:
|
|
279
294
|
return
|
|
280
295
|
lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
|
|
@@ -305,10 +320,35 @@ class CopilotDaemon:
|
|
|
305
320
|
# Agent runner helpers
|
|
306
321
|
# ------------------------------------------------------------------
|
|
307
322
|
|
|
308
|
-
def _on_turn_error(self) -> None:
|
|
309
|
-
"""
|
|
323
|
+
async def _on_turn_error(self) -> None:
|
|
324
|
+
"""Send error feedback to IRC and clean up stale relay target."""
|
|
310
325
|
if self._mention_targets:
|
|
311
|
-
self._mention_targets.popleft()
|
|
326
|
+
relay_target = self._mention_targets.popleft()
|
|
327
|
+
if self._transport and relay_target:
|
|
328
|
+
await self._transport.send_privmsg(
|
|
329
|
+
relay_target,
|
|
330
|
+
"Sorry, I encountered an error processing your request.",
|
|
331
|
+
)
|
|
332
|
+
self._consecutive_turn_failures += 1
|
|
333
|
+
if self._consecutive_turn_failures >= MAX_CONSECUTIVE_TURN_FAILURES:
|
|
334
|
+
self._paused = True
|
|
335
|
+
self._manually_paused = True
|
|
336
|
+
logger.error(
|
|
337
|
+
"Agent %s paused after %d consecutive turn failures",
|
|
338
|
+
self.agent.nick,
|
|
339
|
+
self._consecutive_turn_failures,
|
|
340
|
+
)
|
|
341
|
+
if self._webhook:
|
|
342
|
+
await self._webhook.fire(
|
|
343
|
+
AlertEvent(
|
|
344
|
+
event_type="agent_spiraling",
|
|
345
|
+
nick=self.agent.nick,
|
|
346
|
+
message=(
|
|
347
|
+
f"Agent {self.agent.nick} paused after "
|
|
348
|
+
f"{self._consecutive_turn_failures} consecutive turn failures."
|
|
349
|
+
),
|
|
350
|
+
)
|
|
351
|
+
)
|
|
312
352
|
|
|
313
353
|
async def _start_agent_runner(self) -> None:
|
|
314
354
|
# Resolve installed skill path for the Copilot session
|
|
@@ -450,6 +490,7 @@ class CopilotDaemon:
|
|
|
450
490
|
|
|
451
491
|
async def _on_agent_message(self, msg: dict) -> None:
|
|
452
492
|
"""Relay agent text to IRC and feed to supervisor."""
|
|
493
|
+
self._consecutive_turn_failures = 0
|
|
453
494
|
await self._relay_response_to_irc(msg)
|
|
454
495
|
|
|
455
496
|
if self._supervisor:
|
|
@@ -588,11 +629,13 @@ class CopilotDaemon:
|
|
|
588
629
|
|
|
589
630
|
def _ipc_pause(self, req_id: str, msg: dict) -> dict:
|
|
590
631
|
self._paused = True
|
|
591
|
-
|
|
632
|
+
self._manually_paused = True
|
|
633
|
+
logger.info("Agent %s paused (manual)", self.agent.nick)
|
|
592
634
|
return make_response(req_id, ok=True)
|
|
593
635
|
|
|
594
636
|
def _ipc_resume(self, req_id: str, msg: dict) -> dict:
|
|
595
637
|
self._paused = False
|
|
638
|
+
self._manually_paused = False
|
|
596
639
|
logger.info("Agent %s resumed", self.agent.nick)
|
|
597
640
|
# NOTE: Catch-up on missed messages is not yet implemented.
|
|
598
641
|
# IRCTransport does not process HISTORY responses into the buffer.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Agent Lifecycle"
|
|
3
|
-
nav_order:
|
|
3
|
+
nav_order: 4
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Culture agents aren't configured — they're developed. You introduce an agent to a project, educate it through real work until it's autonomous enough to contribute, then join it to the mesh. Once on the mesh, you mentor it as things change. Over time your network becomes a community of specialists that developed out of real work — and the process never ends.
|