Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/a365/hosting/turnContextUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ export function getCallerBaggagePairs(turnContext: TurnContextLike): Array<[stri
return [];
}
const from = turnContext.activity.from;
// Fallback chain for userId: aadObjectId (Teams) → agenticUserId (A2A) → from.id (other channels)
const userId = from.aadObjectId || from.agenticUserId || from.id;
const pairs: Array<[string, string | undefined]> = [
[OpenTelemetryConstants.USER_ID_KEY, from.aadObjectId],
[OpenTelemetryConstants.USER_ID_KEY, userId],
[OpenTelemetryConstants.USER_NAME_KEY, from.name],
Comment thread
fpfp100 marked this conversation as resolved.
Outdated
[OpenTelemetryConstants.USER_EMAIL_KEY, from.agenticUserId],
[OpenTelemetryConstants.GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY, from.agenticAppBlueprintId],
Expand Down
1 change: 1 addition & 0 deletions src/a365/hosting/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface ActivityLike {
channelIdSubChannel?: string | unknown;
serviceUrl?: string;
from?: {
id?: string;
aadObjectId?: string;
name?: string;
role?: string;
Expand Down
42 changes: 42 additions & 0 deletions test/internal/unit/a365/hosting/turnContextUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,48 @@ describe("TurnContextUtils", () => {
expect(pairs).toEqual([]);
});

it("should fall back to from.id when aadObjectId is undefined (non-Teams channel)", () => {
const ctx: TurnContextLike = {
activity: {
from: { id: "webchat-user-123", name: "Web User" },
},
turnState: new Map(),
};
const pairs = getCallerBaggagePairs(ctx);
const obj = Object.fromEntries(pairs);
expect(obj[OpenTelemetryConstants.USER_ID_KEY]).toBe("webchat-user-123");
expect(obj[OpenTelemetryConstants.USER_NAME_KEY]).toBe("Web User");
});

it("should fall back to agenticUserId when aadObjectId is undefined (A2A)", () => {
const ctx: TurnContextLike = {
activity: {
from: { agenticUserId: "agent@contoso.com", name: "Upstream Agent" },
},
turnState: new Map(),
};
const pairs = getCallerBaggagePairs(ctx);
const obj = Object.fromEntries(pairs);
expect(obj[OpenTelemetryConstants.USER_ID_KEY]).toBe("agent@contoso.com");
});

it("should prefer aadObjectId over agenticUserId and from.id", () => {
const ctx: TurnContextLike = {
activity: {
from: {
id: "fallback-id",
aadObjectId: "aad-oid",
agenticUserId: "agent@contoso.com",
name: "User",
},
},
turnState: new Map(),
};
const pairs = getCallerBaggagePairs(ctx);
const obj = Object.fromEntries(pairs);
expect(obj[OpenTelemetryConstants.USER_ID_KEY]).toBe("aad-oid");
});

it("should filter out undefined/empty values", () => {
const ctx: TurnContextLike = {
activity: { from: { name: "User", aadObjectId: "" } },
Expand Down
Loading