@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,118 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from elizaos.bootstrap.types import EvaluatorResult
6
+ from elizaos.bootstrap.utils.xml import parse_key_value_xml
7
+ from elizaos.generated.spec_helpers import require_evaluator_spec
8
+ from elizaos.prompts import REFLECTION_TEMPLATE
9
+ from elizaos.types import Evaluator, ModelType
10
+
11
+ if TYPE_CHECKING:
12
+ from elizaos.types import IAgentRuntime, Memory, State
13
+
14
+ # Get text content from centralized specs
15
+ _spec = require_evaluator_spec("REFLECTION")
16
+
17
+
18
+ async def evaluate_reflection(
19
+ runtime: IAgentRuntime,
20
+ message: Memory,
21
+ state: State | None = None,
22
+ ) -> EvaluatorResult:
23
+ if state is None:
24
+ return EvaluatorResult(
25
+ score=50,
26
+ passed=True,
27
+ reason="No state for reflection",
28
+ details={},
29
+ )
30
+
31
+ recent_interactions: list[str] = []
32
+ room_id = message.room_id
33
+
34
+ if room_id:
35
+ recent_messages = await runtime.get_memories(
36
+ room_id=room_id,
37
+ limit=10,
38
+ order_by="created_at",
39
+ order_direction="desc",
40
+ )
41
+
42
+ for msg in recent_messages:
43
+ if msg.content and msg.content.text:
44
+ sender = "Unknown"
45
+ if msg.entity_id:
46
+ if str(msg.entity_id) == str(runtime.agent_id):
47
+ sender = runtime.character.name
48
+ else:
49
+ entity = await runtime.get_entity(msg.entity_id)
50
+ if entity and entity.name:
51
+ sender = entity.name
52
+ recent_interactions.append(f"{sender}: {msg.content.text}")
53
+
54
+ if not recent_interactions:
55
+ return EvaluatorResult(
56
+ score=50,
57
+ passed=True,
58
+ reason="No recent interactions to reflect on",
59
+ details={"noInteractions": True},
60
+ )
61
+
62
+ interactions_text = "\n".join(recent_interactions)
63
+
64
+ template = (
65
+ runtime.character.templates.get("reflectionTemplate")
66
+ if runtime.character.templates and "reflectionTemplate" in runtime.character.templates
67
+ else REFLECTION_TEMPLATE
68
+ )
69
+ prompt = runtime.compose_prompt(state=state, template=template)
70
+ prompt = prompt.replace("{{recentInteractions}}", interactions_text)
71
+
72
+ response_text = await runtime.use_model(ModelType.TEXT_LARGE, prompt=prompt)
73
+ parsed_xml = parse_key_value_xml(response_text)
74
+
75
+ if parsed_xml is None:
76
+ raise ValueError("Failed to parse reflection response")
77
+
78
+ quality_str = str(parsed_xml.get("quality_score", "50"))
79
+ quality_score = max(0, min(100, int(quality_str)))
80
+
81
+ thought = str(parsed_xml.get("thought", ""))
82
+ strengths = str(parsed_xml.get("strengths", ""))
83
+ improvements = str(parsed_xml.get("improvements", ""))
84
+ learnings = str(parsed_xml.get("learnings", ""))
85
+
86
+ passed = quality_score >= 50
87
+
88
+ return EvaluatorResult(
89
+ score=quality_score,
90
+ passed=passed,
91
+ reason=f"Strengths: {strengths}\nImprovements: {improvements}",
92
+ details={
93
+ "thought": thought,
94
+ "strengths": strengths,
95
+ "improvements": improvements,
96
+ "learnings": learnings,
97
+ "interactionCount": len(recent_interactions),
98
+ },
99
+ )
100
+
101
+
102
+ async def validate_reflection(
103
+ runtime: IAgentRuntime,
104
+ message: Memory,
105
+ _state: State | None = None,
106
+ ) -> bool:
107
+ return True
108
+
109
+
110
+ reflection_evaluator = Evaluator(
111
+ name=_spec["name"],
112
+ description=_spec["description"],
113
+ similes=_spec.get("similes", []),
114
+ validate=validate_reflection,
115
+ handler=evaluate_reflection,
116
+ always_run=_spec.get("alwaysRun", False),
117
+ examples=_spec.get("examples", []),
118
+ )
@@ -0,0 +1,192 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import TYPE_CHECKING
5
+
6
+ from elizaos.bootstrap.types import EvaluatorResult
7
+ from elizaos.generated.spec_helpers import require_evaluator_spec
8
+ from elizaos.types import Evaluator
9
+
10
+ if TYPE_CHECKING:
11
+ from elizaos.types import IAgentRuntime, Memory, State
12
+
13
+ # Get text content from centralized specs
14
+ _spec = require_evaluator_spec("RELATIONSHIP_EXTRACTION")
15
+
16
+ X_HANDLE_PATTERN = re.compile(r"@[\w]+")
17
+ EMAIL_PATTERN = re.compile(r"[\w.+-]+@[\w.-]+\.\w+")
18
+ PHONE_PATTERN = re.compile(r"\+?[\d\s\-()]{10,}")
19
+ DISCORD_PATTERN = re.compile(r"[\w]+#\d{4}")
20
+
21
+
22
+ def extract_platform_identities(text: str) -> list[dict[str, str | bool | float]]:
23
+ identities: list[dict[str, str | bool | float]] = []
24
+
25
+ for match in X_HANDLE_PATTERN.finditer(text):
26
+ handle = match.group()
27
+ if handle.lower() not in ("@here", "@everyone", "@channel"):
28
+ identities.append(
29
+ {
30
+ "platform": "x",
31
+ "handle": handle,
32
+ "verified": False,
33
+ "confidence": 0.7,
34
+ }
35
+ )
36
+
37
+ for match in EMAIL_PATTERN.finditer(text):
38
+ identities.append(
39
+ {
40
+ "platform": "email",
41
+ "handle": match.group(),
42
+ "verified": False,
43
+ "confidence": 0.9,
44
+ }
45
+ )
46
+
47
+ for match in DISCORD_PATTERN.finditer(text):
48
+ identities.append(
49
+ {
50
+ "platform": "discord",
51
+ "handle": match.group(),
52
+ "verified": False,
53
+ "confidence": 0.8,
54
+ }
55
+ )
56
+
57
+ return identities
58
+
59
+
60
+ def detect_relationship_indicators(text: str) -> list[dict[str, str | float]]:
61
+ indicators: list[dict[str, str | float]] = []
62
+
63
+ friend_patterns = [
64
+ r"my friend",
65
+ r"good friend",
66
+ r"best friend",
67
+ r"close friend",
68
+ r"we're friends",
69
+ ]
70
+ for pattern in friend_patterns:
71
+ if re.search(pattern, text, re.IGNORECASE):
72
+ indicators.append(
73
+ {
74
+ "type": "friend",
75
+ "sentiment": "positive",
76
+ "confidence": 0.8,
77
+ }
78
+ )
79
+ break
80
+
81
+ colleague_patterns = [
82
+ r"my colleague",
83
+ r"coworker",
84
+ r"co-worker",
85
+ r"work together",
86
+ r"at work",
87
+ ]
88
+ for pattern in colleague_patterns:
89
+ if re.search(pattern, text, re.IGNORECASE):
90
+ indicators.append(
91
+ {
92
+ "type": "colleague",
93
+ "sentiment": "neutral",
94
+ "confidence": 0.8,
95
+ }
96
+ )
97
+ break
98
+
99
+ family_patterns = [
100
+ r"my (brother|sister|mom|dad|mother|father|parent|son|daughter|child)",
101
+ r"my family",
102
+ r"family member",
103
+ ]
104
+ for pattern in family_patterns:
105
+ if re.search(pattern, text, re.IGNORECASE):
106
+ indicators.append(
107
+ {
108
+ "type": "family",
109
+ "sentiment": "positive",
110
+ "confidence": 0.9,
111
+ }
112
+ )
113
+ break
114
+
115
+ return indicators
116
+
117
+
118
+ async def evaluate_relationship_extraction(
119
+ runtime: IAgentRuntime,
120
+ message: Memory,
121
+ state: State | None = None,
122
+ ) -> EvaluatorResult:
123
+ text = message.content.text if message.content else ""
124
+
125
+ if not text:
126
+ return EvaluatorResult(
127
+ score=50,
128
+ passed=True,
129
+ reason="No text to analyze",
130
+ details={"noText": True},
131
+ )
132
+
133
+ identities = extract_platform_identities(text)
134
+
135
+ indicators = detect_relationship_indicators(text)
136
+
137
+ if identities and message.entity_id:
138
+ entity = await runtime.get_entity(message.entity_id)
139
+ if entity:
140
+ metadata = entity.metadata or {}
141
+ existing_identities = metadata.get("platformIdentities", [])
142
+ if isinstance(existing_identities, list):
143
+ for identity in identities:
144
+ exists = any(
145
+ i.get("platform") == identity["platform"]
146
+ and i.get("handle") == identity["handle"]
147
+ for i in existing_identities
148
+ )
149
+ if not exists:
150
+ existing_identities.append(identity)
151
+ metadata["platformIdentities"] = existing_identities
152
+ entity.metadata = metadata
153
+ await runtime.update_entity(entity)
154
+
155
+ runtime.logger.info(
156
+ {
157
+ "src": "evaluator:relationship_extraction",
158
+ "agentId": str(runtime.agent_id),
159
+ "identitiesFound": len(identities),
160
+ "indicatorsFound": len(indicators),
161
+ },
162
+ "Completed extraction",
163
+ )
164
+
165
+ return EvaluatorResult(
166
+ score=70,
167
+ passed=True,
168
+ reason=f"Found {len(identities)} identities and {len(indicators)} relationship indicators",
169
+ details={
170
+ "identitiesCount": len(identities),
171
+ "indicatorsCount": len(indicators),
172
+ },
173
+ )
174
+
175
+
176
+ async def validate_relationship_extraction(
177
+ runtime: IAgentRuntime,
178
+ message: Memory,
179
+ _state: State | None = None,
180
+ ) -> bool:
181
+ return message.content is not None and bool(message.content.text)
182
+
183
+
184
+ relationship_extraction_evaluator = Evaluator(
185
+ name=_spec["name"],
186
+ description=_spec["description"],
187
+ similes=_spec.get("similes", []),
188
+ validate=validate_relationship_extraction,
189
+ handler=evaluate_relationship_extraction,
190
+ always_run=_spec.get("alwaysRun", False),
191
+ examples=_spec.get("examples", []),
192
+ )
@@ -0,0 +1,140 @@
1
+ """elizaOS Bootstrap Plugin - Python implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from elizaos.action_docs import with_canonical_action_docs, with_canonical_evaluator_docs
8
+ from elizaos.advanced_capabilities import (
9
+ advanced_actions,
10
+ advanced_evaluators,
11
+ advanced_providers,
12
+ advanced_services,
13
+ )
14
+
15
+ # Import from new capability modules
16
+ from elizaos.basic_capabilities import basic_actions, basic_providers, basic_services
17
+ from elizaos.types import Plugin
18
+
19
+ # Autonomy capabilities remain in bootstrap
20
+ from .autonomy import (
21
+ AutonomyService,
22
+ admin_chat_provider,
23
+ autonomy_status_provider,
24
+ send_to_admin_action,
25
+ )
26
+ from .types import CapabilityConfig
27
+
28
+ # Re-export for backward compatibility
29
+ BASIC_ACTIONS = basic_actions
30
+ EXTENDED_ACTIONS = advanced_actions
31
+ BASIC_PROVIDERS = basic_providers
32
+ EXTENDED_PROVIDERS = advanced_providers
33
+ BASIC_EVALUATORS: list = [] # No basic evaluators
34
+ EXTENDED_EVALUATORS = advanced_evaluators
35
+ BASIC_SERVICES = basic_services
36
+ EXTENDED_SERVICES = advanced_services
37
+
38
+ if TYPE_CHECKING:
39
+ from elizaos.types import IAgentRuntime
40
+
41
+
42
+ def _get_providers(config: CapabilityConfig) -> list:
43
+ """Get providers based on capability config."""
44
+ result = []
45
+ if not config.disable_basic:
46
+ providers_to_add = BASIC_PROVIDERS
47
+ if config.skip_character_provider:
48
+ providers_to_add = [p for p in providers_to_add if p.name != "CHARACTER"]
49
+ result.extend(providers_to_add)
50
+ if config.enable_extended:
51
+ result.extend(EXTENDED_PROVIDERS)
52
+ if config.enable_autonomy:
53
+ result.extend([admin_chat_provider, autonomy_status_provider])
54
+ return result
55
+
56
+
57
+ def _get_actions(config: CapabilityConfig) -> list:
58
+ """Get actions based on capability config."""
59
+ result = []
60
+ if not config.disable_basic:
61
+ result.extend(BASIC_ACTIONS)
62
+ if config.enable_extended:
63
+ result.extend(EXTENDED_ACTIONS)
64
+ if config.enable_autonomy:
65
+ result.append(send_to_admin_action)
66
+ return result
67
+
68
+
69
+ def _get_evaluators(config: CapabilityConfig) -> list:
70
+ """Get evaluators based on capability config."""
71
+ result = []
72
+ if not config.disable_basic:
73
+ result.extend(BASIC_EVALUATORS)
74
+ if config.enable_extended:
75
+ result.extend(EXTENDED_EVALUATORS)
76
+ return result
77
+
78
+
79
+ def _get_services(config: CapabilityConfig) -> list[type]:
80
+ """Get services based on capability config."""
81
+ result = []
82
+ if not config.disable_basic:
83
+ result.extend(BASIC_SERVICES)
84
+ if config.enable_extended:
85
+ result.extend(EXTENDED_SERVICES)
86
+ if config.enable_autonomy:
87
+ result.append(AutonomyService)
88
+ return result
89
+
90
+
91
+ def create_bootstrap_plugin(config: CapabilityConfig | None = None) -> Plugin:
92
+ """Create a bootstrap plugin with the specified capability configuration."""
93
+ if config is None:
94
+ config = CapabilityConfig()
95
+
96
+ providers = _get_providers(config)
97
+ actions = [with_canonical_action_docs(a) for a in _get_actions(config)]
98
+ evaluators = [with_canonical_evaluator_docs(e) for e in _get_evaluators(config)]
99
+ services = _get_services(config)
100
+
101
+ async def init_plugin(
102
+ plugin_config: dict[str, str | int | float | bool | None],
103
+ runtime: IAgentRuntime,
104
+ ) -> None:
105
+ """Initialize the Bootstrap plugin."""
106
+ _ = plugin_config
107
+ runtime.logger.info(
108
+ "Initializing Bootstrap plugin",
109
+ src="plugin:bootstrap",
110
+ agentId=str(runtime.agent_id),
111
+ )
112
+
113
+ runtime.logger.info(
114
+ "Bootstrap plugin initialized",
115
+ src="plugin:bootstrap",
116
+ agentId=str(runtime.agent_id),
117
+ actionCount=len(actions),
118
+ providerCount=len(providers),
119
+ evaluatorCount=len(evaluators),
120
+ serviceCount=len(services),
121
+ )
122
+
123
+ return Plugin(
124
+ name="bootstrap",
125
+ description=(
126
+ "elizaOS Bootstrap Plugin - Python implementation of core agent "
127
+ "actions, providers, evaluators, and services"
128
+ ),
129
+ init=init_plugin,
130
+ config={},
131
+ services=services,
132
+ actions=actions,
133
+ providers=providers,
134
+ evaluators=evaluators,
135
+ )
136
+
137
+
138
+ bootstrap_plugin = create_bootstrap_plugin()
139
+
140
+ __all__ = ["bootstrap_plugin", "create_bootstrap_plugin", "CapabilityConfig"]
@@ -0,0 +1,80 @@
1
+ from .action_state import action_state_provider
2
+ from .actions import actions_provider
3
+ from .agent_settings import agent_settings_provider
4
+ from .attachments import attachments_provider
5
+ from .capabilities import capabilities_provider
6
+ from .character import character_provider
7
+ from .choice import choice_provider
8
+ from .contacts import contacts_provider
9
+ from .context_bench import context_bench_provider
10
+ from .current_time import current_time_provider
11
+ from .entities import entities_provider
12
+ from .evaluators import evaluators_provider
13
+ from .facts import facts_provider
14
+ from .follow_ups import follow_ups_provider
15
+ from .knowledge import knowledge_provider
16
+ from .providers_list import providers_list_provider
17
+ from .recent_messages import recent_messages_provider
18
+ from .relationships import relationships_provider
19
+ from .roles import roles_provider
20
+ from .settings import settings_provider
21
+ from .time import time_provider
22
+ from .world import world_provider
23
+
24
+ __all__ = [
25
+ "action_state_provider",
26
+ "actions_provider",
27
+ "agent_settings_provider",
28
+ "attachments_provider",
29
+ "capabilities_provider",
30
+ "character_provider",
31
+ "context_bench_provider",
32
+ "choice_provider",
33
+ "contacts_provider",
34
+ "current_time_provider",
35
+ "entities_provider",
36
+ "evaluators_provider",
37
+ "facts_provider",
38
+ "follow_ups_provider",
39
+ "knowledge_provider",
40
+ "providers_list_provider",
41
+ "recent_messages_provider",
42
+ "relationships_provider",
43
+ "roles_provider",
44
+ "settings_provider",
45
+ "time_provider",
46
+ "world_provider",
47
+ "BASIC_PROVIDERS",
48
+ "EXTENDED_PROVIDERS",
49
+ "ALL_PROVIDERS",
50
+ ]
51
+
52
+ BASIC_PROVIDERS = [
53
+ actions_provider,
54
+ action_state_provider,
55
+ attachments_provider,
56
+ capabilities_provider,
57
+ character_provider,
58
+ context_bench_provider,
59
+ entities_provider,
60
+ evaluators_provider,
61
+ providers_list_provider,
62
+ recent_messages_provider,
63
+ current_time_provider,
64
+ time_provider,
65
+ world_provider,
66
+ ]
67
+
68
+ EXTENDED_PROVIDERS = [
69
+ choice_provider,
70
+ contacts_provider,
71
+ facts_provider,
72
+ follow_ups_provider,
73
+ knowledge_provider,
74
+ relationships_provider,
75
+ roles_provider,
76
+ agent_settings_provider,
77
+ settings_provider,
78
+ ]
79
+
80
+ ALL_PROVIDERS = BASIC_PROVIDERS + EXTENDED_PROVIDERS
@@ -0,0 +1,71 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from elizaos.generated.spec_helpers import require_provider_spec
6
+ from elizaos.types import Provider, ProviderResult
7
+
8
+ if TYPE_CHECKING:
9
+ from elizaos.types import IAgentRuntime, Memory, State
10
+
11
+ # Get text content from centralized specs
12
+ _spec = require_provider_spec("ACTION_STATE")
13
+
14
+
15
+ async def get_action_state_context(
16
+ runtime: IAgentRuntime,
17
+ message: Memory,
18
+ state: State | None = None,
19
+ ) -> ProviderResult:
20
+ sections: list[str] = []
21
+ action_data: dict[str, list[str]] = {
22
+ "pending": [],
23
+ "completed": [],
24
+ "available": [],
25
+ }
26
+
27
+ # Use the actions property instead of get_available_actions()
28
+ available_actions = runtime.actions
29
+ action_data["available"] = [a.name for a in available_actions]
30
+
31
+ if action_data["available"]:
32
+ sections.append("## Available Actions")
33
+ sections.append(", ".join(action_data["available"]))
34
+
35
+ if state and state.values:
36
+ pending = state.values.get("pendingActions", [])
37
+ if isinstance(pending, list):
38
+ action_data["pending"] = [str(a) for a in pending]
39
+
40
+ completed = state.values.get("completedActions", [])
41
+ if isinstance(completed, list):
42
+ action_data["completed"] = [str(a) for a in completed]
43
+
44
+ if action_data["pending"]:
45
+ sections.append("\n## Pending Actions")
46
+ sections.append("\n".join(f"- {a}" for a in action_data["pending"]))
47
+
48
+ if action_data["completed"]:
49
+ sections.append("\n## Recently Completed")
50
+ sections.append("\n".join(f"- {a}" for a in action_data["completed"][-5:]))
51
+
52
+ context_text = "# Action State\n" + "\n".join(sections) if sections else ""
53
+
54
+ return ProviderResult(
55
+ text=context_text,
56
+ values={
57
+ "availableActionCount": len(action_data["available"]),
58
+ "pendingActionCount": len(action_data["pending"]),
59
+ "completedActionCount": len(action_data["completed"]),
60
+ },
61
+ data=action_data,
62
+ )
63
+
64
+
65
+ action_state_provider = Provider(
66
+ name=_spec["name"],
67
+ description=_spec["description"],
68
+ get=get_action_state_context,
69
+ position=_spec.get("position"),
70
+ dynamic=_spec.get("dynamic", True),
71
+ )