aury-agent 0.0.10__py3-none-any.whl → 0.0.12__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/core/base.py +7 -0
- aury/agents/core/types/tool.py +15 -2
- aury/agents/llm/adapter.py +3 -0
- aury/agents/llm/provider.py +23 -3
- aury/agents/react/persistence.py +12 -2
- aury/agents/react/step.py +18 -13
- aury/agents/react/tools.py +17 -4
- {aury_agent-0.0.10.dist-info → aury_agent-0.0.12.dist-info}/METADATA +1 -1
- {aury_agent-0.0.10.dist-info → aury_agent-0.0.12.dist-info}/RECORD +11 -11
- {aury_agent-0.0.10.dist-info → aury_agent-0.0.12.dist-info}/WHEEL +0 -0
- {aury_agent-0.0.10.dist-info → aury_agent-0.0.12.dist-info}/entry_points.txt +0 -0
aury/agents/core/base.py
CHANGED
|
@@ -352,6 +352,13 @@ class BaseAgent(ABC):
|
|
|
352
352
|
logger.error(f"{self.agent_type}Agent run error, error={type(e).__name__}, invocation_id={self._ctx.invocation_id}", exc_info=True)
|
|
353
353
|
raise
|
|
354
354
|
finally:
|
|
355
|
+
# Cancel exec_task if still running (e.g., when run() is cancelled externally)
|
|
356
|
+
if exec_task and not exec_task.done():
|
|
357
|
+
exec_task.cancel()
|
|
358
|
+
try:
|
|
359
|
+
await exec_task
|
|
360
|
+
except asyncio.CancelledError:
|
|
361
|
+
pass
|
|
355
362
|
_reset_current_ctx(ctx_token)
|
|
356
363
|
_emit_queue_var.reset(queue_token)
|
|
357
364
|
self._run_config = {} # Clear runtime overrides
|
aury/agents/core/types/tool.py
CHANGED
|
@@ -148,6 +148,7 @@ class ToolInvocation:
|
|
|
148
148
|
args: dict[str, Any] = field(default_factory=dict)
|
|
149
149
|
args_raw: str = "" # Raw JSON string for streaming
|
|
150
150
|
result: str | None = None
|
|
151
|
+
truncated_result: str | None = None # Shortened result for context window
|
|
151
152
|
is_error: bool = False
|
|
152
153
|
|
|
153
154
|
# Timing
|
|
@@ -161,10 +162,22 @@ class ToolInvocation:
|
|
|
161
162
|
self.state = ToolInvocationState.CALL
|
|
162
163
|
self.time["start"] = datetime.now()
|
|
163
164
|
|
|
164
|
-
def mark_result(
|
|
165
|
-
|
|
165
|
+
def mark_result(
|
|
166
|
+
self,
|
|
167
|
+
result: str,
|
|
168
|
+
is_error: bool = False,
|
|
169
|
+
truncated_result: str | None = None,
|
|
170
|
+
) -> None:
|
|
171
|
+
"""Mark execution complete.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
result: Complete result (raw)
|
|
175
|
+
is_error: Whether this is an error result
|
|
176
|
+
truncated_result: Shortened result for context window (defaults to result)
|
|
177
|
+
"""
|
|
166
178
|
self.state = ToolInvocationState.RESULT
|
|
167
179
|
self.result = result
|
|
180
|
+
self.truncated_result = truncated_result if truncated_result is not None else result
|
|
168
181
|
self.is_error = is_error
|
|
169
182
|
self.time["end"] = datetime.now()
|
|
170
183
|
|
aury/agents/llm/adapter.py
CHANGED
|
@@ -261,6 +261,9 @@ class ModelClientProvider:
|
|
|
261
261
|
case Evt.thinking:
|
|
262
262
|
return LLMEvent(type="thinking", delta=event.delta)
|
|
263
263
|
|
|
264
|
+
case Evt.thinking_completed:
|
|
265
|
+
return LLMEvent(type="thinking_completed")
|
|
266
|
+
|
|
264
267
|
case Evt.tool_call_start:
|
|
265
268
|
if event.tool_call:
|
|
266
269
|
return LLMEvent(
|
aury/agents/llm/provider.py
CHANGED
|
@@ -134,11 +134,16 @@ class LLMMessage:
|
|
|
134
134
|
- user: User message (can include images)
|
|
135
135
|
- assistant: Assistant response (can include tool_calls)
|
|
136
136
|
- tool: Tool result (requires tool_call_id and name)
|
|
137
|
+
|
|
138
|
+
Supports dual content for context management:
|
|
139
|
+
- content: Complete content (raw), for storage and recall
|
|
140
|
+
- truncated_content: Shortened content for context window (defaults to content)
|
|
137
141
|
"""
|
|
138
142
|
role: Literal["system", "user", "assistant", "tool"]
|
|
139
143
|
content: str | list[dict[str, Any]]
|
|
140
144
|
tool_call_id: str | None = None # Required for tool role
|
|
141
145
|
name: str | None = None # Tool name, required for Gemini compatibility
|
|
146
|
+
truncated_content: str | list[dict[str, Any]] | None = None # Shortened content (defaults to content)
|
|
142
147
|
|
|
143
148
|
def to_dict(self) -> dict[str, Any]:
|
|
144
149
|
d = {"role": self.role, "content": self.content}
|
|
@@ -146,6 +151,8 @@ class LLMMessage:
|
|
|
146
151
|
d["tool_call_id"] = self.tool_call_id
|
|
147
152
|
if self.name:
|
|
148
153
|
d["name"] = self.name
|
|
154
|
+
if self.truncated_content is not None:
|
|
155
|
+
d["truncated_content"] = self.truncated_content
|
|
149
156
|
return d
|
|
150
157
|
|
|
151
158
|
def get(self, key: str, default: Any = None) -> Any:
|
|
@@ -174,15 +181,28 @@ class LLMMessage:
|
|
|
174
181
|
return cls(role="assistant", content=content)
|
|
175
182
|
|
|
176
183
|
@classmethod
|
|
177
|
-
def tool(
|
|
184
|
+
def tool(
|
|
185
|
+
cls,
|
|
186
|
+
content: str,
|
|
187
|
+
tool_call_id: str,
|
|
188
|
+
name: str | None = None,
|
|
189
|
+
truncated_content: str | None = None,
|
|
190
|
+
) -> "LLMMessage":
|
|
178
191
|
"""Create tool result message.
|
|
179
192
|
|
|
180
193
|
Args:
|
|
181
|
-
content: Tool result content
|
|
194
|
+
content: Tool result content (complete/raw)
|
|
182
195
|
tool_call_id: ID of the tool call this result is for
|
|
183
196
|
name: Tool name (required for Gemini compatibility)
|
|
197
|
+
truncated_content: Shortened content for context window (defaults to content)
|
|
184
198
|
"""
|
|
185
|
-
return cls(
|
|
199
|
+
return cls(
|
|
200
|
+
role="tool",
|
|
201
|
+
content=content,
|
|
202
|
+
tool_call_id=tool_call_id,
|
|
203
|
+
name=name,
|
|
204
|
+
truncated_content=truncated_content,
|
|
205
|
+
)
|
|
186
206
|
|
|
187
207
|
|
|
188
208
|
@runtime_checkable
|
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 = {}
|
|
@@ -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:
|
|
@@ -569,15 +583,6 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
569
583
|
extra={"invocation_id": agent._current_invocation.id},
|
|
570
584
|
)
|
|
571
585
|
|
|
572
|
-
# Emit text block completed status
|
|
573
|
-
if agent._current_text_block_id:
|
|
574
|
-
await agent.ctx.emit(BlockEvent(
|
|
575
|
-
block_id=agent._current_text_block_id,
|
|
576
|
-
kind=BlockKind.TEXT,
|
|
577
|
-
op=BlockOp.PATCH,
|
|
578
|
-
data={"status": "completed"},
|
|
579
|
-
))
|
|
580
|
-
|
|
581
586
|
# === Middleware: on_thinking_stream_end (flush buffered thinking) ===
|
|
582
587
|
if agent.middleware:
|
|
583
588
|
thinking_chunks = await agent.middleware.process_thinking_stream_end()
|
|
@@ -600,11 +605,11 @@ async def execute_step(agent: "ReactAgent") -> str | None:
|
|
|
600
605
|
extra={"invocation_id": agent._current_invocation.id},
|
|
601
606
|
)
|
|
602
607
|
|
|
603
|
-
# Emit
|
|
604
|
-
if agent.
|
|
608
|
+
# Emit text block completed status
|
|
609
|
+
if agent._current_text_block_id:
|
|
605
610
|
await agent.ctx.emit(BlockEvent(
|
|
606
|
-
block_id=agent.
|
|
607
|
-
kind=BlockKind.
|
|
611
|
+
block_id=agent._current_text_block_id,
|
|
612
|
+
kind=BlockKind.TEXT,
|
|
608
613
|
op=BlockOp.PATCH,
|
|
609
614
|
data={"status": "completed"},
|
|
610
615
|
))
|
aury/agents/react/tools.py
CHANGED
|
@@ -276,19 +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,
|
|
291
294
|
name=invocation.tool_name, # Required for Gemini
|
|
295
|
+
truncated_content=invocation.truncated_result,
|
|
292
296
|
)
|
|
293
297
|
)
|
|
294
298
|
|
|
@@ -310,6 +314,13 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
310
314
|
error_msg = f"Tool execution error: {str(result)}"
|
|
311
315
|
invocation.mark_result(error_msg, is_error=True)
|
|
312
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
|
+
)
|
|
313
324
|
|
|
314
325
|
# Get parent block_id from tool_call mapping
|
|
315
326
|
parent_block_id = agent._tool_call_blocks.get(invocation.tool_call_id)
|
|
@@ -342,6 +353,7 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
342
353
|
"tool_use_id": invocation.tool_call_id,
|
|
343
354
|
"tool_name": invocation.tool_name,
|
|
344
355
|
"content": result.output,
|
|
356
|
+
"truncated_content": result.truncated_output,
|
|
345
357
|
"is_error": invocation.is_error,
|
|
346
358
|
}
|
|
347
359
|
)
|
|
@@ -355,5 +367,6 @@ async def process_tool_results(agent: "ReactAgent") -> None:
|
|
|
355
367
|
content=tr["content"],
|
|
356
368
|
tool_call_id=tr["tool_use_id"],
|
|
357
369
|
name=tr["tool_name"], # Required for Gemini
|
|
370
|
+
truncated_content=tr.get("truncated_content"),
|
|
358
371
|
)
|
|
359
372
|
)
|
|
@@ -55,7 +55,7 @@ aury/agents/context_providers/skill.py,sha256=w_R1txvu45ruMjuOtckuD9oG_hqeFGqAa_
|
|
|
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
|
-
aury/agents/core/base.py,sha256=
|
|
58
|
+
aury/agents/core/base.py,sha256=1QgPe50DGajBgRhd8HFrzLaRAqkYioGpvU_ARwtV2DQ,21585
|
|
59
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
|
|
@@ -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
|
|
@@ -114,9 +114,9 @@ aury/agents/react/agent.py,sha256=DYWxuspMs3srOuxW4Sxis_Hkg4R6YkM0aM-rLRjD9Oo,23
|
|
|
114
114
|
aury/agents/react/context.py,sha256=Q7pY5j6b-OvKAmI1UsuawC3BmVxFkKN1oXxeBTVFejQ,11067
|
|
115
115
|
aury/agents/react/factory.py,sha256=7aWb2YqSdlIq161Ke0JZwnjpaA9U7Q5xejAnkrmjMUw,10776
|
|
116
116
|
aury/agents/react/pause.py,sha256=bcrhbuoJQUz7WxZSsKr5qjxQlDdpwai54ns_qio0du4,7306
|
|
117
|
-
aury/agents/react/persistence.py,sha256=
|
|
118
|
-
aury/agents/react/step.py,sha256=
|
|
119
|
-
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
|
|
120
120
|
aury/agents/sandbox/__init__.py,sha256=adH29NhzpZUIFVCxhRUZxyANKpFauUjsPVd8iktUOaI,635
|
|
121
121
|
aury/agents/sandbox/local.py,sha256=Dl-zJZ5FUz7WONtuze7MdpCDBjm9YZbjLIkGa9lYbwY,8328
|
|
122
122
|
aury/agents/sandbox/remote.py,sha256=6NcYIs_thjyxa5LgIqwoPNsHYpT70DG6xGbjDYV6-X4,6444
|
|
@@ -147,7 +147,7 @@ aury/agents/workflow/expression.py,sha256=Hsx2jBigtt5zbJb9uK9pveipqMbBBUUAvlgYjB
|
|
|
147
147
|
aury/agents/workflow/parser.py,sha256=mfiFZ_TtFq3IxAqPlTGcNkluiZ8ww16y3NYwbmbsrwE,6149
|
|
148
148
|
aury/agents/workflow/state.py,sha256=AxTSo7P9b1DbWjGdQdzFY4_7m6CJGNFo7xkGK28SPZw,4234
|
|
149
149
|
aury/agents/workflow/types.py,sha256=PVvjTQRgTObx5Mq_lXFogyLjGChOi5pUgcJwF5ZzVtg,2354
|
|
150
|
-
aury_agent-0.0.
|
|
151
|
-
aury_agent-0.0.
|
|
152
|
-
aury_agent-0.0.
|
|
153
|
-
aury_agent-0.0.
|
|
150
|
+
aury_agent-0.0.12.dist-info/METADATA,sha256=FNI9HTb1CwWuXKdPxWGcHD2PCu8V3QIogdr126INtvU,2115
|
|
151
|
+
aury_agent-0.0.12.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
152
|
+
aury_agent-0.0.12.dist-info/entry_points.txt,sha256=7EC5SMAKdC9HZLG8RfPhGno4OKOeSjaGsOWi1gOL-K8,56
|
|
153
|
+
aury_agent-0.0.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|