agentstack-sdk 0.4.2rc9__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.
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/PKG-INFO +1 -1
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/pyproject.toml +2 -3
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/__init__.py +1 -0
- agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/tools/__init__.py +5 -0
- agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/tools/call.py +114 -0
- agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/tools/exceptions.py +6 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/__init__.py +1 -0
- agentstack_sdk-0.4.3/src/agentstack_sdk/a2a/extensions/ui/error.py +213 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/types.py +7 -1
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/vector_store.py +14 -2
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/agent.py +131 -113
- agentstack_sdk-0.4.3/src/agentstack_sdk/server/constants.py +12 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/context.py +5 -0
- agentstack_sdk-0.4.2rc9/src/agentstack_sdk/server/constants.py +0 -8
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/README.md +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/oauth.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/storage/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/storage/base.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/oauth/storage/memory.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/secrets/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/secrets/secrets.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/base.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/common/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/common/form.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/exceptions.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/embedding.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/form.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/llm.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/mcp.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/platform.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/agent_detail.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/canvas.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/citation.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/form_request.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/settings.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/trajectory.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/client.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/common.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/configuration.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/context.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/file.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/model_provider.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/provider.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/provider_build.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/types.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/user.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/variables.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/py.typed +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/app.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/dependencies.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/server.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/context_store.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/memory_context_store.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/platform_context_store.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/telemetry.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/utils.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/__init__.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/file.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/httpx.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/logging.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/resource_context.py +0 -0
- {agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentstack-sdk"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.3"
|
|
4
4
|
description = "Agent Stack SDK"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "IBM Corp." }]
|
|
@@ -26,8 +26,7 @@ dependencies = [
|
|
|
26
26
|
|
|
27
27
|
[dependency-groups]
|
|
28
28
|
dev = [
|
|
29
|
-
"beeai-framework[duckduckgo,wikipedia]>=0.1.
|
|
30
|
-
"ddgs>=9.9.1",
|
|
29
|
+
"beeai-framework[duckduckgo,wikipedia]>=0.1.70",
|
|
31
30
|
"pyright>=1.1.403",
|
|
32
31
|
"pytest>=8.4.1",
|
|
33
32
|
"pytest-asyncio>=1.1.0",
|
|
@@ -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,213 @@
|
|
|
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 contextvars
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
import traceback
|
|
10
|
+
from collections.abc import AsyncIterator
|
|
11
|
+
from contextlib import asynccontextmanager
|
|
12
|
+
from types import NoneType
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
import pydantic
|
|
16
|
+
|
|
17
|
+
from agentstack_sdk.a2a.extensions.base import (
|
|
18
|
+
BaseExtensionClient,
|
|
19
|
+
BaseExtensionServer,
|
|
20
|
+
BaseExtensionSpec,
|
|
21
|
+
)
|
|
22
|
+
from agentstack_sdk.a2a.types import AgentMessage, JsonDict, Metadata
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Error(pydantic.BaseModel):
|
|
28
|
+
"""
|
|
29
|
+
Represents error information for displaying exceptions in the UI.
|
|
30
|
+
|
|
31
|
+
This extension helps display errors in a user-friendly way with:
|
|
32
|
+
- A clear error title (exception type)
|
|
33
|
+
- A descriptive error message
|
|
34
|
+
|
|
35
|
+
Visually, this may appear as an error card in the UI.
|
|
36
|
+
|
|
37
|
+
Properties:
|
|
38
|
+
- title: Title of the error (typically the exception class name).
|
|
39
|
+
- message: The error message describing what went wrong.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
title: str
|
|
43
|
+
message: str
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ErrorGroup(pydantic.BaseModel):
|
|
47
|
+
"""
|
|
48
|
+
Represents a group of errors.
|
|
49
|
+
|
|
50
|
+
Properties:
|
|
51
|
+
- message: A message describing the group of errors.
|
|
52
|
+
- errors: A list of error objects.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
message: str
|
|
56
|
+
errors: list[Error]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ErrorMetadata(pydantic.BaseModel):
|
|
60
|
+
"""
|
|
61
|
+
Metadata containing an error (or group of errors) and an optional stack trace.
|
|
62
|
+
|
|
63
|
+
Properties:
|
|
64
|
+
- error: The error object or group of errors.
|
|
65
|
+
- stack_trace: Optional formatted stack trace for debugging.
|
|
66
|
+
- context: Optional context dictionary.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
error: Error | ErrorGroup
|
|
70
|
+
stack_trace: str | None = None
|
|
71
|
+
context: JsonDict | None = None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ErrorExtensionParams(pydantic.BaseModel):
|
|
75
|
+
"""
|
|
76
|
+
Configuration parameters for the error extension.
|
|
77
|
+
|
|
78
|
+
Properties:
|
|
79
|
+
- include_stacktrace: Whether to include stack traces in error messages (default: False).
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
include_stacktrace: bool = False
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ErrorExtensionSpec(BaseExtensionSpec[ErrorExtensionParams]):
|
|
86
|
+
URI: str = "https://a2a-extensions.agentstack.beeai.dev/ui/error/v1"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _format_stacktrace(exc: BaseException, include_cause: bool = True) -> str:
|
|
90
|
+
"""Format exception with full traceback including nested causes."""
|
|
91
|
+
return "".join(traceback.format_exception(type(exc), exc, exc.__traceback__, chain=include_cause))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _extract_error(exc: BaseException) -> Error | ErrorGroup:
|
|
95
|
+
"""
|
|
96
|
+
Extract error information from an exception, handling:
|
|
97
|
+
- BaseExceptionGroup (returns ErrorGroup)
|
|
98
|
+
- FrameworkError from beeai_framework (uses .explain() method)
|
|
99
|
+
"""
|
|
100
|
+
# Handle BaseExceptionGroup by recursively extracting errors from each exception
|
|
101
|
+
if isinstance(exc, BaseExceptionGroup):
|
|
102
|
+
errors: list[Error] = []
|
|
103
|
+
for sub_exc in exc.exceptions:
|
|
104
|
+
extracted = _extract_error(sub_exc)
|
|
105
|
+
if isinstance(extracted, ErrorGroup):
|
|
106
|
+
errors.extend(extracted.errors)
|
|
107
|
+
else:
|
|
108
|
+
errors.append(extracted)
|
|
109
|
+
return ErrorGroup(message=str(exc), errors=errors)
|
|
110
|
+
|
|
111
|
+
# Try to handle FrameworkError if beeai_framework is available
|
|
112
|
+
try:
|
|
113
|
+
from beeai_framework.errors import FrameworkError
|
|
114
|
+
|
|
115
|
+
if isinstance(exc, FrameworkError):
|
|
116
|
+
# FrameworkError has special .explain() method
|
|
117
|
+
return Error(title=exc.name(), message=exc.explain())
|
|
118
|
+
except ImportError:
|
|
119
|
+
# beeai_framework not installed, continue with standard handling
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
return Error(title=type(exc).__name__, message=str(exc))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class ErrorExtensionServer(BaseExtensionServer[ErrorExtensionSpec, NoneType]):
|
|
126
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
127
|
+
super().__init__(*args, **kwargs)
|
|
128
|
+
# Server-scoped ContextVar for request-scoped error context
|
|
129
|
+
self._error_context_var: contextvars.ContextVar[JsonDict] = contextvars.ContextVar("error_context")
|
|
130
|
+
|
|
131
|
+
@asynccontextmanager
|
|
132
|
+
async def lifespan(self) -> AsyncIterator[None]:
|
|
133
|
+
"""Set up request-scoped error context using ContextVar."""
|
|
134
|
+
# Set an empty dict for this request's context
|
|
135
|
+
token = self._error_context_var.set({})
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
yield
|
|
139
|
+
finally:
|
|
140
|
+
self._error_context_var.reset(token)
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def context(self) -> JsonDict:
|
|
144
|
+
"""Get the current request's error context."""
|
|
145
|
+
try:
|
|
146
|
+
return self._error_context_var.get()
|
|
147
|
+
except LookupError:
|
|
148
|
+
# Fallback for when lifespan hasn't been entered yet
|
|
149
|
+
logger.warning(
|
|
150
|
+
"Attempted to use error context when the error extension is not initialized. Make sure to add the ErrorExtensionServer to the agent dependencies."
|
|
151
|
+
)
|
|
152
|
+
return {}
|
|
153
|
+
|
|
154
|
+
def error_metadata(self, error: BaseException) -> Metadata[str, Any]:
|
|
155
|
+
"""
|
|
156
|
+
Create metadata for an error.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
error: The exception to convert to metadata
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
Metadata dictionary with error information
|
|
163
|
+
"""
|
|
164
|
+
error_data = _extract_error(error)
|
|
165
|
+
stack_trace = _format_stacktrace(error) if self.spec.params.include_stacktrace else None
|
|
166
|
+
return Metadata(
|
|
167
|
+
{
|
|
168
|
+
self.spec.URI: ErrorMetadata(
|
|
169
|
+
error=error_data,
|
|
170
|
+
stack_trace=stack_trace,
|
|
171
|
+
context=self.context or None,
|
|
172
|
+
).model_dump(mode="json")
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
def message(
|
|
177
|
+
self,
|
|
178
|
+
error: BaseException,
|
|
179
|
+
) -> AgentMessage:
|
|
180
|
+
"""
|
|
181
|
+
Create an AgentMessage with error metadata and serialized text representation.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
error: The exception to include in the message
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
AgentMessage with error metadata and markdown-formatted text
|
|
188
|
+
"""
|
|
189
|
+
metadata = self.error_metadata(error)
|
|
190
|
+
error_metadata = ErrorMetadata.model_validate(metadata[self.spec.URI])
|
|
191
|
+
|
|
192
|
+
# Serialize to markdown for display
|
|
193
|
+
text_lines: list[str] = []
|
|
194
|
+
if isinstance(error_metadata.error, ErrorGroup):
|
|
195
|
+
text_lines.append(f"## {error_metadata.error.message}\n")
|
|
196
|
+
for err in error_metadata.error.errors:
|
|
197
|
+
text_lines.append(f"### {err.title}\n{err.message}")
|
|
198
|
+
else:
|
|
199
|
+
text_lines.append(f"## {error_metadata.error.title}\n{error_metadata.error.message}")
|
|
200
|
+
|
|
201
|
+
# Add context if present
|
|
202
|
+
if error_metadata.context:
|
|
203
|
+
text_lines.append(f"## Context\n```json\n{json.dumps(error_metadata.context, indent=2)}\n```")
|
|
204
|
+
|
|
205
|
+
if error_metadata.stack_trace:
|
|
206
|
+
text_lines.append(f"## Stack Trace\n```\n{error_metadata.stack_trace}\n```")
|
|
207
|
+
|
|
208
|
+
text = "\n\n".join(text_lines)
|
|
209
|
+
|
|
210
|
+
return AgentMessage(text=text, metadata=metadata)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class ErrorExtensionClient(BaseExtensionClient[ErrorExtensionSpec, ErrorMetadata]): ...
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import typing
|
|
4
4
|
import uuid
|
|
5
|
-
from typing import Generic, Literal, TypeAlias
|
|
5
|
+
from typing import Generic, Literal, TypeAlias, TypeAliasType, Union
|
|
6
6
|
|
|
7
7
|
from a2a.types import (
|
|
8
8
|
Artifact,
|
|
@@ -104,3 +104,9 @@ class InputRequired(TaskStatus):
|
|
|
104
104
|
|
|
105
105
|
class AuthRequired(InputRequired):
|
|
106
106
|
state: Literal[TaskState.auth_required] = TaskState.auth_required # pyright: ignore [reportIncompatibleVariableOverride]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
JsonDict = TypeAliasType(
|
|
110
|
+
"JsonDict",
|
|
111
|
+
"Union[dict[str, JsonDict], list[JsonDict], str, int, float, bool, None]", # pyright: ignore[reportDeprecated] # noqa: UP007
|
|
112
|
+
)
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/vector_store.py
RENAMED
|
@@ -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
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
import asyncio
|
|
5
5
|
import inspect
|
|
6
|
-
import json
|
|
7
6
|
from asyncio import CancelledError
|
|
8
7
|
from collections.abc import AsyncGenerator, AsyncIterator, Callable, Generator
|
|
9
8
|
from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager
|
|
@@ -37,14 +36,14 @@ from a2a.types import (
|
|
|
37
36
|
)
|
|
38
37
|
|
|
39
38
|
from agentstack_sdk.a2a.extensions.ui.agent_detail import AgentDetail, AgentDetailExtensionSpec
|
|
40
|
-
from agentstack_sdk.a2a.
|
|
41
|
-
from agentstack_sdk.
|
|
39
|
+
from agentstack_sdk.a2a.extensions.ui.error import ErrorExtensionParams, ErrorExtensionServer, ErrorExtensionSpec
|
|
40
|
+
from agentstack_sdk.a2a.types import AgentMessage, ArtifactChunk, Metadata, RunYield, RunYieldResume
|
|
41
|
+
from agentstack_sdk.server.constants import _IMPLICIT_DEPENDENCY_PREFIX, DEFAULT_ERROR_EXTENSION
|
|
42
42
|
from agentstack_sdk.server.context import RunContext
|
|
43
43
|
from agentstack_sdk.server.dependencies import extract_dependencies
|
|
44
44
|
from agentstack_sdk.server.store.context_store import ContextStore
|
|
45
45
|
from agentstack_sdk.server.utils import cancel_task, close_queue
|
|
46
46
|
from agentstack_sdk.util.logging import logger
|
|
47
|
-
from agentstack_sdk.util.utils import extract_messages
|
|
48
47
|
|
|
49
48
|
AgentFunction: TypeAlias = Callable[[], AsyncGenerator[RunYield, RunYieldResume]]
|
|
50
49
|
AgentFunctionFactory: TypeAlias = Callable[
|
|
@@ -124,9 +123,14 @@ def agent(
|
|
|
124
123
|
resolved_name = name or fn.__name__
|
|
125
124
|
resolved_description = description or fn.__doc__ or ""
|
|
126
125
|
|
|
126
|
+
# Check if user has provided an ErrorExtensionServer, if not add default
|
|
127
|
+
has_error_extension = any(isinstance(ext, ErrorExtensionServer) for ext in sdk_extensions)
|
|
128
|
+
error_extension_spec = ErrorExtensionSpec(ErrorExtensionParams()) if not has_error_extension else None
|
|
129
|
+
|
|
127
130
|
capabilities.extensions = [
|
|
128
131
|
*(capabilities.extensions or []),
|
|
129
132
|
*(AgentDetailExtensionSpec(detail).to_agent_card_extensions()),
|
|
133
|
+
*(error_extension_spec.to_agent_card_extensions() if error_extension_spec else []),
|
|
130
134
|
*(e_card for ext in sdk_extensions for e_card in ext.spec.to_agent_card_extensions()),
|
|
131
135
|
]
|
|
132
136
|
|
|
@@ -232,6 +236,11 @@ def agent(
|
|
|
232
236
|
depends(message, context, dependency_args)
|
|
233
237
|
)
|
|
234
238
|
|
|
239
|
+
context._error_extension = next(
|
|
240
|
+
(ext for ext in dependency_args.values() if isinstance(ext, ErrorExtensionServer)),
|
|
241
|
+
DEFAULT_ERROR_EXTENSION,
|
|
242
|
+
)
|
|
243
|
+
|
|
235
244
|
context._store = await context_store.create(
|
|
236
245
|
context_id=request_context.context_id,
|
|
237
246
|
initialized_dependencies=list(dependency_args.values()),
|
|
@@ -339,124 +348,133 @@ class Executor(AgentExecutor):
|
|
|
339
348
|
deep=True, update={"context_id": task_updater.context_id, "task_id": task_updater.task_id}
|
|
340
349
|
)
|
|
341
350
|
|
|
351
|
+
run_context: RunContext | None = None
|
|
342
352
|
try:
|
|
343
|
-
async with self._agent_executor_span(task_updater, context, context_store) as (execute_fn,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
artifact_id=artifact_id,
|
|
376
|
-
name=name,
|
|
377
|
-
metadata=metadata,
|
|
378
|
-
last_chunk=last_chunk,
|
|
379
|
-
):
|
|
380
|
-
await task_updater.add_artifact(
|
|
381
|
-
parts=cast(list[Part], parts),
|
|
382
|
-
artifact_id=artifact_id,
|
|
383
|
-
name=name,
|
|
384
|
-
metadata=metadata,
|
|
385
|
-
append=artifact_id in opened_artifacts,
|
|
386
|
-
last_chunk=last_chunk,
|
|
387
|
-
)
|
|
388
|
-
opened_artifacts.add(artifact_id)
|
|
389
|
-
case Artifact(parts=parts, artifact_id=artifact_id, name=name, metadata=metadata):
|
|
390
|
-
await task_updater.add_artifact(
|
|
353
|
+
async with self._agent_executor_span(task_updater, context, context_store) as (execute_fn, run_context):
|
|
354
|
+
try:
|
|
355
|
+
agent_generator_fn = execute_fn()
|
|
356
|
+
|
|
357
|
+
await task_updater.start_work()
|
|
358
|
+
value: RunYieldResume = None
|
|
359
|
+
opened_artifacts: set[str] = set()
|
|
360
|
+
while True:
|
|
361
|
+
# update invocation time
|
|
362
|
+
self._running_tasks[task_updater.task_id]["last_invocation"] = datetime.now()
|
|
363
|
+
|
|
364
|
+
yielded_value = await agent_generator_fn.asend(value)
|
|
365
|
+
|
|
366
|
+
match yielded_value:
|
|
367
|
+
case str(text):
|
|
368
|
+
await task_updater.update_status(
|
|
369
|
+
TaskState.working,
|
|
370
|
+
message=task_updater.new_agent_message(parts=[Part(root=TextPart(text=text))]),
|
|
371
|
+
)
|
|
372
|
+
case Part(root=part) | (TextPart() | FilePart() | DataPart() as part):
|
|
373
|
+
await task_updater.update_status(
|
|
374
|
+
TaskState.working,
|
|
375
|
+
message=task_updater.new_agent_message(parts=[Part(root=part)]),
|
|
376
|
+
)
|
|
377
|
+
case FileWithBytes() | FileWithUri() as file:
|
|
378
|
+
await task_updater.update_status(
|
|
379
|
+
TaskState.working,
|
|
380
|
+
message=task_updater.new_agent_message(parts=[Part(root=FilePart(file=file))]),
|
|
381
|
+
)
|
|
382
|
+
case Message() as message:
|
|
383
|
+
await task_updater.update_status(TaskState.working, message=with_context(message))
|
|
384
|
+
case ArtifactChunk(
|
|
391
385
|
parts=parts,
|
|
392
386
|
artifact_id=artifact_id,
|
|
393
387
|
name=name,
|
|
394
388
|
metadata=metadata,
|
|
395
|
-
last_chunk=
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
389
|
+
last_chunk=last_chunk,
|
|
390
|
+
):
|
|
391
|
+
await task_updater.add_artifact(
|
|
392
|
+
parts=cast(list[Part], parts),
|
|
393
|
+
artifact_id=artifact_id,
|
|
394
|
+
name=name,
|
|
395
|
+
metadata=metadata,
|
|
396
|
+
append=artifact_id in opened_artifacts,
|
|
397
|
+
last_chunk=last_chunk,
|
|
398
|
+
)
|
|
399
|
+
opened_artifacts.add(artifact_id)
|
|
400
|
+
case Artifact(parts=parts, artifact_id=artifact_id, name=name, metadata=metadata):
|
|
401
|
+
await task_updater.add_artifact(
|
|
402
|
+
parts=parts,
|
|
403
|
+
artifact_id=artifact_id,
|
|
404
|
+
name=name,
|
|
405
|
+
metadata=metadata,
|
|
406
|
+
last_chunk=True,
|
|
407
|
+
append=False,
|
|
408
|
+
)
|
|
409
|
+
case TaskStatus(state=TaskState.input_required, message=message, timestamp=timestamp):
|
|
410
|
+
await task_updater.requires_input(message=with_context(message), final=True)
|
|
411
|
+
value = cast(RunYieldResume, await resume_queue.dequeue_event())
|
|
412
|
+
resume_queue.task_done()
|
|
413
|
+
continue
|
|
414
|
+
case TaskStatus(state=TaskState.auth_required, message=message, timestamp=timestamp):
|
|
415
|
+
await task_updater.requires_auth(message=with_context(message), final=True)
|
|
416
|
+
value = cast(RunYieldResume, await resume_queue.dequeue_event())
|
|
417
|
+
resume_queue.task_done()
|
|
418
|
+
continue
|
|
419
|
+
case TaskStatus(state=state, message=message, timestamp=timestamp):
|
|
420
|
+
await task_updater.update_status(
|
|
421
|
+
state=state, message=with_context(message), timestamp=timestamp
|
|
422
|
+
)
|
|
423
|
+
case TaskStatusUpdateEvent(
|
|
424
|
+
status=TaskStatus(state=state, message=message, timestamp=timestamp),
|
|
421
425
|
final=final,
|
|
422
426
|
metadata=metadata,
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
name=name,
|
|
433
|
-
metadata=metadata,
|
|
427
|
+
):
|
|
428
|
+
await task_updater.update_status(
|
|
429
|
+
state=state,
|
|
430
|
+
message=with_context(message),
|
|
431
|
+
timestamp=timestamp,
|
|
432
|
+
final=final,
|
|
433
|
+
metadata=metadata,
|
|
434
|
+
)
|
|
435
|
+
case TaskArtifactUpdateEvent(
|
|
436
|
+
artifact=Artifact(artifact_id=artifact_id, name=name, metadata=metadata, parts=parts),
|
|
434
437
|
append=append,
|
|
435
438
|
last_chunk=last_chunk,
|
|
436
|
-
)
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
439
|
+
):
|
|
440
|
+
await task_updater.add_artifact(
|
|
441
|
+
parts=parts,
|
|
442
|
+
artifact_id=artifact_id,
|
|
443
|
+
name=name,
|
|
444
|
+
metadata=metadata,
|
|
445
|
+
append=append,
|
|
446
|
+
last_chunk=last_chunk,
|
|
447
|
+
)
|
|
448
|
+
case Metadata() as metadata:
|
|
449
|
+
await task_updater.update_status(
|
|
450
|
+
state=TaskState.working,
|
|
451
|
+
message=task_updater.new_agent_message(parts=[], metadata=metadata),
|
|
452
|
+
)
|
|
453
|
+
case dict() as data:
|
|
454
|
+
await task_updater.update_status(
|
|
455
|
+
state=TaskState.working,
|
|
456
|
+
message=task_updater.new_agent_message(parts=[Part(root=DataPart(data=data))]),
|
|
457
|
+
)
|
|
458
|
+
case Exception() as ex:
|
|
459
|
+
raise ex
|
|
460
|
+
case _:
|
|
461
|
+
raise ValueError(f"Invalid value yielded from agent: {type(yielded_value)}")
|
|
462
|
+
value = None
|
|
463
|
+
except StopAsyncIteration:
|
|
464
|
+
await task_updater.complete()
|
|
465
|
+
except CancelledError:
|
|
466
|
+
await task_updater.cancel()
|
|
467
|
+
except Exception as ex:
|
|
468
|
+
logger.error("Error when executing agent", exc_info=ex)
|
|
469
|
+
try:
|
|
470
|
+
error_extension = run_context._error_extension if run_context else None
|
|
471
|
+
error_extension = error_extension if error_extension is not None else DEFAULT_ERROR_EXTENSION
|
|
472
|
+
error_msg = error_extension.message(ex)
|
|
473
|
+
except Exception as error_exc:
|
|
474
|
+
error_msg = AgentMessage(
|
|
475
|
+
text=(f"Failed to create error message: {error_exc!s}\noriginal exc: {ex!s}")
|
|
476
|
+
)
|
|
477
|
+
await task_updater.failed(error_msg)
|
|
460
478
|
finally: # cleanup
|
|
461
479
|
await cancel_task(cancellation_task)
|
|
462
480
|
is_cancelling = bool(current_task.cancelling())
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Copyright 2025 © BeeAI a Series of LF Projects, LLC
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
from typing import Final
|
|
5
|
+
|
|
6
|
+
from agentstack_sdk.a2a.extensions.ui.error import ErrorExtensionParams, ErrorExtensionServer, ErrorExtensionSpec
|
|
7
|
+
|
|
8
|
+
_IMPLICIT_DEPENDENCY_PREFIX: Final = "___server_dep"
|
|
9
|
+
|
|
10
|
+
DEFAULT_ERROR_EXTENSION: Final = ErrorExtensionServer(ErrorExtensionSpec(ErrorExtensionParams()))
|
|
11
|
+
|
|
12
|
+
__all__ = []
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
from collections.abc import AsyncIterator
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
6
7
|
|
|
7
8
|
import janus
|
|
8
9
|
from a2a.server.context import ServerCallContext
|
|
@@ -13,6 +14,9 @@ from pydantic import BaseModel, PrivateAttr
|
|
|
13
14
|
from agentstack_sdk.a2a.types import RunYield, RunYieldResume
|
|
14
15
|
from agentstack_sdk.server.store.context_store import ContextStoreInstance
|
|
15
16
|
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from agentstack_sdk.a2a.extensions.ui.error import ErrorExtensionServer
|
|
19
|
+
|
|
16
20
|
|
|
17
21
|
class RunContext(BaseModel, arbitrary_types_allowed=True):
|
|
18
22
|
configuration: MessageSendConfiguration | None = None
|
|
@@ -26,6 +30,7 @@ class RunContext(BaseModel, arbitrary_types_allowed=True):
|
|
|
26
30
|
_store: ContextStoreInstance | None = PrivateAttr(None)
|
|
27
31
|
_yield_queue: janus.Queue[RunYield] = PrivateAttr(default_factory=janus.Queue)
|
|
28
32
|
_yield_resume_queue: janus.Queue[RunYieldResume] = PrivateAttr(default_factory=janus.Queue)
|
|
33
|
+
_error_extension: "ErrorExtensionServer | None" = PrivateAttr(None)
|
|
29
34
|
|
|
30
35
|
async def store(self, data: Message | Artifact):
|
|
31
36
|
if not self._store:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/auth/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/common/form.py
RENAMED
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/form.py
RENAMED
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/llm.py
RENAMED
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/services/mcp.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/canvas.py
RENAMED
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/citation.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/settings.py
RENAMED
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/a2a/extensions/ui/trajectory.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/model_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/platform/provider_build.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/__init__.py
RENAMED
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/server/store/context_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentstack_sdk-0.4.2rc9 → agentstack_sdk-0.4.3}/src/agentstack_sdk/util/resource_context.py
RENAMED
|
File without changes
|
|
File without changes
|