agentstack-sdk 0.4.2rc10__tar.gz → 0.4.3__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.
Files changed (69) hide show
  1. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/PKG-INFO +1 -1
  2. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/pyproject.toml +1 -1
  3. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/__init__.py +1 -0
  4. agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/tools/__init__.py +5 -0
  5. agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/tools/call.py +114 -0
  6. agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/tools/exceptions.py +6 -0
  7. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/vector_store.py +14 -2
  8. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/README.md +0 -0
  9. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/__init__.py +0 -0
  10. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/__init__.py +0 -0
  11. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/__init__.py +0 -0
  12. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/__init__.py +0 -0
  13. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/oauth.py +0 -0
  14. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/storage/__init__.py +0 -0
  15. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/storage/base.py +0 -0
  16. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/storage/memory.py +0 -0
  17. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/secrets/__init__.py +0 -0
  18. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/secrets/secrets.py +0 -0
  19. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/base.py +0 -0
  20. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/common/__init__.py +0 -0
  21. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/common/form.py +0 -0
  22. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/exceptions.py +0 -0
  23. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/__init__.py +0 -0
  24. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/embedding.py +0 -0
  25. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/form.py +0 -0
  26. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/llm.py +0 -0
  27. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/mcp.py +0 -0
  28. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/platform.py +0 -0
  29. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/__init__.py +0 -0
  30. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/agent_detail.py +0 -0
  31. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/canvas.py +0 -0
  32. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/citation.py +0 -0
  33. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/error.py +0 -0
  34. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/form_request.py +0 -0
  35. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/settings.py +0 -0
  36. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/trajectory.py +0 -0
  37. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/types.py +0 -0
  38. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/__init__.py +0 -0
  39. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/client.py +0 -0
  40. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/common.py +0 -0
  41. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/configuration.py +0 -0
  42. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/context.py +0 -0
  43. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/file.py +0 -0
  44. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/model_provider.py +0 -0
  45. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/provider.py +0 -0
  46. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/provider_build.py +0 -0
  47. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/types.py +0 -0
  48. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/user.py +0 -0
  49. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/variables.py +0 -0
  50. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/py.typed +0 -0
  51. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/__init__.py +0 -0
  52. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/agent.py +0 -0
  53. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/app.py +0 -0
  54. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/constants.py +0 -0
  55. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/context.py +0 -0
  56. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/dependencies.py +0 -0
  57. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/server.py +0 -0
  58. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/__init__.py +0 -0
  59. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/context_store.py +0 -0
  60. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/memory_context_store.py +0 -0
  61. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/platform_context_store.py +0 -0
  62. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/telemetry.py +0 -0
  63. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/utils.py +0 -0
  64. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/__init__.py +0 -0
  65. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/file.py +0 -0
  66. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/httpx.py +0 -0
  67. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/logging.py +0 -0
  68. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/resource_context.py +0 -0
  69. {agentstack_sdk-0.4.2rc10 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: agentstack-sdk
3
- Version: 0.4.2rc10
3
+ Version: 0.4.3
4
4
  Summary: Agent Stack SDK
5
5
  Author: IBM Corp.
6
6
  Requires-Dist: a2a-sdk==0.3.9
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentstack-sdk"
3
- version = "0.4.2-rc10"
3
+ version = "0.4.3"
4
4
  description = "Agent Stack SDK"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "IBM Corp." }]
@@ -3,4 +3,5 @@
3
3
 
4
4
  from .auth import *
5
5
  from .services import *
6
+ from .tools import *
6
7
  from .ui import *
@@ -0,0 +1,5 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from .call import *
5
+ from .exceptions import *
@@ -0,0 +1,114 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from __future__ import annotations
5
+
6
+ import uuid
7
+ from types import NoneType
8
+ from typing import TYPE_CHECKING, Any, Literal
9
+
10
+ import a2a.types
11
+ from mcp import Tool
12
+ from mcp.types import Implementation
13
+ from pydantic import BaseModel, Field
14
+
15
+ from agentstack_sdk.a2a.extensions.base import BaseExtensionClient, BaseExtensionServer, BaseExtensionSpec
16
+ from agentstack_sdk.a2a.extensions.tools.exceptions import ToolCallRejectionError
17
+ from agentstack_sdk.a2a.types import AgentMessage, InputRequired
18
+
19
+ if TYPE_CHECKING:
20
+ from agentstack_sdk.server.context import RunContext
21
+
22
+
23
+ class ToolCallServer(BaseModel):
24
+ name: str = Field(description="The programmatic name of the server.")
25
+ title: str | None = Field(description="A human-readable title for the server.")
26
+ version: str = Field(description="The version of the server.")
27
+
28
+
29
+ class ToolCallRequest(BaseModel):
30
+ name: str = Field(description="The programmatic name of the tool.")
31
+ title: str | None = Field(None, description="A human-readable title for the tool.")
32
+ description: str | None = Field(None, description="A human-readable description of the tool.")
33
+
34
+ input: dict[str, Any] | None = Field(description="The input for the tool.")
35
+
36
+ server: ToolCallServer | None = Field(None, description="The server executing the tool.")
37
+
38
+ @staticmethod
39
+ def from_mcp_tool(
40
+ tool: Tool, input: dict[str, Any] | None, server: Implementation | None = None
41
+ ) -> ToolCallRequest:
42
+ return ToolCallRequest(
43
+ name=tool.name,
44
+ title=tool.annotations.title if tool.annotations else None,
45
+ description=tool.description,
46
+ input=input,
47
+ server=ToolCallServer(name=server.name, title=server.title, version=server.version) if server else None,
48
+ )
49
+
50
+
51
+ class ToolCallResponse(BaseModel):
52
+ action: Literal["accept", "reject"]
53
+
54
+
55
+ class ToolCallExtensionParams(BaseModel):
56
+ pass
57
+
58
+
59
+ class ToolCallExtensionSpec(BaseExtensionSpec[ToolCallExtensionParams]):
60
+ URI: str = "https://a2a-extensions.agentstack.beeai.dev/tools/call/v1"
61
+
62
+
63
+ class ToolCallExtensionMetadata(BaseModel):
64
+ pass
65
+
66
+
67
+ class ToolCallExtensionServer(BaseExtensionServer[ToolCallExtensionSpec, ToolCallExtensionMetadata]):
68
+ def create_request_message(self, *, request: ToolCallRequest):
69
+ return AgentMessage(
70
+ text="Tool call approval requested", metadata={self.spec.URI: request.model_dump(mode="json")}
71
+ )
72
+
73
+ def parse_response(self, *, message: a2a.types.Message):
74
+ if not message or not message.metadata or not (data := message.metadata.get(self.spec.URI)):
75
+ raise RuntimeError("Invalid mcp response")
76
+ return ToolCallResponse.model_validate(data)
77
+
78
+ async def request_tool_call_approval(
79
+ self,
80
+ request: ToolCallRequest,
81
+ *,
82
+ context: RunContext,
83
+ ) -> ToolCallResponse:
84
+ message = self.create_request_message(request=request)
85
+ message = await context.yield_async(InputRequired(message=message))
86
+ if message:
87
+ result = self.parse_response(message=message)
88
+ match result.action:
89
+ case "accept":
90
+ return result
91
+ case "reject":
92
+ raise ToolCallRejectionError("User has rejected the tool call")
93
+
94
+ else:
95
+ raise RuntimeError("Yield did not return a message")
96
+
97
+
98
+ class ToolCallExtensionClient(BaseExtensionClient[ToolCallExtensionSpec, NoneType]):
99
+ def create_response_message(self, *, response: ToolCallResponse, task_id: str | None):
100
+ return a2a.types.Message(
101
+ message_id=str(uuid.uuid4()),
102
+ role=a2a.types.Role.user,
103
+ parts=[],
104
+ task_id=task_id,
105
+ metadata={self.spec.URI: response.model_dump(mode="json")},
106
+ )
107
+
108
+ def parse_request(self, *, message: a2a.types.Message):
109
+ if not message or not message.metadata or not (data := message.metadata.get(self.spec.URI)):
110
+ raise ValueError("Invalid tool call request")
111
+ return ToolCallRequest.model_validate(data)
112
+
113
+ def metadata(self) -> dict[str, Any]:
114
+ return {self.spec.URI: ToolCallExtensionMetadata().model_dump(mode="json")}
@@ -0,0 +1,6 @@
1
+ # Copyright 2025 © BeeAI a Series of LF Projects, LLC
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+
5
+ class ToolCallRejectionError(RuntimeError):
6
+ pass
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
 
6
6
  import typing
7
7
  import uuid
8
- from typing import Literal
8
+ from typing import Literal, Self
9
9
 
10
10
  import pydantic
11
11
 
@@ -29,12 +29,24 @@ class VectorStoreDocument(pydantic.BaseModel):
29
29
  class VectorStoreItem(pydantic.BaseModel):
30
30
  id: str = pydantic.Field(default_factory=lambda: uuid.uuid4().hex)
31
31
  document_id: str
32
- document_type: typing.Literal["platform_file", "external"] = "platform_file"
32
+ document_type: typing.Literal["platform_file", "external"] | None = "platform_file"
33
33
  model_id: str | typing.Literal["platform"] = "platform"
34
34
  text: str
35
35
  embedding: list[float]
36
36
  metadata: Metadata | None = None
37
37
 
38
+ @pydantic.model_validator(mode="after")
39
+ def validate_document_id(self) -> Self:
40
+ """Validate that document_id is a valid UUID when document_type is platform_file."""
41
+ if self.document_type == "platform_file":
42
+ try:
43
+ _ = uuid.UUID(self.document_id)
44
+ except ValueError as ex:
45
+ raise ValueError(
46
+ f"document_id must be a valid UUID when document_type is platform_file, got: {self.document_id}"
47
+ ) from ex
48
+ return self
49
+
38
50
 
39
51
  class VectorStoreSearchResult(pydantic.BaseModel):
40
52
  item: VectorStoreItem