aury-agent 0.0.9__py3-none-any.whl → 0.0.10__py3-none-any.whl

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.
@@ -1,154 +0,0 @@
1
- """RawMessageMiddleware - stores complete messages for HITL recovery.
2
-
3
- This middleware stores complete, untruncated messages to RawMessageStore.
4
- Works alongside MessageBackendMiddleware which stores truncated messages.
5
-
6
- Usage:
7
- raw_store = InMemoryRawMessageStore()
8
- raw_middleware = RawMessageMiddleware(raw_store, persist_raw=False)
9
-
10
- agent = ReactAgent.create(
11
- llm=llm,
12
- middlewares=[raw_middleware, MessageBackendMiddleware()],
13
- )
14
- """
15
- from __future__ import annotations
16
-
17
- from typing import TYPE_CHECKING, Any
18
-
19
- from .base import BaseMiddleware
20
- from .types import HookResult
21
-
22
- if TYPE_CHECKING:
23
- from ..messages.raw_store import RawMessageStore
24
- from ..core.state import State
25
-
26
-
27
- class RawMessageMiddleware(BaseMiddleware):
28
- """Middleware that stores complete messages to RawMessageStore.
29
-
30
- Stores untruncated messages for:
31
- - HITL recovery (restore exact conversation state)
32
- - Full-context recall (when truncated history is insufficient)
33
-
34
- Messages are stored per invocation and can be cleaned up when
35
- the invocation completes (controlled by persist_raw).
36
- """
37
-
38
- def __init__(
39
- self,
40
- raw_store: "RawMessageStore",
41
- persist_raw: bool = False,
42
- state: "State | None" = None,
43
- ):
44
- """Initialize with RawMessageStore.
45
-
46
- Args:
47
- raw_store: RawMessageStore for storing complete messages
48
- persist_raw: Whether to keep messages after invocation completes.
49
- False = clean up after invocation (default)
50
- True = keep forever (for audit/recall)
51
- state: State instance for storing message_ids in execution namespace.
52
- If provided, message IDs are automatically added to
53
- state.execution["message_ids"].
54
- """
55
- self.raw_store = raw_store
56
- self.persist_raw = persist_raw
57
- self.state = state
58
-
59
- # Track message IDs per invocation (for cleanup)
60
- self._invocation_msg_ids: dict[str, list[str]] = {}
61
-
62
- def set_state(self, state: "State") -> None:
63
- """Set state instance (can be set after construction).
64
-
65
- Args:
66
- state: State instance for storing message_ids
67
- """
68
- self.state = state
69
-
70
- async def on_message_save(
71
- self,
72
- message: dict[str, Any],
73
- ) -> dict[str, Any] | None:
74
- """Store complete message to RawMessageStore.
75
-
76
- Args:
77
- message: Complete message dict with 'role', 'content', etc.
78
-
79
- Returns:
80
- The message with added 'raw_msg_id' field
81
- """
82
- from ..core.context import get_current_ctx_or_none
83
- ctx = get_current_ctx_or_none()
84
- invocation_id = ctx.invocation_id if ctx else ""
85
- if not invocation_id:
86
- return message
87
-
88
- # Store to raw store
89
- msg_id = await self.raw_store.add(invocation_id, message)
90
-
91
- # Track for cleanup
92
- if invocation_id not in self._invocation_msg_ids:
93
- self._invocation_msg_ids[invocation_id] = []
94
- self._invocation_msg_ids[invocation_id].append(msg_id)
95
-
96
- # Add to state.execution["message_ids"] if state is available
97
- if self.state:
98
- message_ids = self.state.execution.get("message_ids", [])
99
- message_ids.append(msg_id)
100
- self.state.execution["message_ids"] = message_ids
101
-
102
- # Add msg_id to message for downstream middlewares
103
- message["raw_msg_id"] = msg_id
104
-
105
- return message
106
-
107
- async def on_agent_end(
108
- self,
109
- agent_id: str,
110
- result: Any,
111
- ) -> HookResult:
112
- """Clean up raw messages when invocation completes.
113
-
114
- Only cleans up if persist_raw is False.
115
- """
116
- if self.persist_raw:
117
- return HookResult.proceed()
118
-
119
- from ..core.context import get_current_ctx_or_none
120
- ctx = get_current_ctx_or_none()
121
- invocation_id = ctx.invocation_id if ctx else ""
122
- if invocation_id:
123
- await self._cleanup_invocation(invocation_id)
124
-
125
- return HookResult.proceed()
126
-
127
- async def _cleanup_invocation(self, invocation_id: str) -> int:
128
- """Clean up raw messages for an invocation.
129
-
130
- Args:
131
- invocation_id: Invocation ID to clean up
132
-
133
- Returns:
134
- Number of messages deleted
135
- """
136
- # Remove from tracking
137
- self._invocation_msg_ids.pop(invocation_id, None)
138
-
139
- # Delete from store
140
- return await self.raw_store.delete_by_invocation(invocation_id)
141
-
142
- def get_message_ids(self, invocation_id: str) -> list[str]:
143
- """Get tracked message IDs for an invocation.
144
-
145
- Args:
146
- invocation_id: Invocation ID
147
-
148
- Returns:
149
- List of message IDs
150
- """
151
- return self._invocation_msg_ids.get(invocation_id, []).copy()
152
-
153
-
154
- __all__ = ["RawMessageMiddleware"]