@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
package/elizaos/__init__.py
CHANGED
|
@@ -108,7 +108,6 @@ from elizaos.types import (
|
|
|
108
108
|
string_to_uuid,
|
|
109
109
|
)
|
|
110
110
|
from elizaos.types.database import IDatabaseAdapter # noqa: E402
|
|
111
|
-
from elizaos.types.environment import ChannelType # noqa: E402
|
|
112
111
|
from elizaos.types.primitives import ( # noqa: E402
|
|
113
112
|
ChannelType,
|
|
114
113
|
Content,
|
|
@@ -1,85 +1,50 @@
|
|
|
1
1
|
"""Advanced Capabilities - Extended features for agent operation.
|
|
2
2
|
|
|
3
3
|
This module provides advanced capabilities that can be enabled with
|
|
4
|
-
`advanced_capabilities=True` or `enable_extended=True
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
- Extended services (rolodex, follow-up scheduling)
|
|
4
|
+
`advanced_capabilities=True` or `enable_extended=True`.
|
|
5
|
+
|
|
6
|
+
Relationship/contact extraction and social-memory features are owned by
|
|
7
|
+
`plugin-rolodex` and are intentionally not auto-registered here.
|
|
9
8
|
"""
|
|
10
9
|
|
|
11
10
|
from .actions import (
|
|
12
|
-
add_contact_action,
|
|
13
11
|
advanced_actions,
|
|
14
12
|
follow_room_action,
|
|
15
13
|
generate_image_action,
|
|
16
14
|
mute_room_action,
|
|
17
|
-
remove_contact_action,
|
|
18
|
-
schedule_follow_up_action,
|
|
19
|
-
search_contacts_action,
|
|
20
|
-
send_message_action,
|
|
21
15
|
unfollow_room_action,
|
|
22
16
|
unmute_room_action,
|
|
23
|
-
update_contact_action,
|
|
24
|
-
update_entity_action,
|
|
25
17
|
update_role_action,
|
|
26
18
|
update_settings_action,
|
|
27
19
|
)
|
|
28
|
-
from .evaluators import
|
|
29
|
-
advanced_evaluators,
|
|
30
|
-
reflection_evaluator,
|
|
31
|
-
relationship_extraction_evaluator,
|
|
32
|
-
)
|
|
20
|
+
from .evaluators import advanced_evaluators
|
|
33
21
|
from .providers import (
|
|
34
22
|
advanced_providers,
|
|
35
23
|
agent_settings_provider,
|
|
36
|
-
contacts_provider,
|
|
37
|
-
facts_provider,
|
|
38
|
-
follow_ups_provider,
|
|
39
24
|
knowledge_provider,
|
|
40
|
-
relationships_provider,
|
|
41
25
|
roles_provider,
|
|
42
26
|
settings_provider,
|
|
43
27
|
)
|
|
44
|
-
from .services import
|
|
45
|
-
FollowUpService,
|
|
46
|
-
RolodexService,
|
|
47
|
-
advanced_services,
|
|
48
|
-
)
|
|
28
|
+
from .services import advanced_services
|
|
49
29
|
|
|
50
30
|
__all__ = [
|
|
51
31
|
# Actions
|
|
52
32
|
"advanced_actions",
|
|
53
|
-
"add_contact_action",
|
|
54
33
|
"follow_room_action",
|
|
55
34
|
"generate_image_action",
|
|
56
35
|
"mute_room_action",
|
|
57
|
-
"remove_contact_action",
|
|
58
|
-
"schedule_follow_up_action",
|
|
59
|
-
"search_contacts_action",
|
|
60
|
-
"send_message_action",
|
|
61
36
|
"unfollow_room_action",
|
|
62
37
|
"unmute_room_action",
|
|
63
|
-
"update_contact_action",
|
|
64
|
-
"update_entity_action",
|
|
65
38
|
"update_role_action",
|
|
66
39
|
"update_settings_action",
|
|
67
40
|
# Providers
|
|
68
41
|
"advanced_providers",
|
|
69
42
|
"agent_settings_provider",
|
|
70
|
-
"contacts_provider",
|
|
71
|
-
"facts_provider",
|
|
72
|
-
"follow_ups_provider",
|
|
73
43
|
"knowledge_provider",
|
|
74
|
-
"relationships_provider",
|
|
75
44
|
"roles_provider",
|
|
76
45
|
"settings_provider",
|
|
77
46
|
# Evaluators
|
|
78
47
|
"advanced_evaluators",
|
|
79
|
-
"reflection_evaluator",
|
|
80
|
-
"relationship_extraction_evaluator",
|
|
81
48
|
# Services
|
|
82
49
|
"advanced_services",
|
|
83
|
-
"FollowUpService",
|
|
84
|
-
"RolodexService",
|
|
85
50
|
]
|
|
@@ -3,52 +3,32 @@
|
|
|
3
3
|
Extended actions that can be enabled with `advanced_capabilities=True`.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from .add_contact import add_contact_action
|
|
7
6
|
from .follow_room import follow_room_action
|
|
8
7
|
from .image_generation import generate_image_action
|
|
9
8
|
from .mute_room import mute_room_action
|
|
10
|
-
from .remove_contact import remove_contact_action
|
|
11
9
|
from .roles import update_role_action
|
|
12
|
-
from .schedule_follow_up import schedule_follow_up_action
|
|
13
|
-
from .search_contacts import search_contacts_action
|
|
14
|
-
from .send_message import send_message_action
|
|
15
10
|
from .settings import update_settings_action
|
|
16
11
|
from .unfollow_room import unfollow_room_action
|
|
17
12
|
from .unmute_room import unmute_room_action
|
|
18
|
-
from .update_contact import update_contact_action
|
|
19
|
-
from .update_entity import update_entity_action
|
|
20
13
|
|
|
21
14
|
__all__ = [
|
|
22
|
-
"add_contact_action",
|
|
23
15
|
"follow_room_action",
|
|
24
16
|
"generate_image_action",
|
|
25
17
|
"mute_room_action",
|
|
26
|
-
"remove_contact_action",
|
|
27
|
-
"schedule_follow_up_action",
|
|
28
|
-
"search_contacts_action",
|
|
29
|
-
"send_message_action",
|
|
30
18
|
"unfollow_room_action",
|
|
31
19
|
"unmute_room_action",
|
|
32
|
-
"update_contact_action",
|
|
33
|
-
"update_entity_action",
|
|
34
20
|
"update_role_action",
|
|
35
21
|
"update_settings_action",
|
|
36
22
|
"advanced_actions",
|
|
37
23
|
]
|
|
38
24
|
|
|
25
|
+
# Rolodex/contact actions are provided by plugin-rolodex.
|
|
39
26
|
advanced_actions = [
|
|
40
|
-
add_contact_action,
|
|
41
27
|
follow_room_action,
|
|
42
28
|
generate_image_action,
|
|
43
29
|
mute_room_action,
|
|
44
|
-
remove_contact_action,
|
|
45
|
-
schedule_follow_up_action,
|
|
46
|
-
search_contacts_action,
|
|
47
|
-
send_message_action,
|
|
48
30
|
unfollow_room_action,
|
|
49
31
|
unmute_room_action,
|
|
50
|
-
update_contact_action,
|
|
51
|
-
update_entity_action,
|
|
52
32
|
update_role_action,
|
|
53
33
|
update_settings_action,
|
|
54
34
|
]
|
|
@@ -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("ADD_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
|
|
@@ -89,18 +103,14 @@ class AddContactAction:
|
|
|
89
103
|
notes = str(parsed.get("notes", ""))
|
|
90
104
|
reason = str(parsed.get("reason", ""))
|
|
91
105
|
|
|
92
|
-
from uuid import UUID as StdUUID
|
|
93
|
-
|
|
94
106
|
entity_id = message.entity_id
|
|
95
|
-
entity_id_uuid = StdUUID(str(entity_id)) if entity_id else None
|
|
96
107
|
preferences = ContactPreferences(notes=notes) if notes else None
|
|
97
108
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
109
|
+
await rolodex_service.add_contact(
|
|
110
|
+
entity_id=entity_id,
|
|
111
|
+
categories=categories,
|
|
112
|
+
preferences=preferences,
|
|
113
|
+
)
|
|
104
114
|
|
|
105
115
|
response_text = (
|
|
106
116
|
f"I've added {contact_name} to your contacts as {', '.join(categories)}. {reason}"
|
|
@@ -3,27 +3,41 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
|
+
from elizaos.generated.spec_helpers import require_action_spec
|
|
6
7
|
from elizaos.types import Action, ActionExample, ActionResult, Content
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
9
10
|
from elizaos.types import HandlerCallback, HandlerOptions, IAgentRuntime, Memory, State
|
|
10
11
|
|
|
12
|
+
# Get text content from centralized specs
|
|
13
|
+
_spec = require_action_spec("FOLLOW_ROOM")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
17
|
+
"""Convert spec examples to ActionExample format."""
|
|
18
|
+
spec_examples = _spec.get("examples", [])
|
|
19
|
+
if spec_examples:
|
|
20
|
+
return [
|
|
21
|
+
[
|
|
22
|
+
ActionExample(
|
|
23
|
+
name=msg.get("name", ""),
|
|
24
|
+
content=Content(
|
|
25
|
+
text=msg.get("content", {}).get("text", ""),
|
|
26
|
+
actions=msg.get("content", {}).get("actions"),
|
|
27
|
+
),
|
|
28
|
+
)
|
|
29
|
+
for msg in example
|
|
30
|
+
]
|
|
31
|
+
for example in spec_examples
|
|
32
|
+
]
|
|
33
|
+
return []
|
|
34
|
+
|
|
11
35
|
|
|
12
36
|
@dataclass
|
|
13
37
|
class FollowRoomAction:
|
|
14
|
-
name: str = "
|
|
15
|
-
similes: list[str] = field(
|
|
16
|
-
|
|
17
|
-
"JOIN_ROOM",
|
|
18
|
-
"SUBSCRIBE_ROOM",
|
|
19
|
-
"WATCH_ROOM",
|
|
20
|
-
"ENTER_ROOM",
|
|
21
|
-
]
|
|
22
|
-
)
|
|
23
|
-
description: str = (
|
|
24
|
-
"Follow a room to receive updates and monitor messages. "
|
|
25
|
-
"Use this when you want to actively engage with a room's content."
|
|
26
|
-
)
|
|
38
|
+
name: str = _spec["name"]
|
|
39
|
+
similes: list[str] = field(default_factory=lambda: list(_spec.get("similes", [])))
|
|
40
|
+
description: str = _spec["description"]
|
|
27
41
|
|
|
28
42
|
async def validate(
|
|
29
43
|
self, runtime: IAgentRuntime, message: Memory, _state: State | None = None
|
|
@@ -124,21 +138,7 @@ class FollowRoomAction:
|
|
|
124
138
|
|
|
125
139
|
@property
|
|
126
140
|
def examples(self) -> list[list[ActionExample]]:
|
|
127
|
-
return
|
|
128
|
-
[
|
|
129
|
-
ActionExample(
|
|
130
|
-
name="{{name1}}",
|
|
131
|
-
content=Content(text="Can you keep an eye on this channel?"),
|
|
132
|
-
),
|
|
133
|
-
ActionExample(
|
|
134
|
-
name="{{name2}}",
|
|
135
|
-
content=Content(
|
|
136
|
-
text="I'll follow this room and monitor its activity.",
|
|
137
|
-
actions=["FOLLOW_ROOM"],
|
|
138
|
-
),
|
|
139
|
-
),
|
|
140
|
-
],
|
|
141
|
-
]
|
|
141
|
+
return _convert_spec_examples()
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
follow_room_action = Action(
|
|
@@ -18,34 +18,21 @@ _spec = require_action_spec("GENERATE_IMAGE")
|
|
|
18
18
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
19
19
|
"""Convert spec examples to ActionExample format."""
|
|
20
20
|
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(
|
|
21
|
+
if spec_examples:
|
|
22
|
+
return [
|
|
23
|
+
[
|
|
41
24
|
ActionExample(
|
|
42
|
-
name=
|
|
43
|
-
content=Content(
|
|
25
|
+
name=msg.get("name", ""),
|
|
26
|
+
content=Content(
|
|
27
|
+
text=msg.get("content", {}).get("text", ""),
|
|
28
|
+
actions=msg.get("content", {}).get("actions"),
|
|
29
|
+
),
|
|
44
30
|
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
31
|
+
for msg in example
|
|
32
|
+
]
|
|
33
|
+
for example in spec_examples
|
|
34
|
+
]
|
|
35
|
+
return []
|
|
49
36
|
|
|
50
37
|
|
|
51
38
|
@dataclass
|
|
@@ -16,34 +16,21 @@ _spec = require_action_spec("MUTE_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("REMOVE_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
|
|
@@ -7,7 +7,6 @@ from uuid import UUID
|
|
|
7
7
|
|
|
8
8
|
from elizaos.bootstrap.utils.xml import parse_key_value_xml
|
|
9
9
|
from elizaos.generated.spec_helpers import require_action_spec
|
|
10
|
-
from elizaos.prompts import UPDATE_ROLE_TEMPLATE
|
|
11
10
|
from elizaos.types import Action, ActionExample, ActionResult, Content, ModelType
|
|
12
11
|
|
|
13
12
|
if TYPE_CHECKING:
|
|
@@ -20,34 +19,21 @@ _spec = require_action_spec("UPDATE_ROLE")
|
|
|
20
19
|
def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
21
20
|
"""Convert spec examples to ActionExample format."""
|
|
22
21
|
spec_examples = _spec.get("examples", [])
|
|
23
|
-
if
|
|
24
|
-
return [
|
|
25
|
-
|
|
26
|
-
for example in spec_examples:
|
|
27
|
-
if not isinstance(example, list):
|
|
28
|
-
continue
|
|
29
|
-
row: list[ActionExample] = []
|
|
30
|
-
for msg in example:
|
|
31
|
-
if not isinstance(msg, dict):
|
|
32
|
-
continue
|
|
33
|
-
content = msg.get("content", {})
|
|
34
|
-
text = ""
|
|
35
|
-
actions: list[str] | None = None
|
|
36
|
-
if isinstance(content, dict):
|
|
37
|
-
text_val = content.get("text", "")
|
|
38
|
-
text = str(text_val) if text_val else ""
|
|
39
|
-
actions_val = content.get("actions")
|
|
40
|
-
if isinstance(actions_val, list) and all(isinstance(a, str) for a in actions_val):
|
|
41
|
-
actions = list(actions_val)
|
|
42
|
-
row.append(
|
|
22
|
+
if spec_examples:
|
|
23
|
+
return [
|
|
24
|
+
[
|
|
43
25
|
ActionExample(
|
|
44
|
-
name=
|
|
45
|
-
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
|
+
),
|
|
46
31
|
)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
32
|
+
for msg in example
|
|
33
|
+
]
|
|
34
|
+
for example in spec_examples
|
|
35
|
+
]
|
|
36
|
+
return []
|
|
51
37
|
|
|
52
38
|
|
|
53
39
|
class Role(str, Enum):
|
|
@@ -3,8 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
|
+
from uuid import UUID as StdUUID
|
|
6
7
|
|
|
7
8
|
from elizaos.bootstrap.utils.xml import parse_key_value_xml
|
|
9
|
+
from elizaos.deterministic import get_prompt_reference_datetime
|
|
8
10
|
from elizaos.generated.spec_helpers import require_action_spec
|
|
9
11
|
from elizaos.prompts import SCHEDULE_FOLLOW_UP_TEMPLATE
|
|
10
12
|
from elizaos.types import (
|
|
@@ -34,6 +36,25 @@ def _convert_spec_examples() -> list[list[ActionExample]]:
|
|
|
34
36
|
return convert_spec_examples(_spec)
|
|
35
37
|
|
|
36
38
|
|
|
39
|
+
def _normalize_priority(raw_priority: str) -> str:
|
|
40
|
+
normalized = raw_priority.strip().lower()
|
|
41
|
+
if normalized in {"high", "medium", "low"}:
|
|
42
|
+
return normalized
|
|
43
|
+
return "medium"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _coerce_uuid(value: object | None) -> StdUUID | None:
|
|
47
|
+
if value is None:
|
|
48
|
+
return None
|
|
49
|
+
text = str(value).strip()
|
|
50
|
+
if not text:
|
|
51
|
+
return None
|
|
52
|
+
try:
|
|
53
|
+
return StdUUID(text)
|
|
54
|
+
except ValueError:
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
37
58
|
@dataclass
|
|
38
59
|
class ScheduleFollowUpAction:
|
|
39
60
|
name: str = _spec["name"]
|
|
@@ -79,7 +100,12 @@ class ScheduleFollowUpAction:
|
|
|
79
100
|
)
|
|
80
101
|
|
|
81
102
|
state = await runtime.compose_state(message, ["RECENT_MESSAGES", "ENTITIES"])
|
|
82
|
-
state.values["currentDateTime"] =
|
|
103
|
+
state.values["currentDateTime"] = get_prompt_reference_datetime(
|
|
104
|
+
runtime,
|
|
105
|
+
message,
|
|
106
|
+
state,
|
|
107
|
+
"action:schedule_follow_up",
|
|
108
|
+
).isoformat()
|
|
83
109
|
|
|
84
110
|
prompt = runtime.compose_prompt_from_state(
|
|
85
111
|
state=state,
|
|
@@ -100,24 +126,53 @@ class ScheduleFollowUpAction:
|
|
|
100
126
|
contact_name = str(parsed.get("contactName", ""))
|
|
101
127
|
scheduled_at_str = str(parsed.get("scheduledAt", ""))
|
|
102
128
|
reason = str(parsed.get("reason", "Follow-up"))
|
|
103
|
-
priority = str(parsed.get("priority", "medium"))
|
|
129
|
+
priority = _normalize_priority(str(parsed.get("priority", "medium")))
|
|
104
130
|
follow_up_message = str(parsed.get("message", ""))
|
|
131
|
+
parsed_entity_id = _coerce_uuid(parsed.get("entityId"))
|
|
132
|
+
message_entity_id = _coerce_uuid(message.entity_id)
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
scheduled_at = datetime.fromisoformat(scheduled_at_str.replace("Z", "+00:00"))
|
|
136
|
+
except ValueError:
|
|
137
|
+
return ActionResult(
|
|
138
|
+
text="Could not parse the follow-up date/time",
|
|
139
|
+
success=False,
|
|
140
|
+
values={"error": True},
|
|
141
|
+
data={"error": "Invalid follow-up datetime"},
|
|
142
|
+
)
|
|
105
143
|
|
|
106
|
-
|
|
144
|
+
entity_id_uuid = parsed_entity_id or message_entity_id
|
|
107
145
|
|
|
108
|
-
|
|
146
|
+
if entity_id_uuid is None and contact_name:
|
|
147
|
+
contacts = await rolodex_service.search_contacts(search_term=contact_name)
|
|
148
|
+
if contacts:
|
|
149
|
+
entity_id_uuid = contacts[0].entity_id
|
|
109
150
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
reason=reason,
|
|
117
|
-
priority=priority,
|
|
118
|
-
message=follow_up_message,
|
|
151
|
+
if entity_id_uuid is None:
|
|
152
|
+
return ActionResult(
|
|
153
|
+
text=f"Could not determine which contact to schedule for ({contact_name}).",
|
|
154
|
+
success=False,
|
|
155
|
+
values={"error": True},
|
|
156
|
+
data={"error": "Missing contact entity id"},
|
|
119
157
|
)
|
|
120
158
|
|
|
159
|
+
contact = await rolodex_service.get_contact(entity_id_uuid)
|
|
160
|
+
if contact is None:
|
|
161
|
+
return ActionResult(
|
|
162
|
+
text=f"Contact '{contact_name}' was not found in the rolodex.",
|
|
163
|
+
success=False,
|
|
164
|
+
values={"error": True},
|
|
165
|
+
data={"error": "Contact not found"},
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
await follow_up_service.schedule_follow_up(
|
|
169
|
+
entity_id=entity_id_uuid,
|
|
170
|
+
scheduled_at=scheduled_at,
|
|
171
|
+
reason=reason,
|
|
172
|
+
priority=priority,
|
|
173
|
+
message=follow_up_message,
|
|
174
|
+
)
|
|
175
|
+
|
|
121
176
|
response_text = f"I've scheduled a follow-up with {contact_name} for {scheduled_at.strftime('%B %d, %Y')}. Reason: {reason}"
|
|
122
177
|
|
|
123
178
|
if callback:
|
|
@@ -127,11 +182,11 @@ class ScheduleFollowUpAction:
|
|
|
127
182
|
text=response_text,
|
|
128
183
|
success=True,
|
|
129
184
|
values={
|
|
130
|
-
"contactId": str(
|
|
185
|
+
"contactId": str(entity_id_uuid),
|
|
131
186
|
"scheduledAt": scheduled_at.isoformat(),
|
|
132
187
|
},
|
|
133
188
|
data={
|
|
134
|
-
"contactId": str(
|
|
189
|
+
"contactId": str(entity_id_uuid),
|
|
135
190
|
"contactName": contact_name,
|
|
136
191
|
"scheduledAt": scheduled_at.isoformat(),
|
|
137
192
|
"reason": reason,
|
|
@@ -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("SEARCH_CONTACTS")
|
|
|
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
|
|
@@ -95,7 +109,7 @@ class SearchContactsAction:
|
|
|
95
109
|
|
|
96
110
|
contact_details: list[dict[str, str]] = []
|
|
97
111
|
for contact in contacts:
|
|
98
|
-
entity = await runtime.get_entity(
|
|
112
|
+
entity = await runtime.get_entity(contact.entity_id)
|
|
99
113
|
name = entity.name if entity and entity.name else "Unknown"
|
|
100
114
|
contact_details.append(
|
|
101
115
|
{
|