inspect-ai 0.3.70__py3-none-any.whl → 0.3.72__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.
Files changed (219) hide show
  1. inspect_ai/_cli/eval.py +14 -8
  2. inspect_ai/_display/core/display.py +2 -0
  3. inspect_ai/_display/core/footer.py +13 -3
  4. inspect_ai/_display/plain/display.py +6 -2
  5. inspect_ai/_display/rich/display.py +19 -6
  6. inspect_ai/_display/textual/app.py +6 -1
  7. inspect_ai/_display/textual/display.py +4 -0
  8. inspect_ai/_display/textual/widgets/transcript.py +10 -6
  9. inspect_ai/_eval/task/run.py +5 -8
  10. inspect_ai/_util/content.py +20 -1
  11. inspect_ai/_util/transcript.py +10 -4
  12. inspect_ai/_util/working.py +4 -0
  13. inspect_ai/_view/www/App.css +6 -0
  14. inspect_ai/_view/www/dist/assets/index.css +115 -87
  15. inspect_ai/_view/www/dist/assets/index.js +5324 -2276
  16. inspect_ai/_view/www/eslint.config.mjs +24 -1
  17. inspect_ai/_view/www/log-schema.json +283 -20
  18. inspect_ai/_view/www/package.json +8 -3
  19. inspect_ai/_view/www/src/App.tsx +2 -2
  20. inspect_ai/_view/www/src/components/AnsiDisplay.tsx +4 -3
  21. inspect_ai/_view/www/src/components/Card.tsx +9 -8
  22. inspect_ai/_view/www/src/components/DownloadButton.tsx +2 -1
  23. inspect_ai/_view/www/src/components/EmptyPanel.tsx +2 -2
  24. inspect_ai/_view/www/src/components/ErrorPanel.tsx +4 -3
  25. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +13 -5
  26. inspect_ai/_view/www/src/components/FindBand.tsx +3 -3
  27. inspect_ai/_view/www/src/components/HumanBaselineView.tsx +3 -3
  28. inspect_ai/_view/www/src/components/LabeledValue.tsx +5 -4
  29. inspect_ai/_view/www/src/components/LargeModal.tsx +18 -13
  30. inspect_ai/_view/www/src/components/{LightboxCarousel.css → LightboxCarousel.module.css} +22 -18
  31. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +36 -27
  32. inspect_ai/_view/www/src/components/MessageBand.tsx +2 -1
  33. inspect_ai/_view/www/src/components/NavPills.tsx +9 -8
  34. inspect_ai/_view/www/src/components/ProgressBar.tsx +2 -1
  35. inspect_ai/_view/www/src/components/TabSet.tsx +21 -15
  36. inspect_ai/_view/www/src/index.tsx +2 -2
  37. inspect_ai/_view/www/src/metadata/MetaDataGrid.tsx +11 -9
  38. inspect_ai/_view/www/src/metadata/MetaDataView.tsx +3 -2
  39. inspect_ai/_view/www/src/metadata/MetadataGrid.module.css +1 -0
  40. inspect_ai/_view/www/src/metadata/RenderedContent.tsx +16 -0
  41. inspect_ai/_view/www/src/plan/DatasetDetailView.tsx +3 -2
  42. inspect_ai/_view/www/src/plan/DetailStep.tsx +2 -1
  43. inspect_ai/_view/www/src/plan/PlanCard.tsx +2 -5
  44. inspect_ai/_view/www/src/plan/PlanDetailView.tsx +6 -9
  45. inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +2 -1
  46. inspect_ai/_view/www/src/plan/SolverDetailView.tsx +3 -3
  47. inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +2 -2
  48. inspect_ai/_view/www/src/samples/SampleDialog.tsx +3 -3
  49. inspect_ai/_view/www/src/samples/SampleDisplay.tsx +2 -2
  50. inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +2 -2
  51. inspect_ai/_view/www/src/samples/SamplesTools.tsx +2 -1
  52. inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +3 -19
  53. inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +2 -1
  54. inspect_ai/_view/www/src/samples/chat/ChatMessageRow.tsx +2 -1
  55. inspect_ai/_view/www/src/samples/chat/ChatView.tsx +2 -1
  56. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +22 -7
  57. inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +35 -6
  58. inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +2 -2
  59. inspect_ai/_view/www/src/samples/chat/messages.ts +15 -2
  60. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +13 -4
  61. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.module.css +2 -2
  62. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +18 -19
  63. inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.module.css +1 -1
  64. inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.tsx +4 -3
  65. inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.tsx +2 -2
  66. inspect_ai/_view/www/src/samples/error/FlatSampleErrorView.tsx +2 -3
  67. inspect_ai/_view/www/src/samples/error/SampleErrorView.tsx +3 -2
  68. inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +2 -1
  69. inspect_ai/_view/www/src/samples/list/SampleHeader.tsx +2 -1
  70. inspect_ai/_view/www/src/samples/list/SampleList.tsx +57 -45
  71. inspect_ai/_view/www/src/samples/list/SampleRow.tsx +2 -1
  72. inspect_ai/_view/www/src/samples/list/SampleSeparator.tsx +2 -1
  73. inspect_ai/_view/www/src/samples/sample-tools/EpochFilter.tsx +2 -2
  74. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +4 -3
  75. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +2 -5
  76. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +2 -2
  77. inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +2 -1
  78. inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +2 -2
  79. inspect_ai/_view/www/src/samples/transcript/ApprovalEventView.tsx +2 -1
  80. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +2 -1
  81. inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +2 -1
  82. inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +2 -1
  83. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.module.css +4 -0
  84. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.tsx +12 -2
  85. inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +1 -1
  86. inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +25 -28
  87. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +2 -1
  88. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +5 -4
  89. inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +2 -2
  90. inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +8 -7
  91. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +2 -2
  92. inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +3 -3
  93. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +18 -14
  94. inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +5 -5
  95. inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +34 -15
  96. inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +2 -1
  97. inspect_ai/_view/www/src/samples/transcript/event/EventNavs.tsx +2 -1
  98. inspect_ai/_view/www/src/samples/transcript/event/EventRow.tsx +3 -2
  99. inspect_ai/_view/www/src/samples/transcript/event/EventSection.tsx +2 -2
  100. inspect_ai/_view/www/src/samples/transcript/event/EventTimingPanel.module.css +28 -0
  101. inspect_ai/_view/www/src/samples/transcript/event/EventTimingPanel.tsx +115 -0
  102. inspect_ai/_view/www/src/samples/transcript/event/utils.ts +29 -0
  103. inspect_ai/_view/www/src/samples/transcript/state/StateDiffView.tsx +2 -1
  104. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +3 -3
  105. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +11 -8
  106. inspect_ai/_view/www/src/types/log.d.ts +129 -34
  107. inspect_ai/_view/www/src/usage/ModelTokenTable.tsx +6 -10
  108. inspect_ai/_view/www/src/usage/ModelUsagePanel.module.css +4 -0
  109. inspect_ai/_view/www/src/usage/ModelUsagePanel.tsx +32 -9
  110. inspect_ai/_view/www/src/usage/TokenTable.tsx +4 -6
  111. inspect_ai/_view/www/src/usage/UsageCard.tsx +2 -1
  112. inspect_ai/_view/www/src/utils/format.ts +1 -1
  113. inspect_ai/_view/www/src/utils/json.ts +24 -0
  114. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +6 -5
  115. inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +9 -2
  116. inspect_ai/_view/www/src/workspace/error/TaskErrorPanel.tsx +2 -1
  117. inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +2 -1
  118. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +3 -3
  119. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +4 -3
  120. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +5 -4
  121. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +5 -8
  122. inspect_ai/_view/www/src/workspace/sidebar/EvalStatus.tsx +5 -4
  123. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +2 -1
  124. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +2 -1
  125. inspect_ai/_view/www/src/workspace/sidebar/SidebarLogEntry.tsx +2 -2
  126. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoreView.tsx +2 -1
  127. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoresView.tsx +2 -2
  128. inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +2 -2
  129. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +2 -5
  130. inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +12 -11
  131. inspect_ai/_view/www/yarn.lock +241 -5
  132. inspect_ai/log/_condense.py +3 -0
  133. inspect_ai/log/_recorders/eval.py +6 -1
  134. inspect_ai/log/_transcript.py +58 -1
  135. inspect_ai/model/__init__.py +2 -0
  136. inspect_ai/model/_call_tools.py +7 -0
  137. inspect_ai/model/_chat_message.py +22 -7
  138. inspect_ai/model/_conversation.py +10 -8
  139. inspect_ai/model/_generate_config.py +25 -4
  140. inspect_ai/model/_model.py +133 -57
  141. inspect_ai/model/_model_output.py +3 -0
  142. inspect_ai/model/_openai.py +106 -40
  143. inspect_ai/model/_providers/anthropic.py +281 -153
  144. inspect_ai/model/_providers/google.py +27 -8
  145. inspect_ai/model/_providers/groq.py +9 -4
  146. inspect_ai/model/_providers/openai.py +57 -4
  147. inspect_ai/model/_providers/openai_o1.py +10 -0
  148. inspect_ai/model/_providers/providers.py +1 -1
  149. inspect_ai/model/_reasoning.py +15 -2
  150. inspect_ai/scorer/_model.py +23 -19
  151. inspect_ai/solver/_human_agent/agent.py +14 -10
  152. inspect_ai/solver/_human_agent/commands/__init__.py +7 -3
  153. inspect_ai/solver/_human_agent/commands/submit.py +76 -30
  154. inspect_ai/tool/__init__.py +2 -0
  155. inspect_ai/tool/_tool.py +3 -1
  156. inspect_ai/tool/_tools/_computer/_common.py +117 -58
  157. inspect_ai/tool/_tools/_computer/_computer.py +80 -57
  158. inspect_ai/tool/_tools/_computer/_resources/image_home_dir/.config/Code/User/settings.json +7 -1
  159. inspect_ai/tool/_tools/_computer/_resources/image_home_dir/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml +91 -0
  160. inspect_ai/tool/_tools/_computer/_resources/tool/.pylintrc +8 -0
  161. inspect_ai/tool/_tools/_computer/_resources/tool/.vscode/settings.json +12 -0
  162. inspect_ai/tool/_tools/_computer/_resources/tool/_args.py +78 -0
  163. inspect_ai/tool/_tools/_computer/_resources/tool/_constants.py +20 -0
  164. inspect_ai/tool/_tools/_computer/_resources/tool/_run.py +1 -1
  165. inspect_ai/tool/_tools/_computer/_resources/tool/_x11_client.py +175 -113
  166. inspect_ai/tool/_tools/_computer/_resources/tool/computer_tool.py +76 -20
  167. inspect_ai/tool/_tools/_computer/_resources/tool/pyproject.toml +65 -0
  168. inspect_ai/tool/_tools/_computer/test_args.py +151 -0
  169. inspect_ai/tool/_tools/_web_browser/_resources/.pylintrc +8 -0
  170. inspect_ai/tool/_tools/_web_browser/_resources/.vscode/launch.json +24 -0
  171. inspect_ai/tool/_tools/_web_browser/_resources/.vscode/settings.json +25 -0
  172. inspect_ai/tool/_tools/_web_browser/_resources/Dockerfile +5 -6
  173. inspect_ai/tool/_tools/_web_browser/_resources/README.md +10 -11
  174. inspect_ai/tool/_tools/_web_browser/_resources/accessibility_tree.py +71 -0
  175. inspect_ai/tool/_tools/_web_browser/_resources/accessibility_tree_node.py +323 -0
  176. inspect_ai/tool/_tools/_web_browser/_resources/cdp/__init__.py +5 -0
  177. inspect_ai/tool/_tools/_web_browser/_resources/cdp/a11y.py +279 -0
  178. inspect_ai/tool/_tools/_web_browser/_resources/cdp/dom.py +9 -0
  179. inspect_ai/tool/_tools/_web_browser/_resources/cdp/dom_snapshot.py +293 -0
  180. inspect_ai/tool/_tools/_web_browser/_resources/cdp/page.py +94 -0
  181. inspect_ai/tool/_tools/_web_browser/_resources/constants.py +2 -0
  182. inspect_ai/tool/_tools/_web_browser/_resources/images/usage_diagram.svg +2 -0
  183. inspect_ai/tool/_tools/_web_browser/_resources/playwright_browser.py +50 -0
  184. inspect_ai/tool/_tools/_web_browser/_resources/playwright_crawler.py +31 -359
  185. inspect_ai/tool/_tools/_web_browser/_resources/playwright_page_crawler.py +280 -0
  186. inspect_ai/tool/_tools/_web_browser/_resources/pyproject.toml +65 -0
  187. inspect_ai/tool/_tools/_web_browser/_resources/rectangle.py +64 -0
  188. inspect_ai/tool/_tools/_web_browser/_resources/rpc_client_helpers.py +146 -0
  189. inspect_ai/tool/_tools/_web_browser/_resources/scale_factor.py +64 -0
  190. inspect_ai/tool/_tools/_web_browser/_resources/test_accessibility_tree_node.py +180 -0
  191. inspect_ai/tool/_tools/_web_browser/_resources/test_playwright_crawler.py +15 -9
  192. inspect_ai/tool/_tools/_web_browser/_resources/test_rectangle.py +15 -0
  193. inspect_ai/tool/_tools/_web_browser/_resources/test_web_client.py +44 -0
  194. inspect_ai/tool/_tools/_web_browser/_resources/web_browser_rpc_types.py +39 -0
  195. inspect_ai/tool/_tools/_web_browser/_resources/web_client.py +198 -48
  196. inspect_ai/tool/_tools/_web_browser/_resources/web_client_new_session.py +26 -25
  197. inspect_ai/tool/_tools/_web_browser/_resources/web_server.py +178 -39
  198. inspect_ai/tool/_tools/_web_browser/_web_browser.py +38 -19
  199. inspect_ai/util/__init__.py +2 -1
  200. inspect_ai/util/_display.py +12 -0
  201. inspect_ai/util/_sandbox/events.py +55 -21
  202. inspect_ai/util/_sandbox/self_check.py +131 -43
  203. inspect_ai/util/_subtask.py +11 -0
  204. {inspect_ai-0.3.70.dist-info → inspect_ai-0.3.72.dist-info}/METADATA +1 -1
  205. {inspect_ai-0.3.70.dist-info → inspect_ai-0.3.72.dist-info}/RECORD +209 -186
  206. {inspect_ai-0.3.70.dist-info → inspect_ai-0.3.72.dist-info}/WHEEL +1 -1
  207. inspect_ai/_view/www/src/components/VirtualList.module.css +0 -19
  208. inspect_ai/_view/www/src/components/VirtualList.tsx +0 -292
  209. inspect_ai/tool/_tools/_computer/_computer_split.py +0 -198
  210. inspect_ai/tool/_tools/_web_browser/_resources/accessibility_node.py +0 -312
  211. inspect_ai/tool/_tools/_web_browser/_resources/dm_env_servicer.py +0 -275
  212. inspect_ai/tool/_tools/_web_browser/_resources/images/usage_diagram.png +0 -0
  213. inspect_ai/tool/_tools/_web_browser/_resources/test_accessibility_node.py +0 -176
  214. inspect_ai/tool/_tools/_web_browser/_resources/test_dm_env_servicer.py +0 -135
  215. inspect_ai/tool/_tools/_web_browser/_resources/test_web_environment.py +0 -71
  216. inspect_ai/tool/_tools/_web_browser/_resources/web_environment.py +0 -184
  217. {inspect_ai-0.3.70.dist-info → inspect_ai-0.3.72.dist-info}/LICENSE +0 -0
  218. {inspect_ai-0.3.70.dist-info → inspect_ai-0.3.72.dist-info}/entry_points.txt +0 -0
  219. {inspect_ai-0.3.70.dist-info → inspect_ai-0.3.72.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,19 +0,0 @@
1
- .container {
2
- position: relative;
3
- width: 100%;
4
- min-height: 100%;
5
- overflow: visible;
6
- }
7
-
8
- .container.hidden {
9
- overflow: hidden;
10
- }
11
-
12
- .content {
13
- position: absolute;
14
- top: 0;
15
- left: 0;
16
- height: 100%;
17
- width: 100%;
18
- overflow: visible;
19
- }
@@ -1,292 +0,0 @@
1
- import clsx from "clsx";
2
- import React, {
3
- forwardRef,
4
- useEffect,
5
- useImperativeHandle,
6
- useMemo,
7
- useRef,
8
- useState,
9
- } from "react";
10
- import styles from "./VirtualList.module.css";
11
-
12
- export interface VirtualListRef {
13
- focus: () => void;
14
- scrollToIndex: (index: number, direction?: "up" | "down") => void;
15
- }
16
-
17
- interface VirtualListProps<T> {
18
- data: T[];
19
- renderRow: (item: T, index: number) => React.ReactNode;
20
- overscanCount?: number;
21
- initialEstimatedRowHeight?: number;
22
- sync?: boolean;
23
- scrollRef?: React.RefObject<HTMLElement | null>;
24
- className?: string;
25
- style?: React.CSSProperties;
26
- tabIndex?: number;
27
- onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
28
- }
29
-
30
- interface ListMetrics {
31
- rowHeights: Map<number, number>;
32
- totalHeight: number;
33
- estimatedRowHeight: number;
34
- }
35
-
36
- export const VirtualList = forwardRef(function VirtualList<T>(
37
- {
38
- data,
39
- renderRow,
40
- overscanCount = 15,
41
- initialEstimatedRowHeight = 50,
42
- sync = false,
43
- scrollRef,
44
- onKeyDown,
45
- ...props
46
- }: VirtualListProps<T>,
47
- ref: React.Ref<VirtualListRef>,
48
- ) {
49
- const [height, setHeight] = useState(0);
50
- const [offset, setOffset] = useState(0);
51
- const [listMetrics, setListMetrics] = useState<ListMetrics>({
52
- rowHeights: new Map(),
53
- totalHeight: data.length * initialEstimatedRowHeight,
54
- estimatedRowHeight: initialEstimatedRowHeight,
55
- });
56
-
57
- const baseRef = useRef<HTMLDivElement>(null);
58
- const containerRef = useRef<HTMLDivElement>(null);
59
- const rowRefs = useRef<Map<number, HTMLElement>>(new Map());
60
-
61
- const getRowHeight = (index: number): number => {
62
- return listMetrics.rowHeights.get(index) || listMetrics.estimatedRowHeight;
63
- };
64
-
65
- // Calculate new estimated height based on measured rows
66
- const calculateEstimatedHeight = (heights: Map<number, number>): number => {
67
- if (heights.size === 0) return listMetrics.estimatedRowHeight;
68
-
69
- // Calculate average of measured heights
70
- let sum = 0;
71
- heights.forEach((height) => {
72
- sum += height;
73
- });
74
-
75
- // Use exponential moving average to smooth transitions
76
- const alpha = 0.2; // Smoothing factor
77
- const newEstimate = sum / heights.size;
78
- return Math.round(
79
- alpha * newEstimate + (1 - alpha) * listMetrics.estimatedRowHeight,
80
- );
81
- };
82
-
83
- const rowPositions = useMemo(() => {
84
- let currentPosition = 0;
85
- const positions = new Map<number, number>();
86
-
87
- for (let i = 0; i < data.length; i++) {
88
- positions.set(i, currentPosition);
89
- currentPosition += getRowHeight(i);
90
- }
91
-
92
- return positions;
93
- }, [listMetrics.rowHeights, listMetrics.estimatedRowHeight, data.length]);
94
-
95
- // Measure rendered rows and update heights if needed
96
- const measureRows = () => {
97
- let updates: [number, number][] = [];
98
-
99
- rowRefs.current.forEach((element, index) => {
100
- if (element) {
101
- const measuredHeight = element.offsetHeight;
102
- if (
103
- measuredHeight &&
104
- measuredHeight !== listMetrics.rowHeights.get(index)
105
- ) {
106
- updates.push([index, measuredHeight]);
107
- }
108
- }
109
- });
110
-
111
- if (updates.length === 0) return;
112
-
113
- const newHeights = new Map(listMetrics.rowHeights);
114
- updates.forEach(([index, height]) => {
115
- newHeights.set(index, height);
116
- });
117
-
118
- // Calculate new estimated height
119
- const newEstimatedHeight = calculateEstimatedHeight(newHeights);
120
-
121
- let newTotalHeight = 0;
122
- for (let i = 0; i < data.length; i++) {
123
- newTotalHeight += newHeights.get(i) || newEstimatedHeight;
124
- }
125
-
126
- setListMetrics({
127
- rowHeights: newHeights,
128
- totalHeight: newTotalHeight,
129
- estimatedRowHeight: newEstimatedHeight,
130
- });
131
- };
132
-
133
- useImperativeHandle(
134
- ref,
135
- () => ({
136
- focus: () => {
137
- baseRef.current?.focus();
138
- },
139
- scrollToIndex: (index: number, direction?: "up" | "down") => {
140
- const scrollElement = scrollRef?.current || baseRef.current;
141
- if (!scrollElement || index < 0 || index >= data.length) return;
142
-
143
- const currentScrollTop = scrollElement.scrollTop;
144
- const viewportHeight = scrollElement.offsetHeight;
145
-
146
- const rowTop = rowPositions.get(index) || 0;
147
- const rowHeight = getRowHeight(index);
148
- const rowBottom = rowTop + rowHeight;
149
-
150
- const isVisible =
151
- rowTop >= currentScrollTop &&
152
- rowBottom <= currentScrollTop + viewportHeight;
153
- if (isVisible) return;
154
-
155
- let newScrollTop: number;
156
- if (direction === "up") {
157
- newScrollTop = rowTop;
158
- } else {
159
- newScrollTop = rowBottom - viewportHeight;
160
- }
161
-
162
- newScrollTop = Math.max(
163
- 0,
164
- Math.min(newScrollTop, listMetrics.totalHeight - viewportHeight),
165
- );
166
- scrollElement.scrollTop = newScrollTop;
167
- },
168
- }),
169
- [rowPositions, data.length],
170
- );
171
-
172
- const resize = () => {
173
- const scrollElement = scrollRef?.current || baseRef.current;
174
- if (scrollElement && height !== scrollElement.offsetHeight) {
175
- setHeight(scrollElement.offsetHeight);
176
- }
177
- };
178
-
179
- const handleScroll = throttle(() => {
180
- const scrollElement = scrollRef?.current || baseRef.current;
181
- if (scrollElement) {
182
- setOffset(scrollElement.scrollTop);
183
- }
184
- if (sync) {
185
- setOffset((prev) => prev);
186
- }
187
- }, 100);
188
-
189
- useEffect(() => {
190
- resize();
191
- const scrollElement = scrollRef?.current || baseRef.current;
192
-
193
- if (scrollElement) {
194
- scrollElement.addEventListener("scroll", handleScroll);
195
- window.addEventListener("resize", resize);
196
-
197
- return () => {
198
- scrollElement.removeEventListener("scroll", handleScroll);
199
- window.removeEventListener("resize", resize);
200
- };
201
- }
202
- }, [scrollRef?.current]);
203
-
204
- useEffect(() => {
205
- measureRows();
206
- });
207
-
208
- const findRowAtOffset = (targetOffset: number): number => {
209
- if (targetOffset <= 0) return 0;
210
- if (targetOffset >= listMetrics.totalHeight) return data.length - 1;
211
-
212
- let low = 0;
213
- let high = data.length - 1;
214
- let lastValid = 0;
215
-
216
- while (low <= high) {
217
- const mid = Math.floor((low + high) / 2);
218
- const rowStart = rowPositions.get(mid) || 0;
219
-
220
- if (rowStart <= targetOffset) {
221
- lastValid = mid;
222
- low = mid + 1;
223
- } else {
224
- high = mid - 1;
225
- }
226
- }
227
- return lastValid;
228
- };
229
-
230
- const firstVisibleIdx = findRowAtOffset(offset);
231
- const lastVisibleIdx = findRowAtOffset(offset + height);
232
-
233
- const start = Math.max(0, firstVisibleIdx - overscanCount);
234
- const end = Math.min(data.length, lastVisibleIdx + overscanCount);
235
-
236
- const renderedRows = useMemo(() => {
237
- const selection = data.slice(start, end);
238
- return selection.map((item, index) => {
239
- const actualIndex = start + index;
240
- return (
241
- <div
242
- key={`list-item-${actualIndex}`}
243
- ref={(el) => {
244
- if (el) {
245
- rowRefs.current.set(actualIndex, el);
246
- } else {
247
- rowRefs.current.delete(actualIndex);
248
- }
249
- }}
250
- >
251
- {renderRow(item, actualIndex)}
252
- </div>
253
- );
254
- });
255
- }, [data, start, end, renderRow]);
256
-
257
- const top = rowPositions.get(start) || 0;
258
- const scrollProps = scrollRef ? {} : { onScroll: handleScroll };
259
-
260
- return (
261
- <div ref={baseRef} {...props} {...scrollProps} onKeyDown={onKeyDown}>
262
- <div
263
- className={clsx(
264
- styles.container,
265
- !scrollRef?.current ? styles.hidden : undefined,
266
- )}
267
- style={{ height: `${listMetrics.totalHeight}px` }}
268
- >
269
- <div
270
- className={styles.content}
271
- style={{ transform: `translateY(${top}px)` }}
272
- ref={containerRef}
273
- >
274
- {renderedRows}
275
- </div>
276
- </div>
277
- </div>
278
- );
279
- }) as <T>(
280
- props: VirtualListProps<T> & { ref?: React.Ref<VirtualListRef> },
281
- ) => React.ReactElement;
282
-
283
- const throttle = (func: (...args: any[]) => void, limit: number) => {
284
- let inThrottle: boolean;
285
- return function (this: any, ...args: any[]) {
286
- if (!inThrottle) {
287
- func.apply(this, args);
288
- inThrottle = true;
289
- setTimeout(() => (inThrottle = false), limit);
290
- }
291
- };
292
- };
@@ -1,198 +0,0 @@
1
- """
2
- This module provides the same functionality as the computer tool but via a list of per-action tools . e.g. computer_mouse_move(100, 100).
3
-
4
- The split version is not publicly exported, but is retained until we decide if it performs better than the monolithic computer tool.
5
- """
6
-
7
- from typing import Awaitable, Callable
8
-
9
- from inspect_ai.tool import Tool, ToolResult, tool
10
-
11
- from . import _common as common
12
-
13
- ActionFunction = Callable[[str], ToolResult | Awaitable[ToolResult]]
14
-
15
-
16
- def computer_split(timeout: int | None = None) -> list[Tool]:
17
- """
18
- Computer interaction tools.
19
-
20
- Args:
21
- timeout (int | None): Timeout (in seconds) for command.
22
-
23
- Returns:
24
- List of computer interaction tools.
25
- """
26
- return [
27
- computer_cursor_position(),
28
- computer_screenshot(),
29
- computer_mouse_move(),
30
- computer_left_click(),
31
- computer_double_click(),
32
- computer_left_click_drag(),
33
- computer_right_click(),
34
- computer_key(),
35
- computer_type(),
36
- ]
37
-
38
-
39
- @tool()
40
- def computer_cursor_position(timeout: int | None = None) -> Tool:
41
- async def execute() -> ToolResult:
42
- """
43
- Get the current (x, y) pixel coordinate of the cursor on the screen.
44
-
45
- Args:
46
- None
47
-
48
- Returns:
49
- A `str` of the form "x y" where x and y are the current mouse coordinates.
50
- """
51
- return await common.cursor_position(timeout=timeout)
52
-
53
- return execute
54
-
55
-
56
- @tool()
57
- def computer_screenshot(timeout: int | None = None) -> Tool:
58
- async def execute() -> ToolResult:
59
- """
60
- Take a screenshot.
61
-
62
- Args:
63
- None
64
-
65
- Returns:
66
- A `list` with a single `ContentImage` of the screen.
67
- """
68
- return await common.screenshot(timeout=timeout)
69
-
70
- return execute
71
-
72
-
73
- @tool()
74
- def computer_mouse_move(timeout: int | None = None) -> Tool:
75
- async def execute(x: int, y: int) -> ToolResult:
76
- """
77
- Move the cursor to a specified (x, y) pixel coordinate on the screen.
78
-
79
- Args:
80
- x: X coordinate of the mouse destination.
81
- y: Y coordinate of the mouse destination.
82
-
83
- Returns:
84
- A `list` with a single `ContentImage` of the screen.
85
- """
86
- return await common.mouse_move(x, y, timeout=timeout)
87
-
88
- return execute
89
-
90
-
91
- @tool()
92
- def computer_left_click(timeout: int | None = None) -> Tool:
93
- async def execute() -> ToolResult:
94
- """
95
- Click the left mouse button.
96
-
97
- Args:
98
- None
99
-
100
- Returns:
101
- A `list` with a single `ContentImage` of the screen.
102
- """
103
- return await common.left_click(timeout=timeout)
104
-
105
- return execute
106
-
107
-
108
- @tool()
109
- def computer_double_click(timeout: int | None = None) -> Tool:
110
- async def execute() -> ToolResult:
111
- """
112
- Double-click the left mouse button.
113
-
114
- Args:
115
- None
116
-
117
- Returns:
118
- A `list` with a single `ContentImage` of the screen.
119
- """
120
- return await common.double_click(timeout=timeout)
121
-
122
- return execute
123
-
124
-
125
- @tool()
126
- def computer_left_click_drag(timeout: int | None = None) -> Tool:
127
- async def execute(x: int, y: int) -> ToolResult:
128
- """
129
- Click and drag the cursor to a specified (x, y) pixel coordinate on the screen.
130
-
131
- Args:
132
- x: X coordinate of the mouse destination.
133
- y: Y coordinate of the mouse destination.
134
-
135
- Returns:
136
- A `list` with a single `ContentImage` of the screen.
137
- """
138
- return await common.left_click_drag(x, y, timeout=timeout)
139
-
140
- return execute
141
-
142
-
143
- @tool()
144
- def computer_right_click(timeout: int | None = None) -> Tool:
145
- async def execute() -> ToolResult:
146
- """
147
- Click the right mouse button.
148
-
149
- Args:
150
- None
151
-
152
- Returns:
153
- A `list` with a single `ContentImage` of the screen.
154
- """
155
- return await common.right_click(timeout=timeout)
156
-
157
- return execute
158
-
159
-
160
- # keysm list is from https://gist.github.com/rvaiya/be31f42049a4b5ad46666a8e120d9843
161
- @tool()
162
- def computer_key(timeout: int | None = None) -> Tool:
163
- async def execute(key: str) -> ToolResult:
164
- """
165
- Press a key or key-combination on the keyboard.
166
-
167
- Args:
168
- key: The key or key-combination to press. Can be any key name supported by xdotool's `key` such as:
169
- "Return", "Escape", "alt+Tab", "BackSpace", "Tab", "alt+Tab", "ctrl+s", "Up", "KP_0" (for the numpad 0 key),
170
- "Insert", "Delete", "Home", "End", "Prior", "Next", "Left", "Up", "Right", "Down",
171
- "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
172
- "Shift_L", "Shift_R", "Control_L", "Control_R", "Alt_L", "Alt_R", "Scroll_Lock", "Num_Lock", "Caps_Lock", "Pause",
173
- "KP_Multiply", "KP_Home", "KP_Up", "KP_Prior", "KP_Subtract", "KP_Left", "KP_Begin", "KP_Right", "KP_Add", "KP_End","KP_Down",
174
- "KP_Next", "KP_Insert", "KP_Delete", "KP_Enter", "KP_Divide", "KP_Equal", "KP_Decimal"
175
-
176
- Returns:
177
- A `list` with a single `ContentImage` of the screen.
178
- """
179
- return await common.press_key(key, timeout=timeout)
180
-
181
- return execute
182
-
183
-
184
- @tool()
185
- def computer_type(timeout: int | None = None) -> Tool:
186
- async def execute(text: str) -> ToolResult:
187
- """
188
- Type a string of text on the keyboard.
189
-
190
- Args:
191
- text: The text to type. If the text contains spaces, enclose it in quotes.
192
-
193
- Returns:
194
- A `list` with a single `ContentImage` of the screen.
195
- """
196
- return await common.type(text, timeout=timeout)
197
-
198
- return execute