@microsoft/teams.apps
Version:
<p> <a href="https://www.npmjs.com/package/@microsoft/teams.apps" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.apps/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.apps?activeTab=code
212 lines • 14.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Agent365BaggageKeys = void 0;
exports.withAgent365Baggage = withAgent365Baggage;
exports.agent365BaggageFromActivity = agent365BaggageFromActivity;
exports.createAgent365Scope = createAgent365Scope;
const api_1 = require("@opentelemetry/api");
const teams_api_1 = require("@microsoft/teams.api");
/**
* Agent365-compatible baggage keys populated by the SDK. Exported so app code
* can read or extend the same shape when creating scopes with an OpenTelemetry distro.
*/
exports.Agent365BaggageKeys = {
/**
* Microsoft 365 tenant identifier for the operation.
*/
tenantId: 'microsoft.tenant.id',
/**
* Teams conversation identifier used as the Agent365 conversation/session correlation id.
*/
conversationId: 'gen_ai.conversation.id',
/**
* Link or service URL associated with the Teams conversation item.
*/
conversationItemLink: 'microsoft.conversation.item.link',
/**
* Teams channel identifier, such as `msteams`.
*/
channelName: 'microsoft.channel.name',
/**
* Optional channel link supplied by the app when it has one.
*/
channelLink: 'microsoft.channel.link',
/**
* Agent or bot identifier. Agentic app instance id is preferred when present.
*/
agentId: 'gen_ai.agent.id',
/**
* Agent or bot display name. Only set when `include` contains `agentName`.
*/
agentName: 'gen_ai.agent.name',
/**
* Agent365 user identifier for the user-backed AgenticIdentity the operation acts as.
*/
agenticUserId: 'microsoft.agent.user.id',
/**
* Agent365 blueprint identifier backing the agentic app.
*/
agentBlueprintId: 'microsoft.a365.agent.blueprint.id',
/**
* Caller display name. Only set when `include` contains `senderName`.
*/
userName: 'user.name',
/**
* Logical operation source for downstream Agent365 telemetry correlation.
*/
operationSource: 'service.name',
/**
* Caller user identifier. Azure AD object id is preferred when present.
*/
userId: 'user.id',
/**
* Caller email address. Only set when `include` contains `senderEmail`.
*/
userEmail: 'user.email',
/**
* Agent description or role metadata. Only set when `include` contains `agentDescription`.
*/
agentDescription: 'gen_ai.agent.description',
/**
* Agent365 user email address. Only set when `include` contains `agentEmail`.
*/
agenticUserEmail: 'microsoft.agent.user.email',
};
/**
* Runs `fn` with the supplied Agent365 baggage layered onto the active context.
* Supplied values win over existing baggage. Use in proactive flows to open an
* identity scope before creating the span it should describe.
*
* @param values the baggage entries to set. Blank and non-finite values are skipped.
* @param fn the function to run inside the scope. Its return value is passed through.
*/
function withAgent365Baggage(values, fn) {
return runWithBaggage(values, fn);
}
/**
* Baggage key for each opt-in personal-data field.
*/
const INCLUDE_BAGGAGE_KEYS = {
senderName: exports.Agent365BaggageKeys.userName,
senderEmail: exports.Agent365BaggageKeys.userEmail,
agentName: exports.Agent365BaggageKeys.agentName,
agentEmail: exports.Agent365BaggageKeys.agenticUserEmail,
agentDescription: exports.Agent365BaggageKeys.agentDescription,
};
/**
* @internal
* Resolves the baggage entries an inbound activity contributes.
*/
function agent365BaggageFromActivity(activity, options) {
return toBaggageEntries({
tenantId: activity.recipient?.tenantId
?? activity.conversation?.tenantId
?? activity.channelData?.tenant?.id,
conversationId: activity.conversation?.id,
conversationItemLink: activity.serviceUrl,
channelName: activity.channelId,
agentId: activity.recipient?.agenticAppId ?? activity.recipient?.id,
agenticUserId: activity.recipient?.agenticUserId,
agentBlueprintId: activity.recipient?.agenticAppBlueprintId,
userId: activity.from?.aadObjectId ?? activity.from?.id,
senderName: activity.from?.name,
senderEmail: activity.from?.email,
agentName: activity.recipient?.name,
agentEmail: activity.recipient?.email,
agentDescription: activity.recipient?.userRole,
}, options);
}
/**
* Builds a reusable {@link Agent365ScopeOpener} bound to one set of options.
* Pass the same options given to `App`'s `telemetry.agent365` so proactive
* baggage matches reactive baggage, and build one per host to share.
*
* ```ts
* const withScope = createAgent365Scope({ operationSource: 'nightly-digest' });
* await withScope({ agenticIdentity, conversationId }, () => runJob());
* ```
*
* @param options host-wide baggage defaults and personal-data policy. Pass
* `false` to disable the bridge, which returns an opener that runs `fn`
* without touching the ambient context.
*/
function createAgent365Scope(options) {
if (options === false) {
return (_scope, fn) => fn();
}
const bound = options ?? {};
return (scope, fn) => {
const agenticIdentity = scope.agenticIdentity;
const userBackedIdentity = agenticIdentity && (0, teams_api_1.isUserBackedAgenticIdentity)(agenticIdentity)
? agenticIdentity
: undefined;
return withAgent365Baggage({
...toBaggageEntries({
tenantId: agenticIdentity?.tenantId,
conversationId: scope.conversationId,
conversationItemLink: bound.serviceUrl,
channelName: bound.channelName,
agentId: agenticIdentity?.agenticAppId ?? bound.agentId,
agenticUserId: userBackedIdentity?.agenticUserId,
agentBlueprintId: agenticIdentity?.agenticAppBlueprintId,
userId: scope.userId,
senderName: scope.senderName,
senderEmail: scope.senderEmail,
agentName: scope.agentName,
agentEmail: scope.agentEmail,
agentDescription: scope.agentDescription,
}, bound),
...scope.additionalBaggage,
}, fn);
};
}
/**
* Maps a resolved source onto baggage keys and gates personal data behind
* `include`. `additionalBaggage` merges last.
*/
function toBaggageEntries(source, options) {
const entries = {
[exports.Agent365BaggageKeys.tenantId]: source.tenantId,
[exports.Agent365BaggageKeys.conversationId]: source.conversationId,
[exports.Agent365BaggageKeys.conversationItemLink]: source.conversationItemLink,
[exports.Agent365BaggageKeys.channelName]: source.channelName,
[exports.Agent365BaggageKeys.agentId]: source.agentId,
[exports.Agent365BaggageKeys.agenticUserId]: source.agenticUserId,
[exports.Agent365BaggageKeys.agentBlueprintId]: source.agentBlueprintId,
[exports.Agent365BaggageKeys.userId]: source.userId,
[exports.Agent365BaggageKeys.channelLink]: options.channelLink,
[exports.Agent365BaggageKeys.operationSource]: options.operationSource,
};
for (const include of options.include ?? []) {
entries[INCLUDE_BAGGAGE_KEYS[include]] = source[include];
}
return { ...entries, ...options.additionalBaggage };
}
function runWithBaggage(values, fn) {
let baggage = api_1.propagation.getActiveBaggage() ?? api_1.propagation.createBaggage();
let changed = false;
for (const [key, value] of Object.entries(values)) {
const baggageKey = key.trim();
const baggageValue = normalizeBaggageValue(value);
if (!baggageKey || baggageValue === undefined) {
continue;
}
baggage = baggage.setEntry(baggageKey, { value: baggageValue });
changed = true;
}
if (!changed) {
return fn();
}
return api_1.context.with(api_1.propagation.setBaggage(api_1.context.active(), baggage), fn);
}
function normalizeBaggageValue(value) {
if (value === null || value === undefined) {
return undefined;
}
if (typeof value === 'number' && !Number.isFinite(value)) {
return undefined;
}
const normalized = `${value}`.trim();
return normalized ? normalized : undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQzNjUtYmFnZ2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWFnbm9zdGljcy9hZ2VudDM2NS1iYWdnYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWtKQSxrREFFQztBQXNDRCxrRUFxQkM7QUEyR0Qsa0RBd0NDO0FBbFdELDRDQUF5RTtBQUV6RSxvREFBd0c7QUFtQnhHOzs7R0FHRztBQUNVLFFBQUEsbUJBQW1CLEdBQUc7SUFDakM7O09BRUc7SUFDSCxRQUFRLEVBQUUscUJBQXFCO0lBRS9COztPQUVHO0lBQ0gsY0FBYyxFQUFFLHdCQUF3QjtJQUV4Qzs7T0FFRztJQUNILG9CQUFvQixFQUFFLGtDQUFrQztJQUV4RDs7T0FFRztJQUNILFdBQVcsRUFBRSx3QkFBd0I7SUFFckM7O09BRUc7SUFDSCxXQUFXLEVBQUUsd0JBQXdCO0lBRXJDOztPQUVHO0lBQ0gsT0FBTyxFQUFFLGlCQUFpQjtJQUUxQjs7T0FFRztJQUNILFNBQVMsRUFBRSxtQkFBbUI7SUFFOUI7O09BRUc7SUFDSCxhQUFhLEVBQUUseUJBQXlCO0lBRXhDOztPQUVHO0lBQ0gsZ0JBQWdCLEVBQUUsbUNBQW1DO0lBRXJEOztPQUVHO0lBQ0gsUUFBUSxFQUFFLFdBQVc7SUFFckI7O09BRUc7SUFDSCxlQUFlLEVBQUUsY0FBYztJQUUvQjs7T0FFRztJQUNILE1BQU0sRUFBRSxTQUFTO0lBRWpCOztPQUVHO0lBQ0gsU0FBUyxFQUFFLFlBQVk7SUFFdkI7O09BRUc7SUFDSCxnQkFBZ0IsRUFBRSwwQkFBMEI7SUFFNUM7O09BRUc7SUFDSCxnQkFBZ0IsRUFBRSw0QkFBNEI7Q0FDdEMsQ0FBQztBQXNDWDs7Ozs7OztHQU9HO0FBQ0gsU0FBZ0IsbUJBQW1CLENBQUksTUFBOEIsRUFBRSxFQUFXO0lBQ2hGLE9BQU8sY0FBYyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBdUJEOztHQUVHO0FBQ0gsTUFBTSxvQkFB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