-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'fix/chore-fix' into dev/plugin-deploy
- Loading branch information
Showing
15 changed files
with
446 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from typing import Optional | ||
|
||
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator | ||
|
||
from core.tools.entities.common_entities import I18nObject | ||
from core.tools.entities.tool_entities import ToolIdentity, ToolParameter, ToolProviderIdentity | ||
|
||
|
||
class AgentProviderIdentity(ToolProviderIdentity): | ||
pass | ||
|
||
|
||
class AgentParameter(ToolParameter): | ||
pass | ||
|
||
|
||
class AgentProviderEntity(BaseModel): | ||
identity: AgentProviderIdentity | ||
plugin_id: Optional[str] = Field(None, description="The id of the plugin") | ||
|
||
|
||
class AgentIdentity(ToolIdentity): | ||
pass | ||
|
||
|
||
class AgentStrategyEntity(BaseModel): | ||
identity: AgentIdentity | ||
parameters: list[AgentParameter] = Field(default_factory=list) | ||
description: I18nObject = Field(..., description="The description of the agent strategy") | ||
output_schema: Optional[dict] = None | ||
|
||
# pydantic configs | ||
model_config = ConfigDict(protected_namespaces=()) | ||
|
||
@field_validator("parameters", mode="before") | ||
@classmethod | ||
def set_parameters(cls, v, validation_info: ValidationInfo) -> list[AgentParameter]: | ||
return v or [] | ||
|
||
|
||
class AgentProviderEntityWithPlugin(AgentProviderEntity): | ||
strategies: list[AgentStrategyEntity] = Field(default_factory=list) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from abc import ABC, abstractmethod | ||
from typing import Any, Generator, Optional, Sequence | ||
|
||
from core.agent.entities import AgentInvokeMessage | ||
from core.agent.plugin_entities import AgentParameter | ||
|
||
|
||
class BaseAgentStrategy(ABC): | ||
""" | ||
Agent Strategy | ||
""" | ||
|
||
def invoke( | ||
self, | ||
params: dict[str, Any], | ||
user_id: str, | ||
conversation_id: Optional[str] = None, | ||
app_id: Optional[str] = None, | ||
message_id: Optional[str] = None, | ||
) -> Generator[AgentInvokeMessage, None, None]: | ||
""" | ||
Invoke the agent strategy. | ||
""" | ||
yield from self._invoke(params, user_id, conversation_id, app_id, message_id) | ||
|
||
def get_parameters(self) -> Sequence[AgentParameter]: | ||
""" | ||
Get the parameters for the agent strategy. | ||
""" | ||
return [] | ||
|
||
@abstractmethod | ||
def _invoke( | ||
self, | ||
params: dict[str, Any], | ||
user_id: str, | ||
conversation_id: Optional[str] = None, | ||
app_id: Optional[str] = None, | ||
message_id: Optional[str] = None, | ||
) -> Generator[AgentInvokeMessage, None, None]: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
from typing import Any, Generator, Optional, Sequence | ||
|
||
from core.agent.entities import AgentInvokeMessage | ||
from core.agent.plugin_entities import AgentParameter, AgentStrategyEntity | ||
from core.agent.strategy.base import BaseAgentStrategy | ||
from core.plugin.manager.agent import PluginAgentManager | ||
from core.tools.plugin_tool.tool import PluginTool | ||
|
||
|
||
class PluginAgentStrategy(BaseAgentStrategy): | ||
""" | ||
Agent Strategy | ||
""" | ||
|
||
tenant_id: str | ||
plugin_unique_identifier: str | ||
declaration: AgentStrategyEntity | ||
|
||
def __init__(self, tenant_id: str, plugin_unique_identifier: str, declaration: AgentStrategyEntity): | ||
self.tenant_id = tenant_id | ||
self.plugin_unique_identifier = plugin_unique_identifier | ||
self.declaration = declaration | ||
|
||
def get_parameters(self) -> Sequence[AgentParameter]: | ||
return self.declaration.parameters | ||
|
||
def _invoke( | ||
self, | ||
params: dict[str, Any], | ||
user_id: str, | ||
conversation_id: Optional[str] = None, | ||
app_id: Optional[str] = None, | ||
message_id: Optional[str] = None, | ||
) -> Generator[AgentInvokeMessage, None, None]: | ||
""" | ||
Invoke the agent strategy. | ||
""" | ||
manager = PluginAgentManager() | ||
|
||
# convert agent parameters with File type to PluginFileEntity | ||
params = PluginTool._transform_image_parameters(params) | ||
|
||
yield from manager.invoke( | ||
tenant_id=self.tenant_id, | ||
user_id=user_id, | ||
agent_provider=self.declaration.identity.provider, | ||
agent_strategy=self.declaration.identity.name, | ||
agent_params=params, | ||
conversation_id=conversation_id, | ||
app_id=app_id, | ||
message_id=message_id, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
from collections.abc import Generator | ||
from typing import Any, Optional | ||
|
||
from core.agent.entities import AgentInvokeMessage | ||
from core.plugin.entities.plugin import GenericProviderID | ||
from core.plugin.entities.plugin_daemon import ( | ||
PluginAgentProviderEntity, | ||
) | ||
from core.plugin.manager.base import BasePluginManager | ||
|
||
|
||
class PluginAgentManager(BasePluginManager): | ||
def fetch_agent_providers(self, tenant_id: str) -> list[PluginAgentProviderEntity]: | ||
""" | ||
Fetch agent providers for the given tenant. | ||
""" | ||
|
||
def transformer(json_response: dict[str, Any]) -> dict: | ||
for provider in json_response.get("data", []): | ||
declaration = provider.get("declaration", {}) or {} | ||
provider_name = declaration.get("identity", {}).get("name") | ||
for tool in declaration.get("tools", []): | ||
tool["identity"]["provider"] = provider_name | ||
|
||
return json_response | ||
|
||
response = self._request_with_plugin_daemon_response( | ||
"GET", | ||
f"plugin/{tenant_id}/management/agents", | ||
list[PluginAgentProviderEntity], | ||
params={"page": 1, "page_size": 256}, | ||
transformer=transformer, | ||
) | ||
|
||
for provider in response: | ||
provider.declaration.identity.name = f"{provider.plugin_id}/{provider.declaration.identity.name}" | ||
|
||
# override the provider name for each tool to plugin_id/provider_name | ||
for strategy in provider.declaration.strategies: | ||
strategy.identity.provider = provider.declaration.identity.name | ||
|
||
return response | ||
|
||
def fetch_agent_provider(self, tenant_id: str, provider: str) -> PluginAgentProviderEntity: | ||
""" | ||
Fetch tool provider for the given tenant and plugin. | ||
""" | ||
agent_provider_id = GenericProviderID(provider) | ||
|
||
def transformer(json_response: dict[str, Any]) -> dict: | ||
for strategy in json_response.get("data", {}).get("declaration", {}).get("strategies", []): | ||
strategy["identity"]["provider"] = agent_provider_id.provider_name | ||
|
||
return json_response | ||
|
||
response = self._request_with_plugin_daemon_response( | ||
"GET", | ||
f"plugin/{tenant_id}/management/agent", | ||
PluginAgentProviderEntity, | ||
params={"provider": agent_provider_id.provider_name, "plugin_id": agent_provider_id.plugin_id}, | ||
transformer=transformer, | ||
) | ||
|
||
response.declaration.identity.name = f"{response.plugin_id}/{response.declaration.identity.name}" | ||
|
||
# override the provider name for each tool to plugin_id/provider_name | ||
for strategy in response.declaration.strategies: | ||
strategy.identity.provider = response.declaration.identity.name | ||
|
||
return response | ||
|
||
def invoke( | ||
self, | ||
tenant_id: str, | ||
user_id: str, | ||
agent_provider: str, | ||
agent_strategy: str, | ||
agent_params: dict[str, Any], | ||
conversation_id: Optional[str] = None, | ||
app_id: Optional[str] = None, | ||
message_id: Optional[str] = None, | ||
) -> Generator[AgentInvokeMessage, None, None]: | ||
""" | ||
Invoke the agent with the given tenant, user, plugin, provider, name and parameters. | ||
""" | ||
|
||
agent_provider_id = GenericProviderID(agent_provider) | ||
|
||
response = self._request_with_plugin_daemon_response_stream( | ||
"POST", | ||
f"plugin/{tenant_id}/dispatch/agent/invoke", | ||
AgentInvokeMessage, | ||
data={ | ||
"user_id": user_id, | ||
"conversation_id": conversation_id, | ||
"app_id": app_id, | ||
"message_id": message_id, | ||
"data": { | ||
"provider": agent_provider_id.provider_name, | ||
"strategy": agent_strategy, | ||
"agent_params": agent_params, | ||
}, | ||
}, | ||
headers={ | ||
"X-Plugin-ID": agent_provider_id.plugin_id, | ||
"Content-Type": "application/json", | ||
}, | ||
) | ||
return response |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .agent_node import AgentNode | ||
|
||
__all__ = ["AgentNode"] |
Oops, something went wrong.