inspect-ai 0.3.57__py3-none-any.whl → 0.3.59__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 (161) hide show
  1. inspect_ai/__init__.py +2 -1
  2. inspect_ai/_cli/common.py +7 -3
  3. inspect_ai/_cli/eval.py +17 -2
  4. inspect_ai/_cli/trace.py +21 -2
  5. inspect_ai/_display/core/active.py +4 -3
  6. inspect_ai/_display/core/config.py +3 -3
  7. inspect_ai/_display/core/panel.py +7 -3
  8. inspect_ai/_display/plain/__init__.py +0 -0
  9. inspect_ai/_display/plain/display.py +203 -0
  10. inspect_ai/_display/rich/display.py +4 -9
  11. inspect_ai/_display/textual/app.py +4 -1
  12. inspect_ai/_display/textual/widgets/port_mappings.py +110 -0
  13. inspect_ai/_display/textual/widgets/samples.py +119 -16
  14. inspect_ai/_display/textual/widgets/sandbox.py +37 -0
  15. inspect_ai/_eval/eval.py +32 -20
  16. inspect_ai/_eval/evalset.py +7 -5
  17. inspect_ai/_eval/score.py +1 -0
  18. inspect_ai/_eval/task/__init__.py +2 -2
  19. inspect_ai/_eval/task/images.py +40 -25
  20. inspect_ai/_eval/task/results.py +50 -22
  21. inspect_ai/_eval/task/run.py +180 -124
  22. inspect_ai/_eval/task/sandbox.py +10 -5
  23. inspect_ai/_eval/task/task.py +140 -25
  24. inspect_ai/_util/constants.py +2 -0
  25. inspect_ai/_util/content.py +23 -1
  26. inspect_ai/_util/images.py +20 -17
  27. inspect_ai/_util/kvstore.py +73 -0
  28. inspect_ai/_util/notgiven.py +18 -0
  29. inspect_ai/_util/port_names.py +61 -0
  30. inspect_ai/_util/text.py +23 -0
  31. inspect_ai/_util/thread.py +5 -0
  32. inspect_ai/_view/www/App.css +31 -1
  33. inspect_ai/_view/www/dist/assets/index.css +31 -1
  34. inspect_ai/_view/www/dist/assets/index.js +25375 -1846
  35. inspect_ai/_view/www/log-schema.json +129 -15
  36. inspect_ai/_view/www/package.json +2 -0
  37. inspect_ai/_view/www/src/App.mjs +8 -10
  38. inspect_ai/_view/www/src/Types.mjs +0 -1
  39. inspect_ai/_view/www/src/components/ChatView.mjs +133 -43
  40. inspect_ai/_view/www/src/components/ExpandablePanel.mjs +0 -4
  41. inspect_ai/_view/www/src/components/LargeModal.mjs +19 -20
  42. inspect_ai/_view/www/src/components/MessageBand.mjs +2 -2
  43. inspect_ai/_view/www/src/components/MessageContent.mjs +43 -1
  44. inspect_ai/_view/www/src/components/TabSet.mjs +3 -1
  45. inspect_ai/_view/www/src/components/VirtualList.mjs +266 -84
  46. inspect_ai/_view/www/src/index.js +75 -2
  47. inspect_ai/_view/www/src/navbar/Navbar.mjs +3 -0
  48. inspect_ai/_view/www/src/navbar/SecondaryBar.mjs +18 -9
  49. inspect_ai/_view/www/src/samples/SampleDialog.mjs +5 -1
  50. inspect_ai/_view/www/src/samples/SampleDisplay.mjs +23 -15
  51. inspect_ai/_view/www/src/samples/SampleList.mjs +18 -48
  52. inspect_ai/_view/www/src/samples/SampleTranscript.mjs +8 -3
  53. inspect_ai/_view/www/src/samples/SamplesDescriptor.mjs +29 -13
  54. inspect_ai/_view/www/src/samples/SamplesTab.mjs +4 -1
  55. inspect_ai/_view/www/src/samples/SamplesTools.mjs +8 -8
  56. inspect_ai/_view/www/src/samples/tools/SampleFilter.mjs +712 -89
  57. inspect_ai/_view/www/src/samples/tools/filters.mjs +260 -87
  58. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.mjs +24 -2
  59. inspect_ai/_view/www/src/samples/transcript/EventPanel.mjs +29 -24
  60. inspect_ai/_view/www/src/samples/transcript/EventRow.mjs +1 -1
  61. inspect_ai/_view/www/src/samples/transcript/InfoEventView.mjs +24 -2
  62. inspect_ai/_view/www/src/samples/transcript/InputEventView.mjs +24 -2
  63. inspect_ai/_view/www/src/samples/transcript/ModelEventView.mjs +31 -10
  64. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.mjs +24 -2
  65. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.mjs +23 -2
  66. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.mjs +24 -2
  67. inspect_ai/_view/www/src/samples/transcript/StepEventView.mjs +33 -3
  68. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.mjs +25 -2
  69. inspect_ai/_view/www/src/samples/transcript/ToolEventView.mjs +25 -2
  70. inspect_ai/_view/www/src/samples/transcript/TranscriptView.mjs +193 -11
  71. inspect_ai/_view/www/src/samples/transcript/Types.mjs +10 -0
  72. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.mjs +26 -2
  73. inspect_ai/_view/www/src/types/log.d.ts +62 -27
  74. inspect_ai/_view/www/src/utils/Format.mjs +10 -3
  75. inspect_ai/_view/www/src/utils/Json.mjs +12 -6
  76. inspect_ai/_view/www/src/workspace/WorkSpace.mjs +10 -4
  77. inspect_ai/_view/www/vite.config.js +7 -0
  78. inspect_ai/_view/www/yarn.lock +116 -0
  79. inspect_ai/approval/_human/__init__.py +0 -0
  80. inspect_ai/approval/_human/util.py +2 -2
  81. inspect_ai/approval/_policy.py +12 -6
  82. inspect_ai/dataset/_sources/csv.py +2 -1
  83. inspect_ai/dataset/_sources/json.py +2 -1
  84. inspect_ai/dataset/_sources/util.py +15 -7
  85. inspect_ai/log/_condense.py +11 -1
  86. inspect_ai/log/_log.py +3 -6
  87. inspect_ai/log/_recorders/eval.py +19 -8
  88. inspect_ai/log/_samples.py +26 -5
  89. inspect_ai/log/_transcript.py +32 -2
  90. inspect_ai/model/__init__.py +10 -2
  91. inspect_ai/model/_call_tools.py +59 -12
  92. inspect_ai/model/_chat_message.py +2 -4
  93. inspect_ai/model/_conversation.py +61 -0
  94. inspect_ai/model/_generate_config.py +10 -4
  95. inspect_ai/model/_model.py +117 -18
  96. inspect_ai/model/_model_output.py +7 -2
  97. inspect_ai/model/_providers/anthropic.py +109 -51
  98. inspect_ai/model/_providers/azureai.py +26 -24
  99. inspect_ai/model/_providers/bedrock.py +43 -44
  100. inspect_ai/model/_providers/google.py +121 -58
  101. inspect_ai/model/_providers/groq.py +7 -5
  102. inspect_ai/model/_providers/hf.py +11 -6
  103. inspect_ai/model/_providers/mistral.py +17 -20
  104. inspect_ai/model/_providers/openai.py +32 -21
  105. inspect_ai/model/_providers/openai_o1.py +9 -8
  106. inspect_ai/model/_providers/providers.py +1 -1
  107. inspect_ai/model/_providers/together.py +8 -8
  108. inspect_ai/model/_providers/vertex.py +18 -8
  109. inspect_ai/scorer/__init__.py +13 -2
  110. inspect_ai/scorer/_metrics/__init__.py +2 -2
  111. inspect_ai/scorer/_metrics/std.py +3 -3
  112. inspect_ai/scorer/_reducer/reducer.py +1 -1
  113. inspect_ai/scorer/_scorer.py +2 -2
  114. inspect_ai/solver/__init__.py +2 -5
  115. inspect_ai/solver/_prompt.py +35 -5
  116. inspect_ai/solver/_task_state.py +80 -38
  117. inspect_ai/tool/__init__.py +11 -1
  118. inspect_ai/tool/_tool.py +21 -3
  119. inspect_ai/tool/_tool_call.py +10 -0
  120. inspect_ai/tool/_tool_def.py +16 -5
  121. inspect_ai/tool/_tool_with.py +21 -4
  122. inspect_ai/tool/beta/__init__.py +5 -0
  123. inspect_ai/tool/beta/_computer/__init__.py +3 -0
  124. inspect_ai/tool/beta/_computer/_common.py +133 -0
  125. inspect_ai/tool/beta/_computer/_computer.py +155 -0
  126. inspect_ai/tool/beta/_computer/_computer_split.py +198 -0
  127. inspect_ai/tool/beta/_computer/_resources/Dockerfile +100 -0
  128. inspect_ai/tool/beta/_computer/_resources/README.md +30 -0
  129. inspect_ai/tool/beta/_computer/_resources/entrypoint/entrypoint.sh +18 -0
  130. inspect_ai/tool/beta/_computer/_resources/entrypoint/novnc_startup.sh +20 -0
  131. inspect_ai/tool/beta/_computer/_resources/entrypoint/x11vnc_startup.sh +48 -0
  132. inspect_ai/tool/beta/_computer/_resources/entrypoint/xfce_startup.sh +13 -0
  133. inspect_ai/tool/beta/_computer/_resources/entrypoint/xvfb_startup.sh +48 -0
  134. inspect_ai/tool/beta/_computer/_resources/image_home_dir/Desktop/Firefox Web Browser.desktop +10 -0
  135. inspect_ai/tool/beta/_computer/_resources/image_home_dir/Desktop/Visual Studio Code.desktop +10 -0
  136. inspect_ai/tool/beta/_computer/_resources/image_home_dir/Desktop/XPaint.desktop +10 -0
  137. inspect_ai/tool/beta/_computer/_resources/tool/__init__.py +0 -0
  138. inspect_ai/tool/beta/_computer/_resources/tool/_logger.py +22 -0
  139. inspect_ai/tool/beta/_computer/_resources/tool/_run.py +42 -0
  140. inspect_ai/tool/beta/_computer/_resources/tool/_tool_result.py +33 -0
  141. inspect_ai/tool/beta/_computer/_resources/tool/_x11_client.py +262 -0
  142. inspect_ai/tool/beta/_computer/_resources/tool/computer_tool.py +85 -0
  143. inspect_ai/tool/beta/_computer/_resources/tool/requirements.txt +0 -0
  144. inspect_ai/util/__init__.py +2 -3
  145. inspect_ai/util/{_trace.py → _conversation.py} +3 -17
  146. inspect_ai/util/_display.py +14 -4
  147. inspect_ai/util/_limit.py +26 -0
  148. inspect_ai/util/_sandbox/context.py +12 -13
  149. inspect_ai/util/_sandbox/docker/compose.py +24 -11
  150. inspect_ai/util/_sandbox/docker/docker.py +84 -14
  151. inspect_ai/util/_sandbox/docker/internal.py +3 -1
  152. inspect_ai/util/_sandbox/environment.py +27 -1
  153. inspect_ai/util/_sandbox/local.py +1 -0
  154. {inspect_ai-0.3.57.dist-info → inspect_ai-0.3.59.dist-info}/METADATA +2 -2
  155. {inspect_ai-0.3.57.dist-info → inspect_ai-0.3.59.dist-info}/RECORD +159 -128
  156. inspect_ai/_view/www/src/samples/transcript/TranscriptState.mjs +0 -70
  157. inspect_ai/model/_trace.py +0 -48
  158. {inspect_ai-0.3.57.dist-info → inspect_ai-0.3.59.dist-info}/LICENSE +0 -0
  159. {inspect_ai-0.3.57.dist-info → inspect_ai-0.3.59.dist-info}/WHEEL +0 -0
  160. {inspect_ai-0.3.57.dist-info → inspect_ai-0.3.59.dist-info}/entry_points.txt +0 -0
  161. {inspect_ai-0.3.57.dist-info → inspect_ai-0.3.59.dist-info}/top_level.txt +0 -0
@@ -25,5 +25,27 @@ class ContentImage(BaseModel):
25
25
  """
26
26
 
27
27
 
28
- Content = Union[ContentText, ContentImage]
28
+ class ContentAudio(BaseModel):
29
+ type: Literal["audio"] = Field(default="audio")
30
+ """Type."""
31
+
32
+ audio: str
33
+ """Audio file path or base64 encoded data URL."""
34
+
35
+ format: Literal["wav", "mp3"]
36
+ """Format of audio data ('mp3' or 'wav')"""
37
+
38
+
39
+ class ContentVideo(BaseModel):
40
+ type: Literal["video"] = Field(default="video")
41
+ """Type."""
42
+
43
+ video: str
44
+ """Audio file path or base64 encoded data URL."""
45
+
46
+ format: Literal["mp4", "mpeg", "mov"]
47
+ """Format of video data ('mp4', 'mpeg', or 'mov')"""
48
+
49
+
50
+ Content = Union[ContentText, ContentImage, ContentAudio, ContentVideo]
29
51
  """Content sent to or received from a model."""
@@ -3,7 +3,7 @@ import mimetypes
3
3
 
4
4
  import httpx
5
5
 
6
- from .file import file
6
+ from .file import file as open_file
7
7
  from .url import (
8
8
  data_uri_mime_type,
9
9
  data_uri_to_base64,
@@ -12,34 +12,37 @@ from .url import (
12
12
  )
13
13
 
14
14
 
15
- async def image_as_data(image: str) -> tuple[bytes, str]:
16
- if is_data_uri(image):
15
+ async def file_as_data(file: str) -> tuple[bytes, str]:
16
+ if is_data_uri(file):
17
17
  # resolve mime type and base64 content
18
- mime_type = data_uri_mime_type(image) or "image/png"
19
- image_base64 = data_uri_to_base64(image)
20
- image_bytes = base64.b64decode(image_base64)
18
+ mime_type = data_uri_mime_type(file) or "image/png"
19
+ file_base64 = data_uri_to_base64(file)
20
+ file_bytes = base64.b64decode(file_base64)
21
21
  else:
22
22
  # guess mime type; need strict=False for webp images
23
- type, _ = mimetypes.guess_type(image, strict=False)
23
+ type, _ = mimetypes.guess_type(file, strict=False)
24
24
  if type:
25
25
  mime_type = type
26
26
  else:
27
27
  mime_type = "image/png"
28
28
 
29
29
  # handle url or file
30
- if is_http_url(image):
30
+ if is_http_url(file):
31
31
  client = httpx.AsyncClient()
32
- image_bytes = (await client.get(image)).content
32
+ file_bytes = (await client.get(file)).content
33
33
  else:
34
- with file(image, "rb") as f:
35
- image_bytes = f.read()
34
+ with open_file(file, "rb") as f:
35
+ file_bytes = f.read()
36
36
 
37
37
  # return bytes and type
38
- return image_bytes, mime_type
38
+ return file_bytes, mime_type
39
39
 
40
40
 
41
- async def image_as_data_uri(image: str) -> str:
42
- bytes, mime_type = await image_as_data(image)
43
- base64_image = base64.b64encode(bytes).decode("utf-8")
44
- image = f"data:{mime_type};base64,{base64_image}"
45
- return image
41
+ async def file_as_data_uri(file: str) -> str:
42
+ if is_data_uri(file):
43
+ return file
44
+ else:
45
+ bytes, mime_type = await file_as_data(file)
46
+ base64_file = base64.b64encode(bytes).decode("utf-8")
47
+ file = f"data:{mime_type};base64,{base64_file}"
48
+ return file
@@ -0,0 +1,73 @@
1
+ import sqlite3
2
+ from contextlib import AbstractContextManager
3
+ from typing import Any, Optional, cast
4
+
5
+ from .appdirs import inspect_data_dir
6
+
7
+
8
+ class KVStore(AbstractContextManager["KVStore"]):
9
+ def __init__(self, filename: str, max_entries: int | None = None):
10
+ self.filename = filename
11
+ self.max_entries = max_entries
12
+
13
+ def __enter__(self) -> "KVStore":
14
+ self.conn = sqlite3.connect(self.filename)
15
+ self.conn.execute("""
16
+ CREATE TABLE IF NOT EXISTS kv_store (
17
+ key TEXT PRIMARY KEY,
18
+ value TEXT,
19
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
20
+ )
21
+ """)
22
+ self.conn.commit()
23
+ return self
24
+
25
+ def __exit__(self, *excinfo: Any) -> None:
26
+ self.conn.close()
27
+
28
+ def put(self, key: str, value: str) -> None:
29
+ # Insert or update the value
30
+ self.conn.execute(
31
+ """
32
+ INSERT OR REPLACE INTO kv_store (key, value, created_at)
33
+ VALUES (?, ?, CURRENT_TIMESTAMP)
34
+ """,
35
+ (key, value),
36
+ )
37
+
38
+ # If we have a max_entries limit, remove oldest entries
39
+ if self.max_entries:
40
+ count = self.count()
41
+ if count > self.max_entries:
42
+ self.conn.execute(
43
+ """
44
+ DELETE FROM kv_store
45
+ WHERE key IN (
46
+ SELECT key FROM kv_store
47
+ ORDER BY created_at ASC
48
+ LIMIT ?
49
+ )
50
+ """,
51
+ (max(0, count - self.max_entries),),
52
+ )
53
+
54
+ self.conn.commit()
55
+
56
+ def get(self, key: str) -> Optional[str]:
57
+ cursor = self.conn.execute("SELECT value FROM kv_store WHERE key = ?", (key,))
58
+ result = cursor.fetchone()
59
+ return result[0] if result else None
60
+
61
+ def delete(self, key: str) -> bool:
62
+ cursor = self.conn.execute("DELETE FROM kv_store WHERE key = ?", (key,))
63
+ self.conn.commit()
64
+ return cursor.rowcount > 0
65
+
66
+ def count(self) -> int:
67
+ cursor = self.conn.execute("SELECT COUNT(*) FROM kv_store")
68
+ return cast(int, cursor.fetchone()[0])
69
+
70
+
71
+ def inspect_kvstore(name: str, max_entries: int | None = None) -> KVStore:
72
+ filename = inspect_data_dir("kvstore") / f"{name}.db"
73
+ return KVStore(filename.as_posix(), max_entries=max_entries)
@@ -0,0 +1,18 @@
1
+ # Sentinel class used until PEP 0661 is accepted
2
+ from typing import Literal
3
+
4
+ from typing_extensions import override
5
+
6
+
7
+ class NotGiven:
8
+ """A sentinel singleton class used to distinguish omitted keyword arguments from those passed in with the value None (which may have different behavior)."""
9
+
10
+ def __bool__(self) -> Literal[False]:
11
+ return False
12
+
13
+ @override
14
+ def __repr__(self) -> str:
15
+ return "NOT_GIVEN"
16
+
17
+
18
+ NOT_GIVEN = NotGiven()
@@ -0,0 +1,61 @@
1
+ from typing import Literal
2
+
3
+
4
+ def get_service_by_port(port: int, protocol: Literal["tcp", "udp"]) -> str | None:
5
+ """
6
+ Returns the likely service running on a given port number.
7
+
8
+ Args:
9
+ port (int): The port number to look up
10
+ protocol (str): Either 'tcp' or 'udp'
11
+
12
+ Returns:
13
+ str: Description of the likely service, or None if not found
14
+ """
15
+ # Common port mappings based on IANA assignments and common usage
16
+ port_mappings = {
17
+ "tcp": {
18
+ 20: "FTP (Data)",
19
+ 21: "FTP (Control)",
20
+ 22: "SSH",
21
+ 23: "Telnet",
22
+ 25: "SMTP",
23
+ 53: "DNS",
24
+ 80: "HTTP",
25
+ 110: "POP3",
26
+ 143: "IMAP",
27
+ 443: "HTTPS",
28
+ 445: "Microsoft-DS (SMB)",
29
+ 587: "SMTP (Submission)",
30
+ 993: "IMAPS",
31
+ 995: "POP3S",
32
+ 1433: "Microsoft SQL Server",
33
+ 1521: "Oracle Database",
34
+ 3306: "MySQL",
35
+ 3389: "RDP (Remote Desktop)",
36
+ 5432: "PostgreSQL",
37
+ 5900: "VNC",
38
+ 5901: "VNC Display :1",
39
+ 5902: "VNC Display :2",
40
+ 6080: "noVNC",
41
+ 8080: "HTTP Alternate",
42
+ 8443: "HTTPS Alternate",
43
+ 27017: "MongoDB",
44
+ 27018: "MongoDB Shard",
45
+ 27019: "MongoDB Config Server",
46
+ },
47
+ "udp": {
48
+ 53: "DNS",
49
+ 67: "DHCP Server",
50
+ 68: "DHCP Client",
51
+ 69: "TFTP",
52
+ 123: "NTP",
53
+ 161: "SNMP",
54
+ 162: "SNMP Trap",
55
+ 514: "Syslog",
56
+ 1194: "OpenVPN",
57
+ 5353: "mDNS",
58
+ },
59
+ }
60
+
61
+ return port_mappings.get(protocol, {}).get(port, None)
inspect_ai/_util/text.py CHANGED
@@ -108,3 +108,26 @@ def str_to_float(s: str) -> float:
108
108
  exponent = 1 # Default exponent is 1 if no superscript is present
109
109
 
110
110
  return base**exponent
111
+
112
+
113
+ def truncate(text: str, length: int, overflow: str = "...", pad: bool = True) -> str:
114
+ """
115
+ Truncate text to specified length with optional padding and overflow indicator.
116
+
117
+ Args:
118
+ text (str): Text to truncate
119
+ length (int): Maximum length including overflow indicator
120
+ overflow (str): String to indicate truncation (defaults to '...')
121
+ pad (bool): Whether to pad the result to full length (defaults to padding)
122
+
123
+ Returns:
124
+ Truncated string, padded if requested
125
+
126
+ """
127
+ if len(text) <= length:
128
+ return text + (" " * (length - len(text))) if pad else text
129
+
130
+ overflow_length = len(overflow)
131
+ truncated = text[: length - overflow_length] + overflow
132
+
133
+ return truncated
@@ -0,0 +1,5 @@
1
+ import threading
2
+
3
+
4
+ def is_main_thread() -> bool:
5
+ return threading.current_thread() is threading.main_thread()
@@ -9,6 +9,12 @@
9
9
  --inspect-input-border: var(--bs-light-border-subtle);
10
10
  --inspect-diff-add-color: #dafbe1;
11
11
  --inspect-diff-remove-color: #ffebe9;
12
+ --inspect-inactive-selection-background: var(--vscode-editor-inactiveSelectionBackground, #d9d9d9);
13
+ --inspect-active-selection-background: var(--vscode-editor-selectionBackground, #d7d4f0);
14
+ --inspect-focus-border-color: #86b7fe;
15
+ --inspect-focus-border-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
16
+ --inspect-focus-border-gray-color: #808080;
17
+ --inspect-focus-border-gray-shadow: 0 0 0 0.25rem rgba(48, 48, 48, 0.25);
12
18
  }
13
19
 
14
20
  body:not([class^="vscode-"]) button {
@@ -650,6 +656,30 @@ table.table.table-sm td {
650
656
  height: auto !important;
651
657
  }
652
658
 
659
+ [data-tooltip] {
660
+ position: relative;
661
+ }
662
+ [data-tooltip]:hover::after {
663
+ content: attr(data-tooltip);
664
+ position: absolute;
665
+ line-height: 1.25;
666
+ background: var(--bs-light);
667
+ color: var(--bs-body-color);
668
+ opacity: 1;
669
+ padding: 4px 8px;
670
+ border-radius: 4px;
671
+ border: 1px solid var(--bs-border-color);
672
+ box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.25);
673
+ white-space: pre-wrap;
674
+ width: max-content;
675
+ max-width: 400px;
676
+ z-index: 1000;
677
+ }
678
+ [data-tooltip][data-tooltip-position="bottom-left"]:hover::after {
679
+ right: 0%;
680
+ top: 100%;
681
+ }
682
+
653
683
  /* ANSI Coloring */
654
684
  .ansi-display {
655
685
  font-family: monospace;
@@ -725,7 +755,7 @@ pre[class*="language-"].tool-output {
725
755
  background: none !important;
726
756
  border: none !important;
727
757
  box-shadow: none !important;
728
- border-radius: var(--bs-border-radius) !important;
758
+ border-radius: var(--bs-border-radius) !important;
729
759
  }
730
760
 
731
761
  /* lightbox styles */
@@ -14282,6 +14282,12 @@ pre[class*="language-"] {
14282
14282
  --inspect-input-border: var(--bs-light-border-subtle);
14283
14283
  --inspect-diff-add-color: #dafbe1;
14284
14284
  --inspect-diff-remove-color: #ffebe9;
14285
+ --inspect-inactive-selection-background: var(--vscode-editor-inactiveSelectionBackground, #d9d9d9);
14286
+ --inspect-active-selection-background: var(--vscode-editor-selectionBackground, #d7d4f0);
14287
+ --inspect-focus-border-color: #86b7fe;
14288
+ --inspect-focus-border-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
14289
+ --inspect-focus-border-gray-color: #808080;
14290
+ --inspect-focus-border-gray-shadow: 0 0 0 0.25rem rgba(48, 48, 48, 0.25);
14285
14291
  }
14286
14292
 
14287
14293
  body:not([class^="vscode-"]) button {
@@ -14923,6 +14929,30 @@ table.table.table-sm td {
14923
14929
  height: auto !important;
14924
14930
  }
14925
14931
 
14932
+ [data-tooltip] {
14933
+ position: relative;
14934
+ }
14935
+ [data-tooltip]:hover::after {
14936
+ content: attr(data-tooltip);
14937
+ position: absolute;
14938
+ line-height: 1.25;
14939
+ background: var(--bs-light);
14940
+ color: var(--bs-body-color);
14941
+ opacity: 1;
14942
+ padding: 4px 8px;
14943
+ border-radius: 4px;
14944
+ border: 1px solid var(--bs-border-color);
14945
+ box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.25);
14946
+ white-space: pre-wrap;
14947
+ width: max-content;
14948
+ max-width: 400px;
14949
+ z-index: 1000;
14950
+ }
14951
+ [data-tooltip][data-tooltip-position="bottom-left"]:hover::after {
14952
+ right: 0%;
14953
+ top: 100%;
14954
+ }
14955
+
14926
14956
  /* ANSI Coloring */
14927
14957
  .ansi-display {
14928
14958
  font-family: monospace;
@@ -14998,7 +15028,7 @@ pre[class*="language-"].tool-output {
14998
15028
  background: none !important;
14999
15029
  border: none !important;
15000
15030
  box-shadow: none !important;
15001
- border-radius: var(--bs-border-radius) !important;
15031
+ border-radius: var(--bs-border-radius) !important;
15002
15032
  }
15003
15033
 
15004
15034
  /* lightbox styles */