@elizaos/python 2.0.0-alpha.10

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 (197) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +239 -0
  3. package/elizaos/__init__.py +280 -0
  4. package/elizaos/action_docs.py +149 -0
  5. package/elizaos/advanced_capabilities/__init__.py +85 -0
  6. package/elizaos/advanced_capabilities/actions/__init__.py +54 -0
  7. package/elizaos/advanced_capabilities/actions/add_contact.py +139 -0
  8. package/elizaos/advanced_capabilities/actions/follow_room.py +151 -0
  9. package/elizaos/advanced_capabilities/actions/image_generation.py +148 -0
  10. package/elizaos/advanced_capabilities/actions/mute_room.py +164 -0
  11. package/elizaos/advanced_capabilities/actions/remove_contact.py +145 -0
  12. package/elizaos/advanced_capabilities/actions/roles.py +207 -0
  13. package/elizaos/advanced_capabilities/actions/schedule_follow_up.py +154 -0
  14. package/elizaos/advanced_capabilities/actions/search_contacts.py +145 -0
  15. package/elizaos/advanced_capabilities/actions/send_message.py +187 -0
  16. package/elizaos/advanced_capabilities/actions/settings.py +151 -0
  17. package/elizaos/advanced_capabilities/actions/unfollow_room.py +164 -0
  18. package/elizaos/advanced_capabilities/actions/unmute_room.py +164 -0
  19. package/elizaos/advanced_capabilities/actions/update_contact.py +164 -0
  20. package/elizaos/advanced_capabilities/actions/update_entity.py +161 -0
  21. package/elizaos/advanced_capabilities/evaluators/__init__.py +18 -0
  22. package/elizaos/advanced_capabilities/evaluators/reflection.py +134 -0
  23. package/elizaos/advanced_capabilities/evaluators/relationship_extraction.py +203 -0
  24. package/elizaos/advanced_capabilities/providers/__init__.py +36 -0
  25. package/elizaos/advanced_capabilities/providers/agent_settings.py +60 -0
  26. package/elizaos/advanced_capabilities/providers/contacts.py +77 -0
  27. package/elizaos/advanced_capabilities/providers/facts.py +82 -0
  28. package/elizaos/advanced_capabilities/providers/follow_ups.py +113 -0
  29. package/elizaos/advanced_capabilities/providers/knowledge.py +83 -0
  30. package/elizaos/advanced_capabilities/providers/relationships.py +112 -0
  31. package/elizaos/advanced_capabilities/providers/roles.py +97 -0
  32. package/elizaos/advanced_capabilities/providers/settings.py +51 -0
  33. package/elizaos/advanced_capabilities/services/__init__.py +18 -0
  34. package/elizaos/advanced_capabilities/services/follow_up.py +138 -0
  35. package/elizaos/advanced_capabilities/services/rolodex.py +244 -0
  36. package/elizaos/advanced_memory/__init__.py +3 -0
  37. package/elizaos/advanced_memory/evaluators.py +97 -0
  38. package/elizaos/advanced_memory/memory_service.py +556 -0
  39. package/elizaos/advanced_memory/plugin.py +30 -0
  40. package/elizaos/advanced_memory/prompts.py +12 -0
  41. package/elizaos/advanced_memory/providers.py +90 -0
  42. package/elizaos/advanced_memory/types.py +65 -0
  43. package/elizaos/advanced_planning/__init__.py +10 -0
  44. package/elizaos/advanced_planning/actions.py +145 -0
  45. package/elizaos/advanced_planning/message_classifier.py +127 -0
  46. package/elizaos/advanced_planning/planning_service.py +712 -0
  47. package/elizaos/advanced_planning/plugin.py +40 -0
  48. package/elizaos/advanced_planning/prompts.py +4 -0
  49. package/elizaos/basic_capabilities/__init__.py +66 -0
  50. package/elizaos/basic_capabilities/actions/__init__.py +24 -0
  51. package/elizaos/basic_capabilities/actions/choice.py +140 -0
  52. package/elizaos/basic_capabilities/actions/ignore.py +66 -0
  53. package/elizaos/basic_capabilities/actions/none.py +56 -0
  54. package/elizaos/basic_capabilities/actions/reply.py +120 -0
  55. package/elizaos/basic_capabilities/providers/__init__.py +54 -0
  56. package/elizaos/basic_capabilities/providers/action_state.py +113 -0
  57. package/elizaos/basic_capabilities/providers/actions.py +263 -0
  58. package/elizaos/basic_capabilities/providers/attachments.py +76 -0
  59. package/elizaos/basic_capabilities/providers/capabilities.py +62 -0
  60. package/elizaos/basic_capabilities/providers/character.py +113 -0
  61. package/elizaos/basic_capabilities/providers/choice.py +73 -0
  62. package/elizaos/basic_capabilities/providers/context_bench.py +44 -0
  63. package/elizaos/basic_capabilities/providers/current_time.py +58 -0
  64. package/elizaos/basic_capabilities/providers/entities.py +99 -0
  65. package/elizaos/basic_capabilities/providers/evaluators.py +54 -0
  66. package/elizaos/basic_capabilities/providers/providers_list.py +55 -0
  67. package/elizaos/basic_capabilities/providers/recent_messages.py +85 -0
  68. package/elizaos/basic_capabilities/providers/time.py +45 -0
  69. package/elizaos/basic_capabilities/providers/world.py +93 -0
  70. package/elizaos/basic_capabilities/services/__init__.py +18 -0
  71. package/elizaos/basic_capabilities/services/embedding.py +122 -0
  72. package/elizaos/basic_capabilities/services/task.py +178 -0
  73. package/elizaos/bootstrap/__init__.py +12 -0
  74. package/elizaos/bootstrap/actions/__init__.py +68 -0
  75. package/elizaos/bootstrap/actions/add_contact.py +149 -0
  76. package/elizaos/bootstrap/actions/choice.py +147 -0
  77. package/elizaos/bootstrap/actions/follow_room.py +151 -0
  78. package/elizaos/bootstrap/actions/ignore.py +80 -0
  79. package/elizaos/bootstrap/actions/image_generation.py +135 -0
  80. package/elizaos/bootstrap/actions/mute_room.py +151 -0
  81. package/elizaos/bootstrap/actions/none.py +71 -0
  82. package/elizaos/bootstrap/actions/remove_contact.py +159 -0
  83. package/elizaos/bootstrap/actions/reply.py +140 -0
  84. package/elizaos/bootstrap/actions/roles.py +193 -0
  85. package/elizaos/bootstrap/actions/schedule_follow_up.py +164 -0
  86. package/elizaos/bootstrap/actions/search_contacts.py +159 -0
  87. package/elizaos/bootstrap/actions/send_message.py +173 -0
  88. package/elizaos/bootstrap/actions/settings.py +165 -0
  89. package/elizaos/bootstrap/actions/unfollow_room.py +151 -0
  90. package/elizaos/bootstrap/actions/unmute_room.py +151 -0
  91. package/elizaos/bootstrap/actions/update_contact.py +178 -0
  92. package/elizaos/bootstrap/actions/update_entity.py +175 -0
  93. package/elizaos/bootstrap/autonomy/__init__.py +18 -0
  94. package/elizaos/bootstrap/autonomy/action.py +197 -0
  95. package/elizaos/bootstrap/autonomy/providers.py +165 -0
  96. package/elizaos/bootstrap/autonomy/routes.py +171 -0
  97. package/elizaos/bootstrap/autonomy/service.py +562 -0
  98. package/elizaos/bootstrap/autonomy/types.py +18 -0
  99. package/elizaos/bootstrap/evaluators/__init__.py +19 -0
  100. package/elizaos/bootstrap/evaluators/reflection.py +118 -0
  101. package/elizaos/bootstrap/evaluators/relationship_extraction.py +192 -0
  102. package/elizaos/bootstrap/plugin.py +140 -0
  103. package/elizaos/bootstrap/providers/__init__.py +80 -0
  104. package/elizaos/bootstrap/providers/action_state.py +71 -0
  105. package/elizaos/bootstrap/providers/actions.py +256 -0
  106. package/elizaos/bootstrap/providers/agent_settings.py +63 -0
  107. package/elizaos/bootstrap/providers/attachments.py +76 -0
  108. package/elizaos/bootstrap/providers/capabilities.py +66 -0
  109. package/elizaos/bootstrap/providers/character.py +128 -0
  110. package/elizaos/bootstrap/providers/choice.py +77 -0
  111. package/elizaos/bootstrap/providers/contacts.py +78 -0
  112. package/elizaos/bootstrap/providers/context_bench.py +49 -0
  113. package/elizaos/bootstrap/providers/current_time.py +56 -0
  114. package/elizaos/bootstrap/providers/entities.py +99 -0
  115. package/elizaos/bootstrap/providers/evaluators.py +58 -0
  116. package/elizaos/bootstrap/providers/facts.py +86 -0
  117. package/elizaos/bootstrap/providers/follow_ups.py +116 -0
  118. package/elizaos/bootstrap/providers/knowledge.py +73 -0
  119. package/elizaos/bootstrap/providers/providers_list.py +59 -0
  120. package/elizaos/bootstrap/providers/recent_messages.py +85 -0
  121. package/elizaos/bootstrap/providers/relationships.py +106 -0
  122. package/elizaos/bootstrap/providers/roles.py +95 -0
  123. package/elizaos/bootstrap/providers/settings.py +55 -0
  124. package/elizaos/bootstrap/providers/time.py +45 -0
  125. package/elizaos/bootstrap/providers/world.py +97 -0
  126. package/elizaos/bootstrap/services/__init__.py +26 -0
  127. package/elizaos/bootstrap/services/embedding.py +122 -0
  128. package/elizaos/bootstrap/services/follow_up.py +138 -0
  129. package/elizaos/bootstrap/services/rolodex.py +244 -0
  130. package/elizaos/bootstrap/services/task.py +585 -0
  131. package/elizaos/bootstrap/types.py +54 -0
  132. package/elizaos/bootstrap/utils/__init__.py +7 -0
  133. package/elizaos/bootstrap/utils/xml.py +69 -0
  134. package/elizaos/character.py +149 -0
  135. package/elizaos/logger.py +179 -0
  136. package/elizaos/media/__init__.py +45 -0
  137. package/elizaos/media/mime.py +315 -0
  138. package/elizaos/media/search.py +161 -0
  139. package/elizaos/media/tests/__init__.py +1 -0
  140. package/elizaos/media/tests/test_mime.py +117 -0
  141. package/elizaos/media/tests/test_search.py +156 -0
  142. package/elizaos/plugin.py +191 -0
  143. package/elizaos/prompts.py +1071 -0
  144. package/elizaos/py.typed +0 -0
  145. package/elizaos/runtime.py +2572 -0
  146. package/elizaos/services/__init__.py +49 -0
  147. package/elizaos/services/hook_service.py +511 -0
  148. package/elizaos/services/message_service.py +1248 -0
  149. package/elizaos/settings.py +182 -0
  150. package/elizaos/streaming_context.py +159 -0
  151. package/elizaos/trajectory_context.py +18 -0
  152. package/elizaos/types/__init__.py +512 -0
  153. package/elizaos/types/agent.py +31 -0
  154. package/elizaos/types/components.py +208 -0
  155. package/elizaos/types/database.py +64 -0
  156. package/elizaos/types/environment.py +46 -0
  157. package/elizaos/types/events.py +47 -0
  158. package/elizaos/types/memory.py +45 -0
  159. package/elizaos/types/model.py +393 -0
  160. package/elizaos/types/plugin.py +188 -0
  161. package/elizaos/types/primitives.py +100 -0
  162. package/elizaos/types/runtime.py +460 -0
  163. package/elizaos/types/service.py +113 -0
  164. package/elizaos/types/service_interfaces.py +244 -0
  165. package/elizaos/types/state.py +188 -0
  166. package/elizaos/types/task.py +29 -0
  167. package/elizaos/utils/__init__.py +108 -0
  168. package/elizaos/utils/spec_examples.py +48 -0
  169. package/elizaos/utils/streaming.py +426 -0
  170. package/elizaos_atropos_shared/__init__.py +1 -0
  171. package/elizaos_atropos_shared/canonical_eliza.py +282 -0
  172. package/package.json +19 -0
  173. package/pyproject.toml +143 -0
  174. package/requirements-dev.in +11 -0
  175. package/requirements-dev.lock +134 -0
  176. package/requirements.in +9 -0
  177. package/requirements.lock +64 -0
  178. package/tests/__init__.py +0 -0
  179. package/tests/test_action_parameters.py +154 -0
  180. package/tests/test_actions_provider_examples.py +39 -0
  181. package/tests/test_advanced_memory_behavior.py +96 -0
  182. package/tests/test_advanced_memory_flag.py +30 -0
  183. package/tests/test_advanced_planning_behavior.py +225 -0
  184. package/tests/test_advanced_planning_flag.py +26 -0
  185. package/tests/test_autonomy.py +445 -0
  186. package/tests/test_bootstrap_initialize.py +37 -0
  187. package/tests/test_character.py +163 -0
  188. package/tests/test_character_provider.py +231 -0
  189. package/tests/test_dynamic_prompt_exec.py +561 -0
  190. package/tests/test_logger_redaction.py +43 -0
  191. package/tests/test_plugin.py +117 -0
  192. package/tests/test_runtime.py +422 -0
  193. package/tests/test_salt_production_enforcement.py +22 -0
  194. package/tests/test_settings_crypto.py +118 -0
  195. package/tests/test_streaming.py +295 -0
  196. package/tests/test_types.py +221 -0
  197. package/tests/test_uuid_parity.py +46 -0
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@elizaos/python",
3
+ "version": "2.0.0-alpha.10",
4
+ "description": "elizaOS Core - Python runtime and types",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "scripts": {
9
+ "build": "python3 -c \"from pathlib import Path; import json; Path('elizaos.egg-info').mkdir(exist_ok=True); Path('elizaos.egg-info/PKG-INFO').write_text('Metadata-Version: 2.1\\nName: elizaos\\nVersion: 1.0.0\\n'); print('✅ Build completed - egg-info created')\"",
10
+ "test": "pytest",
11
+ "lint": "ruff check --fix --unsafe-fixes . && ruff format .",
12
+ "lint:fix": "ruff check --fix . && ruff format .",
13
+ "format": "ruff format .",
14
+ "format:check": "ruff format --check .",
15
+ "typecheck": "python3.13 -m mypy elizaos || echo 'mypy not installed, skipping typecheck'"
16
+ },
17
+ "author": "elizaOS",
18
+ "license": "MIT"
19
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,143 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "elizaos"
7
+ version = "2.0.0a4"
8
+ description = "elizaOS Core - The Python runtime and types for elizaOS AI agents"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.11"
12
+ authors = [
13
+ { name = "elizaOS Contributors" }
14
+ ]
15
+ keywords = ["ai", "agents", "llm", "runtime", "elizaos"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "pydantic>=2.12.5",
27
+ "pydantic-settings>=2.12.0",
28
+ "protobuf>=5.29.0",
29
+ "uuid6>=2024.1.12",
30
+ "aiohttp>=3.13.3",
31
+ "cryptography>=42.0.0",
32
+ "structlog>=25.5.0",
33
+ "typing-extensions>=4.9.0",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest>=9.0.2",
39
+ "pytest-asyncio>=0.23.0",
40
+ "pytest-cov>=4.1.0",
41
+ "pytest-xprocess>=1.0.2",
42
+ "mypy>=1.19.1",
43
+ "ruff>=0.14.11",
44
+ "black>=24.1.0",
45
+ "isort>=5.13.0",
46
+ "pip-tools>=7.4.1",
47
+ ]
48
+
49
+ [project.urls]
50
+ Homepage = "https://github.com/elizaos/eliza"
51
+ Documentation = "https://elizaos.ai/docs"
52
+ Repository = "https://github.com/elizaos/eliza"
53
+
54
+ [tool.hatch.build.targets.wheel]
55
+ packages = ["elizaos"]
56
+
57
+ [tool.hatch.build.targets.sdist]
58
+ include = [
59
+ "/elizaos",
60
+ "/tests",
61
+ "/README.md",
62
+ ]
63
+
64
+ [tool.pytest.ini_options]
65
+ testpaths = ["tests"]
66
+ python_files = "test_*.py"
67
+ python_functions = "test_*"
68
+ addopts = "-v -p no:anchorpy"
69
+ asyncio_mode = "auto"
70
+ asyncio_default_fixture_loop_scope = "function"
71
+
72
+ [tool.mypy]
73
+ python_version = "3.11"
74
+ # Relaxed strict settings - to be tightened over time
75
+ strict = false
76
+ warn_return_any = false
77
+ warn_unused_ignores = false
78
+ disallow_untyped_defs = false
79
+ disallow_incomplete_defs = false
80
+ check_untyped_defs = true
81
+ no_implicit_optional = true
82
+ warn_redundant_casts = true
83
+ # Ignore generated protobuf files which have known type issues
84
+ exclude = ["elizaos/types/generated/"]
85
+
86
+ [[tool.mypy.overrides]]
87
+ module = "elizaos.types.generated.*"
88
+ ignore_errors = true
89
+
90
+ [[tool.mypy.overrides]]
91
+ module = "google.protobuf.*"
92
+ ignore_missing_imports = true
93
+
94
+ [[tool.mypy.overrides]]
95
+ module = "elizaos.bootstrap.*"
96
+ # Bootstrap module has many structural mismatches that need refactoring
97
+ ignore_errors = true
98
+
99
+ [[tool.mypy.overrides]]
100
+ module = "elizaos.services.*"
101
+ # Services module uses different patterns that need alignment
102
+ ignore_errors = true
103
+
104
+ [tool.ruff]
105
+ target-version = "py311"
106
+ line-length = 100
107
+ exclude = ["elizaos/types/generated/"]
108
+
109
+ [tool.ruff.lint]
110
+ select = [
111
+ "E", # pycodestyle errors
112
+ "W", # pycodestyle warnings
113
+ "F", # Pyflakes
114
+ "I", # isort
115
+ "B", # flake8-bugbear
116
+ "C4", # flake8-comprehensions
117
+ "UP", # pyupgrade
118
+ "ARG", # flake8-unused-arguments
119
+ "SIM", # flake8-simplify
120
+ ]
121
+ ignore = [
122
+ "E402", # module level import not at top of file (common in __init__.py with __all__)
123
+ "E501", # line too long (handled by black)
124
+ "E741", # ambiguous variable name (common in list comprehensions)
125
+ "B008", # do not perform function calls in argument defaults
126
+ "B024", # abstract base class without abstract methods (service interfaces)
127
+ "ARG001", # unused function argument (common in test fixtures and callbacks)
128
+ "ARG002", # unused method argument (common in handler patterns)
129
+ "SIM102", # nested if statements (sometimes clearer for readability)
130
+ "SIM116", # dictionary instead of if/elif (not always cleaner)
131
+ "F811", # redefinition of unused name (common in type stubs)
132
+ "F404", # from __future__ imports must occur at beginning (generated code)
133
+ "F821", # undefined name (some names are injected at runtime)
134
+ ]
135
+
136
+ [tool.ruff.lint.isort]
137
+ known-first-party = ["elizaos"]
138
+
139
+ [tool.black]
140
+ line-length = 100
141
+ target-version = ["py311"]
142
+ exclude = "elizaos/types/generated/"
143
+
@@ -0,0 +1,11 @@
1
+ -r requirements.in
2
+ pytest>=9.0.2
3
+ pytest-asyncio>=0.23.0
4
+ pytest-cov>=4.1.0
5
+ pytest-xprocess>=1.0.2
6
+ mypy>=1.19.1
7
+ ruff>=0.14.11
8
+ black>=24.1.0
9
+ isort>=5.13.0
10
+ pip-tools>=7.4.1
11
+
@@ -0,0 +1,134 @@
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.13
3
+ # by the following command:
4
+ #
5
+ # pip-compile --output-file=requirements-dev.lock requirements-dev.in
6
+ #
7
+ aiohappyeyeballs==2.6.1
8
+ # via aiohttp
9
+ aiohttp==3.13.3
10
+ # via -r requirements.in
11
+ aiosignal==1.4.0
12
+ # via aiohttp
13
+ annotated-types==0.7.0
14
+ # via pydantic
15
+ attrs==25.4.0
16
+ # via aiohttp
17
+ black==25.12.0
18
+ # via -r requirements-dev.in
19
+ build==1.4.0
20
+ # via pip-tools
21
+ cffi==2.0.0
22
+ # via cryptography
23
+ click==8.3.1
24
+ # via
25
+ # black
26
+ # pip-tools
27
+ coverage[toml]==7.13.1
28
+ # via pytest-cov
29
+ cryptography==46.0.3
30
+ # via -r requirements.in
31
+ frozenlist==1.8.0
32
+ # via
33
+ # aiohttp
34
+ # aiosignal
35
+ idna==3.11
36
+ # via yarl
37
+ iniconfig==2.3.0
38
+ # via pytest
39
+ isort==7.0.0
40
+ # via -r requirements-dev.in
41
+ librt==0.7.7
42
+ # via mypy
43
+ multidict==6.7.0
44
+ # via
45
+ # aiohttp
46
+ # yarl
47
+ mypy==1.19.1
48
+ # via -r requirements-dev.in
49
+ mypy-extensions==1.1.0
50
+ # via
51
+ # black
52
+ # mypy
53
+ packaging==25.0
54
+ # via
55
+ # black
56
+ # build
57
+ # pytest
58
+ pathspec==1.0.3
59
+ # via
60
+ # black
61
+ # mypy
62
+ pip-tools==7.5.2
63
+ # via -r requirements-dev.in
64
+ platformdirs==4.5.1
65
+ # via black
66
+ pluggy==1.6.0
67
+ # via
68
+ # pytest
69
+ # pytest-cov
70
+ propcache==0.4.1
71
+ # via
72
+ # aiohttp
73
+ # yarl
74
+ protobuf==6.33.4
75
+ # via -r requirements.in
76
+ psutil==7.2.1
77
+ # via pytest-xprocess
78
+ pycparser==2.23
79
+ # via cffi
80
+ pydantic==2.12.5
81
+ # via
82
+ # -r requirements.in
83
+ # pydantic-settings
84
+ pydantic-core==2.41.5
85
+ # via pydantic
86
+ pydantic-settings==2.12.0
87
+ # via -r requirements.in
88
+ pygments==2.19.2
89
+ # via pytest
90
+ pyproject-hooks==1.2.0
91
+ # via
92
+ # build
93
+ # pip-tools
94
+ pytest==9.0.2
95
+ # via
96
+ # -r requirements-dev.in
97
+ # pytest-asyncio
98
+ # pytest-cov
99
+ # pytest-xprocess
100
+ pytest-asyncio==1.3.0
101
+ # via -r requirements-dev.in
102
+ pytest-cov==7.0.0
103
+ # via -r requirements-dev.in
104
+ pytest-xprocess==1.0.2
105
+ # via -r requirements-dev.in
106
+ python-dotenv==1.2.1
107
+ # via pydantic-settings
108
+ pytokens==0.3.0
109
+ # via black
110
+ ruff==0.14.11
111
+ # via -r requirements-dev.in
112
+ structlog==25.5.0
113
+ # via -r requirements.in
114
+ typing-extensions==4.15.0
115
+ # via
116
+ # -r requirements.in
117
+ # mypy
118
+ # pydantic
119
+ # pydantic-core
120
+ # typing-inspection
121
+ typing-inspection==0.4.2
122
+ # via
123
+ # pydantic
124
+ # pydantic-settings
125
+ uuid6==2025.0.1
126
+ # via -r requirements.in
127
+ wheel==0.45.1
128
+ # via pip-tools
129
+ yarl==1.22.0
130
+ # via aiohttp
131
+
132
+ # The following packages are considered to be unsafe in a requirements file:
133
+ # pip
134
+ # setuptools
@@ -0,0 +1,9 @@
1
+ pydantic>=2.12.5
2
+ pydantic-settings>=2.12.0
3
+ protobuf>=5.29.0
4
+ uuid6>=2024.1.12
5
+ aiohttp>=3.13.3
6
+ cryptography>=42.0.0
7
+ structlog>=25.5.0
8
+ typing-extensions>=4.9.0
9
+
@@ -0,0 +1,64 @@
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.13
3
+ # by the following command:
4
+ #
5
+ # pip-compile --output-file=requirements.lock requirements.in
6
+ #
7
+ aiohappyeyeballs==2.6.1
8
+ # via aiohttp
9
+ aiohttp==3.13.3
10
+ # via -r requirements.in
11
+ aiosignal==1.4.0
12
+ # via aiohttp
13
+ annotated-types==0.7.0
14
+ # via pydantic
15
+ attrs==25.4.0
16
+ # via aiohttp
17
+ cffi==2.0.0
18
+ # via cryptography
19
+ cryptography==46.0.3
20
+ # via -r requirements.in
21
+ frozenlist==1.8.0
22
+ # via
23
+ # aiohttp
24
+ # aiosignal
25
+ idna==3.11
26
+ # via yarl
27
+ multidict==6.7.0
28
+ # via
29
+ # aiohttp
30
+ # yarl
31
+ propcache==0.4.1
32
+ # via
33
+ # aiohttp
34
+ # yarl
35
+ protobuf==6.33.4
36
+ # via -r requirements.in
37
+ pycparser==2.23
38
+ # via cffi
39
+ pydantic==2.12.5
40
+ # via
41
+ # -r requirements.in
42
+ # pydantic-settings
43
+ pydantic-core==2.41.5
44
+ # via pydantic
45
+ pydantic-settings==2.12.0
46
+ # via -r requirements.in
47
+ python-dotenv==1.2.1
48
+ # via pydantic-settings
49
+ structlog==25.5.0
50
+ # via -r requirements.in
51
+ typing-extensions==4.15.0
52
+ # via
53
+ # -r requirements.in
54
+ # pydantic
55
+ # pydantic-core
56
+ # typing-inspection
57
+ typing-inspection==0.4.2
58
+ # via
59
+ # pydantic
60
+ # pydantic-settings
61
+ uuid6==2025.0.1
62
+ # via -r requirements.in
63
+ yarl==1.22.0
64
+ # via aiohttp
File without changes
@@ -0,0 +1,154 @@
1
+ from typing import Any
2
+
3
+ import pytest
4
+ from google.protobuf.struct_pb2 import Value
5
+
6
+ from elizaos.runtime import AgentRuntime
7
+ from elizaos.types import (
8
+ Action,
9
+ ActionParameter,
10
+ ActionParameterSchema,
11
+ ActionResult,
12
+ Character,
13
+ Content,
14
+ HandlerOptions,
15
+ IAgentRuntime,
16
+ Memory,
17
+ State,
18
+ as_uuid,
19
+ )
20
+
21
+
22
+ @pytest.mark.skip(reason="Content proto doesn't have params field")
23
+ @pytest.mark.asyncio
24
+ async def test_process_actions_passes_validated_params_to_handler_options() -> None:
25
+ character = Character(name="ParamAgent", bio=["Test agent"], system="Test")
26
+ runtime = AgentRuntime(character=character, action_planning=False)
27
+
28
+ received: list[str] = []
29
+
30
+ async def validate(_rt: IAgentRuntime, _msg: Memory, _state: State | None) -> bool:
31
+ return True
32
+
33
+ async def handler(
34
+ _rt: IAgentRuntime,
35
+ _msg: Memory,
36
+ _state: State | None,
37
+ options: HandlerOptions | None,
38
+ _callback: Any,
39
+ _responses: list[Memory] | None,
40
+ ) -> ActionResult | None:
41
+ params = getattr(options, "parameters", None) if options else None
42
+ direction = params.get("direction") if isinstance(params, dict) else None
43
+ received.append(str(direction))
44
+ return ActionResult(success=True)
45
+
46
+ action = Action(
47
+ name="MOVE",
48
+ description="Move the agent.",
49
+ validate=validate,
50
+ handler=handler,
51
+ parameters=[
52
+ ActionParameter(
53
+ name="direction",
54
+ description="Direction to move.",
55
+ required=False,
56
+ schema=ActionParameterSchema(
57
+ type="string",
58
+ enum_values=["north", "south"],
59
+ default_value=Value(string_value="north"),
60
+ ),
61
+ )
62
+ ],
63
+ )
64
+ runtime.register_action(action)
65
+
66
+ message = Memory(
67
+ id=as_uuid("12345678-1234-1234-1234-123456789012"),
68
+ entity_id=as_uuid("12345678-1234-1234-1234-123456789013"),
69
+ room_id=as_uuid("12345678-1234-1234-1234-123456789014"),
70
+ content=Content(text="tick"),
71
+ )
72
+
73
+ response = Memory(
74
+ id=as_uuid("12345678-1234-1234-1234-123456789015"),
75
+ entity_id=as_uuid("12345678-1234-1234-1234-123456789016"),
76
+ room_id=message.room_id,
77
+ content=Content(
78
+ text="move",
79
+ actions=["MOVE"],
80
+ # Note: params field doesn't exist in proto, this test is skipped
81
+ ),
82
+ )
83
+
84
+ await runtime.process_actions(message, [response], state=None, callback=None)
85
+
86
+ assert received == ["south"]
87
+
88
+
89
+ @pytest.mark.skip(reason="Content proto doesn't have params field")
90
+ @pytest.mark.asyncio
91
+ async def test_process_actions_skips_action_when_required_param_missing() -> None:
92
+ character = Character(name="ParamAgent", bio=["Test agent"], system="Test")
93
+ runtime = AgentRuntime(character=character, action_planning=False)
94
+
95
+ executed = False
96
+ received_errors: list[str] = []
97
+
98
+ async def validate(_rt: IAgentRuntime, _msg: Memory, _state: State | None) -> bool:
99
+ return True
100
+
101
+ async def handler(
102
+ _rt: IAgentRuntime,
103
+ _msg: Memory,
104
+ _state: State | None,
105
+ options: HandlerOptions | None,
106
+ _callback: Any,
107
+ _responses: list[Memory] | None,
108
+ ) -> ActionResult | None:
109
+ nonlocal executed
110
+ executed = True
111
+ errs = getattr(options, "parameter_errors", None) if options else None
112
+ received_errors.extend(errs if isinstance(errs, list) else [])
113
+ return ActionResult(success=True)
114
+
115
+ action = Action(
116
+ name="MOVE",
117
+ description="Move the agent.",
118
+ validate=validate,
119
+ handler=handler,
120
+ parameters=[
121
+ ActionParameter(
122
+ name="direction",
123
+ description="Direction to move.",
124
+ required=True,
125
+ schema=ActionParameterSchema(
126
+ type="string",
127
+ enum_values=["north", "south"],
128
+ ),
129
+ )
130
+ ],
131
+ )
132
+ runtime.register_action(action)
133
+
134
+ message = Memory(
135
+ id=as_uuid("22345678-1234-1234-1234-123456789012"),
136
+ entity_id=as_uuid("22345678-1234-1234-1234-123456789013"),
137
+ room_id=as_uuid("22345678-1234-1234-1234-123456789014"),
138
+ content=Content(text="tick"),
139
+ )
140
+
141
+ response = Memory(
142
+ id=as_uuid("22345678-1234-1234-1234-123456789015"),
143
+ entity_id=as_uuid("22345678-1234-1234-1234-123456789016"),
144
+ room_id=message.room_id,
145
+ content=Content(
146
+ text="move",
147
+ actions=["MOVE"],
148
+ ),
149
+ )
150
+
151
+ await runtime.process_actions(message, [response], state=None, callback=None)
152
+
153
+ assert executed is True
154
+ assert any("Required parameter 'direction'" in e for e in received_errors)
@@ -0,0 +1,39 @@
1
+ import pytest
2
+
3
+ from elizaos.action_docs import with_canonical_action_docs
4
+ from elizaos.bootstrap.actions import send_message_action
5
+ from elizaos.runtime import AgentRuntime
6
+ from elizaos.types import Character, Content, Memory, as_uuid
7
+
8
+
9
+ @pytest.mark.asyncio
10
+ async def test_actions_provider_includes_examples_and_parameter_examples() -> None:
11
+ runtime = AgentRuntime(
12
+ character=Character(name="DocsTest", bio=["docs test"], system="test"),
13
+ log_level="ERROR",
14
+ )
15
+ await runtime.initialize()
16
+
17
+ # Bootstrap initializes with basic actions only; register an extended action to
18
+ # verify parameter example formatting end-to-end.
19
+ runtime.register_action(with_canonical_action_docs(send_message_action))
20
+
21
+ # Find the ACTIONS provider
22
+ actions_provider = next(p for p in runtime.providers if p.name == "ACTIONS")
23
+
24
+ message = Memory(
25
+ id=as_uuid("32345678-1234-1234-1234-123456789012"),
26
+ entity_id=as_uuid("32345678-1234-1234-1234-123456789013"),
27
+ room_id=as_uuid("32345678-1234-1234-1234-123456789014"),
28
+ content=Content(text="hello"),
29
+ )
30
+
31
+ state = await runtime.compose_state(message)
32
+ result = await actions_provider.get(runtime, message, state)
33
+
34
+ text = result.text or ""
35
+ assert "# Available Actions" in text
36
+ assert "# Action Examples" in text
37
+ # Canonical docs include examples for SEND_MESSAGE parameters
38
+ assert "SEND_MESSAGE" in text
39
+ assert "# Action Call Examples" in text
@@ -0,0 +1,96 @@
1
+ from __future__ import annotations
2
+
3
+ import pytest
4
+
5
+ from elizaos.advanced_memory.memory_service import MemoryService
6
+ from elizaos.advanced_memory.types import LongTermMemoryCategory
7
+ from elizaos.runtime import AgentRuntime
8
+ from elizaos.types.agent import Character
9
+ from elizaos.types.components import ProviderResult
10
+ from elizaos.types.memory import Memory
11
+ from elizaos.types.primitives import Content, as_uuid
12
+
13
+
14
+ @pytest.mark.skip(reason="MemoryService requires runtime settings.get() which isn't implemented")
15
+ @pytest.mark.asyncio
16
+ async def test_memory_provider_formats_long_term_memories() -> None:
17
+ runtime = AgentRuntime(
18
+ character=Character(name="AdvMemoryBehavior", bio=["Test"], advanced_memory=True),
19
+ plugins=[],
20
+ )
21
+ await runtime.initialize()
22
+
23
+ svc = runtime.get_service("memory")
24
+ assert svc is not None
25
+
26
+ entity_id = as_uuid("12345678-1234-1234-1234-123456789201")
27
+ room_id = as_uuid("12345678-1234-1234-1234-123456789202")
28
+ agent_id = runtime.agent_id
29
+
30
+ await svc.store_long_term_memory(
31
+ agent_id=agent_id,
32
+ entity_id=entity_id,
33
+ category=LongTermMemoryCategory.SEMANTIC,
34
+ content="User likes concise answers",
35
+ confidence=0.9,
36
+ source="test",
37
+ metadata={"x": 1},
38
+ )
39
+
40
+ msg = Memory(
41
+ id=as_uuid("12345678-1234-1234-1234-123456789203"),
42
+ entity_id=entity_id,
43
+ room_id=room_id,
44
+ content=Content(text="hi"),
45
+ )
46
+
47
+ provider = next(p for p in runtime.providers if p.name == "LONG_TERM_MEMORY")
48
+ result: ProviderResult = await provider.get(runtime, msg, await runtime.compose_state(msg))
49
+ assert result.text and "What I Know About You" in result.text
50
+
51
+
52
+ @pytest.mark.skip(reason="MemoryService runtime not set")
53
+ @pytest.mark.asyncio
54
+ async def test_get_long_term_memories_returns_top_confidence() -> None:
55
+ svc = MemoryService(runtime=None)
56
+ entity_id = as_uuid("12345678-1234-1234-1234-123456789210")
57
+
58
+ await svc.store_long_term_memory(
59
+ agent_id=as_uuid("12345678-1234-1234-1234-123456789211"),
60
+ entity_id=entity_id,
61
+ category=LongTermMemoryCategory.SEMANTIC,
62
+ content="low",
63
+ confidence=0.1,
64
+ source=None,
65
+ metadata={},
66
+ )
67
+ await svc.store_long_term_memory(
68
+ agent_id=as_uuid("12345678-1234-1234-1234-123456789211"),
69
+ entity_id=entity_id,
70
+ category=LongTermMemoryCategory.SEMANTIC,
71
+ content="high",
72
+ confidence=0.9,
73
+ source=None,
74
+ metadata={},
75
+ )
76
+ await svc.store_long_term_memory(
77
+ agent_id=as_uuid("12345678-1234-1234-1234-123456789211"),
78
+ entity_id=entity_id,
79
+ category=LongTermMemoryCategory.SEMANTIC,
80
+ content="mid",
81
+ confidence=0.5,
82
+ source=None,
83
+ metadata={},
84
+ )
85
+
86
+ results = await svc.get_long_term_memories(entity_id, None, 2)
87
+ assert len(results) == 2
88
+ assert results[0].content == "high"
89
+
90
+
91
+ @pytest.mark.asyncio
92
+ async def test_get_long_term_memories_handles_zero_limit() -> None:
93
+ svc = MemoryService(runtime=None)
94
+ entity_id = as_uuid("12345678-1234-1234-1234-123456789220")
95
+ results = await svc.get_long_term_memories(entity_id, None, 0)
96
+ assert results == []