@cuylabs/agent-channel-teams 3.0.0 → 3.2.1
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/README.md +30 -0
- package/dist/index.d.ts +40 -2
- package/dist/index.js +367 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -134,6 +134,36 @@ Teams handler handles the invoke, the adapter returns an explicit `501`.
|
|
|
134
134
|
Build common Teams dialog/search invoke bodies without making callers hand-roll
|
|
135
135
|
raw payload objects.
|
|
136
136
|
|
|
137
|
+
### Interactive Request Cards
|
|
138
|
+
|
|
139
|
+
`createTeamsApprovalRequestCard(...)`,
|
|
140
|
+
`createTeamsHumanInputRequestCard(...)`, and
|
|
141
|
+
`parseTeamsInputRequestSubmit(...)` provide the Teams UI pieces for approval and
|
|
142
|
+
human-input requests. They are intentionally state-free: `agent-server` should
|
|
143
|
+
own pending request state and turn resolution, while Teams renders cards and
|
|
144
|
+
passes submit payloads back to `server.respondToInputRequest(...)`.
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import {
|
|
148
|
+
createTeamsApprovalRequestCard,
|
|
149
|
+
parseTeamsInputRequestSubmit,
|
|
150
|
+
} from "@cuylabs/agent-channel-teams";
|
|
151
|
+
|
|
152
|
+
server.subscribe(async (notification) => {
|
|
153
|
+
if (notification.type !== "input/request") return;
|
|
154
|
+
if (notification.request.kind !== "approval") return;
|
|
155
|
+
|
|
156
|
+
await sendCardToTeams(
|
|
157
|
+
createTeamsApprovalRequestCard(notification.request),
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const submit = parseTeamsInputRequestSubmit(ctx.turnContext.activity.value);
|
|
162
|
+
if (submit) {
|
|
163
|
+
server.respondToInputRequest(submit.requestId, submit.payload);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
137
167
|
## TeamsInfo and Typed Channel Data
|
|
138
168
|
|
|
139
169
|
The curated Teams helper surface is available directly from the main barrel. If
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentEvent } from '@cuylabs/agent-core';
|
|
1
|
+
import { AgentEvent, ApprovalRequest, HumanInputRequest, ApprovalAction, ApprovalRememberScope, HumanInputResponse } from '@cuylabs/agent-core';
|
|
2
2
|
import { M365ChannelOptions, M365TurnRequestContext, M365TurnPreparation, M365UserIdentity, M365TurnSource, M365ChannelAdapter, M365AmbientTurnContext } from '@cuylabs/agent-channel-m365';
|
|
3
3
|
import { TurnContext, AuthConfiguration, CloudAdapter } from '@microsoft/agents-hosting';
|
|
4
4
|
import { TeamsChannelData } from '@microsoft/agents-hosting-extensions-teams';
|
|
@@ -295,6 +295,44 @@ interface TeamsDialogMessageBody {
|
|
|
295
295
|
declare function createTeamsDialog(dialog: TeamsDialogDefinition): TeamsDialogResponse;
|
|
296
296
|
declare function createTeamsDialogMessage(message: string): TeamsDialogMessageBody;
|
|
297
297
|
|
|
298
|
+
declare const TEAMS_INPUT_REQUEST_APPROVAL_VERB = "cuylabs.agent.input.approval";
|
|
299
|
+
declare const TEAMS_INPUT_REQUEST_HUMAN_VERB = "cuylabs.agent.input.human";
|
|
300
|
+
type TeamsInputRequestVerb = typeof TEAMS_INPUT_REQUEST_APPROVAL_VERB | typeof TEAMS_INPUT_REQUEST_HUMAN_VERB;
|
|
301
|
+
interface TeamsInputRequestEnvelope<TRequest> {
|
|
302
|
+
request: TRequest;
|
|
303
|
+
sessionId?: string;
|
|
304
|
+
turnId?: string;
|
|
305
|
+
}
|
|
306
|
+
type TeamsApprovalCardRequest = ApprovalRequest | TeamsInputRequestEnvelope<ApprovalRequest>;
|
|
307
|
+
type TeamsHumanInputCardRequest = HumanInputRequest | TeamsInputRequestEnvelope<HumanInputRequest>;
|
|
308
|
+
interface TeamsApprovalCardOptions {
|
|
309
|
+
title?: string;
|
|
310
|
+
includeArguments?: boolean;
|
|
311
|
+
maxArgumentChars?: number;
|
|
312
|
+
}
|
|
313
|
+
interface TeamsHumanInputCardOptions {
|
|
314
|
+
title?: string;
|
|
315
|
+
}
|
|
316
|
+
type TeamsResolveInputPayload = {
|
|
317
|
+
kind: "approval";
|
|
318
|
+
action: ApprovalAction;
|
|
319
|
+
feedback?: string;
|
|
320
|
+
rememberScope?: ApprovalRememberScope;
|
|
321
|
+
} | {
|
|
322
|
+
kind: "human";
|
|
323
|
+
response: HumanInputResponse;
|
|
324
|
+
};
|
|
325
|
+
interface TeamsInputRequestSubmit {
|
|
326
|
+
verb: TeamsInputRequestVerb;
|
|
327
|
+
requestId: string;
|
|
328
|
+
sessionId?: string;
|
|
329
|
+
turnId?: string;
|
|
330
|
+
payload: TeamsResolveInputPayload;
|
|
331
|
+
}
|
|
332
|
+
declare function createTeamsApprovalRequestCard(input: TeamsApprovalCardRequest, options?: TeamsApprovalCardOptions): Attachment;
|
|
333
|
+
declare function createTeamsHumanInputRequestCard(input: TeamsHumanInputCardRequest, options?: TeamsHumanInputCardOptions): Attachment;
|
|
334
|
+
declare function parseTeamsInputRequestSubmit(value: unknown): TeamsInputRequestSubmit | undefined;
|
|
335
|
+
|
|
298
336
|
interface ParseTeamsActivityOptions {
|
|
299
337
|
strictChannelData?: boolean;
|
|
300
338
|
}
|
|
@@ -322,4 +360,4 @@ declare const TEAMS_MEETING_INVOKE_NAMES: Readonly<Record<string, TeamsActivityK
|
|
|
322
360
|
declare function parseTeamsActivity(context: TurnContext, options?: ParseTeamsActivityOptions): TeamsActivityInfo;
|
|
323
361
|
declare function parseTeamsActivitySafe(context: TurnContext): TeamsActivityInfo;
|
|
324
362
|
|
|
325
|
-
export { type MountTeamsAgentOptions, type MountTeamsAgentResult, type ParseTeamsActivityOptions, TEAMS_ACTIONABLE_MESSAGE_NAMES, TEAMS_ADAPTIVE_CARD_ACTION_NAMES, TEAMS_ADAPTIVE_CARD_SEARCH_NAMES, TEAMS_CARD_ACTION_SUBMIT_NAMES, TEAMS_CONFIG_FETCH_NAMES, TEAMS_CONFIG_SUBMIT_NAMES, TEAMS_CONVERSATION_UPDATE_EVENT_NAMES, TEAMS_FILE_CONSENT_NAMES, TEAMS_MEETING_EVENT_NAMES, TEAMS_MEETING_INVOKE_NAMES, TEAMS_MESSAGE_EXTENSION_CARD_BUTTON_CLICKED_NAMES, TEAMS_MESSAGE_EXTENSION_FETCH_TASK_NAMES, TEAMS_MESSAGE_EXTENSION_QUERY_NAMES, TEAMS_MESSAGE_EXTENSION_QUERY_SETTING_URL_NAMES, TEAMS_MESSAGE_EXTENSION_SELECT_NAMES, TEAMS_MESSAGE_EXTENSION_SETTING_NAMES, TEAMS_MESSAGE_EXTENSION_SUBMIT_ACTION_NAMES, TEAMS_TAB_FETCH_NAMES, TEAMS_TAB_SUBMIT_NAMES, TEAMS_TASK_MODULE_FETCH_NAMES, TEAMS_TASK_MODULE_SUBMIT_NAMES, type TeamsActivityHandler, type TeamsActivityHandlers, type TeamsActivityInfo, type TeamsActivityKind, type TeamsActorReference, type TeamsAmbientTurnContext, type TeamsCardActionHandlers, type TeamsChannelAdapter, type TeamsChannelOptions, type TeamsConfigHandlers, type TeamsConversationUpdateHandlers, type TeamsDialogDefinition, type TeamsDialogMessageBody, type TeamsDialogResponse, type TeamsDialogSize, type TeamsHandlerContext, type TeamsHandlerDecision, type TeamsInvokeResult, type TeamsMeetingHandlers, type TeamsMessageActivityHandlers, type TeamsMessageExtensionHandlers, type TeamsSearchAttachment, type TeamsSearchLayout, type TeamsSearchMessageBody, type TeamsSearchResponse, type TeamsSearchResult, type TeamsSearchResultBody, type TeamsSearchResultType, type TeamsSurface, type TeamsTabHandlers, type TeamsTaskModuleHandlers, type TeamsTurnPreparation, type TeamsTurnRequestContext, createTeamsChannelAdapter, createTeamsDialog, createTeamsDialogMessage, createTeamsInvokeActivity, createTeamsSearchMessage, createTeamsSearchResult, currentTeamsTurnContext, mountTeamsAgent, parseTeamsActivity, parseTeamsActivitySafe, runWithTeamsTurnContext, sendTeamsInvoke };
|
|
363
|
+
export { type MountTeamsAgentOptions, type MountTeamsAgentResult, type ParseTeamsActivityOptions, TEAMS_ACTIONABLE_MESSAGE_NAMES, TEAMS_ADAPTIVE_CARD_ACTION_NAMES, TEAMS_ADAPTIVE_CARD_SEARCH_NAMES, TEAMS_CARD_ACTION_SUBMIT_NAMES, TEAMS_CONFIG_FETCH_NAMES, TEAMS_CONFIG_SUBMIT_NAMES, TEAMS_CONVERSATION_UPDATE_EVENT_NAMES, TEAMS_FILE_CONSENT_NAMES, TEAMS_INPUT_REQUEST_APPROVAL_VERB, TEAMS_INPUT_REQUEST_HUMAN_VERB, TEAMS_MEETING_EVENT_NAMES, TEAMS_MEETING_INVOKE_NAMES, TEAMS_MESSAGE_EXTENSION_CARD_BUTTON_CLICKED_NAMES, TEAMS_MESSAGE_EXTENSION_FETCH_TASK_NAMES, TEAMS_MESSAGE_EXTENSION_QUERY_NAMES, TEAMS_MESSAGE_EXTENSION_QUERY_SETTING_URL_NAMES, TEAMS_MESSAGE_EXTENSION_SELECT_NAMES, TEAMS_MESSAGE_EXTENSION_SETTING_NAMES, TEAMS_MESSAGE_EXTENSION_SUBMIT_ACTION_NAMES, TEAMS_TAB_FETCH_NAMES, TEAMS_TAB_SUBMIT_NAMES, TEAMS_TASK_MODULE_FETCH_NAMES, TEAMS_TASK_MODULE_SUBMIT_NAMES, type TeamsActivityHandler, type TeamsActivityHandlers, type TeamsActivityInfo, type TeamsActivityKind, type TeamsActorReference, type TeamsAmbientTurnContext, type TeamsApprovalCardOptions, type TeamsApprovalCardRequest, type TeamsCardActionHandlers, type TeamsChannelAdapter, type TeamsChannelOptions, type TeamsConfigHandlers, type TeamsConversationUpdateHandlers, type TeamsDialogDefinition, type TeamsDialogMessageBody, type TeamsDialogResponse, type TeamsDialogSize, type TeamsHandlerContext, type TeamsHandlerDecision, type TeamsHumanInputCardOptions, type TeamsHumanInputCardRequest, type TeamsInputRequestEnvelope, type TeamsInputRequestSubmit, type TeamsInputRequestVerb, type TeamsInvokeResult, type TeamsMeetingHandlers, type TeamsMessageActivityHandlers, type TeamsMessageExtensionHandlers, type TeamsResolveInputPayload, type TeamsSearchAttachment, type TeamsSearchLayout, type TeamsSearchMessageBody, type TeamsSearchResponse, type TeamsSearchResult, type TeamsSearchResultBody, type TeamsSearchResultType, type TeamsSurface, type TeamsTabHandlers, type TeamsTaskModuleHandlers, type TeamsTurnPreparation, type TeamsTurnRequestContext, createTeamsApprovalRequestCard, createTeamsChannelAdapter, createTeamsDialog, createTeamsDialogMessage, createTeamsHumanInputRequestCard, createTeamsInvokeActivity, createTeamsSearchMessage, createTeamsSearchResult, currentTeamsTurnContext, mountTeamsAgent, parseTeamsActivity, parseTeamsActivitySafe, parseTeamsInputRequestSubmit, runWithTeamsTurnContext, sendTeamsInvoke };
|
package/dist/index.js
CHANGED
|
@@ -768,6 +768,368 @@ function createTeamsDialogMessage(message) {
|
|
|
768
768
|
}
|
|
769
769
|
};
|
|
770
770
|
}
|
|
771
|
+
|
|
772
|
+
// src/interactive-requests.ts
|
|
773
|
+
var TEAMS_INPUT_REQUEST_APPROVAL_VERB = "cuylabs.agent.input.approval";
|
|
774
|
+
var TEAMS_INPUT_REQUEST_HUMAN_VERB = "cuylabs.agent.input.human";
|
|
775
|
+
var ADAPTIVE_CARD_CONTENT_TYPE = "application/vnd.microsoft.card.adaptive";
|
|
776
|
+
var DEFAULT_MAX_ARGUMENT_CHARS = 1200;
|
|
777
|
+
function createTeamsApprovalRequestCard(input, options = {}) {
|
|
778
|
+
const { request, sessionId, turnId } = normalizeInputRequest(input);
|
|
779
|
+
const body = [
|
|
780
|
+
{
|
|
781
|
+
type: "TextBlock",
|
|
782
|
+
size: "Medium",
|
|
783
|
+
weight: "Bolder",
|
|
784
|
+
text: options.title ?? "Approval required",
|
|
785
|
+
wrap: true
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
type: "FactSet",
|
|
789
|
+
facts: [
|
|
790
|
+
{ title: "Tool", value: request.tool },
|
|
791
|
+
{ title: "Risk", value: request.risk }
|
|
792
|
+
]
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
type: "TextBlock",
|
|
796
|
+
text: request.description,
|
|
797
|
+
wrap: true
|
|
798
|
+
}
|
|
799
|
+
];
|
|
800
|
+
if (options.includeArguments ?? true) {
|
|
801
|
+
const formattedArgs = formatToolArguments(
|
|
802
|
+
request.args,
|
|
803
|
+
options.maxArgumentChars ?? DEFAULT_MAX_ARGUMENT_CHARS
|
|
804
|
+
);
|
|
805
|
+
if (formattedArgs) {
|
|
806
|
+
body.push({
|
|
807
|
+
type: "TextBlock",
|
|
808
|
+
text: formattedArgs,
|
|
809
|
+
wrap: true,
|
|
810
|
+
fontType: "Monospace",
|
|
811
|
+
isSubtle: true
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const rememberScopes = normalizeRememberScopes(request);
|
|
816
|
+
if (rememberScopes.length > 0) {
|
|
817
|
+
body.push({
|
|
818
|
+
type: "Input.ChoiceSet",
|
|
819
|
+
id: "rememberScope",
|
|
820
|
+
label: "Remember scope",
|
|
821
|
+
style: "compact",
|
|
822
|
+
value: request.defaultRememberScope ?? rememberScopes[0],
|
|
823
|
+
choices: rememberScopes.map((scope) => ({
|
|
824
|
+
title: labelRememberScope(scope),
|
|
825
|
+
value: scope
|
|
826
|
+
}))
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
body.push({
|
|
830
|
+
type: "Input.Text",
|
|
831
|
+
id: "feedback",
|
|
832
|
+
label: "Feedback",
|
|
833
|
+
isMultiline: true,
|
|
834
|
+
isRequired: false,
|
|
835
|
+
placeholder: "Optional"
|
|
836
|
+
});
|
|
837
|
+
const baseData = {
|
|
838
|
+
requestId: request.id,
|
|
839
|
+
sessionId,
|
|
840
|
+
...turnId ? { turnId } : {}
|
|
841
|
+
};
|
|
842
|
+
const actions = [
|
|
843
|
+
{
|
|
844
|
+
type: "Action.Submit",
|
|
845
|
+
title: "Approve",
|
|
846
|
+
data: {
|
|
847
|
+
...baseData,
|
|
848
|
+
verb: TEAMS_INPUT_REQUEST_APPROVAL_VERB,
|
|
849
|
+
action: "allow"
|
|
850
|
+
}
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
type: "Action.Submit",
|
|
854
|
+
title: "Deny",
|
|
855
|
+
data: {
|
|
856
|
+
...baseData,
|
|
857
|
+
verb: TEAMS_INPUT_REQUEST_APPROVAL_VERB,
|
|
858
|
+
action: "deny"
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
];
|
|
862
|
+
if (rememberScopes.length > 0) {
|
|
863
|
+
actions.push({
|
|
864
|
+
type: "Action.Submit",
|
|
865
|
+
title: "Remember",
|
|
866
|
+
data: {
|
|
867
|
+
...baseData,
|
|
868
|
+
verb: TEAMS_INPUT_REQUEST_APPROVAL_VERB,
|
|
869
|
+
action: "remember"
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
return createAdaptiveCardAttachment(body, actions);
|
|
874
|
+
}
|
|
875
|
+
function createTeamsHumanInputRequestCard(input, options = {}) {
|
|
876
|
+
const { request, sessionId, turnId } = normalizeInputRequest(input);
|
|
877
|
+
const body = [
|
|
878
|
+
{
|
|
879
|
+
type: "TextBlock",
|
|
880
|
+
size: "Medium",
|
|
881
|
+
weight: "Bolder",
|
|
882
|
+
text: options.title ?? request.title,
|
|
883
|
+
wrap: true
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
type: "TextBlock",
|
|
887
|
+
text: request.question,
|
|
888
|
+
wrap: true
|
|
889
|
+
}
|
|
890
|
+
];
|
|
891
|
+
const baseData = {
|
|
892
|
+
requestId: request.id,
|
|
893
|
+
sessionId,
|
|
894
|
+
...turnId ? { turnId } : {}
|
|
895
|
+
};
|
|
896
|
+
if (request.kind === "choice") {
|
|
897
|
+
body.push({
|
|
898
|
+
type: "Input.ChoiceSet",
|
|
899
|
+
id: "selected",
|
|
900
|
+
label: request.title,
|
|
901
|
+
style: request.allowMultiple ? "expanded" : "compact",
|
|
902
|
+
isMultiSelect: request.allowMultiple ?? false,
|
|
903
|
+
choices: (request.options ?? []).map((option) => ({
|
|
904
|
+
title: option.label,
|
|
905
|
+
value: option.value ?? option.label
|
|
906
|
+
}))
|
|
907
|
+
});
|
|
908
|
+
} else if (request.kind === "text") {
|
|
909
|
+
body.push({
|
|
910
|
+
type: "Input.Text",
|
|
911
|
+
id: "text",
|
|
912
|
+
label: request.title,
|
|
913
|
+
isMultiline: true,
|
|
914
|
+
placeholder: request.placeholder ?? "Type a response"
|
|
915
|
+
});
|
|
916
|
+
} else {
|
|
917
|
+
body.push({
|
|
918
|
+
type: "Input.Text",
|
|
919
|
+
id: "text",
|
|
920
|
+
label: "Details",
|
|
921
|
+
isMultiline: true,
|
|
922
|
+
isRequired: false,
|
|
923
|
+
placeholder: request.placeholder ?? "Optional"
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
const actions = request.kind === "confirm" ? [
|
|
927
|
+
{
|
|
928
|
+
type: "Action.Submit",
|
|
929
|
+
title: request.confirmLabel ?? "Confirm",
|
|
930
|
+
data: {
|
|
931
|
+
...baseData,
|
|
932
|
+
verb: TEAMS_INPUT_REQUEST_HUMAN_VERB,
|
|
933
|
+
responseKind: "confirm",
|
|
934
|
+
confirmed: true
|
|
935
|
+
}
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
type: "Action.Submit",
|
|
939
|
+
title: request.denyLabel ?? "Cancel",
|
|
940
|
+
data: {
|
|
941
|
+
...baseData,
|
|
942
|
+
verb: TEAMS_INPUT_REQUEST_HUMAN_VERB,
|
|
943
|
+
responseKind: "confirm",
|
|
944
|
+
confirmed: false
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
] : [
|
|
948
|
+
{
|
|
949
|
+
type: "Action.Submit",
|
|
950
|
+
title: request.confirmLabel ?? "Submit",
|
|
951
|
+
data: {
|
|
952
|
+
...baseData,
|
|
953
|
+
verb: TEAMS_INPUT_REQUEST_HUMAN_VERB,
|
|
954
|
+
responseKind: request.kind
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
];
|
|
958
|
+
return createAdaptiveCardAttachment(body, actions);
|
|
959
|
+
}
|
|
960
|
+
function parseTeamsInputRequestSubmit(value) {
|
|
961
|
+
const data = readSubmitData(value);
|
|
962
|
+
const verb = readString2(data, "verb");
|
|
963
|
+
const requestId = readString2(data, "requestId");
|
|
964
|
+
if (!requestId || verb !== TEAMS_INPUT_REQUEST_APPROVAL_VERB && verb !== TEAMS_INPUT_REQUEST_HUMAN_VERB) {
|
|
965
|
+
return void 0;
|
|
966
|
+
}
|
|
967
|
+
const sessionId = readString2(data, "sessionId");
|
|
968
|
+
const turnId = readString2(data, "turnId");
|
|
969
|
+
if (verb === TEAMS_INPUT_REQUEST_APPROVAL_VERB) {
|
|
970
|
+
const action = readApprovalAction(data);
|
|
971
|
+
if (!action) {
|
|
972
|
+
return void 0;
|
|
973
|
+
}
|
|
974
|
+
const feedback = readTrimmedString(data, "feedback");
|
|
975
|
+
const rememberScope = action === "remember" ? readRememberScope(data) : void 0;
|
|
976
|
+
return {
|
|
977
|
+
verb,
|
|
978
|
+
requestId,
|
|
979
|
+
...sessionId ? { sessionId } : {},
|
|
980
|
+
...turnId ? { turnId } : {},
|
|
981
|
+
payload: {
|
|
982
|
+
kind: "approval",
|
|
983
|
+
action,
|
|
984
|
+
...feedback ? { feedback } : {},
|
|
985
|
+
...rememberScope ? { rememberScope } : {}
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
const response = readHumanInputResponse(data);
|
|
990
|
+
if (!response) {
|
|
991
|
+
return void 0;
|
|
992
|
+
}
|
|
993
|
+
return {
|
|
994
|
+
verb,
|
|
995
|
+
requestId,
|
|
996
|
+
...sessionId ? { sessionId } : {},
|
|
997
|
+
...turnId ? { turnId } : {},
|
|
998
|
+
payload: {
|
|
999
|
+
kind: "human",
|
|
1000
|
+
response
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
function createAdaptiveCardAttachment(body, actions) {
|
|
1005
|
+
return {
|
|
1006
|
+
contentType: ADAPTIVE_CARD_CONTENT_TYPE,
|
|
1007
|
+
content: {
|
|
1008
|
+
type: "AdaptiveCard",
|
|
1009
|
+
version: "1.5",
|
|
1010
|
+
body,
|
|
1011
|
+
actions
|
|
1012
|
+
}
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
function normalizeInputRequest(input) {
|
|
1016
|
+
if ("request" in input) {
|
|
1017
|
+
return {
|
|
1018
|
+
request: input.request,
|
|
1019
|
+
sessionId: input.sessionId ?? input.request.sessionId,
|
|
1020
|
+
...input.turnId ? { turnId: input.turnId } : {}
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
return {
|
|
1024
|
+
request: input,
|
|
1025
|
+
sessionId: input.sessionId
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
function formatToolArguments(args, maxChars) {
|
|
1029
|
+
let formatted;
|
|
1030
|
+
try {
|
|
1031
|
+
formatted = JSON.stringify(args, null, 2);
|
|
1032
|
+
} catch {
|
|
1033
|
+
return "";
|
|
1034
|
+
}
|
|
1035
|
+
if (!formatted || formatted === "undefined") {
|
|
1036
|
+
return "";
|
|
1037
|
+
}
|
|
1038
|
+
if (formatted.length <= maxChars) {
|
|
1039
|
+
return formatted;
|
|
1040
|
+
}
|
|
1041
|
+
return `${formatted.slice(0, Math.max(0, maxChars - 1))}...`;
|
|
1042
|
+
}
|
|
1043
|
+
function normalizeRememberScopes(request) {
|
|
1044
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
1045
|
+
"session",
|
|
1046
|
+
"project",
|
|
1047
|
+
"user"
|
|
1048
|
+
]);
|
|
1049
|
+
return (request.rememberScopes ?? []).filter((scope) => allowed.has(scope));
|
|
1050
|
+
}
|
|
1051
|
+
function labelRememberScope(scope) {
|
|
1052
|
+
switch (scope) {
|
|
1053
|
+
case "session":
|
|
1054
|
+
return "This session";
|
|
1055
|
+
case "project":
|
|
1056
|
+
return "This project";
|
|
1057
|
+
case "user":
|
|
1058
|
+
return "My user";
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
function readSubmitData(value) {
|
|
1062
|
+
const record = asRecord(value);
|
|
1063
|
+
const nested = asRecord(record?.data);
|
|
1064
|
+
return {
|
|
1065
|
+
...nested ?? {},
|
|
1066
|
+
...record ?? {}
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
function readHumanInputResponse(data) {
|
|
1070
|
+
const responseKind = readString2(data, "responseKind");
|
|
1071
|
+
switch (responseKind) {
|
|
1072
|
+
case "text": {
|
|
1073
|
+
const text = readString2(data, "text") ?? "";
|
|
1074
|
+
return { kind: "text", text };
|
|
1075
|
+
}
|
|
1076
|
+
case "confirm": {
|
|
1077
|
+
const confirmed = readBoolean(data, "confirmed");
|
|
1078
|
+
if (confirmed === void 0) {
|
|
1079
|
+
return void 0;
|
|
1080
|
+
}
|
|
1081
|
+
const text = readString2(data, "text") ?? (confirmed ? "confirmed" : "denied");
|
|
1082
|
+
return { kind: "confirm", confirmed, text };
|
|
1083
|
+
}
|
|
1084
|
+
case "choice": {
|
|
1085
|
+
const selected = readSelectedValues(data, "selected");
|
|
1086
|
+
return { kind: "choice", selected, text: selected.join(", ") };
|
|
1087
|
+
}
|
|
1088
|
+
default:
|
|
1089
|
+
return void 0;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
function readApprovalAction(data) {
|
|
1093
|
+
const action = readString2(data, "action");
|
|
1094
|
+
return action === "allow" || action === "deny" || action === "remember" ? action : void 0;
|
|
1095
|
+
}
|
|
1096
|
+
function readRememberScope(data) {
|
|
1097
|
+
const scope = readString2(data, "rememberScope");
|
|
1098
|
+
return scope === "session" || scope === "project" || scope === "user" ? scope : void 0;
|
|
1099
|
+
}
|
|
1100
|
+
function readSelectedValues(data, key) {
|
|
1101
|
+
const value = data[key];
|
|
1102
|
+
if (Array.isArray(value)) {
|
|
1103
|
+
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
1104
|
+
}
|
|
1105
|
+
if (typeof value === "string") {
|
|
1106
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
1107
|
+
}
|
|
1108
|
+
return [];
|
|
1109
|
+
}
|
|
1110
|
+
function readTrimmedString(data, key) {
|
|
1111
|
+
return readString2(data, key)?.trim() || void 0;
|
|
1112
|
+
}
|
|
1113
|
+
function readString2(data, key) {
|
|
1114
|
+
const value = data?.[key];
|
|
1115
|
+
return typeof value === "string" ? value : void 0;
|
|
1116
|
+
}
|
|
1117
|
+
function readBoolean(data, key) {
|
|
1118
|
+
const value = data[key];
|
|
1119
|
+
if (typeof value === "boolean") {
|
|
1120
|
+
return value;
|
|
1121
|
+
}
|
|
1122
|
+
if (value === "true") {
|
|
1123
|
+
return true;
|
|
1124
|
+
}
|
|
1125
|
+
if (value === "false") {
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
return void 0;
|
|
1129
|
+
}
|
|
1130
|
+
function asRecord(value) {
|
|
1131
|
+
return value && typeof value === "object" ? value : void 0;
|
|
1132
|
+
}
|
|
771
1133
|
export {
|
|
772
1134
|
TEAMS_ACTIONABLE_MESSAGE_NAMES,
|
|
773
1135
|
TEAMS_ADAPTIVE_CARD_ACTION_NAMES,
|
|
@@ -777,6 +1139,8 @@ export {
|
|
|
777
1139
|
TEAMS_CONFIG_SUBMIT_NAMES,
|
|
778
1140
|
TEAMS_CONVERSATION_UPDATE_EVENT_NAMES,
|
|
779
1141
|
TEAMS_FILE_CONSENT_NAMES,
|
|
1142
|
+
TEAMS_INPUT_REQUEST_APPROVAL_VERB,
|
|
1143
|
+
TEAMS_INPUT_REQUEST_HUMAN_VERB,
|
|
780
1144
|
TEAMS_MEETING_EVENT_NAMES,
|
|
781
1145
|
TEAMS_MEETING_INVOKE_NAMES,
|
|
782
1146
|
TEAMS_MESSAGE_EXTENSION_CARD_BUTTON_CLICKED_NAMES,
|
|
@@ -792,9 +1156,11 @@ export {
|
|
|
792
1156
|
TEAMS_TASK_MODULE_SUBMIT_NAMES,
|
|
793
1157
|
TeamsAttachmentDownloader,
|
|
794
1158
|
TeamsInfo,
|
|
1159
|
+
createTeamsApprovalRequestCard,
|
|
795
1160
|
createTeamsChannelAdapter,
|
|
796
1161
|
createTeamsDialog,
|
|
797
1162
|
createTeamsDialogMessage,
|
|
1163
|
+
createTeamsHumanInputRequestCard,
|
|
798
1164
|
createTeamsInvokeActivity,
|
|
799
1165
|
createTeamsSearchMessage,
|
|
800
1166
|
createTeamsSearchResult,
|
|
@@ -803,6 +1169,7 @@ export {
|
|
|
803
1169
|
parseTeamsActivity,
|
|
804
1170
|
parseTeamsActivitySafe,
|
|
805
1171
|
parseTeamsChannelData,
|
|
1172
|
+
parseTeamsInputRequestSubmit,
|
|
806
1173
|
runWithTeamsTurnContext,
|
|
807
1174
|
sendTeamsInvoke
|
|
808
1175
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cuylabs/agent-channel-teams",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "Teams-native channel layer for @cuylabs/agent-core built on top of @cuylabs/agent-channel-m365",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@microsoft/agents-hosting-extensions-teams": "^1.4.2",
|
|
27
|
-
"@cuylabs/agent-channel-m365": "^3.
|
|
28
|
-
"@cuylabs/agent-core": "^3.
|
|
27
|
+
"@cuylabs/agent-channel-m365": "^3.2.1",
|
|
28
|
+
"@cuylabs/agent-core": "^3.2.1"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@microsoft/agents-activity": "^1.4.2",
|