cua-agent 0.4.23__py3-none-any.whl → 0.4.24__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.
Potentially problematic release.
This version of cua-agent might be problematic. Click here for more details.
- agent/callbacks/image_retention.py +38 -87
- agent/callbacks/operator_validator.py +32 -32
- {cua_agent-0.4.23.dist-info → cua_agent-0.4.24.dist-info}/METADATA +1 -1
- {cua_agent-0.4.23.dist-info → cua_agent-0.4.24.dist-info}/RECORD +6 -6
- {cua_agent-0.4.23.dist-info → cua_agent-0.4.24.dist-info}/WHEEL +0 -0
- {cua_agent-0.4.23.dist-info → cua_agent-0.4.24.dist-info}/entry_points.txt +0 -0
|
@@ -50,90 +50,41 @@ class ImageRetentionCallback(AsyncCallbackHandler):
|
|
|
50
50
|
"""
|
|
51
51
|
if self.only_n_most_recent_images is None:
|
|
52
52
|
return messages
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
for
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
for
|
|
90
|
-
|
|
91
|
-
call_id = msg.get("call_id")
|
|
92
|
-
|
|
93
|
-
# Remove old computer_call items
|
|
94
|
-
if msg_type == "computer_call" and call_id not in keep_call_ids:
|
|
95
|
-
# Check if this call_id corresponds to an image call
|
|
96
|
-
has_image_output = any(
|
|
97
|
-
m.get("type") == "computer_call_output" and
|
|
98
|
-
m.get("call_id") == call_id and
|
|
99
|
-
isinstance(m.get("output"), dict) and
|
|
100
|
-
"image_url" in m.get("output", {})
|
|
101
|
-
for m in messages_with_call_ids
|
|
102
|
-
)
|
|
103
|
-
if has_image_output:
|
|
104
|
-
continue # Skip this computer_call
|
|
105
|
-
|
|
106
|
-
# Remove old computer_call_output items with images
|
|
107
|
-
if (msg_type == "computer_call_output" and
|
|
108
|
-
call_id not in keep_call_ids and
|
|
109
|
-
isinstance(msg.get("output"), dict) and
|
|
110
|
-
"image_url" in msg.get("output", {})):
|
|
111
|
-
continue # Skip this computer_call_output
|
|
112
|
-
|
|
113
|
-
# Remove old reasoning items that are paired with removed computer calls
|
|
114
|
-
if (msg_type == "reasoning" and
|
|
115
|
-
call_id and call_id not in keep_call_ids):
|
|
116
|
-
# Check if this call_id corresponds to an image call that's being removed
|
|
117
|
-
has_image_output = any(
|
|
118
|
-
m.get("type") == "computer_call_output" and
|
|
119
|
-
m.get("call_id") == call_id and
|
|
120
|
-
isinstance(m.get("output"), dict) and
|
|
121
|
-
"image_url" in m.get("output", {})
|
|
122
|
-
for m in messages_with_call_ids
|
|
123
|
-
)
|
|
124
|
-
if has_image_output:
|
|
125
|
-
continue # Skip this reasoning item
|
|
126
|
-
|
|
127
|
-
filtered_messages.append(msg)
|
|
128
|
-
|
|
129
|
-
# Clean up: Remove call_id from reasoning items before returning
|
|
130
|
-
final_messages = []
|
|
131
|
-
for msg in filtered_messages:
|
|
132
|
-
if msg.get("type") == "reasoning" and "call_id" in msg:
|
|
133
|
-
# Create a copy without call_id for reasoning items
|
|
134
|
-
cleaned_msg = {k: v for k, v in msg.items() if k != "call_id"}
|
|
135
|
-
final_messages.append(cleaned_msg)
|
|
136
|
-
else:
|
|
137
|
-
final_messages.append(msg)
|
|
138
|
-
|
|
139
|
-
return final_messages
|
|
53
|
+
|
|
54
|
+
# Gather indices of all computer_call_output messages that contain an image_url
|
|
55
|
+
output_indices: List[int] = []
|
|
56
|
+
for idx, msg in enumerate(messages):
|
|
57
|
+
if msg.get("type") == "computer_call_output":
|
|
58
|
+
out = msg.get("output")
|
|
59
|
+
if isinstance(out, dict) and ("image_url" in out):
|
|
60
|
+
output_indices.append(idx)
|
|
61
|
+
|
|
62
|
+
# Nothing to trim
|
|
63
|
+
if len(output_indices) <= self.only_n_most_recent_images:
|
|
64
|
+
return messages
|
|
65
|
+
|
|
66
|
+
# Determine which outputs to keep (most recent N)
|
|
67
|
+
keep_output_indices = set(output_indices[-self.only_n_most_recent_images :])
|
|
68
|
+
|
|
69
|
+
# Build set of indices to remove in one pass
|
|
70
|
+
to_remove: set[int] = set()
|
|
71
|
+
|
|
72
|
+
for idx in output_indices:
|
|
73
|
+
if idx in keep_output_indices:
|
|
74
|
+
continue # keep this screenshot and its context
|
|
75
|
+
|
|
76
|
+
to_remove.add(idx) # remove the computer_call_output itself
|
|
77
|
+
|
|
78
|
+
# Remove the immediately preceding computer_call with matching call_id (if present)
|
|
79
|
+
call_id = messages[idx].get("call_id")
|
|
80
|
+
prev_idx = idx - 1
|
|
81
|
+
if prev_idx >= 0 and messages[prev_idx].get("type") == "computer_call" and messages[prev_idx].get("call_id") == call_id:
|
|
82
|
+
to_remove.add(prev_idx)
|
|
83
|
+
# Check a single reasoning immediately before that computer_call
|
|
84
|
+
r_idx = prev_idx - 1
|
|
85
|
+
if r_idx >= 0 and messages[r_idx].get("type") == "reasoning":
|
|
86
|
+
to_remove.add(r_idx)
|
|
87
|
+
|
|
88
|
+
# Construct filtered list
|
|
89
|
+
filtered = [m for i, m in enumerate(messages) if i not in to_remove]
|
|
90
|
+
return filtered
|
|
@@ -102,37 +102,37 @@ class OperatorNormalizerCallback(AsyncCallbackHandler):
|
|
|
102
102
|
_keep_keys(action, keep)
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
# Second pass: if an assistant message is immediately followed by a computer_call,
|
|
106
|
-
# replace the assistant message itself with a reasoning message with summary text.
|
|
107
|
-
if isinstance(output, list):
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
105
|
+
# # Second pass: if an assistant message is immediately followed by a computer_call,
|
|
106
|
+
# # replace the assistant message itself with a reasoning message with summary text.
|
|
107
|
+
# if isinstance(output, list):
|
|
108
|
+
# for i, item in enumerate(output):
|
|
109
|
+
# # AssistantMessage shape: { type: 'message', role: 'assistant', content: OutputContent[] }
|
|
110
|
+
# if item.get("type") == "message" and item.get("role") == "assistant":
|
|
111
|
+
# next_idx = i + 1
|
|
112
|
+
# if next_idx >= len(output):
|
|
113
|
+
# continue
|
|
114
|
+
# next_item = output[next_idx]
|
|
115
|
+
# if not isinstance(next_item, dict):
|
|
116
|
+
# continue
|
|
117
|
+
# if next_item.get("type") != "computer_call":
|
|
118
|
+
# continue
|
|
119
|
+
# contents = item.get("content") or []
|
|
120
|
+
# # Extract text from OutputContent[]
|
|
121
|
+
# text_parts: List[str] = []
|
|
122
|
+
# if isinstance(contents, list):
|
|
123
|
+
# for c in contents:
|
|
124
|
+
# if isinstance(c, dict) and c.get("type") == "output_text" and isinstance(c.get("text"), str):
|
|
125
|
+
# text_parts.append(c["text"])
|
|
126
|
+
# text_content = "\n".join(text_parts).strip()
|
|
127
|
+
# # Replace assistant message with reasoning message
|
|
128
|
+
# output[i] = {
|
|
129
|
+
# "type": "reasoning",
|
|
130
|
+
# "summary": [
|
|
131
|
+
# {
|
|
132
|
+
# "type": "summary_text",
|
|
133
|
+
# "text": text_content,
|
|
134
|
+
# }
|
|
135
|
+
# ],
|
|
136
|
+
# }
|
|
137
137
|
|
|
138
138
|
return output
|
|
@@ -8,9 +8,9 @@ agent/agent.py,sha256=ao3SKnZoX5_P6mTzEg0hgOUam6bNRwpbitzlyvwI3bg,29826
|
|
|
8
8
|
agent/callbacks/__init__.py,sha256=et6pNfX_AiJqhVzUfCvcjzFbDhfLoHazKCXN5sqwxaM,631
|
|
9
9
|
agent/callbacks/base.py,sha256=UnnnYlh6XCm6HKZZsAPaT_Eyo9LUYLyjyNwF-QRm6Ns,4691
|
|
10
10
|
agent/callbacks/budget_manager.py,sha256=RyKM-7iXQcDotYvrw3eURzeEHEXvQjID-NobtvQWE7k,1832
|
|
11
|
-
agent/callbacks/image_retention.py,sha256=
|
|
11
|
+
agent/callbacks/image_retention.py,sha256=8MeLo5-Y7cACpsNk2p_bvnZIYKpW6XgyukmdYGX23rE,3588
|
|
12
12
|
agent/callbacks/logging.py,sha256=OOxU97EzrxlnUAtiEnvy9FB7SwCUK90-rdpDFA2Ae4E,10921
|
|
13
|
-
agent/callbacks/operator_validator.py,sha256=
|
|
13
|
+
agent/callbacks/operator_validator.py,sha256=T5tp62pkShkcdHu2rgREUGdk8fryL_ziJsItXsfgYUQ,6494
|
|
14
14
|
agent/callbacks/pii_anonymization.py,sha256=NEkUTUjQBi82nqus7kT-1E4RaeQ2hQrY7YCnKndLhP8,3272
|
|
15
15
|
agent/callbacks/telemetry.py,sha256=RbUDhE41mTi8g9hNre0EpltK_NUZkLj8buJLWBzs0Ek,7363
|
|
16
16
|
agent/callbacks/trajectory_saver.py,sha256=rslgg4Ak7JHSNmmJgANRQ5TsUYWGuUJDZ6amureaz_o,15963
|
|
@@ -45,7 +45,7 @@ agent/ui/__main__.py,sha256=vudWXYvGM0aNT5aZ94HPtGW8YXOZ4cLXepHyhUM_k1g,73
|
|
|
45
45
|
agent/ui/gradio/__init__.py,sha256=yv4Mrfo-Sj2U5sVn_UJHAuwYCezo-5O4ItR2C9jzNko,145
|
|
46
46
|
agent/ui/gradio/app.py,sha256=Ol97YEbwREZZQ9_PMjVHlfOcu9BGsawxgAGAm79hT80,9117
|
|
47
47
|
agent/ui/gradio/ui_components.py,sha256=dJUvKDmc1oSejtoR_gU_oWWYwxaOOQyPloSYRGMrUCQ,36068
|
|
48
|
-
cua_agent-0.4.
|
|
49
|
-
cua_agent-0.4.
|
|
50
|
-
cua_agent-0.4.
|
|
51
|
-
cua_agent-0.4.
|
|
48
|
+
cua_agent-0.4.24.dist-info/METADATA,sha256=-yvFHUziugRMdDqtf_NDVnQfcNbHKut_rr-yswIDYkM,12712
|
|
49
|
+
cua_agent-0.4.24.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
|
50
|
+
cua_agent-0.4.24.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
|
51
|
+
cua_agent-0.4.24.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|