inspect-ai 0.3.76__py3-none-any.whl → 0.3.78__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.
@@ -0,0 +1,177 @@
1
+ from logging import getLogger
2
+ from typing import Any
3
+
4
+ from openai import (
5
+ AsyncAzureOpenAI,
6
+ AsyncOpenAI,
7
+ BadRequestError,
8
+ )
9
+ from openai._types import NOT_GIVEN
10
+ from openai.types.responses import Response, ResponseFormatTextJSONSchemaConfigParam
11
+
12
+ from inspect_ai._util.logger import warn_once
13
+ from inspect_ai.tool import ToolChoice, ToolInfo
14
+
15
+ from .._chat_message import ChatMessage
16
+ from .._generate_config import GenerateConfig
17
+ from .._model_call import ModelCall
18
+ from .._model_output import (
19
+ ModelOutput,
20
+ ModelUsage,
21
+ )
22
+ from .._openai import (
23
+ OpenAIResponseError,
24
+ is_gpt,
25
+ is_o1_mini,
26
+ is_o1_preview,
27
+ is_o_series,
28
+ openai_handle_bad_request,
29
+ openai_media_filter,
30
+ )
31
+ from .._openai_responses import (
32
+ openai_responses_chat_choices,
33
+ openai_responses_inputs,
34
+ openai_responses_tool_choice,
35
+ openai_responses_tools,
36
+ )
37
+ from .util.hooks import HttpxHooks
38
+
39
+ logger = getLogger(__name__)
40
+
41
+
42
+ async def generate_responses(
43
+ client: AsyncAzureOpenAI | AsyncOpenAI,
44
+ http_hooks: HttpxHooks,
45
+ model_name: str,
46
+ input: list[ChatMessage],
47
+ tools: list[ToolInfo],
48
+ tool_choice: ToolChoice,
49
+ config: GenerateConfig,
50
+ ) -> ModelOutput | tuple[ModelOutput | Exception, ModelCall]:
51
+ # allocate request_id (so we can see it from ModelCall)
52
+ request_id = http_hooks.start_request()
53
+
54
+ # setup request and response for ModelCall
55
+ request: dict[str, Any] = {}
56
+ response: dict[str, Any] = {}
57
+
58
+ def model_call() -> ModelCall:
59
+ return ModelCall.create(
60
+ request=request,
61
+ response=response,
62
+ # TODO: is this the right filter?
63
+ filter=openai_media_filter,
64
+ time=http_hooks.end_request(request_id),
65
+ )
66
+
67
+ # prepare request (we do this so we can log the ModelCall)
68
+ request = dict(
69
+ input=await openai_responses_inputs(input, model_name),
70
+ tools=openai_responses_tools(tools) if len(tools) > 0 else NOT_GIVEN,
71
+ tool_choice=openai_responses_tool_choice(tool_choice)
72
+ if len(tools) > 0
73
+ else NOT_GIVEN,
74
+ extra_headers={HttpxHooks.REQUEST_ID_HEADER: request_id},
75
+ **completion_params_responses(model_name, config, len(tools) > 0),
76
+ )
77
+
78
+ try:
79
+ # generate response
80
+ model_response: Response = await client.responses.create(**request)
81
+
82
+ # check for error
83
+ if model_response.error is not None:
84
+ raise OpenAIResponseError(
85
+ code=model_response.error.code, message=model_response.error.message
86
+ )
87
+
88
+ # save response for model_call
89
+ response = model_response.model_dump()
90
+
91
+ # parse out choices
92
+ choices = openai_responses_chat_choices(model_response, tools)
93
+
94
+ # return output and call
95
+ return ModelOutput(
96
+ model=model_response.model,
97
+ choices=choices,
98
+ usage=(
99
+ ModelUsage(
100
+ input_tokens=model_response.usage.input_tokens,
101
+ output_tokens=model_response.usage.output_tokens,
102
+ input_tokens_cache_read=(
103
+ model_response.usage.input_tokens_details.cached_tokens
104
+ ),
105
+ reasoning_tokens=model_response.usage.output_tokens_details.reasoning_tokens,
106
+ total_tokens=model_response.usage.total_tokens,
107
+ )
108
+ if model_response.usage
109
+ else None
110
+ ),
111
+ ), model_call()
112
+ except BadRequestError as e:
113
+ return openai_handle_bad_request(model_name, e), model_call()
114
+
115
+
116
+ def completion_params_responses(
117
+ model_name: str, config: GenerateConfig, tools: bool
118
+ ) -> dict[str, Any]:
119
+ # TODO: we'll need a computer_use_preview bool for the 'include'
120
+ # and 'reasoning' parameters
121
+ def unsupported_warning(param: str) -> None:
122
+ warn_once(
123
+ logger,
124
+ f"OpenAI Responses API does not support the '{param}' parameter.",
125
+ )
126
+
127
+ params: dict[str, Any] = dict(model=model_name, store=False)
128
+ if config.max_tokens is not None:
129
+ params["max_output_tokens"] = config.max_tokens
130
+ if config.frequency_penalty is not None:
131
+ unsupported_warning("frequency_penalty")
132
+ if config.stop_seqs is not None:
133
+ unsupported_warning("stop_seqs")
134
+ if config.presence_penalty is not None:
135
+ unsupported_warning("presence_penalty")
136
+ if config.logit_bias is not None:
137
+ unsupported_warning("logit_bias")
138
+ if config.seed is not None:
139
+ unsupported_warning("seed")
140
+ if config.temperature is not None:
141
+ if is_o_series(model_name):
142
+ warn_once(
143
+ logger,
144
+ "o series models do not support the 'temperature' parameter (temperature is always 1).",
145
+ )
146
+ else:
147
+ params["temperature"] = config.temperature
148
+ if config.top_p is not None:
149
+ params["top_p"] = config.top_p
150
+ if config.num_choices is not None:
151
+ unsupported_warning("num_choices")
152
+ if config.logprobs is not None:
153
+ unsupported_warning("logprobs")
154
+ if config.top_logprobs is not None:
155
+ unsupported_warning("top_logprobs")
156
+ if tools and config.parallel_tool_calls is not None and not is_o_series(model_name):
157
+ params["parallel_tool_calls"] = config.parallel_tool_calls
158
+ if (
159
+ config.reasoning_effort is not None
160
+ and not is_gpt(model_name)
161
+ and not is_o1_mini(model_name)
162
+ and not is_o1_preview(model_name)
163
+ ):
164
+ params["reasoning"] = dict(effort=config.reasoning_effort)
165
+ if config.response_schema is not None:
166
+ params["text"] = dict(
167
+ format=ResponseFormatTextJSONSchemaConfigParam(
168
+ type="json_schema",
169
+ name=config.response_schema.name,
170
+ schema=config.response_schema.json_schema.model_dump(exclude_none=True),
171
+ description=config.response_schema.description
172
+ or config.response_schema.name,
173
+ strict=config.response_schema.strict,
174
+ )
175
+ )
176
+
177
+ return params
@@ -1,9 +1,11 @@
1
+ import json
1
2
  import os
2
- from typing import Any
3
+ from typing import Any, TypedDict
3
4
 
4
- from typing_extensions import override
5
+ from typing_extensions import NotRequired, override
5
6
 
6
7
  from inspect_ai._util.error import PrerequisiteError
8
+ from inspect_ai.model._openai import OpenAIResponseError
7
9
  from inspect_ai.model._providers.util import model_base_url
8
10
  from inspect_ai.model._providers.util.util import environment_prerequisite_error
9
11
 
@@ -13,6 +15,28 @@ from .openai import OpenAIAPI
13
15
  OPENROUTER_API_KEY = "OPENROUTER_API_KEY"
14
16
 
15
17
 
18
+ class ErrorResponse(TypedDict):
19
+ code: int
20
+ message: str
21
+ metadata: NotRequired[dict[str, Any]]
22
+
23
+
24
+ class OpenRouterError(Exception):
25
+ def __init__(self, response: ErrorResponse) -> None:
26
+ self.response = response
27
+
28
+ @property
29
+ def message(self) -> str:
30
+ return f"Error {self.response['code']} - {self.response['message']}"
31
+
32
+ def __str__(self) -> str:
33
+ return (
34
+ self.message + ("\n" + json.dumps(self.response["metadata"], indent=2))
35
+ if "metadata" in self.response
36
+ else ""
37
+ )
38
+
39
+
16
40
  class OpenRouterAPI(OpenAIAPI):
17
41
  def __init__(
18
42
  self,
@@ -67,6 +91,32 @@ class OpenRouterAPI(OpenAIAPI):
67
91
  **model_args,
68
92
  )
69
93
 
94
+ @override
95
+ def on_response(self, response: dict[str, Any]) -> None:
96
+ """Handle documented OpenRouter error conditions.
97
+
98
+ https://openrouter.ai/docs/api-reference/errors
99
+ """
100
+ # check if open-router yielded an error (raise explicit
101
+ # OpenAIResponseError for cases where we should retry)
102
+ error: ErrorResponse | None = response.get("error", None)
103
+ if error is not None:
104
+ if error["code"] == 429:
105
+ raise OpenAIResponseError("rate_limit_exceeded", error["message"])
106
+ elif error["code"] in [408, 502]:
107
+ raise OpenAIResponseError("server_error", error["message"])
108
+ else:
109
+ raise OpenRouterError(error)
110
+
111
+ # check for an empty response (which they document can occur on
112
+ # startup). for this we'll return a "server_error" which will
113
+ # trigger a retry w/ exponential backoff
114
+ elif response.get("choices", None) is None:
115
+ raise OpenAIResponseError(
116
+ "server_error",
117
+ "Model is warming up, please retry again after waiting for warmup.",
118
+ )
119
+
70
120
  @override
71
121
  def completion_params(self, config: GenerateConfig, tools: bool) -> dict[str, Any]:
72
122
  # default params
@@ -282,7 +282,7 @@ def goodfire() -> type[ModelAPI]:
282
282
  def validate_openai_client(feature: str) -> None:
283
283
  FEATURE = feature
284
284
  PACKAGE = "openai"
285
- MIN_VERSION = "1.58.1"
285
+ MIN_VERSION = "1.68.0"
286
286
 
287
287
  # verify we have the package
288
288
  try:
@@ -26,6 +26,7 @@ from ._tools._bash_session import bash_session
26
26
  from ._tools._computer import computer
27
27
  from ._tools._execute import bash, python
28
28
  from ._tools._text_editor import text_editor
29
+ from ._tools._think import think
29
30
  from ._tools._web_browser import web_browser
30
31
  from ._tools._web_search import web_search
31
32
 
@@ -36,6 +37,7 @@ __all__ = [
36
37
  "python",
37
38
  "web_browser",
38
39
  "web_search",
40
+ "think",
39
41
  "text_editor",
40
42
  "tool",
41
43
  "tool_with",
inspect_ai/tool/_tool.py CHANGED
@@ -20,6 +20,7 @@ from inspect_ai._util.content import (
20
20
  )
21
21
  from inspect_ai._util.registry import (
22
22
  RegistryInfo,
23
+ is_registry_object,
23
24
  registry_add,
24
25
  registry_name,
25
26
  registry_tag,
@@ -200,7 +201,25 @@ def tool(
200
201
  # wrap instantiations of scorer so they carry registry info and metrics
201
202
  @wraps(tool_type)
202
203
  def tool_wrapper(*args: P.args, **kwargs: P.kwargs) -> Tool:
204
+ # create the tool
203
205
  tool = tool_type(*args, **kwargs)
206
+
207
+ # this might already have registry info, in that case
208
+ # capture it and use it as defaults
209
+ from inspect_ai.tool._tool_def import tool_registry_info
210
+
211
+ tool_parallel = parallel
212
+ tool_viewer = viewer
213
+ tool_model_input = model_input
214
+ if is_registry_object(tool):
215
+ _, _, reg_parallel, reg_viewer, reg_model_input = tool_registry_info(
216
+ tool
217
+ )
218
+ tool_parallel = parallel and reg_parallel
219
+ tool_viewer = viewer or reg_viewer
220
+ tool_model_input = model_input or reg_model_input
221
+
222
+ # tag the object
204
223
  registry_tag(
205
224
  tool_type,
206
225
  tool,
@@ -209,10 +228,11 @@ def tool(
209
228
  name=tool_name,
210
229
  metadata={
211
230
  TOOL_PROMPT: prompt,
212
- TOOL_PARALLEL: parallel,
213
- TOOL_VIEWER: viewer,
231
+ TOOL_PARALLEL: tool_parallel,
232
+ TOOL_VIEWER: tool_viewer,
214
233
  TOOL_MODEL_INPUT: (
215
- model_input or getattr(tool, TOOL_INIT_MODEL_INPUT, None)
234
+ tool_model_input
235
+ or getattr(tool, TOOL_INIT_MODEL_INPUT, None)
216
236
  ),
217
237
  },
218
238
  ),
@@ -0,0 +1,48 @@
1
+ from .._tool import Tool, tool
2
+ from .._tool_call import ToolCall, ToolCallContent, ToolCallView, ToolCallViewer
3
+ from .._tool_def import ToolDef
4
+
5
+
6
+ @tool
7
+ def think(
8
+ description: str | None = None,
9
+ thought_description: str | None = None,
10
+ ) -> Tool:
11
+ """Think tool for extra thinking.
12
+
13
+ Tool that provides models with the ability to include an additional thinking step as part of getting to its final answer.
14
+
15
+ Note that the `think()` tool is not a substitute for reasoning and extended thinking, but rather an an alternate way of letting models express thinking that is better suited to some tool use scenarios. Please see the documentation on using the [think tool](https://inspect.aisi.org.uk/tools-standard.html#sec-think) before using it in your evaluations.
16
+
17
+ Args:
18
+ description: Override the default description of the think tool.
19
+ thought_description: Override the default description of the thought parameter.
20
+ """
21
+
22
+ async def execute(thought: str) -> str:
23
+ """Use the tool to think about something.
24
+
25
+ The will not obtain new information or change the environment, but just append the thought to the log. Use it when complex reasoning or some cache memory is needed."
26
+
27
+ Args:
28
+ thought: A thought to think about.
29
+ """
30
+ return ""
31
+
32
+ return ToolDef(
33
+ execute,
34
+ name="think",
35
+ description=description,
36
+ parameters=(dict(thought=thought_description) if thought_description else None),
37
+ viewer=think_tool_viewer(),
38
+ ).as_tool()
39
+
40
+
41
+ def think_tool_viewer() -> ToolCallViewer:
42
+ def viewer(tool_call: ToolCall) -> ToolCallView:
43
+ call = ToolCallContent(
44
+ format="markdown", content=tool_call.arguments["thought"]
45
+ )
46
+ return ToolCallView(call=call)
47
+
48
+ return viewer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inspect_ai
3
- Version: 0.3.76
3
+ Version: 0.3.78
4
4
  Summary: Framework for large language model evaluations
5
5
  Author: UK AI Security Institute
6
6
  License: MIT License
@@ -3,7 +3,7 @@ inspect_ai/__main__.py,sha256=oWX4YwDZDg3GS3-IG0yPGoSEOfSzWihELg7QmrUlxjM,67
3
3
  inspect_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  inspect_ai/_cli/cache.py,sha256=RVGuBYwwk3c45JfyfcSFJ419etSsv3-Z7AyfQE-Hul0,3912
5
5
  inspect_ai/_cli/common.py,sha256=v4ZRvj4fJSbCq61IbZukb-iR_ZGawrmYH4n8JP_piVg,3676
6
- inspect_ai/_cli/eval.py,sha256=Jv506NwbcgsU8D-JbeNFsvYSZc779zq1ljJq4sB-9BA,34732
6
+ inspect_ai/_cli/eval.py,sha256=76igFkS-c3uX8pPUcHWwSFlyF4ji_STZh6Ses8XHvlo,35233
7
7
  inspect_ai/_cli/info.py,sha256=QMxaTG9TmzW95EiLrOgkzubvavoR-VHxo3eV7ppmrzI,1789
8
8
  inspect_ai/_cli/list.py,sha256=M8mazI8Zuq8Hp99YWKnxQd9UWx1Qi87zfXRzZYAAakk,2459
9
9
  inspect_ai/_cli/log.py,sha256=O-w7GqsE7tLojPnEtpWXPSh0Vu2Hbrbxjneyc1BFfpk,5817
@@ -21,7 +21,7 @@ inspect_ai/_display/core/footer.py,sha256=_EI6yhv0TErl2Xku-mJBBSJXjiFnUJyvAp_TJR
21
21
  inspect_ai/_display/core/group.py,sha256=z8CIwQ-8Mm9adQ8JDuMjw94ih9GfymU5s-1qnbKoEPs,2871
22
22
  inspect_ai/_display/core/panel.py,sha256=gyGYnsqHurUkUC51MyVuh3oGAtUEaFtyRwewOB6pDts,3828
23
23
  inspect_ai/_display/core/progress.py,sha256=2dIRbpJGUx-Wz89ZABoACBGvJEGWJ3SDrFsuCrrpL7w,4198
24
- inspect_ai/_display/core/results.py,sha256=aFLmG1Ij0fxYk2848QgQlesfMeRdHVEg_W9esmeL_S0,7355
24
+ inspect_ai/_display/core/results.py,sha256=zWzHZsZAdkcBTB0ZFRPvkFFjiHP9ekkRcKLJl8qh4Uw,7548
25
25
  inspect_ai/_display/core/rich.py,sha256=GPzc-0PWZVOPWxnjfQmNSK66uZXc3x8joz4ethgv_4M,2729
26
26
  inspect_ai/_display/core/textual.py,sha256=kzMTt8ijrodwhDB5V50pP2IBhnUCusVbP86TytU_rA8,870
27
27
  inspect_ai/_display/plain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -45,12 +45,12 @@ inspect_ai/_display/textual/widgets/toggle.py,sha256=ToYs-S4n90yuxWcAW2OTg6AbRf0
45
45
  inspect_ai/_display/textual/widgets/transcript.py,sha256=zaxlDixT6Fie0acAWBM9Hltnk3Qf7G2awHGhK3vC4Nk,11752
46
46
  inspect_ai/_eval/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
47
  inspect_ai/_eval/context.py,sha256=gWTjEEMVTJMJpCCKLRs4joZDkG00rzE7-HXZFyzSC_I,1283
48
- inspect_ai/_eval/eval.py,sha256=lmDIfrfx9hmlIOSYEUkH6QzpX1dDV6JUgEB_fo4GANg,37824
49
- inspect_ai/_eval/evalset.py,sha256=1N4sJ-gvGe-viZtIUIjJ4DcUCjAHxUrB6ZN0SYGp0-4,23541
48
+ inspect_ai/_eval/eval.py,sha256=yo5SFToYovoTxt7mvvuNEl_9b-ML125xHF8LvdIkgBg,38138
49
+ inspect_ai/_eval/evalset.py,sha256=HGrz0LkTMsBbYDPZEMVnZCmFi_pYegZtSoqRVYbRDiE,23682
50
50
  inspect_ai/_eval/list.py,sha256=VbZ-2EI6MqrXvCN7VTz21TQSoU5K5_Q0hqhxmj5A_m0,3744
51
51
  inspect_ai/_eval/loader.py,sha256=yOj8HqYBFQntx0_GY4Wxqm6jivlT4N4WiQ1T8J9uRVA,23606
52
52
  inspect_ai/_eval/registry.py,sha256=9Q-Re9uZagQ2nw-W7hA6zhrmCQFmo3KcxncTcG24EG8,5315
53
- inspect_ai/_eval/run.py,sha256=1i-r9ha4afTyKKEwcA5PlMZ1SHZM80pt-N2MUKBzAk8,19093
53
+ inspect_ai/_eval/run.py,sha256=9TtOp1vc18KclxstjvWhEL5VtcLBL3SRbRwsoRXaah8,19179
54
54
  inspect_ai/_eval/score.py,sha256=qf9T8XwUmfE6A8QK1-D-jUbNlLETVM-HXhucPWZ0Ro0,9591
55
55
  inspect_ai/_eval/task/__init__.py,sha256=6FvojMW3yo36L7xDacppCHDxt6A8_tzj_ftg5bQ6eNk,199
56
56
  inspect_ai/_eval/task/constants.py,sha256=quAKMw-4-3xKd1T_KwXCZvHYoKRXt1ZGuaHbBcWJwnA,72
@@ -73,7 +73,7 @@ inspect_ai/_util/ansi.py,sha256=fMxOAn72Nl5NG_kdlY408nC62bKhsW29L__A5FwwMJQ,983
73
73
  inspect_ai/_util/appdirs.py,sha256=lhURbDS9xT2YBzWOe0jjxsdK4ZdiVAv_WwXQC83V_jw,563
74
74
  inspect_ai/_util/config.py,sha256=nuWVZbShE8IPnotDfRJx0uBZJxwbV36M0qKVYsQDEEI,848
75
75
  inspect_ai/_util/constants.py,sha256=ZkpYBs6qnulFNBRhEBVUgQhnNw_phpuCdViA6FQhe3c,1031
76
- inspect_ai/_util/content.py,sha256=RU3RIMIBWNumMI-bSWtdco5-oSUUmIfHrGS0EmNKFkY,2128
76
+ inspect_ai/_util/content.py,sha256=mYnN1m-VZ__leOyX8czbi1JRKukYCCxlQZgPwCk0aXE,2214
77
77
  inspect_ai/_util/datetime.py,sha256=WeQKSgT8VnmmJcHZbS-lWtVSDTPbQ4vO_V835wdTU7Y,270
78
78
  inspect_ai/_util/decorator.py,sha256=AEyOt-4VYMwXkEvMVyxMiB6xg_ZKQ89Q5gmJLf-dcpU,2595
79
79
  inspect_ai/_util/deprecation.py,sha256=Ng-_MXXf6zbsHa5FaFLTTvVeUMI5oQw7bl392hsiV1g,6670
@@ -144,7 +144,7 @@ inspect_ai/_view/www/.vscode/settings.json,sha256=g5hrVnMaYxM06JpiJD2EuE2xjcbF6x
144
144
  inspect_ai/_view/www/dist/index.html,sha256=gpdu6SR-SOH9EWx15cCWHzujMZujnZR5tRlEfROJg2A,997
145
145
  inspect_ai/_view/www/dist/assets/favicon.svg,sha256=b9AHYZaO2zBzeKH6G4PwXZMGGW_UxY0omKHam-c9MAs,1508
146
146
  inspect_ai/_view/www/dist/assets/index.css,sha256=V0HHB6ss9UdKAlLKTmyHoYAZrstD6nvb-UhnWInyhQQ,895546
147
- inspect_ai/_view/www/dist/assets/index.js,sha256=zcV5qvFRVPEBJkVclKSbtg91IX6L-T7dmO2M8yY9mZ4,2748105
147
+ inspect_ai/_view/www/dist/assets/index.js,sha256=-dI_BWa2w7TMj1_inAgHQmG4qq44oG_X2JM70W7DygY,2748559
148
148
  inspect_ai/_view/www/src/App.tsx,sha256=rhiZKs-f1y9amyX_OLay7aL4OXaQ_o0gNd04M3pZVuk,28852
149
149
  inspect_ai/_view/www/src/AppErrorBoundary.tsx,sha256=RyhZWbIMZj1QeUOUUXh9hUFvq6LoDEoHuTY0giswmL0,1169
150
150
  inspect_ai/_view/www/src/constants.ts,sha256=aLncMT1XjKzyphLF_jkXPZicsCJXMsBXcDomAC4EaIY,1228
@@ -247,9 +247,9 @@ inspect_ai/_view/www/src/samples/chat/MessageContent.tsx,sha256=9T_MjXhUPKXQHMws
247
247
  inspect_ai/_view/www/src/samples/chat/MessageContents.module.css,sha256=t9sk1CbuwDuYhwuBjWzWip7JPdN0PnzwzqNwdgVJCWU,35
248
248
  inspect_ai/_view/www/src/samples/chat/MessageContents.tsx,sha256=FMKAg7e_8OOqoIvrO_Bc_XLbfrnh7IL55VQByPknqVs,3338
249
249
  inspect_ai/_view/www/src/samples/chat/messages.ts,sha256=qm5AE2yQWtk1KbxDDSwgg_uvtU8-MStfhMpkTWSQ1DM,3070
250
- inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx,sha256=DdDHbVjRDZ4LD9tHBptMykO9mU8_pVk4zf7MwTvuQeQ,3261
250
+ inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx,sha256=FcEhHVa2LpJqH-QWHYPFVXgfTm8GfmxzePKEzHVSD6w,3651
251
251
  inspect_ai/_view/www/src/samples/chat/tools/ToolInput.module.css,sha256=apEfqHAe683GyFx803xDO6Wid3m3xn_3ftGSLa4uxVI,190
252
- inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx,sha256=B7_R2_Y8k8POQ69mR807kQdq3izxyN3CuURLb_FpvcQ,2009
252
+ inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx,sha256=MWVvXSRPER394f273p8OIPvHXYzqvJkkjd-WK41Hong,2041
253
253
  inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.module.css,sha256=p8jLonoAawbhuaqNzFPzToD-KRa3tBwX9w4yVOf3xqo,266
254
254
  inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.tsx,sha256=kOHkL97fnw1xwfgP_ys0JGl-9gd7rZDO_FVQzX8oQ9s,1616
255
255
  inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.module.css,sha256=RhrswSho4BZcJLi_YXtfDu7Ea70Z11rkwzeMvzsYsrM,51
@@ -456,16 +456,16 @@ inspect_ai/model/_call_tools.py,sha256=XvPO-RrbDSIk3A6dCXrqHG2IYAfBart1a-uMKUydA
456
456
  inspect_ai/model/_chat_message.py,sha256=I2EPWuVFRZVwS9mqA80mZCXm37brsEvnD633cq99wM0,7249
457
457
  inspect_ai/model/_conversation.py,sha256=7KPqnCx5ETNkdhR1g1gsjV8sCrJlrOOPwlBz_Yoc9kg,2463
458
458
  inspect_ai/model/_generate_config.py,sha256=JMX_48p-zv7WW0dGm_PQPyGpyJoa4AuFXBaBXajWWpo,10973
459
- inspect_ai/model/_image.py,sha256=kpO2Bn_-c-dK80HuPOPH1eSNmcoc39kofwf4yTTiTFE,477
460
459
  inspect_ai/model/_model.py,sha256=LaRXqKvM2fl9HGCQAdrOOkNryfYU970LZGsyOxk1o00,48304
461
460
  inspect_ai/model/_model_call.py,sha256=VJ8wnl9Y81JaiClBYM8eyt1jVb3n-yc6Dd88ofRiJDc,2234
462
461
  inspect_ai/model/_model_output.py,sha256=1picjX2Y0NSmEZ-vdQi42QAx3QvMcWVRn8pXP2wtmN8,7733
463
- inspect_ai/model/_openai.py,sha256=VvEUg0lQdXCq0vV3iR7GfqW52WjHXNRA2QDslIjg9RY,16975
462
+ inspect_ai/model/_openai.py,sha256=3_lQ3u-WJ8BOY5bMLM49LvAePzCZAn57Vi2SNLrWPm4,19093
463
+ inspect_ai/model/_openai_responses.py,sha256=qav1Fj2R-DOCkUfkrtGxV_PeT578mBZNwKt-yL4bmT0,10049
464
464
  inspect_ai/model/_reasoning.py,sha256=qmR8WT6t_cb7NIsJOQHPyFZh2eLV0HmYxKo2vtvteQ4,929
465
465
  inspect_ai/model/_registry.py,sha256=Cr2y32EqLnOqLbSWoXHVK4ivTTzCUhJuACxoTyPt8kY,2032
466
466
  inspect_ai/model/_render.py,sha256=rWypNUjgrH4NGp0r-ESAze9gZz7lYNjheEP438vRYZE,922
467
- inspect_ai/model/_providers/anthropic.py,sha256=SuXXs-VmG4XzSyHin7N1HPAHJoy43jExqhio2OPNV0o,33369
468
- inspect_ai/model/_providers/azureai.py,sha256=3phdDrrsKzinphLtGj39bet_jVLcKgtLcWr_uILO0cc,14225
467
+ inspect_ai/model/_providers/anthropic.py,sha256=qA6GOl64axTjuL5ciEakoYsRbUljfxM9SDZr13Kbjns,33396
468
+ inspect_ai/model/_providers/azureai.py,sha256=tDWuePLhnZBcpHLVzX7J3Wx8VRPhW8tmtjiwLPmJouU,14232
469
469
  inspect_ai/model/_providers/bedrock.py,sha256=mLeMW2JkG4lF0VQGEdku73ZL00EBy-hEvEcyCdjDUDo,24153
470
470
  inspect_ai/model/_providers/cloudflare.py,sha256=0e0HPas21cVC8N9mNJlZnSZyIt6FUB9lTIAqPXJDrtE,4586
471
471
  inspect_ai/model/_providers/goodfire.py,sha256=EzebC1woEjIXfHLP_ixpMR6G1hC-LxbSUxiilq1c-Is,8868
@@ -474,14 +474,15 @@ inspect_ai/model/_providers/grok.py,sha256=dS88ueXiD-kHAFr0jCoTpTGLGa2VsUlB_TFP8
474
474
  inspect_ai/model/_providers/groq.py,sha256=Fr4fy8NmqllmUW7jhnQ3W94zGlxyr276qaGFS_iDI3Q,11189
475
475
  inspect_ai/model/_providers/hf.py,sha256=EZRiiRSzIoRCdFYKj3Otn5ebsROdjzx5YSQ6CzqOJxk,17969
476
476
  inspect_ai/model/_providers/llama_cpp_python.py,sha256=i2I56Damgb8VDhMuPxPca24fVhlajDHzxCTYFnT41uI,702
477
- inspect_ai/model/_providers/mistral.py,sha256=pwBaO7VoW-ZsiZfNjF3-m7Zr44OkNasOlI5N3SEE1dc,17377
477
+ inspect_ai/model/_providers/mistral.py,sha256=TPJIB0AytktnFwwAlvg6Mz2hXarJK8m0G6ggJw5Cbqg,17774
478
478
  inspect_ai/model/_providers/mockllm.py,sha256=gL9f-f5TOdE4a0GVENr3cOIIp2kv8zVXWPZ608rouGk,2440
479
479
  inspect_ai/model/_providers/none.py,sha256=6qLbZpHSoEZaaxFO7luieFjqig2Ju8Fu00DlRngAry8,935
480
480
  inspect_ai/model/_providers/ollama.py,sha256=mBPSxaEkiH_RnlHKqOyFBlXObQhc2dfjL-rCKrea5u8,675
481
- inspect_ai/model/_providers/openai.py,sha256=9ze3TOLQ5ycRGquJ67bwCPOgfMPYwRZZbN-h2lN4Gys,15058
481
+ inspect_ai/model/_providers/openai.py,sha256=Qg0MM2OftmzzZ8aio-hvg3GZv77-PyuuY0uk3wtIM60,15189
482
482
  inspect_ai/model/_providers/openai_o1.py,sha256=wURSSI7aCBxbZONQBaEOYPrQleBExL2c2uSIdJXLi1U,12763
483
- inspect_ai/model/_providers/openrouter.py,sha256=5G8qS8xA7Gy4IGodEJd04xwjsN-O_as4oeU8DTsKB5s,2932
484
- inspect_ai/model/_providers/providers.py,sha256=GI68ptXsLoEkzuLMZseJQ1_jI2f1uqfZwKy9y8IX-Yg,6508
483
+ inspect_ai/model/_providers/openai_responses.py,sha256=9mVdfcKgIULv6YpwCFKFUj63JVi7szvBzHczj12ZdOc,6096
484
+ inspect_ai/model/_providers/openrouter.py,sha256=pDimDmm_4FzS4GZx0n9z8z717mQf3IQlgEy30huzpc4,4730
485
+ inspect_ai/model/_providers/providers.py,sha256=TdRXKzNQmeWZyTaAWkalmxVylRHkft0O8LqGJ054EiI,6508
485
486
  inspect_ai/model/_providers/together.py,sha256=Hwg-5jlFR3K61Epp_NnmDR5lX-bHZ2QT77GjM9dQOKY,9461
486
487
  inspect_ai/model/_providers/vertex.py,sha256=3PX3pVvzydA-IczZaEAeqQeiTtimBa3a6t418GAtjhY,17235
487
488
  inspect_ai/model/_providers/vllm.py,sha256=KNEjdu-oeCXH-vhpMeF1Pmnf8-mkLpQ5pbyFJMlaT9c,14172
@@ -544,8 +545,8 @@ inspect_ai/solver/_human_agent/commands/note.py,sha256=yOHXPkm3yFrXzf-CK-IS6B3M0
544
545
  inspect_ai/solver/_human_agent/commands/score.py,sha256=Pkcd3g-8BAYlxQnvJsMFKPZCnqWsFjUYAM7T4Dl5rtM,2207
545
546
  inspect_ai/solver/_human_agent/commands/status.py,sha256=uUO5M4skWDp29OS8sqVKAqZw0OcM3MSesBYQNbRypJ0,1934
546
547
  inspect_ai/solver/_human_agent/commands/submit.py,sha256=D2p1M2ApvAcaVZhbP3fFofG9ZsPVvmxivSLIF5xQxtA,6524
547
- inspect_ai/tool/__init__.py,sha256=krnJakKZ2A8hC_Lz1SyMKx5nEeLUGwgZL-vmBqUTVZM,2420
548
- inspect_ai/tool/_tool.py,sha256=e5a2fHtCg5_AObaDfJliV6s-bJZNfa6HEbj587MjDuM,6285
548
+ inspect_ai/tool/__init__.py,sha256=M1xR4GLN4LBCzWWbMbIGXE-XnagdvC9mK5_a4qK35Ew,2466
549
+ inspect_ai/tool/_tool.py,sha256=VjnbMnsXPLpNqglc6Oss7OK7cVHHG7W2qzWtjcOc5Us,7055
549
550
  inspect_ai/tool/_tool_call.py,sha256=yCkcQBl5iSdESX2Mv6z54IOFytmo6spzIk6UWJo3s7g,2294
550
551
  inspect_ai/tool/_tool_choice.py,sha256=L8QNmcnSnilzKg2HU3G65W5aYaSngO09z4FQ0fQlATM,496
551
552
  inspect_ai/tool/_tool_def.py,sha256=wS6yX2_64-O6L4k1kMihUp52-OnGypMn11L3oXMNeQc,8191
@@ -560,6 +561,7 @@ inspect_ai/tool/_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
560
561
  inspect_ai/tool/_tools/_bash_session.py,sha256=_5Y8e5qGX_WTtLsg4bCmj0WH_xNY2locCz4rQCOlvM8,3480
561
562
  inspect_ai/tool/_tools/_execute.py,sha256=SZdtVxxGoQNErWFtYaJgfTtLsZbBP28lnY112mt-VWQ,3435
562
563
  inspect_ai/tool/_tools/_text_editor.py,sha256=9Z6vB4_sgwQw2OH22reA6FSw6LgFslbQ5X7ufvaVl5U,3939
564
+ inspect_ai/tool/_tools/_think.py,sha256=FndjEwPbkkdqEmxpVHpecEwRJo6DYWFJzwUnNNLmy9Y,1821
563
565
  inspect_ai/tool/_tools/_web_search.py,sha256=GYkGasfmZWG3TY1XqBfa6yJnG7ysPtdGCVmPUJHQRSM,8012
564
566
  inspect_ai/tool/_tools/_computer/__init__.py,sha256=fq4BSM4aDhtEtE4279xm47NiO6vyiZHhhw7cq-azFzk,56
565
567
  inspect_ai/tool/_tools/_computer/_common.py,sha256=nX8Cf9jagsnjwZb9f9eWADUjzETf6PSNRcFrzp0_KLg,5949
@@ -625,9 +627,9 @@ inspect_ai/util/_sandbox/docker/internal.py,sha256=c8X8TLrBPOvsfnq5TkMlb_bzTALyc
625
627
  inspect_ai/util/_sandbox/docker/prereqs.py,sha256=0j6_OauBBnVlpBleADcZavIAAQZy4WewVjbRn9c0stg,3355
626
628
  inspect_ai/util/_sandbox/docker/service.py,sha256=hhHIWH1VDFLwehdGd19aUBD_VKfDO3GCPxpw1HSwVQk,2437
627
629
  inspect_ai/util/_sandbox/docker/util.py,sha256=EeInihCNXgUWxaqZ4dNOJd719kXL2_jr63QCoXn68vA,3154
628
- inspect_ai-0.3.76.dist-info/licenses/LICENSE,sha256=xZPCr8gTiFIerrA_DRpLAbw-UUftnLFsHxKeW-NTtq8,1081
629
- inspect_ai-0.3.76.dist-info/METADATA,sha256=qQk_DES_FDFGm7FFo85Tz9LI3Vrkj9MnUb-EHIi-ym0,4997
630
- inspect_ai-0.3.76.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
631
- inspect_ai-0.3.76.dist-info/entry_points.txt,sha256=WGGLmzTzDWLzYfiyovSY6oEKuf-gqzSDNOb5V-hk3fM,54
632
- inspect_ai-0.3.76.dist-info/top_level.txt,sha256=Tp3za30CHXJEKLk8xLe9qGsW4pBzJpEIOMHOHNCXiVo,11
633
- inspect_ai-0.3.76.dist-info/RECORD,,
630
+ inspect_ai-0.3.78.dist-info/licenses/LICENSE,sha256=xZPCr8gTiFIerrA_DRpLAbw-UUftnLFsHxKeW-NTtq8,1081
631
+ inspect_ai-0.3.78.dist-info/METADATA,sha256=NNzcpeDyLChQBQ9aFqlE2iVcY-sod8sd5B72_pI2qq8,4997
632
+ inspect_ai-0.3.78.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
633
+ inspect_ai-0.3.78.dist-info/entry_points.txt,sha256=WGGLmzTzDWLzYfiyovSY6oEKuf-gqzSDNOb5V-hk3fM,54
634
+ inspect_ai-0.3.78.dist-info/top_level.txt,sha256=Tp3za30CHXJEKLk8xLe9qGsW4pBzJpEIOMHOHNCXiVo,11
635
+ inspect_ai-0.3.78.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.0.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,15 +0,0 @@
1
- from copy import copy
2
-
3
- from pydantic import JsonValue
4
-
5
- from inspect_ai._util.constants import BASE_64_DATA_REMOVED
6
-
7
-
8
- def image_url_filter(key: JsonValue | None, value: JsonValue) -> JsonValue:
9
- # remove images from raw api call
10
- if key == "image_url" and isinstance(value, dict) and "url" in value:
11
- url = str(value.get("url"))
12
- if url.startswith("data:"):
13
- value = copy(value)
14
- value.update(url=BASE_64_DATA_REMOVED)
15
- return value