@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
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from elizaos.types import Plugin
4
+
5
+ from .actions import (
6
+ analyze_input_action,
7
+ create_plan_action,
8
+ execute_final_action,
9
+ process_analysis_action,
10
+ )
11
+ from .message_classifier import message_classifier_provider
12
+ from .planning_service import PlanningService
13
+
14
+
15
+ def create_advanced_planning_plugin() -> Plugin:
16
+ async def init_plugin(_config, runtime) -> None:
17
+ runtime.logger.info(
18
+ "Advanced planning enabled",
19
+ src="plugin:advanced-planning",
20
+ agentId=str(runtime.agent_id),
21
+ )
22
+
23
+ return Plugin(
24
+ name="advanced-planning",
25
+ description="Built-in advanced planning and execution capabilities",
26
+ init=init_plugin,
27
+ config={},
28
+ services=[PlanningService],
29
+ actions=[
30
+ analyze_input_action,
31
+ process_analysis_action,
32
+ execute_final_action,
33
+ create_plan_action,
34
+ ],
35
+ providers=[message_classifier_provider],
36
+ evaluators=[],
37
+ )
38
+
39
+
40
+ advanced_planning_plugin = create_advanced_planning_plugin()
@@ -0,0 +1,4 @@
1
+ # Re-export from centralized prompts
2
+ from elizaos.prompts import MESSAGE_CLASSIFIER_TEMPLATE
3
+
4
+ __all__ = ["MESSAGE_CLASSIFIER_TEMPLATE"]
@@ -0,0 +1,66 @@
1
+ """Basic Capabilities - Core functionality for agent operation.
2
+
3
+ This module provides the fundamental capabilities needed for basic agent operation:
4
+ - Core actions (reply, ignore, none, choice)
5
+ - Core providers (actions, character, entities, messages, etc.)
6
+ - Essential services (task management, embeddings)
7
+ """
8
+
9
+ from .actions import (
10
+ basic_actions,
11
+ choice_action,
12
+ ignore_action,
13
+ none_action,
14
+ reply_action,
15
+ )
16
+ from .providers import (
17
+ action_state_provider,
18
+ actions_provider,
19
+ attachments_provider,
20
+ basic_providers,
21
+ capabilities_provider,
22
+ character_provider,
23
+ choice_provider,
24
+ context_bench_provider,
25
+ current_time_provider,
26
+ entities_provider,
27
+ evaluators_provider,
28
+ providers_list_provider,
29
+ recent_messages_provider,
30
+ time_provider,
31
+ world_provider,
32
+ )
33
+ from .services import (
34
+ EmbeddingService,
35
+ TaskService,
36
+ basic_services,
37
+ )
38
+
39
+ __all__ = [
40
+ # Actions
41
+ "basic_actions",
42
+ "choice_action",
43
+ "ignore_action",
44
+ "none_action",
45
+ "reply_action",
46
+ # Providers
47
+ "basic_providers",
48
+ "action_state_provider",
49
+ "actions_provider",
50
+ "attachments_provider",
51
+ "capabilities_provider",
52
+ "character_provider",
53
+ "choice_provider",
54
+ "context_bench_provider",
55
+ "current_time_provider",
56
+ "entities_provider",
57
+ "evaluators_provider",
58
+ "providers_list_provider",
59
+ "recent_messages_provider",
60
+ "time_provider",
61
+ "world_provider",
62
+ # Services
63
+ "basic_services",
64
+ "EmbeddingService",
65
+ "TaskService",
66
+ ]
@@ -0,0 +1,24 @@
1
+ """Basic Actions - Core response actions.
2
+
3
+ Fundamental actions included by default in the bootstrap plugin.
4
+ """
5
+
6
+ from .choice import choose_option_action as choice_action
7
+ from .ignore import ignore_action
8
+ from .none import none_action
9
+ from .reply import reply_action
10
+
11
+ __all__ = [
12
+ "choice_action",
13
+ "ignore_action",
14
+ "none_action",
15
+ "reply_action",
16
+ "basic_actions",
17
+ ]
18
+
19
+ basic_actions = [
20
+ choice_action,
21
+ reply_action,
22
+ ignore_action,
23
+ none_action,
24
+ ]
@@ -0,0 +1,140 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import TYPE_CHECKING
5
+
6
+ from elizaos.bootstrap.utils.xml import parse_key_value_xml
7
+ from elizaos.generated.spec_helpers import require_action_spec
8
+ from elizaos.prompts import CHOOSE_OPTION_TEMPLATE
9
+ from elizaos.types import Action, ActionExample, ActionResult, Content, ModelType
10
+ from elizaos.utils.spec_examples import convert_spec_examples
11
+
12
+ if TYPE_CHECKING:
13
+ from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
14
+
15
+ # Get text content from centralized specs
16
+ _spec = require_action_spec("CHOOSE_OPTION")
17
+
18
+
19
+ def _convert_spec_examples() -> list[list[ActionExample]]:
20
+ """Convert spec examples to ActionExample format."""
21
+ return convert_spec_examples(_spec)
22
+
23
+
24
+ @dataclass
25
+ class ChooseOptionAction:
26
+ name: str = _spec["name"]
27
+ similes: list[str] = field(default_factory=lambda: list(_spec.get("similes", [])))
28
+ description: str = _spec["description"]
29
+
30
+ async def validate(
31
+ self, runtime: IAgentRuntime, message: Memory, _state: State | None = None
32
+ ) -> bool:
33
+ # Check for options in content.data (protobuf) or content.options (legacy)
34
+ if message.content:
35
+ options = getattr(message.content, "options", None)
36
+ if options is None and hasattr(message.content, "data"):
37
+ data = message.content.data
38
+ if hasattr(data, "get"):
39
+ options = data.get("options", [])
40
+ if options:
41
+ return len(options) > 0
42
+ return True
43
+
44
+ async def handler(
45
+ self,
46
+ runtime: IAgentRuntime,
47
+ message: Memory,
48
+ state: State | None = None,
49
+ options: HandlerOptions | None = None,
50
+ callback: HandlerCallback | None = None,
51
+ responses: list[Memory] | None = None,
52
+ ) -> ActionResult:
53
+ if state is None:
54
+ raise ValueError("State is required for CHOOSE_OPTION action")
55
+
56
+ available_options: list[dict[str, str]] = []
57
+ if message.content and message.content.options:
58
+ available_options = message.content.options
59
+
60
+ if not available_options:
61
+ return ActionResult(
62
+ text="No options available to choose from",
63
+ values={"success": False, "error": "no_options"},
64
+ data={"actionName": "CHOOSE_OPTION"},
65
+ success=False,
66
+ )
67
+
68
+ state = await runtime.compose_state(message, ["RECENT_MESSAGES", "ACTION_STATE"])
69
+
70
+ options_context = "\n".join(
71
+ f"- [{opt.get('id', idx)}] {opt.get('label', '')}: {opt.get('description', '')}"
72
+ for idx, opt in enumerate(available_options)
73
+ )
74
+
75
+ template = (
76
+ runtime.character.templates.get("chooseOptionTemplate")
77
+ if runtime.character.templates and "chooseOptionTemplate" in runtime.character.templates
78
+ else CHOOSE_OPTION_TEMPLATE
79
+ )
80
+ prompt = runtime.compose_prompt(state=state, template=template)
81
+ prompt = prompt.replace("{{options}}", options_context)
82
+
83
+ response_text = await runtime.use_model(ModelType.TEXT_LARGE, prompt=prompt)
84
+ parsed_xml = parse_key_value_xml(response_text)
85
+
86
+ if parsed_xml is None:
87
+ raise ValueError("Failed to parse XML response")
88
+
89
+ thought = str(parsed_xml.get("thought", ""))
90
+ selected_id = str(parsed_xml.get("selected_id", ""))
91
+
92
+ if not selected_id:
93
+ raise ValueError("No option selected")
94
+
95
+ selected_option = next(
96
+ (opt for opt in available_options if str(opt.get("id", "")) == selected_id),
97
+ None,
98
+ )
99
+
100
+ if selected_option is None:
101
+ raise ValueError(f"Selected option ID '{selected_id}' not found")
102
+
103
+ response_content = Content(
104
+ thought=thought,
105
+ text=f"Selected option: {selected_option.get('label', selected_id)}",
106
+ actions=["CHOOSE_OPTION"],
107
+ )
108
+
109
+ if callback:
110
+ await callback(response_content)
111
+
112
+ return ActionResult(
113
+ text=f"Selected option: {selected_option.get('label', selected_id)}",
114
+ values={
115
+ "success": True,
116
+ "selectedId": selected_id,
117
+ "selectedLabel": selected_option.get("label", ""),
118
+ "thought": thought,
119
+ },
120
+ data={
121
+ "actionName": "CHOOSE_OPTION",
122
+ "selectedOption": selected_option,
123
+ "thought": thought,
124
+ },
125
+ success=True,
126
+ )
127
+
128
+ @property
129
+ def examples(self) -> list[list[ActionExample]]:
130
+ return _convert_spec_examples()
131
+
132
+
133
+ choose_option_action = Action(
134
+ name=ChooseOptionAction.name,
135
+ similes=ChooseOptionAction().similes,
136
+ description=ChooseOptionAction.description,
137
+ validate=ChooseOptionAction().validate,
138
+ handler=ChooseOptionAction().handler,
139
+ examples=ChooseOptionAction().examples,
140
+ )
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import TYPE_CHECKING
5
+
6
+ from elizaos.generated.spec_helpers import require_action_spec
7
+ from elizaos.types import Action, ActionExample, ActionResult
8
+ from elizaos.utils.spec_examples import convert_spec_examples
9
+
10
+ if TYPE_CHECKING:
11
+ from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
12
+
13
+ # Get text content from centralized specs
14
+ _spec = require_action_spec("IGNORE")
15
+
16
+
17
+ def _convert_spec_examples() -> list[list[ActionExample]]:
18
+ """Convert spec examples to ActionExample format."""
19
+ return convert_spec_examples(_spec)
20
+
21
+
22
+ @dataclass
23
+ class IgnoreAction:
24
+ name: str = _spec["name"]
25
+ similes: list[str] = field(default_factory=lambda: list(_spec.get("similes", [])))
26
+ description: str = _spec["description"]
27
+
28
+ async def validate(
29
+ self, runtime: IAgentRuntime, _message: Memory, _state: State | None = None
30
+ ) -> bool:
31
+ return True
32
+
33
+ async def handler(
34
+ self,
35
+ runtime: IAgentRuntime,
36
+ message: Memory,
37
+ state: State | None = None,
38
+ options: HandlerOptions | None = None,
39
+ callback: HandlerCallback | None = None,
40
+ responses: list[Memory] | None = None,
41
+ ) -> ActionResult:
42
+ if callback and responses and len(responses) > 0:
43
+ first_response = responses[0]
44
+ if first_response.content:
45
+ await callback(first_response.content)
46
+
47
+ return ActionResult(
48
+ text="Ignoring message",
49
+ values={"success": True, "ignored": True},
50
+ data={"actionName": "IGNORE"},
51
+ success=True,
52
+ )
53
+
54
+ @property
55
+ def examples(self) -> list[list[ActionExample]]:
56
+ return _convert_spec_examples()
57
+
58
+
59
+ ignore_action = Action(
60
+ name=IgnoreAction.name,
61
+ similes=IgnoreAction().similes,
62
+ description=IgnoreAction.description,
63
+ validate=IgnoreAction().validate,
64
+ handler=IgnoreAction().handler,
65
+ examples=IgnoreAction().examples,
66
+ )
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import TYPE_CHECKING
5
+
6
+ from elizaos.generated.spec_helpers import require_action_spec
7
+ from elizaos.types import Action, ActionExample, ActionResult
8
+ from elizaos.utils.spec_examples import convert_spec_examples
9
+
10
+ if TYPE_CHECKING:
11
+ from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
12
+
13
+ # Get text content from centralized specs
14
+ _spec = require_action_spec("NONE")
15
+
16
+
17
+ @dataclass
18
+ class NoneAction:
19
+ name: str = _spec["name"]
20
+ similes: list[str] = field(default_factory=lambda: list(_spec.get("similes", [])))
21
+ description: str = _spec["description"]
22
+
23
+ async def validate(
24
+ self, runtime: IAgentRuntime, _message: Memory, _state: State | None = None
25
+ ) -> bool:
26
+ return True
27
+
28
+ async def handler(
29
+ self,
30
+ runtime: IAgentRuntime,
31
+ message: Memory,
32
+ state: State | None = None,
33
+ options: HandlerOptions | None = None,
34
+ callback: HandlerCallback | None = None,
35
+ responses: list[Memory] | None = None,
36
+ ) -> ActionResult:
37
+ return ActionResult(
38
+ text="No action taken",
39
+ values={"success": True, "noAction": True},
40
+ data={"actionName": "NONE"},
41
+ success=True,
42
+ )
43
+
44
+ @property
45
+ def examples(self) -> list[list[ActionExample]]:
46
+ return convert_spec_examples(_spec)
47
+
48
+
49
+ none_action = Action(
50
+ name=NoneAction.name,
51
+ similes=NoneAction().similes,
52
+ description=NoneAction.description,
53
+ validate=NoneAction().validate,
54
+ handler=NoneAction().handler,
55
+ examples=NoneAction().examples,
56
+ )
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import TYPE_CHECKING
5
+
6
+ from elizaos.bootstrap.utils.xml import parse_key_value_xml
7
+ from elizaos.generated.spec_helpers import require_action_spec
8
+ from elizaos.prompts import REPLY_TEMPLATE
9
+ from elizaos.types import Action, ActionExample, ActionResult, Content, ModelType
10
+ from elizaos.utils.spec_examples import convert_spec_examples
11
+
12
+ if TYPE_CHECKING:
13
+ from elizaos.types import (
14
+ HandlerCallback,
15
+ HandlerOptions,
16
+ IAgentRuntime,
17
+ Memory,
18
+ State,
19
+ )
20
+
21
+ # Get text content from centralized specs
22
+ _spec = require_action_spec("REPLY")
23
+
24
+
25
+ def _convert_spec_examples() -> list[list[ActionExample]]:
26
+ """Convert spec examples to ActionExample format."""
27
+ return convert_spec_examples(_spec)
28
+
29
+
30
+ @dataclass
31
+ class ReplyAction:
32
+ name: str = _spec["name"]
33
+ similes: list[str] = field(default_factory=lambda: list(_spec.get("similes", [])))
34
+ description: str = _spec["description"]
35
+
36
+ async def validate(
37
+ self, runtime: IAgentRuntime, _message: Memory, _state: State | None = None
38
+ ) -> bool:
39
+ return True
40
+
41
+ async def handler(
42
+ self,
43
+ runtime: IAgentRuntime,
44
+ message: Memory,
45
+ state: State | None = None,
46
+ options: HandlerOptions | None = None,
47
+ callback: HandlerCallback | None = None,
48
+ responses: list[Memory] | None = None,
49
+ ) -> ActionResult:
50
+ all_providers: list[str] = []
51
+ if responses:
52
+ for res in responses:
53
+ if res.content and res.content.providers:
54
+ all_providers.extend(res.content.providers)
55
+
56
+ state = await runtime.compose_state(
57
+ message, [*all_providers, "RECENT_MESSAGES", "ACTION_STATE"]
58
+ )
59
+
60
+ template = REPLY_TEMPLATE
61
+ if runtime.character.templates and "replyTemplate" in runtime.character.templates:
62
+ template = runtime.character.templates["replyTemplate"]
63
+
64
+ prompt = runtime.compose_prompt_from_state(state=state, template=template)
65
+
66
+ response = await runtime.use_model(
67
+ ModelType.TEXT_LARGE,
68
+ {
69
+ "prompt": prompt,
70
+ "system": str(runtime.character.system or ""),
71
+ },
72
+ )
73
+
74
+ parsed = parse_key_value_xml(response)
75
+ thought = parsed.get("thought", "") if parsed else ""
76
+ text = parsed.get("text", "") if parsed else ""
77
+
78
+ thought = str(thought) if thought else ""
79
+ text = str(text) if text else ""
80
+
81
+ response_content = Content(
82
+ thought=thought,
83
+ text=text,
84
+ actions=["REPLY"],
85
+ )
86
+
87
+ if callback:
88
+ await callback(response_content)
89
+
90
+ return ActionResult(
91
+ text=f"Generated reply: {text}",
92
+ values={
93
+ "success": True,
94
+ "responded": True,
95
+ "lastReply": text,
96
+ "lastReplyTime": runtime.get_current_time_ms(),
97
+ "thoughtProcess": thought,
98
+ },
99
+ data={
100
+ "actionName": "REPLY",
101
+ "responseThought": thought,
102
+ "responseText": text,
103
+ "messageGenerated": True,
104
+ },
105
+ success=True,
106
+ )
107
+
108
+ @property
109
+ def examples(self) -> list[list[ActionExample]]:
110
+ return _convert_spec_examples()
111
+
112
+
113
+ reply_action = Action(
114
+ name=ReplyAction.name,
115
+ similes=ReplyAction().similes,
116
+ description=ReplyAction.description,
117
+ validate=ReplyAction().validate,
118
+ handler=ReplyAction().handler,
119
+ examples=ReplyAction().examples,
120
+ )
@@ -0,0 +1,54 @@
1
+ """Basic Providers - Core providers for agent operation.
2
+
3
+ Fundamental providers included by default in the bootstrap plugin.
4
+ """
5
+
6
+ from .action_state import action_state_provider
7
+ from .actions import actions_provider
8
+ from .attachments import attachments_provider
9
+ from .capabilities import capabilities_provider
10
+ from .character import character_provider
11
+ from .choice import choice_provider
12
+ from .context_bench import context_bench_provider
13
+ from .current_time import current_time_provider
14
+ from .entities import entities_provider
15
+ from .evaluators import evaluators_provider
16
+ from .providers_list import providers_list_provider
17
+ from .recent_messages import recent_messages_provider
18
+ from .time import time_provider
19
+ from .world import world_provider
20
+
21
+ __all__ = [
22
+ "action_state_provider",
23
+ "actions_provider",
24
+ "attachments_provider",
25
+ "capabilities_provider",
26
+ "character_provider",
27
+ "choice_provider",
28
+ "context_bench_provider",
29
+ "current_time_provider",
30
+ "entities_provider",
31
+ "evaluators_provider",
32
+ "providers_list_provider",
33
+ "recent_messages_provider",
34
+ "time_provider",
35
+ "world_provider",
36
+ "basic_providers",
37
+ ]
38
+
39
+ basic_providers = [
40
+ actions_provider,
41
+ action_state_provider,
42
+ attachments_provider,
43
+ capabilities_provider,
44
+ character_provider,
45
+ choice_provider,
46
+ context_bench_provider,
47
+ current_time_provider,
48
+ entities_provider,
49
+ evaluators_provider,
50
+ providers_list_provider,
51
+ recent_messages_provider,
52
+ time_provider,
53
+ world_provider,
54
+ ]
@@ -0,0 +1,113 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from elizaos.types import Provider, ProviderResult
6
+
7
+ if TYPE_CHECKING:
8
+ from elizaos.types import IAgentRuntime, Memory, State
9
+
10
+
11
+ async def get_action_state_context(
12
+ runtime: IAgentRuntime,
13
+ message: Memory,
14
+ state: State | None = None,
15
+ ) -> ProviderResult:
16
+ sections: list[str] = []
17
+ action_data: dict[str, list[str]] = {
18
+ "pending": [],
19
+ "completed": [],
20
+ "available": [],
21
+ }
22
+
23
+ # Use the actions property instead of get_available_actions()
24
+ available_actions = runtime.actions
25
+ action_data["available"] = [a.name for a in available_actions]
26
+
27
+ if action_data["available"]:
28
+ sections.append("## Available Actions")
29
+ sections.append(", ".join(action_data["available"]))
30
+
31
+ if state and state.values:
32
+ # Handle both dict-like and protobuf state.values
33
+ values = state.values
34
+ pending = []
35
+ completed = []
36
+
37
+ if hasattr(values, "get") and callable(values.get):
38
+ # Dict-like access
39
+ pending = values.get("pendingActions", [])
40
+ completed = values.get("completedActions", [])
41
+ elif hasattr(values, "extra"):
42
+ # Protobuf - extra might be a MapField or a message
43
+ extra = values.extra
44
+ if hasattr(extra, "get") and callable(extra.get):
45
+ pending_raw = extra.get("pendingActions", "")
46
+ completed_raw = extra.get("completedActions", "")
47
+ elif hasattr(extra, "__getitem__"):
48
+ try:
49
+ pending_raw = extra["pendingActions"]
50
+ except (KeyError, TypeError, ValueError):
51
+ pending_raw = ""
52
+ try:
53
+ completed_raw = extra["completedActions"]
54
+ except (KeyError, TypeError, ValueError):
55
+ completed_raw = ""
56
+ else:
57
+ pending_raw = ""
58
+ completed_raw = ""
59
+
60
+ # Parse if stored as string
61
+ if isinstance(pending_raw, str) and pending_raw:
62
+ import json
63
+
64
+ try:
65
+ pending = json.loads(pending_raw)
66
+ except json.JSONDecodeError:
67
+ pending = []
68
+ elif isinstance(pending_raw, list):
69
+ pending = pending_raw
70
+
71
+ if isinstance(completed_raw, str) and completed_raw:
72
+ import json
73
+
74
+ try:
75
+ completed = json.loads(completed_raw)
76
+ except json.JSONDecodeError:
77
+ completed = []
78
+ elif isinstance(completed_raw, list):
79
+ completed = completed_raw
80
+
81
+ if isinstance(pending, list):
82
+ action_data["pending"] = [str(a) for a in pending]
83
+
84
+ if isinstance(completed, list):
85
+ action_data["completed"] = [str(a) for a in completed]
86
+
87
+ if action_data["pending"]:
88
+ sections.append("\n## Pending Actions")
89
+ sections.append("\n".join(f"- {a}" for a in action_data["pending"]))
90
+
91
+ if action_data["completed"]:
92
+ sections.append("\n## Recently Completed")
93
+ sections.append("\n".join(f"- {a}" for a in action_data["completed"][-5:]))
94
+
95
+ context_text = "# Action State\n" + "\n".join(sections) if sections else ""
96
+
97
+ return ProviderResult(
98
+ text=context_text,
99
+ values={
100
+ "availableActionCount": len(action_data["available"]),
101
+ "pendingActionCount": len(action_data["pending"]),
102
+ "completedActionCount": len(action_data["completed"]),
103
+ },
104
+ data=action_data,
105
+ )
106
+
107
+
108
+ action_state_provider = Provider(
109
+ name="ACTION_STATE",
110
+ description="Provides information about the current action state and available actions",
111
+ get=get_action_state_context,
112
+ dynamic=True,
113
+ )