meshagent-anthropic 0.24.6__tar.gz → 0.25.1__tar.gz
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.
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/CHANGELOG.md +16 -2
- {meshagent_anthropic-0.24.6/meshagent_anthropic.egg-info → meshagent_anthropic-0.25.1}/PKG-INFO +4 -4
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/__init__.py +8 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/mcp.py +6 -8
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/messages_adapter.py +21 -5
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/openai_responses_stream_adapter.py +10 -2
- meshagent_anthropic-0.25.1/meshagent/anthropic/request_tool.py +28 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/tests/mcp_test.py +9 -6
- meshagent_anthropic-0.25.1/meshagent/anthropic/version.py +1 -0
- meshagent_anthropic-0.25.1/meshagent/anthropic/web_fetch.py +73 -0
- meshagent_anthropic-0.25.1/meshagent/anthropic/web_search.py +73 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1/meshagent_anthropic.egg-info}/PKG-INFO +4 -4
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent_anthropic.egg-info/SOURCES.txt +3 -0
- meshagent_anthropic-0.25.1/meshagent_anthropic.egg-info/requires.txt +6 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/pyproject.toml +3 -3
- meshagent_anthropic-0.24.6/meshagent/anthropic/version.py +0 -1
- meshagent_anthropic-0.24.6/meshagent_anthropic.egg-info/requires.txt +0 -6
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/LICENSE +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/MANIFEST.in +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/README.md +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/proxy/__init__.py +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/proxy/proxy.py +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/tests/anthropic_live_test.py +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/tests/messages_adapter_test.py +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/tests/openai_responses_stream_adapter_test.py +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent_anthropic.egg-info/dependency_links.txt +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent_anthropic.egg-info/top_level.txt +0 -0
- {meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/setup.cfg +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
## [0.
|
|
2
|
-
-
|
|
1
|
+
## [0.25.1]
|
|
2
|
+
- Added Anthropic web search and web fetch toolkits, including beta header injection and request middleware support.
|
|
3
|
+
- Added a container-based shell tool to run commands in persistent containers with configurable image, mounts, and environment.
|
|
4
|
+
- Expanded the web fetch tool to return text, JSON, or file responses with HTML-to-Markdown conversion and content-type handling.
|
|
5
|
+
- Breaking: CLI commands now reject OpenAI-only tool flags when using Claude models (image generation, local shell, apply patch, computer use).
|
|
6
|
+
- CLI MCP bridge adds streamable HTTP connections plus custom headers and secret-backed headers; OAuth2 secret set now accepts text/base64 input and identity-scoped secrets.
|
|
7
|
+
- Dependency updates: mcp to ~1.26.0; html-to-markdown to ~2.24.3.
|
|
8
|
+
|
|
9
|
+
## [0.25.0]
|
|
10
|
+
- Added SQL column-schema parsing and CLI support for SQL-like `--columns` when creating tables or adding columns.
|
|
11
|
+
- Breaking: SQL query requests now use a single `params` map for typed bindings instead of `parameters`/`param_values`.
|
|
12
|
+
- Added `published`/`public` port fields in service specs for externally routed services.
|
|
13
|
+
- Secrets set now supports `for_identity` to set secrets on behalf of another identity.
|
|
14
|
+
- Added a Slack events HTTP bot package with dependencies including `pyjwt` 2.10.
|
|
15
|
+
- Breaking: the CLI `exec` command was removed.
|
|
16
|
+
- ThreadAdapter message writing now uses `write_text_message` and accepts participant name strings.
|
|
3
17
|
|
|
4
18
|
## [0.24.5]
|
|
5
19
|
- Stability
|
{meshagent_anthropic-0.24.6/meshagent_anthropic.egg-info → meshagent_anthropic-0.25.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-anthropic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.25.1
|
|
4
4
|
Summary: Anthropic Building Blocks for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -11,9 +11,9 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: pytest~=8.4
|
|
13
13
|
Requires-Dist: pytest-asyncio~=0.26
|
|
14
|
-
Requires-Dist: meshagent-api~=0.
|
|
15
|
-
Requires-Dist: meshagent-agents~=0.
|
|
16
|
-
Requires-Dist: meshagent-tools~=0.
|
|
14
|
+
Requires-Dist: meshagent-api~=0.25.1
|
|
15
|
+
Requires-Dist: meshagent-agents~=0.25.1
|
|
16
|
+
Requires-Dist: meshagent-tools~=0.25.1
|
|
17
17
|
Requires-Dist: anthropic<1.0,>=0.25
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
@@ -11,6 +11,8 @@ from .mcp import (
|
|
|
11
11
|
MCPToolkitBuilder,
|
|
12
12
|
)
|
|
13
13
|
from .openai_responses_stream_adapter import AnthropicOpenAIResponsesStreamAdapter
|
|
14
|
+
from .web_fetch import WebFetchConfig, WebFetchTool, WebFetchToolkitBuilder
|
|
15
|
+
from .web_search import WebSearchConfig, WebSearchTool, WebSearchToolkitBuilder
|
|
14
16
|
|
|
15
17
|
__all__ = [
|
|
16
18
|
AnthropicMessagesAdapter,
|
|
@@ -22,4 +24,10 @@ __all__ = [
|
|
|
22
24
|
MCPToolConfig,
|
|
23
25
|
MCPToolset,
|
|
24
26
|
MCPToolkitBuilder,
|
|
27
|
+
WebFetchConfig,
|
|
28
|
+
WebFetchTool,
|
|
29
|
+
WebFetchToolkitBuilder,
|
|
30
|
+
WebSearchConfig,
|
|
31
|
+
WebSearchTool,
|
|
32
|
+
WebSearchToolkitBuilder,
|
|
25
33
|
]
|
|
@@ -4,7 +4,9 @@ from typing import Literal, Optional
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
-
from meshagent.tools import
|
|
7
|
+
from meshagent.tools import Toolkit, ToolkitBuilder, ToolkitConfig
|
|
8
|
+
|
|
9
|
+
from .request_tool import AnthropicRequestTool
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
# This module wraps Anthropic's official MCP connector support:
|
|
@@ -56,21 +58,17 @@ class MCPConfig(ToolkitConfig):
|
|
|
56
58
|
betas: list[str] = [MCP_CONNECTOR_BETA]
|
|
57
59
|
|
|
58
60
|
|
|
59
|
-
class MCPTool(
|
|
61
|
+
class MCPTool(AnthropicRequestTool):
|
|
60
62
|
"""Non-executable tool that augments the Anthropic request."""
|
|
61
63
|
|
|
62
64
|
def __init__(self, *, config: MCPConfig):
|
|
63
65
|
super().__init__(name="mcp")
|
|
64
66
|
self.config = config
|
|
65
67
|
|
|
66
|
-
def apply(self, *, request: dict) -> None:
|
|
68
|
+
def apply(self, *, request: dict, headers: dict) -> None:
|
|
67
69
|
"""Mutate an Anthropic Messages request in-place."""
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
betas = request.setdefault("betas", [])
|
|
71
|
-
for b in self.config.betas:
|
|
72
|
-
if b not in betas:
|
|
73
|
-
betas.append(b)
|
|
71
|
+
self.apply_betas(headers=headers, betas=self.config.betas)
|
|
74
72
|
|
|
75
73
|
toolsets = self.config.toolsets
|
|
76
74
|
if toolsets is None:
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/messages_adapter.py
RENAMED
|
@@ -46,7 +46,11 @@ def safe_tool_name(name: str) -> str:
|
|
|
46
46
|
def _as_jsonable(obj: Any) -> Any:
|
|
47
47
|
if isinstance(obj, dict):
|
|
48
48
|
return obj
|
|
49
|
-
return obj.model_dump(
|
|
49
|
+
return obj.model_dump(
|
|
50
|
+
mode="json",
|
|
51
|
+
exclude_none=True,
|
|
52
|
+
exclude_unset=True,
|
|
53
|
+
)
|
|
50
54
|
|
|
51
55
|
|
|
52
56
|
def _text_block(text: str) -> dict:
|
|
@@ -327,6 +331,9 @@ class AnthropicMessagesAdapter(LLMAdapter[dict]):
|
|
|
327
331
|
# The MCP connector requires `client.beta.messages.*`.
|
|
328
332
|
if request.get("betas") is not None:
|
|
329
333
|
return client.beta.messages
|
|
334
|
+
extra_headers = request.get("extra_headers")
|
|
335
|
+
if isinstance(extra_headers, dict) and extra_headers.get("anthropic-beta"):
|
|
336
|
+
return client.beta.messages
|
|
330
337
|
return client.messages
|
|
331
338
|
|
|
332
339
|
async def _create_with_optional_headers(self, *, client: Any, request: dict) -> Any:
|
|
@@ -372,11 +379,11 @@ class AnthropicMessagesAdapter(LLMAdapter[dict]):
|
|
|
372
379
|
|
|
373
380
|
def _split_toolkits(
|
|
374
381
|
self, *, toolkits: list[Toolkit]
|
|
375
|
-
) -> tuple[list[Toolkit], list[
|
|
382
|
+
) -> tuple[list[Toolkit], list[BaseTool]]:
|
|
376
383
|
"""Split toolkits into executable tools and request middleware tools."""
|
|
377
384
|
|
|
378
385
|
executable_toolkits: list[Toolkit] = []
|
|
379
|
-
middleware: list[
|
|
386
|
+
middleware: list[BaseTool] = []
|
|
380
387
|
|
|
381
388
|
for toolkit in toolkits:
|
|
382
389
|
executable_tools: list[Tool] = []
|
|
@@ -387,6 +394,8 @@ class AnthropicMessagesAdapter(LLMAdapter[dict]):
|
|
|
387
394
|
elif isinstance(t, Tool):
|
|
388
395
|
executable_tools.append(t)
|
|
389
396
|
elif isinstance(t, BaseTool):
|
|
397
|
+
if hasattr(t, "apply") and callable(getattr(t, "apply")):
|
|
398
|
+
middleware.append(t)
|
|
390
399
|
# Non-executable tool types are ignored.
|
|
391
400
|
continue
|
|
392
401
|
else:
|
|
@@ -407,10 +416,17 @@ class AnthropicMessagesAdapter(LLMAdapter[dict]):
|
|
|
407
416
|
return executable_toolkits, middleware
|
|
408
417
|
|
|
409
418
|
def _apply_request_middleware(
|
|
410
|
-
self, *, request: dict, middleware: list[
|
|
419
|
+
self, *, request: dict, middleware: list[BaseTool]
|
|
411
420
|
) -> dict:
|
|
421
|
+
headers = request.get("extra_headers") or {}
|
|
412
422
|
for m in middleware:
|
|
413
|
-
m
|
|
423
|
+
apply = getattr(m, "apply", None)
|
|
424
|
+
if callable(apply):
|
|
425
|
+
try:
|
|
426
|
+
apply(request=request, headers=headers)
|
|
427
|
+
except TypeError:
|
|
428
|
+
apply(request=request)
|
|
429
|
+
request["extra_headers"] = headers or None
|
|
414
430
|
return request
|
|
415
431
|
|
|
416
432
|
async def next(
|
|
@@ -114,7 +114,11 @@ class AnthropicOpenAIResponsesStreamAdapter(AnthropicMessagesAdapter):
|
|
|
114
114
|
|
|
115
115
|
async with client.messages.stream(**request) as stream:
|
|
116
116
|
async for event in stream:
|
|
117
|
-
data = event.model_dump(
|
|
117
|
+
data = event.model_dump(
|
|
118
|
+
mode="json",
|
|
119
|
+
exclude_none=True,
|
|
120
|
+
exclude_unset=True,
|
|
121
|
+
)
|
|
118
122
|
etype = data.get("type")
|
|
119
123
|
|
|
120
124
|
if etype == "message_start":
|
|
@@ -356,7 +360,11 @@ class AnthropicOpenAIResponsesStreamAdapter(AnthropicMessagesAdapter):
|
|
|
356
360
|
continue
|
|
357
361
|
|
|
358
362
|
final_message = await stream.get_final_message()
|
|
359
|
-
final_dict = final_message.model_dump(
|
|
363
|
+
final_dict = final_message.model_dump(
|
|
364
|
+
mode="json",
|
|
365
|
+
exclude_none=True,
|
|
366
|
+
exclude_unset=True,
|
|
367
|
+
)
|
|
360
368
|
usage = final_dict.get("usage") or {}
|
|
361
369
|
input_tokens = usage.get("input_tokens")
|
|
362
370
|
output_tokens = usage.get("output_tokens")
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from meshagent.tools import BaseTool
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AnthropicRequestTool(BaseTool):
|
|
9
|
+
beta_header = "anthropic-beta"
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def apply_betas(*, headers: dict, betas: Optional[list[str]]) -> None:
|
|
13
|
+
if not betas:
|
|
14
|
+
return
|
|
15
|
+
|
|
16
|
+
existing = headers.get(AnthropicRequestTool.beta_header)
|
|
17
|
+
existing_betas: list[str] = []
|
|
18
|
+
|
|
19
|
+
if isinstance(existing, str):
|
|
20
|
+
existing_betas = [b.strip() for b in existing.split(",") if b.strip()]
|
|
21
|
+
elif isinstance(existing, list):
|
|
22
|
+
existing_betas = [str(b) for b in existing if str(b)]
|
|
23
|
+
|
|
24
|
+
for beta in betas:
|
|
25
|
+
if beta not in existing_betas:
|
|
26
|
+
existing_betas.append(beta)
|
|
27
|
+
|
|
28
|
+
headers[AnthropicRequestTool.beta_header] = ",".join(existing_betas)
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/tests/mcp_test.py
RENAMED
|
@@ -11,9 +11,10 @@ def test_mcp_tool_apply_injects_servers_toolsets_and_beta():
|
|
|
11
11
|
|
|
12
12
|
tool = MCPTool(config=cfg)
|
|
13
13
|
request: dict = {"tools": []}
|
|
14
|
-
|
|
14
|
+
headers: dict = {}
|
|
15
|
+
tool.apply(request=request, headers=headers)
|
|
15
16
|
|
|
16
|
-
assert
|
|
17
|
+
assert headers["anthropic-beta"] == "mcp-client-2025-11-20"
|
|
17
18
|
assert request["mcp_servers"] == [
|
|
18
19
|
{
|
|
19
20
|
"type": "url",
|
|
@@ -45,14 +46,16 @@ def test_mcp_tool_apply_dedupes_servers_by_name_and_preserves_existing():
|
|
|
45
46
|
"authorization_token": "OLD",
|
|
46
47
|
}
|
|
47
48
|
],
|
|
48
|
-
"betas": ["some-other-beta"],
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
headers: dict = {"anthropic-beta": "some-other-beta"}
|
|
52
|
+
|
|
53
|
+
tool.apply(request=request, headers=headers)
|
|
52
54
|
|
|
53
55
|
# Keeps existing betas and appends MCP beta.
|
|
54
|
-
|
|
55
|
-
assert "
|
|
56
|
+
betas = {b.strip() for b in headers["anthropic-beta"].split(",") if b.strip()}
|
|
57
|
+
assert "some-other-beta" in betas
|
|
58
|
+
assert "mcp-client-2025-11-20" in betas
|
|
56
59
|
|
|
57
60
|
# Dedupes by name; cfg overwrites the existing server entry.
|
|
58
61
|
by_name = {s["name"]: s for s in request["mcp_servers"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.25.1"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal, Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
from meshagent.tools import Toolkit, ToolkitBuilder, ToolkitConfig
|
|
8
|
+
|
|
9
|
+
from .request_tool import AnthropicRequestTool
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WebFetchCitations(BaseModel):
|
|
13
|
+
enabled: bool = True
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class WebFetchConfig(ToolkitConfig):
|
|
17
|
+
name: Literal["web_fetch"] = "web_fetch"
|
|
18
|
+
max_uses: Optional[int] = None
|
|
19
|
+
allowed_domains: Optional[list[str]] = None
|
|
20
|
+
blocked_domains: Optional[list[str]] = None
|
|
21
|
+
citations: Optional[WebFetchCitations] = None
|
|
22
|
+
max_content_tokens: Optional[int] = None
|
|
23
|
+
betas: Optional[list[str]] = Field(default_factory=lambda: ["web-fetch-2025-09-10"])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class WebFetchTool(AnthropicRequestTool):
|
|
27
|
+
def __init__(self, *, config: Optional[WebFetchConfig] = None):
|
|
28
|
+
if config is None:
|
|
29
|
+
config = WebFetchConfig(name="web_fetch")
|
|
30
|
+
super().__init__(name=config.name)
|
|
31
|
+
self.config = config
|
|
32
|
+
|
|
33
|
+
def apply(self, *, request: dict, headers: dict) -> None:
|
|
34
|
+
if self.config.allowed_domains and self.config.blocked_domains:
|
|
35
|
+
raise ValueError(
|
|
36
|
+
"web_fetch cannot set both allowed_domains and blocked_domains"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
tools = request.setdefault("tools", [])
|
|
40
|
+
tool_def: dict[str, object] = {
|
|
41
|
+
"type": "web_fetch_20250910",
|
|
42
|
+
"name": self.config.name,
|
|
43
|
+
}
|
|
44
|
+
if self.config.max_uses is not None:
|
|
45
|
+
tool_def["max_uses"] = self.config.max_uses
|
|
46
|
+
if self.config.allowed_domains is not None:
|
|
47
|
+
tool_def["allowed_domains"] = self.config.allowed_domains
|
|
48
|
+
if self.config.blocked_domains is not None:
|
|
49
|
+
tool_def["blocked_domains"] = self.config.blocked_domains
|
|
50
|
+
if self.config.citations is not None:
|
|
51
|
+
tool_def["citations"] = self.config.citations.model_dump(
|
|
52
|
+
mode="json", exclude_none=True
|
|
53
|
+
)
|
|
54
|
+
if self.config.max_content_tokens is not None:
|
|
55
|
+
tool_def["max_content_tokens"] = self.config.max_content_tokens
|
|
56
|
+
|
|
57
|
+
if not any(
|
|
58
|
+
isinstance(t, dict)
|
|
59
|
+
and t.get("type") == tool_def["type"]
|
|
60
|
+
and t.get("name") == tool_def["name"]
|
|
61
|
+
for t in tools
|
|
62
|
+
):
|
|
63
|
+
tools.append(tool_def)
|
|
64
|
+
|
|
65
|
+
self.apply_betas(headers=headers, betas=self.config.betas)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class WebFetchToolkitBuilder(ToolkitBuilder):
|
|
69
|
+
def __init__(self):
|
|
70
|
+
super().__init__(name="web_fetch", type=WebFetchConfig)
|
|
71
|
+
|
|
72
|
+
async def make(self, *, room, model: str, config: WebFetchConfig) -> Toolkit:
|
|
73
|
+
return Toolkit(name="web_fetch", tools=[WebFetchTool(config=config)])
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal, Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from meshagent.tools import Toolkit, ToolkitBuilder, ToolkitConfig
|
|
8
|
+
|
|
9
|
+
from .request_tool import AnthropicRequestTool
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WebSearchConfig(ToolkitConfig):
|
|
13
|
+
name: Literal["web_search"] = "web_search"
|
|
14
|
+
max_uses: Optional[int] = None
|
|
15
|
+
allowed_domains: Optional[list[str]] = None
|
|
16
|
+
blocked_domains: Optional[list[str]] = None
|
|
17
|
+
user_location: Optional["WebSearchUserLocation"] = None
|
|
18
|
+
betas: Optional[list[str]] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class WebSearchUserLocation(BaseModel):
|
|
22
|
+
type: Literal["approximate"] = "approximate"
|
|
23
|
+
city: Optional[str] = None
|
|
24
|
+
region: Optional[str] = None
|
|
25
|
+
country: Optional[str] = None
|
|
26
|
+
timezone: Optional[str] = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class WebSearchTool(AnthropicRequestTool):
|
|
30
|
+
def __init__(self, *, config: Optional[WebSearchConfig] = None):
|
|
31
|
+
if config is None:
|
|
32
|
+
config = WebSearchConfig(name="web_search")
|
|
33
|
+
super().__init__(name=config.name)
|
|
34
|
+
self.config = config
|
|
35
|
+
|
|
36
|
+
def apply(self, *, request: dict, headers: dict) -> None:
|
|
37
|
+
if self.config.allowed_domains and self.config.blocked_domains:
|
|
38
|
+
raise ValueError(
|
|
39
|
+
"web_search cannot set both allowed_domains and blocked_domains"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
tools = request.setdefault("tools", [])
|
|
43
|
+
tool_def: dict[str, object] = {
|
|
44
|
+
"type": "web_search_20250305",
|
|
45
|
+
"name": self.config.name,
|
|
46
|
+
}
|
|
47
|
+
if self.config.max_uses is not None:
|
|
48
|
+
tool_def["max_uses"] = self.config.max_uses
|
|
49
|
+
if self.config.allowed_domains is not None:
|
|
50
|
+
tool_def["allowed_domains"] = self.config.allowed_domains
|
|
51
|
+
if self.config.blocked_domains is not None:
|
|
52
|
+
tool_def["blocked_domains"] = self.config.blocked_domains
|
|
53
|
+
if self.config.user_location is not None:
|
|
54
|
+
tool_def["user_location"] = self.config.user_location.model_dump(
|
|
55
|
+
mode="json", exclude_none=True
|
|
56
|
+
)
|
|
57
|
+
if not any(
|
|
58
|
+
isinstance(t, dict)
|
|
59
|
+
and t.get("type") == tool_def["type"]
|
|
60
|
+
and t.get("name") == tool_def["name"]
|
|
61
|
+
for t in tools
|
|
62
|
+
):
|
|
63
|
+
tools.append(tool_def)
|
|
64
|
+
|
|
65
|
+
self.apply_betas(headers=headers, betas=self.config.betas)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class WebSearchToolkitBuilder(ToolkitBuilder):
|
|
69
|
+
def __init__(self):
|
|
70
|
+
super().__init__(name="web_search", type=WebSearchConfig)
|
|
71
|
+
|
|
72
|
+
async def make(self, *, room, model: str, config: WebSearchConfig) -> Toolkit:
|
|
73
|
+
return Toolkit(name="web_search", tools=[WebSearchTool(config=config)])
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1/meshagent_anthropic.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-anthropic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.25.1
|
|
4
4
|
Summary: Anthropic Building Blocks for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -11,9 +11,9 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: pytest~=8.4
|
|
13
13
|
Requires-Dist: pytest-asyncio~=0.26
|
|
14
|
-
Requires-Dist: meshagent-api~=0.
|
|
15
|
-
Requires-Dist: meshagent-agents~=0.
|
|
16
|
-
Requires-Dist: meshagent-tools~=0.
|
|
14
|
+
Requires-Dist: meshagent-api~=0.25.1
|
|
15
|
+
Requires-Dist: meshagent-agents~=0.25.1
|
|
16
|
+
Requires-Dist: meshagent-tools~=0.25.1
|
|
17
17
|
Requires-Dist: anthropic<1.0,>=0.25
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent_anthropic.egg-info/SOURCES.txt
RENAMED
|
@@ -7,7 +7,10 @@ meshagent/anthropic/__init__.py
|
|
|
7
7
|
meshagent/anthropic/mcp.py
|
|
8
8
|
meshagent/anthropic/messages_adapter.py
|
|
9
9
|
meshagent/anthropic/openai_responses_stream_adapter.py
|
|
10
|
+
meshagent/anthropic/request_tool.py
|
|
10
11
|
meshagent/anthropic/version.py
|
|
12
|
+
meshagent/anthropic/web_fetch.py
|
|
13
|
+
meshagent/anthropic/web_search.py
|
|
11
14
|
meshagent/anthropic/proxy/__init__.py
|
|
12
15
|
meshagent/anthropic/proxy/proxy.py
|
|
13
16
|
meshagent/anthropic/tests/anthropic_live_test.py
|
|
@@ -12,9 +12,9 @@ keywords = []
|
|
|
12
12
|
dependencies = [
|
|
13
13
|
"pytest~=8.4",
|
|
14
14
|
"pytest-asyncio~=0.26",
|
|
15
|
-
"meshagent-api~=0.
|
|
16
|
-
"meshagent-agents~=0.
|
|
17
|
-
"meshagent-tools~=0.
|
|
15
|
+
"meshagent-api~=0.25.1",
|
|
16
|
+
"meshagent-agents~=0.25.1",
|
|
17
|
+
"meshagent-tools~=0.25.1",
|
|
18
18
|
"anthropic>=0.25,<1.0"
|
|
19
19
|
]
|
|
20
20
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.24.6"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/proxy/__init__.py
RENAMED
|
File without changes
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent/anthropic/proxy/proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshagent_anthropic-0.24.6 → meshagent_anthropic-0.25.1}/meshagent_anthropic.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|