@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,460 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from collections.abc import AsyncIterator, Awaitable, Callable
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+ from elizaos.logger import Logger
10
+ from elizaos.types.database import IDatabaseAdapter
11
+ from elizaos.types.primitives import UUID, Content
12
+
13
+ if TYPE_CHECKING:
14
+ from elizaos.types.agent import Character, TemplateType
15
+ from elizaos.types.components import (
16
+ Action,
17
+ ActionResult,
18
+ Evaluator,
19
+ HandlerCallback,
20
+ PreEvaluatorResult,
21
+ Provider,
22
+ )
23
+ from elizaos.types.environment import Entity, Room, World
24
+ from elizaos.types.memory import Memory
25
+ from elizaos.types.model import (
26
+ GenerateTextOptions,
27
+ GenerateTextResult,
28
+ ModelType,
29
+ )
30
+ from elizaos.types.plugin import Plugin, Route
31
+ from elizaos.types.service import Service
32
+ from elizaos.types.state import State
33
+ from elizaos.types.task import TaskWorker
34
+
35
+
36
+ # Type alias for streaming model handlers
37
+ StreamingModelHandler = Callable[["IAgentRuntime", dict[str, Any]], AsyncIterator[str]]
38
+
39
+
40
+ # Runtime settings type
41
+ RuntimeSettings = dict[str, str | bool | int | float | None]
42
+
43
+
44
+ # Send handler function type
45
+ SendHandlerFunction = Callable[[Any, Content], Awaitable[None]]
46
+
47
+
48
+ class TargetInfo(BaseModel):
49
+ room_id: UUID | None = Field(default=None, alias="roomId")
50
+ entity_id: UUID | None = Field(default=None, alias="entityId")
51
+ world_id: UUID | None = Field(default=None, alias="worldId")
52
+ source: str | None = None
53
+
54
+ model_config = {"populate_by_name": True, "extra": "allow"}
55
+
56
+
57
+ class IAgentRuntime(ABC):
58
+ # Properties that must be implemented
59
+ @property
60
+ @abstractmethod
61
+ def agent_id(self) -> UUID: ...
62
+
63
+ @property
64
+ @abstractmethod
65
+ def character(self) -> Character: ...
66
+
67
+ @property
68
+ @abstractmethod
69
+ def providers(self) -> list[Provider]: ...
70
+
71
+ @property
72
+ @abstractmethod
73
+ def actions(self) -> list[Action]: ...
74
+
75
+ @property
76
+ @abstractmethod
77
+ def evaluators(self) -> list[Evaluator]: ...
78
+
79
+ @property
80
+ @abstractmethod
81
+ def plugins(self) -> list[Plugin]: ...
82
+
83
+ @property
84
+ @abstractmethod
85
+ def services(self) -> dict[str, list[Service]]: ...
86
+
87
+ @property
88
+ @abstractmethod
89
+ def routes(self) -> list[Route]: ...
90
+
91
+ @property
92
+ @abstractmethod
93
+ def events(self) -> dict[str, list[Callable[[Any], Awaitable[None]]]]: ...
94
+
95
+ @property
96
+ @abstractmethod
97
+ def state_cache(self) -> dict[str, State]: ...
98
+
99
+ @property
100
+ @abstractmethod
101
+ def message_service(self) -> Any | None: ...
102
+
103
+ @property
104
+ @abstractmethod
105
+ def enable_autonomy(self) -> bool: ...
106
+
107
+ @enable_autonomy.setter
108
+ @abstractmethod
109
+ def enable_autonomy(self, value: bool) -> None: ...
110
+
111
+ # Database adapter
112
+ @abstractmethod
113
+ def register_database_adapter(self, adapter: IDatabaseAdapter) -> None: ...
114
+
115
+ @abstractmethod
116
+ async def get_connection(self) -> Any: ...
117
+
118
+ @abstractmethod
119
+ async def get_cache(self, key: str) -> object | None: ...
120
+
121
+ @abstractmethod
122
+ async def set_cache(self, key: str, value: object) -> bool: ...
123
+
124
+ @abstractmethod
125
+ async def delete_cache(self, key: str) -> None: ...
126
+
127
+ @abstractmethod
128
+ async def get_memories(
129
+ self, params: dict[str, Any] | None = None, **kwargs: Any
130
+ ) -> list[Any]: ...
131
+
132
+ @abstractmethod
133
+ async def create_memory(
134
+ self,
135
+ memory: dict[str, object] | None = None,
136
+ table_name: str | None = None,
137
+ unique: bool | None = None,
138
+ **kwargs: object,
139
+ ) -> Any: ...
140
+
141
+ # Plugin management
142
+ @abstractmethod
143
+ async def register_plugin(self, plugin: Plugin) -> None: ...
144
+
145
+ @abstractmethod
146
+ async def initialize(
147
+ self, config: dict[str, str | int | bool | None] | None = None
148
+ ) -> None: ...
149
+
150
+ # Service management
151
+ @abstractmethod
152
+ def get_service(self, service: str) -> Service | None: ...
153
+
154
+ @abstractmethod
155
+ def get_services_by_type(self, service: str) -> list[Service]: ...
156
+
157
+ @abstractmethod
158
+ def get_all_services(self) -> dict[str, list[Service]]: ...
159
+
160
+ @abstractmethod
161
+ async def register_service(self, service: type[Service]) -> None: ...
162
+
163
+ @abstractmethod
164
+ async def get_service_load_promise(self, service_type: str) -> Service: ...
165
+
166
+ @abstractmethod
167
+ def get_registered_service_types(self) -> list[str]: ...
168
+
169
+ @abstractmethod
170
+ def has_service(self, service_type: str) -> bool: ...
171
+
172
+ # Settings
173
+ @abstractmethod
174
+ def set_setting(self, key: str, value: object | None, secret: bool = False) -> None: ...
175
+
176
+ @abstractmethod
177
+ def get_setting(self, key: str) -> object | None: ...
178
+
179
+ @abstractmethod
180
+ def get_all_settings(self) -> dict[str, object | None]: ...
181
+
182
+ @abstractmethod
183
+ def compose_prompt(self, *, state: State, template: TemplateType) -> str: ...
184
+
185
+ @abstractmethod
186
+ def compose_prompt_from_state(self, *, state: State, template: TemplateType) -> str: ...
187
+
188
+ @abstractmethod
189
+ def get_current_time_ms(self) -> int: ...
190
+
191
+ @abstractmethod
192
+ def get_conversation_length(self) -> int: ...
193
+
194
+ @property
195
+ @abstractmethod
196
+ def logger(self) -> Logger: ...
197
+
198
+ @abstractmethod
199
+ def is_action_planning_enabled(self) -> bool: ...
200
+
201
+ @abstractmethod
202
+ def is_check_should_respond_enabled(self) -> bool: ...
203
+
204
+ # Action processing
205
+ @abstractmethod
206
+ async def process_actions(
207
+ self,
208
+ message: Memory,
209
+ responses: list[Memory],
210
+ state: State | None = None,
211
+ callback: HandlerCallback | None = None,
212
+ options: dict[str, Any] | None = None,
213
+ ) -> None: ...
214
+
215
+ @abstractmethod
216
+ def get_action_results(self, message_id: UUID) -> list[ActionResult]: ...
217
+
218
+ # Evaluation
219
+ @abstractmethod
220
+ async def evaluate(
221
+ self,
222
+ message: Memory,
223
+ state: State | None = None,
224
+ did_respond: bool = False,
225
+ callback: HandlerCallback | None = None,
226
+ responses: list[Memory] | None = None,
227
+ ) -> list[Evaluator] | None: ...
228
+
229
+ @abstractmethod
230
+ async def evaluate_pre(
231
+ self,
232
+ message: Memory,
233
+ state: State | None = None,
234
+ ) -> "PreEvaluatorResult": ...
235
+
236
+ # Component registration
237
+ @abstractmethod
238
+ def register_provider(self, provider: Provider) -> None: ...
239
+
240
+ @abstractmethod
241
+ def register_action(self, action: Action) -> None: ...
242
+
243
+ @abstractmethod
244
+ def register_evaluator(self, evaluator: Evaluator) -> None: ...
245
+
246
+ # Connection management
247
+ @abstractmethod
248
+ async def ensure_connections(
249
+ self,
250
+ entities: list[Entity],
251
+ rooms: list[Room],
252
+ source: str,
253
+ world: World,
254
+ ) -> None: ...
255
+
256
+ @abstractmethod
257
+ async def ensure_connection(
258
+ self,
259
+ entity_id: UUID,
260
+ room_id: UUID,
261
+ world_id: UUID,
262
+ user_name: str | None = None,
263
+ name: str | None = None,
264
+ world_name: str | None = None,
265
+ source: str | None = None,
266
+ channel_id: str | None = None,
267
+ message_server_id: UUID | None = None,
268
+ channel_type: str | None = None,
269
+ user_id: UUID | None = None,
270
+ metadata: dict[str, Any] | None = None,
271
+ ) -> None: ...
272
+
273
+ @abstractmethod
274
+ async def ensure_participant_in_room(self, entity_id: UUID, room_id: UUID) -> None: ...
275
+
276
+ @abstractmethod
277
+ async def ensure_world_exists(self, world: World) -> None: ...
278
+
279
+ @abstractmethod
280
+ async def ensure_room_exists(self, room: Room) -> None: ...
281
+
282
+ # State composition
283
+ @abstractmethod
284
+ async def compose_state(
285
+ self,
286
+ message: Memory,
287
+ include_list: list[str] | None = None,
288
+ only_include: bool = False,
289
+ skip_cache: bool = False,
290
+ ) -> State: ...
291
+
292
+ # Model usage
293
+ @abstractmethod
294
+ def has_model(self, model_type: str | ModelType) -> bool: ...
295
+
296
+ @abstractmethod
297
+ async def use_model(
298
+ self,
299
+ model_type: str | ModelType,
300
+ params: dict[str, Any] | None = None,
301
+ provider: str | None = None,
302
+ **kwargs: Any,
303
+ ) -> Any: ...
304
+
305
+ @abstractmethod
306
+ async def generate_text(
307
+ self,
308
+ input_text: str,
309
+ options: GenerateTextOptions | None = None,
310
+ ) -> GenerateTextResult: ...
311
+
312
+ @abstractmethod
313
+ def register_model(
314
+ self,
315
+ model_type: str | ModelType,
316
+ handler: Callable[[IAgentRuntime, dict[str, Any]], Awaitable[Any]],
317
+ provider: str,
318
+ priority: int = 0,
319
+ ) -> None: ...
320
+
321
+ @abstractmethod
322
+ def get_model(
323
+ self, model_type: str
324
+ ) -> Callable[[IAgentRuntime, dict[str, Any]], Awaitable[Any]] | None: ...
325
+
326
+ @abstractmethod
327
+ def use_model_stream(
328
+ self,
329
+ model_type: str | ModelType,
330
+ params: dict[str, Any] | None = None,
331
+ provider: str | None = None,
332
+ **kwargs: Any,
333
+ ) -> AsyncIterator[str]:
334
+ """
335
+ Use a streaming model handler to generate text token by token.
336
+
337
+ Args:
338
+ model_type: The model type (e.g., ModelType.TEXT_LARGE_STREAM)
339
+ params: Parameters for the model (prompt, system, temperature, etc.)
340
+ provider: Optional specific provider to use
341
+ **kwargs: Additional parameters merged into params
342
+
343
+ Returns:
344
+ An async iterator yielding text chunks as they are generated.
345
+ """
346
+ ...
347
+
348
+ @abstractmethod
349
+ def register_streaming_model(
350
+ self,
351
+ model_type: str | ModelType,
352
+ handler: StreamingModelHandler,
353
+ provider: str,
354
+ priority: int = 0,
355
+ ) -> None:
356
+ """Register a streaming model handler."""
357
+ ...
358
+
359
+ # Event handling
360
+ @abstractmethod
361
+ def register_event(
362
+ self,
363
+ event: str,
364
+ handler: Callable[[Any], Awaitable[None]],
365
+ ) -> None: ...
366
+
367
+ @abstractmethod
368
+ def get_event(self, event: str) -> list[Callable[[Any], Awaitable[None]]] | None: ...
369
+
370
+ @abstractmethod
371
+ async def emit_event(
372
+ self,
373
+ event: str | list[str],
374
+ params: Any,
375
+ ) -> None: ...
376
+
377
+ # Task management
378
+ @abstractmethod
379
+ def register_task_worker(self, task_handler: TaskWorker) -> None: ...
380
+
381
+ @abstractmethod
382
+ def get_task_worker(self, name: str) -> TaskWorker | None: ...
383
+
384
+ # Lifecycle
385
+ @abstractmethod
386
+ async def stop(self) -> None: ...
387
+
388
+ # Memory/embedding helpers
389
+ @abstractmethod
390
+ async def add_embedding_to_memory(self, memory: Memory) -> Memory: ...
391
+
392
+ @abstractmethod
393
+ async def queue_embedding_generation(
394
+ self, memory: Memory, priority: str = "normal"
395
+ ) -> None: ...
396
+
397
+ @abstractmethod
398
+ async def get_all_memories(self) -> list[Memory]: ...
399
+
400
+ @abstractmethod
401
+ async def clear_all_agent_memories(self) -> None: ...
402
+
403
+ @abstractmethod
404
+ async def update_memory(self, memory: Memory | dict[str, Any]) -> bool: ...
405
+
406
+ # Run tracking
407
+ @abstractmethod
408
+ def create_run_id(self) -> UUID: ...
409
+
410
+ @abstractmethod
411
+ def start_run(self, room_id: UUID | None = None) -> UUID: ...
412
+
413
+ @abstractmethod
414
+ def end_run(self) -> None: ...
415
+
416
+ @abstractmethod
417
+ def get_current_run_id(self) -> UUID: ...
418
+
419
+ # Convenience wrappers
420
+ @abstractmethod
421
+ async def get_entity_by_id(self, entity_id: UUID) -> Entity | None: ...
422
+
423
+ @abstractmethod
424
+ async def get_entity(self, entity_id: UUID | str) -> Entity | None: ...
425
+
426
+ @abstractmethod
427
+ async def update_entity(self, entity: Entity) -> None: ...
428
+
429
+ @abstractmethod
430
+ async def get_room(self, room_id: UUID) -> Room | None: ...
431
+
432
+ @abstractmethod
433
+ async def create_entity(self, entity: Entity) -> bool: ...
434
+
435
+ @abstractmethod
436
+ async def create_room(self, room: Room) -> UUID: ...
437
+
438
+ @abstractmethod
439
+ async def add_participant(self, entity_id: UUID, room_id: UUID) -> bool: ...
440
+
441
+ @abstractmethod
442
+ async def get_rooms(self, world_id: UUID) -> list[Room]: ...
443
+
444
+ @abstractmethod
445
+ def register_send_handler(self, source: str, handler: SendHandlerFunction) -> None: ...
446
+
447
+ @abstractmethod
448
+ async def send_message_to_target(self, target: TargetInfo, content: Content) -> None: ...
449
+
450
+ @abstractmethod
451
+ async def update_world(self, world: World) -> None: ...
452
+
453
+ @abstractmethod
454
+ async def get_world(self, world_id: UUID) -> World | None: ...
455
+
456
+ @abstractmethod
457
+ async def get_relationships(self, params: dict[str, object]) -> list[object]: ...
458
+
459
+ @abstractmethod
460
+ async def search_knowledge(self, query: str, limit: int = 5) -> list[object]: ...
@@ -0,0 +1,113 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import TYPE_CHECKING, Any, ClassVar
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ if TYPE_CHECKING:
9
+ from elizaos.types.runtime import IAgentRuntime
10
+
11
+
12
+ class ServiceTypeRegistry:
13
+ TRANSCRIPTION: ClassVar[str] = "transcription"
14
+ VIDEO: ClassVar[str] = "video"
15
+ BROWSER: ClassVar[str] = "browser"
16
+ PDF: ClassVar[str] = "pdf"
17
+ REMOTE_FILES: ClassVar[str] = "aws_s3"
18
+ WEB_SEARCH: ClassVar[str] = "web_search"
19
+ EMAIL: ClassVar[str] = "email"
20
+ TEE: ClassVar[str] = "tee"
21
+ TASK: ClassVar[str] = "task"
22
+ WALLET: ClassVar[str] = "wallet"
23
+ LP_POOL: ClassVar[str] = "lp_pool"
24
+ TOKEN_DATA: ClassVar[str] = "token_data"
25
+ MESSAGE_SERVICE: ClassVar[str] = "message_service"
26
+ MESSAGE: ClassVar[str] = "message"
27
+ POST: ClassVar[str] = "post"
28
+ HOOKS: ClassVar[str] = "hooks"
29
+ UNKNOWN: ClassVar[str] = "unknown"
30
+
31
+
32
+ # Type for service names
33
+ ServiceTypeName = str
34
+
35
+
36
+ class ServiceType:
37
+ TRANSCRIPTION = ServiceTypeRegistry.TRANSCRIPTION
38
+ VIDEO = ServiceTypeRegistry.VIDEO
39
+ BROWSER = ServiceTypeRegistry.BROWSER
40
+ PDF = ServiceTypeRegistry.PDF
41
+ REMOTE_FILES = ServiceTypeRegistry.REMOTE_FILES
42
+ WEB_SEARCH = ServiceTypeRegistry.WEB_SEARCH
43
+ EMAIL = ServiceTypeRegistry.EMAIL
44
+ TEE = ServiceTypeRegistry.TEE
45
+ TASK = ServiceTypeRegistry.TASK
46
+ WALLET = ServiceTypeRegistry.WALLET
47
+ LP_POOL = ServiceTypeRegistry.LP_POOL
48
+ TOKEN_DATA = ServiceTypeRegistry.TOKEN_DATA
49
+ MESSAGE_SERVICE = ServiceTypeRegistry.MESSAGE_SERVICE
50
+ MESSAGE = ServiceTypeRegistry.MESSAGE
51
+ POST = ServiceTypeRegistry.POST
52
+ HOOKS = ServiceTypeRegistry.HOOKS
53
+ UNKNOWN = ServiceTypeRegistry.UNKNOWN
54
+
55
+
56
+ class Service(ABC):
57
+ service_type: ClassVar[str] = ServiceType.UNKNOWN
58
+
59
+ def __init__(self, runtime: IAgentRuntime | None = None) -> None:
60
+ self._runtime = runtime
61
+ self._config: object | None = None
62
+
63
+ @property
64
+ def runtime(self) -> IAgentRuntime:
65
+ if self._runtime is None:
66
+ raise RuntimeError("Service runtime not set")
67
+ return self._runtime
68
+
69
+ @runtime.setter
70
+ def runtime(self, value: IAgentRuntime) -> None:
71
+ self._runtime = value
72
+
73
+ @property
74
+ def config(self) -> object | None:
75
+ return self._config
76
+
77
+ @config.setter
78
+ def config(self, value: object | None) -> None:
79
+ self._config = value
80
+
81
+ @property
82
+ @abstractmethod
83
+ def capability_description(self) -> str: ...
84
+
85
+ @abstractmethod
86
+ async def stop(self) -> None: ...
87
+
88
+ @classmethod
89
+ async def start(cls, runtime: IAgentRuntime) -> Service:
90
+ raise NotImplementedError("Subclasses must implement start()")
91
+
92
+ @classmethod
93
+ def register_send_handlers(cls, runtime: IAgentRuntime, service: Service) -> None:
94
+ _ = runtime, service
95
+
96
+
97
+ class ServiceError(BaseModel):
98
+ """Standardized service error type for consistent error handling."""
99
+
100
+ code: str = Field(..., description="Error code")
101
+ message: str = Field(..., description="Error message")
102
+ details: dict[str, Any] | str | int | float | bool | None = Field(
103
+ default=None, description="Additional error details"
104
+ )
105
+ cause: Exception | None = Field(default=None, description="Cause of the error")
106
+
107
+ model_config = {"arbitrary_types_allowed": True}
108
+
109
+
110
+ def create_service_error(error: Exception | str | Any, code: str = "UNKNOWN_ERROR") -> ServiceError:
111
+ if isinstance(error, Exception):
112
+ return ServiceError(code=code, message=str(error), cause=error)
113
+ return ServiceError(code=code, message=str(error))