@elizaos/python 2.0.0-alpha.10 → 2.0.0-alpha.26
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.
- package/elizaos/__init__.py +0 -1
- package/elizaos/advanced_capabilities/__init__.py +6 -41
- package/elizaos/advanced_capabilities/actions/__init__.py +1 -21
- package/elizaos/advanced_capabilities/actions/add_contact.py +21 -11
- package/elizaos/advanced_capabilities/actions/follow_room.py +28 -28
- package/elizaos/advanced_capabilities/actions/image_generation.py +13 -26
- package/elizaos/advanced_capabilities/actions/mute_room.py +13 -26
- package/elizaos/advanced_capabilities/actions/remove_contact.py +16 -2
- package/elizaos/advanced_capabilities/actions/roles.py +13 -27
- package/elizaos/advanced_capabilities/actions/schedule_follow_up.py +70 -15
- package/elizaos/advanced_capabilities/actions/search_contacts.py +17 -3
- package/elizaos/advanced_capabilities/actions/send_message.py +183 -50
- package/elizaos/advanced_capabilities/actions/settings.py +16 -2
- package/elizaos/advanced_capabilities/actions/unfollow_room.py +13 -26
- package/elizaos/advanced_capabilities/actions/unmute_room.py +13 -26
- package/elizaos/advanced_capabilities/actions/update_contact.py +16 -2
- package/elizaos/advanced_capabilities/actions/update_entity.py +16 -2
- package/elizaos/advanced_capabilities/evaluators/__init__.py +2 -9
- package/elizaos/advanced_capabilities/evaluators/reflection.py +3 -132
- package/elizaos/advanced_capabilities/evaluators/relationship_extraction.py +5 -201
- package/elizaos/advanced_capabilities/providers/__init__.py +1 -12
- package/elizaos/advanced_capabilities/providers/knowledge.py +24 -3
- package/elizaos/advanced_capabilities/services/__init__.py +2 -9
- package/elizaos/advanced_memory/actions/reset_session.py +11 -0
- package/elizaos/advanced_memory/evaluators/reflection.py +134 -0
- package/elizaos/advanced_memory/evaluators/relationship_extraction.py +203 -0
- package/elizaos/advanced_memory/memory_service.py +15 -17
- package/elizaos/advanced_memory/test_advanced_memory.py +357 -0
- package/elizaos/advanced_planning/actions/schedule_follow_up.py +222 -0
- package/elizaos/advanced_planning/planning_service.py +26 -14
- package/elizaos/basic_capabilities/__init__.py +0 -2
- package/elizaos/basic_capabilities/providers/__init__.py +0 -3
- package/elizaos/basic_capabilities/providers/actions.py +118 -29
- package/elizaos/basic_capabilities/providers/agent_settings.py +64 -0
- package/elizaos/basic_capabilities/providers/character.py +19 -21
- package/elizaos/basic_capabilities/providers/contacts.py +79 -0
- package/elizaos/basic_capabilities/providers/current_time.py +7 -4
- package/elizaos/basic_capabilities/providers/facts.py +87 -0
- package/elizaos/basic_capabilities/providers/follow_ups.py +117 -0
- package/elizaos/basic_capabilities/providers/knowledge.py +97 -0
- package/elizaos/basic_capabilities/providers/relationships.py +107 -0
- package/elizaos/basic_capabilities/providers/roles.py +96 -0
- package/elizaos/basic_capabilities/providers/settings.py +56 -0
- package/elizaos/basic_capabilities/providers/time.py +7 -4
- package/elizaos/bootstrap/__init__.py +21 -2
- package/elizaos/bootstrap/actions/schedule_follow_up.py +65 -7
- package/elizaos/bootstrap/actions/send_message.py +162 -15
- package/elizaos/bootstrap/autonomy/__init__.py +5 -1
- package/elizaos/bootstrap/autonomy/action.py +161 -0
- package/elizaos/bootstrap/autonomy/evaluators.py +217 -0
- package/elizaos/bootstrap/autonomy/service.py +238 -28
- package/elizaos/bootstrap/plugin.py +7 -0
- package/elizaos/bootstrap/providers/actions.py +118 -27
- package/elizaos/bootstrap/providers/agent_settings.py +1 -0
- package/elizaos/bootstrap/providers/attachments.py +1 -0
- package/elizaos/bootstrap/providers/capabilities.py +1 -0
- package/elizaos/bootstrap/providers/character.py +1 -0
- package/elizaos/bootstrap/providers/choice.py +1 -0
- package/elizaos/bootstrap/providers/contacts.py +1 -0
- package/elizaos/bootstrap/providers/current_time.py +8 -2
- package/elizaos/bootstrap/providers/entities.py +1 -0
- package/elizaos/bootstrap/providers/evaluators.py +1 -0
- package/elizaos/bootstrap/providers/facts.py +1 -0
- package/elizaos/bootstrap/providers/follow_ups.py +1 -0
- package/elizaos/bootstrap/providers/knowledge.py +27 -3
- package/elizaos/bootstrap/providers/providers_list.py +1 -0
- package/elizaos/bootstrap/providers/relationships.py +1 -0
- package/elizaos/bootstrap/providers/roles.py +1 -0
- package/elizaos/bootstrap/providers/settings.py +1 -0
- package/elizaos/bootstrap/providers/time.py +8 -4
- package/elizaos/bootstrap/providers/world.py +1 -0
- package/elizaos/bootstrap/services/embedding.py +156 -1
- package/elizaos/deterministic.py +193 -0
- package/elizaos/generated/__init__.py +1 -0
- package/elizaos/generated/action_docs.py +3181 -0
- package/elizaos/generated/spec_helpers.py +175 -0
- package/elizaos/media/mime.py +2 -2
- package/elizaos/media/search.py +23 -23
- package/elizaos/runtime.py +215 -57
- package/elizaos/services/message_service.py +175 -29
- package/elizaos/types/components.py +2 -2
- package/elizaos/types/generated/__init__.py +12 -0
- package/elizaos/types/generated/eliza/v1/agent_pb2.py +63 -0
- package/elizaos/types/generated/eliza/v1/agent_pb2.pyi +159 -0
- package/elizaos/types/generated/eliza/v1/components_pb2.py +65 -0
- package/elizaos/types/generated/eliza/v1/components_pb2.pyi +160 -0
- package/elizaos/types/generated/eliza/v1/database_pb2.py +78 -0
- package/elizaos/types/generated/eliza/v1/database_pb2.pyi +305 -0
- package/elizaos/types/generated/eliza/v1/environment_pb2.py +58 -0
- package/elizaos/types/generated/eliza/v1/environment_pb2.pyi +135 -0
- package/elizaos/types/generated/eliza/v1/events_pb2.py +82 -0
- package/elizaos/types/generated/eliza/v1/events_pb2.pyi +322 -0
- package/elizaos/types/generated/eliza/v1/ipc_pb2.py +113 -0
- package/elizaos/types/generated/eliza/v1/ipc_pb2.pyi +367 -0
- package/elizaos/types/generated/eliza/v1/knowledge_pb2.py +41 -0
- package/elizaos/types/generated/eliza/v1/knowledge_pb2.pyi +26 -0
- package/elizaos/types/generated/eliza/v1/memory_pb2.py +55 -0
- package/elizaos/types/generated/eliza/v1/memory_pb2.pyi +111 -0
- package/elizaos/types/generated/eliza/v1/message_service_pb2.py +48 -0
- package/elizaos/types/generated/eliza/v1/message_service_pb2.pyi +69 -0
- package/elizaos/types/generated/eliza/v1/messaging_pb2.py +51 -0
- package/elizaos/types/generated/eliza/v1/messaging_pb2.pyi +97 -0
- package/elizaos/types/generated/eliza/v1/model_pb2.py +84 -0
- package/elizaos/types/generated/eliza/v1/model_pb2.pyi +280 -0
- package/elizaos/types/generated/eliza/v1/payment_pb2.py +44 -0
- package/elizaos/types/generated/eliza/v1/payment_pb2.pyi +70 -0
- package/elizaos/types/generated/eliza/v1/plugin_pb2.py +68 -0
- package/elizaos/types/generated/eliza/v1/plugin_pb2.pyi +145 -0
- package/elizaos/types/generated/eliza/v1/primitives_pb2.py +48 -0
- package/elizaos/types/generated/eliza/v1/primitives_pb2.pyi +92 -0
- package/elizaos/types/generated/eliza/v1/prompts_pb2.py +52 -0
- package/elizaos/types/generated/eliza/v1/prompts_pb2.pyi +74 -0
- package/elizaos/types/generated/eliza/v1/service_interfaces_pb2.py +211 -0
- package/elizaos/types/generated/eliza/v1/service_interfaces_pb2.pyi +1296 -0
- package/elizaos/types/generated/eliza/v1/service_pb2.py +42 -0
- package/elizaos/types/generated/eliza/v1/service_pb2.pyi +69 -0
- package/elizaos/types/generated/eliza/v1/settings_pb2.py +58 -0
- package/elizaos/types/generated/eliza/v1/settings_pb2.pyi +85 -0
- package/elizaos/types/generated/eliza/v1/state_pb2.py +60 -0
- package/elizaos/types/generated/eliza/v1/state_pb2.pyi +114 -0
- package/elizaos/types/generated/eliza/v1/task_pb2.py +42 -0
- package/elizaos/types/generated/eliza/v1/task_pb2.pyi +58 -0
- package/elizaos/types/generated/eliza/v1/tee_pb2.py +52 -0
- package/elizaos/types/generated/eliza/v1/tee_pb2.pyi +90 -0
- package/elizaos/types/generated/eliza/v1/testing_pb2.py +39 -0
- package/elizaos/types/generated/eliza/v1/testing_pb2.pyi +23 -0
- package/elizaos/types/model.py +30 -0
- package/elizaos/types/runtime.py +6 -2
- package/elizaos/utils/validation.py +76 -0
- package/package.json +3 -2
- package/tests/test_action_parameters.py +2 -3
- package/tests/test_actions_provider_examples.py +58 -1
- package/tests/test_advanced_memory_behavior.py +0 -2
- package/tests/test_advanced_memory_flag.py +0 -2
- package/tests/test_advanced_planning_behavior.py +11 -5
- package/tests/test_async_embedding.py +124 -0
- package/tests/test_autonomy.py +24 -3
- package/tests/test_runtime.py +8 -17
- package/tests/test_schedule_follow_up_action.py +260 -0
- package/tests/test_send_message_action_targets.py +114 -0
- package/tests/test_settings_crypto.py +0 -2
- package/tests/test_validation.py +141 -0
- package/tests/verify_memory_architecture.py +192 -0
- package/uv.lock +1565 -0
- package/elizaos/basic_capabilities/providers/capabilities.py +0 -62
|
@@ -2,11 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import contextlib
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
from elizaos.generated.spec_helpers import require_action_spec
|
|
8
8
|
from elizaos.types import Action, ActionExample, ActionResult, Content
|
|
9
9
|
from elizaos.types.memory import Memory as MemoryType
|
|
10
|
+
from elizaos.types.primitives import UUID, as_uuid
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
12
13
|
from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
|
|
@@ -18,34 +19,69 @@ _spec = require_action_spec("SEND_MESSAGE")
|
|
|
18
19
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
19
20
|
"""Convert spec examples to ActionExample format."""
|
|
20
21
|
spec_examples = _spec.get("examples", [])
|
|
21
|
-
if
|
|
22
|
-
return [
|
|
23
|
-
|
|
24
|
-
for example in spec_examples:
|
|
25
|
-
if not isinstance(example, list):
|
|
26
|
-
continue
|
|
27
|
-
row: list[ActionExample] = []
|
|
28
|
-
for msg in example:
|
|
29
|
-
if not isinstance(msg, dict):
|
|
30
|
-
continue
|
|
31
|
-
content = msg.get("content", {})
|
|
32
|
-
text = ""
|
|
33
|
-
actions: list[str] | None = None
|
|
34
|
-
if isinstance(content, dict):
|
|
35
|
-
text_val = content.get("text", "")
|
|
36
|
-
text = str(text_val) if text_val else ""
|
|
37
|
-
actions_val = content.get("actions")
|
|
38
|
-
if isinstance(actions_val, list) and all(isinstance(a, str) for a in actions_val):
|
|
39
|
-
actions = list(actions_val)
|
|
40
|
-
row.append(
|
|
22
|
+
if spec_examples:
|
|
23
|
+
return [
|
|
24
|
+
[
|
|
41
25
|
ActionExample(
|
|
42
|
-
name=
|
|
43
|
-
content=Content(
|
|
26
|
+
name=msg.get("name", ""),
|
|
27
|
+
content=Content(
|
|
28
|
+
text=msg.get("content", {}).get("text", ""),
|
|
29
|
+
actions=msg.get("content", {}).get("actions"),
|
|
30
|
+
),
|
|
44
31
|
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
for msg in example
|
|
33
|
+
]
|
|
34
|
+
for example in spec_examples
|
|
35
|
+
]
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _parse_uuid(value: object) -> UUID | None:
|
|
40
|
+
if not isinstance(value, str) or not value.strip():
|
|
41
|
+
return None
|
|
42
|
+
with contextlib.suppress(Exception):
|
|
43
|
+
return as_uuid(value.strip())
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _normalize_parameters(options: HandlerOptions | None) -> dict[str, Any]:
|
|
48
|
+
raw = getattr(options, "parameters", None)
|
|
49
|
+
if isinstance(raw, dict):
|
|
50
|
+
return raw
|
|
51
|
+
|
|
52
|
+
if raw is None:
|
|
53
|
+
return {}
|
|
54
|
+
|
|
55
|
+
if hasattr(raw, "items"):
|
|
56
|
+
try:
|
|
57
|
+
return {str(k): v for k, v in raw.items()}
|
|
58
|
+
except Exception:
|
|
59
|
+
return {}
|
|
60
|
+
|
|
61
|
+
return {}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _coerce_entity_name(entity: object) -> list[str]:
|
|
65
|
+
if isinstance(entity, dict):
|
|
66
|
+
names = entity.get("names")
|
|
67
|
+
if isinstance(names, list):
|
|
68
|
+
return [str(n).strip() for n in names if isinstance(n, str) and n.strip()]
|
|
69
|
+
name = entity.get("name")
|
|
70
|
+
if isinstance(name, str) and name.strip():
|
|
71
|
+
return [name.strip()]
|
|
72
|
+
return []
|
|
73
|
+
|
|
74
|
+
names = getattr(entity, "names", None)
|
|
75
|
+
if isinstance(names, list):
|
|
76
|
+
clean = [str(n).strip() for n in names if isinstance(n, str) and str(n).strip()]
|
|
77
|
+
if clean:
|
|
78
|
+
return clean
|
|
79
|
+
|
|
80
|
+
name = getattr(entity, "name", None)
|
|
81
|
+
if isinstance(name, str) and name.strip():
|
|
82
|
+
return [name.strip()]
|
|
83
|
+
|
|
84
|
+
return []
|
|
49
85
|
|
|
50
86
|
|
|
51
87
|
@dataclass
|
|
@@ -70,9 +106,14 @@ class SendMessageAction:
|
|
|
70
106
|
callback: HandlerCallback | None = None,
|
|
71
107
|
responses: list[Memory] | None = None,
|
|
72
108
|
) -> ActionResult:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
109
|
+
params = _normalize_parameters(options)
|
|
110
|
+
|
|
111
|
+
text_param = params.get("text")
|
|
112
|
+
message_text = str(text_param).strip() if isinstance(text_param, str) else ""
|
|
113
|
+
if not message_text and responses and responses[0].content:
|
|
114
|
+
message_text = str(responses[0].content.text or "").strip()
|
|
115
|
+
if not message_text and message.content and isinstance(message.content.text, str):
|
|
116
|
+
message_text = message.content.text.strip()
|
|
76
117
|
|
|
77
118
|
if not message_text:
|
|
78
119
|
return ActionResult(
|
|
@@ -82,24 +123,95 @@ class SendMessageAction:
|
|
|
82
123
|
success=False,
|
|
83
124
|
)
|
|
84
125
|
|
|
85
|
-
|
|
126
|
+
target_room_id = message.room_id
|
|
127
|
+
target_entity_id: UUID | None = None
|
|
128
|
+
target_type = "room"
|
|
129
|
+
|
|
130
|
+
target_type_param = params.get("targetType") or params.get("target_type")
|
|
131
|
+
target_param = params.get("target")
|
|
132
|
+
source_param = params.get("source")
|
|
133
|
+
|
|
134
|
+
source = (
|
|
135
|
+
source_param.strip()
|
|
136
|
+
if isinstance(source_param, str) and source_param.strip()
|
|
137
|
+
else (
|
|
138
|
+
message.content.source
|
|
139
|
+
if message.content and isinstance(message.content.source, str)
|
|
140
|
+
else "agent"
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if isinstance(target_type_param, str):
|
|
145
|
+
normalized_target_type = target_type_param.strip().lower()
|
|
146
|
+
if normalized_target_type in {"user", "entity"}:
|
|
147
|
+
target_type = "user"
|
|
148
|
+
elif normalized_target_type == "room":
|
|
149
|
+
target_type = "room"
|
|
86
150
|
|
|
87
|
-
|
|
88
|
-
|
|
151
|
+
if isinstance(target_param, str) and target_param.strip():
|
|
152
|
+
target_value = target_param.strip()
|
|
153
|
+
if target_type == "room":
|
|
154
|
+
parsed_room = _parse_uuid(target_value)
|
|
155
|
+
if parsed_room:
|
|
156
|
+
target_room_id = parsed_room
|
|
157
|
+
else:
|
|
158
|
+
world_id = None
|
|
159
|
+
room_data = (
|
|
160
|
+
getattr(getattr(state, "data", None), "room", None) if state else None
|
|
161
|
+
)
|
|
162
|
+
if room_data is not None:
|
|
163
|
+
world_id = getattr(room_data, "world_id", None) or getattr(
|
|
164
|
+
room_data, "worldId", None
|
|
165
|
+
)
|
|
166
|
+
if world_id is None:
|
|
167
|
+
with contextlib.suppress(Exception):
|
|
168
|
+
current_room = await runtime.get_room(message.room_id)
|
|
169
|
+
if current_room:
|
|
170
|
+
world_id = getattr(current_room, "world_id", None) or getattr(
|
|
171
|
+
current_room, "worldId", None
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if world_id is not None:
|
|
175
|
+
with contextlib.suppress(Exception):
|
|
176
|
+
rooms = await runtime.get_rooms(world_id)
|
|
177
|
+
for room in rooms:
|
|
178
|
+
room_name = getattr(room, "name", None)
|
|
179
|
+
if (
|
|
180
|
+
isinstance(room_name, str)
|
|
181
|
+
and room_name.strip().lower() == target_value.lower()
|
|
182
|
+
):
|
|
183
|
+
room_id = getattr(room, "id", None)
|
|
184
|
+
if room_id is not None:
|
|
185
|
+
target_room_id = as_uuid(str(room_id))
|
|
186
|
+
break
|
|
187
|
+
else:
|
|
188
|
+
parsed_entity = _parse_uuid(target_value)
|
|
189
|
+
if parsed_entity:
|
|
190
|
+
target_entity_id = parsed_entity
|
|
191
|
+
else:
|
|
192
|
+
with contextlib.suppress(Exception):
|
|
193
|
+
entities = await runtime.get_entities_for_room(message.room_id)
|
|
194
|
+
for entity in entities:
|
|
195
|
+
names = _coerce_entity_name(entity)
|
|
196
|
+
if any(name.lower() == target_value.lower() for name in names):
|
|
197
|
+
entity_id = getattr(entity, "id", None)
|
|
198
|
+
if entity_id is not None:
|
|
199
|
+
target_entity_id = as_uuid(str(entity_id))
|
|
200
|
+
break
|
|
89
201
|
|
|
90
202
|
if message.content and message.content.target:
|
|
91
203
|
target = message.content.target
|
|
92
204
|
if isinstance(target, dict):
|
|
93
205
|
room_str = target.get("roomId")
|
|
94
206
|
entity_str = target.get("entityId")
|
|
95
|
-
if room_str:
|
|
96
|
-
with contextlib.suppress(
|
|
97
|
-
|
|
98
|
-
if entity_str:
|
|
99
|
-
with contextlib.suppress(
|
|
100
|
-
target_entity_id =
|
|
101
|
-
|
|
102
|
-
if not
|
|
207
|
+
if room_str and target_type == "room":
|
|
208
|
+
with contextlib.suppress(Exception):
|
|
209
|
+
target_room_id = as_uuid(room_str)
|
|
210
|
+
if entity_str and target_type == "user":
|
|
211
|
+
with contextlib.suppress(Exception):
|
|
212
|
+
target_entity_id = as_uuid(entity_str)
|
|
213
|
+
|
|
214
|
+
if not target_room_id:
|
|
103
215
|
return ActionResult(
|
|
104
216
|
text="No target room specified",
|
|
105
217
|
values={"success": False, "error": "no_target"},
|
|
@@ -109,27 +221,39 @@ class SendMessageAction:
|
|
|
109
221
|
|
|
110
222
|
message_content = Content(
|
|
111
223
|
text=message_text,
|
|
112
|
-
source=
|
|
224
|
+
source=source,
|
|
113
225
|
actions=["SEND_MESSAGE"],
|
|
114
226
|
)
|
|
115
227
|
|
|
116
|
-
|
|
228
|
+
send_message_to_target = getattr(runtime, "send_message_to_target", None)
|
|
229
|
+
if callable(send_message_to_target):
|
|
230
|
+
with contextlib.suppress(Exception):
|
|
231
|
+
from elizaos.types.runtime import TargetInfo
|
|
232
|
+
|
|
233
|
+
await send_message_to_target(
|
|
234
|
+
TargetInfo(
|
|
235
|
+
roomId=str(target_room_id),
|
|
236
|
+
entityId=str(target_entity_id) if target_entity_id else None,
|
|
237
|
+
source=source,
|
|
238
|
+
),
|
|
239
|
+
message_content,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Create the message memory
|
|
117
243
|
import time
|
|
118
244
|
import uuid as uuid_module
|
|
119
245
|
|
|
120
|
-
from elizaos.types.primitives import as_uuid
|
|
121
|
-
|
|
122
246
|
message_memory = MemoryType(
|
|
123
247
|
id=as_uuid(str(uuid_module.uuid4())),
|
|
124
248
|
entity_id=runtime.agent_id,
|
|
125
|
-
room_id=
|
|
249
|
+
room_id=target_room_id,
|
|
126
250
|
content=message_content,
|
|
127
251
|
created_at=int(time.time() * 1000),
|
|
128
252
|
)
|
|
129
253
|
|
|
130
254
|
await runtime.create_memory(
|
|
131
255
|
content=message_content,
|
|
132
|
-
room_id=
|
|
256
|
+
room_id=target_room_id,
|
|
133
257
|
entity_id=runtime.agent_id,
|
|
134
258
|
memory_type="message",
|
|
135
259
|
metadata={
|
|
@@ -156,17 +280,26 @@ class SendMessageAction:
|
|
|
156
280
|
if callback:
|
|
157
281
|
await callback(response_content)
|
|
158
282
|
|
|
283
|
+
target_id = (
|
|
284
|
+
target_entity_id if target_type == "user" and target_entity_id else target_room_id
|
|
285
|
+
)
|
|
159
286
|
return ActionResult(
|
|
160
|
-
text="Message sent
|
|
287
|
+
text="Message sent",
|
|
161
288
|
values={
|
|
162
289
|
"success": True,
|
|
163
290
|
"messageSent": True,
|
|
164
|
-
"
|
|
291
|
+
"targetType": target_type,
|
|
292
|
+
"target": str(target_id),
|
|
293
|
+
"source": source,
|
|
294
|
+
"targetRoomId": str(target_room_id),
|
|
165
295
|
"targetEntityId": str(target_entity_id) if target_entity_id else None,
|
|
166
296
|
},
|
|
167
297
|
data={
|
|
168
298
|
"actionName": "SEND_MESSAGE",
|
|
169
|
-
"
|
|
299
|
+
"targetType": target_type,
|
|
300
|
+
"target": str(target_id),
|
|
301
|
+
"source": source,
|
|
302
|
+
"targetRoomId": str(target_room_id),
|
|
170
303
|
"messagePreview": message_text[:100],
|
|
171
304
|
},
|
|
172
305
|
success=True,
|
|
@@ -7,7 +7,6 @@ from elizaos.bootstrap.utils.xml import parse_key_value_xml
|
|
|
7
7
|
from elizaos.generated.spec_helpers import require_action_spec
|
|
8
8
|
from elizaos.prompts import UPDATE_SETTINGS_TEMPLATE
|
|
9
9
|
from elizaos.types import Action, ActionExample, ActionResult, Content, ModelType
|
|
10
|
-
from elizaos.utils.spec_examples import convert_spec_examples
|
|
11
10
|
|
|
12
11
|
if TYPE_CHECKING:
|
|
13
12
|
from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
|
|
@@ -18,7 +17,22 @@ _spec = require_action_spec("UPDATE_SETTINGS")
|
|
|
18
17
|
|
|
19
18
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
20
19
|
"""Convert spec examples to ActionExample format."""
|
|
21
|
-
|
|
20
|
+
spec_examples = _spec.get("examples", [])
|
|
21
|
+
if spec_examples:
|
|
22
|
+
return [
|
|
23
|
+
[
|
|
24
|
+
ActionExample(
|
|
25
|
+
name=msg.get("name", ""),
|
|
26
|
+
content=Content(
|
|
27
|
+
text=msg.get("content", {}).get("text", ""),
|
|
28
|
+
actions=msg.get("content", {}).get("actions"),
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
for msg in example
|
|
32
|
+
]
|
|
33
|
+
for example in spec_examples
|
|
34
|
+
]
|
|
35
|
+
return []
|
|
22
36
|
|
|
23
37
|
|
|
24
38
|
@dataclass
|
|
@@ -16,34 +16,21 @@ _spec = require_action_spec("UNFOLLOW_ROOM")
|
|
|
16
16
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
17
17
|
"""Convert spec examples to ActionExample format."""
|
|
18
18
|
spec_examples = _spec.get("examples", [])
|
|
19
|
-
if
|
|
20
|
-
return [
|
|
21
|
-
|
|
22
|
-
for example in spec_examples:
|
|
23
|
-
if not isinstance(example, list):
|
|
24
|
-
continue
|
|
25
|
-
row: list[ActionExample] = []
|
|
26
|
-
for msg in example:
|
|
27
|
-
if not isinstance(msg, dict):
|
|
28
|
-
continue
|
|
29
|
-
content = msg.get("content", {})
|
|
30
|
-
text = ""
|
|
31
|
-
actions: list[str] | None = None
|
|
32
|
-
if isinstance(content, dict):
|
|
33
|
-
text_val = content.get("text", "")
|
|
34
|
-
text = str(text_val) if text_val else ""
|
|
35
|
-
actions_val = content.get("actions")
|
|
36
|
-
if isinstance(actions_val, list) and all(isinstance(a, str) for a in actions_val):
|
|
37
|
-
actions = list(actions_val)
|
|
38
|
-
row.append(
|
|
19
|
+
if spec_examples:
|
|
20
|
+
return [
|
|
21
|
+
[
|
|
39
22
|
ActionExample(
|
|
40
|
-
name=
|
|
41
|
-
content=Content(
|
|
23
|
+
name=msg.get("name", ""),
|
|
24
|
+
content=Content(
|
|
25
|
+
text=msg.get("content", {}).get("text", ""),
|
|
26
|
+
actions=msg.get("content", {}).get("actions"),
|
|
27
|
+
),
|
|
42
28
|
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
for msg in example
|
|
30
|
+
]
|
|
31
|
+
for example in spec_examples
|
|
32
|
+
]
|
|
33
|
+
return []
|
|
47
34
|
|
|
48
35
|
|
|
49
36
|
@dataclass
|
|
@@ -16,34 +16,21 @@ _spec = require_action_spec("UNMUTE_ROOM")
|
|
|
16
16
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
17
17
|
"""Convert spec examples to ActionExample format."""
|
|
18
18
|
spec_examples = _spec.get("examples", [])
|
|
19
|
-
if
|
|
20
|
-
return [
|
|
21
|
-
|
|
22
|
-
for example in spec_examples:
|
|
23
|
-
if not isinstance(example, list):
|
|
24
|
-
continue
|
|
25
|
-
row: list[ActionExample] = []
|
|
26
|
-
for msg in example:
|
|
27
|
-
if not isinstance(msg, dict):
|
|
28
|
-
continue
|
|
29
|
-
content = msg.get("content", {})
|
|
30
|
-
text = ""
|
|
31
|
-
actions: list[str] | None = None
|
|
32
|
-
if isinstance(content, dict):
|
|
33
|
-
text_val = content.get("text", "")
|
|
34
|
-
text = str(text_val) if text_val else ""
|
|
35
|
-
actions_val = content.get("actions")
|
|
36
|
-
if isinstance(actions_val, list) and all(isinstance(a, str) for a in actions_val):
|
|
37
|
-
actions = list(actions_val)
|
|
38
|
-
row.append(
|
|
19
|
+
if spec_examples:
|
|
20
|
+
return [
|
|
21
|
+
[
|
|
39
22
|
ActionExample(
|
|
40
|
-
name=
|
|
41
|
-
content=Content(
|
|
23
|
+
name=msg.get("name", ""),
|
|
24
|
+
content=Content(
|
|
25
|
+
text=msg.get("content", {}).get("text", ""),
|
|
26
|
+
actions=msg.get("content", {}).get("actions"),
|
|
27
|
+
),
|
|
42
28
|
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
for msg in example
|
|
30
|
+
]
|
|
31
|
+
for example in spec_examples
|
|
32
|
+
]
|
|
33
|
+
return []
|
|
47
34
|
|
|
48
35
|
|
|
49
36
|
@dataclass
|
|
@@ -13,7 +13,6 @@ from elizaos.types import (
|
|
|
13
13
|
Content,
|
|
14
14
|
ModelType,
|
|
15
15
|
)
|
|
16
|
-
from elizaos.utils.spec_examples import convert_spec_examples
|
|
17
16
|
|
|
18
17
|
if TYPE_CHECKING:
|
|
19
18
|
from elizaos.types import (
|
|
@@ -30,7 +29,22 @@ _spec = require_action_spec("UPDATE_CONTACT")
|
|
|
30
29
|
|
|
31
30
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
32
31
|
"""Convert spec examples to ActionExample format."""
|
|
33
|
-
|
|
32
|
+
spec_examples = _spec.get("examples", [])
|
|
33
|
+
if spec_examples:
|
|
34
|
+
return [
|
|
35
|
+
[
|
|
36
|
+
ActionExample(
|
|
37
|
+
name=msg.get("name", ""),
|
|
38
|
+
content=Content(
|
|
39
|
+
text=msg.get("content", {}).get("text", ""),
|
|
40
|
+
actions=msg.get("content", {}).get("actions"),
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
for msg in example
|
|
44
|
+
]
|
|
45
|
+
for example in spec_examples
|
|
46
|
+
]
|
|
47
|
+
return []
|
|
34
48
|
|
|
35
49
|
|
|
36
50
|
@dataclass
|
|
@@ -8,7 +8,6 @@ from elizaos.bootstrap.utils.xml import parse_key_value_xml
|
|
|
8
8
|
from elizaos.generated.spec_helpers import require_action_spec
|
|
9
9
|
from elizaos.prompts import UPDATE_ENTITY_TEMPLATE
|
|
10
10
|
from elizaos.types import Action, ActionExample, ActionResult, Content, ModelType
|
|
11
|
-
from elizaos.utils.spec_examples import convert_spec_examples
|
|
12
11
|
|
|
13
12
|
if TYPE_CHECKING:
|
|
14
13
|
from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
|
|
@@ -19,7 +18,22 @@ _spec = require_action_spec("UPDATE_ENTITY")
|
|
|
19
18
|
|
|
20
19
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
21
20
|
"""Convert spec examples to ActionExample format."""
|
|
22
|
-
|
|
21
|
+
spec_examples = _spec.get("examples", [])
|
|
22
|
+
if spec_examples:
|
|
23
|
+
return [
|
|
24
|
+
[
|
|
25
|
+
ActionExample(
|
|
26
|
+
name=msg.get("name", ""),
|
|
27
|
+
content=Content(
|
|
28
|
+
text=msg.get("content", {}).get("text", ""),
|
|
29
|
+
actions=msg.get("content", {}).get("actions"),
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
for msg in example
|
|
33
|
+
]
|
|
34
|
+
for example in spec_examples
|
|
35
|
+
]
|
|
36
|
+
return []
|
|
23
37
|
|
|
24
38
|
|
|
25
39
|
@dataclass
|
|
@@ -3,16 +3,9 @@
|
|
|
3
3
|
Evaluators that can be enabled with `advanced_capabilities=True`.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from .reflection import reflection_evaluator
|
|
7
|
-
from .relationship_extraction import relationship_extraction_evaluator
|
|
8
|
-
|
|
9
6
|
__all__ = [
|
|
10
|
-
"reflection_evaluator",
|
|
11
|
-
"relationship_extraction_evaluator",
|
|
12
7
|
"advanced_evaluators",
|
|
13
8
|
]
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
relationship_extraction_evaluator,
|
|
18
|
-
]
|
|
10
|
+
# Relationship evaluators are owned by the plugin-rolodex package.
|
|
11
|
+
advanced_evaluators: list = []
|
|
@@ -1,134 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"""Compatibility wrapper for reflection evaluator."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from elizaos.bootstrap.evaluators.reflection import reflection_evaluator
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
from elizaos.bootstrap.utils.xml import parse_key_value_xml
|
|
8
|
-
from elizaos.generated.spec_helpers import require_evaluator_spec
|
|
9
|
-
from elizaos.prompts import REFLECTION_TEMPLATE
|
|
10
|
-
from elizaos.types import ActionResult, Evaluator, HandlerOptions, ModelType
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from elizaos.types import Content, IAgentRuntime, Memory, State
|
|
14
|
-
|
|
15
|
-
# Get text content from centralized specs
|
|
16
|
-
_spec = require_evaluator_spec("REFLECTION")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
async def evaluate_reflection(
|
|
20
|
-
runtime: IAgentRuntime,
|
|
21
|
-
message: Memory,
|
|
22
|
-
state: State | None = None,
|
|
23
|
-
) -> EvaluatorResult:
|
|
24
|
-
if state is None:
|
|
25
|
-
return EvaluatorResult(
|
|
26
|
-
score=50,
|
|
27
|
-
passed=True,
|
|
28
|
-
reason="No state for reflection",
|
|
29
|
-
details={},
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
recent_interactions: list[str] = []
|
|
33
|
-
room_id = message.room_id
|
|
34
|
-
|
|
35
|
-
if room_id:
|
|
36
|
-
recent_messages = await runtime.get_memories(
|
|
37
|
-
room_id=room_id,
|
|
38
|
-
limit=10,
|
|
39
|
-
order_by="created_at",
|
|
40
|
-
order_direction="desc",
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
for msg in recent_messages:
|
|
44
|
-
if msg.content and msg.content.text:
|
|
45
|
-
sender = "Unknown"
|
|
46
|
-
if msg.entity_id:
|
|
47
|
-
if str(msg.entity_id) == str(runtime.agent_id):
|
|
48
|
-
sender = runtime.character.name
|
|
49
|
-
else:
|
|
50
|
-
entity = await runtime.get_entity(msg.entity_id)
|
|
51
|
-
if entity and entity.name:
|
|
52
|
-
sender = entity.name
|
|
53
|
-
recent_interactions.append(f"{sender}: {msg.content.text}")
|
|
54
|
-
|
|
55
|
-
if not recent_interactions:
|
|
56
|
-
return EvaluatorResult(
|
|
57
|
-
score=50,
|
|
58
|
-
passed=True,
|
|
59
|
-
reason="No recent interactions to reflect on",
|
|
60
|
-
details={"noInteractions": True},
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
interactions_text = "\n".join(recent_interactions)
|
|
64
|
-
|
|
65
|
-
template = (
|
|
66
|
-
runtime.character.templates.get("reflectionTemplate")
|
|
67
|
-
if runtime.character.templates and "reflectionTemplate" in runtime.character.templates
|
|
68
|
-
else REFLECTION_TEMPLATE
|
|
69
|
-
)
|
|
70
|
-
prompt = runtime.compose_prompt(state=state, template=template)
|
|
71
|
-
prompt = prompt.replace("{{recentInteractions}}", interactions_text)
|
|
72
|
-
|
|
73
|
-
response_text = await runtime.use_model(ModelType.TEXT_LARGE, prompt=prompt)
|
|
74
|
-
parsed_xml = parse_key_value_xml(response_text)
|
|
75
|
-
|
|
76
|
-
if parsed_xml is None:
|
|
77
|
-
raise ValueError("Failed to parse reflection response")
|
|
78
|
-
|
|
79
|
-
quality_str = str(parsed_xml.get("quality_score", "50"))
|
|
80
|
-
quality_score = max(0, min(100, int(quality_str)))
|
|
81
|
-
|
|
82
|
-
thought = str(parsed_xml.get("thought", ""))
|
|
83
|
-
strengths = str(parsed_xml.get("strengths", ""))
|
|
84
|
-
improvements = str(parsed_xml.get("improvements", ""))
|
|
85
|
-
learnings = str(parsed_xml.get("learnings", ""))
|
|
86
|
-
|
|
87
|
-
passed = quality_score >= 50
|
|
88
|
-
|
|
89
|
-
return EvaluatorResult(
|
|
90
|
-
score=quality_score,
|
|
91
|
-
passed=passed,
|
|
92
|
-
reason=f"Strengths: {strengths}\nImprovements: {improvements}",
|
|
93
|
-
details={
|
|
94
|
-
"thought": thought,
|
|
95
|
-
"strengths": strengths,
|
|
96
|
-
"improvements": improvements,
|
|
97
|
-
"learnings": learnings,
|
|
98
|
-
"interactionCount": len(recent_interactions),
|
|
99
|
-
},
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
async def validate_reflection(
|
|
104
|
-
runtime: IAgentRuntime,
|
|
105
|
-
message: Memory,
|
|
106
|
-
_state: State | None = None,
|
|
107
|
-
) -> bool:
|
|
108
|
-
return True
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
async def _reflection_handler(
|
|
112
|
-
runtime: IAgentRuntime,
|
|
113
|
-
message: Memory,
|
|
114
|
-
state: State | None = None,
|
|
115
|
-
options: HandlerOptions | None = None,
|
|
116
|
-
callback: Callable[[Content], Awaitable[list[Memory]]] | None = None,
|
|
117
|
-
responses: list[Memory] | None = None,
|
|
118
|
-
) -> ActionResult | None:
|
|
119
|
-
"""Wrapper handler that matches the expected signature."""
|
|
120
|
-
_ = options, callback, responses # Unused parameters
|
|
121
|
-
result = await evaluate_reflection(runtime, message, state)
|
|
122
|
-
# Return ActionResult - evaluators don't typically return action results
|
|
123
|
-
return ActionResult(text=result.reason, success=result.passed, values={}, data={})
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
reflection_evaluator = Evaluator(
|
|
127
|
-
name=str(_spec["name"]),
|
|
128
|
-
description=str(_spec["description"]),
|
|
129
|
-
similes=list(_spec.get("similes", [])) if _spec.get("similes") else [],
|
|
130
|
-
validate=validate_reflection,
|
|
131
|
-
handler=_reflection_handler,
|
|
132
|
-
always_run=bool(_spec.get("alwaysRun", False)),
|
|
133
|
-
examples=[],
|
|
134
|
-
)
|
|
5
|
+
__all__ = ["reflection_evaluator"]
|