microsoft-agents-copilotstudio-client 0.0.0__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 (17) hide show
  1. microsoft_agents_copilotstudio_client-0.0.0/PKG-INFO +12 -0
  2. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/__init__.py +19 -0
  3. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/agent_type.py +6 -0
  4. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/connection_settings.py +32 -0
  5. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/copilot_client.py +106 -0
  6. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/direct_to_engine_connection_settings_protocol.py +25 -0
  7. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/execute_turn_request.py +6 -0
  8. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/power_platform_cloud.py +25 -0
  9. microsoft_agents_copilotstudio_client-0.0.0/microsoft/agents/copilotstudio/client/power_platform_environment.py +156 -0
  10. microsoft_agents_copilotstudio_client-0.0.0/microsoft_agents_copilotstudio_client.egg-info/PKG-INFO +12 -0
  11. microsoft_agents_copilotstudio_client-0.0.0/microsoft_agents_copilotstudio_client.egg-info/SOURCES.txt +15 -0
  12. microsoft_agents_copilotstudio_client-0.0.0/microsoft_agents_copilotstudio_client.egg-info/dependency_links.txt +1 -0
  13. microsoft_agents_copilotstudio_client-0.0.0/microsoft_agents_copilotstudio_client.egg-info/requires.txt +1 -0
  14. microsoft_agents_copilotstudio_client-0.0.0/microsoft_agents_copilotstudio_client.egg-info/top_level.txt +1 -0
  15. microsoft_agents_copilotstudio_client-0.0.0/pyproject.toml +18 -0
  16. microsoft_agents_copilotstudio_client-0.0.0/setup.cfg +4 -0
  17. microsoft_agents_copilotstudio_client-0.0.0/setup.py +11 -0
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: microsoft-agents-copilotstudio-client
3
+ Version: 0.0.0
4
+ Summary: A client library for Microsoft Agents
5
+ Author: Microsoft Corporation
6
+ Project-URL: Homepage, https://github.com/microsoft/Agents
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.9
11
+ Requires-Dist: microsoft-agents-hosting-core==0.0.0
12
+ Dynamic: requires-dist
@@ -0,0 +1,19 @@
1
+ from .agent_type import AgentType
2
+ from .connection_settings import ConnectionSettings
3
+ from .copilot_client import CopilotClient
4
+ from .direct_to_engine_connection_settings_protocol import (
5
+ DirectToEngineConnectionSettingsProtocol,
6
+ )
7
+ from .execute_turn_request import ExecuteTurnRequest
8
+ from .power_platform_cloud import PowerPlatformCloud
9
+ from .power_platform_environment import PowerPlatformEnvironment
10
+
11
+ __all__ = [
12
+ "AgentType",
13
+ "ConnectionSettings",
14
+ "CopilotClient",
15
+ "DirectToEngineConnectionSettingsProtocol",
16
+ "ExecuteTurnRequest",
17
+ "PowerPlatformCloud",
18
+ "PowerPlatformEnvironment",
19
+ ]
@@ -0,0 +1,6 @@
1
+ from enum import Enum
2
+
3
+
4
+ class AgentType(str, Enum):
5
+ PUBLISHED = "published"
6
+ PREBUILT = "prebuilt"
@@ -0,0 +1,32 @@
1
+ from typing import Optional
2
+ from .direct_to_engine_connection_settings_protocol import (
3
+ DirectToEngineConnectionSettingsProtocol,
4
+ )
5
+ from .power_platform_cloud import PowerPlatformCloud
6
+ from .agent_type import AgentType
7
+
8
+
9
+ class ConnectionSettings(DirectToEngineConnectionSettingsProtocol):
10
+ """
11
+ Connection settings for the DirectToEngineConnectionConfiguration.
12
+ """
13
+
14
+ def __init__(
15
+ self,
16
+ environment_id: str,
17
+ agent_identifier: str,
18
+ cloud: Optional[PowerPlatformCloud],
19
+ copilot_agent_type: Optional[AgentType],
20
+ custom_power_platform_cloud: Optional[str],
21
+ ) -> None:
22
+ self.environment_id = environment_id
23
+ self.agent_identifier = agent_identifier
24
+
25
+ if not self.environment_id:
26
+ raise ValueError("Environment ID must be provided")
27
+ if not self.agent_identifier:
28
+ raise ValueError("Agent Identifier must be provided")
29
+
30
+ self.cloud = cloud or PowerPlatformCloud.UNKNOWN
31
+ self.copilot_agent_type = copilot_agent_type or AgentType.PUBLISHED
32
+ self.custom_power_platform_cloud = custom_power_platform_cloud
@@ -0,0 +1,106 @@
1
+ import aiohttp
2
+ from typing import AsyncIterable, Callable, Optional
3
+
4
+ from microsoft.agents.activity import Activity, ActivityTypes, ConversationAccount
5
+
6
+ from .connection_settings import ConnectionSettings
7
+ from .execute_turn_request import ExecuteTurnRequest
8
+ from .power_platform_environment import PowerPlatformEnvironment
9
+
10
+
11
+ class CopilotClient:
12
+ EVENT_STREAM_TYPE = "text/event-stream"
13
+ APPLICATION_JSON_TYPE = "application/json"
14
+
15
+ _current_conversation_id = ""
16
+
17
+ def __init__(
18
+ self,
19
+ settings: ConnectionSettings,
20
+ token: str,
21
+ ):
22
+ self.settings = settings
23
+ self._token = token
24
+ # TODO: Add logger
25
+ # self.logger = logger
26
+ self.conversation_id = ""
27
+
28
+ async def post_request(
29
+ self, url: str, data: dict, headers: dict
30
+ ) -> AsyncIterable[Activity]:
31
+ async with aiohttp.ClientSession() as session:
32
+ async with session.post(url, json=data, headers=headers) as response:
33
+ if response.status != 200:
34
+ # self.logger(f"Error sending request: {response.status}")
35
+ raise aiohttp.ClientError(
36
+ f"Error sending request: {response.status}"
37
+ )
38
+ event_type = None
39
+ async for line in response.content:
40
+ if line.startswith(b"event:"):
41
+ event_type = line[6:].decode("utf-8").strip()
42
+ if line.startswith(b"data:") and event_type == "activity":
43
+ activity_data = line[5:].decode("utf-8").strip()
44
+ activity = Activity.model_validate_json(activity_data)
45
+
46
+ if activity.type == ActivityTypes.message:
47
+ self._current_conversation_id = activity.conversation.id
48
+
49
+ yield activity
50
+
51
+ async def start_conversation(
52
+ self, emit_start_conversation_event: bool = True
53
+ ) -> AsyncIterable[Activity]:
54
+ url = PowerPlatformEnvironment.get_copilot_studio_connection_url(
55
+ settings=self.settings
56
+ )
57
+ data = {"emitStartConversationEvent": emit_start_conversation_event}
58
+ headers = {
59
+ "Content-Type": self.APPLICATION_JSON_TYPE,
60
+ "Authorization": f"Bearer {self._token}",
61
+ "Accept": self.EVENT_STREAM_TYPE,
62
+ }
63
+
64
+ async for activity in self.post_request(url, data, headers):
65
+ yield activity
66
+
67
+ async def ask_question(
68
+ self, question: str, conversation_id: Optional[str] = None
69
+ ) -> AsyncIterable[Activity]:
70
+ activity = Activity(
71
+ type="message",
72
+ text=question,
73
+ conversation=ConversationAccount(
74
+ id=conversation_id or self._current_conversation_id
75
+ ),
76
+ )
77
+
78
+ async for activity in self.ask_question_with_activity(activity):
79
+ yield activity
80
+
81
+ async def ask_question_with_activity(
82
+ self, activity: Activity
83
+ ) -> AsyncIterable[Activity]:
84
+ if not activity:
85
+ raise ValueError(
86
+ "CopilotClient.ask_question_with_activity: Activity cannot be None"
87
+ )
88
+
89
+ local_conversation_id = (
90
+ activity.conversation.id or self._current_conversation_id
91
+ )
92
+
93
+ url = PowerPlatformEnvironment.get_copilot_studio_connection_url(
94
+ settings=self.settings, conversation_id=local_conversation_id
95
+ )
96
+ data = ExecuteTurnRequest(activity=activity).model_dump(
97
+ mode="json", by_alias=True, exclude_unset=True
98
+ )
99
+ headers = {
100
+ "Content-Type": self.APPLICATION_JSON_TYPE,
101
+ "Authorization": f"Bearer {self._token}",
102
+ "Accept": self.EVENT_STREAM_TYPE,
103
+ }
104
+
105
+ async for activity in self.post_request(url, data, headers):
106
+ yield activity
@@ -0,0 +1,25 @@
1
+ from typing import Protocol, Optional
2
+
3
+ from .agent_type import AgentType
4
+ from .power_platform_cloud import PowerPlatformCloud
5
+
6
+
7
+ class DirectToEngineConnectionSettingsProtocol(Protocol):
8
+ """
9
+ Protocol for DirectToEngineConnectionConfiguration.
10
+ """
11
+
12
+ # Schema name for the Copilot Studio Hosted Copilot.
13
+ agent_identifier: Optional[str]
14
+
15
+ # if PowerPlatformCloud is set to Other, this is the url for the power platform API endpoint.
16
+ custom_power_platform_cloud: Optional[str]
17
+
18
+ # Environment ID for the environment that hosts the agent
19
+ environment_id: Optional[str]
20
+
21
+ # Power Platform Cloud where the environment is hosted
22
+ cloud: Optional[PowerPlatformCloud]
23
+
24
+ # Type of Agent hosted in Copilot Studio
25
+ copilot_agent_type: Optional[AgentType]
@@ -0,0 +1,6 @@
1
+ from microsoft.agents.activity import AgentsModel, Activity
2
+
3
+
4
+ class ExecuteTurnRequest(AgentsModel):
5
+
6
+ activity: Activity
@@ -0,0 +1,25 @@
1
+ from enum import Enum
2
+
3
+
4
+ class PowerPlatformCloud(str, Enum):
5
+ """
6
+ Enum representing different Power Platform Clouds.
7
+ """
8
+
9
+ UNKNOWN = "Unknown"
10
+ EXP = "Exp"
11
+ DEV = "Dev"
12
+ TEST = "Test"
13
+ PREPROD = "Preprod"
14
+ FIRST_RELEASE = "FirstRelease"
15
+ PROD = "Prod"
16
+ GOV = "Gov"
17
+ HIGH = "High"
18
+ DOD = "DoD"
19
+ MOONCAKE = "Mooncake"
20
+ EX = "Ex"
21
+ RX = "Rx"
22
+ PRV = "Prv"
23
+ LOCAL = "Local"
24
+ GOV_FR = "GovFR"
25
+ OTHER = "Other"
@@ -0,0 +1,156 @@
1
+ from urllib.parse import urlparse, urlunparse
2
+ from typing import Optional
3
+ from .connection_settings import ConnectionSettings
4
+ from .agent_type import AgentType
5
+ from .power_platform_cloud import PowerPlatformCloud
6
+
7
+
8
+ # TODO: POC provides the
9
+ class PowerPlatformEnvironment:
10
+ """
11
+ Class representing the Power Platform Environment.
12
+ """
13
+
14
+ API_VERSION = "2022-03-01-preview"
15
+
16
+ @staticmethod
17
+ def get_copilot_studio_connection_url(
18
+ settings: ConnectionSettings,
19
+ conversation_id: Optional[str] = None,
20
+ agent_type: AgentType = AgentType.PUBLISHED,
21
+ cloud: PowerPlatformCloud = PowerPlatformCloud.PROD,
22
+ cloud_base_address: Optional[str] = None,
23
+ ) -> str:
24
+ if cloud == PowerPlatformCloud.OTHER and not cloud_base_address:
25
+ raise ValueError(
26
+ "cloud_base_address must be provided when PowerPlatformCloud is Other"
27
+ )
28
+ if not settings.environment_id:
29
+ raise ValueError("EnvironmentId must be provided")
30
+ if not settings.agent_identifier:
31
+ raise ValueError("AgentIdentifier must be provided")
32
+ if settings.cloud and settings.cloud != PowerPlatformCloud.UNKNOWN:
33
+ cloud = settings.cloud
34
+ if cloud == PowerPlatformCloud.OTHER:
35
+ parsed_url = urlparse(cloud_base_address)
36
+ is_absolute_url = parsed_url.scheme and parsed_url.netloc
37
+ if cloud_base_address and is_absolute_url:
38
+ pass
39
+ elif settings.custom_power_platform_cloud:
40
+ cloud_base_address = settings.custom_power_platform_cloud
41
+ else:
42
+ raise ValueError(
43
+ "Either CustomPowerPlatformCloud or cloud_base_address must be provided when PowerPlatformCloud is Other"
44
+ )
45
+ if settings.copilot_agent_type:
46
+ agent_type = settings.copilot_agent_type
47
+
48
+ cloud_base_address = cloud_base_address or "api.unknown.powerplatform.com"
49
+ host = PowerPlatformEnvironment.get_environment_endpoint(
50
+ cloud, settings.environment_id, cloud_base_address
51
+ )
52
+ return PowerPlatformEnvironment.create_uri(
53
+ settings.agent_identifier, host, agent_type, conversation_id
54
+ )
55
+
56
+ @staticmethod
57
+ def get_token_audience(
58
+ settings: Optional[ConnectionSettings] = None,
59
+ cloud: PowerPlatformCloud = PowerPlatformCloud.UNKNOWN,
60
+ cloud_base_address: Optional[str] = None,
61
+ ) -> str:
62
+ if cloud == PowerPlatformCloud.OTHER and not cloud_base_address:
63
+ raise ValueError(
64
+ "cloud_base_address must be provided when PowerPlatformCloud is Other"
65
+ )
66
+ if not settings and cloud == PowerPlatformCloud.UNKNOWN:
67
+ raise ValueError("Either settings or cloud must be provided")
68
+ if settings and settings.cloud and settings.cloud != PowerPlatformCloud.UNKNOWN:
69
+ cloud = settings.cloud
70
+ if cloud == PowerPlatformCloud.OTHER:
71
+ if cloud_base_address and urlparse(cloud_base_address).scheme:
72
+ cloud = PowerPlatformCloud.OTHER
73
+ elif (
74
+ settings
75
+ and settings.custom_power_platform_cloud
76
+ and urlparse(settings.custom_power_platform_cloud).scheme
77
+ ):
78
+ cloud = PowerPlatformCloud.OTHER
79
+ cloud_base_address = settings.custom_power_platform_cloud
80
+ else:
81
+ raise ValueError(
82
+ "Either CustomPowerPlatformCloud or cloud_base_address must be provided when PowerPlatformCloud is Other"
83
+ )
84
+
85
+ cloud_base_address = cloud_base_address or "api.unknown.powerplatform.com"
86
+ return f"https://{PowerPlatformEnvironment.get_endpoint_suffix(cloud, cloud_base_address)}/.default"
87
+
88
+ @staticmethod
89
+ def create_uri(
90
+ agent_identifier: str,
91
+ host: str,
92
+ agent_type: AgentType,
93
+ conversation_id: Optional[str],
94
+ ) -> str:
95
+ agent_path_name = (
96
+ "dataverse-backed" if agent_type == AgentType.PUBLISHED else "prebuilt"
97
+ )
98
+ path = f"/copilotstudio/{agent_path_name}/authenticated/bots/{agent_identifier}/conversations"
99
+ if conversation_id:
100
+ path += f"/{conversation_id}"
101
+ return urlunparse(
102
+ (
103
+ "https",
104
+ host,
105
+ path,
106
+ "",
107
+ f"api-version={PowerPlatformEnvironment.API_VERSION}",
108
+ "",
109
+ )
110
+ )
111
+
112
+ @staticmethod
113
+ def get_environment_endpoint(
114
+ cloud: PowerPlatformCloud,
115
+ environment_id: str,
116
+ cloud_base_address: Optional[str] = None,
117
+ ) -> str:
118
+ if cloud == PowerPlatformCloud.OTHER and not cloud_base_address:
119
+ raise ValueError(
120
+ "cloud_base_address must be provided when PowerPlatformCloud is Other"
121
+ )
122
+ cloud_base_address = cloud_base_address or "api.unknown.powerplatform.com"
123
+ normalized_resource_id = environment_id.lower().replace("-", "")
124
+ id_suffix_length = PowerPlatformEnvironment.get_id_suffix_length(cloud)
125
+ hex_prefix = normalized_resource_id[:-id_suffix_length]
126
+ hex_suffix = normalized_resource_id[-id_suffix_length:]
127
+ return f"{hex_prefix}.{hex_suffix}.environment.{PowerPlatformEnvironment.get_endpoint_suffix(cloud, cloud_base_address)}"
128
+
129
+ @staticmethod
130
+ def get_endpoint_suffix(cloud: PowerPlatformCloud, cloud_base_address: str) -> str:
131
+ return {
132
+ PowerPlatformCloud.LOCAL: "api.powerplatform.localhost",
133
+ PowerPlatformCloud.EXP: "api.exp.powerplatform.com",
134
+ PowerPlatformCloud.DEV: "api.dev.powerplatform.com",
135
+ PowerPlatformCloud.PRV: "api.prv.powerplatform.com",
136
+ PowerPlatformCloud.TEST: "api.test.powerplatform.com",
137
+ PowerPlatformCloud.PREPROD: "api.preprod.powerplatform.com",
138
+ PowerPlatformCloud.FIRST_RELEASE: "api.powerplatform.com",
139
+ PowerPlatformCloud.PROD: "api.powerplatform.com",
140
+ PowerPlatformCloud.GOV_FR: "api.gov.powerplatform.microsoft.us",
141
+ PowerPlatformCloud.GOV: "api.gov.powerplatform.microsoft.us",
142
+ PowerPlatformCloud.HIGH: "api.high.powerplatform.microsoft.us",
143
+ PowerPlatformCloud.DOD: "api.appsplatform.us",
144
+ PowerPlatformCloud.MOONCAKE: "api.powerplatform.partner.microsoftonline.cn",
145
+ PowerPlatformCloud.EX: "api.powerplatform.eaglex.ic.gov",
146
+ PowerPlatformCloud.RX: "api.powerplatform.microsoft.scloud",
147
+ PowerPlatformCloud.OTHER: cloud_base_address,
148
+ }.get(cloud, ValueError(f"Invalid cloud category value: {cloud}"))
149
+
150
+ @staticmethod
151
+ def get_id_suffix_length(cloud: PowerPlatformCloud) -> int:
152
+ return (
153
+ 2
154
+ if cloud in {PowerPlatformCloud.FIRST_RELEASE, PowerPlatformCloud.PROD}
155
+ else 1
156
+ )
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: microsoft-agents-copilotstudio-client
3
+ Version: 0.0.0
4
+ Summary: A client library for Microsoft Agents
5
+ Author: Microsoft Corporation
6
+ Project-URL: Homepage, https://github.com/microsoft/Agents
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.9
11
+ Requires-Dist: microsoft-agents-hosting-core==0.0.0
12
+ Dynamic: requires-dist
@@ -0,0 +1,15 @@
1
+ pyproject.toml
2
+ setup.py
3
+ microsoft/agents/copilotstudio/client/__init__.py
4
+ microsoft/agents/copilotstudio/client/agent_type.py
5
+ microsoft/agents/copilotstudio/client/connection_settings.py
6
+ microsoft/agents/copilotstudio/client/copilot_client.py
7
+ microsoft/agents/copilotstudio/client/direct_to_engine_connection_settings_protocol.py
8
+ microsoft/agents/copilotstudio/client/execute_turn_request.py
9
+ microsoft/agents/copilotstudio/client/power_platform_cloud.py
10
+ microsoft/agents/copilotstudio/client/power_platform_environment.py
11
+ microsoft_agents_copilotstudio_client.egg-info/PKG-INFO
12
+ microsoft_agents_copilotstudio_client.egg-info/SOURCES.txt
13
+ microsoft_agents_copilotstudio_client.egg-info/dependency_links.txt
14
+ microsoft_agents_copilotstudio_client.egg-info/requires.txt
15
+ microsoft_agents_copilotstudio_client.egg-info/top_level.txt
@@ -0,0 +1,18 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "microsoft-agents-copilotstudio-client"
7
+ dynamic = ["version", "dependencies"]
8
+ description = "A client library for Microsoft Agents"
9
+ authors = [{name = "Microsoft Corporation"}]
10
+ requires-python = ">=3.9"
11
+ classifiers = [
12
+ "Programming Language :: Python :: 3",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Operating System :: OS Independent",
15
+ ]
16
+
17
+ [project.urls]
18
+ "Homepage" = "https://github.com/microsoft/Agents"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,11 @@
1
+ from os import environ
2
+ from setuptools import setup
3
+
4
+ package_version = environ.get("PackageVersion", "0.0.0")
5
+
6
+ setup(
7
+ version=package_version,
8
+ install_requires=[
9
+ f"microsoft-agents-hosting-core=={package_version}",
10
+ ],
11
+ )