@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.
- 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 +24 -13
- package/elizaos/advanced_capabilities/actions/follow_room.py +29 -29
- package/elizaos/advanced_capabilities/actions/image_generation.py +15 -28
- package/elizaos/advanced_capabilities/actions/mute_room.py +15 -28
- package/elizaos/advanced_capabilities/actions/remove_contact.py +17 -3
- package/elizaos/advanced_capabilities/actions/roles.py +17 -30
- 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 +184 -51
- package/elizaos/advanced_capabilities/actions/settings.py +17 -3
- package/elizaos/advanced_capabilities/actions/unfollow_room.py +15 -28
- package/elizaos/advanced_capabilities/actions/unmute_room.py +15 -28
- package/elizaos/advanced_capabilities/actions/update_contact.py +17 -3
- package/elizaos/advanced_capabilities/actions/update_entity.py +17 -3
- 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 +23 -3
- package/elizaos/advanced_capabilities/services/__init__.py +2 -9
- package/elizaos/advanced_capabilities/services/rolodex.py +2 -2
- package/elizaos/advanced_memory/actions/reset_session.py +143 -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 +69 -27
- package/elizaos/advanced_memory/plugin.py +2 -1
- package/elizaos/advanced_memory/test_advanced_memory.py +357 -0
- package/elizaos/advanced_memory/types.py +2 -2
- 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 +96 -0
- package/elizaos/basic_capabilities/providers/recent_messages.py +5 -0
- package/elizaos/basic_capabilities/providers/relationships.py +113 -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/basic_capabilities/services/embedding.py +10 -7
- package/elizaos/basic_capabilities/services/task.py +3 -3
- package/elizaos/bootstrap/__init__.py +21 -2
- package/elizaos/bootstrap/actions/__init__.py +3 -0
- package/elizaos/bootstrap/actions/reset_session.py +3 -0
- package/elizaos/bootstrap/actions/roles.py +5 -4
- 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 +26 -3
- package/elizaos/bootstrap/providers/providers_list.py +1 -0
- package/elizaos/bootstrap/providers/recent_messages.py +5 -0
- package/elizaos/bootstrap/providers/relationships.py +20 -13
- 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 +206 -8
- package/elizaos/bootstrap/services/rolodex.py +2 -2
- package/elizaos/bootstrap/services/task.py +3 -3
- 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 +4 -4
- package/elizaos/media/search.py +23 -23
- package/elizaos/runtime.py +223 -64
- package/elizaos/services/hook_service.py +3 -3
- 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 +33 -3
- package/elizaos/types/primitives.py +3 -3
- package/elizaos/types/runtime.py +17 -3
- package/elizaos/types/state.py +2 -2
- package/elizaos/utils/streaming.py +3 -3
- package/elizaos/utils/validation.py +76 -0
- package/package.json +4 -3
- package/pyproject.toml +1 -2
- package/requirements-dev.lock +2 -2
- package/requirements.in +1 -2
- package/requirements.lock +2 -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_history_compaction.py +104 -0
- package/tests/test_memory_bounds.py +115 -0
- 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
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import contextlib
|
|
4
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
4
5
|
|
|
5
6
|
from elizaos.action_docs import get_canonical_action_example_calls
|
|
7
|
+
from elizaos.deterministic import (
|
|
8
|
+
build_conversation_seed,
|
|
9
|
+
build_deterministic_seed,
|
|
10
|
+
deterministic_int,
|
|
11
|
+
)
|
|
6
12
|
from elizaos.generated.spec_helpers import require_provider_spec
|
|
7
13
|
from elizaos.types import Provider, ProviderResult
|
|
8
14
|
from elizaos.types.components import ActionExample
|
|
@@ -21,10 +27,6 @@ if TYPE_CHECKING:
|
|
|
21
27
|
_spec = require_provider_spec("ACTIONS")
|
|
22
28
|
|
|
23
29
|
|
|
24
|
-
def format_action_names(actions: list[Action]) -> str:
|
|
25
|
-
return ", ".join(action.name for action in actions)
|
|
26
|
-
|
|
27
|
-
|
|
28
30
|
def _format_parameter_type(schema: ActionParameterSchema) -> str:
|
|
29
31
|
if schema.type == "number" and (schema.minimum is not None or schema.maximum is not None):
|
|
30
32
|
min_val = schema.minimum if schema.minimum is not None else "∞"
|
|
@@ -62,9 +64,23 @@ def _format_action_parameters(parameters: list[ActionParameter]) -> str:
|
|
|
62
64
|
return "\n".join(lines)
|
|
63
65
|
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
T = TypeVar("T")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _deterministic_shuffle(items: list[T], seed: str, surface: str = "shuffle") -> list[T]:
|
|
71
|
+
shuffled = list(items)
|
|
72
|
+
for i in range(len(shuffled) - 1, 0, -1):
|
|
73
|
+
j = deterministic_int(seed, f"{surface}:{i}", i + 1)
|
|
74
|
+
shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
|
|
75
|
+
return shuffled
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def format_actions(actions: list[Action], seed: str | None = None) -> str:
|
|
79
|
+
deterministic_seed = seed or build_deterministic_seed(
|
|
80
|
+
["actions-format", ",".join(action.name for action in actions)]
|
|
81
|
+
)
|
|
66
82
|
lines: list[str] = []
|
|
67
|
-
for action in actions:
|
|
83
|
+
for action in _deterministic_shuffle(actions, deterministic_seed, "actions"):
|
|
68
84
|
line = f"- **{action.name}**: {action.description or 'No description'}"
|
|
69
85
|
if action.parameters:
|
|
70
86
|
params_text = _format_action_parameters(action.parameters)
|
|
@@ -81,7 +97,24 @@ def _replace_name_placeholders(text: str) -> str:
|
|
|
81
97
|
return text
|
|
82
98
|
|
|
83
99
|
|
|
84
|
-
def
|
|
100
|
+
def _replace_name_placeholders_seeded(text: str, seed: str, example_index: int) -> str:
|
|
101
|
+
names = ["Alex", "Jordan", "Sam", "Taylor", "Riley"]
|
|
102
|
+
output = text
|
|
103
|
+
for placeholder_index in range(1, 6):
|
|
104
|
+
name_index = deterministic_int(
|
|
105
|
+
seed,
|
|
106
|
+
f"example:{example_index}:name:{placeholder_index}",
|
|
107
|
+
len(names),
|
|
108
|
+
)
|
|
109
|
+
output = output.replace(f"{{{{name{placeholder_index}}}}}", names[name_index])
|
|
110
|
+
return output
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def format_action_examples(
|
|
114
|
+
actions: list[Action],
|
|
115
|
+
max_examples: int = 10,
|
|
116
|
+
seed: str | None = None,
|
|
117
|
+
) -> str:
|
|
85
118
|
"""
|
|
86
119
|
Format a deterministic subset of action examples for prompt context.
|
|
87
120
|
|
|
@@ -90,27 +123,60 @@ def format_action_examples(actions: list[Action], max_examples: int = 10) -> str
|
|
|
90
123
|
if max_examples <= 0:
|
|
91
124
|
return ""
|
|
92
125
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
examples.append(ex)
|
|
100
|
-
if len(examples) >= max_examples:
|
|
101
|
-
break
|
|
102
|
-
if len(examples) >= max_examples:
|
|
103
|
-
break
|
|
104
|
-
|
|
105
|
-
if not examples:
|
|
126
|
+
actions_with_examples = [
|
|
127
|
+
action
|
|
128
|
+
for action in actions
|
|
129
|
+
if action.examples and isinstance(action.examples, list) and len(action.examples) > 0
|
|
130
|
+
]
|
|
131
|
+
if not actions_with_examples:
|
|
106
132
|
return ""
|
|
107
133
|
|
|
134
|
+
examples_copy: list[list[list[ActionExample]]] = [
|
|
135
|
+
[example for example in (action.examples or []) if isinstance(example, list) and example]
|
|
136
|
+
for action in actions_with_examples
|
|
137
|
+
]
|
|
138
|
+
available_action_indices = [
|
|
139
|
+
idx for idx, action_examples in enumerate(examples_copy) if action_examples
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
selection_seed = seed or build_deterministic_seed(
|
|
143
|
+
[
|
|
144
|
+
"action-examples",
|
|
145
|
+
",".join(action.name for action in actions_with_examples),
|
|
146
|
+
max_examples,
|
|
147
|
+
]
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
selected_examples: list[list[ActionExample]] = []
|
|
151
|
+
iteration = 0
|
|
152
|
+
while len(selected_examples) < max_examples and available_action_indices:
|
|
153
|
+
random_index = deterministic_int(
|
|
154
|
+
selection_seed,
|
|
155
|
+
f"action-index:{iteration}",
|
|
156
|
+
len(available_action_indices),
|
|
157
|
+
)
|
|
158
|
+
action_index = available_action_indices[random_index]
|
|
159
|
+
action_examples = examples_copy[action_index]
|
|
160
|
+
|
|
161
|
+
example_index = deterministic_int(
|
|
162
|
+
selection_seed,
|
|
163
|
+
f"example-index:{iteration}",
|
|
164
|
+
len(action_examples),
|
|
165
|
+
)
|
|
166
|
+
selected_examples.append(action_examples.pop(example_index))
|
|
167
|
+
iteration += 1
|
|
168
|
+
|
|
169
|
+
if not action_examples:
|
|
170
|
+
available_action_indices.pop(random_index)
|
|
171
|
+
|
|
108
172
|
blocks: list[str] = []
|
|
109
|
-
for ex in
|
|
173
|
+
for example_index, ex in enumerate(selected_examples):
|
|
110
174
|
lines: list[str] = []
|
|
111
175
|
for msg in ex:
|
|
112
176
|
msg_text = msg.content.text if msg.content and msg.content.text else ""
|
|
113
|
-
lines.append(
|
|
177
|
+
lines.append(
|
|
178
|
+
f"{msg.name}: {_replace_name_placeholders_seeded(msg_text, selection_seed, example_index)}"
|
|
179
|
+
)
|
|
114
180
|
blocks.append("\n".join(lines))
|
|
115
181
|
|
|
116
182
|
return "\n\n".join(blocks)
|
|
@@ -180,6 +246,17 @@ def format_action_call_examples(actions: list[Action], max_examples: int = 5) ->
|
|
|
180
246
|
return "\n\n".join(blocks)
|
|
181
247
|
|
|
182
248
|
|
|
249
|
+
def format_action_names(actions: list[Action], seed: str | None = None) -> str:
|
|
250
|
+
if not actions:
|
|
251
|
+
return ""
|
|
252
|
+
|
|
253
|
+
deterministic_seed = seed or build_deterministic_seed(
|
|
254
|
+
["action-names", ",".join(action.name for action in actions)]
|
|
255
|
+
)
|
|
256
|
+
shuffled = _deterministic_shuffle(actions, deterministic_seed, "actions")
|
|
257
|
+
return ", ".join(action.name for action in shuffled)
|
|
258
|
+
|
|
259
|
+
|
|
183
260
|
async def get_actions(
|
|
184
261
|
runtime: IAgentRuntime,
|
|
185
262
|
message: Memory,
|
|
@@ -189,13 +266,27 @@ async def get_actions(
|
|
|
189
266
|
|
|
190
267
|
for action in runtime.actions:
|
|
191
268
|
validate_fn = getattr(action, "validate", None) or getattr(action, "validate_fn", None)
|
|
192
|
-
|
|
269
|
+
if not validate_fn:
|
|
270
|
+
is_valid = True
|
|
271
|
+
else:
|
|
272
|
+
try:
|
|
273
|
+
is_valid = await validate_fn(runtime, message, state)
|
|
274
|
+
except Exception:
|
|
275
|
+
if hasattr(runtime, "logger"):
|
|
276
|
+
with contextlib.suppress(Exception):
|
|
277
|
+
runtime.logger.warning(
|
|
278
|
+
f"Action validation failed for {action.name}; excluding from prompt"
|
|
279
|
+
)
|
|
280
|
+
is_valid = False
|
|
193
281
|
if is_valid:
|
|
194
282
|
validated_actions.append(action)
|
|
195
283
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
284
|
+
action_seed = build_conversation_seed(runtime, message, state, "provider:actions")
|
|
285
|
+
action_names = format_action_names(validated_actions, seed=f"{action_seed}:names")
|
|
286
|
+
actions_text = format_actions(validated_actions, seed=f"{action_seed}:descriptions")
|
|
287
|
+
examples_text = format_action_examples(
|
|
288
|
+
validated_actions, max_examples=10, seed=f"{action_seed}:examples"
|
|
289
|
+
)
|
|
199
290
|
call_examples_text = format_action_call_examples(validated_actions, max_examples=5)
|
|
200
291
|
|
|
201
292
|
text_parts: list[str] = [f"Possible response actions: {action_names}"]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from datetime import UTC, datetime
|
|
4
3
|
from typing import TYPE_CHECKING
|
|
5
4
|
|
|
5
|
+
from elizaos.deterministic import get_prompt_reference_datetime
|
|
6
6
|
from elizaos.generated.spec_helpers import require_provider_spec
|
|
7
7
|
from elizaos.types import Provider, ProviderResult
|
|
8
8
|
|
|
@@ -18,7 +18,12 @@ async def get_current_time_context(
|
|
|
18
18
|
message: Memory,
|
|
19
19
|
state: State | None = None,
|
|
20
20
|
) -> ProviderResult:
|
|
21
|
-
now =
|
|
21
|
+
now = get_prompt_reference_datetime(
|
|
22
|
+
runtime,
|
|
23
|
+
message,
|
|
24
|
+
state,
|
|
25
|
+
"provider:current_time",
|
|
26
|
+
)
|
|
22
27
|
|
|
23
28
|
iso_timestamp = now.isoformat()
|
|
24
29
|
human_readable = now.strftime("%A, %B %d, %Y at %H:%M:%S UTC")
|
|
@@ -53,4 +58,5 @@ current_time_provider = Provider(
|
|
|
53
58
|
description=_spec["description"],
|
|
54
59
|
get=get_current_time_context,
|
|
55
60
|
dynamic=_spec.get("dynamic", True),
|
|
61
|
+
position=_spec.get("position"),
|
|
56
62
|
)
|
|
@@ -29,11 +29,33 @@ async def get_knowledge_context(
|
|
|
29
29
|
text="", values={"knowledgeCount": 0, "hasKnowledge": False}, data={"entries": []}
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
limit=5,
|
|
32
|
+
# 1. Fetch recent messages to get embeddings
|
|
33
|
+
recent_messages = await runtime.get_memories(
|
|
34
|
+
room_id=message.room_id, limit=5, table_name="messages"
|
|
35
35
|
)
|
|
36
36
|
|
|
37
|
+
# 2. Extract valid embeddings
|
|
38
|
+
embeddings = [m.embedding for m in recent_messages if m and m.embedding]
|
|
39
|
+
|
|
40
|
+
relevant_knowledge = []
|
|
41
|
+
# 3. Search using the most recent embedding if available
|
|
42
|
+
if embeddings:
|
|
43
|
+
primary_embedding = embeddings[0]
|
|
44
|
+
params = {
|
|
45
|
+
"tableName": "knowledge",
|
|
46
|
+
"roomId": str(message.room_id),
|
|
47
|
+
"embedding": primary_embedding,
|
|
48
|
+
"matchThreshold": 0.75,
|
|
49
|
+
"matchCount": 5,
|
|
50
|
+
"unique": True,
|
|
51
|
+
}
|
|
52
|
+
relevant_knowledge = await runtime.search_memories(params)
|
|
53
|
+
elif query_text:
|
|
54
|
+
# Fallback to search_knowledge if no embeddings found?
|
|
55
|
+
# TS implementation might rely on search_memories logic handling missing embedding?
|
|
56
|
+
# No, TS skips if no embedding.
|
|
57
|
+
pass
|
|
58
|
+
|
|
37
59
|
for entry in relevant_knowledge:
|
|
38
60
|
if entry.content and entry.content.text:
|
|
39
61
|
knowledge_text = entry.content.text
|
|
@@ -70,4 +92,5 @@ knowledge_provider = Provider(
|
|
|
70
92
|
description=_spec["description"],
|
|
71
93
|
get=get_knowledge_context,
|
|
72
94
|
dynamic=_spec.get("dynamic", True),
|
|
95
|
+
position=_spec.get("position"),
|
|
73
96
|
)
|
|
@@ -25,12 +25,17 @@ async def get_recent_messages_context(
|
|
|
25
25
|
|
|
26
26
|
sections: list[str] = []
|
|
27
27
|
message_list: list[dict[str, str | int]] = []
|
|
28
|
+
room = await runtime.get_room(room_id)
|
|
29
|
+
last_compaction_at = None
|
|
30
|
+
if room and getattr(room, "metadata", None):
|
|
31
|
+
last_compaction_at = room.metadata.get("lastCompactionAt")
|
|
28
32
|
|
|
29
33
|
recent_messages = await runtime.get_memories(
|
|
30
34
|
room_id=room_id,
|
|
31
35
|
limit=20,
|
|
32
36
|
order_by="created_at",
|
|
33
37
|
order_direction="desc",
|
|
38
|
+
start=last_compaction_at,
|
|
34
39
|
)
|
|
35
40
|
|
|
36
41
|
recent_messages = list(reversed(recent_messages))
|
|
@@ -39,11 +39,10 @@ async def get_relationships(
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
try:
|
|
42
|
-
relationships = await runtime.get_relationships(entity_id
|
|
42
|
+
relationships = await runtime.get_relationships({"entityId": str(entity_id)})
|
|
43
43
|
except Exception as e:
|
|
44
44
|
runtime.logger.debug(
|
|
45
|
-
|
|
46
|
-
"Failed to get relationships",
|
|
45
|
+
f"Failed to get relationships: src=provider:relationships agentId={runtime.agent_id} error={e}"
|
|
47
46
|
)
|
|
48
47
|
relationships = []
|
|
49
48
|
|
|
@@ -54,24 +53,31 @@ async def get_relationships(
|
|
|
54
53
|
data={"relationships": []},
|
|
55
54
|
)
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
def _get_interactions(relationship: object) -> int:
|
|
57
|
+
if isinstance(relationship, dict):
|
|
58
|
+
metadata = relationship.get("metadata", {})
|
|
59
|
+
if isinstance(metadata, dict):
|
|
60
|
+
value = metadata.get("interactions", 0)
|
|
61
|
+
return int(value) if isinstance(value, (int, float)) else 0
|
|
62
|
+
return 0
|
|
63
|
+
|
|
64
|
+
sorted_relationships = sorted(relationships, key=_get_interactions, reverse=True)[:30]
|
|
62
65
|
|
|
63
66
|
formatted_relationships: list[str] = []
|
|
64
|
-
entity_cache: dict[
|
|
67
|
+
entity_cache: dict[str, str] = {}
|
|
65
68
|
for rel in sorted_relationships:
|
|
69
|
+
if not isinstance(rel, dict):
|
|
70
|
+
continue
|
|
66
71
|
target_id = rel.get("targetEntityId")
|
|
67
72
|
if not target_id:
|
|
68
73
|
continue
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
target_id_str = str(target_id)
|
|
76
|
+
target_name = entity_cache.get(target_id_str)
|
|
71
77
|
if target_name is None:
|
|
72
|
-
target_entity = await runtime.get_entity(
|
|
73
|
-
target_name = target_entity.name if target_entity else
|
|
74
|
-
entity_cache[
|
|
78
|
+
target_entity = await runtime.get_entity(target_id_str)
|
|
79
|
+
target_name = target_entity.name if target_entity else target_id_str[:8]
|
|
80
|
+
entity_cache[target_id_str] = target_name
|
|
75
81
|
|
|
76
82
|
formatted_relationships.append(format_relationship(rel, target_name))
|
|
77
83
|
|
|
@@ -103,4 +109,5 @@ relationships_provider = Provider(
|
|
|
103
109
|
description=_spec["description"],
|
|
104
110
|
get=get_relationships,
|
|
105
111
|
dynamic=_spec.get("dynamic", True),
|
|
112
|
+
position=_spec.get("position"),
|
|
106
113
|
)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from datetime import UTC, datetime
|
|
4
3
|
from typing import TYPE_CHECKING
|
|
5
4
|
|
|
5
|
+
from elizaos.deterministic import get_prompt_reference_datetime
|
|
6
6
|
from elizaos.generated.spec_helpers import require_provider_spec
|
|
7
7
|
from elizaos.types import Provider, ProviderResult
|
|
8
8
|
|
|
@@ -18,9 +18,12 @@ async def get_time_context(
|
|
|
18
18
|
message: Memory,
|
|
19
19
|
state: State | None = None,
|
|
20
20
|
) -> ProviderResult:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
now = get_prompt_reference_datetime(
|
|
22
|
+
runtime,
|
|
23
|
+
message,
|
|
24
|
+
state,
|
|
25
|
+
"provider:time",
|
|
26
|
+
)
|
|
24
27
|
iso_string = now.isoformat()
|
|
25
28
|
timestamp_ms = int(now.timestamp() * 1000)
|
|
26
29
|
human_readable = now.strftime("%A, %B %d, %Y at %H:%M:%S UTC")
|
|
@@ -42,4 +45,5 @@ time_provider = Provider(
|
|
|
42
45
|
description=_spec["description"],
|
|
43
46
|
get=get_time_context,
|
|
44
47
|
dynamic=_spec.get("dynamic", True),
|
|
48
|
+
position=_spec.get("position"),
|
|
45
49
|
)
|