@microsoft/agents-hosting 1.6.0-beta.9.gce9d8facd2 → 1.7.0-beta.1.g8bcd4f11a7
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.
- package/dist/package.json +4 -9
- package/dist/src/agent-client/agentClient.js +2 -2
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.js +2 -2
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/app/agentApplication.js +28 -2
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/agentApplicationOptions.d.ts +10 -0
- package/dist/src/app/attachmentDownloader.js +5 -10
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/auth/authorizationManager.d.ts +4 -0
- package/dist/src/app/auth/authorizationManager.js +94 -67
- package/dist/src/app/auth/authorizationManager.js.map +1 -1
- package/dist/src/app/auth/handlers/azureBotAuthorization.js +2 -2
- package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -1
- package/dist/src/app/proactive/createConversationOptionsBuilder.js +10 -6
- package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -1
- package/dist/src/app/proactive/proactive.d.ts +1 -0
- package/dist/src/app/proactive/proactive.js +30 -15
- package/dist/src/app/proactive/proactive.js.map +1 -1
- package/dist/src/app/streaming/streamingResponse.d.ts +11 -0
- package/dist/src/app/streaming/streamingResponse.js +21 -0
- package/dist/src/app/streaming/streamingResponse.js.map +1 -1
- package/dist/src/app/teamsAttachmentDownloader.js +6 -14
- package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
- package/dist/src/auth/MemoryCache.d.ts +2 -1
- package/dist/src/auth/MemoryCache.js +7 -1
- package/dist/src/auth/MemoryCache.js.map +1 -1
- package/dist/src/auth/authConfiguration.d.ts +2 -143
- package/dist/src/auth/authConfiguration.js +336 -257
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/authConstants.d.ts +7 -7
- package/dist/src/auth/authConstants.js.map +1 -1
- package/dist/src/auth/connectionManager.d.ts +92 -0
- package/dist/src/auth/{msalConnectionManager.js → connectionManager.js} +48 -33
- package/dist/src/auth/connectionManager.js.map +1 -0
- package/dist/src/auth/index.d.ts +5 -3
- package/dist/src/auth/index.js +5 -3
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.d.ts +6 -0
- package/dist/src/auth/jwt-middleware.js +34 -2
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msal/msalConnectionManager.d.ts +17 -0
- package/dist/src/auth/msal/msalConnectionManager.js +50 -0
- package/dist/src/auth/msal/msalConnectionManager.js.map +1 -0
- package/dist/src/auth/msal/msalConnectionSettings.d.ts +68 -0
- package/dist/src/auth/msal/msalConnectionSettings.js +7 -0
- package/dist/src/auth/msal/msalConnectionSettings.js.map +1 -0
- package/dist/src/auth/{msalTokenCredential.d.ts → msal/msalTokenCredential.d.ts} +1 -1
- package/dist/src/auth/{msalTokenCredential.js → msal/msalTokenCredential.js} +2 -2
- package/dist/src/auth/msal/msalTokenCredential.js.map +1 -0
- package/dist/src/auth/{msalTokenProvider.d.ts → msal/msalTokenProvider.d.ts} +30 -3
- package/dist/src/auth/msal/msalTokenProvider.js +733 -0
- package/dist/src/auth/msal/msalTokenProvider.js.map +1 -0
- package/dist/src/auth/settings.d.ts +336 -0
- package/dist/src/auth/settings.js +202 -0
- package/dist/src/auth/settings.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.d.ts +74 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js +181 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.d.ts +65 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.js +7 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.d.ts +95 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.js +406 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarModels.d.ts +110 -0
- package/dist/src/auth/sidecar/sidecarModels.js +48 -0
- package/dist/src/auth/sidecar/sidecarModels.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.d.ts +13 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.js +39 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.js.map +1 -0
- package/dist/src/cloudAdapter.d.ts +58 -1
- package/dist/src/cloudAdapter.js +233 -53
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +12 -8
- package/dist/src/connector-client/connectorClient.js +99 -82
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/dist/src/errorHelper.js +181 -7
- package/dist/src/errorHelper.js.map +1 -1
- package/dist/src/getProductInfo.d.ts +23 -0
- package/dist/src/getProductInfo.js +71 -1
- package/dist/src/getProductInfo.js.map +1 -1
- package/dist/src/headerPropagation.d.ts +17 -2
- package/dist/src/headerPropagation.js +46 -24
- package/dist/src/headerPropagation.js.map +1 -1
- package/dist/src/httpClient.d.ts +60 -0
- package/dist/src/httpClient.js +173 -0
- package/dist/src/httpClient.js.map +1 -0
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +8 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +17 -4
- package/dist/src/oauth/userTokenClient.js +119 -80
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/observability/traces.d.ts +11 -4
- package/dist/src/observability/traces.js +39 -7
- package/dist/src/observability/traces.js.map +1 -1
- package/dist/src/utils/env.d.ts +50 -0
- package/dist/src/utils/env.js +113 -0
- package/dist/src/utils/env.js.map +1 -0
- package/dist/src/utils.d.ts +10 -0
- package/dist/src/utils.js +18 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +4 -9
- package/src/agent-client/agentClient.ts +2 -2
- package/src/agent-client/agentResponseHandler.ts +2 -2
- package/src/app/agentApplication.ts +30 -3
- package/src/app/agentApplicationOptions.ts +11 -0
- package/src/app/attachmentDownloader.ts +6 -8
- package/src/app/auth/authorizationManager.ts +84 -41
- package/src/app/auth/handlers/azureBotAuthorization.ts +2 -2
- package/src/app/proactive/createConversationOptionsBuilder.ts +8 -4
- package/src/app/proactive/proactive.ts +39 -23
- package/src/app/streaming/streamingResponse.ts +24 -1
- package/src/app/teamsAttachmentDownloader.ts +7 -11
- package/src/auth/MemoryCache.ts +7 -1
- package/src/auth/authConfiguration.ts +350 -356
- package/src/auth/authConstants.ts +7 -7
- package/src/auth/{msalConnectionManager.ts → connectionManager.ts} +65 -44
- package/src/auth/index.ts +5 -3
- package/src/auth/jwt-middleware.ts +32 -2
- package/src/auth/msal/msalConnectionManager.ts +55 -0
- package/src/auth/msal/msalConnectionSettings.ts +79 -0
- package/src/auth/{msalTokenCredential.ts → msal/msalTokenCredential.ts} +2 -1
- package/src/auth/msal/msalTokenProvider.ts +881 -0
- package/src/auth/settings.ts +378 -0
- package/src/auth/sidecar/sidecarAuthProvider.ts +234 -0
- package/src/auth/sidecar/sidecarConnectionSettings.ts +72 -0
- package/src/auth/sidecar/sidecarHttpClient.ts +443 -0
- package/src/auth/sidecar/sidecarModels.ts +153 -0
- package/src/auth/sidecar/sidecarTokenExpiry.ts +35 -0
- package/src/cloudAdapter.ts +292 -13
- package/src/connector-client/connectorClient.ts +116 -94
- package/src/errorHelper.ts +206 -7
- package/src/getProductInfo.ts +79 -1
- package/src/headerPropagation.ts +55 -23
- package/src/httpClient.ts +223 -0
- package/src/index.ts +6 -2
- package/src/oauth/userTokenClient.ts +137 -84
- package/src/observability/traces.ts +39 -8
- package/src/utils/env.ts +105 -0
- package/src/utils.ts +14 -0
- package/dist/src/auth/msalConnectionManager.d.ts +0 -64
- package/dist/src/auth/msalConnectionManager.js.map +0 -1
- package/dist/src/auth/msalTokenCredential.js.map +0 -1
- package/dist/src/auth/msalTokenProvider.js +0 -485
- package/dist/src/auth/msalTokenProvider.js.map +0 -1
- package/src/auth/msalTokenProvider.ts +0 -562
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
3
6
|
import { AuthConfiguration } from '../auth/authConfiguration'
|
|
4
7
|
import { AuthProvider } from '../auth/authProvider'
|
|
5
8
|
import { debug } from '@microsoft/agents-telemetry'
|
|
@@ -11,72 +14,47 @@ import { ResourceResponse } from './resourceResponse'
|
|
|
11
14
|
import { AttachmentInfo } from './attachmentInfo'
|
|
12
15
|
import { AttachmentData } from './attachmentData'
|
|
13
16
|
import { normalizeOutgoingActivity } from '../activityWireCompat'
|
|
14
|
-
import { getProductInfo } from '../getProductInfo'
|
|
17
|
+
import { applyUserAgentHeader, getProductInfo } from '../getProductInfo'
|
|
15
18
|
import { HeaderPropagation, HeaderPropagationCollection } from '../headerPropagation'
|
|
16
19
|
import { trace } from '@microsoft/agents-telemetry'
|
|
17
20
|
import { ConnectorClientTraceDefinitions } from '../observability'
|
|
21
|
+
import { parseIntEnv } from '../utils/env'
|
|
22
|
+
import { HttpClient, HttpRequestConfig, HttpResponse, HttpError } from '../httpClient'
|
|
18
23
|
|
|
19
24
|
const logger = debug('agents:connector-client')
|
|
20
25
|
|
|
26
|
+
function formatHttpErrorMessage (error: HttpError): string {
|
|
27
|
+
const responseData = error.response?.data
|
|
28
|
+
if (responseData === undefined) {
|
|
29
|
+
return error.message
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const serializedResponseData = JSON.stringify(responseData)
|
|
34
|
+
return serializedResponseData === undefined ? error.message : `${error.message}: ${serializedResponseData}`
|
|
35
|
+
} catch {
|
|
36
|
+
return error.message
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
21
40
|
export { getProductInfo }
|
|
22
41
|
|
|
23
42
|
/**
|
|
24
43
|
* ConnectorClient is a client for interacting with the Microsoft Connector API.
|
|
25
44
|
*/
|
|
26
45
|
export class ConnectorClient {
|
|
27
|
-
protected readonly
|
|
46
|
+
protected readonly _httpClient: HttpClient
|
|
28
47
|
|
|
29
48
|
/**
|
|
30
49
|
* Private constructor for the ConnectorClient.
|
|
31
|
-
* @param
|
|
50
|
+
* @param httpClient - The HttpClient instance to use for HTTP requests.
|
|
32
51
|
*/
|
|
33
|
-
protected constructor (
|
|
34
|
-
this.
|
|
35
|
-
this._axiosInstance.interceptors.request.use((config) => {
|
|
36
|
-
const { method, url, data, headers, params } = config
|
|
37
|
-
// Clone headers and remove Authorization before logging
|
|
38
|
-
const { Authorization, authorization, ...headersToLog } = headers || {}
|
|
39
|
-
logger.debug('Request: ', {
|
|
40
|
-
host: this._axiosInstance.getUri(),
|
|
41
|
-
url,
|
|
42
|
-
data,
|
|
43
|
-
method,
|
|
44
|
-
params,
|
|
45
|
-
headers: headersToLog
|
|
46
|
-
})
|
|
47
|
-
return config
|
|
48
|
-
})
|
|
49
|
-
this._axiosInstance.interceptors.response.use(
|
|
50
|
-
(config) => {
|
|
51
|
-
const { status, statusText, config: requestConfig } = config
|
|
52
|
-
logger.debug('Response: ', {
|
|
53
|
-
status,
|
|
54
|
-
statusText,
|
|
55
|
-
host: this._axiosInstance.getUri(),
|
|
56
|
-
url: requestConfig?.url,
|
|
57
|
-
data: config.config.data,
|
|
58
|
-
method: requestConfig?.method,
|
|
59
|
-
})
|
|
60
|
-
return config
|
|
61
|
-
},
|
|
62
|
-
(error) => {
|
|
63
|
-
const { code, message, stack, response } = error
|
|
64
|
-
const errorDetails = {
|
|
65
|
-
code,
|
|
66
|
-
host: this._axiosInstance.getUri(),
|
|
67
|
-
url: error.config.url,
|
|
68
|
-
method: error.config.method,
|
|
69
|
-
data: error.config.data,
|
|
70
|
-
message: message + JSON.stringify(response?.data),
|
|
71
|
-
stack,
|
|
72
|
-
}
|
|
73
|
-
return Promise.reject(errorDetails)
|
|
74
|
-
}
|
|
75
|
-
)
|
|
52
|
+
protected constructor (httpClient: HttpClient) {
|
|
53
|
+
this._httpClient = httpClient
|
|
76
54
|
}
|
|
77
55
|
|
|
78
|
-
public get
|
|
79
|
-
return this.
|
|
56
|
+
public get httpClient (): HttpClient {
|
|
57
|
+
return this._httpClient
|
|
80
58
|
}
|
|
81
59
|
|
|
82
60
|
/**
|
|
@@ -112,28 +90,23 @@ export class ConnectorClient {
|
|
|
112
90
|
headers?: HeaderPropagationCollection
|
|
113
91
|
): ConnectorClient {
|
|
114
92
|
const headerPropagation = headers ?? new HeaderPropagation({})
|
|
115
|
-
|
|
116
|
-
const productInfo = getProductInfo()
|
|
117
|
-
if (!userAgent) {
|
|
118
|
-
headerPropagation.add({ 'User-Agent': productInfo })
|
|
119
|
-
} else if (!userAgent.includes(productInfo)) {
|
|
120
|
-
headerPropagation.concat({ 'User-Agent': productInfo })
|
|
121
|
-
}
|
|
93
|
+
applyUserAgentHeader(headerPropagation)
|
|
122
94
|
headerPropagation.override({
|
|
123
95
|
Accept: 'application/json',
|
|
124
|
-
'Content-Type': 'application/json',
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
const axiosInstance = axios.create({
|
|
128
|
-
baseURL,
|
|
129
|
-
headers: headerPropagation.outgoing,
|
|
96
|
+
'Content-Type': 'application/json',
|
|
130
97
|
})
|
|
131
98
|
|
|
99
|
+
const clientHeaders: Record<string, string> = { ...headerPropagation.outgoing }
|
|
132
100
|
if (token && token.length > 1) {
|
|
133
|
-
|
|
101
|
+
clientHeaders.Authorization = `Bearer ${token}`
|
|
134
102
|
}
|
|
135
103
|
|
|
136
|
-
|
|
104
|
+
const httpClient = new HttpClient({
|
|
105
|
+
baseURL,
|
|
106
|
+
headers: clientHeaders,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
return new ConnectorClient(httpClient)
|
|
137
110
|
}
|
|
138
111
|
|
|
139
112
|
/**
|
|
@@ -143,12 +116,12 @@ export class ConnectorClient {
|
|
|
143
116
|
*/
|
|
144
117
|
public async getConversations (continuationToken?: string): Promise<ConversationsResult> {
|
|
145
118
|
return trace(ConnectorClientTraceDefinitions.getConversations, async ({ record }) => {
|
|
146
|
-
const config:
|
|
119
|
+
const config: HttpRequestConfig = {
|
|
147
120
|
method: 'get',
|
|
148
121
|
url: '/v3/conversations',
|
|
149
122
|
params: continuationToken ? { continuationToken } : undefined
|
|
150
123
|
}
|
|
151
|
-
const response = await this.
|
|
124
|
+
const response = await this.executeRequest<ConversationsResult>(config)
|
|
152
125
|
record({ httpStatusCode: response.status?.toString() })
|
|
153
126
|
return response.data
|
|
154
127
|
})
|
|
@@ -159,14 +132,14 @@ export class ConnectorClient {
|
|
|
159
132
|
if (!userId || !conversationId) {
|
|
160
133
|
throw ExceptionHelper.generateException(Error, Errors.UserIdAndConversationIdRequired)
|
|
161
134
|
}
|
|
162
|
-
const config:
|
|
135
|
+
const config: HttpRequestConfig = {
|
|
163
136
|
method: 'get',
|
|
164
137
|
url: `v3/conversations/${conversationId}/members/${userId}`,
|
|
165
138
|
headers: {
|
|
166
139
|
'Content-Type': 'application/json'
|
|
167
140
|
}
|
|
168
141
|
}
|
|
169
|
-
const response = await this.
|
|
142
|
+
const response = await this.executeRequest<ChannelAccount>(config)
|
|
170
143
|
record({ httpStatusCode: response.status?.toString() })
|
|
171
144
|
return response.data
|
|
172
145
|
})
|
|
@@ -183,7 +156,7 @@ export class ConnectorClient {
|
|
|
183
156
|
...body,
|
|
184
157
|
activity: normalizeOutgoingActivity(body.activity)
|
|
185
158
|
}
|
|
186
|
-
const config:
|
|
159
|
+
const config: HttpRequestConfig = {
|
|
187
160
|
method: 'post',
|
|
188
161
|
url: '/v3/conversations',
|
|
189
162
|
headers: {
|
|
@@ -191,7 +164,7 @@ export class ConnectorClient {
|
|
|
191
164
|
},
|
|
192
165
|
data: payload
|
|
193
166
|
}
|
|
194
|
-
const response
|
|
167
|
+
const response = await this.executeRequest<ConversationResourceResponse>(config)
|
|
195
168
|
record({ httpStatusCode: response.status?.toString() })
|
|
196
169
|
return response.data
|
|
197
170
|
})
|
|
@@ -219,7 +192,7 @@ export class ConnectorClient {
|
|
|
219
192
|
|
|
220
193
|
const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
|
|
221
194
|
|
|
222
|
-
const config:
|
|
195
|
+
const config: HttpRequestConfig = {
|
|
223
196
|
method: 'post',
|
|
224
197
|
url: `v3/conversations/${trimmedConversationId}/activities/${encodeURIComponent(activityId)}`,
|
|
225
198
|
headers: {
|
|
@@ -228,7 +201,7 @@ export class ConnectorClient {
|
|
|
228
201
|
data: normalizeOutgoingActivity(body),
|
|
229
202
|
...(body.channelId === Channels.Msteams && body.isTargetedActivity() ? { params: { isTargetedActivity: 'true' } } : {})
|
|
230
203
|
}
|
|
231
|
-
const response = await this.
|
|
204
|
+
const response = await this.executeRequest<ResourceResponse>(config)
|
|
232
205
|
record({ httpStatusCode: response.status?.toString() })
|
|
233
206
|
logger.info('Reply to conversation/activity: ', response.data.id!, activityId)
|
|
234
207
|
return response.data
|
|
@@ -236,20 +209,19 @@ export class ConnectorClient {
|
|
|
236
209
|
}
|
|
237
210
|
|
|
238
211
|
/**
|
|
239
|
-
* Trim the conversationId
|
|
212
|
+
* Trim and sanitize the conversationId when creating the URL for agentic calls in agents channels.
|
|
240
213
|
* @param conversationId The ID of the conversation to potentially truncate.
|
|
241
214
|
* @param activity The activity object used to determine if truncation is necessary.
|
|
242
|
-
* @returns The original
|
|
215
|
+
* @returns The original conversationId for non-agents channels/non-agentic roles, otherwise a trimmed and sanitized value.
|
|
243
216
|
*/
|
|
244
217
|
private conditionallyTruncateConversationId (conversationId: string, activity: Activity): string {
|
|
245
218
|
if (
|
|
246
|
-
|
|
219
|
+
activity.channelIdChannel === Channels.Agents &&
|
|
247
220
|
(activity.from?.role === RoleTypes.AgenticIdentity || activity.from?.role === RoleTypes.AgenticUser)) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return conversationId.length > maxLength ? conversationId.substring(0, maxLength) : conversationId
|
|
221
|
+
const maxLength = parseIntEnv(process.env.MAX_APX_CONVERSATION_ID_LENGTH, 150)
|
|
222
|
+
const trimmedConversationId = conversationId.length > maxLength ? conversationId.substring(0, maxLength) : conversationId
|
|
223
|
+
|
|
224
|
+
return trimmedConversationId.replace(/[/\\#?]/g, '_')
|
|
253
225
|
} else {
|
|
254
226
|
return conversationId
|
|
255
227
|
}
|
|
@@ -275,7 +247,7 @@ export class ConnectorClient {
|
|
|
275
247
|
|
|
276
248
|
const trimmedConversationId: string = this.conditionallyTruncateConversationId(conversationId, body)
|
|
277
249
|
|
|
278
|
-
const config:
|
|
250
|
+
const config: HttpRequestConfig = {
|
|
279
251
|
method: 'post',
|
|
280
252
|
url: `v3/conversations/${trimmedConversationId}/activities`,
|
|
281
253
|
headers: {
|
|
@@ -285,7 +257,7 @@ export class ConnectorClient {
|
|
|
285
257
|
...(body.channelId === Channels.Msteams && body.isTargetedActivity() ? { params: { isTargetedActivity: 'true' } } : {})
|
|
286
258
|
|
|
287
259
|
}
|
|
288
|
-
const response = await this.
|
|
260
|
+
const response = await this.executeRequest<ResourceResponse>(config)
|
|
289
261
|
record({ httpStatusCode: response.status?.toString() })
|
|
290
262
|
return response.data
|
|
291
263
|
})
|
|
@@ -308,7 +280,7 @@ export class ConnectorClient {
|
|
|
308
280
|
throw ExceptionHelper.generateException(Error, Errors.ConversationIdAndActivityIdRequired)
|
|
309
281
|
}
|
|
310
282
|
record({ conversationId, activityId })
|
|
311
|
-
const config:
|
|
283
|
+
const config: HttpRequestConfig = {
|
|
312
284
|
method: 'put',
|
|
313
285
|
url: `v3/conversations/${conversationId}/activities/${activityId}`,
|
|
314
286
|
headers: {
|
|
@@ -317,7 +289,7 @@ export class ConnectorClient {
|
|
|
317
289
|
data: normalizeOutgoingActivity(body),
|
|
318
290
|
...(body.channelId === Channels.Msteams && body.isTargetedActivity() ? { params: { isTargetedActivity: 'true' } } : {})
|
|
319
291
|
}
|
|
320
|
-
const response = await this.
|
|
292
|
+
const response = await this.executeRequest<ResourceResponse>(config)
|
|
321
293
|
record({ httpStatusCode: response.status?.toString() })
|
|
322
294
|
return response.data
|
|
323
295
|
})
|
|
@@ -341,7 +313,7 @@ export class ConnectorClient {
|
|
|
341
313
|
if (!conversationId || !activityId) {
|
|
342
314
|
throw ExceptionHelper.generateException(Error, Errors.ConversationIdAndActivityIdRequired)
|
|
343
315
|
}
|
|
344
|
-
const config:
|
|
316
|
+
const config: HttpRequestConfig = {
|
|
345
317
|
method: 'delete',
|
|
346
318
|
url: `v3/conversations/${conversationId}/activities/${activityId}`,
|
|
347
319
|
headers: {
|
|
@@ -349,7 +321,7 @@ export class ConnectorClient {
|
|
|
349
321
|
},
|
|
350
322
|
...(isTargetedActivity ? { params: { isTargetedActivity: 'true' } } : {})
|
|
351
323
|
}
|
|
352
|
-
const response = await this.
|
|
324
|
+
const response = await this.executeRequest<void>(config)
|
|
353
325
|
record({ httpStatusCode: response.status?.toString() })
|
|
354
326
|
return response.data
|
|
355
327
|
})
|
|
@@ -370,7 +342,7 @@ export class ConnectorClient {
|
|
|
370
342
|
if (conversationId === undefined) {
|
|
371
343
|
throw ExceptionHelper.generateException(Error, Errors.ConversationIdRequired)
|
|
372
344
|
}
|
|
373
|
-
const config:
|
|
345
|
+
const config: HttpRequestConfig = {
|
|
374
346
|
method: 'post',
|
|
375
347
|
url: `v3/conversations/${conversationId}/attachments`,
|
|
376
348
|
headers: {
|
|
@@ -378,7 +350,7 @@ export class ConnectorClient {
|
|
|
378
350
|
},
|
|
379
351
|
data: body
|
|
380
352
|
}
|
|
381
|
-
const response = await this.
|
|
353
|
+
const response = await this.executeRequest<ResourceResponse>(config)
|
|
382
354
|
record({ httpStatusCode: response.status?.toString() })
|
|
383
355
|
return response.data
|
|
384
356
|
})
|
|
@@ -397,14 +369,14 @@ export class ConnectorClient {
|
|
|
397
369
|
if (attachmentId === undefined) {
|
|
398
370
|
throw ExceptionHelper.generateException(Error, Errors.AttachmentIdRequired)
|
|
399
371
|
}
|
|
400
|
-
const config:
|
|
372
|
+
const config: HttpRequestConfig = {
|
|
401
373
|
method: 'get',
|
|
402
374
|
url: `v3/attachments/${attachmentId}`,
|
|
403
375
|
headers: {
|
|
404
376
|
'Content-Type': 'application/json'
|
|
405
377
|
}
|
|
406
378
|
}
|
|
407
|
-
const response = await this.
|
|
379
|
+
const response = await this.executeRequest<AttachmentInfo>(config)
|
|
408
380
|
record({ httpStatusCode: response.status?.toString() })
|
|
409
381
|
return response.data
|
|
410
382
|
})
|
|
@@ -428,16 +400,66 @@ export class ConnectorClient {
|
|
|
428
400
|
if (viewId === undefined) {
|
|
429
401
|
throw ExceptionHelper.generateException(Error, Errors.ViewIdRequired)
|
|
430
402
|
}
|
|
431
|
-
const config:
|
|
403
|
+
const config: HttpRequestConfig = {
|
|
432
404
|
method: 'get',
|
|
433
405
|
url: `v3/attachments/${attachmentId}/views/${viewId}`,
|
|
434
406
|
headers: {
|
|
435
407
|
'Content-Type': 'application/json'
|
|
436
|
-
}
|
|
408
|
+
},
|
|
409
|
+
responseType: 'stream'
|
|
437
410
|
}
|
|
438
|
-
const response = await this.
|
|
411
|
+
const response = await this.executeRequest<NodeJS.ReadableStream>(config)
|
|
439
412
|
record({ httpStatusCode: response.status?.toString() })
|
|
440
413
|
return response.data
|
|
441
414
|
})
|
|
442
415
|
}
|
|
416
|
+
|
|
417
|
+
private async executeRequest<T = unknown> (config: HttpRequestConfig): Promise<HttpResponse<T>> {
|
|
418
|
+
const { method, url, data, headers, params } = config
|
|
419
|
+
const { Authorization, authorization, ...headersToLog } = { ...this._httpClient.defaultHeaders, ...headers } as Record<string, string>
|
|
420
|
+
logger.debug('Request: ', {
|
|
421
|
+
host: this._httpClient.baseURL,
|
|
422
|
+
url,
|
|
423
|
+
data,
|
|
424
|
+
method,
|
|
425
|
+
params,
|
|
426
|
+
headers: headersToLog
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
try {
|
|
430
|
+
const response = await this._httpClient.request<T>(config)
|
|
431
|
+
logger.debug('Response: ', {
|
|
432
|
+
status: response.status,
|
|
433
|
+
statusText: response.statusText,
|
|
434
|
+
host: this._httpClient.baseURL,
|
|
435
|
+
url: response.config?.url,
|
|
436
|
+
data: response.config?.data,
|
|
437
|
+
method: response.config?.method,
|
|
438
|
+
})
|
|
439
|
+
return response
|
|
440
|
+
} catch (error) {
|
|
441
|
+
if (error instanceof HttpError) {
|
|
442
|
+
const message = formatHttpErrorMessage(error)
|
|
443
|
+
logger.debug('Response error: ', {
|
|
444
|
+
host: this._httpClient.baseURL,
|
|
445
|
+
url: error.config.url,
|
|
446
|
+
method: error.config.method,
|
|
447
|
+
data: error.config.data,
|
|
448
|
+
message,
|
|
449
|
+
stack: error.stack,
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
Object.assign(error, {
|
|
453
|
+
host: this._httpClient.baseURL,
|
|
454
|
+
url: error.config.url,
|
|
455
|
+
method: error.config.method,
|
|
456
|
+
data: error.config.data,
|
|
457
|
+
message,
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
throw error
|
|
461
|
+
}
|
|
462
|
+
throw error
|
|
463
|
+
}
|
|
464
|
+
}
|
|
443
465
|
}
|
package/src/errorHelper.ts
CHANGED
|
@@ -232,6 +232,14 @@ export const Errors: { [key: string]: AgentErrorDefinition } = {
|
|
|
232
232
|
description: 'attachmentId is required'
|
|
233
233
|
},
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Error thrown when attachment is null or undefined.
|
|
237
|
+
*/
|
|
238
|
+
AttachmentNullOrUndefined: {
|
|
239
|
+
code: -120265,
|
|
240
|
+
description: 'attachment cannot be null or undefined.'
|
|
241
|
+
},
|
|
242
|
+
|
|
235
243
|
/**
|
|
236
244
|
* Error thrown when viewId is required but missing.
|
|
237
245
|
*/
|
|
@@ -256,6 +264,14 @@ export const Errors: { [key: string]: AgentErrorDefinition } = {
|
|
|
256
264
|
description: 'request.body parameter required'
|
|
257
265
|
},
|
|
258
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Error thrown when HttpClient is given a relative URL without a configured base URL.
|
|
269
|
+
*/
|
|
270
|
+
HttpClientRelativeUrlRequiresBaseUrl: {
|
|
271
|
+
code: -120291,
|
|
272
|
+
description: 'HttpClient requires baseURL when using a relative URL: {url}'
|
|
273
|
+
},
|
|
274
|
+
|
|
259
275
|
// ============================================================================
|
|
260
276
|
// Connection and Authentication Errors (-120300 to -120590)
|
|
261
277
|
// ============================================================================
|
|
@@ -516,8 +532,166 @@ export const Errors: { [key: string]: AgentErrorDefinition } = {
|
|
|
516
532
|
description: "The current token for the '{connectionName}' AzureBot connection is not exchangeable for an on-behalf-of flow. Ensure the base token audience is for the bot/resource app, such as an App ID URI like 'api://...' or otherwise includes the app's client id."
|
|
517
533
|
},
|
|
518
534
|
|
|
535
|
+
/**
|
|
536
|
+
* Error thrown when an unsupported authentication type is specified in authConfig.
|
|
537
|
+
*/
|
|
538
|
+
UnsupportedAuthType: {
|
|
539
|
+
code: -120593,
|
|
540
|
+
description: 'Unsupported authentication type: {authType}'
|
|
541
|
+
},
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Error thrown when WorkloadIdentity authentication requires `federatedTokenFile` or the deprecated `WIDAssertionFile` to be configured.
|
|
545
|
+
*/
|
|
546
|
+
WorkloadIdentityTokenFileRequired: {
|
|
547
|
+
code: -120594,
|
|
548
|
+
description: 'WorkloadIdentity authentication requires `federatedTokenFile` or the deprecated `WIDAssertionFile` to be configured'
|
|
549
|
+
},
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Error thrown when ClientSecret authentication is specified but `clientSecret` is not configured.
|
|
553
|
+
*/
|
|
554
|
+
ClientSecretRequired: {
|
|
555
|
+
code: -120595,
|
|
556
|
+
description: 'ClientSecret authentication requires `clientSecret` to be configured'
|
|
557
|
+
},
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Error thrown when Certificate authentication is specified but `certPemFile` or `certKeyFile` is not configured.
|
|
561
|
+
*/
|
|
562
|
+
CertificateFilesRequired: {
|
|
563
|
+
code: -120596,
|
|
564
|
+
description: 'Certificate authentication requires both `certPemFile` and `certKeyFile` to be configured'
|
|
565
|
+
},
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Error thrown when FederatedCredentials authentication is specified but `federatedClientId` or the deprecated `FICClientId` is not configured.
|
|
569
|
+
*/
|
|
570
|
+
FICClientIdRequired: {
|
|
571
|
+
code: -120597,
|
|
572
|
+
description: 'FederatedCredentials authentication requires `federatedClientId` or the deprecated `FICClientId` to be configured'
|
|
573
|
+
},
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Error thrown when UserManagedIdentity authentication is specified but `clientId` is not configured.
|
|
577
|
+
*/
|
|
578
|
+
ClientIdRequiredForUserManagedIdentity: {
|
|
579
|
+
code: -120598,
|
|
580
|
+
description: 'UserManagedIdentity authentication requires `clientId` to be configured'
|
|
581
|
+
},
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Error thrown when there's a timeout during a token request.
|
|
585
|
+
*/
|
|
586
|
+
TokenRequestTimeout: {
|
|
587
|
+
code: -120599,
|
|
588
|
+
description: 'Token request timed out after {timeoutMs} ms'
|
|
589
|
+
},
|
|
590
|
+
|
|
519
591
|
// ============================================================================
|
|
520
|
-
// Agent
|
|
592
|
+
// Entra Agent ID Sidecar Authentication Errors (-120800 to -120849)
|
|
593
|
+
// ============================================================================
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Error thrown when the Entra sidecar auth provider is used without connection settings.
|
|
597
|
+
*/
|
|
598
|
+
SidecarConnectionSettingsRequired: {
|
|
599
|
+
code: -120800,
|
|
600
|
+
description: 'Connection settings must be provided when using the Entra sidecar auth provider'
|
|
601
|
+
},
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Error thrown when the resolved sidecar base URL is not a valid absolute URL.
|
|
605
|
+
*/
|
|
606
|
+
SidecarBaseUrlInvalid: {
|
|
607
|
+
code: -120801,
|
|
608
|
+
description: 'The resolved sidecar base URL `{url}` is not a valid absolute URL'
|
|
609
|
+
},
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Error thrown when the resolved sidecar base URL does not use the http or https scheme.
|
|
613
|
+
*/
|
|
614
|
+
SidecarBaseUrlInsecureScheme: {
|
|
615
|
+
code: -120802,
|
|
616
|
+
description: 'The resolved sidecar base URL `{url}` must use the http or https scheme'
|
|
617
|
+
},
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Error thrown when the resolved sidecar base URL contains userinfo (credentials).
|
|
621
|
+
*/
|
|
622
|
+
SidecarBaseUrlUserInfo: {
|
|
623
|
+
code: -120803,
|
|
624
|
+
description: 'The resolved sidecar base URL `{url}` must not contain userinfo (credentials)'
|
|
625
|
+
},
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Error thrown when the resolved sidecar base URL points to a non-loopback, non-private address.
|
|
629
|
+
*/
|
|
630
|
+
SidecarBaseUrlNotLocal: {
|
|
631
|
+
code: -120804,
|
|
632
|
+
description: 'The resolved sidecar base URL `{url}` points to a non-loopback, non-private address. The Entra Agent ID sidecar (agent container) must be reachable only from within the agent\'s network boundary. Set `bypassLocalNetworkRestriction` to true in the connection configuration to override this safety check (UNSAFE: only for carefully validated private-network configurations)'
|
|
633
|
+
},
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Error thrown when both AgentUsername and AgentUserId are supplied on a sidecar request (mutually exclusive).
|
|
637
|
+
*/
|
|
638
|
+
SidecarUserIdentityMutuallyExclusive: {
|
|
639
|
+
code: -120805,
|
|
640
|
+
description: 'AgentUsername and AgentUserId are mutually exclusive; set only one on the sidecar request options'
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Error thrown when a sidecar request fails after exhausting all retry attempts.
|
|
645
|
+
*/
|
|
646
|
+
SidecarRequestFailed: {
|
|
647
|
+
code: -120806,
|
|
648
|
+
description: 'Sidecar request failed after {attempts} attempt(s): {message}'
|
|
649
|
+
},
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Error thrown when the sidecar responds with a non-success status code.
|
|
653
|
+
*/
|
|
654
|
+
SidecarErrorResponse: {
|
|
655
|
+
code: -120807,
|
|
656
|
+
description: 'Sidecar returned error status {status}: {message}'
|
|
657
|
+
},
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Error thrown when the sidecar response is missing the authorizationHeader field.
|
|
661
|
+
*/
|
|
662
|
+
SidecarResponseMissingAuthorizationHeader: {
|
|
663
|
+
code: -120808,
|
|
664
|
+
description: 'Sidecar response missing `authorizationHeader` field'
|
|
665
|
+
},
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Error thrown when the sidecar response body cannot be parsed.
|
|
669
|
+
*/
|
|
670
|
+
SidecarResponseUnparsable: {
|
|
671
|
+
code: -120809,
|
|
672
|
+
description: 'Sidecar returned an unparsable response body'
|
|
673
|
+
},
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Error thrown when acquireTokenOnBehalfOf is called on the sidecar provider, which does not support OBO in Phase 1.
|
|
677
|
+
*/
|
|
678
|
+
OnBehalfOfNotSupportedBySidecar: {
|
|
679
|
+
code: -120810,
|
|
680
|
+
description: 'acquireTokenOnBehalfOf is not supported by the Entra sidecar auth provider in Phase 1'
|
|
681
|
+
},
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Error thrown when the sidecar returns a token with an authorization scheme other than Bearer.
|
|
685
|
+
* The hosting stack always transmits tokens as `Bearer {token}`, so a non-Bearer scheme cannot be
|
|
686
|
+
* honored and is rejected rather than silently sent as an invalid Authorization header.
|
|
687
|
+
*/
|
|
688
|
+
SidecarUnsupportedAuthScheme: {
|
|
689
|
+
code: -120811,
|
|
690
|
+
description: 'The Entra Agent ID sidecar returned an unsupported authorization scheme `{scheme}`. Only the Bearer scheme is supported'
|
|
691
|
+
},
|
|
692
|
+
|
|
693
|
+
// ============================================================================
|
|
694
|
+
// Agent and Client Errors (-120600 to -120650)
|
|
521
695
|
// ============================================================================
|
|
522
696
|
|
|
523
697
|
/**
|
|
@@ -537,18 +711,34 @@ export const Errors: { [key: string]: AgentErrorDefinition } = {
|
|
|
537
711
|
},
|
|
538
712
|
|
|
539
713
|
/**
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
714
|
+
* Error thrown when agent ID is required.
|
|
715
|
+
*/
|
|
716
|
+
AgentIdRequired: {
|
|
543
717
|
code: -120620,
|
|
718
|
+
description: 'Agent ID is required to apply outbound agent headers'
|
|
719
|
+
},
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Error thrown when agent name contains invalid characters.
|
|
723
|
+
*/
|
|
724
|
+
AgentNameInvalid: {
|
|
725
|
+
code: -120630,
|
|
726
|
+
description: 'Agent name contains invalid characters: {agentName}'
|
|
727
|
+
},
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Error thrown when failed to post activity to agent.
|
|
731
|
+
*/
|
|
732
|
+
FailedToPostActivityToAgent: {
|
|
733
|
+
code: -120640,
|
|
544
734
|
description: 'Failed to post activity to agent: {statusText}'
|
|
545
735
|
},
|
|
546
736
|
|
|
547
737
|
/**
|
|
548
|
-
|
|
549
|
-
|
|
738
|
+
* Error thrown when logic parameter must be defined.
|
|
739
|
+
*/
|
|
550
740
|
LogicParameterRequired: {
|
|
551
|
-
code: -
|
|
741
|
+
code: -120650,
|
|
552
742
|
description: 'logic must be defined'
|
|
553
743
|
},
|
|
554
744
|
|
|
@@ -784,6 +974,15 @@ export const Errors: { [key: string]: AgentErrorDefinition } = {
|
|
|
784
974
|
description: 'This proactive operation requires app storage to load and save TurnState. Set options.storage on AgentApplication.'
|
|
785
975
|
},
|
|
786
976
|
|
|
977
|
+
/**
|
|
978
|
+
* Error thrown when CreateConversationOptionsBuilder.build() is called for a Teams channel
|
|
979
|
+
* conversation (withTeamsChannelId) without an activity set via withActivity().
|
|
980
|
+
*/
|
|
981
|
+
CreateConversationBuilderChannelActivityRequired: {
|
|
982
|
+
code: -120753,
|
|
983
|
+
description: 'CreateConversationOptionsBuilder: Teams channel conversations require an initial activity. Call withActivity() before build().'
|
|
984
|
+
},
|
|
985
|
+
|
|
787
986
|
// ============================================================================
|
|
788
987
|
// General Errors (-120990)
|
|
789
988
|
// ============================================================================
|