aury-agent 0.0.9__py3-none-any.whl → 0.0.11__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.
- aury/agents/backends/__init__.py +2 -3
- aury/agents/backends/message/__init__.py +1 -2
- aury/agents/backends/message/memory.py +15 -37
- aury/agents/backends/message/types.py +5 -32
- aury/agents/context_providers/message.py +0 -1
- aury/agents/core/context.py +3 -3
- aury/agents/core/types/tool.py +47 -7
- aury/agents/llm/adapter.py +3 -0
- aury/agents/llm/provider.py +43 -4
- aury/agents/messages/__init__.py +0 -9
- aury/agents/middleware/__init__.py +0 -2
- aury/agents/middleware/base.py +35 -5
- aury/agents/middleware/chain.py +64 -8
- aury/agents/middleware/message.py +5 -53
- aury/agents/react/factory.py +11 -6
- aury/agents/react/persistence.py +12 -2
- aury/agents/react/step.py +72 -6
- aury/agents/react/tools.py +20 -4
- aury/agents/tool/decorator.py +5 -20
- {aury_agent-0.0.9.dist-info → aury_agent-0.0.11.dist-info}/METADATA +1 -1
- {aury_agent-0.0.9.dist-info → aury_agent-0.0.11.dist-info}/RECORD +23 -25
- aury/agents/messages/raw_store.py +0 -224
- aury/agents/middleware/raw_message.py +0 -154
- {aury_agent-0.0.9.dist-info → aury_agent-0.0.11.dist-info}/WHEEL +0 -0
- {aury_agent-0.0.9.dist-info → aury_agent-0.0.11.dist-info}/entry_points.txt +0 -0
aury/agents/middleware/chain.py
CHANGED
|
@@ -163,32 +163,44 @@ class MiddlewareChain:
|
|
|
163
163
|
logger.debug("Error processing completed")
|
|
164
164
|
return current
|
|
165
165
|
|
|
166
|
-
async def
|
|
166
|
+
async def process_text_stream(
|
|
167
167
|
self,
|
|
168
168
|
chunk: dict[str, Any],
|
|
169
169
|
) -> dict[str, Any] | None:
|
|
170
|
-
"""Process streaming chunk through middlewares based on trigger mode."""
|
|
171
|
-
text = chunk.get("
|
|
170
|
+
"""Process text streaming chunk through middlewares based on trigger mode."""
|
|
171
|
+
text = chunk.get("delta", "")
|
|
172
172
|
self._token_buffer += text
|
|
173
173
|
self._token_count += 1
|
|
174
174
|
|
|
175
175
|
current = chunk
|
|
176
|
-
triggered_count = 0
|
|
177
176
|
|
|
178
177
|
for i, mw in enumerate(self._middlewares):
|
|
179
178
|
should_trigger = self._should_trigger(mw, text)
|
|
180
179
|
|
|
181
180
|
if should_trigger:
|
|
182
|
-
|
|
183
|
-
result = await mw.on_model_stream(current)
|
|
181
|
+
result = await mw.on_text_stream(current)
|
|
184
182
|
if result is None:
|
|
185
|
-
logger.info(f"Middleware #{i} blocked stream chunk")
|
|
186
183
|
return None
|
|
187
184
|
current = result
|
|
188
185
|
|
|
189
186
|
# Log only every 50 tokens to reduce noise
|
|
190
187
|
if self._token_count % 50 == 0:
|
|
191
|
-
logger.debug(f"
|
|
188
|
+
logger.debug(f"Text stream progress: token_count={self._token_count}")
|
|
189
|
+
|
|
190
|
+
return current
|
|
191
|
+
|
|
192
|
+
async def process_thinking_stream(
|
|
193
|
+
self,
|
|
194
|
+
chunk: dict[str, Any],
|
|
195
|
+
) -> dict[str, Any] | None:
|
|
196
|
+
"""Process thinking streaming chunk through all middlewares."""
|
|
197
|
+
current = chunk
|
|
198
|
+
|
|
199
|
+
for i, mw in enumerate(self._middlewares):
|
|
200
|
+
result = await mw.on_thinking_stream(current)
|
|
201
|
+
if result is None:
|
|
202
|
+
return None
|
|
203
|
+
current = result
|
|
192
204
|
|
|
193
205
|
return current
|
|
194
206
|
|
|
@@ -241,6 +253,50 @@ class MiddlewareChain:
|
|
|
241
253
|
boundaries = (".", "。", "\n", "!", "?", "!", "?", ";", ";")
|
|
242
254
|
return text.rstrip().endswith(boundaries)
|
|
243
255
|
|
|
256
|
+
async def process_text_stream_end(self) -> list[dict[str, Any]]:
|
|
257
|
+
"""Process text stream end through all middlewares.
|
|
258
|
+
|
|
259
|
+
Called when text stream ends, before on_response.
|
|
260
|
+
Allows middlewares to flush any buffered content.
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
List of final chunks to emit (may be empty)
|
|
264
|
+
"""
|
|
265
|
+
final_chunks: list[dict[str, Any]] = []
|
|
266
|
+
logger.debug(f"Processing text_stream_end through {len(self._middlewares)} middlewares")
|
|
267
|
+
|
|
268
|
+
for i, mw in enumerate(self._middlewares):
|
|
269
|
+
if hasattr(mw, 'on_text_stream_end'):
|
|
270
|
+
result = await mw.on_text_stream_end()
|
|
271
|
+
if result is not None:
|
|
272
|
+
logger.debug(f"Middleware #{i} returned final chunk on text_stream_end")
|
|
273
|
+
final_chunks.append(result)
|
|
274
|
+
|
|
275
|
+
logger.debug(f"Text stream end processing completed, {len(final_chunks)} final chunks")
|
|
276
|
+
return final_chunks
|
|
277
|
+
|
|
278
|
+
async def process_thinking_stream_end(self) -> list[dict[str, Any]]:
|
|
279
|
+
"""Process thinking stream end through all middlewares.
|
|
280
|
+
|
|
281
|
+
Called when thinking stream ends.
|
|
282
|
+
Allows middlewares to flush any buffered thinking content.
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
List of final thinking chunks to emit (may be empty)
|
|
286
|
+
"""
|
|
287
|
+
final_chunks: list[dict[str, Any]] = []
|
|
288
|
+
logger.debug(f"Processing thinking_stream_end through {len(self._middlewares)} middlewares")
|
|
289
|
+
|
|
290
|
+
for i, mw in enumerate(self._middlewares):
|
|
291
|
+
if hasattr(mw, 'on_thinking_stream_end'):
|
|
292
|
+
result = await mw.on_thinking_stream_end()
|
|
293
|
+
if result is not None:
|
|
294
|
+
logger.debug(f"Middleware #{i} returned final chunk on thinking_stream_end")
|
|
295
|
+
final_chunks.append(result)
|
|
296
|
+
|
|
297
|
+
logger.debug(f"Thinking stream end processing completed, {len(final_chunks)} final chunks")
|
|
298
|
+
return final_chunks
|
|
299
|
+
|
|
244
300
|
def reset_stream_state(self) -> None:
|
|
245
301
|
"""Reset streaming state (call at start of new stream)."""
|
|
246
302
|
logger.debug("Resetting stream state")
|
|
@@ -21,15 +21,10 @@ if TYPE_CHECKING:
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class MessageBackendMiddleware(BaseMiddleware):
|
|
24
|
-
"""Middleware that persists messages
|
|
24
|
+
"""Middleware that persists messages via MessageBackend.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Features:
|
|
30
|
-
- Saves both truncated (for LLM context) and raw (for audit) messages
|
|
31
|
-
- Supports namespace isolation for sub-agents
|
|
32
|
-
- Works with any MessageBackend implementation
|
|
26
|
+
Simple middleware that passes messages to the backend.
|
|
27
|
+
Storage details (raw/truncated handling) are left to the application layer.
|
|
33
28
|
|
|
34
29
|
Example:
|
|
35
30
|
agent = ReactAgent.create(
|
|
@@ -38,21 +33,6 @@ class MessageBackendMiddleware(BaseMiddleware):
|
|
|
38
33
|
)
|
|
39
34
|
"""
|
|
40
35
|
|
|
41
|
-
def __init__(
|
|
42
|
-
self,
|
|
43
|
-
*,
|
|
44
|
-
save_raw: bool = False,
|
|
45
|
-
max_history: int = 100,
|
|
46
|
-
):
|
|
47
|
-
"""Initialize MessageBackendMiddleware.
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
save_raw: Also save raw (untruncated) messages for audit
|
|
51
|
-
max_history: Max messages to keep in history (for truncation)
|
|
52
|
-
"""
|
|
53
|
-
self.save_raw = save_raw
|
|
54
|
-
self.max_history = max_history
|
|
55
|
-
|
|
56
36
|
async def on_message_save(
|
|
57
37
|
self,
|
|
58
38
|
message: dict[str, Any],
|
|
@@ -78,45 +58,17 @@ class MessageBackendMiddleware(BaseMiddleware):
|
|
|
78
58
|
return message
|
|
79
59
|
|
|
80
60
|
backend = ctx.backends.message
|
|
81
|
-
|
|
82
|
-
# Extract message fields
|
|
83
|
-
role = message.get("role", "")
|
|
84
|
-
content = message.get("content", "")
|
|
85
61
|
invocation_id = ctx.invocation_id or ""
|
|
86
62
|
agent_id = ctx.agent_id
|
|
87
|
-
tool_call_id = message.get("tool_call_id")
|
|
88
|
-
|
|
89
|
-
# Build message dict for backend
|
|
90
|
-
msg_dict = {
|
|
91
|
-
"role": role,
|
|
92
|
-
"content": content,
|
|
93
|
-
}
|
|
94
|
-
if tool_call_id:
|
|
95
|
-
msg_dict["tool_call_id"] = tool_call_id
|
|
96
63
|
|
|
97
|
-
#
|
|
98
|
-
if "tool_calls" in message:
|
|
99
|
-
msg_dict["tool_calls"] = message["tool_calls"]
|
|
100
|
-
|
|
101
|
-
# Save truncated message (for LLM context)
|
|
64
|
+
# Save message
|
|
102
65
|
await backend.add(
|
|
103
66
|
session_id=session_id,
|
|
104
|
-
message=
|
|
105
|
-
type="truncated",
|
|
67
|
+
message=message,
|
|
106
68
|
agent_id=agent_id,
|
|
107
69
|
invocation_id=invocation_id,
|
|
108
70
|
)
|
|
109
71
|
|
|
110
|
-
# Optionally save raw message (for audit)
|
|
111
|
-
if self.save_raw:
|
|
112
|
-
await backend.add(
|
|
113
|
-
session_id=session_id,
|
|
114
|
-
message=message, # Full original message
|
|
115
|
-
type="raw",
|
|
116
|
-
agent_id=agent_id,
|
|
117
|
-
invocation_id=invocation_id,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
72
|
# Pass through to other middlewares
|
|
121
73
|
return message
|
|
122
74
|
|
aury/agents/react/factory.py
CHANGED
|
@@ -40,6 +40,7 @@ def create_react_agent(
|
|
|
40
40
|
snapshot: "SnapshotBackend | None" = None,
|
|
41
41
|
# ContextProvider system
|
|
42
42
|
context_providers: "list[ContextProvider] | None" = None,
|
|
43
|
+
message_provider: "ContextProvider | None" = None,
|
|
43
44
|
enable_history: bool = True,
|
|
44
45
|
history_limit: int = 50,
|
|
45
46
|
# Tool customization
|
|
@@ -64,8 +65,9 @@ def create_react_agent(
|
|
|
64
65
|
memory: Memory manager (optional)
|
|
65
66
|
snapshot: Snapshot backend (optional)
|
|
66
67
|
context_providers: Additional custom context providers (optional)
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
message_provider: Custom message context provider (replaces default MessageContextProvider)
|
|
69
|
+
enable_history: Enable message history (default True, ignored if message_provider is set)
|
|
70
|
+
history_limit: Max conversation turns to keep (default 50, ignored if message_provider is set)
|
|
69
71
|
delegate_tool_class: Custom DelegateTool class (optional)
|
|
70
72
|
|
|
71
73
|
Returns:
|
|
@@ -128,7 +130,7 @@ def create_react_agent(
|
|
|
128
130
|
middleware_chain = MiddlewareChain()
|
|
129
131
|
# Add message persistence middleware first (uses backends.message)
|
|
130
132
|
if enable_history and backends.message is not None:
|
|
131
|
-
middleware_chain.use(MessageBackendMiddleware(
|
|
133
|
+
middleware_chain.use(MessageBackendMiddleware())
|
|
132
134
|
# Add user middlewares
|
|
133
135
|
if middlewares:
|
|
134
136
|
for mw in middlewares:
|
|
@@ -152,10 +154,13 @@ def create_react_agent(
|
|
|
152
154
|
# === Build providers ===
|
|
153
155
|
default_providers: list["ContextProvider"] = []
|
|
154
156
|
|
|
155
|
-
# MessageContextProvider - for fetching history
|
|
156
|
-
if
|
|
157
|
-
|
|
157
|
+
# MessageContextProvider - for fetching history
|
|
158
|
+
# Use custom message_provider if provided, otherwise use default
|
|
159
|
+
if message_provider is not None:
|
|
158
160
|
default_providers.append(message_provider)
|
|
161
|
+
elif enable_history:
|
|
162
|
+
default_message_provider = MessageContextProvider(max_messages=history_limit * 2)
|
|
163
|
+
default_providers.append(default_message_provider)
|
|
159
164
|
|
|
160
165
|
# Combine default + custom context_providers
|
|
161
166
|
all_providers = default_providers + (context_providers or [])
|
aury/agents/react/persistence.py
CHANGED
|
@@ -157,7 +157,7 @@ async def save_tool_messages(agent: "ReactAgent") -> None:
|
|
|
157
157
|
"""
|
|
158
158
|
for inv in agent._tool_invocations:
|
|
159
159
|
if inv.result is not None:
|
|
160
|
-
# Build tool result message
|
|
160
|
+
# Build tool result message (raw content)
|
|
161
161
|
content: list[dict] = [{
|
|
162
162
|
"type": "tool_result",
|
|
163
163
|
"tool_use_id": inv.tool_call_id,
|
|
@@ -165,11 +165,21 @@ async def save_tool_messages(agent: "ReactAgent") -> None:
|
|
|
165
165
|
"is_error": inv.is_error,
|
|
166
166
|
}]
|
|
167
167
|
|
|
168
|
-
message = {
|
|
168
|
+
message: dict = {
|
|
169
169
|
"role": "tool",
|
|
170
170
|
"content": content,
|
|
171
171
|
"tool_call_id": inv.tool_call_id,
|
|
172
172
|
"invocation_id": agent._current_invocation.id if agent._current_invocation else "",
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
# Add truncated_content if different from raw
|
|
176
|
+
if inv.truncated_result is not None and inv.truncated_result != inv.result:
|
|
177
|
+
truncated_content: list[dict] = [{
|
|
178
|
+
"type": "tool_result",
|
|
179
|
+
"tool_use_id": inv.tool_call_id,
|
|
180
|
+
"content": inv.truncated_result,
|
|
181
|
+
"is_error": inv.is_error,
|
|
182
|
+
}]
|
|
183
|
+
message["truncated_content"] = truncated_content
|
|
184
|
+
|
|
175
185
|
await trigger_message_save(agent, message)
|
aury/agents/react/step.py
CHANGED
|
@@ -196,6 +196,9 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
196
196
|
agent._current_text_block_id = None
|
|
197
197
|
agent._current_thinking_block_id = None
|
|
198
198
|
|
|
199
|
+
# Track if thinking_completed has been emitted (to avoid duplicate)
|
|
200
|
+
thinking_completed_emitted = False
|
|
201
|
+
|
|
199
202
|
# Reset tool call tracking
|
|
200
203
|
agent._call_id_to_tool = {}
|
|
201
204
|
agent._tool_call_blocks = {}
|
|
@@ -293,10 +296,10 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
293
296
|
if event.type == "content":
|
|
294
297
|
# Text content
|
|
295
298
|
if event.delta:
|
|
296
|
-
# === Middleware:
|
|
297
|
-
stream_chunk = {"delta": event.delta
|
|
299
|
+
# === Middleware: on_text_stream ===
|
|
300
|
+
stream_chunk = {"delta": event.delta}
|
|
298
301
|
if agent.middleware:
|
|
299
|
-
stream_chunk = await agent.middleware.
|
|
302
|
+
stream_chunk = await agent.middleware.process_text_stream(
|
|
300
303
|
stream_chunk
|
|
301
304
|
)
|
|
302
305
|
if stream_chunk is None:
|
|
@@ -328,10 +331,10 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
328
331
|
# Thinking content - only emit if thinking is enabled
|
|
329
332
|
stream_thinking = agent._get_stream_thinking()
|
|
330
333
|
if event.delta and enable_thinking:
|
|
331
|
-
# === Middleware:
|
|
332
|
-
stream_chunk = {"delta": event.delta
|
|
334
|
+
# === Middleware: on_thinking_stream ===
|
|
335
|
+
stream_chunk = {"delta": event.delta}
|
|
333
336
|
if agent.middleware:
|
|
334
|
-
stream_chunk = await agent.middleware.
|
|
337
|
+
stream_chunk = await agent.middleware.process_thinking_stream(
|
|
335
338
|
stream_chunk
|
|
336
339
|
)
|
|
337
340
|
if stream_chunk is None:
|
|
@@ -355,6 +358,17 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
355
358
|
data={"content": delta},
|
|
356
359
|
))
|
|
357
360
|
|
|
361
|
+
elif event.type == "thinking_completed":
|
|
362
|
+
# Thinking completed - emit block completed status
|
|
363
|
+
if agent._current_thinking_block_id and not thinking_completed_emitted:
|
|
364
|
+
await agent.ctx.emit(BlockEvent(
|
|
365
|
+
block_id=agent._current_thinking_block_id,
|
|
366
|
+
kind=BlockKind.THINKING,
|
|
367
|
+
op=BlockOp.PATCH,
|
|
368
|
+
data={"status": "completed"},
|
|
369
|
+
))
|
|
370
|
+
thinking_completed_emitted = True
|
|
371
|
+
|
|
358
372
|
elif event.type == "tool_call_start":
|
|
359
373
|
# Tool call started (name known, arguments pending)
|
|
360
374
|
if event.tool_call:
|
|
@@ -548,6 +562,58 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
548
562
|
data={"message": event.error or "Unknown LLM error"},
|
|
549
563
|
))
|
|
550
564
|
|
|
565
|
+
# === Middleware: on_text_stream_end (flush buffered content) ===
|
|
566
|
+
if agent.middleware:
|
|
567
|
+
final_chunks = await agent.middleware.process_text_stream_end()
|
|
568
|
+
for final_chunk in final_chunks:
|
|
569
|
+
final_delta = final_chunk.get("delta", "")
|
|
570
|
+
if final_delta:
|
|
571
|
+
agent._text_buffer += final_delta
|
|
572
|
+
# Emit the final text content
|
|
573
|
+
if agent._current_text_block_id is None:
|
|
574
|
+
agent._current_text_block_id = generate_id("blk")
|
|
575
|
+
await agent.ctx.emit(BlockEvent(
|
|
576
|
+
block_id=agent._current_text_block_id,
|
|
577
|
+
kind=BlockKind.TEXT,
|
|
578
|
+
op=BlockOp.DELTA,
|
|
579
|
+
data={"content": final_delta},
|
|
580
|
+
))
|
|
581
|
+
logger.debug(
|
|
582
|
+
f"Emitted final text chunk from middleware: {len(final_delta)} chars",
|
|
583
|
+
extra={"invocation_id": agent._current_invocation.id},
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
# === Middleware: on_thinking_stream_end (flush buffered thinking) ===
|
|
587
|
+
if agent.middleware:
|
|
588
|
+
thinking_chunks = await agent.middleware.process_thinking_stream_end()
|
|
589
|
+
for thinking_chunk in thinking_chunks:
|
|
590
|
+
thinking_delta = thinking_chunk.get("delta", "")
|
|
591
|
+
if thinking_delta:
|
|
592
|
+
agent._thinking_buffer += thinking_delta
|
|
593
|
+
# Emit the final thinking content (if streaming thinking)
|
|
594
|
+
if agent.config.stream_thinking:
|
|
595
|
+
if agent._current_thinking_block_id is None:
|
|
596
|
+
agent._current_thinking_block_id = generate_id("blk")
|
|
597
|
+
await agent.ctx.emit(BlockEvent(
|
|
598
|
+
block_id=agent._current_thinking_block_id,
|
|
599
|
+
kind=BlockKind.THINKING,
|
|
600
|
+
op=BlockOp.DELTA,
|
|
601
|
+
data={"content": thinking_delta},
|
|
602
|
+
))
|
|
603
|
+
logger.debug(
|
|
604
|
+
f"Emitted final thinking chunk from middleware: {len(thinking_delta)} chars",
|
|
605
|
+
extra={"invocation_id": agent._current_invocation.id},
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
# Emit text block completed status
|
|
609
|
+
if agent._current_text_block_id:
|
|
610
|
+
await agent.ctx.emit(BlockEvent(
|
|
611
|
+
block_id=agent._current_text_block_id,
|
|
612
|
+
kind=BlockKind.TEXT,
|
|
613
|
+
op=BlockOp.PATCH,
|
|
614
|
+
data={"status": "completed"},
|
|
615
|
+
))
|
|
616
|
+
|
|
551
617
|
# If thinking was buffered, emit it now
|
|
552
618
|
if agent._thinking_buffer and not agent.config.stream_thinking:
|
|
553
619
|
await agent.ctx.emit(BlockEvent(
|
aury/agents/react/tools.py
CHANGED
|
@@ -276,18 +276,23 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
276
276
|
# HITL tool - record placeholder result
|
|
277
277
|
invocation.mark_result(f"[等待用户输入: {suspend_signal.request_type}]", is_error=False)
|
|
278
278
|
else:
|
|
279
|
-
# Normal tool result
|
|
279
|
+
# Normal tool result - pass truncated_output
|
|
280
|
+
output = result.output if hasattr(result, 'output') else str(result)
|
|
281
|
+
truncated = getattr(result, 'truncated_output', None)
|
|
280
282
|
invocation.mark_result(
|
|
281
|
-
|
|
282
|
-
is_error=getattr(result, 'is_error', False)
|
|
283
|
+
output,
|
|
284
|
+
is_error=getattr(result, 'is_error', False),
|
|
285
|
+
truncated_result=truncated,
|
|
283
286
|
)
|
|
284
287
|
|
|
285
|
-
# Add to in-memory history
|
|
288
|
+
# Add to in-memory history (use truncated for context window)
|
|
286
289
|
agent._message_history.append(
|
|
287
290
|
LLMMessage(
|
|
288
291
|
role="tool",
|
|
289
292
|
content=invocation.result,
|
|
290
293
|
tool_call_id=invocation.tool_call_id,
|
|
294
|
+
name=invocation.tool_name, # Required for Gemini
|
|
295
|
+
truncated_content=invocation.truncated_result,
|
|
291
296
|
)
|
|
292
297
|
)
|
|
293
298
|
|
|
@@ -309,6 +314,13 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
309
314
|
error_msg = f"Tool execution error: {str(result)}"
|
|
310
315
|
invocation.mark_result(error_msg, is_error=True)
|
|
311
316
|
result = ToolResult.error(error_msg)
|
|
317
|
+
else:
|
|
318
|
+
# Mark result with truncated_output
|
|
319
|
+
invocation.mark_result(
|
|
320
|
+
result.output,
|
|
321
|
+
is_error=result.is_error,
|
|
322
|
+
truncated_result=result.truncated_output,
|
|
323
|
+
)
|
|
312
324
|
|
|
313
325
|
# Get parent block_id from tool_call mapping
|
|
314
326
|
parent_block_id = agent._tool_call_blocks.get(invocation.tool_call_id)
|
|
@@ -339,7 +351,9 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
339
351
|
{
|
|
340
352
|
"type": "tool_result",
|
|
341
353
|
"tool_use_id": invocation.tool_call_id,
|
|
354
|
+
"tool_name": invocation.tool_name,
|
|
342
355
|
"content": result.output,
|
|
356
|
+
"truncated_content": result.truncated_output,
|
|
343
357
|
"is_error": invocation.is_error,
|
|
344
358
|
}
|
|
345
359
|
)
|
|
@@ -352,5 +366,7 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
352
366
|
role="tool",
|
|
353
367
|
content=tr["content"],
|
|
354
368
|
tool_call_id=tr["tool_use_id"],
|
|
369
|
+
name=tr["tool_name"], # Required for Gemini
|
|
370
|
+
truncated_content=tr.get("truncated_content"),
|
|
355
371
|
)
|
|
356
372
|
)
|
aury/agents/tool/decorator.py
CHANGED
|
@@ -6,7 +6,7 @@ import inspect
|
|
|
6
6
|
from functools import wraps
|
|
7
7
|
from typing import Any, Callable, get_type_hints, get_origin, get_args, Union
|
|
8
8
|
|
|
9
|
-
from ..core.types.tool import BaseTool, ToolContext, ToolResult, ToolInfo
|
|
9
|
+
from ..core.types.tool import BaseTool, ToolContext, ToolResult, ToolInfo, ToolConfig
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def _type_to_schema(t: type) -> dict[str, Any]:
|
|
@@ -196,20 +196,12 @@ def tool(
|
|
|
196
196
|
accepts_ctx = "ctx" in sig.parameters or "context" in sig.parameters
|
|
197
197
|
ctx_param_name = "ctx" if "ctx" in sig.parameters else "context"
|
|
198
198
|
|
|
199
|
-
class FunctionTool:
|
|
199
|
+
class FunctionTool(BaseTool):
|
|
200
200
|
"""Tool created from decorated function."""
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
@property
|
|
207
|
-
def description(self) -> str:
|
|
208
|
-
return tool_desc
|
|
209
|
-
|
|
210
|
-
@property
|
|
211
|
-
def parameters(self) -> dict[str, Any]:
|
|
212
|
-
return parameters_schema
|
|
202
|
+
_name = tool_name
|
|
203
|
+
_description = tool_desc
|
|
204
|
+
_parameters = parameters_schema
|
|
213
205
|
|
|
214
206
|
async def execute(
|
|
215
207
|
self,
|
|
@@ -237,13 +229,6 @@ def tool(
|
|
|
237
229
|
|
|
238
230
|
except Exception as e:
|
|
239
231
|
return ToolResult.error(str(e))
|
|
240
|
-
|
|
241
|
-
def get_info(self) -> ToolInfo:
|
|
242
|
-
return ToolInfo(
|
|
243
|
-
name=tool_name,
|
|
244
|
-
description=tool_desc,
|
|
245
|
-
parameters=parameters_schema,
|
|
246
|
-
)
|
|
247
232
|
|
|
248
233
|
return FunctionTool()
|
|
249
234
|
|
|
@@ -2,7 +2,7 @@ aury/__init__.py,sha256=yTnJ3EOYYknROar-CUqU825NRcsc06fAp_dEIEUwRMI,94
|
|
|
2
2
|
aury/agents/__init__.py,sha256=kaSH-1392iNti6GfFJra9nl7lu4iz1QHANz-y7IDl8Q,1842
|
|
3
3
|
aury/agents/plugin.py,sha256=V2KCu4MIBoar6BmCevKp7AzGZvHbGi3CizQSE2gCOzs,5438
|
|
4
4
|
aury/agents/a2a/__init__.py,sha256=xwZLlAOhv2nGU6FHaCd8lygaJ5IPdVnvw-cB_w1Dwxg,4979
|
|
5
|
-
aury/agents/backends/__init__.py,sha256=
|
|
5
|
+
aury/agents/backends/__init__.py,sha256=7vFpBzRUvWDUKv1aadFgIeQ8zcX-9F2J_BDRvT5BsiM,5898
|
|
6
6
|
aury/agents/backends/sandbox.py,sha256=imOItqBu47GUc8sqHKDJFYlRoBlfn4VV-8CG8cL9480,8029
|
|
7
7
|
aury/agents/backends/shell.py,sha256=Bc72UQ5LVu-ZKxb7K3V8wS8UI_WV0pib-F2Ou7_p3Rw,6006
|
|
8
8
|
aury/agents/backends/artifact/__init__.py,sha256=YMKBSAoItGQMTqKBodWg8xaitJOMuOq4MGI9MuzpjkE,210
|
|
@@ -18,9 +18,9 @@ aury/agents/backends/invocation/types.py,sha256=2b3DcCmum6Ctkn7JuNZeSvnxRlN_VJ9Z
|
|
|
18
18
|
aury/agents/backends/memory/__init__.py,sha256=mIaSJOnFNybMPNNOtR2zch_wFs6b11JFMp9LL8tvOLM,162
|
|
19
19
|
aury/agents/backends/memory/memory.py,sha256=HWpME3vl4nLM5J3lv_iHuKjpbbLBLWE23SFFDG8NQJk,5621
|
|
20
20
|
aury/agents/backends/memory/types.py,sha256=qbKPZc-E_SMnGVq1Eh_5Da_3Fp235p6xzV9b044qI2A,3680
|
|
21
|
-
aury/agents/backends/message/__init__.py,sha256=
|
|
22
|
-
aury/agents/backends/message/memory.py,sha256=
|
|
23
|
-
aury/agents/backends/message/types.py,sha256=
|
|
21
|
+
aury/agents/backends/message/__init__.py,sha256=NgQZPYZ7NJfZ59OXSx_s7LRvkXGYtkXx9f-F5QatLys,167
|
|
22
|
+
aury/agents/backends/message/memory.py,sha256=9DNMotsjje_jfwsixmgNlSxrigO93m6zgkFRbgrLxbU,2916
|
|
23
|
+
aury/agents/backends/message/types.py,sha256=eYRmjGbnD3NG84Tdz_OmfqnRe_j_ovHT6sgXxQ4mM14,2564
|
|
24
24
|
aury/agents/backends/session/__init__.py,sha256=27WuH6ulc3RBrPN3pTK2iittVdGno5iMlY9knBKnZ-E,167
|
|
25
25
|
aury/agents/backends/session/memory.py,sha256=qMBnNgq5HxA39VHGUtftzJqCtsSpHWuetqF5nFFnmgQ,2837
|
|
26
26
|
aury/agents/backends/session/types.py,sha256=ukfmE__QIbDNeMz0pj6gYEyjHYtGgolpqPGEu7X_u6E,3309
|
|
@@ -50,13 +50,13 @@ aury/agents/context_providers/__init__.py,sha256=QlbTh2vAHbxfZcXjcY5mOsLqOiYkIYG
|
|
|
50
50
|
aury/agents/context_providers/artifact.py,sha256=tjjaseE2iosKLx6BAJ7kR5xmo9VsNY2ukkbj5NLHlC0,9144
|
|
51
51
|
aury/agents/context_providers/base.py,sha256=FhFRWJS_afDFTHl7Yjr6vGIje58IpEOlEolgqpFR-QQ,6246
|
|
52
52
|
aury/agents/context_providers/memory.py,sha256=HKIR5fRNzsZSV1-IjV325cTYIFqmNVPFPujufSI1CrY,1942
|
|
53
|
-
aury/agents/context_providers/message.py,sha256=
|
|
53
|
+
aury/agents/context_providers/message.py,sha256=LDQ1BPozyunh_4FM9WLcnf4CX3piOeD94zUkn9QG84o,4524
|
|
54
54
|
aury/agents/context_providers/skill.py,sha256=w_R1txvu45ruMjuOtckuD9oG_hqeFGqAa_NZ_0T8WNs,1355
|
|
55
55
|
aury/agents/context_providers/subagent.py,sha256=Y-6bYjaq6nbLS9d3siyy5eAt6SzFfk6N3Y1WU209lhI,1364
|
|
56
56
|
aury/agents/context_providers/tool.py,sha256=wQGmcZi_XuB9ukweg5PUVO93GLzley0xftje-iVSfq8,2266
|
|
57
57
|
aury/agents/core/__init__.py,sha256=-euIGAwoe2gU_2xEqJ8YmOMnDOaOlgWXwXxzIQnDG8E,1716
|
|
58
58
|
aury/agents/core/base.py,sha256=nqsQ7fG0HZ08bqJh7KdpBgIxtJzDXZ6qLMf5hZ5vBuc,21279
|
|
59
|
-
aury/agents/core/context.py,sha256=
|
|
59
|
+
aury/agents/core/context.py,sha256=co_v6Mz7fYR0jaTlUHlnSBWaOgr_1_84lVO0FPo_tKo,28932
|
|
60
60
|
aury/agents/core/context_builder.py,sha256=HF0hfnKBVCmlcFDmdyj53org90318ixmZl1LYQBl0fM,9075
|
|
61
61
|
aury/agents/core/factory.py,sha256=8rx_2jD9Sj2tK-8_We09fHT1czjbN-yF1ws0hmUX2w4,6829
|
|
62
62
|
aury/agents/core/isolator.py,sha256=zi_ZXk-a6b7D2EAeWH3FKkO5_7PwK975zRd9enbBf_E,2916
|
|
@@ -79,7 +79,7 @@ aury/agents/core/types/message.py,sha256=W0d8elddcbvW98bejDkHIzKiTigr6O5KxVuVUne
|
|
|
79
79
|
aury/agents/core/types/recall.py,sha256=BZSDgv8Q0eK7Sshc-jA6ycpFpMHzndZ-lS86MPto9-c,4898
|
|
80
80
|
aury/agents/core/types/session.py,sha256=oRn9jKFe8Tg-12ZFQcGJ0VLaJIWBfk8YQDzXUuXSNEk,9406
|
|
81
81
|
aury/agents/core/types/subagent.py,sha256=vIxDkfekAaHj_V2UdSIaygDKb5RjiLqi8twTnhIUF_o,4651
|
|
82
|
-
aury/agents/core/types/tool.py,sha256=
|
|
82
|
+
aury/agents/core/types/tool.py,sha256=Zadqjp2QjNsX617whpWnXJ1XUvPXDl47f8nuCQ1AbaY,7676
|
|
83
83
|
aury/agents/eval/__init__.py,sha256=uRGZN-RBpNlwOmrn66EwZBNKufDVKgMc3tODuMM6WB4,8850
|
|
84
84
|
aury/agents/hitl/__init__.py,sha256=6H8cBU-dSR0eSOGWte_Iy7OvTKGDl4ZMb0E56KrfFkw,1020
|
|
85
85
|
aury/agents/hitl/ask_user.py,sha256=3MAJOo0rI0Wl7ZpZdDSQVBkO0GJFYH6bT7hnrcED4qI,9071
|
|
@@ -88,9 +88,9 @@ aury/agents/hitl/exceptions.py,sha256=O1r9OCLwQqo7Ebr5o3kX0p0bvWYKbHapftf1vfnMh0
|
|
|
88
88
|
aury/agents/hitl/permission.py,sha256=bbwp0heb8YZ_palRCU55QtXm1rfMi9hJ8g3DWKtTc3Q,19117
|
|
89
89
|
aury/agents/hitl/revert.py,sha256=i3F8Zcibuo3fjhJTK-rQEYSPMKxmRQeua5cjoDzAR14,6684
|
|
90
90
|
aury/agents/llm/__init__.py,sha256=teantqedfyQ6IxLD6LayLr2cbgFYbMT2I4TUSfkOrQ4,625
|
|
91
|
-
aury/agents/llm/adapter.py,sha256=
|
|
91
|
+
aury/agents/llm/adapter.py,sha256=_8FKf_HqJip-oRTgKhai0OBZObSG_wbgigU0oK0bb9k,15029
|
|
92
92
|
aury/agents/llm/openai.py,sha256=v4Qlc5EIJDNcqkGHA2aIEaTTKaPVGMPf1227aKcef58,11192
|
|
93
|
-
aury/agents/llm/provider.py,sha256=
|
|
93
|
+
aury/agents/llm/provider.py,sha256=YRlDY0mSEMb4oTmKusLlj_vh5vhDdOf4yrY3c5vBpfM,16827
|
|
94
94
|
aury/agents/mcp/__init__.py,sha256=7zsY-5LhQBLpiQI-XWe2uUHdTwJrDHrr0pDd_SXfO3o,4355
|
|
95
95
|
aury/agents/memory/__init__.py,sha256=PMGMQ1VE-j3M0n4dIeb9DYO3qrCyv5AMSfMWTyhPARE,816
|
|
96
96
|
aury/agents/memory/compaction.py,sha256=3inOVsbwSgTghcsSLgvUdX8IG2J6_0Qbr36vAqanV0M,12757
|
|
@@ -98,27 +98,25 @@ aury/agents/memory/manager.py,sha256=9UsuZUYmp5Pju9lRa0bsque6gHpLIE5UwdqtQKZ3fO0
|
|
|
98
98
|
aury/agents/memory/processor.py,sha256=Y4PZIMFdNtn_TQ3fRdhynFLUgcURi8Xu-ZeRq5kDS_s,4816
|
|
99
99
|
aury/agents/memory/store.py,sha256=SX5AYMbifCEFfLqPahhDRZLswZK0g6vFy523F1CTUWg,5822
|
|
100
100
|
aury/agents/memory/types.py,sha256=N8Rhc79OEjdJ3Xe7iG1AwnWK1Ej6b-zI51FIqmyGmLg,4560
|
|
101
|
-
aury/agents/messages/__init__.py,sha256=
|
|
101
|
+
aury/agents/messages/__init__.py,sha256=AAKgyGtnI60APvIo8RBgipF1jyaaOydUlL1TZVwXUH4,715
|
|
102
102
|
aury/agents/messages/config.py,sha256=1ed8Akbna75Z5-eR6qnDPBFo91qwbdkSgQHc3wF5uBQ,1685
|
|
103
|
-
aury/agents/messages/raw_store.py,sha256=QT6tJlJO-cBXKuVqYUsGXavWrA0cAsoJp6zcgMx6anY,6788
|
|
104
103
|
aury/agents/messages/store.py,sha256=1zE24GHnXpPOhDQbehmAGQpNxW9Gv1-sas9dm0FYt4s,3969
|
|
105
104
|
aury/agents/messages/types.py,sha256=riNl-C6f_zakpS673U0KRlAVSvQg5L4Pd6FNs2Isssg,2582
|
|
106
|
-
aury/agents/middleware/__init__.py,sha256=
|
|
107
|
-
aury/agents/middleware/base.py,sha256=
|
|
108
|
-
aury/agents/middleware/chain.py,sha256=
|
|
109
|
-
aury/agents/middleware/message.py,sha256=
|
|
105
|
+
aury/agents/middleware/__init__.py,sha256=8iafxYOQtYgzYUorN68gdq2xFbiGLd-D7JR263lIf9U,822
|
|
106
|
+
aury/agents/middleware/base.py,sha256=M4sKdIPOqHOsiiYveQaqgZgK-n4bQW2FSg5pbah_b04,10445
|
|
107
|
+
aury/agents/middleware/chain.py,sha256=7HlTvTZI5bOMIzp3UbIjCwhqXytJTgMndz8zhGnxEg8,17609
|
|
108
|
+
aury/agents/middleware/message.py,sha256=hDGGb0QwL04K2llbUId1938sd4DIJSpq_KnRJ6fcriE,2017
|
|
110
109
|
aury/agents/middleware/message_container.py,sha256=0I_C-mIVVUqSzMzaYKUZGPtJUbV3Plo1msW8BIU-3RE,4073
|
|
111
|
-
aury/agents/middleware/raw_message.py,sha256=ogcvGhqYLu6j35UJC4AGydokC91PHEQY81t-lcNy9y4,5064
|
|
112
110
|
aury/agents/middleware/truncation.py,sha256=SM1ldZ6kC-joQVaoukNwFqKiHQ0symJAnzBJVANkxmg,4786
|
|
113
111
|
aury/agents/middleware/types.py,sha256=T63AgePVSs4b1NT0MZ5PyaQJBLoVqNoAQt9NSGjBwBs,2512
|
|
114
112
|
aury/agents/react/__init__.py,sha256=yixRP3RSXQtVaamtwjaOpmW55sZb-xp4XRjxYcy0HfU,90
|
|
115
113
|
aury/agents/react/agent.py,sha256=DYWxuspMs3srOuxW4Sxis_Hkg4R6YkM0aM-rLRjD9Oo,23300
|
|
116
114
|
aury/agents/react/context.py,sha256=Q7pY5j6b-OvKAmI1UsuawC3BmVxFkKN1oXxeBTVFejQ,11067
|
|
117
|
-
aury/agents/react/factory.py,sha256=
|
|
115
|
+
aury/agents/react/factory.py,sha256=7aWb2YqSdlIq161Ke0JZwnjpaA9U7Q5xejAnkrmjMUw,10776
|
|
118
116
|
aury/agents/react/pause.py,sha256=bcrhbuoJQUz7WxZSsKr5qjxQlDdpwai54ns_qio0du4,7306
|
|
119
|
-
aury/agents/react/persistence.py,sha256=
|
|
120
|
-
aury/agents/react/step.py,sha256=
|
|
121
|
-
aury/agents/react/tools.py,sha256=
|
|
117
|
+
aury/agents/react/persistence.py,sha256=4BYmx3Dxu1grEpt4Qw3fUG26LgYyAhRnXVQC03OJDtE,6354
|
|
118
|
+
aury/agents/react/step.py,sha256=LQ9O3tqIITnEfHGfbZ1Sm9wWdkpVKAWPBczjeEi2PUg,29316
|
|
119
|
+
aury/agents/react/tools.py,sha256=RmXImt7jbr8fxc3wmFDAY8XreeHOJGg84GSEK1xtfhI,14013
|
|
122
120
|
aury/agents/sandbox/__init__.py,sha256=adH29NhzpZUIFVCxhRUZxyANKpFauUjsPVd8iktUOaI,635
|
|
123
121
|
aury/agents/sandbox/local.py,sha256=Dl-zJZ5FUz7WONtuze7MdpCDBjm9YZbjLIkGa9lYbwY,8328
|
|
124
122
|
aury/agents/sandbox/remote.py,sha256=6NcYIs_thjyxa5LgIqwoPNsHYpT70DG6xGbjDYV6-X4,6444
|
|
@@ -127,7 +125,7 @@ aury/agents/skill/__init__.py,sha256=CkWSSclFphXCrQkQDbf6ndclP4dsLvWYhSW8Wj5lVcw
|
|
|
127
125
|
aury/agents/skill/loader.py,sha256=g2mhC0CLzP0s8BlNk21e_IEonHNyekK7EbqUOFkfOHc,5516
|
|
128
126
|
aury/agents/skill/types.py,sha256=yDzMxF9S5D4NNA3k1KnQvhhVBd4plCu2oJXCWTO1jSI,2696
|
|
129
127
|
aury/agents/tool/__init__.py,sha256=_IC06waxr9cC-HXdalwDByOBAZgfQiMwjsXypj-9mVE,731
|
|
130
|
-
aury/agents/tool/decorator.py,sha256=
|
|
128
|
+
aury/agents/tool/decorator.py,sha256=dTd9tj851ydik-cjClsHB97gN34qXsv3IV9677y7u5g,8052
|
|
131
129
|
aury/agents/tool/set.py,sha256=6UgI12E2b-C0Kfwg3KUr4e5kraBK887wbveAs8GudyY,7728
|
|
132
130
|
aury/agents/tool/builtin/__init__.py,sha256=Pp5NlE0i1jiNlfZ6kVH-iSeE553RMysa4icmOgPzezI,513
|
|
133
131
|
aury/agents/tool/builtin/ask_user.py,sha256=RnAJ969YE77AYG_foI7KlVsISvHj5Ykrdz0l2ZYZh-g,4871
|
|
@@ -149,7 +147,7 @@ aury/agents/workflow/expression.py,sha256=Hsx2jBigtt5zbJb9uK9pveipqMbBBUUAvlgYjB
|
|
|
149
147
|
aury/agents/workflow/parser.py,sha256=mfiFZ_TtFq3IxAqPlTGcNkluiZ8ww16y3NYwbmbsrwE,6149
|
|
150
148
|
aury/agents/workflow/state.py,sha256=AxTSo7P9b1DbWjGdQdzFY4_7m6CJGNFo7xkGK28SPZw,4234
|
|
151
149
|
aury/agents/workflow/types.py,sha256=PVvjTQRgTObx5Mq_lXFogyLjGChOi5pUgcJwF5ZzVtg,2354
|
|
152
|
-
aury_agent-0.0.
|
|
153
|
-
aury_agent-0.0.
|
|
154
|
-
aury_agent-0.0.
|
|
155
|
-
aury_agent-0.0.
|
|
150
|
+
aury_agent-0.0.11.dist-info/METADATA,sha256=Tp5cn5OyHPnSa6b22xHYzyzaFhHB1o5LdfJFbSWrmKQ,2115
|
|
151
|
+
aury_agent-0.0.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
152
|
+
aury_agent-0.0.11.dist-info/entry_points.txt,sha256=7EC5SMAKdC9HZLG8RfPhGno4OKOeSjaGsOWi1gOL-K8,56
|
|
153
|
+
aury_agent-0.0.11.dist-info/RECORD,,
|