@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,244 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC
4
+ from dataclasses import dataclass, field
5
+ from typing import Any
6
+
7
+ from elizaos.types.generated.eliza.v1 import service_interfaces_pb2
8
+
9
+ TokenBalance = service_interfaces_pb2.TokenBalance
10
+ TokenData = service_interfaces_pb2.TokenData
11
+ WalletAsset = service_interfaces_pb2.WalletAsset
12
+ WalletPortfolio = service_interfaces_pb2.WalletPortfolio
13
+ PoolTokenInfo = service_interfaces_pb2.PoolTokenInfo
14
+ PoolInfo = service_interfaces_pb2.PoolInfo
15
+ LpPositionDetails = service_interfaces_pb2.LpPositionDetails
16
+ TransactionResult = service_interfaces_pb2.TransactionResult
17
+ TranscriptionOptions = service_interfaces_pb2.TranscriptionOptions
18
+ TranscriptionSegment = service_interfaces_pb2.TranscriptionSegment
19
+ TranscriptionWord = service_interfaces_pb2.TranscriptionWord
20
+ TranscriptionResult = service_interfaces_pb2.TranscriptionResult
21
+ SpeechToTextOptions = service_interfaces_pb2.SpeechToTextOptions
22
+ TextToSpeechOptions = service_interfaces_pb2.TextToSpeechOptions
23
+ VideoFormat = service_interfaces_pb2.VideoFormat
24
+ VideoInfo = service_interfaces_pb2.VideoInfo
25
+ VideoDownloadOptions = service_interfaces_pb2.VideoDownloadOptions
26
+ VideoProcessingOptions = service_interfaces_pb2.VideoProcessingOptions
27
+ BrowserViewport = service_interfaces_pb2.BrowserViewport
28
+ BrowserNavigationOptions = service_interfaces_pb2.BrowserNavigationOptions
29
+ ScreenshotClip = service_interfaces_pb2.ScreenshotClip
30
+ ScreenshotOptions = service_interfaces_pb2.ScreenshotOptions
31
+ ElementSelector = service_interfaces_pb2.ElementSelector
32
+ ExtractedLink = service_interfaces_pb2.LinkInfo
33
+ ExtractedImage = service_interfaces_pb2.ImageInfo
34
+ ExtractedContent = service_interfaces_pb2.ExtractedContent
35
+ ClickOptions = service_interfaces_pb2.ClickOptions
36
+ TypeOptions = service_interfaces_pb2.TypeOptions
37
+ PdfMetadata = service_interfaces_pb2.PdfMetadata
38
+ PdfExtractionResult = service_interfaces_pb2.PdfExtractionResult
39
+ PdfMargins = service_interfaces_pb2.PdfMargins
40
+ PdfGenerationOptions = service_interfaces_pb2.PdfGenerationOptions
41
+ PdfConversionOptions = service_interfaces_pb2.PdfConversionOptions
42
+ SearchDateRange = service_interfaces_pb2.DateRange
43
+ WebSearchBaseOptions = service_interfaces_pb2.SearchOptions
44
+ SearchResult = service_interfaces_pb2.SearchResult
45
+ SearchResponse = service_interfaces_pb2.SearchResponse
46
+ NewsSearchOptions = service_interfaces_pb2.NewsSearchOptions
47
+ ImageSearchOptions = service_interfaces_pb2.ImageSearchOptions
48
+ VideoSearchOptions = service_interfaces_pb2.VideoSearchOptions
49
+ EmailAddress = service_interfaces_pb2.EmailAddress
50
+ EmailAttachment = service_interfaces_pb2.EmailAttachment
51
+ EmailMessage = service_interfaces_pb2.EmailMessage
52
+ EmailSendOptions = service_interfaces_pb2.EmailSendOptions
53
+ EmailSearchOptions = service_interfaces_pb2.EmailSearchOptions
54
+ EmailFolder = service_interfaces_pb2.EmailFolder
55
+ EmailAccount = service_interfaces_pb2.EmailAccount
56
+ MessageParticipant = service_interfaces_pb2.MessageParticipant
57
+ MessageAttachment = service_interfaces_pb2.MessageAttachment
58
+ MessageReaction = service_interfaces_pb2.MessageReaction
59
+ MessageReference = service_interfaces_pb2.MessageReference
60
+ EmbedField = service_interfaces_pb2.EmbedField
61
+ MessageEmbed = service_interfaces_pb2.MessageEmbed
62
+ MessageContent = service_interfaces_pb2.MessageContent
63
+ MessageThread = service_interfaces_pb2.MessageThreadInfo
64
+ MessageInfo = service_interfaces_pb2.MessageInfo
65
+ MessageSendOptions = service_interfaces_pb2.MessageSendOptions
66
+ MessageSearchOptions = service_interfaces_pb2.MessageSearchOptions
67
+ ChannelPermissions = service_interfaces_pb2.ChannelPermissions
68
+ MessageChannel = service_interfaces_pb2.MessageChannel
69
+ PostMedia = service_interfaces_pb2.PostMedia
70
+ PostLocation = service_interfaces_pb2.PostLocation
71
+ PostAuthor = service_interfaces_pb2.PostAuthor
72
+ PostEngagement = service_interfaces_pb2.PostEngagement
73
+ PostLinkPreview = service_interfaces_pb2.PostLinkPreview
74
+ PollOption = service_interfaces_pb2.PostPollOption
75
+ PostPoll = service_interfaces_pb2.PostPoll
76
+ PostContent = service_interfaces_pb2.PostContent
77
+ PostThread = service_interfaces_pb2.PostThreadInfo
78
+ CrossPostedInfo = service_interfaces_pb2.CrossPostInfo
79
+ PostInfo = service_interfaces_pb2.PostInfo
80
+ PostCreateOptions = service_interfaces_pb2.PostCreateOptions
81
+ PostSearchOptions = service_interfaces_pb2.PostSearchOptions
82
+ DemographicsData = service_interfaces_pb2.Demographics
83
+ PerformingHour = service_interfaces_pb2.TopPerformingHour
84
+ PostAnalytics = service_interfaces_pb2.PostAnalytics
85
+
86
+
87
+ # Types not in protobuf - define as dataclasses
88
+ @dataclass
89
+ class VoiceInfo:
90
+ """Voice information for text-to-speech."""
91
+
92
+ voice_id: str
93
+ name: str
94
+ language: str | None = None
95
+ gender: str | None = None
96
+ provider: str | None = None
97
+ metadata: dict[str, Any] = field(default_factory=dict)
98
+
99
+
100
+ @dataclass
101
+ class PageInfo:
102
+ """Pagination information for search results."""
103
+
104
+ page: int = 1
105
+ per_page: int = 10
106
+ total: int = 0
107
+ has_more: bool = False
108
+
109
+
110
+ class ITokenDataService(ABC):
111
+ """Runtime service interface (implementation-specific)."""
112
+
113
+
114
+ class IWalletService(ABC):
115
+ """Runtime service interface (implementation-specific)."""
116
+
117
+
118
+ class ILpService(ABC):
119
+ """Runtime service interface (implementation-specific)."""
120
+
121
+
122
+ class ITranscriptionService(ABC):
123
+ """Runtime service interface (implementation-specific)."""
124
+
125
+
126
+ class IVideoService(ABC):
127
+ """Runtime service interface (implementation-specific)."""
128
+
129
+
130
+ class IBrowserService(ABC):
131
+ """Runtime service interface (implementation-specific)."""
132
+
133
+
134
+ class IPdfService(ABC):
135
+ """Runtime service interface (implementation-specific)."""
136
+
137
+
138
+ class IWebSearchService(ABC):
139
+ """Runtime service interface (implementation-specific)."""
140
+
141
+
142
+ class IEmailService(ABC):
143
+ """Runtime service interface (implementation-specific)."""
144
+
145
+
146
+ class IMessagingService(ABC):
147
+ """Runtime service interface (implementation-specific)."""
148
+
149
+
150
+ class IPostService(ABC):
151
+ """Runtime service interface (implementation-specific)."""
152
+
153
+
154
+ __all__ = [
155
+ "TokenBalance",
156
+ "TokenData",
157
+ "WalletAsset",
158
+ "WalletPortfolio",
159
+ "PoolTokenInfo",
160
+ "PoolInfo",
161
+ "LpPositionDetails",
162
+ "TransactionResult",
163
+ "TranscriptionOptions",
164
+ "TranscriptionSegment",
165
+ "TranscriptionWord",
166
+ "TranscriptionResult",
167
+ "SpeechToTextOptions",
168
+ "TextToSpeechOptions",
169
+ "VoiceInfo",
170
+ "VideoFormat",
171
+ "VideoInfo",
172
+ "VideoDownloadOptions",
173
+ "VideoProcessingOptions",
174
+ "BrowserViewport",
175
+ "BrowserNavigationOptions",
176
+ "ScreenshotClip",
177
+ "ScreenshotOptions",
178
+ "ElementSelector",
179
+ "ExtractedLink",
180
+ "ExtractedImage",
181
+ "ExtractedContent",
182
+ "ClickOptions",
183
+ "TypeOptions",
184
+ "PdfMetadata",
185
+ "PdfExtractionResult",
186
+ "PdfMargins",
187
+ "PdfGenerationOptions",
188
+ "PdfConversionOptions",
189
+ "SearchDateRange",
190
+ "WebSearchBaseOptions",
191
+ "SearchResult",
192
+ "SearchResponse",
193
+ "NewsSearchOptions",
194
+ "ImageSearchOptions",
195
+ "VideoSearchOptions",
196
+ "PageInfo",
197
+ "EmailAddress",
198
+ "EmailAttachment",
199
+ "EmailMessage",
200
+ "EmailSendOptions",
201
+ "EmailSearchOptions",
202
+ "EmailFolder",
203
+ "EmailAccount",
204
+ "MessageParticipant",
205
+ "MessageAttachment",
206
+ "MessageReaction",
207
+ "MessageReference",
208
+ "EmbedField",
209
+ "MessageEmbed",
210
+ "MessageContent",
211
+ "MessageThread",
212
+ "MessageInfo",
213
+ "MessageSendOptions",
214
+ "MessageSearchOptions",
215
+ "ChannelPermissions",
216
+ "MessageChannel",
217
+ "PostMedia",
218
+ "PostLocation",
219
+ "PostAuthor",
220
+ "PostEngagement",
221
+ "PostLinkPreview",
222
+ "PollOption",
223
+ "PostPoll",
224
+ "PostContent",
225
+ "PostThread",
226
+ "CrossPostedInfo",
227
+ "PostInfo",
228
+ "PostCreateOptions",
229
+ "PostSearchOptions",
230
+ "DemographicsData",
231
+ "PerformingHour",
232
+ "PostAnalytics",
233
+ "ITokenDataService",
234
+ "IWalletService",
235
+ "ILpService",
236
+ "ITranscriptionService",
237
+ "IVideoService",
238
+ "IBrowserService",
239
+ "IPdfService",
240
+ "IWebSearchService",
241
+ "IEmailService",
242
+ "IMessagingService",
243
+ "IPostService",
244
+ ]
@@ -0,0 +1,188 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from dataclasses import dataclass, field
5
+ from enum import Enum
6
+
7
+ from elizaos.types.generated.eliza.v1 import state_pb2
8
+
9
+ ActionPlanStep = state_pb2.ActionPlanStep
10
+ ActionPlan = state_pb2.ActionPlan
11
+ ProviderCacheEntry = state_pb2.ProviderCacheEntry
12
+ WorkingMemoryItem = state_pb2.WorkingMemoryItem
13
+ StateData = state_pb2.StateData
14
+ StateValues = state_pb2.StateValues
15
+ State = state_pb2.State
16
+
17
+
18
+ # ============================================================================
19
+ # Dynamic Prompt Execution Types
20
+ # ============================================================================
21
+
22
+
23
+ @dataclass
24
+ class SchemaRow:
25
+ """Schema row for dynamic prompt execution.
26
+
27
+ WHY: dynamic_prompt_exec_from_state generates structured prompts that ask the LLM
28
+ to output specific fields. Each SchemaRow defines one field the LLM must produce.
29
+ The schema also controls validation behavior for streaming scenarios.
30
+
31
+ Example:
32
+ schema = [
33
+ SchemaRow("thought", "Your internal reasoning"),
34
+ SchemaRow("text", "Response to user", required=True),
35
+ SchemaRow("actions", "Actions to execute"),
36
+ ]
37
+ """
38
+
39
+ field: str
40
+ """Field name - will become an XML tag or JSON property"""
41
+
42
+ description: str
43
+ """Description shown to LLM - explains what to put in this field"""
44
+
45
+ required: bool = False
46
+ """If true, validation fails when field is empty/missing"""
47
+
48
+ validate_field: bool | None = None
49
+ """Control per-field validation codes for streaming (levels 0-1 only).
50
+
51
+ WHY: Validation codes are UUID snippets that surround each field. If the LLM
52
+ outputs the same code before and after a field, we know the context window
53
+ wasn't truncated mid-field. This trades off token usage for reliability.
54
+
55
+ Behavior by level:
56
+ - Level 0 (Trusted): default False. Set to True to opt-in to per-field codes.
57
+ - Level 1 (Progressive): default True. Set to False to opt-out of codes.
58
+ - Levels 2-3: ignored (uses checkpoint codes at start/end of response instead).
59
+ """
60
+
61
+ stream_field: bool | None = None
62
+ """Control whether this field's content is streamed to the consumer.
63
+
64
+ WHY: Not all fields should be shown to users in real-time:
65
+ - 'thought': Internal reasoning - might be verbose or confusing to show
66
+ - 'actions': System field for action routing - not user-visible
67
+ - 'text': The actual response - should definitely stream
68
+
69
+ Default: True for 'text' field, False for others.
70
+ """
71
+
72
+
73
+ @dataclass
74
+ class RetryBackoffConfig:
75
+ """Configuration for retry backoff timing.
76
+
77
+ WHY: When retries happen, immediate retries can:
78
+ - Overwhelm rate-limited APIs
79
+ - Hit transient failures repeatedly
80
+ - Waste resources on brief outages
81
+
82
+ Backoff gives the system time to recover between attempts.
83
+ """
84
+
85
+ initial_ms: int = 1000
86
+ """Initial delay in milliseconds before first retry. Default: 1000ms (1 second)"""
87
+
88
+ multiplier: float = 2.0
89
+ """Multiplier for exponential backoff. delay = initial_ms * multiplier^(retry_count - 1). Default: 2"""
90
+
91
+ max_ms: int = 30000
92
+ """Maximum delay in milliseconds. Caps exponential growth. Default: 30000ms (30 seconds)"""
93
+
94
+ def delay_for_retry(self, retry_count: int) -> int:
95
+ """Calculate the delay for a given retry attempt (1-indexed)."""
96
+ delay = self.initial_ms * (self.multiplier ** (retry_count - 1))
97
+ return min(int(delay), self.max_ms)
98
+
99
+
100
+ class StreamEventType(str, Enum):
101
+ """Stream event types for validation-aware streaming.
102
+
103
+ Rich consumers receive these typed events for custom UX handling.
104
+ """
105
+
106
+ CHUNK = "chunk"
107
+ """Regular content chunk being streamed"""
108
+
109
+ FIELD_VALIDATED = "field_validated"
110
+ """A field passed validation (level 1)"""
111
+
112
+ RETRY_START = "retry_start"
113
+ """Starting a retry attempt"""
114
+
115
+ ERROR = "error"
116
+ """Unrecoverable error occurred"""
117
+
118
+ COMPLETE = "complete"
119
+ """Successfully finished all validation"""
120
+
121
+
122
+ @dataclass
123
+ class StreamEvent:
124
+ """Rich stream event for sophisticated consumers.
125
+
126
+ WHY: Simple consumers just want text chunks. Advanced UIs want to know
127
+ about validation progress, retries, and errors to show appropriate UI
128
+ (spinners, clear partial content, error messages).
129
+ """
130
+
131
+ event_type: StreamEventType
132
+ """Event type"""
133
+
134
+ timestamp: int = field(default_factory=lambda: int(time.time() * 1000))
135
+ """Timestamp of the event (milliseconds since epoch)"""
136
+
137
+ field: str | None = None
138
+ """Field name (for chunk and field_validated events)"""
139
+
140
+ chunk: str | None = None
141
+ """Content chunk (for chunk events)"""
142
+
143
+ retry_count: int | None = None
144
+ """Retry attempt number (for retry_start events)"""
145
+
146
+ error: str | None = None
147
+ """Error message (for error events)"""
148
+
149
+ @classmethod
150
+ def chunk_event(cls, field: str, chunk: str) -> StreamEvent:
151
+ """Create a chunk event."""
152
+ return cls(event_type=StreamEventType.CHUNK, field=field, chunk=chunk)
153
+
154
+ @classmethod
155
+ def field_validated_event(cls, field: str) -> StreamEvent:
156
+ """Create a field_validated event."""
157
+ return cls(event_type=StreamEventType.FIELD_VALIDATED, field=field)
158
+
159
+ @classmethod
160
+ def retry_start_event(cls, retry_count: int) -> StreamEvent:
161
+ """Create a retry_start event."""
162
+ return cls(event_type=StreamEventType.RETRY_START, retry_count=retry_count)
163
+
164
+ @classmethod
165
+ def error_event(cls, message: str) -> StreamEvent:
166
+ """Create an error event."""
167
+ return cls(event_type=StreamEventType.ERROR, error=message)
168
+
169
+ @classmethod
170
+ def complete_event(cls) -> StreamEvent:
171
+ """Create a complete event."""
172
+ return cls(event_type=StreamEventType.COMPLETE)
173
+
174
+
175
+ __all__ = [
176
+ "ActionPlanStep",
177
+ "ActionPlan",
178
+ "ProviderCacheEntry",
179
+ "WorkingMemoryItem",
180
+ "StateData",
181
+ "StateValues",
182
+ "State",
183
+ # Dynamic prompt execution types
184
+ "SchemaRow",
185
+ "RetryBackoffConfig",
186
+ "StreamEventType",
187
+ "StreamEvent",
188
+ ]
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Awaitable
4
+ from typing import TYPE_CHECKING, Protocol, runtime_checkable
5
+
6
+ from elizaos.types.generated.eliza.v1 import task_pb2
7
+
8
+ if TYPE_CHECKING:
9
+ from elizaos.types.runtime import IAgentRuntime
10
+
11
+ Task = task_pb2.Task
12
+ TaskMetadata = task_pb2.TaskMetadata
13
+ TaskStatus = task_pb2.TaskStatus
14
+
15
+
16
+ # Runtime worker interface (not in proto)
17
+ @runtime_checkable
18
+ class TaskWorker(Protocol):
19
+ name: str
20
+
21
+ def __call__(
22
+ self,
23
+ runtime: IAgentRuntime,
24
+ params: dict[str, object],
25
+ task: Task,
26
+ ) -> Awaitable[None]: ...
27
+
28
+
29
+ __all__ = ["Task", "TaskMetadata", "TaskStatus", "TaskWorker"]
@@ -0,0 +1,108 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import re
5
+ import time
6
+ from collections.abc import Mapping
7
+
8
+ from google.protobuf.json_format import MessageToDict
9
+ from google.protobuf.message import Message
10
+
11
+ from elizaos.types.agent import TemplateType
12
+ from elizaos.types.state import State
13
+
14
+ # Re-export from spec_examples for convenience
15
+ from .spec_examples import convert_spec_examples
16
+
17
+ # Re-export streaming utilities for validation-aware streaming
18
+ from .streaming import (
19
+ MAX_CHUNK_SIZE,
20
+ ChunkSizeError,
21
+ ExtractorState,
22
+ FieldState,
23
+ IStreamExtractor,
24
+ MarkableExtractor,
25
+ ValidationDiagnosis,
26
+ ValidationStreamExtractor,
27
+ ValidationStreamExtractorConfig,
28
+ validate_chunk_size,
29
+ )
30
+
31
+ _TEMPLATE_TOKEN_RE = re.compile(r"\{\{\{?\s*([A-Za-z0-9_.-]+)\s*\}\}\}?")
32
+
33
+
34
+ def get_current_time_ms() -> int:
35
+ return int(time.time() * 1000)
36
+
37
+
38
+ def _to_dict(value: object) -> dict[str, object]:
39
+ if isinstance(value, Message):
40
+ return MessageToDict(value, preserving_proto_field_name=False)
41
+ if hasattr(value, "model_dump"):
42
+ return value.model_dump(by_alias=True)
43
+ if isinstance(value, Mapping):
44
+ return dict(value)
45
+ raise TypeError(f"Unsupported value type: {type(value).__name__}")
46
+
47
+
48
+ def _stringify_template_value(value: object) -> str:
49
+ if value is None:
50
+ return ""
51
+ if isinstance(value, bool):
52
+ return "true" if value else "false"
53
+ if isinstance(value, (int, float)):
54
+ return str(value)
55
+ if isinstance(value, str):
56
+ return value
57
+ if isinstance(value, (Message, Mapping)) or hasattr(value, "model_dump"):
58
+ return json.dumps(_to_dict(value), ensure_ascii=False)
59
+ if isinstance(value, list):
60
+ return "\n".join(_stringify_template_value(v) for v in value)
61
+ return str(value)
62
+
63
+
64
+ def _render_template(template_str: str, ctx: Mapping[str, object]) -> str:
65
+ def replacer(match: re.Match[str]) -> str:
66
+ key = match.group(1)
67
+ return _stringify_template_value(ctx.get(key))
68
+
69
+ return _TEMPLATE_TOKEN_RE.sub(replacer, template_str)
70
+
71
+
72
+ def compose_prompt(*, state: Mapping[str, str], template: TemplateType) -> str:
73
+ template_str = template({"state": state}) if callable(template) else template
74
+ return _render_template(template_str, state)
75
+
76
+
77
+ def compose_prompt_from_state(*, state: State, template: TemplateType) -> str:
78
+ template_str = template({"state": state}) if callable(template) else template
79
+
80
+ dumped = _to_dict(state)
81
+ values_raw = dumped.get("values")
82
+ values: dict[str, object] = values_raw if isinstance(values_raw, dict) else {}
83
+
84
+ ctx: dict[str, object] = {
85
+ k: v for k, v in dumped.items() if k not in ("text", "values", "data")
86
+ }
87
+ ctx.update(values)
88
+
89
+ return _render_template(template_str, ctx)
90
+
91
+
92
+ __all__ = [
93
+ "get_current_time_ms",
94
+ "compose_prompt",
95
+ "compose_prompt_from_state",
96
+ "convert_spec_examples",
97
+ # Streaming utilities
98
+ "ChunkSizeError",
99
+ "ExtractorState",
100
+ "FieldState",
101
+ "IStreamExtractor",
102
+ "MarkableExtractor",
103
+ "MAX_CHUNK_SIZE",
104
+ "validate_chunk_size",
105
+ "ValidationDiagnosis",
106
+ "ValidationStreamExtractor",
107
+ "ValidationStreamExtractorConfig",
108
+ ]
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import TYPE_CHECKING
5
+
6
+ from elizaos.types import ActionExample, Content
7
+
8
+ if TYPE_CHECKING:
9
+ from elizaos.generated.action_docs import ActionDoc
10
+
11
+
12
+ def _coerce_text(value: object) -> str:
13
+ return value if isinstance(value, str) else ""
14
+
15
+
16
+ def _coerce_actions(value: object) -> list[str] | None:
17
+ if isinstance(value, list) and all(isinstance(item, str) for item in value):
18
+ return list(value)
19
+ return None
20
+
21
+
22
+ def convert_spec_examples(spec: ActionDoc | Mapping[str, object]) -> list[list[ActionExample]]:
23
+ examples = spec.get("examples")
24
+ if not isinstance(examples, list):
25
+ return []
26
+ out: list[list[ActionExample]] = []
27
+ for example in examples:
28
+ if not isinstance(example, list):
29
+ continue
30
+ row: list[ActionExample] = []
31
+ for msg in example:
32
+ if not isinstance(msg, dict):
33
+ continue
34
+ content = msg.get("content")
35
+ text = ""
36
+ actions: list[str] | None = None
37
+ if isinstance(content, dict):
38
+ text = _coerce_text(content.get("text"))
39
+ actions = _coerce_actions(content.get("actions"))
40
+ row.append(
41
+ ActionExample(
42
+ name=str(msg.get("name") or ""),
43
+ content=Content(text=text, actions=actions),
44
+ )
45
+ )
46
+ if row:
47
+ out.append(row)
48
+ return out