@open-everywhere/provider-teams 0.0.0-stage → 0.1.0
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/LICENSE +201 -0
- package/NOTICE +21 -0
- package/README.md +46 -2
- package/agent/channels/teams-bot-name.ts +162 -0
- package/agent/channels/teams-catch-up.ts +244 -0
- package/agent/channels/teams-connector.ts +183 -0
- package/agent/channels/teams-conversation-ref.ts +398 -0
- package/agent/channels/teams-directory.ts +193 -0
- package/agent/channels/teams-engagement.ts +391 -0
- package/agent/channels/teams-fire-eligibility.ts +152 -0
- package/agent/channels/teams-front.ts +1404 -0
- package/agent/channels/teams-graph-boundary.ts +178 -0
- package/agent/channels/teams-graph-team-id.ts +106 -0
- package/agent/channels/teams-id-restore.ts +131 -0
- package/agent/channels/teams-identity.ts +395 -0
- package/agent/channels/teams-input-response.ts +129 -0
- package/agent/channels/teams-message-ops.ts +79 -0
- package/agent/channels/teams-origin-codec.ts +104 -0
- package/agent/channels/teams-post-arm.ts +323 -0
- package/agent/channels/teams-reaction-feedback.ts +127 -0
- package/agent/channels/teams-read.ts +510 -0
- package/agent/channels/teams-roster.ts +136 -0
- package/agent/channels/teams-stop.ts +319 -0
- package/agent/channels/teams-supervisor.ts +638 -0
- package/agent/channels/teams.ts +270 -0
- package/agent/contributions.ts +31 -0
- package/agent/docs-generated.ts +15 -0
- package/agent/ops.ts +129 -0
- package/agent/provider-events.ts +69 -0
- package/agent/register.ts +219 -0
- package/agent/surface-parity.ts +112 -0
- package/dist/agent/channels/teams-bot-name.d.ts +36 -0
- package/dist/agent/channels/teams-bot-name.d.ts.map +1 -0
- package/dist/agent/channels/teams-bot-name.js +141 -0
- package/dist/agent/channels/teams-bot-name.js.map +1 -0
- package/dist/agent/channels/teams-catch-up.d.ts +53 -0
- package/dist/agent/channels/teams-catch-up.d.ts.map +1 -0
- package/dist/agent/channels/teams-catch-up.js +221 -0
- package/dist/agent/channels/teams-catch-up.js.map +1 -0
- package/dist/agent/channels/teams-connector.d.ts +57 -0
- package/dist/agent/channels/teams-connector.d.ts.map +1 -0
- package/dist/agent/channels/teams-connector.js +132 -0
- package/dist/agent/channels/teams-connector.js.map +1 -0
- package/dist/agent/channels/teams-conversation-ref.d.ts +123 -0
- package/dist/agent/channels/teams-conversation-ref.d.ts.map +1 -0
- package/dist/agent/channels/teams-conversation-ref.js +368 -0
- package/dist/agent/channels/teams-conversation-ref.js.map +1 -0
- package/dist/agent/channels/teams-directory.d.ts +11 -0
- package/dist/agent/channels/teams-directory.d.ts.map +1 -0
- package/dist/agent/channels/teams-directory.js +179 -0
- package/dist/agent/channels/teams-directory.js.map +1 -0
- package/dist/agent/channels/teams-engagement.d.ts +174 -0
- package/dist/agent/channels/teams-engagement.d.ts.map +1 -0
- package/dist/agent/channels/teams-engagement.js +336 -0
- package/dist/agent/channels/teams-engagement.js.map +1 -0
- package/dist/agent/channels/teams-fire-eligibility.d.ts +26 -0
- package/dist/agent/channels/teams-fire-eligibility.d.ts.map +1 -0
- package/dist/agent/channels/teams-fire-eligibility.js +126 -0
- package/dist/agent/channels/teams-fire-eligibility.js.map +1 -0
- package/dist/agent/channels/teams-front.d.ts +249 -0
- package/dist/agent/channels/teams-front.d.ts.map +1 -0
- package/dist/agent/channels/teams-front.js +1143 -0
- package/dist/agent/channels/teams-front.js.map +1 -0
- package/dist/agent/channels/teams-graph-boundary.d.ts +45 -0
- package/dist/agent/channels/teams-graph-boundary.d.ts.map +1 -0
- package/dist/agent/channels/teams-graph-boundary.js +168 -0
- package/dist/agent/channels/teams-graph-boundary.js.map +1 -0
- package/dist/agent/channels/teams-graph-team-id.d.ts +30 -0
- package/dist/agent/channels/teams-graph-team-id.d.ts.map +1 -0
- package/dist/agent/channels/teams-graph-team-id.js +89 -0
- package/dist/agent/channels/teams-graph-team-id.js.map +1 -0
- package/dist/agent/channels/teams-id-restore.d.ts +34 -0
- package/dist/agent/channels/teams-id-restore.d.ts.map +1 -0
- package/dist/agent/channels/teams-id-restore.js +123 -0
- package/dist/agent/channels/teams-id-restore.js.map +1 -0
- package/dist/agent/channels/teams-identity.d.ts +148 -0
- package/dist/agent/channels/teams-identity.d.ts.map +1 -0
- package/dist/agent/channels/teams-identity.js +336 -0
- package/dist/agent/channels/teams-identity.js.map +1 -0
- package/dist/agent/channels/teams-input-response.d.ts +23 -0
- package/dist/agent/channels/teams-input-response.d.ts.map +1 -0
- package/dist/agent/channels/teams-input-response.js +102 -0
- package/dist/agent/channels/teams-input-response.js.map +1 -0
- package/dist/agent/channels/teams-message-ops.d.ts +3 -0
- package/dist/agent/channels/teams-message-ops.d.ts.map +1 -0
- package/dist/agent/channels/teams-message-ops.js +72 -0
- package/dist/agent/channels/teams-message-ops.js.map +1 -0
- package/dist/agent/channels/teams-origin-codec.d.ts +16 -0
- package/dist/agent/channels/teams-origin-codec.d.ts.map +1 -0
- package/dist/agent/channels/teams-origin-codec.js +99 -0
- package/dist/agent/channels/teams-origin-codec.js.map +1 -0
- package/dist/agent/channels/teams-post-arm.d.ts +37 -0
- package/dist/agent/channels/teams-post-arm.d.ts.map +1 -0
- package/dist/agent/channels/teams-post-arm.js +280 -0
- package/dist/agent/channels/teams-post-arm.js.map +1 -0
- package/dist/agent/channels/teams-reaction-feedback.d.ts +22 -0
- package/dist/agent/channels/teams-reaction-feedback.d.ts.map +1 -0
- package/dist/agent/channels/teams-reaction-feedback.js +108 -0
- package/dist/agent/channels/teams-reaction-feedback.js.map +1 -0
- package/dist/agent/channels/teams-read.d.ts +127 -0
- package/dist/agent/channels/teams-read.d.ts.map +1 -0
- package/dist/agent/channels/teams-read.js +424 -0
- package/dist/agent/channels/teams-read.js.map +1 -0
- package/dist/agent/channels/teams-roster.d.ts +54 -0
- package/dist/agent/channels/teams-roster.d.ts.map +1 -0
- package/dist/agent/channels/teams-roster.js +121 -0
- package/dist/agent/channels/teams-roster.js.map +1 -0
- package/dist/agent/channels/teams-stop.d.ts +74 -0
- package/dist/agent/channels/teams-stop.d.ts.map +1 -0
- package/dist/agent/channels/teams-stop.js +252 -0
- package/dist/agent/channels/teams-stop.js.map +1 -0
- package/dist/agent/channels/teams-supervisor.d.ts +351 -0
- package/dist/agent/channels/teams-supervisor.d.ts.map +1 -0
- package/dist/agent/channels/teams-supervisor.js +366 -0
- package/dist/agent/channels/teams-supervisor.js.map +1 -0
- package/dist/agent/channels/teams.d.ts +5 -0
- package/dist/agent/channels/teams.d.ts.map +1 -0
- package/dist/agent/channels/teams.js +246 -0
- package/dist/agent/channels/teams.js.map +1 -0
- package/dist/agent/contributions.d.ts +12 -0
- package/dist/agent/contributions.d.ts.map +1 -0
- package/dist/agent/contributions.js +31 -0
- package/dist/agent/contributions.js.map +1 -0
- package/dist/agent/docs-generated.d.ts +3 -0
- package/dist/agent/docs-generated.d.ts.map +1 -0
- package/dist/agent/docs-generated.js +13 -0
- package/dist/agent/docs-generated.js.map +1 -0
- package/dist/agent/ops.d.ts +14 -0
- package/dist/agent/ops.d.ts.map +1 -0
- package/dist/agent/ops.js +122 -0
- package/dist/agent/ops.js.map +1 -0
- package/dist/agent/provider-events.d.ts +3 -0
- package/dist/agent/provider-events.d.ts.map +1 -0
- package/dist/agent/provider-events.js +67 -0
- package/dist/agent/provider-events.js.map +1 -0
- package/dist/agent/register.d.ts +16 -0
- package/dist/agent/register.d.ts.map +1 -0
- package/dist/agent/register.js +198 -0
- package/dist/agent/register.js.map +1 -0
- package/dist/agent/surface-parity.d.ts +3 -0
- package/dist/agent/surface-parity.d.ts.map +1 -0
- package/dist/agent/surface-parity.js +106 -0
- package/dist/agent/surface-parity.js.map +1 -0
- package/package.json +183 -4
- package/tsconfig.build.json +22 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
// The Microsoft Teams SINGLE-WINDOW core — the eve-FREE tested half of the Teams cross-surface
|
|
2
|
+
// window legs (the FIFTH surface after Slack/GitHub/Linear/Notion; teams-front.ts is the live
|
|
3
|
+
// wiring). Teams is deliberately NARROWER than the other surfaces: it has no per-conversation
|
|
4
|
+
// ambient supervisor of its own, so this core exists ONLY for the single-window mode — every
|
|
5
|
+
// dispatch that reaches it carries a window and is delivered into the synthetic `unified`
|
|
6
|
+
// channel (channels/unified.ts). Flag-off, teams-front forwards every activity to eve's native
|
|
7
|
+
// teamsChannel untouched and nothing in this file runs: byte-identical.
|
|
8
|
+
//
|
|
9
|
+
// WHAT'S REUSED WHOLESALE (zero Teams-specific logic in any of it):
|
|
10
|
+
// • singleWindowMentionPolicy — the ONE shared mention seam — unified-window.ts
|
|
11
|
+
// • renderWake + the channel-watch / direct-mention preambles — normalized-wake.ts
|
|
12
|
+
// • shouldRotate — the pure rotation policy — slack-events.ts (via the live deps)
|
|
13
|
+
// WHAT'S NEW (this file): the Teams PRIVACY FLOOR (the load-bearing decision — see
|
|
14
|
+
// teamsSingleWindowPrivacyOk), the single-window plan, the NormalizedWake builder, and the
|
|
15
|
+
// dispatch core (session get-or-create → build → wake), each mirroring
|
|
16
|
+
// the Notion equivalents (planNotionSingleWindow / buildNotionSupervisorWake /
|
|
17
|
+
// handleNotionSupervisorDispatch) — the closest prior single-leg surface.
|
|
18
|
+
//
|
|
19
|
+
// SINGLE-LEG BY CONSTRUCTION (the Slack build's hard-won lesson): Slack fires TWO webhooks for
|
|
20
|
+
// one @mention (app_mention + its message.channels sibling), and the original two-leg
|
|
21
|
+
// suppress/deliver design could disagree across webhooks and LOSE the mention — the fix was to
|
|
22
|
+
// divert the mention event itself in one leg. Teams never had the hazard: ONE Bot-Framework
|
|
23
|
+
// activity per message, ONE synchronous policy read (the vouch register is a set lookup — no
|
|
24
|
+
// network, no TTL cache to go stale between legs), ONE verdict driving both "suppress the
|
|
25
|
+
// native forward" and "deliver as an addressed wake". There is no second webhook to coordinate
|
|
26
|
+
// with, so neither a lost mention nor a double answer is structurally possible.
|
|
27
|
+
import { spreadVendorTs, renderWake, mkMessageTrigger, mintWakeId, singleWindowMentionPolicy, tailAuthorGrain, seatCatchUpSinceMs, catchUpUnavailableReason, } from "@open-everywhere/core/agent/adapter-api.js";
|
|
28
|
+
/** The catch-up's REACHBACK FLOOR (hours): how far back a seat that has been quiet for a long time
|
|
29
|
+
* reads. 7 days, the same floor every other surface uses. */
|
|
30
|
+
const TEAMS_CATCH_UP_REACHBACK_HOURS = 168;
|
|
31
|
+
/**
|
|
32
|
+
* What a seat is told when THIS wake could not resolve the team's Graph address (OPE-1808). TRUSTED,
|
|
33
|
+
* OE-authored and CONSTANT, the same posture as core's `catchUpUnavailableReason`, and deliberately
|
|
34
|
+
* NOT that sentence: this bound is about one wake, not about the surface, and the seat must not be
|
|
35
|
+
* told Teams cannot read its own history when the next wake may read it perfectly well. It states the
|
|
36
|
+
* bound the seat has to act on either way — an empty context here is not evidence of a quiet room.
|
|
37
|
+
*/
|
|
38
|
+
const TEAM_ADDRESS_UNRESOLVED_NOTE = "teams: this team's Microsoft 365 group id could not be resolved on this wake, so the channel's history since your last wake is NOT shown. That is a failure to READ, not a quiet room — an absence of messages here says nothing about what was said.";
|
|
39
|
+
// --- supervisor token / sentinel (carry the :oe-sup:g infix — load-bearing) ----------
|
|
40
|
+
//
|
|
41
|
+
// hooks/spend.ts isSupervisorToken keys off the `:oe-sup:g` substring to (a) tag the usage-event
|
|
42
|
+
// `kind="supervisor"` and (b) drive the per-generation cumulative-token rotation counter. Carry
|
|
43
|
+
// the infix and the whole cost/rotation apparatus works for free. In practice Teams only ever
|
|
44
|
+
// dispatches on a unified singleWindow grain (the token is unifiedSupervisorToken's), so this
|
|
45
|
+
// per-container form exists for supervisorTokenForGrain's `perContainer` thunk + shape parity
|
|
46
|
+
// with the other surfaces (notionSupervisorToken et al.), not as a live path.
|
|
47
|
+
/** The reserved pseudo-thread sentinel for a supervisor generation (mirrors Slack's). */
|
|
48
|
+
function teamsSupervisorSentinel(generation) {
|
|
49
|
+
return `oe-sup:g${generation}`;
|
|
50
|
+
}
|
|
51
|
+
/** The per-container supervisor token for a Teams channel container (the grain fallback —
|
|
52
|
+
* see the header note; a live Teams dispatch always resolves the unified domain token). */
|
|
53
|
+
export function teamsSupervisorToken(channelKey, generation) {
|
|
54
|
+
return `teams:${channelKey}:${teamsSupervisorSentinel(generation)}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The Teams privacy floor for the cross-surface window, FAIL-CLOSED. Every surface has one so a
|
|
58
|
+
* public/external surface can never join a private shared window (GitHub: `repository.private
|
|
59
|
+
* === true`; Slack: positively-confirmed-internal channel/group; Linear: team positively
|
|
60
|
+
* private; Notion: operator vouch). Teams' rule:
|
|
61
|
+
*
|
|
62
|
+
* ADMIT ⟺ scope === "channel" AND tenantId present AND membershipType ≠ "shared"
|
|
63
|
+
* AND the OPERATOR VOUCHED the surface (vouch register / OE_TRUST=internal).
|
|
64
|
+
*
|
|
65
|
+
* WHY OPERATOR-VOUCH AND NOT A PLATFORM SIGNAL (the Notion posture, deliberately): Teams has NO
|
|
66
|
+
* reliable in-band fact that means "internal-only, no external eyes".
|
|
67
|
+
* • `membershipType` is usually ABSENT on inbound activities, and even when positively
|
|
68
|
+
* "standard" or "private" it does NOT exclude tenant GUESTS — a guest (an external identity
|
|
69
|
+
* invited into the tenant) sees every standard channel of the teams they're on, and can be a
|
|
70
|
+
* member of private channels too. So the memory-gate verdict (teams-identity.ts teamsTrust,
|
|
71
|
+
* which reads standard/private+tenant as internal) is deliberately NOT sufficient here —
|
|
72
|
+
* the window floor is STRICTER than the memory floor.
|
|
73
|
+
* • A Graph roster sweep (TeamMember.Read.All → userType === "Guest") could positively prove
|
|
74
|
+
* guest-freedom, but OE has no Graph credential plane wired (the bot speaks Bot Connector
|
|
75
|
+
* only), the sweep is racy (membership changes after the check), and Bot-Framework
|
|
76
|
+
* pagedMembers' `userRole` is not a documented-reliable field — inventing a weaker signal
|
|
77
|
+
* is exactly what the floor doctrine forbids. So: the operator vouches, code enforces.
|
|
78
|
+
*
|
|
79
|
+
* ATTACKER ANALYSIS: the leak vector is a message from a surface visible outside the org being
|
|
80
|
+
* admitted to (and answered from) a private cross-surface window. All four conjuncts are
|
|
81
|
+
* host-derived: scope/membershipType/tenantId come off the Bot-Connector-signed activity (a
|
|
82
|
+
* user cannot author channelData — the Teams service stamps it), and the vouch is the
|
|
83
|
+
* operator's own register. Absence of membershipType never ADMITS (only the vouch admits;
|
|
84
|
+
* membershipType only REFUSES). The one positive-external fact we CAN see — membershipType ===
|
|
85
|
+
* "shared", a Teams Connect shared channel spanning tenants — refuses EVEN WHEN VOUCHED (a
|
|
86
|
+
* positive cross-org fact beats a standing assertion). BUT membershipType is usually ABSENT
|
|
87
|
+
* inbound, and an absent signal never demotes, so that guard catches only the rooms Teams labels
|
|
88
|
+
* for us.
|
|
89
|
+
*
|
|
90
|
+
* 🔴 THERE IS NO EXACT-GRAIN BACKSTOP BEHIND IT — the operator's declaration IS the protection.
|
|
91
|
+
* `isVouchedSurface` walks the declaration rungs (OPE-1521), the same most-specific-wins walk every
|
|
92
|
+
* other trust reader uses, and since OPE-1538 the wiring hands it the TEAM rung too, so the walk
|
|
93
|
+
* here has the same reach the binding and memory planes have: a `public` `teams/<tenant>/team:<id>`
|
|
94
|
+
* carve-out now demotes one team out of an internal tenant at this floor, where it used to be
|
|
95
|
+
* skipped and the room admitted. A coarse `teams/<tenant>` declaration still admits EVERY room under
|
|
96
|
+
* that tenant that no narrower entry demotes. `agent/identity/surfaces.ts` ships exactly such a tenant line today. A native
|
|
97
|
+
* internal channel and a cross-tenant Connect/shared channel look alike at that grain, so a
|
|
98
|
+
* shared room whose inbound activities omit membershipType IS admitted on the tenant line. That is
|
|
99
|
+
* the ruling, not a gap: a declaration vouches, and only a POSITIVE external signal demotes. The
|
|
100
|
+
* operator narrows the reach by declaring the channel rung instead. This floor admits or refuses a
|
|
101
|
+
* room that is ALREADY a window member — it enrolls nobody; the domain CONFIG
|
|
102
|
+
* (`agent/memory/config/domains.ts`, read by teams-front.ts) enrolls. Do not read that as a second
|
|
103
|
+
* bound on the reach: a domain's container `reach` entry is legal at TENANT grain, so a tenant claim
|
|
104
|
+
* beside a tenant declaration puts every room in the tenant through this floor, and config load
|
|
105
|
+
* cannot enumerate them. In-tree domains name exact channels today. Residual: the standing
|
|
106
|
+
* "operator vouched something they shouldn't have" residual every vouch surface carries (identical
|
|
107
|
+
* to vouching a web-published Notion page) — now at whatever grain the operator wrote, so a tenant
|
|
108
|
+
* declaration carries it for the whole tenant. Personal and group chats
|
|
109
|
+
* are refused outright: they are per-person surfaces, not org containers, mirroring Slack's
|
|
110
|
+
* channels/groups-only rule. Residual acceptance: a vouched tenant/channel that LATER gains a
|
|
111
|
+
* guest is admitted until the operator retracts the vouch — the documented trade of the vouch
|
|
112
|
+
* posture (identical to Notion's), and strictly safer than any inference we could make.
|
|
113
|
+
*/
|
|
114
|
+
export function teamsSingleWindowPrivacyOk(f) {
|
|
115
|
+
if (f.scope !== "channel")
|
|
116
|
+
return false; // personal/groupChat/unknown never join the shared window
|
|
117
|
+
if (!f.tenantId)
|
|
118
|
+
return false; // no org anchor → fail closed
|
|
119
|
+
if (f.membershipType === "shared")
|
|
120
|
+
return false; // positively cross-tenant → refuse even when vouched
|
|
121
|
+
return f.vouched === true; // the operator's vouch is the ONLY admitting signal
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The LIVE-shaped single-window mention decision for one Teams activity — the Teams arm of the
|
|
125
|
+
* shared seam (unified-window.ts {@link singleWindowMentionPolicy}), next to the Slack
|
|
126
|
+
* equivalent (slack-events.ts slackSingleWindowMentionPolicy). Pure and SYNCHRONOUS (the floor
|
|
127
|
+
* needs no network — the vouch register is a set lookup), which is what makes the Teams legs
|
|
128
|
+
* single-leg by construction: one verdict, no cache to go stale between a suppress read and a
|
|
129
|
+
* deliver read. Fail-closed throughout: singleWindow off, or any floor conjunct failing, yields
|
|
130
|
+
* today's split (native owns the mention, no addressed wake).
|
|
131
|
+
*/
|
|
132
|
+
function teamsSingleWindowMentionPolicy(singleWindow, isMention, facts) {
|
|
133
|
+
return singleWindowMentionPolicy(singleWindow, isMention, teamsSingleWindowPrivacyOk(facts));
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The ONE single-window decision for a Teams delivery, mirroring planNotionSingleWindow: given
|
|
137
|
+
* the grain's `singleWindow`, whether the activity @mentions the bot, the PRIVACY-FLOOR facts,
|
|
138
|
+
* and the frozen reply target, return the {@link UnifiedWindowWake} the dispatch should carry —
|
|
139
|
+
* or undefined for the byte-identical native path (teams-front then FORWARDS the activity to
|
|
140
|
+
* eve's native teamsChannel exactly as today).
|
|
141
|
+
*
|
|
142
|
+
* Teams' mention signal lives in ONE Bot-Framework activity (no Slack-style dual event), and its
|
|
143
|
+
* "native" handler is the forward this plan suppresses — so suppress-native and divert are the
|
|
144
|
+
* SAME act, both read off this one verdict (never a double turn, never a gap):
|
|
145
|
+
* • @mention on a singleWindow, floor-passing channel → the seam suppresses the native forward
|
|
146
|
+
* and stamps `addressing:"direct-mention"` (the terminal-prose delivery bridge's arm);
|
|
147
|
+
* • ambient (non-mention) channel message on the same surface → Leg A: the window WITHOUT the
|
|
148
|
+
* addressed stamp (judged treatment in the shared window, prose stays hard-dropped);
|
|
149
|
+
* • floor fails, singleWindow off, or no routable reply target → undefined (forward — a
|
|
150
|
+
* mention then keeps today's native conversation-session turn).
|
|
151
|
+
*/
|
|
152
|
+
export function planTeamsSingleWindow(singleWindow, isMention, facts, target) {
|
|
153
|
+
const policy = teamsSingleWindowMentionPolicy(singleWindow, isMention, facts);
|
|
154
|
+
// A mention diverts iff the seam suppresses the native forward; an ambient message diverts on
|
|
155
|
+
// the same `singleWindow && privacyOk` floor (Leg A). Both derive from the seam's one predicate.
|
|
156
|
+
const divert = isMention ? policy.suppressNative : singleWindow && teamsSingleWindowPrivacyOk(facts);
|
|
157
|
+
if (!divert)
|
|
158
|
+
return undefined;
|
|
159
|
+
if (!target.serviceUrl || !target.conversationId)
|
|
160
|
+
return undefined; // no frozen reply target ⇒ no window (fail closed)
|
|
161
|
+
return {
|
|
162
|
+
wakeId: mintWakeId(),
|
|
163
|
+
origin: {
|
|
164
|
+
platform: "teams",
|
|
165
|
+
serviceUrl: target.serviceUrl,
|
|
166
|
+
conversationId: target.conversationId,
|
|
167
|
+
...(target.replyToActivityId ? { replyToActivityId: target.replyToActivityId } : {}),
|
|
168
|
+
...(target.tenantId ? { tenantId: target.tenantId } : {}),
|
|
169
|
+
},
|
|
170
|
+
// ADDRESSED @mention ⇒ the seam's stamp marks the wake as OWED a reply, so the envelope tells
|
|
171
|
+
// the seat it owes an answer through the `reply` tool. Ambient wakes omit it. It is not a delivery
|
|
172
|
+
// path: a turn that ends in prose is dropped and re-driven once, on every addressing (OPE-1982).
|
|
173
|
+
...(policy.addressing !== undefined ? { addressing: policy.addressing } : {}),
|
|
174
|
+
...spreadVendorTs(target.vendorTs),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Build the NormalizedWake for one Teams single-window turn. platform "teams", containerNoun
|
|
179
|
+
* "channel" (a Teams channel is a channel), locus.channel = the Teams channel, locus.thread =
|
|
180
|
+
* the reply chain the trigger sat in (when it did). NO PLATFORM-FETCH BOOTSTRAP: the Bot Connector
|
|
181
|
+
* API this wake arrives over has no message-history read (unlike Slack's conversations.history), so a
|
|
182
|
+
* FRESH generation carries the RECORDED TAIL of the outgoing generation (OPE-794) and nothing else —
|
|
183
|
+
* which is why the recorded ring matters more on Teams than anywhere else. A Teams seat with no
|
|
184
|
+
* recorded tail opens cold, honestly.
|
|
185
|
+
* 🔴 AN ONGOING GENERATION IS A DIFFERENT QUESTION, AND IT IS ANSWERED (OPE-1726): the since-last-wake
|
|
186
|
+
* catch-up reads MICROSOFT GRAPH — a different credential and a different transport from the Bot
|
|
187
|
+
* Connector, the one `read_channel` has always used — so a Teams seat does see what the channel said
|
|
188
|
+
* between its own wakes. See channels/teams-catch-up.ts; the bootstrap gap above is unchanged.
|
|
189
|
+
* Always the unified render (platform address + P5 disclosure): Teams has no non-window
|
|
190
|
+
* supervisor path, so there is no per-container twin to stay byte-identical with.
|
|
191
|
+
*/
|
|
192
|
+
export function buildTeamsSupervisorWake(input) {
|
|
193
|
+
return {
|
|
194
|
+
platform: "teams",
|
|
195
|
+
reason: input.directMention ? "mention" : "channel-activity",
|
|
196
|
+
addressing: input.directMention ? "direct-mention" : "channel-watch",
|
|
197
|
+
// The ambient calibration dial — an addressed mention is owed an answer, so watch-only.
|
|
198
|
+
engagementTier: input.directMention ? undefined : input.engagementTier,
|
|
199
|
+
wakeId: input.wakeId,
|
|
200
|
+
locus: {
|
|
201
|
+
channel: { id: input.channelId },
|
|
202
|
+
...(input.threadRootId ? { thread: { ts: input.threadRootId } } : {}),
|
|
203
|
+
},
|
|
204
|
+
...(input.trigger.authorName ? { participants: [{ id: input.trigger.authorId, name: input.trigger.authorName }] } : {}),
|
|
205
|
+
backscroll: input.tail && input.tail.length > 0 ? input.tail : undefined,
|
|
206
|
+
...(input.catchUpUnavailable !== undefined ? { catchUpUnavailable: input.catchUpUnavailable } : {}),
|
|
207
|
+
trigger: mkMessageTrigger({
|
|
208
|
+
from: "human", // bot/self-authored activities are dropped upstream (teams-front's author gate)
|
|
209
|
+
author: input.trigger.authorName ?? input.trigger.authorId,
|
|
210
|
+
authorId: input.trigger.authorId,
|
|
211
|
+
id: input.trigger.id,
|
|
212
|
+
sentAt: input.trigger.sentAt,
|
|
213
|
+
// The caller's stated per-person tier — no default (OPE-596).
|
|
214
|
+
trust: input.trigger.trust,
|
|
215
|
+
mention: input.directMention,
|
|
216
|
+
body: input.trigger.text,
|
|
217
|
+
}),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Route one floor-passing Teams activity to the domain's single-window supervisor: get-or-create
|
|
222
|
+
* the (unified-grain) session, build + render the wake for that generation, and deliver it via
|
|
223
|
+
* the wake dep (whose live wiring diverts into the unified channel — registering the durable
|
|
224
|
+
* wakeId→origin map entry BEFORE the send).
|
|
225
|
+
*
|
|
226
|
+
* A DELIVERY failure (the enqueue/divert itself) propagates to the caller's catch. A session that
|
|
227
|
+
* dies at TURN time does not: nothing here observes it, so the trigger is lost SILENTLY, and no
|
|
228
|
+
* reactive arm can exist (OPE-174 removed the inert one; channels/session-resume.ts holds the
|
|
229
|
+
* measurement). The working remedy is PRE-DISPATCH — the live `getOrCreateSession` claims the
|
|
230
|
+
* OPE-599 runtime-change rotation before this call and hands back a session the running eve build
|
|
231
|
+
* can read.
|
|
232
|
+
*/
|
|
233
|
+
export async function handleTeamsSingleWindowDispatch(d, deps) {
|
|
234
|
+
const atIso = deps.now ? deps.now() : new Date().toISOString();
|
|
235
|
+
const session = await deps.getOrCreateSession(d.surfaceKey, d.channelId, atIso);
|
|
236
|
+
const doWake = async (token, generation, tail, catchUpUnavailable) => {
|
|
237
|
+
const nw = buildTeamsSupervisorWake({
|
|
238
|
+
channelId: d.channelId,
|
|
239
|
+
trigger: d.trigger,
|
|
240
|
+
threadRootId: d.threadRootId,
|
|
241
|
+
directMention: d.window.addressing === "direct-mention",
|
|
242
|
+
wakeId: d.window.wakeId,
|
|
243
|
+
engagementTier: d.engagementTier,
|
|
244
|
+
tail,
|
|
245
|
+
catchUpUnavailable,
|
|
246
|
+
});
|
|
247
|
+
const { message, context } = renderWake(nw, deps.now);
|
|
248
|
+
await deps.wake({ token, auth: d.auth, message, context: context ?? [], window: d.window });
|
|
249
|
+
};
|
|
250
|
+
// A wake failure PROPAGATES to the caller's catch. (OPE-174 removed a terminal-session-death
|
|
251
|
+
// force-rotate branch here: it could never fire — a conversation-mode session PARKS at eve's
|
|
252
|
+
// token bound rather than failing, and a turn-time error cannot reject the awaited enqueue
|
|
253
|
+
// anyway. The reachable handler is core's agent/channels/session-park.ts.)
|
|
254
|
+
// 🔴 EVERY WAKE READS THE CHANNEL SINCE THE SEAT LAST LOOKED (OPE-1695 (b), brought to Teams by
|
|
255
|
+
// OPE-1726). A FRESH generation renders its carried tail, as it always did; an ONGOING generation
|
|
256
|
+
// reads what the channel AND this reply chain said since its own `lastWakeAt`, through the ONE
|
|
257
|
+
// shared catch-up path — same bounds, same admission policy, same cap as Slack's. The read runs on
|
|
258
|
+
// MICROSOFT GRAPH, not on the Bot Connector this wake arrived over; see teams-catch-up.ts.
|
|
259
|
+
// FAIL-SOFT: the shared path never throws, and an unregistered fetch comes back as the UNAVAILABLE
|
|
260
|
+
// note rather than as a silent empty context.
|
|
261
|
+
// 🔴 NO TEAM ID STATES ITS BOUND RATHER THAN READING EMPTY, and TWO shapes reach that arm with TWO
|
|
262
|
+
// DIFFERENT SENTENCES. Graph addresses a history read as `/teams/{team}/channels/{channel}`.
|
|
263
|
+
// • A PERSONAL OR GROUP CHAT carries no team at all. That is STRUCTURAL — this surface cannot
|
|
264
|
+
// read its own history, ever — so it takes core's own `catchUpUnavailableReason`.
|
|
265
|
+
// • A CHANNEL whose Connector team id would not resolve to its Graph one
|
|
266
|
+
// (channels/teams-graph-team-id.ts) has no address ON THIS WAKE. That is TRANSIENT, and saying
|
|
267
|
+
// "this surface cannot read its own history" over it would tell the seat something false about
|
|
268
|
+
// Teams — the exact line core's seat-catch-up.ts draws between a structural absence and a
|
|
269
|
+
// failed read. So it gets its own sentence, below.
|
|
270
|
+
// Either way the wake SAYS SO: skipping in silence would render the same empty context a quiet
|
|
271
|
+
// channel renders, which is the one thing this whole mechanism exists to stop.
|
|
272
|
+
// See TeamsSupervisorDispatch.replyChainRootId: the chain this wake sits in is what the read adds
|
|
273
|
+
// to the channel; the envelope's own thread meta is the fallback for a caller that names only that.
|
|
274
|
+
const catchUpRoot = d.replyChainRootId ?? d.threadRootId;
|
|
275
|
+
const catchUp = session.freshGeneration || !deps.catchUp
|
|
276
|
+
? undefined
|
|
277
|
+
: !d.teamId
|
|
278
|
+
? {
|
|
279
|
+
messages: [],
|
|
280
|
+
unavailable: d.teamAddressUnresolved ? TEAM_ADDRESS_UNRESOLVED_NOTE : catchUpUnavailableReason("teams"),
|
|
281
|
+
}
|
|
282
|
+
: await deps.catchUp({
|
|
283
|
+
container: `${d.teamId}/${d.channelId}`,
|
|
284
|
+
...(catchUpRoot ? { threadRoot: catchUpRoot } : {}),
|
|
285
|
+
sinceMs: seatCatchUpSinceMs(session.lastWakeAt, Date.parse(atIso) || Date.now(), TEAMS_CATCH_UP_REACHBACK_HOURS),
|
|
286
|
+
untilMs: Date.parse(d.trigger.sentAt) || Date.parse(atIso) || Date.now(),
|
|
287
|
+
excludeId: d.trigger.id,
|
|
288
|
+
channelKey: d.surfaceKey,
|
|
289
|
+
});
|
|
290
|
+
await doWake(session.token, session.generation, session.freshGeneration ? session.tail : (catchUp?.messages ?? []), catchUp?.unavailable);
|
|
291
|
+
if (deps.touchSession)
|
|
292
|
+
await deps.touchSession(d.surfaceKey, atIso);
|
|
293
|
+
if (deps.recordWake) {
|
|
294
|
+
// AFTER the wake landed, and only the TRIGGER — never the backscroll rendered beside it. That is
|
|
295
|
+
// what stops a tail inheriting a tail (channels/session-tail.ts).
|
|
296
|
+
await deps.recordWake({
|
|
297
|
+
kind: "wake",
|
|
298
|
+
at: atIso,
|
|
299
|
+
from: "human",
|
|
300
|
+
trust: d.trigger.trust,
|
|
301
|
+
// THE AUTHOR GRAIN (OPE-1747) — `d.ingested[0]` is the TRIGGER's own facts, the one entry the
|
|
302
|
+
// front's own `stampNonMemberChatAuth` join reads, resolved through the one core road.
|
|
303
|
+
// `refuted: false` on an empty carriage is the answer the live wake acted on, never the UNKNOWN
|
|
304
|
+
// an absent field means — that is reserved for a row persisted before this field existed.
|
|
305
|
+
...tailAuthorGrain(d.ingested[0] ?? { trust: d.trigger.trust }),
|
|
306
|
+
author: d.trigger.authorName ?? d.trigger.authorId,
|
|
307
|
+
authorId: d.trigger.authorId,
|
|
308
|
+
id: d.trigger.id,
|
|
309
|
+
platform: "teams",
|
|
310
|
+
// The ROOM, not the domain — see TeamsSupervisorDispatch.containerKey. The post that answers
|
|
311
|
+
// this wake files under `partition.surfaceKey`, and the fold policy compares the two strings.
|
|
312
|
+
container: d.containerKey,
|
|
313
|
+
...(d.threadRootId ? { threadRoot: d.threadRootId } : {}),
|
|
314
|
+
text: d.trigger.text,
|
|
315
|
+
}, session.token, d.surfaceKey);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* THE 1:1 (and group) DM WAKE for a first-classed Teams DM window (OPE-357) — the Teams twin of
|
|
320
|
+
* slack-events.ts's `slackDmWake` and discord-gateway.ts's {@link buildTeamsDmWake} sibling
|
|
321
|
+
* `buildDiscordDmWake`, and it renders through the SAME core renderer with no platform branch, so all
|
|
322
|
+
* three surfaces' DM envelopes are one dialect.
|
|
323
|
+
*
|
|
324
|
+
* ADDRESSING IS `direct-mention`, ALWAYS, doing the same two jobs it does on Slack/Discord. Semantically
|
|
325
|
+
* it is simply TRUE: everything said in a DM is said to the agent, which is why this path bypasses the
|
|
326
|
+
* engagement gate and the name-drop judge entirely — a DM IS ALWAYS ANSWERED. Mechanically it is
|
|
327
|
+
* LOAD-BEARING: `direct-mention` stamps `oe_addressing` through the divert, which marks the wake as
|
|
328
|
+
* OWED a reply and selects the `[direct]` preamble's reply mandate. 🔴 IT IS NOT A DELIVERY PATH
|
|
329
|
+
* (OPE-1982): the addressed-prose bridge it used to arm is deleted, so a DM answer written as prose
|
|
330
|
+
* rather than a `reply` call is DROPPED on that channel like any other, and re-driven once.
|
|
331
|
+
*
|
|
332
|
+
* `reason` is `dm`, not `mention`: the envelope's reason describes the SURFACE SHAPE, and it is the
|
|
333
|
+
* one reason that survives the OPE-744 collapse of `mention` into `channel-activity` — no other
|
|
334
|
+
* attribute states "this is a direct-message room". NO `engagementTier` either — that dial raises
|
|
335
|
+
* the bar for AMBIENT watching, and a DM is always answered.
|
|
336
|
+
*
|
|
337
|
+
* NO PLATFORM-FETCH BACKSCROLL, EVER — and here that is not merely the native path's choice (as on
|
|
338
|
+
* Discord) but a platform fact: the Bot Connector exposes no DM message-history read and the Graph
|
|
339
|
+
* chat-history endpoint is deliberately unwired (teams-read.ts). So a fresh Teams DM generation
|
|
340
|
+
* carries the RECORDED TAIL and nothing else. Pure → unit-testable.
|
|
341
|
+
*/
|
|
342
|
+
export function buildTeamsDmWake(input) {
|
|
343
|
+
return {
|
|
344
|
+
platform: "teams",
|
|
345
|
+
reason: "dm",
|
|
346
|
+
addressing: "direct-mention",
|
|
347
|
+
wakeId: input.wakeId,
|
|
348
|
+
// A DM's container IS the DM conversation: no parent, no thread, and — unlike the channel
|
|
349
|
+
// builder — no `platform` address stamp, because this window sees exactly one surface.
|
|
350
|
+
locus: { channel: { id: input.conversationId } },
|
|
351
|
+
backscroll: input.tail && input.tail.length > 0 ? input.tail : undefined,
|
|
352
|
+
trigger: mkMessageTrigger({
|
|
353
|
+
from: "human", // bot/self-authored activities are dropped at the front's author gate
|
|
354
|
+
author: input.trigger.author,
|
|
355
|
+
authorId: input.trigger.authorId,
|
|
356
|
+
id: input.trigger.id,
|
|
357
|
+
sentAt: input.trigger.sentAt,
|
|
358
|
+
// The caller's stated per-person tier — no default (OPE-596).
|
|
359
|
+
trust: input.trigger.trust,
|
|
360
|
+
// The response-obligation flag, exactly as the Slack/Discord DM wakes carry it.
|
|
361
|
+
mention: true,
|
|
362
|
+
body: input.trigger.text,
|
|
363
|
+
}),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=teams-supervisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-supervisor.js","sourceRoot":"","sources":["../../../agent/channels/teams-supervisor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type TeamsInboundMessageContext, type TeamsMessageActivity, type TeamsInboundResult } from "eve/channels/teams";
|
|
2
|
+
export declare const teamsOnMessage: (ctx: TeamsInboundMessageContext, message: TeamsMessageActivity) => Promise<TeamsInboundResult>;
|
|
3
|
+
declare const _default: import("eve/channels/teams").TeamsChannel;
|
|
4
|
+
export default _default;
|
|
5
|
+
//# sourceMappingURL=teams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../../agent/channels/teams.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAgB,KAAK,0BAA0B,EAAE,KAAK,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AA4DvI,eAAO,MAAM,cAAc,QAAe,0BAA0B,WAAW,oBAAoB,KAAG,OAAO,CAAC,kBAAkB,CAgE/H,CAAC"}
|