agentlings 0.2.0__tar.gz → 0.2.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.
- agentlings-0.2.2/.github/workflows/publish.yml +22 -0
- {agentlings-0.2.0/.claude/worktrees/agent-af4d7e32 → agentlings-0.2.2}/.gitignore +2 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/PKG-INFO +78 -38
- {agentlings-0.2.0 → agentlings-0.2.2}/README.md +77 -37
- {agentlings-0.2.0 → agentlings-0.2.2}/pyproject.toml +1 -1
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/protocol/a2a_task_store.py +12 -3
- agentlings-0.2.2/src/agentlings/templates/default/agent.yaml +41 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_a2a_task_store.py +16 -0
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/.git +0 -1
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/.gitignore +0 -12
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/CLAUDE.md +0 -128
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/README.md +0 -367
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/agent.example.yaml +0 -41
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/pyproject.toml +0 -51
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/__main__.py +0 -112
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/config.py +0 -235
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/core/llm.py +0 -482
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/core/prompt.py +0 -146
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/protocol/a2a_task_store.py +0 -150
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/protocol/mcp.py +0 -245
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/server.py +0 -244
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/integration/a2a_client.py +0 -192
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_a2a_task_store.py +0 -211
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_config.py +0 -305
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_llm.py +0 -220
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_mcp_handler.py +0 -94
- agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_prompt.py +0 -221
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/.env.example +0 -14
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/.git +0 -1
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/.github/workflows/ci.yml +0 -34
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/CLAUDE.md +0 -128
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/Dockerfile +0 -11
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/README.md +0 -367
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/agent.example.yaml +0 -41
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/docker-compose.test.yml +0 -27
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/logo.png +0 -0
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/pyproject.toml +0 -51
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/sleep.png +0 -0
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/__init__.py +0 -3
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/__main__.py +0 -112
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/config.py +0 -235
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/__init__.py +0 -1
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/completion.py +0 -219
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/llm.py +0 -482
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/loop.py +0 -134
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/memory_models.py +0 -97
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/memory_store.py +0 -109
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/models.py +0 -231
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/prompt.py +0 -146
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/scheduler.py +0 -141
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/sleep.py +0 -393
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/store.py +0 -318
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/task.py +0 -1087
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/telemetry.py +0 -181
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/log.py +0 -23
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/__init__.py +0 -1
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/a2a.py +0 -199
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/a2a_task_store.py +0 -139
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/agent_card.py +0 -69
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/server.py +0 -233
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/__init__.py +0 -1
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/builtins.py +0 -307
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/memory.py +0 -104
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/registry.py +0 -154
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/Dockerfile +0 -7
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/__init__.py +0 -0
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/agent.test.yaml +0 -16
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/__init__.py +0 -0
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/a2a_client.py +0 -158
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/conftest.py +0 -146
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/mcp_client.py +0 -106
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_a2a.py +0 -63
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_agent_card.py +0 -42
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_mcp.py +0 -141
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_task_flow.py +0 -337
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/__init__.py +0 -0
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/conftest.py +0 -58
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_a2a_task_store.py +0 -210
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_agent_card.py +0 -77
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_completion.py +0 -384
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_config.py +0 -305
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_live_api.py +0 -134
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_llm.py +0 -220
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_logging.py +0 -51
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_loop.py +0 -103
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_memory_models.py +0 -80
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_memory_store.py +0 -152
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_memory_tool.py +0 -72
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_models.py +0 -33
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_prompt.py +0 -221
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_scheduler.py +0 -73
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_sleep.py +0 -198
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_store.py +0 -508
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_task.py +0 -1241
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_telemetry.py +0 -46
- agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_tools.py +0 -299
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.env.example +0 -14
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.git +0 -1
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.github/workflows/ci.yml +0 -34
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.gitignore +0 -12
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/CLAUDE.md +0 -128
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/Dockerfile +0 -11
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/README.md +0 -367
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/agent.example.yaml +0 -41
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/docker-compose.test.yml +0 -27
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/logo.png +0 -0
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/pyproject.toml +0 -51
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/sleep.png +0 -0
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/__init__.py +0 -3
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/__main__.py +0 -112
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/config.py +0 -235
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/__init__.py +0 -1
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/completion.py +0 -219
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/llm.py +0 -482
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/loop.py +0 -134
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/memory_models.py +0 -97
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/memory_store.py +0 -109
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/models.py +0 -231
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/prompt.py +0 -146
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/scheduler.py +0 -141
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/sleep.py +0 -393
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/store.py +0 -318
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/task.py +0 -1087
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/telemetry.py +0 -181
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/log.py +0 -23
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/__init__.py +0 -1
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/a2a.py +0 -199
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/a2a_task_store.py +0 -139
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/agent_card.py +0 -69
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/mcp.py +0 -245
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/server.py +0 -233
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/__init__.py +0 -1
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/builtins.py +0 -307
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/memory.py +0 -104
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/registry.py +0 -154
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/Dockerfile +0 -7
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/__init__.py +0 -0
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/agent.test.yaml +0 -16
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/__init__.py +0 -0
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/a2a_client.py +0 -158
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/conftest.py +0 -146
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/mcp_client.py +0 -106
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_a2a.py +0 -63
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_agent_card.py +0 -42
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_mcp.py +0 -141
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_task_flow.py +0 -337
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/__init__.py +0 -0
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/conftest.py +0 -58
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_a2a_task_store.py +0 -210
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_agent_card.py +0 -77
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_completion.py +0 -384
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_config.py +0 -305
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_live_api.py +0 -134
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_llm.py +0 -220
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_logging.py +0 -51
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_loop.py +0 -103
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_mcp_handler.py +0 -94
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_memory_models.py +0 -80
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_memory_store.py +0 -152
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_memory_tool.py +0 -72
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_models.py +0 -33
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_prompt.py +0 -221
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_scheduler.py +0 -73
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_sleep.py +0 -198
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_store.py +0 -508
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_task.py +0 -1241
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_telemetry.py +0 -46
- agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_tools.py +0 -299
- agentlings-0.2.0/.env.example +0 -14
- agentlings-0.2.0/.env.test +0 -4
- agentlings-0.2.0/.github/workflows/ci.yml +0 -34
- agentlings-0.2.0/.github/workflows/publish.yml +0 -37
- agentlings-0.2.0/.gitignore +0 -12
- agentlings-0.2.0/.idea/.gitignore +0 -15
- agentlings-0.2.0/.idea/DonkeyWork-Agentlings.iml +0 -9
- agentlings-0.2.0/.idea/copilot.data.migration.ask2agent.xml +0 -6
- agentlings-0.2.0/.idea/encodings.xml +0 -4
- agentlings-0.2.0/.idea/go.imports.xml +0 -11
- agentlings-0.2.0/.idea/indexLayout.xml +0 -8
- agentlings-0.2.0/.idea/modules.xml +0 -8
- agentlings-0.2.0/.idea/projectSettingsUpdater.xml +0 -8
- agentlings-0.2.0/.idea/vcs.xml +0 -6
- agentlings-0.2.0/.idea/workspace.xml +0 -85
- agentlings-0.2.0/Dockerfile +0 -11
- agentlings-0.2.0/docker-compose.test.yml +0 -27
- agentlings-0.2.0/logo.png +0 -0
- agentlings-0.2.0/navi_fixed.ico +0 -0
- agentlings-0.2.0/navi_full.ico +0 -0
- agentlings-0.2.0/sleep.png +0 -0
- agentlings-0.2.0/src/agentlings/__init__.py +0 -3
- agentlings-0.2.0/src/agentlings/core/__init__.py +0 -1
- agentlings-0.2.0/src/agentlings/core/completion.py +0 -219
- agentlings-0.2.0/src/agentlings/core/loop.py +0 -134
- agentlings-0.2.0/src/agentlings/core/memory_models.py +0 -97
- agentlings-0.2.0/src/agentlings/core/memory_store.py +0 -109
- agentlings-0.2.0/src/agentlings/core/models.py +0 -231
- agentlings-0.2.0/src/agentlings/core/scheduler.py +0 -141
- agentlings-0.2.0/src/agentlings/core/sleep.py +0 -393
- agentlings-0.2.0/src/agentlings/core/store.py +0 -318
- agentlings-0.2.0/src/agentlings/core/task.py +0 -1087
- agentlings-0.2.0/src/agentlings/core/telemetry.py +0 -181
- agentlings-0.2.0/src/agentlings/log.py +0 -23
- agentlings-0.2.0/src/agentlings/protocol/__init__.py +0 -1
- agentlings-0.2.0/src/agentlings/protocol/a2a.py +0 -220
- agentlings-0.2.0/src/agentlings/protocol/agent_card.py +0 -83
- agentlings-0.2.0/src/agentlings/protocol/mcp.py +0 -232
- agentlings-0.2.0/src/agentlings/templates/default/agent.yaml +0 -14
- agentlings-0.2.0/src/agentlings/tools/__init__.py +0 -1
- agentlings-0.2.0/src/agentlings/tools/builtins.py +0 -307
- agentlings-0.2.0/src/agentlings/tools/memory.py +0 -104
- agentlings-0.2.0/src/agentlings/tools/registry.py +0 -154
- agentlings-0.2.0/tests/Dockerfile +0 -7
- agentlings-0.2.0/tests/__init__.py +0 -0
- agentlings-0.2.0/tests/agent.test.yaml +0 -16
- agentlings-0.2.0/tests/integration/__init__.py +0 -0
- agentlings-0.2.0/tests/integration/conftest.py +0 -146
- agentlings-0.2.0/tests/integration/mcp_client.py +0 -106
- agentlings-0.2.0/tests/integration/test_a2a.py +0 -111
- agentlings-0.2.0/tests/integration/test_agent_card.py +0 -45
- agentlings-0.2.0/tests/integration/test_mcp.py +0 -141
- agentlings-0.2.0/tests/integration/test_task_flow.py +0 -337
- agentlings-0.2.0/tests/unit/__init__.py +0 -0
- agentlings-0.2.0/tests/unit/conftest.py +0 -58
- agentlings-0.2.0/tests/unit/test_agent_card.py +0 -85
- agentlings-0.2.0/tests/unit/test_completion.py +0 -384
- agentlings-0.2.0/tests/unit/test_live_api.py +0 -134
- agentlings-0.2.0/tests/unit/test_logging.py +0 -51
- agentlings-0.2.0/tests/unit/test_loop.py +0 -103
- agentlings-0.2.0/tests/unit/test_mcp_handler.py +0 -56
- agentlings-0.2.0/tests/unit/test_memory_models.py +0 -80
- agentlings-0.2.0/tests/unit/test_memory_store.py +0 -152
- agentlings-0.2.0/tests/unit/test_memory_tool.py +0 -72
- agentlings-0.2.0/tests/unit/test_models.py +0 -33
- agentlings-0.2.0/tests/unit/test_scheduler.py +0 -73
- agentlings-0.2.0/tests/unit/test_sleep.py +0 -198
- agentlings-0.2.0/tests/unit/test_store.py +0 -508
- agentlings-0.2.0/tests/unit/test_task.py +0 -1241
- agentlings-0.2.0/tests/unit/test_telemetry.py +0 -46
- agentlings-0.2.0/tests/unit/test_tools.py +0 -299
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/.env.example +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/.github/workflows/ci.yml +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/CLAUDE.md +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/DESIGN-memory-sleep.md +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/Dockerfile +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/LICENSE +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/agent.example.yaml +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/docker-compose.test.yml +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/logo.png +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/scripts/release.sh +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/sleep.png +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/__init__.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/__main__.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/__init__.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/_migrations.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/_templates.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/_version.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/init.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/upgrade.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/config.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/__init__.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/completion.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/core/llm.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/loop.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/memory_models.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/memory_store.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/models.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/core/prompt.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/scheduler.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/sleep.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/store.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/task.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/telemetry.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/log.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/migrations/__init__.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/migrations/m0001_seed.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/protocol/__init__.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/protocol/a2a.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/protocol/agent_card.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-af4d7e32 → agentlings-0.2.2}/src/agentlings/protocol/mcp.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/server.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/templates/__init__.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/templates/default/.env.example +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/__init__.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/builtins.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/memory.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/registry.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/Dockerfile +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/__init__.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/agent.test.yaml +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/__init__.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/integration/a2a_client.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/conftest.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/mcp_client.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_a2a.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_agent_card.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_mcp.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/integration/test_ollama.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_task_flow.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/__init__.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/conftest.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_agent_card.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_cli_init.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_cli_upgrade.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_completion.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_config.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_live_api.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_llm.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_logging.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_loop.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-af4d7e32 → agentlings-0.2.2}/tests/unit/test_mcp_handler.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_memory_models.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_memory_store.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_memory_tool.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_models.py +0 -0
- {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_prompt.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_scheduler.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_sleep.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_store.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_task.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_telemetry.py +0 -0
- {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_tools.py +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
- run: python -m pip install --upgrade build twine
|
|
18
|
+
- run: python -m build
|
|
19
|
+
- run: python -m twine check dist/*
|
|
20
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
21
|
+
with:
|
|
22
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentlings
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Lightweight A2A + MCP single-process agent framework
|
|
5
5
|
Project-URL: Homepage, https://github.com/andyjmorgan/DonkeyWork-Agentlings
|
|
6
6
|
Project-URL: Repository, https://github.com/andyjmorgan/DonkeyWork-Agentlings
|
|
@@ -52,33 +52,77 @@ Description-Content-Type: text/markdown
|
|
|
52
52
|
|
|
53
53
|
Each agentling is a small, focused AI agent whose identity is defined by a YAML config file — name, description, system prompt, tools, and skills. The framework handles protocol compliance, conversation journaling, and context management. The LLM is the agent; the framework records and replays.
|
|
54
54
|
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install agentlings
|
|
59
|
+
# or, isolated in a managed venv:
|
|
60
|
+
uv tool install agentlings
|
|
61
|
+
```
|
|
62
|
+
|
|
55
63
|
## Quick start
|
|
56
64
|
|
|
57
65
|
```bash
|
|
58
|
-
|
|
66
|
+
# Scaffold a new agent in ./my-agent/
|
|
67
|
+
agentling init my-agent
|
|
68
|
+
cd my-agent
|
|
59
69
|
|
|
60
|
-
#
|
|
61
|
-
|
|
70
|
+
# Add your Anthropic key (or leave blank to point at Ollama via ANTHROPIC_BASE_URL)
|
|
71
|
+
$EDITOR .env
|
|
62
72
|
|
|
63
|
-
# Run
|
|
64
|
-
|
|
73
|
+
# Run from the agent dir
|
|
74
|
+
agentling run
|
|
75
|
+
```
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
AGENT_CONFIG=./agent.yaml ANTHROPIC_API_KEY=sk-ant-... AGENT_API_KEY=your-key agentling
|
|
77
|
+
`agentling init` produces a self-contained directory:
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
```
|
|
80
|
+
my-agent/
|
|
81
|
+
├── agent.yaml # identity, system prompt, tools, sleep config
|
|
82
|
+
├── .env # AGENT_API_KEY auto-generated; ANTHROPIC_API_KEY blank for you
|
|
83
|
+
├── .env.example # checked into source control as a template
|
|
84
|
+
├── .framework-version # the framework version that scaffolded this dir
|
|
85
|
+
└── data/ # journals, memory, conversations
|
|
86
|
+
└── .migrations # applied-migrations log
|
|
71
87
|
```
|
|
72
88
|
|
|
73
|
-
|
|
89
|
+
`agentling run` reads `agent.yaml`, `.env`, and `data/` from the current directory. To operate on a different dir without `cd`-ing in: `agentling run --dir /path/to/agent`.
|
|
90
|
+
|
|
91
|
+
Bumping the framework version preserves your data — `pip install --upgrade agentlings && agentling upgrade` runs any pending data migrations against `data/` without touching `agent.yaml` or `.env`.
|
|
92
|
+
|
|
93
|
+
The running agent serves:
|
|
74
94
|
- `GET /.well-known/agent-card.json` — A2A Agent Card (public, no auth)
|
|
75
95
|
- `POST /a2a` — A2A JSON-RPC endpoint
|
|
76
96
|
- `POST /mcp` — MCP Streamable HTTP endpoint
|
|
77
97
|
|
|
98
|
+
## CLI
|
|
99
|
+
|
|
100
|
+
| Command | Purpose |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `agentling init <name>` | Scaffold a new agent directory from a bundled template |
|
|
103
|
+
| `agentling run [--dir]` | Run the agent server from CWD or the given directory |
|
|
104
|
+
| `agentling upgrade [--dir]` | Apply pending data migrations after upgrading the framework |
|
|
105
|
+
| `agentling memory show` | Print the long-term memory store for the agent in CWD |
|
|
106
|
+
| `agentling sleep [--date]` | Run a one-off sleep cycle |
|
|
107
|
+
| `agentling list-tools` | List available tools and groups |
|
|
108
|
+
|
|
78
109
|
## Running as a daemon
|
|
79
110
|
|
|
111
|
+
The framework deliberately stays out of service-management — `agentling run` is just a long-running foreground process that reads `agent.yaml`, `.env`, and `data/` from its working directory. Wire it into whatever supervisor you already use.
|
|
112
|
+
|
|
80
113
|
### systemd (Linux)
|
|
81
114
|
|
|
115
|
+
Set up the agent dir once:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
sudo useradd -r -s /bin/false agentling
|
|
119
|
+
sudo mkdir -p /opt/agentling && sudo chown agentling: /opt/agentling
|
|
120
|
+
sudo -u agentling python3 -m venv /opt/agentling/venv
|
|
121
|
+
sudo -u agentling /opt/agentling/venv/bin/pip install agentlings
|
|
122
|
+
sudo -u agentling /opt/agentling/venv/bin/agentling init . --dir /opt/agentling --force
|
|
123
|
+
sudo $EDITOR /opt/agentling/.env # add ANTHROPIC_API_KEY
|
|
124
|
+
```
|
|
125
|
+
|
|
82
126
|
Create `/etc/systemd/system/agentling.service`:
|
|
83
127
|
|
|
84
128
|
```ini
|
|
@@ -90,8 +134,7 @@ After=network.target
|
|
|
90
134
|
Type=simple
|
|
91
135
|
User=agentling
|
|
92
136
|
WorkingDirectory=/opt/agentling
|
|
93
|
-
|
|
94
|
-
ExecStart=/opt/agentling/venv/bin/agentling
|
|
137
|
+
ExecStart=/opt/agentling/venv/bin/agentling run
|
|
95
138
|
Restart=on-failure
|
|
96
139
|
RestartSec=5
|
|
97
140
|
|
|
@@ -100,25 +143,16 @@ WantedBy=multi-user.target
|
|
|
100
143
|
```
|
|
101
144
|
|
|
102
145
|
```bash
|
|
103
|
-
# Set up
|
|
104
|
-
sudo useradd -r -s /bin/false agentling
|
|
105
|
-
sudo mkdir -p /opt/agentling
|
|
106
|
-
sudo python3 -m venv /opt/agentling/venv
|
|
107
|
-
sudo /opt/agentling/venv/bin/pip install agentlings
|
|
108
|
-
|
|
109
|
-
# Copy your config
|
|
110
|
-
sudo cp agent.yaml /opt/agentling/agent.yaml
|
|
111
|
-
sudo cp .env /opt/agentling/.env # ANTHROPIC_API_KEY, AGENT_API_KEY, AGENT_CONFIG=./agent.yaml
|
|
112
|
-
|
|
113
|
-
# Start
|
|
114
146
|
sudo systemctl daemon-reload
|
|
115
147
|
sudo systemctl enable --now agentling
|
|
116
148
|
sudo journalctl -u agentling -f
|
|
117
149
|
```
|
|
118
150
|
|
|
151
|
+
To upgrade: `sudo -u agentling /opt/agentling/venv/bin/pip install --upgrade agentlings && sudo -u agentling /opt/agentling/venv/bin/agentling upgrade --dir /opt/agentling && sudo systemctl restart agentling`.
|
|
152
|
+
|
|
119
153
|
### launchd (macOS)
|
|
120
154
|
|
|
121
|
-
|
|
155
|
+
Set up the agent dir once with `agentling init ~/.agentlings/my-agent`, then create `~/Library/LaunchAgents/com.donkeywork.agentling.plist`:
|
|
122
156
|
|
|
123
157
|
```xml
|
|
124
158
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -130,18 +164,10 @@ Create `~/Library/LaunchAgents/com.donkeywork.agentling.plist`:
|
|
|
130
164
|
<key>ProgramArguments</key>
|
|
131
165
|
<array>
|
|
132
166
|
<string>/path/to/venv/bin/agentling</string>
|
|
167
|
+
<string>run</string>
|
|
133
168
|
</array>
|
|
134
169
|
<key>WorkingDirectory</key>
|
|
135
|
-
<string>/
|
|
136
|
-
<key>EnvironmentVariables</key>
|
|
137
|
-
<dict>
|
|
138
|
-
<key>AGENT_CONFIG</key>
|
|
139
|
-
<string>./agent.yaml</string>
|
|
140
|
-
<key>ANTHROPIC_API_KEY</key>
|
|
141
|
-
<string>sk-ant-...</string>
|
|
142
|
-
<key>AGENT_API_KEY</key>
|
|
143
|
-
<string>your-key</string>
|
|
144
|
-
</dict>
|
|
170
|
+
<string>/Users/you/.agentlings/my-agent</string>
|
|
145
171
|
<key>KeepAlive</key>
|
|
146
172
|
<true/>
|
|
147
173
|
<key>StandardErrorPath</key>
|
|
@@ -200,18 +226,32 @@ Tools are off by default. Run `agentling --list-tools` for details.
|
|
|
200
226
|
|
|
201
227
|
## Docker
|
|
202
228
|
|
|
229
|
+
The simplest containerised setup uses the same `init` + `run` flow:
|
|
230
|
+
|
|
231
|
+
```dockerfile
|
|
232
|
+
FROM python:3.12-slim
|
|
233
|
+
WORKDIR /agent
|
|
234
|
+
RUN pip install agentlings
|
|
235
|
+
RUN agentling init . --api-key dev
|
|
236
|
+
VOLUME ["/agent/data"]
|
|
237
|
+
EXPOSE 8420
|
|
238
|
+
CMD ["agentling", "run"]
|
|
239
|
+
```
|
|
240
|
+
|
|
203
241
|
```bash
|
|
204
242
|
docker build -t agentling:latest .
|
|
205
|
-
docker run -e
|
|
243
|
+
docker run -e ANTHROPIC_API_KEY=sk-ant-... -p 8420:8420 -v ./data:/agent/data agentling:latest
|
|
206
244
|
```
|
|
207
245
|
|
|
246
|
+
For production, mount your own `agent.yaml` and `.env` over the scaffolded ones (or skip the `agentling init` build step entirely and bind-mount a host directory with everything pre-populated).
|
|
247
|
+
|
|
208
248
|
## Environment variables
|
|
209
249
|
|
|
210
|
-
Secrets and runtime settings stay in env vars
|
|
250
|
+
Secrets and runtime settings stay in env vars or, more commonly, the `.env` file inside the agent directory. `agentling init` creates an `.env` with `AGENT_API_KEY` already populated; everything else is opt-in.
|
|
211
251
|
|
|
212
252
|
| Variable | Default | Description |
|
|
213
253
|
|----------|---------|-------------|
|
|
214
|
-
| `AGENT_CONFIG` |
|
|
254
|
+
| `AGENT_CONFIG` | `./agent.yaml` (when present) | Path to agent YAML definition |
|
|
215
255
|
| `ANTHROPIC_API_KEY` | — | Anthropic API key (required for api.anthropic.com; optional with `ANTHROPIC_BASE_URL` pointed at e.g. Ollama) |
|
|
216
256
|
| `ANTHROPIC_BASE_URL` | — | Override the Messages endpoint. Use `http://localhost:11434` to target Ollama's Anthropic-compatible API |
|
|
217
257
|
| `AGENT_API_KEY` | — | API key for authenticating clients |
|
|
@@ -14,33 +14,77 @@
|
|
|
14
14
|
|
|
15
15
|
Each agentling is a small, focused AI agent whose identity is defined by a YAML config file — name, description, system prompt, tools, and skills. The framework handles protocol compliance, conversation journaling, and context management. The LLM is the agent; the framework records and replays.
|
|
16
16
|
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install agentlings
|
|
21
|
+
# or, isolated in a managed venv:
|
|
22
|
+
uv tool install agentlings
|
|
23
|
+
```
|
|
24
|
+
|
|
17
25
|
## Quick start
|
|
18
26
|
|
|
19
27
|
```bash
|
|
20
|
-
|
|
28
|
+
# Scaffold a new agent in ./my-agent/
|
|
29
|
+
agentling init my-agent
|
|
30
|
+
cd my-agent
|
|
21
31
|
|
|
22
|
-
#
|
|
23
|
-
|
|
32
|
+
# Add your Anthropic key (or leave blank to point at Ollama via ANTHROPIC_BASE_URL)
|
|
33
|
+
$EDITOR .env
|
|
24
34
|
|
|
25
|
-
# Run
|
|
26
|
-
|
|
35
|
+
# Run from the agent dir
|
|
36
|
+
agentling run
|
|
37
|
+
```
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
AGENT_CONFIG=./agent.yaml ANTHROPIC_API_KEY=sk-ant-... AGENT_API_KEY=your-key agentling
|
|
39
|
+
`agentling init` produces a self-contained directory:
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
```
|
|
42
|
+
my-agent/
|
|
43
|
+
├── agent.yaml # identity, system prompt, tools, sleep config
|
|
44
|
+
├── .env # AGENT_API_KEY auto-generated; ANTHROPIC_API_KEY blank for you
|
|
45
|
+
├── .env.example # checked into source control as a template
|
|
46
|
+
├── .framework-version # the framework version that scaffolded this dir
|
|
47
|
+
└── data/ # journals, memory, conversations
|
|
48
|
+
└── .migrations # applied-migrations log
|
|
33
49
|
```
|
|
34
50
|
|
|
35
|
-
|
|
51
|
+
`agentling run` reads `agent.yaml`, `.env`, and `data/` from the current directory. To operate on a different dir without `cd`-ing in: `agentling run --dir /path/to/agent`.
|
|
52
|
+
|
|
53
|
+
Bumping the framework version preserves your data — `pip install --upgrade agentlings && agentling upgrade` runs any pending data migrations against `data/` without touching `agent.yaml` or `.env`.
|
|
54
|
+
|
|
55
|
+
The running agent serves:
|
|
36
56
|
- `GET /.well-known/agent-card.json` — A2A Agent Card (public, no auth)
|
|
37
57
|
- `POST /a2a` — A2A JSON-RPC endpoint
|
|
38
58
|
- `POST /mcp` — MCP Streamable HTTP endpoint
|
|
39
59
|
|
|
60
|
+
## CLI
|
|
61
|
+
|
|
62
|
+
| Command | Purpose |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `agentling init <name>` | Scaffold a new agent directory from a bundled template |
|
|
65
|
+
| `agentling run [--dir]` | Run the agent server from CWD or the given directory |
|
|
66
|
+
| `agentling upgrade [--dir]` | Apply pending data migrations after upgrading the framework |
|
|
67
|
+
| `agentling memory show` | Print the long-term memory store for the agent in CWD |
|
|
68
|
+
| `agentling sleep [--date]` | Run a one-off sleep cycle |
|
|
69
|
+
| `agentling list-tools` | List available tools and groups |
|
|
70
|
+
|
|
40
71
|
## Running as a daemon
|
|
41
72
|
|
|
73
|
+
The framework deliberately stays out of service-management — `agentling run` is just a long-running foreground process that reads `agent.yaml`, `.env`, and `data/` from its working directory. Wire it into whatever supervisor you already use.
|
|
74
|
+
|
|
42
75
|
### systemd (Linux)
|
|
43
76
|
|
|
77
|
+
Set up the agent dir once:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
sudo useradd -r -s /bin/false agentling
|
|
81
|
+
sudo mkdir -p /opt/agentling && sudo chown agentling: /opt/agentling
|
|
82
|
+
sudo -u agentling python3 -m venv /opt/agentling/venv
|
|
83
|
+
sudo -u agentling /opt/agentling/venv/bin/pip install agentlings
|
|
84
|
+
sudo -u agentling /opt/agentling/venv/bin/agentling init . --dir /opt/agentling --force
|
|
85
|
+
sudo $EDITOR /opt/agentling/.env # add ANTHROPIC_API_KEY
|
|
86
|
+
```
|
|
87
|
+
|
|
44
88
|
Create `/etc/systemd/system/agentling.service`:
|
|
45
89
|
|
|
46
90
|
```ini
|
|
@@ -52,8 +96,7 @@ After=network.target
|
|
|
52
96
|
Type=simple
|
|
53
97
|
User=agentling
|
|
54
98
|
WorkingDirectory=/opt/agentling
|
|
55
|
-
|
|
56
|
-
ExecStart=/opt/agentling/venv/bin/agentling
|
|
99
|
+
ExecStart=/opt/agentling/venv/bin/agentling run
|
|
57
100
|
Restart=on-failure
|
|
58
101
|
RestartSec=5
|
|
59
102
|
|
|
@@ -62,25 +105,16 @@ WantedBy=multi-user.target
|
|
|
62
105
|
```
|
|
63
106
|
|
|
64
107
|
```bash
|
|
65
|
-
# Set up
|
|
66
|
-
sudo useradd -r -s /bin/false agentling
|
|
67
|
-
sudo mkdir -p /opt/agentling
|
|
68
|
-
sudo python3 -m venv /opt/agentling/venv
|
|
69
|
-
sudo /opt/agentling/venv/bin/pip install agentlings
|
|
70
|
-
|
|
71
|
-
# Copy your config
|
|
72
|
-
sudo cp agent.yaml /opt/agentling/agent.yaml
|
|
73
|
-
sudo cp .env /opt/agentling/.env # ANTHROPIC_API_KEY, AGENT_API_KEY, AGENT_CONFIG=./agent.yaml
|
|
74
|
-
|
|
75
|
-
# Start
|
|
76
108
|
sudo systemctl daemon-reload
|
|
77
109
|
sudo systemctl enable --now agentling
|
|
78
110
|
sudo journalctl -u agentling -f
|
|
79
111
|
```
|
|
80
112
|
|
|
113
|
+
To upgrade: `sudo -u agentling /opt/agentling/venv/bin/pip install --upgrade agentlings && sudo -u agentling /opt/agentling/venv/bin/agentling upgrade --dir /opt/agentling && sudo systemctl restart agentling`.
|
|
114
|
+
|
|
81
115
|
### launchd (macOS)
|
|
82
116
|
|
|
83
|
-
|
|
117
|
+
Set up the agent dir once with `agentling init ~/.agentlings/my-agent`, then create `~/Library/LaunchAgents/com.donkeywork.agentling.plist`:
|
|
84
118
|
|
|
85
119
|
```xml
|
|
86
120
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -92,18 +126,10 @@ Create `~/Library/LaunchAgents/com.donkeywork.agentling.plist`:
|
|
|
92
126
|
<key>ProgramArguments</key>
|
|
93
127
|
<array>
|
|
94
128
|
<string>/path/to/venv/bin/agentling</string>
|
|
129
|
+
<string>run</string>
|
|
95
130
|
</array>
|
|
96
131
|
<key>WorkingDirectory</key>
|
|
97
|
-
<string>/
|
|
98
|
-
<key>EnvironmentVariables</key>
|
|
99
|
-
<dict>
|
|
100
|
-
<key>AGENT_CONFIG</key>
|
|
101
|
-
<string>./agent.yaml</string>
|
|
102
|
-
<key>ANTHROPIC_API_KEY</key>
|
|
103
|
-
<string>sk-ant-...</string>
|
|
104
|
-
<key>AGENT_API_KEY</key>
|
|
105
|
-
<string>your-key</string>
|
|
106
|
-
</dict>
|
|
132
|
+
<string>/Users/you/.agentlings/my-agent</string>
|
|
107
133
|
<key>KeepAlive</key>
|
|
108
134
|
<true/>
|
|
109
135
|
<key>StandardErrorPath</key>
|
|
@@ -162,18 +188,32 @@ Tools are off by default. Run `agentling --list-tools` for details.
|
|
|
162
188
|
|
|
163
189
|
## Docker
|
|
164
190
|
|
|
191
|
+
The simplest containerised setup uses the same `init` + `run` flow:
|
|
192
|
+
|
|
193
|
+
```dockerfile
|
|
194
|
+
FROM python:3.12-slim
|
|
195
|
+
WORKDIR /agent
|
|
196
|
+
RUN pip install agentlings
|
|
197
|
+
RUN agentling init . --api-key dev
|
|
198
|
+
VOLUME ["/agent/data"]
|
|
199
|
+
EXPOSE 8420
|
|
200
|
+
CMD ["agentling", "run"]
|
|
201
|
+
```
|
|
202
|
+
|
|
165
203
|
```bash
|
|
166
204
|
docker build -t agentling:latest .
|
|
167
|
-
docker run -e
|
|
205
|
+
docker run -e ANTHROPIC_API_KEY=sk-ant-... -p 8420:8420 -v ./data:/agent/data agentling:latest
|
|
168
206
|
```
|
|
169
207
|
|
|
208
|
+
For production, mount your own `agent.yaml` and `.env` over the scaffolded ones (or skip the `agentling init` build step entirely and bind-mount a host directory with everything pre-populated).
|
|
209
|
+
|
|
170
210
|
## Environment variables
|
|
171
211
|
|
|
172
|
-
Secrets and runtime settings stay in env vars
|
|
212
|
+
Secrets and runtime settings stay in env vars or, more commonly, the `.env` file inside the agent directory. `agentling init` creates an `.env` with `AGENT_API_KEY` already populated; everything else is opt-in.
|
|
173
213
|
|
|
174
214
|
| Variable | Default | Description |
|
|
175
215
|
|----------|---------|-------------|
|
|
176
|
-
| `AGENT_CONFIG` |
|
|
216
|
+
| `AGENT_CONFIG` | `./agent.yaml` (when present) | Path to agent YAML definition |
|
|
177
217
|
| `ANTHROPIC_API_KEY` | — | Anthropic API key (required for api.anthropic.com; optional with `ANTHROPIC_BASE_URL` pointed at e.g. Ollama) |
|
|
178
218
|
| `ANTHROPIC_BASE_URL` | — | Override the Messages endpoint. Use `http://localhost:11434` to target Ollama's Anthropic-compatible API |
|
|
179
219
|
| `AGENT_API_KEY` | — | API key for authenticating clients |
|
|
@@ -18,6 +18,7 @@ from typing import Any
|
|
|
18
18
|
from a2a.server.context import ServerCallContext
|
|
19
19
|
from a2a.server.tasks.task_store import TaskStore
|
|
20
20
|
from a2a.types import (
|
|
21
|
+
Artifact,
|
|
21
22
|
ListTasksRequest,
|
|
22
23
|
ListTasksResponse,
|
|
23
24
|
Message,
|
|
@@ -50,11 +51,12 @@ _STATE_MAP: dict[TaskStatus, int] = {
|
|
|
50
51
|
def task_state_to_a2a_task(state: TaskState) -> Task:
|
|
51
52
|
"""Render an engine ``TaskState`` as an A2A ``Task`` for the wire.
|
|
52
53
|
|
|
53
|
-
Completed tasks carry their final assistant message in ``
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
Completed tasks carry their final assistant message in both ``artifacts``
|
|
55
|
+
(per the A2A spec, which says results SHOULD be returned via Artifacts)
|
|
56
|
+
and ``history`` (kept for backward compatibility with existing clients).
|
|
56
57
|
"""
|
|
57
58
|
history: list[Message] = []
|
|
59
|
+
artifacts: list[Artifact] = []
|
|
58
60
|
if state.status == TaskStatus.COMPLETED and state.content:
|
|
59
61
|
text = _extract_text(state.content)
|
|
60
62
|
if text:
|
|
@@ -67,6 +69,12 @@ def task_state_to_a2a_task(state: TaskState) -> Task:
|
|
|
67
69
|
message_id=f"{state.task_id}-final",
|
|
68
70
|
)
|
|
69
71
|
)
|
|
72
|
+
artifacts.append(
|
|
73
|
+
Artifact(
|
|
74
|
+
artifact_id=f"{state.task_id}-result",
|
|
75
|
+
parts=[Part(text=text)],
|
|
76
|
+
)
|
|
77
|
+
)
|
|
70
78
|
|
|
71
79
|
status_kwargs: dict[str, Any] = {"state": _STATE_MAP[state.status]}
|
|
72
80
|
if state.error and state.status in (TaskStatus.FAILED, TaskStatus.CANCELLED):
|
|
@@ -82,6 +90,7 @@ def task_state_to_a2a_task(state: TaskState) -> Task:
|
|
|
82
90
|
id=state.task_id,
|
|
83
91
|
context_id=state.context_id,
|
|
84
92
|
status=A2ATaskStatus(**status_kwargs),
|
|
93
|
+
artifacts=artifacts,
|
|
85
94
|
history=history,
|
|
86
95
|
)
|
|
87
96
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: {{NAME}}
|
|
2
|
+
description: A lightweight AI agent
|
|
3
|
+
|
|
4
|
+
system_prompt: |
|
|
5
|
+
You are {{NAME}}, a lightweight AI agent.
|
|
6
|
+
|
|
7
|
+
Use the tools available to you to accomplish tasks. When a tool returns
|
|
8
|
+
output, incorporate it into your response. Be concise. Use code blocks for
|
|
9
|
+
command output. Respond in plain text unless the user asks for a specific
|
|
10
|
+
format.
|
|
11
|
+
|
|
12
|
+
You operate under strict time constraints — every request has a limited
|
|
13
|
+
execution window. Follow these rules:
|
|
14
|
+
1. PLAN FIRST: Before touching any tool, state what you will do and roughly
|
|
15
|
+
how many steps it requires. If more than a few tool calls are needed,
|
|
16
|
+
say so upfront.
|
|
17
|
+
2. STAY FOCUSED: Do exactly what was asked. Do not explore, refactor, or
|
|
18
|
+
improve things that were not requested.
|
|
19
|
+
3. DELIVER INCREMENTALLY: After each meaningful step, summarize what you
|
|
20
|
+
completed and what remains. If the remaining work is non-trivial, ask
|
|
21
|
+
whether to continue rather than pressing on silently.
|
|
22
|
+
4. PREFER COMPLETE OVER AMBITIOUS: A small, finished result is better than
|
|
23
|
+
a large, half-done one. If the request is too broad to finish, do the
|
|
24
|
+
most valuable slice and report what is left.
|
|
25
|
+
5. CLARIFY EARLY: If the request is ambiguous, ask before acting — do not
|
|
26
|
+
guess and waste cycles.
|
|
27
|
+
|
|
28
|
+
Edit or remove these rules to taste — they are operator-owned, not
|
|
29
|
+
framework-imposed.
|
|
30
|
+
|
|
31
|
+
tools: []
|
|
32
|
+
|
|
33
|
+
skills: []
|
|
34
|
+
|
|
35
|
+
memory:
|
|
36
|
+
token_budget: 2000
|
|
37
|
+
inject_into_prompt: true
|
|
38
|
+
|
|
39
|
+
sleep:
|
|
40
|
+
enabled: true
|
|
41
|
+
schedule: "0 2 * * *"
|
|
@@ -49,6 +49,22 @@ class TestTaskStateTranslation:
|
|
|
49
49
|
# Part carries text directly (no nested TextPart wrapper in 1.0).
|
|
50
50
|
assert msg.parts[0].text == "the final answer"
|
|
51
51
|
|
|
52
|
+
def test_completed_artifacts_contain_final_response(self) -> None:
|
|
53
|
+
"""A2A spec: results SHOULD be returned via Artifacts on the Task."""
|
|
54
|
+
state = TaskState(
|
|
55
|
+
task_id="t1",
|
|
56
|
+
context_id="c1",
|
|
57
|
+
status=TaskStatus.COMPLETED,
|
|
58
|
+
content=[{"type": "text", "text": "the final answer"}],
|
|
59
|
+
)
|
|
60
|
+
a2a_task = task_state_to_a2a_task(state)
|
|
61
|
+
assert len(a2a_task.artifacts) == 1
|
|
62
|
+
artifact = a2a_task.artifacts[0]
|
|
63
|
+
assert artifact.artifact_id == "t1-result"
|
|
64
|
+
assert artifact.parts[0].text == "the final answer"
|
|
65
|
+
# History remains populated for backward compatibility.
|
|
66
|
+
assert len(a2a_task.history) == 1
|
|
67
|
+
|
|
52
68
|
def test_working_maps_to_working(self) -> None:
|
|
53
69
|
state = TaskState(
|
|
54
70
|
task_id="t1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
gitdir: /Users/andrewmorgan/Personal/source/DonkeyWork-Agentlings/.git/worktrees/agent-ac15d433
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Project
|
|
6
|
-
|
|
7
|
-
Agentlings — a lightweight single-process Python framework for running AI agents that expose both A2A (Agent-to-Agent Protocol v1.0) and MCP (Model Context Protocol) on a single HTTP port. Each agentling is a small, focused agent whose identity is defined by configuration (name, description, system prompt, tools), not code.
|
|
8
|
-
|
|
9
|
-
## Architecture
|
|
10
|
-
|
|
11
|
-
Two protocol interfaces (A2A JSON-RPC at `/a2a`, MCP Streamable HTTP at `/mcp`) feed into a shared **task engine**. Every request becomes a task with its own sub-journal; the HTTP handler awaits up to `AGENT_TASK_AWAIT_SECONDS` (default 60) and either returns the final result inline (fast path) or yields a task handle the caller polls (slow path). FIFO ordering is preserved per context — only one task can run per context at a time, so concurrent requests are rejected with `context_busy` for the LLM to retry.
|
|
12
|
-
|
|
13
|
-
Data layout:
|
|
14
|
-
|
|
15
|
-
- Parent journal: `{data_dir}/{contextId}/journal.jsonl` (conversation history)
|
|
16
|
-
- Sub-journal: `{data_dir}/{contextId}/tasks/{taskId}.jsonl` (task execution trace)
|
|
17
|
-
- Legacy `{data_dir}/{contextId}.jsonl` files are auto-migrated on first access.
|
|
18
|
-
|
|
19
|
-
Package structure under `src/agentlings/`:
|
|
20
|
-
- `config.py` — Pydantic BaseSettings, all config via env vars + `.env`
|
|
21
|
-
- `log.py` — console-first logging setup
|
|
22
|
-
- `server.py` — Starlette app wiring A2A + MCP routes, API key middleware, startup crash-recovery
|
|
23
|
-
- `core/` — task engine
|
|
24
|
-
- `task.py` — `TaskEngine`, `TaskRegistry`, `TaskWorker`, merge-back, crash recovery
|
|
25
|
-
- `loop.py` — synchronous facade over `TaskEngine` for legacy callers
|
|
26
|
-
- `llm.py` — LLM client abstraction (Anthropic + mock backends)
|
|
27
|
-
- `store.py` — JSONL append/replay with compaction cursor + `TaskJournal` (sub-journal)
|
|
28
|
-
- `models.py` — journal entry types (messages, compaction, task markers, merge wrappers)
|
|
29
|
-
- `prompt.py` — system prompt builder
|
|
30
|
-
- `completion.py` — shared LLM completion cycle with per-turn callback + cancellation
|
|
31
|
-
- `protocol/` — protocol adapters
|
|
32
|
-
- `a2a.py` — `AgentlingExecutor` bridging A2A SDK to the task engine
|
|
33
|
-
- `mcp.py` — MCP server exposing a single task-aware tool
|
|
34
|
-
- `agent_card.py` — Agent Card generation from config
|
|
35
|
-
- `tools/` — pluggable tool system
|
|
36
|
-
- `registry.py` — `ToolRegistry` with group-based registration
|
|
37
|
-
- `builtins.py` — bash and filesystem tool implementations
|
|
38
|
-
|
|
39
|
-
The Agent Card at `/.well-known/agent.json` is the single source of truth — the MCP tool schema is derived from it.
|
|
40
|
-
|
|
41
|
-
### Task engine lifecycle
|
|
42
|
-
|
|
43
|
-
1. **Ingress**: `engine.spawn(message, contextId?)` atomically admits one task per context, writes a `TaskDispatched` audit marker to the parent journal, creates a sub-journal with `TaskStarted`, and spawns a worker.
|
|
44
|
-
2. **Execution**: the worker snapshots the parent journal (replay from latest compaction cursor), runs the LLM loop via `compact_20260112`, writes each turn to the sub-journal.
|
|
45
|
-
3. **Merge-back (success)**: under the per-context lock, the engine atomically writes `MergeStarted` → user message → latest sub-journal compaction (if any) → assistant final response → `MergeCommitted` to the parent journal.
|
|
46
|
-
4. **Cancel/fail**: only a `TaskCancelled` or `TaskFailed` audit marker lands on the parent. No conversational content leaks.
|
|
47
|
-
5. **Replay**: audit markers (`task_dispatch`, `task_cancel`, `task_fail`, `merge_start`, `merge_commit`) are stripped by the store's `replay()` — they never reach the LLM.
|
|
48
|
-
6. **Crash recovery**: on startup, orphaned sub-journals get `TaskFailed { reason: "process_crash_recovery" }` and partial merge-backs are completed idempotently.
|
|
49
|
-
|
|
50
|
-
## Commands
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# Install in dev mode
|
|
54
|
-
pip install -e ".[dev]"
|
|
55
|
-
|
|
56
|
-
# Run the agent
|
|
57
|
-
agentling
|
|
58
|
-
|
|
59
|
-
# Run with overrides
|
|
60
|
-
AGENT_NAME="my-agent" AGENT_PORT=9000 agentling
|
|
61
|
-
|
|
62
|
-
# Build container
|
|
63
|
-
docker build -t agentling:latest .
|
|
64
|
-
|
|
65
|
-
# Run container
|
|
66
|
-
docker run -e ANTHROPIC_API_KEY=... -e AGENT_API_KEY=... -v ./data:/data -p 8420:8420 agentling:latest
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Configuration
|
|
70
|
-
|
|
71
|
-
All via environment variables (loaded from `.env` via python-dotenv):
|
|
72
|
-
- `ANTHROPIC_API_KEY` (required)
|
|
73
|
-
- `AGENT_API_KEY` (required) — checked via `X-API-Key` header
|
|
74
|
-
- `AGENT_MODEL` (default `claude-sonnet-4-6`)
|
|
75
|
-
- `AGENT_MAX_TOKENS` (default `4096`)
|
|
76
|
-
- `AGENT_HOST` / `AGENT_PORT` (default `0.0.0.0:8420`)
|
|
77
|
-
- `AGENT_DATA_DIR` (default `./data`) — JSONL journal storage
|
|
78
|
-
- `AGENT_NAME` / `AGENT_DESCRIPTION` — identity for Agent Card + MCP tool
|
|
79
|
-
- `AGENT_SYSTEM_PROMPT_FILE` — optional path to override default system prompt
|
|
80
|
-
- `AGENT_LOG_LEVEL` (default `INFO`)
|
|
81
|
-
- `AGENT_TASK_AWAIT_SECONDS` (default `60`) — HTTP handler await timeout before yielding a task handle to the caller
|
|
82
|
-
|
|
83
|
-
## Logging
|
|
84
|
-
|
|
85
|
-
Console-only, format: `datetime - level - path - message`. All modules use `logging.getLogger(__name__)`. No third-party logging libraries.
|
|
86
|
-
|
|
87
|
-
## Design Constraints
|
|
88
|
-
|
|
89
|
-
- **Task-enabled, message-shape.** Every request becomes a task with its own sub-journal. Protocol surfaces expose task handles for long-running work, but A2A/MCP interactions are still carried as messages — no artifacts, no push notifications, no streaming.
|
|
90
|
-
- **One task per context.** FIFO is architectural, not configurable. Concurrent requests to a busy context are rejected with `context_busy`; the LLM retries.
|
|
91
|
-
- **Parent journal records only successful completions.** Cancel/fail leave only audit markers, never conversational content. Replay strips audit markers unconditionally.
|
|
92
|
-
- **contextId is the conversation handle; taskId is the execution handle.** ContextId maps to a directory; taskId is UUID4 and path-bound via `{contextId}/tasks/{taskId}.jsonl` — the filesystem enforces `(contextId, taskId)` pairing.
|
|
93
|
-
- **Confirmation is conversation** — no `input-required` state, just natural language turns.
|
|
94
|
-
- **The LLM is the agent** — the framework records and replays, it does not orchestrate.
|
|
95
|
-
- **Tools are pluggable** — register at startup, errors returned to LLM as tool results (not exceptions).
|
|
96
|
-
- **JSONL is append-only**, never modified or deleted; compaction markers are replay cursors, task compactions are ported to parent on merge-back.
|
|
97
|
-
- **Merge-back is atomic** via `MergeStarted`/`MergeCommitted` wrappers so startup recovery can repair partial writes idempotently.
|
|
98
|
-
- **MCP Session ID and contextId are independent concepts**, never cross-referenced.
|
|
99
|
-
|
|
100
|
-
## Development Methodology
|
|
101
|
-
|
|
102
|
-
**Write → Test → Continue.** Every piece of code gets tested before moving on.
|
|
103
|
-
|
|
104
|
-
- Bug workflow: write a failing test that reproduces the bug → verify it fails → fix the code → verify the test passes. No exceptions.
|
|
105
|
-
- Each task ends with tests that prove the task works.
|
|
106
|
-
- Each milestone ends with rigorous integration testing.
|
|
107
|
-
- Tests run in Docker via `docker compose` — the test harness spins up the agentling container and runs an MCP client and A2A client against it.
|
|
108
|
-
- Unit tests (pytest) for internal modules; integration tests for protocol-level behaviour.
|
|
109
|
-
- All LLM responses are mocked — tests never call the real Anthropic API or require a real key. The agentling container in integration tests runs with a mock LLM backend.
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
# Run unit tests
|
|
113
|
-
pytest tests/unit/
|
|
114
|
-
|
|
115
|
-
# Run integration tests (builds + runs container)
|
|
116
|
-
docker compose -f docker-compose.test.yml up --build --abort-on-container-exit
|
|
117
|
-
|
|
118
|
-
# Run all tests
|
|
119
|
-
pytest tests/unit/ && docker compose -f docker-compose.test.yml up --build --abort-on-container-exit
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Dependencies
|
|
123
|
-
|
|
124
|
-
- `anthropic` — LLM backend with `compact_20260112`
|
|
125
|
-
- `starlette` + `uvicorn` — HTTP server
|
|
126
|
-
- `pydantic` — config and models
|
|
127
|
-
- `mcp` — MCP SDK (Streamable HTTP)
|
|
128
|
-
- `python-dotenv` — env file loading
|