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.
Files changed (321) hide show
  1. agentlings-0.2.2/.github/workflows/publish.yml +22 -0
  2. {agentlings-0.2.0/.claude/worktrees/agent-af4d7e32 → agentlings-0.2.2}/.gitignore +2 -0
  3. {agentlings-0.2.0 → agentlings-0.2.2}/PKG-INFO +78 -38
  4. {agentlings-0.2.0 → agentlings-0.2.2}/README.md +77 -37
  5. {agentlings-0.2.0 → agentlings-0.2.2}/pyproject.toml +1 -1
  6. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/protocol/a2a_task_store.py +12 -3
  7. agentlings-0.2.2/src/agentlings/templates/default/agent.yaml +41 -0
  8. {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_a2a_task_store.py +16 -0
  9. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/.git +0 -1
  10. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/.gitignore +0 -12
  11. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/CLAUDE.md +0 -128
  12. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/README.md +0 -367
  13. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/agent.example.yaml +0 -41
  14. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/pyproject.toml +0 -51
  15. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/__main__.py +0 -112
  16. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/config.py +0 -235
  17. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/core/llm.py +0 -482
  18. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/core/prompt.py +0 -146
  19. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/protocol/a2a_task_store.py +0 -150
  20. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/protocol/mcp.py +0 -245
  21. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/src/agentlings/server.py +0 -244
  22. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/integration/a2a_client.py +0 -192
  23. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_a2a_task_store.py +0 -211
  24. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_config.py +0 -305
  25. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_llm.py +0 -220
  26. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_mcp_handler.py +0 -94
  27. agentlings-0.2.0/.claude/worktrees/agent-ac15d433/tests/unit/test_prompt.py +0 -221
  28. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/.env.example +0 -14
  29. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/.git +0 -1
  30. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/.github/workflows/ci.yml +0 -34
  31. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/CLAUDE.md +0 -128
  32. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/Dockerfile +0 -11
  33. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/README.md +0 -367
  34. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/agent.example.yaml +0 -41
  35. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/docker-compose.test.yml +0 -27
  36. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/logo.png +0 -0
  37. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/pyproject.toml +0 -51
  38. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/sleep.png +0 -0
  39. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/__init__.py +0 -3
  40. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/__main__.py +0 -112
  41. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/config.py +0 -235
  42. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/__init__.py +0 -1
  43. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/completion.py +0 -219
  44. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/llm.py +0 -482
  45. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/loop.py +0 -134
  46. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/memory_models.py +0 -97
  47. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/memory_store.py +0 -109
  48. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/models.py +0 -231
  49. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/prompt.py +0 -146
  50. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/scheduler.py +0 -141
  51. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/sleep.py +0 -393
  52. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/store.py +0 -318
  53. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/task.py +0 -1087
  54. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/core/telemetry.py +0 -181
  55. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/log.py +0 -23
  56. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/__init__.py +0 -1
  57. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/a2a.py +0 -199
  58. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/a2a_task_store.py +0 -139
  59. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/protocol/agent_card.py +0 -69
  60. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/server.py +0 -233
  61. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/__init__.py +0 -1
  62. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/builtins.py +0 -307
  63. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/memory.py +0 -104
  64. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/src/agentlings/tools/registry.py +0 -154
  65. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/Dockerfile +0 -7
  66. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/__init__.py +0 -0
  67. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/agent.test.yaml +0 -16
  68. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/__init__.py +0 -0
  69. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/a2a_client.py +0 -158
  70. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/conftest.py +0 -146
  71. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/mcp_client.py +0 -106
  72. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_a2a.py +0 -63
  73. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_agent_card.py +0 -42
  74. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_mcp.py +0 -141
  75. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/integration/test_task_flow.py +0 -337
  76. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/__init__.py +0 -0
  77. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/conftest.py +0 -58
  78. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_a2a_task_store.py +0 -210
  79. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_agent_card.py +0 -77
  80. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_completion.py +0 -384
  81. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_config.py +0 -305
  82. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_live_api.py +0 -134
  83. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_llm.py +0 -220
  84. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_logging.py +0 -51
  85. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_loop.py +0 -103
  86. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_memory_models.py +0 -80
  87. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_memory_store.py +0 -152
  88. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_memory_tool.py +0 -72
  89. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_models.py +0 -33
  90. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_prompt.py +0 -221
  91. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_scheduler.py +0 -73
  92. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_sleep.py +0 -198
  93. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_store.py +0 -508
  94. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_task.py +0 -1241
  95. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_telemetry.py +0 -46
  96. agentlings-0.2.0/.claude/worktrees/agent-af4d7e32/tests/unit/test_tools.py +0 -299
  97. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.env.example +0 -14
  98. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.git +0 -1
  99. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.github/workflows/ci.yml +0 -34
  100. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/.gitignore +0 -12
  101. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/CLAUDE.md +0 -128
  102. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/Dockerfile +0 -11
  103. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/README.md +0 -367
  104. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/agent.example.yaml +0 -41
  105. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/docker-compose.test.yml +0 -27
  106. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/logo.png +0 -0
  107. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/pyproject.toml +0 -51
  108. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/sleep.png +0 -0
  109. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/__init__.py +0 -3
  110. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/__main__.py +0 -112
  111. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/config.py +0 -235
  112. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/__init__.py +0 -1
  113. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/completion.py +0 -219
  114. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/llm.py +0 -482
  115. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/loop.py +0 -134
  116. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/memory_models.py +0 -97
  117. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/memory_store.py +0 -109
  118. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/models.py +0 -231
  119. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/prompt.py +0 -146
  120. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/scheduler.py +0 -141
  121. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/sleep.py +0 -393
  122. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/store.py +0 -318
  123. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/task.py +0 -1087
  124. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/core/telemetry.py +0 -181
  125. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/log.py +0 -23
  126. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/__init__.py +0 -1
  127. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/a2a.py +0 -199
  128. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/a2a_task_store.py +0 -139
  129. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/agent_card.py +0 -69
  130. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/protocol/mcp.py +0 -245
  131. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/server.py +0 -233
  132. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/__init__.py +0 -1
  133. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/builtins.py +0 -307
  134. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/memory.py +0 -104
  135. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/src/agentlings/tools/registry.py +0 -154
  136. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/Dockerfile +0 -7
  137. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/__init__.py +0 -0
  138. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/agent.test.yaml +0 -16
  139. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/__init__.py +0 -0
  140. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/a2a_client.py +0 -158
  141. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/conftest.py +0 -146
  142. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/mcp_client.py +0 -106
  143. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_a2a.py +0 -63
  144. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_agent_card.py +0 -42
  145. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_mcp.py +0 -141
  146. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/integration/test_task_flow.py +0 -337
  147. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/__init__.py +0 -0
  148. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/conftest.py +0 -58
  149. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_a2a_task_store.py +0 -210
  150. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_agent_card.py +0 -77
  151. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_completion.py +0 -384
  152. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_config.py +0 -305
  153. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_live_api.py +0 -134
  154. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_llm.py +0 -220
  155. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_logging.py +0 -51
  156. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_loop.py +0 -103
  157. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_mcp_handler.py +0 -94
  158. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_memory_models.py +0 -80
  159. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_memory_store.py +0 -152
  160. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_memory_tool.py +0 -72
  161. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_models.py +0 -33
  162. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_prompt.py +0 -221
  163. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_scheduler.py +0 -73
  164. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_sleep.py +0 -198
  165. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_store.py +0 -508
  166. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_task.py +0 -1241
  167. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_telemetry.py +0 -46
  168. agentlings-0.2.0/.claude/worktrees/floofy-chasing-trinket/tests/unit/test_tools.py +0 -299
  169. agentlings-0.2.0/.env.example +0 -14
  170. agentlings-0.2.0/.env.test +0 -4
  171. agentlings-0.2.0/.github/workflows/ci.yml +0 -34
  172. agentlings-0.2.0/.github/workflows/publish.yml +0 -37
  173. agentlings-0.2.0/.gitignore +0 -12
  174. agentlings-0.2.0/.idea/.gitignore +0 -15
  175. agentlings-0.2.0/.idea/DonkeyWork-Agentlings.iml +0 -9
  176. agentlings-0.2.0/.idea/copilot.data.migration.ask2agent.xml +0 -6
  177. agentlings-0.2.0/.idea/encodings.xml +0 -4
  178. agentlings-0.2.0/.idea/go.imports.xml +0 -11
  179. agentlings-0.2.0/.idea/indexLayout.xml +0 -8
  180. agentlings-0.2.0/.idea/modules.xml +0 -8
  181. agentlings-0.2.0/.idea/projectSettingsUpdater.xml +0 -8
  182. agentlings-0.2.0/.idea/vcs.xml +0 -6
  183. agentlings-0.2.0/.idea/workspace.xml +0 -85
  184. agentlings-0.2.0/Dockerfile +0 -11
  185. agentlings-0.2.0/docker-compose.test.yml +0 -27
  186. agentlings-0.2.0/logo.png +0 -0
  187. agentlings-0.2.0/navi_fixed.ico +0 -0
  188. agentlings-0.2.0/navi_full.ico +0 -0
  189. agentlings-0.2.0/sleep.png +0 -0
  190. agentlings-0.2.0/src/agentlings/__init__.py +0 -3
  191. agentlings-0.2.0/src/agentlings/core/__init__.py +0 -1
  192. agentlings-0.2.0/src/agentlings/core/completion.py +0 -219
  193. agentlings-0.2.0/src/agentlings/core/loop.py +0 -134
  194. agentlings-0.2.0/src/agentlings/core/memory_models.py +0 -97
  195. agentlings-0.2.0/src/agentlings/core/memory_store.py +0 -109
  196. agentlings-0.2.0/src/agentlings/core/models.py +0 -231
  197. agentlings-0.2.0/src/agentlings/core/scheduler.py +0 -141
  198. agentlings-0.2.0/src/agentlings/core/sleep.py +0 -393
  199. agentlings-0.2.0/src/agentlings/core/store.py +0 -318
  200. agentlings-0.2.0/src/agentlings/core/task.py +0 -1087
  201. agentlings-0.2.0/src/agentlings/core/telemetry.py +0 -181
  202. agentlings-0.2.0/src/agentlings/log.py +0 -23
  203. agentlings-0.2.0/src/agentlings/protocol/__init__.py +0 -1
  204. agentlings-0.2.0/src/agentlings/protocol/a2a.py +0 -220
  205. agentlings-0.2.0/src/agentlings/protocol/agent_card.py +0 -83
  206. agentlings-0.2.0/src/agentlings/protocol/mcp.py +0 -232
  207. agentlings-0.2.0/src/agentlings/templates/default/agent.yaml +0 -14
  208. agentlings-0.2.0/src/agentlings/tools/__init__.py +0 -1
  209. agentlings-0.2.0/src/agentlings/tools/builtins.py +0 -307
  210. agentlings-0.2.0/src/agentlings/tools/memory.py +0 -104
  211. agentlings-0.2.0/src/agentlings/tools/registry.py +0 -154
  212. agentlings-0.2.0/tests/Dockerfile +0 -7
  213. agentlings-0.2.0/tests/__init__.py +0 -0
  214. agentlings-0.2.0/tests/agent.test.yaml +0 -16
  215. agentlings-0.2.0/tests/integration/__init__.py +0 -0
  216. agentlings-0.2.0/tests/integration/conftest.py +0 -146
  217. agentlings-0.2.0/tests/integration/mcp_client.py +0 -106
  218. agentlings-0.2.0/tests/integration/test_a2a.py +0 -111
  219. agentlings-0.2.0/tests/integration/test_agent_card.py +0 -45
  220. agentlings-0.2.0/tests/integration/test_mcp.py +0 -141
  221. agentlings-0.2.0/tests/integration/test_task_flow.py +0 -337
  222. agentlings-0.2.0/tests/unit/__init__.py +0 -0
  223. agentlings-0.2.0/tests/unit/conftest.py +0 -58
  224. agentlings-0.2.0/tests/unit/test_agent_card.py +0 -85
  225. agentlings-0.2.0/tests/unit/test_completion.py +0 -384
  226. agentlings-0.2.0/tests/unit/test_live_api.py +0 -134
  227. agentlings-0.2.0/tests/unit/test_logging.py +0 -51
  228. agentlings-0.2.0/tests/unit/test_loop.py +0 -103
  229. agentlings-0.2.0/tests/unit/test_mcp_handler.py +0 -56
  230. agentlings-0.2.0/tests/unit/test_memory_models.py +0 -80
  231. agentlings-0.2.0/tests/unit/test_memory_store.py +0 -152
  232. agentlings-0.2.0/tests/unit/test_memory_tool.py +0 -72
  233. agentlings-0.2.0/tests/unit/test_models.py +0 -33
  234. agentlings-0.2.0/tests/unit/test_scheduler.py +0 -73
  235. agentlings-0.2.0/tests/unit/test_sleep.py +0 -198
  236. agentlings-0.2.0/tests/unit/test_store.py +0 -508
  237. agentlings-0.2.0/tests/unit/test_task.py +0 -1241
  238. agentlings-0.2.0/tests/unit/test_telemetry.py +0 -46
  239. agentlings-0.2.0/tests/unit/test_tools.py +0 -299
  240. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/.env.example +0 -0
  241. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/.github/workflows/ci.yml +0 -0
  242. {agentlings-0.2.0 → agentlings-0.2.2}/CLAUDE.md +0 -0
  243. {agentlings-0.2.0 → agentlings-0.2.2}/DESIGN-memory-sleep.md +0 -0
  244. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/Dockerfile +0 -0
  245. {agentlings-0.2.0 → agentlings-0.2.2}/LICENSE +0 -0
  246. {agentlings-0.2.0 → agentlings-0.2.2}/agent.example.yaml +0 -0
  247. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/docker-compose.test.yml +0 -0
  248. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/logo.png +0 -0
  249. {agentlings-0.2.0 → agentlings-0.2.2}/scripts/release.sh +0 -0
  250. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/sleep.png +0 -0
  251. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/__init__.py +0 -0
  252. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/__main__.py +0 -0
  253. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/__init__.py +0 -0
  254. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/_migrations.py +0 -0
  255. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/_templates.py +0 -0
  256. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/_version.py +0 -0
  257. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/init.py +0 -0
  258. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/cli/upgrade.py +0 -0
  259. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/config.py +0 -0
  260. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/__init__.py +0 -0
  261. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/completion.py +0 -0
  262. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/core/llm.py +0 -0
  263. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/loop.py +0 -0
  264. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/memory_models.py +0 -0
  265. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/memory_store.py +0 -0
  266. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/models.py +0 -0
  267. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/core/prompt.py +0 -0
  268. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/scheduler.py +0 -0
  269. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/sleep.py +0 -0
  270. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/store.py +0 -0
  271. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/task.py +0 -0
  272. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/core/telemetry.py +0 -0
  273. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/log.py +0 -0
  274. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/migrations/__init__.py +0 -0
  275. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/migrations/m0001_seed.py +0 -0
  276. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/protocol/__init__.py +0 -0
  277. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/protocol/a2a.py +0 -0
  278. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/protocol/agent_card.py +0 -0
  279. {agentlings-0.2.0/.claude/worktrees/agent-af4d7e32 → agentlings-0.2.2}/src/agentlings/protocol/mcp.py +0 -0
  280. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/server.py +0 -0
  281. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/templates/__init__.py +0 -0
  282. {agentlings-0.2.0 → agentlings-0.2.2}/src/agentlings/templates/default/.env.example +0 -0
  283. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/__init__.py +0 -0
  284. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/builtins.py +0 -0
  285. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/memory.py +0 -0
  286. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/src/agentlings/tools/registry.py +0 -0
  287. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/Dockerfile +0 -0
  288. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/__init__.py +0 -0
  289. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/agent.test.yaml +0 -0
  290. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/__init__.py +0 -0
  291. {agentlings-0.2.0 → agentlings-0.2.2}/tests/integration/a2a_client.py +0 -0
  292. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/conftest.py +0 -0
  293. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/mcp_client.py +0 -0
  294. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_a2a.py +0 -0
  295. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_agent_card.py +0 -0
  296. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_mcp.py +0 -0
  297. {agentlings-0.2.0 → agentlings-0.2.2}/tests/integration/test_ollama.py +0 -0
  298. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/integration/test_task_flow.py +0 -0
  299. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/__init__.py +0 -0
  300. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/conftest.py +0 -0
  301. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_agent_card.py +0 -0
  302. {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_cli_init.py +0 -0
  303. {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_cli_upgrade.py +0 -0
  304. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_completion.py +0 -0
  305. {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_config.py +0 -0
  306. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_live_api.py +0 -0
  307. {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_llm.py +0 -0
  308. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_logging.py +0 -0
  309. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_loop.py +0 -0
  310. {agentlings-0.2.0/.claude/worktrees/agent-af4d7e32 → agentlings-0.2.2}/tests/unit/test_mcp_handler.py +0 -0
  311. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_memory_models.py +0 -0
  312. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_memory_store.py +0 -0
  313. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_memory_tool.py +0 -0
  314. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_models.py +0 -0
  315. {agentlings-0.2.0 → agentlings-0.2.2}/tests/unit/test_prompt.py +0 -0
  316. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_scheduler.py +0 -0
  317. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_sleep.py +0 -0
  318. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_store.py +0 -0
  319. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_task.py +0 -0
  320. {agentlings-0.2.0/.claude/worktrees/agent-ac15d433 → agentlings-0.2.2}/tests/unit/test_telemetry.py +0 -0
  321. {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 }}
@@ -10,3 +10,5 @@ build/
10
10
  .pytest_cache/
11
11
  .venv/
12
12
  venv/
13
+ .idea/
14
+ .DS_Store
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentlings
3
- Version: 0.2.0
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
- pip install -e ".[dev]"
66
+ # Scaffold a new agent in ./my-agent/
67
+ agentling init my-agent
68
+ cd my-agent
59
69
 
60
- # Create your agent definition
61
- cp agent.example.yaml agent.yaml
70
+ # Add your Anthropic key (or leave blank to point at Ollama via ANTHROPIC_BASE_URL)
71
+ $EDITOR .env
62
72
 
63
- # Run with mock LLM (no API key needed)
64
- AGENT_CONFIG=./agent.yaml AGENT_LLM_BACKEND=mock AGENT_API_KEY=dev agentling
73
+ # Run from the agent dir
74
+ agentling run
75
+ ```
65
76
 
66
- # Run with Anthropic
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
- # See available tools
70
- agentling --list-tools
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
- The agent serves:
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
- EnvironmentFile=/opt/agentling/.env
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
- Create `~/Library/LaunchAgents/com.donkeywork.agentling.plist`:
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>/path/to/agentling</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 AGENT_API_KEY=your-key -e AGENT_LLM_BACKEND=mock -p 8420:8420 agentling
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 (or `.env` file):
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` | | Path to agent YAML definition |
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
- pip install -e ".[dev]"
28
+ # Scaffold a new agent in ./my-agent/
29
+ agentling init my-agent
30
+ cd my-agent
21
31
 
22
- # Create your agent definition
23
- cp agent.example.yaml agent.yaml
32
+ # Add your Anthropic key (or leave blank to point at Ollama via ANTHROPIC_BASE_URL)
33
+ $EDITOR .env
24
34
 
25
- # Run with mock LLM (no API key needed)
26
- AGENT_CONFIG=./agent.yaml AGENT_LLM_BACKEND=mock AGENT_API_KEY=dev agentling
35
+ # Run from the agent dir
36
+ agentling run
37
+ ```
27
38
 
28
- # Run with Anthropic
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
- # See available tools
32
- agentling --list-tools
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
- The agent serves:
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
- EnvironmentFile=/opt/agentling/.env
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
- Create `~/Library/LaunchAgents/com.donkeywork.agentling.plist`:
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>/path/to/agentling</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 AGENT_API_KEY=your-key -e AGENT_LLM_BACKEND=mock -p 8420:8420 agentling
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 (or `.env` file):
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` | | Path to agent YAML definition |
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 |
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentlings"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  description = "Lightweight A2A + MCP single-process agent framework"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -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 ``history`` so
54
- ``GetTask`` responses are self-contained the client doesn't need a
55
- separate call to retrieve the result.
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,12 +0,0 @@
1
- data/
2
- .env
3
- __pycache__/
4
- *.py[cod]
5
- *.egg-info/
6
- dist/
7
- build/
8
- .eggs/
9
- *.egg
10
- .pytest_cache/
11
- .venv/
12
- venv/
@@ -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