@elizaos/python 2.0.0-alpha.3 → 2.0.0-alpha.30

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 (167) hide show
  1. package/elizaos/__init__.py +0 -1
  2. package/elizaos/advanced_capabilities/__init__.py +6 -41
  3. package/elizaos/advanced_capabilities/actions/__init__.py +1 -21
  4. package/elizaos/advanced_capabilities/actions/add_contact.py +24 -13
  5. package/elizaos/advanced_capabilities/actions/follow_room.py +29 -29
  6. package/elizaos/advanced_capabilities/actions/image_generation.py +15 -28
  7. package/elizaos/advanced_capabilities/actions/mute_room.py +15 -28
  8. package/elizaos/advanced_capabilities/actions/remove_contact.py +17 -3
  9. package/elizaos/advanced_capabilities/actions/roles.py +17 -30
  10. package/elizaos/advanced_capabilities/actions/schedule_follow_up.py +70 -15
  11. package/elizaos/advanced_capabilities/actions/search_contacts.py +17 -3
  12. package/elizaos/advanced_capabilities/actions/send_message.py +184 -51
  13. package/elizaos/advanced_capabilities/actions/settings.py +17 -3
  14. package/elizaos/advanced_capabilities/actions/unfollow_room.py +15 -28
  15. package/elizaos/advanced_capabilities/actions/unmute_room.py +15 -28
  16. package/elizaos/advanced_capabilities/actions/update_contact.py +17 -3
  17. package/elizaos/advanced_capabilities/actions/update_entity.py +17 -3
  18. package/elizaos/advanced_capabilities/evaluators/__init__.py +2 -9
  19. package/elizaos/advanced_capabilities/evaluators/reflection.py +3 -132
  20. package/elizaos/advanced_capabilities/evaluators/relationship_extraction.py +5 -201
  21. package/elizaos/advanced_capabilities/providers/__init__.py +1 -12
  22. package/elizaos/advanced_capabilities/providers/knowledge.py +23 -3
  23. package/elizaos/advanced_capabilities/services/__init__.py +2 -9
  24. package/elizaos/advanced_capabilities/services/rolodex.py +2 -2
  25. package/elizaos/advanced_memory/actions/reset_session.py +143 -0
  26. package/elizaos/advanced_memory/evaluators/reflection.py +134 -0
  27. package/elizaos/advanced_memory/evaluators/relationship_extraction.py +203 -0
  28. package/elizaos/advanced_memory/memory_service.py +69 -27
  29. package/elizaos/advanced_memory/plugin.py +2 -1
  30. package/elizaos/advanced_memory/test_advanced_memory.py +357 -0
  31. package/elizaos/advanced_memory/types.py +2 -2
  32. package/elizaos/advanced_planning/actions/schedule_follow_up.py +222 -0
  33. package/elizaos/advanced_planning/planning_service.py +26 -14
  34. package/elizaos/basic_capabilities/__init__.py +0 -2
  35. package/elizaos/basic_capabilities/providers/__init__.py +0 -3
  36. package/elizaos/basic_capabilities/providers/actions.py +118 -29
  37. package/elizaos/basic_capabilities/providers/agent_settings.py +64 -0
  38. package/elizaos/basic_capabilities/providers/character.py +19 -21
  39. package/elizaos/basic_capabilities/providers/contacts.py +79 -0
  40. package/elizaos/basic_capabilities/providers/current_time.py +7 -4
  41. package/elizaos/basic_capabilities/providers/facts.py +87 -0
  42. package/elizaos/basic_capabilities/providers/follow_ups.py +117 -0
  43. package/elizaos/basic_capabilities/providers/knowledge.py +96 -0
  44. package/elizaos/basic_capabilities/providers/recent_messages.py +5 -0
  45. package/elizaos/basic_capabilities/providers/relationships.py +113 -0
  46. package/elizaos/basic_capabilities/providers/roles.py +96 -0
  47. package/elizaos/basic_capabilities/providers/settings.py +56 -0
  48. package/elizaos/basic_capabilities/providers/time.py +7 -4
  49. package/elizaos/basic_capabilities/services/embedding.py +10 -7
  50. package/elizaos/basic_capabilities/services/task.py +3 -3
  51. package/elizaos/bootstrap/__init__.py +21 -2
  52. package/elizaos/bootstrap/actions/__init__.py +3 -0
  53. package/elizaos/bootstrap/actions/reset_session.py +3 -0
  54. package/elizaos/bootstrap/actions/roles.py +5 -4
  55. package/elizaos/bootstrap/actions/schedule_follow_up.py +65 -7
  56. package/elizaos/bootstrap/actions/send_message.py +162 -15
  57. package/elizaos/bootstrap/autonomy/__init__.py +5 -1
  58. package/elizaos/bootstrap/autonomy/action.py +161 -0
  59. package/elizaos/bootstrap/autonomy/evaluators.py +217 -0
  60. package/elizaos/bootstrap/autonomy/service.py +238 -28
  61. package/elizaos/bootstrap/plugin.py +7 -0
  62. package/elizaos/bootstrap/providers/actions.py +118 -27
  63. package/elizaos/bootstrap/providers/agent_settings.py +1 -0
  64. package/elizaos/bootstrap/providers/attachments.py +1 -0
  65. package/elizaos/bootstrap/providers/capabilities.py +1 -0
  66. package/elizaos/bootstrap/providers/character.py +1 -0
  67. package/elizaos/bootstrap/providers/choice.py +1 -0
  68. package/elizaos/bootstrap/providers/contacts.py +1 -0
  69. package/elizaos/bootstrap/providers/current_time.py +8 -2
  70. package/elizaos/bootstrap/providers/entities.py +1 -0
  71. package/elizaos/bootstrap/providers/evaluators.py +1 -0
  72. package/elizaos/bootstrap/providers/facts.py +1 -0
  73. package/elizaos/bootstrap/providers/follow_ups.py +1 -0
  74. package/elizaos/bootstrap/providers/knowledge.py +26 -3
  75. package/elizaos/bootstrap/providers/providers_list.py +1 -0
  76. package/elizaos/bootstrap/providers/recent_messages.py +5 -0
  77. package/elizaos/bootstrap/providers/relationships.py +20 -13
  78. package/elizaos/bootstrap/providers/roles.py +1 -0
  79. package/elizaos/bootstrap/providers/settings.py +1 -0
  80. package/elizaos/bootstrap/providers/time.py +8 -4
  81. package/elizaos/bootstrap/providers/world.py +1 -0
  82. package/elizaos/bootstrap/services/embedding.py +206 -8
  83. package/elizaos/bootstrap/services/rolodex.py +2 -2
  84. package/elizaos/bootstrap/services/task.py +3 -3
  85. package/elizaos/deterministic.py +193 -0
  86. package/elizaos/generated/__init__.py +1 -0
  87. package/elizaos/generated/action_docs.py +3181 -0
  88. package/elizaos/generated/spec_helpers.py +175 -0
  89. package/elizaos/media/mime.py +4 -4
  90. package/elizaos/media/search.py +23 -23
  91. package/elizaos/runtime.py +223 -64
  92. package/elizaos/services/hook_service.py +3 -3
  93. package/elizaos/services/message_service.py +175 -29
  94. package/elizaos/types/components.py +2 -2
  95. package/elizaos/types/generated/__init__.py +12 -0
  96. package/elizaos/types/generated/eliza/v1/agent_pb2.py +63 -0
  97. package/elizaos/types/generated/eliza/v1/agent_pb2.pyi +159 -0
  98. package/elizaos/types/generated/eliza/v1/components_pb2.py +65 -0
  99. package/elizaos/types/generated/eliza/v1/components_pb2.pyi +160 -0
  100. package/elizaos/types/generated/eliza/v1/database_pb2.py +78 -0
  101. package/elizaos/types/generated/eliza/v1/database_pb2.pyi +305 -0
  102. package/elizaos/types/generated/eliza/v1/environment_pb2.py +58 -0
  103. package/elizaos/types/generated/eliza/v1/environment_pb2.pyi +135 -0
  104. package/elizaos/types/generated/eliza/v1/events_pb2.py +82 -0
  105. package/elizaos/types/generated/eliza/v1/events_pb2.pyi +322 -0
  106. package/elizaos/types/generated/eliza/v1/ipc_pb2.py +113 -0
  107. package/elizaos/types/generated/eliza/v1/ipc_pb2.pyi +367 -0
  108. package/elizaos/types/generated/eliza/v1/knowledge_pb2.py +41 -0
  109. package/elizaos/types/generated/eliza/v1/knowledge_pb2.pyi +26 -0
  110. package/elizaos/types/generated/eliza/v1/memory_pb2.py +55 -0
  111. package/elizaos/types/generated/eliza/v1/memory_pb2.pyi +111 -0
  112. package/elizaos/types/generated/eliza/v1/message_service_pb2.py +48 -0
  113. package/elizaos/types/generated/eliza/v1/message_service_pb2.pyi +69 -0
  114. package/elizaos/types/generated/eliza/v1/messaging_pb2.py +51 -0
  115. package/elizaos/types/generated/eliza/v1/messaging_pb2.pyi +97 -0
  116. package/elizaos/types/generated/eliza/v1/model_pb2.py +84 -0
  117. package/elizaos/types/generated/eliza/v1/model_pb2.pyi +280 -0
  118. package/elizaos/types/generated/eliza/v1/payment_pb2.py +44 -0
  119. package/elizaos/types/generated/eliza/v1/payment_pb2.pyi +70 -0
  120. package/elizaos/types/generated/eliza/v1/plugin_pb2.py +68 -0
  121. package/elizaos/types/generated/eliza/v1/plugin_pb2.pyi +145 -0
  122. package/elizaos/types/generated/eliza/v1/primitives_pb2.py +48 -0
  123. package/elizaos/types/generated/eliza/v1/primitives_pb2.pyi +92 -0
  124. package/elizaos/types/generated/eliza/v1/prompts_pb2.py +52 -0
  125. package/elizaos/types/generated/eliza/v1/prompts_pb2.pyi +74 -0
  126. package/elizaos/types/generated/eliza/v1/service_interfaces_pb2.py +211 -0
  127. package/elizaos/types/generated/eliza/v1/service_interfaces_pb2.pyi +1296 -0
  128. package/elizaos/types/generated/eliza/v1/service_pb2.py +42 -0
  129. package/elizaos/types/generated/eliza/v1/service_pb2.pyi +69 -0
  130. package/elizaos/types/generated/eliza/v1/settings_pb2.py +58 -0
  131. package/elizaos/types/generated/eliza/v1/settings_pb2.pyi +85 -0
  132. package/elizaos/types/generated/eliza/v1/state_pb2.py +60 -0
  133. package/elizaos/types/generated/eliza/v1/state_pb2.pyi +114 -0
  134. package/elizaos/types/generated/eliza/v1/task_pb2.py +42 -0
  135. package/elizaos/types/generated/eliza/v1/task_pb2.pyi +58 -0
  136. package/elizaos/types/generated/eliza/v1/tee_pb2.py +52 -0
  137. package/elizaos/types/generated/eliza/v1/tee_pb2.pyi +90 -0
  138. package/elizaos/types/generated/eliza/v1/testing_pb2.py +39 -0
  139. package/elizaos/types/generated/eliza/v1/testing_pb2.pyi +23 -0
  140. package/elizaos/types/model.py +33 -3
  141. package/elizaos/types/primitives.py +3 -3
  142. package/elizaos/types/runtime.py +17 -3
  143. package/elizaos/types/state.py +2 -2
  144. package/elizaos/utils/streaming.py +3 -3
  145. package/elizaos/utils/validation.py +76 -0
  146. package/package.json +4 -3
  147. package/pyproject.toml +1 -2
  148. package/requirements-dev.lock +2 -2
  149. package/requirements.in +1 -2
  150. package/requirements.lock +2 -2
  151. package/tests/test_action_parameters.py +2 -3
  152. package/tests/test_actions_provider_examples.py +58 -1
  153. package/tests/test_advanced_memory_behavior.py +0 -2
  154. package/tests/test_advanced_memory_flag.py +0 -2
  155. package/tests/test_advanced_planning_behavior.py +11 -5
  156. package/tests/test_async_embedding.py +124 -0
  157. package/tests/test_autonomy.py +24 -3
  158. package/tests/test_history_compaction.py +104 -0
  159. package/tests/test_memory_bounds.py +115 -0
  160. package/tests/test_runtime.py +8 -17
  161. package/tests/test_schedule_follow_up_action.py +260 -0
  162. package/tests/test_send_message_action_targets.py +114 -0
  163. package/tests/test_settings_crypto.py +0 -2
  164. package/tests/test_validation.py +141 -0
  165. package/tests/verify_memory_architecture.py +192 -0
  166. package/uv.lock +1565 -0
  167. package/elizaos/basic_capabilities/providers/capabilities.py +0 -62
@@ -0,0 +1,90 @@
1
+ from google.protobuf import struct_pb2 as _struct_pb2
2
+ from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
3
+ from google.protobuf import descriptor as _descriptor
4
+ from google.protobuf import message as _message
5
+ from collections.abc import Mapping as _Mapping
6
+ from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
7
+
8
+ DESCRIPTOR: _descriptor.FileDescriptor
9
+
10
+ class TEEMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
11
+ __slots__ = ()
12
+ TEE_MODE_UNSPECIFIED: _ClassVar[TEEMode]
13
+ TEE_MODE_OFF: _ClassVar[TEEMode]
14
+ TEE_MODE_LOCAL: _ClassVar[TEEMode]
15
+ TEE_MODE_DOCKER: _ClassVar[TEEMode]
16
+ TEE_MODE_PRODUCTION: _ClassVar[TEEMode]
17
+
18
+ class TeeType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
19
+ __slots__ = ()
20
+ TEE_TYPE_UNSPECIFIED: _ClassVar[TeeType]
21
+ TEE_TYPE_TDX_DSTACK: _ClassVar[TeeType]
22
+ TEE_MODE_UNSPECIFIED: TEEMode
23
+ TEE_MODE_OFF: TEEMode
24
+ TEE_MODE_LOCAL: TEEMode
25
+ TEE_MODE_DOCKER: TEEMode
26
+ TEE_MODE_PRODUCTION: TEEMode
27
+ TEE_TYPE_UNSPECIFIED: TeeType
28
+ TEE_TYPE_TDX_DSTACK: TeeType
29
+
30
+ class TeeAgent(_message.Message):
31
+ __slots__ = ("id", "agent_id", "agent_name", "created_at", "public_key", "attestation")
32
+ ID_FIELD_NUMBER: _ClassVar[int]
33
+ AGENT_ID_FIELD_NUMBER: _ClassVar[int]
34
+ AGENT_NAME_FIELD_NUMBER: _ClassVar[int]
35
+ CREATED_AT_FIELD_NUMBER: _ClassVar[int]
36
+ PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int]
37
+ ATTESTATION_FIELD_NUMBER: _ClassVar[int]
38
+ id: str
39
+ agent_id: str
40
+ agent_name: str
41
+ created_at: int
42
+ public_key: str
43
+ attestation: str
44
+ def __init__(self, id: _Optional[str] = ..., agent_id: _Optional[str] = ..., agent_name: _Optional[str] = ..., created_at: _Optional[int] = ..., public_key: _Optional[str] = ..., attestation: _Optional[str] = ...) -> None: ...
45
+
46
+ class RemoteAttestationQuote(_message.Message):
47
+ __slots__ = ("quote", "timestamp")
48
+ QUOTE_FIELD_NUMBER: _ClassVar[int]
49
+ TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
50
+ quote: str
51
+ timestamp: int
52
+ def __init__(self, quote: _Optional[str] = ..., timestamp: _Optional[int] = ...) -> None: ...
53
+
54
+ class DeriveKeyAttestationData(_message.Message):
55
+ __slots__ = ("agent_id", "public_key", "subject")
56
+ AGENT_ID_FIELD_NUMBER: _ClassVar[int]
57
+ PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int]
58
+ SUBJECT_FIELD_NUMBER: _ClassVar[int]
59
+ agent_id: str
60
+ public_key: str
61
+ subject: str
62
+ def __init__(self, agent_id: _Optional[str] = ..., public_key: _Optional[str] = ..., subject: _Optional[str] = ...) -> None: ...
63
+
64
+ class AttestedMessage(_message.Message):
65
+ __slots__ = ("entity_id", "room_id", "content")
66
+ ENTITY_ID_FIELD_NUMBER: _ClassVar[int]
67
+ ROOM_ID_FIELD_NUMBER: _ClassVar[int]
68
+ CONTENT_FIELD_NUMBER: _ClassVar[int]
69
+ entity_id: str
70
+ room_id: str
71
+ content: str
72
+ def __init__(self, entity_id: _Optional[str] = ..., room_id: _Optional[str] = ..., content: _Optional[str] = ...) -> None: ...
73
+
74
+ class RemoteAttestationMessage(_message.Message):
75
+ __slots__ = ("agent_id", "timestamp", "message")
76
+ AGENT_ID_FIELD_NUMBER: _ClassVar[int]
77
+ TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
78
+ MESSAGE_FIELD_NUMBER: _ClassVar[int]
79
+ agent_id: str
80
+ timestamp: int
81
+ message: AttestedMessage
82
+ def __init__(self, agent_id: _Optional[str] = ..., timestamp: _Optional[int] = ..., message: _Optional[_Union[AttestedMessage, _Mapping]] = ...) -> None: ...
83
+
84
+ class TeePluginConfig(_message.Message):
85
+ __slots__ = ("vendor", "vendor_config")
86
+ VENDOR_FIELD_NUMBER: _ClassVar[int]
87
+ VENDOR_CONFIG_FIELD_NUMBER: _ClassVar[int]
88
+ vendor: str
89
+ vendor_config: _struct_pb2.Struct
90
+ def __init__(self, vendor: _Optional[str] = ..., vendor_config: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: eliza/v1/testing.proto
5
+ # Protobuf Python Version: 7.34.0
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 7,
15
+ 34,
16
+ 0,
17
+ '',
18
+ 'eliza/v1/testing.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x65liza/v1/testing.proto\x12\x08\x65liza.v1\"Q\n\x08TestCase\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\"\n\nhandler_id\x18\x02 \x01(\tH\x00R\thandlerId\x88\x01\x01\x42\r\n\x0b_handler_id\"I\n\tTestSuite\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12(\n\x05tests\x18\x02 \x03(\x0b\x32\x12.eliza.v1.TestCaseR\x05testsB\x8f\x01\n\x0c\x63om.eliza.v1B\x0cTestingProtoP\x01Z0github.com/elizaos/eliza/gen/go/eliza/v1;elizav1\xa2\x02\x03\x45XX\xaa\x02\x08\x45liza.V1\xca\x02\x08\x45liza\\V1\xe2\x02\x14\x45liza\\V1\\GPBMetadata\xea\x02\tEliza::V1b\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'eliza.v1.testing_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ _globals['DESCRIPTOR']._loaded_options = None
34
+ _globals['DESCRIPTOR']._serialized_options = b'\n\014com.eliza.v1B\014TestingProtoP\001Z0github.com/elizaos/eliza/gen/go/eliza/v1;elizav1\242\002\003EXX\252\002\010Eliza.V1\312\002\010Eliza\\V1\342\002\024Eliza\\V1\\GPBMetadata\352\002\tEliza::V1'
35
+ _globals['_TESTCASE']._serialized_start=36
36
+ _globals['_TESTCASE']._serialized_end=117
37
+ _globals['_TESTSUITE']._serialized_start=119
38
+ _globals['_TESTSUITE']._serialized_end=192
39
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,23 @@
1
+ from google.protobuf.internal import containers as _containers
2
+ from google.protobuf import descriptor as _descriptor
3
+ from google.protobuf import message as _message
4
+ from collections.abc import Iterable as _Iterable, Mapping as _Mapping
5
+ from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
6
+
7
+ DESCRIPTOR: _descriptor.FileDescriptor
8
+
9
+ class TestCase(_message.Message):
10
+ __slots__ = ("name", "handler_id")
11
+ NAME_FIELD_NUMBER: _ClassVar[int]
12
+ HANDLER_ID_FIELD_NUMBER: _ClassVar[int]
13
+ name: str
14
+ handler_id: str
15
+ def __init__(self, name: _Optional[str] = ..., handler_id: _Optional[str] = ...) -> None: ...
16
+
17
+ class TestSuite(_message.Message):
18
+ __slots__ = ("name", "tests")
19
+ NAME_FIELD_NUMBER: _ClassVar[int]
20
+ TESTS_FIELD_NUMBER: _ClassVar[int]
21
+ name: str
22
+ tests: _containers.RepeatedCompositeFieldContainer[TestCase]
23
+ def __init__(self, name: _Optional[str] = ..., tests: _Optional[_Iterable[_Union[TestCase, _Mapping]]] = ...) -> None: ...
@@ -1,19 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from collections.abc import Awaitable, Callable
4
- from enum import Enum
4
+ from enum import StrEnum
5
5
  from typing import TYPE_CHECKING, Any
6
6
 
7
7
  from pydantic import BaseModel, Field
8
8
 
9
+ if TYPE_CHECKING:
10
+ from elizaos.types.runtime import IAgentRuntime
11
+
9
12
 
10
- class LLMMode(str, Enum):
13
+ class LLMMode(StrEnum):
11
14
  DEFAULT = "DEFAULT"
12
15
  SMALL = "SMALL"
13
16
  LARGE = "LARGE"
14
17
 
15
18
 
16
- class ModelType(str, Enum):
19
+ class ModelType(StrEnum):
17
20
  # Text generation models
18
21
  TEXT_SMALL = "TEXT_SMALL"
19
22
  TEXT_LARGE = "TEXT_LARGE"
@@ -53,6 +56,9 @@ class ModelType(str, Enum):
53
56
  # Research models (deep research)
54
57
  RESEARCH = "RESEARCH"
55
58
 
59
+ # Safeguard models
60
+ SAFEGUARD = "SAFEGUARD"
61
+
56
62
 
57
63
  # Type for model type names - allows string for extensibility
58
64
  ModelTypeName = str
@@ -278,6 +284,30 @@ class ObjectGenerationParams(BaseModel):
278
284
  model_config = {"populate_by_name": True, "extra": "allow"}
279
285
 
280
286
 
287
+ # ============================================================================
288
+ # Safeguard Model Types
289
+ # ============================================================================
290
+
291
+
292
+ class SafeguardParams(BaseModel):
293
+ """Parameters for safeguard (content moderation) models."""
294
+
295
+ input: str = Field(..., description="Input text to classify")
296
+ model_type: str = Field(..., alias="modelType", description="Model type (must be SAFEGUARD)")
297
+
298
+ model_config = {"populate_by_name": True}
299
+
300
+
301
+ class SafeguardResult(BaseModel):
302
+ """Result from a safeguard model classification."""
303
+
304
+ violation: float = Field(..., description="Violation score (0-1)")
305
+ category: str | None = Field(default=None, description="Violation category if any")
306
+ rationale: str | None = Field(default=None, description="Rationale for the classification")
307
+
308
+ model_config = {"populate_by_name": True}
309
+
310
+
281
311
  # ============================================================================
282
312
  # Research Model Types (Deep Research)
283
313
  # ============================================================================
@@ -4,7 +4,7 @@ import hashlib
4
4
  import re
5
5
  import urllib.parse
6
6
  import uuid as uuid_module
7
- from enum import Enum
7
+ from enum import StrEnum
8
8
 
9
9
  from elizaos.types.generated.eliza.v1 import primitives_pb2
10
10
 
@@ -63,7 +63,7 @@ def string_to_uuid(target: str | int | uuid_module.UUID) -> str:
63
63
  return str(uuid_module.UUID(bytes=bytes(b)))
64
64
 
65
65
 
66
- class ChannelType(str, Enum):
66
+ class ChannelType(StrEnum):
67
67
  SELF = "SELF"
68
68
  DM = "DM"
69
69
  GROUP = "GROUP"
@@ -76,7 +76,7 @@ class ChannelType(str, Enum):
76
76
  API = "API"
77
77
 
78
78
 
79
- class ContentType(str, Enum):
79
+ class ContentType(StrEnum):
80
80
  IMAGE = "image"
81
81
  VIDEO = "video"
82
82
  AUDIO = "audio"
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any
7
7
  from pydantic import BaseModel, Field
8
8
 
9
9
  from elizaos.logger import Logger
10
- from elizaos.types.database import IDatabaseAdapter
10
+ from elizaos.types.database import IDatabaseAdapter, MemorySearchOptions
11
11
  from elizaos.types.primitives import UUID, Content
12
12
 
13
13
  if TYPE_CHECKING:
@@ -231,7 +231,7 @@ class IAgentRuntime(ABC):
231
231
  self,
232
232
  message: Memory,
233
233
  state: State | None = None,
234
- ) -> "PreEvaluatorResult": ...
234
+ ) -> PreEvaluatorResult: ...
235
235
 
236
236
  # Component registration
237
237
  @abstractmethod
@@ -287,6 +287,7 @@ class IAgentRuntime(ABC):
287
287
  include_list: list[str] | None = None,
288
288
  only_include: bool = False,
289
289
  skip_cache: bool = False,
290
+ trajectory_phase: str | None = None,
290
291
  ) -> State: ...
291
292
 
292
293
  # Model usage
@@ -418,11 +419,16 @@ class IAgentRuntime(ABC):
418
419
 
419
420
  # Convenience wrappers
420
421
  @abstractmethod
421
- async def get_entity_by_id(self, entity_id: UUID) -> Entity | None: ...
422
+ async def get_entity_by_id(self, entity_id: UUID | str) -> Entity | None: ...
422
423
 
423
424
  @abstractmethod
424
425
  async def get_entity(self, entity_id: UUID | str) -> Entity | None: ...
425
426
 
427
+ @abstractmethod
428
+ async def get_entities_for_room(
429
+ self, room_id: UUID, include_components: bool = False
430
+ ) -> list[Entity]: ...
431
+
426
432
  @abstractmethod
427
433
  async def update_entity(self, entity: Entity) -> None: ...
428
434
 
@@ -435,6 +441,9 @@ class IAgentRuntime(ABC):
435
441
  @abstractmethod
436
442
  async def create_room(self, room: Room) -> UUID: ...
437
443
 
444
+ @abstractmethod
445
+ async def update_room(self, room: Room) -> None: ...
446
+
438
447
  @abstractmethod
439
448
  async def add_participant(self, entity_id: UUID, room_id: UUID) -> bool: ...
440
449
 
@@ -456,5 +465,10 @@ class IAgentRuntime(ABC):
456
465
  @abstractmethod
457
466
  async def get_relationships(self, params: dict[str, object]) -> list[object]: ...
458
467
 
468
+ @abstractmethod
469
+ async def search_memories(
470
+ self, params: MemorySearchOptions | dict[str, Any]
471
+ ) -> list[Memory]: ...
472
+
459
473
  @abstractmethod
460
474
  async def search_knowledge(self, query: str, limit: int = 5) -> list[object]: ...
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import time
4
4
  from dataclasses import dataclass, field
5
- from enum import Enum
5
+ from enum import StrEnum
6
6
 
7
7
  from elizaos.types.generated.eliza.v1 import state_pb2
8
8
 
@@ -97,7 +97,7 @@ class RetryBackoffConfig:
97
97
  return min(int(delay), self.max_ms)
98
98
 
99
99
 
100
- class StreamEventType(str, Enum):
100
+ class StreamEventType(StrEnum):
101
101
  """Stream event types for validation-aware streaming.
102
102
 
103
103
  Rich consumers receive these typed events for custom UX handling.
@@ -16,7 +16,7 @@ code matches, we know that part wasn't truncated.
16
16
 
17
17
  from collections.abc import Callable
18
18
  from dataclasses import dataclass, field
19
- from enum import Enum
19
+ from enum import StrEnum
20
20
 
21
21
  from elizaos.types.state import SchemaRow, StreamEvent
22
22
 
@@ -109,7 +109,7 @@ class MarkableExtractor(IStreamExtractor):
109
109
  self._done = True
110
110
 
111
111
 
112
- class ExtractorState(str, Enum):
112
+ class ExtractorState(StrEnum):
113
113
  """Extractor state machine for validation-aware streaming."""
114
114
 
115
115
  STREAMING = "streaming" # Normal operation - actively receiving chunks
@@ -119,7 +119,7 @@ class ExtractorState(str, Enum):
119
119
  FAILED = "failed" # Unrecoverable error
120
120
 
121
121
 
122
- class FieldState(str, Enum):
122
+ class FieldState(StrEnum):
123
123
  """Per-field state tracking for progressive validation."""
124
124
 
125
125
  PENDING = "pending" # Haven't seen this field yet
@@ -0,0 +1,76 @@
1
+ import re
2
+
3
+ from elizaos.types.memory import Memory
4
+
5
+
6
+ def validate_action_keywords(
7
+ message: Memory, recent_messages: list[Memory], keywords: list[str]
8
+ ) -> bool:
9
+ """
10
+ Validates if any of the given keywords are present in the recent message history.
11
+
12
+ Checks:
13
+ 1. The current message content
14
+ 2. The last 5 messages in recent_messages
15
+ """
16
+ if not keywords:
17
+ return False
18
+
19
+ relevant_text = []
20
+
21
+ # 1. Current message content
22
+ if message.content and message.content.text:
23
+ relevant_text.append(message.content.text)
24
+
25
+ # 2. Recent messages (last 5)
26
+ # Take the last 5 messages
27
+ recent_subset = recent_messages[-5:] if recent_messages else []
28
+
29
+ for msg in recent_subset:
30
+ if msg.content and msg.content.text:
31
+ relevant_text.append(msg.content.text)
32
+
33
+ if not relevant_text:
34
+ return False
35
+
36
+ combined_text = "\n".join(relevant_text).lower()
37
+
38
+ return any(keyword.lower() in combined_text for keyword in keywords)
39
+
40
+
41
+ def validate_action_regex(
42
+ message: Memory, recent_messages: list[Memory], regex_pattern: str
43
+ ) -> bool:
44
+ """
45
+ Validates if any of the recent message history matches the given regex pattern.
46
+
47
+ Args:
48
+ message: The current message memory
49
+ recent_messages: List of recent memories
50
+ regex_pattern: The regular expression pattern to check against
51
+
52
+ Returns:
53
+ bool: True if the regex matches any message content, False otherwise
54
+ """
55
+ if not regex_pattern:
56
+ return False
57
+
58
+ relevant_text = []
59
+
60
+ # 1. Current message content
61
+ if message.content and message.content.text:
62
+ relevant_text.append(message.content.text)
63
+
64
+ # 2. Recent messages (last 5)
65
+ recent_subset = recent_messages[-5:] if recent_messages else []
66
+
67
+ for msg in recent_subset:
68
+ if msg.content and msg.content.text:
69
+ relevant_text.append(msg.content.text)
70
+
71
+ if not relevant_text:
72
+ return False
73
+
74
+ combined_text = "\n".join(relevant_text)
75
+
76
+ return bool(re.search(regex_pattern, combined_text, re.MULTILINE))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/python",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.30",
4
4
  "description": "elizaOS Core - Python runtime and types",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -12,8 +12,9 @@
12
12
  "lint:fix": "ruff check --fix . && ruff format .",
13
13
  "format": "ruff format .",
14
14
  "format:check": "ruff format --check .",
15
- "typecheck": "python3.13 -m mypy elizaos || echo 'mypy not installed, skipping typecheck'"
15
+ "typecheck": "python3.13 -c \"import importlib.util, subprocess, sys; spec = importlib.util.find_spec('mypy'); sys.exit(0 if spec is None and print('mypy not installed, skipping typecheck') is None else subprocess.call([sys.executable, '-m', 'mypy', 'elizaos']))\""
16
16
  },
17
17
  "author": "elizaOS",
18
- "license": "MIT"
18
+ "license": "MIT",
19
+ "gitHead": "b6d792be2dddcbe53f0342e04d99512a6cf33fef"
19
20
  }
package/pyproject.toml CHANGED
@@ -25,7 +25,7 @@ classifiers = [
25
25
  dependencies = [
26
26
  "pydantic>=2.12.5",
27
27
  "pydantic-settings>=2.12.0",
28
- "protobuf>=5.29.0",
28
+ "protobuf>=7.34.0",
29
29
  "uuid6>=2024.1.12",
30
30
  "aiohttp>=3.13.3",
31
31
  "cryptography>=42.0.0",
@@ -140,4 +140,3 @@ known-first-party = ["elizaos"]
140
140
  line-length = 100
141
141
  target-version = ["py311"]
142
142
  exclude = "elizaos/types/generated/"
143
-
@@ -1,5 +1,5 @@
1
1
  #
2
- # This file is autogenerated by pip-compile with Python 3.13
2
+ # This file is autogenerated by pip-compile with Python 3.14
3
3
  # by the following command:
4
4
  #
5
5
  # pip-compile --output-file=requirements-dev.lock requirements-dev.in
@@ -71,7 +71,7 @@ propcache==0.4.1
71
71
  # via
72
72
  # aiohttp
73
73
  # yarl
74
- protobuf==6.33.4
74
+ protobuf==7.34.0
75
75
  # via -r requirements.in
76
76
  psutil==7.2.1
77
77
  # via pytest-xprocess
package/requirements.in CHANGED
@@ -1,9 +1,8 @@
1
1
  pydantic>=2.12.5
2
2
  pydantic-settings>=2.12.0
3
- protobuf>=5.29.0
3
+ protobuf>=7.34.0
4
4
  uuid6>=2024.1.12
5
5
  aiohttp>=3.13.3
6
6
  cryptography>=42.0.0
7
7
  structlog>=25.5.0
8
8
  typing-extensions>=4.9.0
9
-
package/requirements.lock CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # This file is autogenerated by pip-compile with Python 3.13
2
+ # This file is autogenerated by pip-compile with Python 3.14
3
3
  # by the following command:
4
4
  #
5
5
  # pip-compile --output-file=requirements.lock requirements.in
@@ -32,7 +32,7 @@ propcache==0.4.1
32
32
  # via
33
33
  # aiohttp
34
34
  # yarl
35
- protobuf==6.33.4
35
+ protobuf==7.34.0
36
36
  # via -r requirements.in
37
37
  pycparser==2.23
38
38
  # via cffi
@@ -19,7 +19,6 @@ from elizaos.types import (
19
19
  )
20
20
 
21
21
 
22
- @pytest.mark.skip(reason="Content proto doesn't have params field")
23
22
  @pytest.mark.asyncio
24
23
  async def test_process_actions_passes_validated_params_to_handler_options() -> None:
25
24
  character = Character(name="ParamAgent", bio=["Test agent"], system="Test")
@@ -83,10 +82,10 @@ async def test_process_actions_passes_validated_params_to_handler_options() -> N
83
82
 
84
83
  await runtime.process_actions(message, [response], state=None, callback=None)
85
84
 
86
- assert received == ["south"]
85
+ # Content proto has no params field, so schema defaults are applied.
86
+ assert received == ["north"]
87
87
 
88
88
 
89
- @pytest.mark.skip(reason="Content proto doesn't have params field")
90
89
  @pytest.mark.asyncio
91
90
  async def test_process_actions_skips_action_when_required_param_missing() -> None:
92
91
  character = Character(name="ParamAgent", bio=["Test agent"], system="Test")
@@ -3,7 +3,26 @@ import pytest
3
3
  from elizaos.action_docs import with_canonical_action_docs
4
4
  from elizaos.bootstrap.actions import send_message_action
5
5
  from elizaos.runtime import AgentRuntime
6
- from elizaos.types import Character, Content, Memory, as_uuid
6
+ from elizaos.types import Action, Character, Content, Memory, as_uuid
7
+
8
+
9
+ async def _noop_handler(
10
+ runtime: AgentRuntime,
11
+ message: Memory,
12
+ state: object | None = None,
13
+ options: object | None = None,
14
+ callback: object | None = None,
15
+ responses: object | None = None,
16
+ ) -> None:
17
+ return None
18
+
19
+
20
+ async def _always_valid(
21
+ runtime: AgentRuntime,
22
+ message: Memory,
23
+ state: object | None = None,
24
+ ) -> bool:
25
+ return True
7
26
 
8
27
 
9
28
  @pytest.mark.asyncio
@@ -37,3 +56,41 @@ async def test_actions_provider_includes_examples_and_parameter_examples() -> No
37
56
  # Canonical docs include examples for SEND_MESSAGE parameters
38
57
  assert "SEND_MESSAGE" in text
39
58
  assert "# Action Call Examples" in text
59
+
60
+
61
+ @pytest.mark.asyncio
62
+ async def test_actions_provider_does_not_trim_available_actions_to_top_10() -> None:
63
+ runtime = AgentRuntime(
64
+ character=Character(name="NoTrimTest", bio=["no trim test"], system="test"),
65
+ log_level="ERROR",
66
+ )
67
+ await runtime.initialize()
68
+
69
+ custom_action_names: list[str] = []
70
+ for index in range(12):
71
+ action_name = f"CUSTOM_ACTION_{index:02d}"
72
+ custom_action_names.append(action_name)
73
+ runtime.register_action(
74
+ Action(
75
+ name=action_name,
76
+ description=f"Custom action {index}",
77
+ handler=_noop_handler,
78
+ validate=_always_valid,
79
+ )
80
+ )
81
+
82
+ actions_provider = next(p for p in runtime.providers if p.name == "ACTIONS")
83
+
84
+ message = Memory(
85
+ id=as_uuid("42345678-1234-1234-1234-123456789012"),
86
+ entity_id=as_uuid("42345678-1234-1234-1234-123456789013"),
87
+ room_id=as_uuid("42345678-1234-1234-1234-123456789014"),
88
+ content=Content(text="show me every action"),
89
+ )
90
+
91
+ state = await runtime.compose_state(message)
92
+ result = await actions_provider.get(runtime, message, state)
93
+
94
+ text = result.text or ""
95
+ for action_name in custom_action_names:
96
+ assert action_name in text
@@ -11,7 +11,6 @@ from elizaos.types.memory import Memory
11
11
  from elizaos.types.primitives import Content, as_uuid
12
12
 
13
13
 
14
- @pytest.mark.skip(reason="MemoryService requires runtime settings.get() which isn't implemented")
15
14
  @pytest.mark.asyncio
16
15
  async def test_memory_provider_formats_long_term_memories() -> None:
17
16
  runtime = AgentRuntime(
@@ -49,7 +48,6 @@ async def test_memory_provider_formats_long_term_memories() -> None:
49
48
  assert result.text and "What I Know About You" in result.text
50
49
 
51
50
 
52
- @pytest.mark.skip(reason="MemoryService runtime not set")
53
51
  @pytest.mark.asyncio
54
52
  async def test_get_long_term_memories_returns_top_confidence() -> None:
55
53
  svc = MemoryService(runtime=None)
@@ -6,7 +6,6 @@ from elizaos.runtime import AgentRuntime
6
6
  from elizaos.types.agent import Character
7
7
 
8
8
 
9
- @pytest.mark.skip(reason="MemoryService requires runtime settings.get() which isn't implemented")
10
9
  @pytest.mark.asyncio
11
10
  async def test_advanced_memory_autoloads_when_enabled() -> None:
12
11
  runtime = AgentRuntime(
@@ -19,7 +18,6 @@ async def test_advanced_memory_autoloads_when_enabled() -> None:
19
18
  assert any(e.name == "MEMORY_SUMMARIZATION" for e in runtime.evaluators)
20
19
 
21
20
 
22
- @pytest.mark.skip(reason="MemoryService requires runtime settings.get() which isn't implemented")
23
21
  @pytest.mark.asyncio
24
22
  async def test_advanced_memory_not_loaded_when_disabled() -> None:
25
23
  runtime = AgentRuntime(