crewly 1.20.382 → 1.20.384
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/backend/backend/src/constants.d.ts +53 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +53 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +96 -12
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts +16 -2
- package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/drive/drive-agent.service.js +60 -5
- package/dist/backend/backend/src/services/drive/drive-agent.service.js.map +1 -1
- package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts +61 -1
- package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/drive/drive-cloud.contract.js +72 -3
- package/dist/backend/backend/src/services/drive/drive-cloud.contract.js.map +1 -1
- package/dist/backend/backend/src/services/drive/drive-meeting-pack.d.ts +233 -0
- package/dist/backend/backend/src/services/drive/drive-meeting-pack.d.ts.map +1 -0
- package/dist/backend/backend/src/services/drive/drive-meeting-pack.js +327 -0
- package/dist/backend/backend/src/services/drive/drive-meeting-pack.js.map +1 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.service.d.ts +157 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.service.js +219 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.service.js.map +1 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.wiring.d.ts +80 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.wiring.js +153 -0
- package/dist/backend/backend/src/services/drive/drive-meeting.wiring.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +53 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +53 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meetings P2b (crewly#1415): the meeting pack for a voice 1:1 meeting with
|
|
3
|
+
* one agent — what the voice needs to speak as that agent. Pure: the wiring
|
|
4
|
+
* (drive-meeting.wiring.ts) reads the sources, this module turns them into
|
|
5
|
+
* the wire shape Cloud expects (crewly-services `auth/src/drive/meeting-agent.ts`).
|
|
6
|
+
*
|
|
7
|
+
* The pack holds:
|
|
8
|
+
* - the agent (name, role, team) and its latest handover (clipped);
|
|
9
|
+
* - its active and waiting work in plain words, from the status snapshot;
|
|
10
|
+
* - the last owner↔agent messages and recent decisions;
|
|
11
|
+
* - the agenda: open owner↔agent threads (Slack threads, Crewly chat
|
|
12
|
+
* threads, open decision cards), each `{threadRef, topic, state}` with
|
|
13
|
+
* state `waiting_on_owner` (a card waits on the owner), `question` (the
|
|
14
|
+
* agent asked and the owner has not answered) or `in_progress` (the owner
|
|
15
|
+
* asked and the agent still owes the answer, or said it is on it);
|
|
16
|
+
* - wiki pages relevant to the team and the agenda (read by the wiring).
|
|
17
|
+
*
|
|
18
|
+
* Only this agent's own conversations, cards and work go in. Everything
|
|
19
|
+
* is made speakable, passed through the secret redactor and clipped, and the
|
|
20
|
+
* whole pack is kept under {@link MEETING_CONSTANTS.PACK_MAX_TOKENS}.
|
|
21
|
+
*
|
|
22
|
+
* @module services/drive/drive-meeting-pack
|
|
23
|
+
*/
|
|
24
|
+
import type { BriefingSnapshot } from './drive-briefing.contract.js';
|
|
25
|
+
/** Where an agenda thread stands. */
|
|
26
|
+
export type MeetingThreadState = 'waiting_on_owner' | 'question' | 'in_progress';
|
|
27
|
+
/** One line of a conversation, as the pack carries it. */
|
|
28
|
+
export interface MeetingLine {
|
|
29
|
+
from: 'owner' | 'agent';
|
|
30
|
+
text: string;
|
|
31
|
+
at: string;
|
|
32
|
+
}
|
|
33
|
+
/** One agenda topic: an open owner↔agent thread. */
|
|
34
|
+
export interface MeetingAgendaEntry {
|
|
35
|
+
threadRef: string;
|
|
36
|
+
topic: string;
|
|
37
|
+
state: MeetingThreadState;
|
|
38
|
+
lastAt?: string;
|
|
39
|
+
/** Where the thread is, in words (`Slack DM`, `Crewly chat`, `#launch`) */
|
|
40
|
+
where?: string;
|
|
41
|
+
recent?: MeetingLine[];
|
|
42
|
+
}
|
|
43
|
+
/** The pack, as posted to Cloud. */
|
|
44
|
+
export interface MeetingPackWire {
|
|
45
|
+
v: 1;
|
|
46
|
+
agent: {
|
|
47
|
+
name: string;
|
|
48
|
+
session: string;
|
|
49
|
+
role?: string;
|
|
50
|
+
team?: string;
|
|
51
|
+
};
|
|
52
|
+
handover?: string;
|
|
53
|
+
work: Array<{
|
|
54
|
+
title: string;
|
|
55
|
+
status: string;
|
|
56
|
+
last?: string;
|
|
57
|
+
}>;
|
|
58
|
+
waiting: Array<{
|
|
59
|
+
kind: string;
|
|
60
|
+
summary: string;
|
|
61
|
+
}>;
|
|
62
|
+
messages: Array<MeetingLine & {
|
|
63
|
+
where?: string;
|
|
64
|
+
}>;
|
|
65
|
+
decisions: Array<{
|
|
66
|
+
question: string;
|
|
67
|
+
answer: string;
|
|
68
|
+
at: string;
|
|
69
|
+
}>;
|
|
70
|
+
agenda: MeetingAgendaEntry[];
|
|
71
|
+
wiki: Array<{
|
|
72
|
+
title: string;
|
|
73
|
+
where: string;
|
|
74
|
+
text: string;
|
|
75
|
+
}>;
|
|
76
|
+
builtAt: string;
|
|
77
|
+
estTokens: number;
|
|
78
|
+
}
|
|
79
|
+
/** An agent timeline row (chat-v2 `getAgentTimeline` item, the fields used). */
|
|
80
|
+
export interface MeetingTimelineRow {
|
|
81
|
+
id: string;
|
|
82
|
+
channelId: string;
|
|
83
|
+
channelType?: string;
|
|
84
|
+
channelName?: string;
|
|
85
|
+
threadId?: string;
|
|
86
|
+
senderType: string;
|
|
87
|
+
/** `owner`, `agent`, `human`, `system` */
|
|
88
|
+
senderKind?: string;
|
|
89
|
+
senderId: string;
|
|
90
|
+
content: string;
|
|
91
|
+
createdAt: number;
|
|
92
|
+
metadata?: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
/** An owner decision card (the fields used). */
|
|
95
|
+
export interface MeetingDecisionSource {
|
|
96
|
+
id: string;
|
|
97
|
+
question: string;
|
|
98
|
+
status: string;
|
|
99
|
+
asker: string;
|
|
100
|
+
requestedBy: string;
|
|
101
|
+
options: Array<{
|
|
102
|
+
key: string;
|
|
103
|
+
label: string;
|
|
104
|
+
}>;
|
|
105
|
+
card?: {
|
|
106
|
+
slackChannelId: string;
|
|
107
|
+
messageTs: string;
|
|
108
|
+
threadTs?: string;
|
|
109
|
+
};
|
|
110
|
+
place?: {
|
|
111
|
+
slackChannelId: string;
|
|
112
|
+
threadTs?: string;
|
|
113
|
+
};
|
|
114
|
+
chosenKey?: string;
|
|
115
|
+
answerText?: string;
|
|
116
|
+
ownerWords?: string;
|
|
117
|
+
createdAt: string;
|
|
118
|
+
updatedAt: string;
|
|
119
|
+
}
|
|
120
|
+
/** Everything a pack is built from. */
|
|
121
|
+
export interface MeetingPackSources {
|
|
122
|
+
now: Date;
|
|
123
|
+
agent: {
|
|
124
|
+
session: string;
|
|
125
|
+
name: string;
|
|
126
|
+
role?: string;
|
|
127
|
+
team?: string;
|
|
128
|
+
};
|
|
129
|
+
handover?: string | null;
|
|
130
|
+
snapshot?: BriefingSnapshot | null;
|
|
131
|
+
/** The agent's timeline, any order */
|
|
132
|
+
timeline: MeetingTimelineRow[];
|
|
133
|
+
decisions: MeetingDecisionSource[];
|
|
134
|
+
wiki: Array<{
|
|
135
|
+
title: string;
|
|
136
|
+
where: string;
|
|
137
|
+
text: string;
|
|
138
|
+
}>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Plain spoken words for one message: harness tags, links and markdown out,
|
|
142
|
+
* secrets masked, clipped.
|
|
143
|
+
*
|
|
144
|
+
* @param text - Raw text
|
|
145
|
+
* @param max - Longest result
|
|
146
|
+
* @returns Clean text
|
|
147
|
+
*/
|
|
148
|
+
export declare function plainWords(text: string, max: number): string;
|
|
149
|
+
/**
|
|
150
|
+
* Rough token count: CJK characters one each, other text four characters a
|
|
151
|
+
* token (the same estimate Cloud uses).
|
|
152
|
+
*
|
|
153
|
+
* @param text - Text
|
|
154
|
+
* @returns Estimated tokens
|
|
155
|
+
*/
|
|
156
|
+
export declare function estimateTokens(text: string): number;
|
|
157
|
+
/**
|
|
158
|
+
* The thread a timeline row belongs to, as a meeting thread ref; null for a
|
|
159
|
+
* row that is not part of an owner↔agent thread (a room's top level).
|
|
160
|
+
*
|
|
161
|
+
* @param row - Timeline row
|
|
162
|
+
* @returns `slack:<conversation>:<ts>`, `chat:<channel>:<root>` or `chat:<dm channel>`
|
|
163
|
+
*/
|
|
164
|
+
export declare function threadRefOfRow(row: MeetingTimelineRow): string | null;
|
|
165
|
+
/**
|
|
166
|
+
* Split a `chat:` thread ref: the channel, and the thread root when the last
|
|
167
|
+
* segment is a message id.
|
|
168
|
+
*
|
|
169
|
+
* @param ref - Thread ref
|
|
170
|
+
* @returns Channel + root, or null for a ref that is not `chat:`
|
|
171
|
+
*/
|
|
172
|
+
export declare function parseChatThreadRef(ref: string): {
|
|
173
|
+
channelId: string;
|
|
174
|
+
rootId?: string;
|
|
175
|
+
} | null;
|
|
176
|
+
/**
|
|
177
|
+
* Split a `slack:` thread ref.
|
|
178
|
+
*
|
|
179
|
+
* @param ref - Thread ref
|
|
180
|
+
* @returns Slack conversation + thread ts, or null
|
|
181
|
+
*/
|
|
182
|
+
export declare function parseSlackThreadRef(ref: string): {
|
|
183
|
+
slackChannelId: string;
|
|
184
|
+
threadTs: string;
|
|
185
|
+
} | null;
|
|
186
|
+
/**
|
|
187
|
+
* Where an open conversation stands, or null when it is settled.
|
|
188
|
+
*
|
|
189
|
+
* @param lines - The conversation, oldest first
|
|
190
|
+
* @returns State or null
|
|
191
|
+
*/
|
|
192
|
+
export declare function threadState(lines: readonly MeetingLine[]): MeetingThreadState | null;
|
|
193
|
+
/**
|
|
194
|
+
* The agenda: open decision cards first, then open threads, newest first
|
|
195
|
+
* within each state, at most {@link MEETING_CONSTANTS.AGENDA_MAX}.
|
|
196
|
+
*
|
|
197
|
+
* @param s - Sources
|
|
198
|
+
* @returns Agenda entries
|
|
199
|
+
*/
|
|
200
|
+
export declare function buildAgenda(s: Pick<MeetingPackSources, 'now' | 'agent' | 'timeline' | 'decisions'>): MeetingAgendaEntry[];
|
|
201
|
+
/**
|
|
202
|
+
* The words to search the wiki with for the pack: the team, the role and
|
|
203
|
+
* the agenda topics, at most 200 characters.
|
|
204
|
+
*
|
|
205
|
+
* @param agent - The agent
|
|
206
|
+
* @param agenda - Its agenda
|
|
207
|
+
* @returns Query, or '' when there is nothing to search for
|
|
208
|
+
*/
|
|
209
|
+
export declare function packWikiQuery(agent: MeetingPackSources['agent'], agenda: readonly MeetingAgendaEntry[]): string;
|
|
210
|
+
/**
|
|
211
|
+
* The pack text Cloud renders, for the size estimate (close enough to
|
|
212
|
+
* Cloud's own rendering for budgeting).
|
|
213
|
+
*
|
|
214
|
+
* @param p - Pack
|
|
215
|
+
* @returns Text
|
|
216
|
+
*/
|
|
217
|
+
export declare function packTextForBudget(p: MeetingPackWire): string;
|
|
218
|
+
/**
|
|
219
|
+
* Build the pack.
|
|
220
|
+
*
|
|
221
|
+
* @param s - Sources
|
|
222
|
+
* @returns The pack, within the token budget
|
|
223
|
+
*/
|
|
224
|
+
export declare function buildMeetingPack(s: MeetingPackSources): MeetingPackWire;
|
|
225
|
+
/**
|
|
226
|
+
* Trim a pack to the token budget: wiki pages first, then old messages,
|
|
227
|
+
* then the handover's tail.
|
|
228
|
+
*
|
|
229
|
+
* @param pack - Pack (changed in place)
|
|
230
|
+
* @returns The same pack, with `estTokens`
|
|
231
|
+
*/
|
|
232
|
+
export declare function fitBudget(pack: MeetingPackWire): MeetingPackWire;
|
|
233
|
+
//# sourceMappingURL=drive-meeting-pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-meeting-pack.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting-pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meetings P2b (crewly#1415): the meeting pack for a voice 1:1 meeting with
|
|
3
|
+
* one agent — what the voice needs to speak as that agent. Pure: the wiring
|
|
4
|
+
* (drive-meeting.wiring.ts) reads the sources, this module turns them into
|
|
5
|
+
* the wire shape Cloud expects (crewly-services `auth/src/drive/meeting-agent.ts`).
|
|
6
|
+
*
|
|
7
|
+
* The pack holds:
|
|
8
|
+
* - the agent (name, role, team) and its latest handover (clipped);
|
|
9
|
+
* - its active and waiting work in plain words, from the status snapshot;
|
|
10
|
+
* - the last owner↔agent messages and recent decisions;
|
|
11
|
+
* - the agenda: open owner↔agent threads (Slack threads, Crewly chat
|
|
12
|
+
* threads, open decision cards), each `{threadRef, topic, state}` with
|
|
13
|
+
* state `waiting_on_owner` (a card waits on the owner), `question` (the
|
|
14
|
+
* agent asked and the owner has not answered) or `in_progress` (the owner
|
|
15
|
+
* asked and the agent still owes the answer, or said it is on it);
|
|
16
|
+
* - wiki pages relevant to the team and the agenda (read by the wiring).
|
|
17
|
+
*
|
|
18
|
+
* Only this agent's own conversations, cards and work go in. Everything
|
|
19
|
+
* is made speakable, passed through the secret redactor and clipped, and the
|
|
20
|
+
* whole pack is kept under {@link MEETING_CONSTANTS.PACK_MAX_TOKENS}.
|
|
21
|
+
*
|
|
22
|
+
* @module services/drive/drive-meeting-pack
|
|
23
|
+
*/
|
|
24
|
+
import { MEETING_CONSTANTS } from '../../constants.js';
|
|
25
|
+
import { redactSecrets } from '../../utils/secret-redactor.js';
|
|
26
|
+
import { clip, speakable } from '../briefing/briefing.utils.js';
|
|
27
|
+
import { slackThreadOfMetadata } from '../slack/slack-thread-key.js';
|
|
28
|
+
const C = MEETING_CONSTANTS;
|
|
29
|
+
/** `[SLACK-THREAD:…]`, `[Drive mode · …]` and similar harness tags. */
|
|
30
|
+
const HARNESS_TAG = /\[(?:SLACK-THREAD|Drive mode[^\]]*|Meeting[^\]]*|TRIGGERED-BY[^\]]*)[^\]]*\]/gi;
|
|
31
|
+
/** A chat-v2 message id (uuid). */
|
|
32
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
33
|
+
/** The agent asks the owner something. */
|
|
34
|
+
const ASKS = /[??]\s*$|[??]\s*\S{0,40}$|\b(should i|shall i|do you want|would you like|which (one|option)|can you (confirm|approve|check)|let me know|your call|ok to|okay to|approve)\b|要不要|可以吗|行吗|好吗|确认一下|请确认|选哪个|你看|您看|需要你|等你/i;
|
|
35
|
+
/** The agent says it is on it. */
|
|
36
|
+
const ON_IT = /\b(working on|on it|i'?ll|i will|in progress|will (send|post|share|finish|get back)|started|starting|looking into|digging|drafting)\b|正在|在做|在弄|在改|稍后|马上|我来|我去|处理中|进行中/i;
|
|
37
|
+
/**
|
|
38
|
+
* Plain spoken words for one message: harness tags, links and markdown out,
|
|
39
|
+
* secrets masked, clipped.
|
|
40
|
+
*
|
|
41
|
+
* @param text - Raw text
|
|
42
|
+
* @param max - Longest result
|
|
43
|
+
* @returns Clean text
|
|
44
|
+
*/
|
|
45
|
+
export function plainWords(text, max) {
|
|
46
|
+
const noTags = (text ?? '').replace(HARNESS_TAG, ' ');
|
|
47
|
+
return clip(speakable(redactSecrets(noTags)).replace(/\s+/g, ' ').trim(), max);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rough token count: CJK characters one each, other text four characters a
|
|
51
|
+
* token (the same estimate Cloud uses).
|
|
52
|
+
*
|
|
53
|
+
* @param text - Text
|
|
54
|
+
* @returns Estimated tokens
|
|
55
|
+
*/
|
|
56
|
+
export function estimateTokens(text) {
|
|
57
|
+
let cjk = 0;
|
|
58
|
+
for (const ch of text)
|
|
59
|
+
if (/[ -鿿가--]/.test(ch))
|
|
60
|
+
cjk += 1;
|
|
61
|
+
return cjk + Math.ceil((text.length - cjk) / 4);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The thread a timeline row belongs to, as a meeting thread ref; null for a
|
|
65
|
+
* row that is not part of an owner↔agent thread (a room's top level).
|
|
66
|
+
*
|
|
67
|
+
* @param row - Timeline row
|
|
68
|
+
* @returns `slack:<conversation>:<ts>`, `chat:<channel>:<root>` or `chat:<dm channel>`
|
|
69
|
+
*/
|
|
70
|
+
export function threadRefOfRow(row) {
|
|
71
|
+
const slack = slackThreadOfMetadata(row.metadata);
|
|
72
|
+
if (slack)
|
|
73
|
+
return `slack:${slack.slackChannelId}:${slack.threadTs}`;
|
|
74
|
+
if (row.threadId)
|
|
75
|
+
return `chat:${row.channelId}:${row.threadId}`;
|
|
76
|
+
if (row.channelType === 'dm')
|
|
77
|
+
return `chat:${row.channelId}`;
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Split a `chat:` thread ref: the channel, and the thread root when the last
|
|
82
|
+
* segment is a message id.
|
|
83
|
+
*
|
|
84
|
+
* @param ref - Thread ref
|
|
85
|
+
* @returns Channel + root, or null for a ref that is not `chat:`
|
|
86
|
+
*/
|
|
87
|
+
export function parseChatThreadRef(ref) {
|
|
88
|
+
if (!ref.startsWith('chat:'))
|
|
89
|
+
return null;
|
|
90
|
+
const rest = ref.slice('chat:'.length);
|
|
91
|
+
const cut = rest.lastIndexOf(':');
|
|
92
|
+
if (cut > 0 && UUID.test(rest.slice(cut + 1)))
|
|
93
|
+
return { channelId: rest.slice(0, cut), rootId: rest.slice(cut + 1) };
|
|
94
|
+
return rest ? { channelId: rest } : null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Split a `slack:` thread ref.
|
|
98
|
+
*
|
|
99
|
+
* @param ref - Thread ref
|
|
100
|
+
* @returns Slack conversation + thread ts, or null
|
|
101
|
+
*/
|
|
102
|
+
export function parseSlackThreadRef(ref) {
|
|
103
|
+
const m = /^slack:([A-Za-z0-9]{5,24}):(\d{6,12}(?:\.\d{1,8})?)$/.exec(ref);
|
|
104
|
+
return m ? { slackChannelId: m[1], threadTs: m[2] } : null;
|
|
105
|
+
}
|
|
106
|
+
/** Who wrote a row, from the agent's side. */
|
|
107
|
+
function sideOf(row, agentSession) {
|
|
108
|
+
if (row.senderType === 'system' || row.senderKind === 'system')
|
|
109
|
+
return null;
|
|
110
|
+
if (row.senderType === 'agent')
|
|
111
|
+
return row.senderId === agentSession ? 'agent' : null;
|
|
112
|
+
if (row.senderKind === 'agent' || row.senderKind === 'human')
|
|
113
|
+
return null;
|
|
114
|
+
return 'owner';
|
|
115
|
+
}
|
|
116
|
+
/** Where a thread is, in words. */
|
|
117
|
+
function whereOf(row) {
|
|
118
|
+
const slack = slackThreadOfMetadata(row.metadata);
|
|
119
|
+
if (row.channelType === 'dm')
|
|
120
|
+
return slack ? 'Slack DM' : 'Crewly chat';
|
|
121
|
+
const name = (row.channelName ?? '').trim();
|
|
122
|
+
return name ? (slack ? `Slack #${name}` : `#${name}`) : slack ? 'Slack' : 'Crewly chat';
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Where an open conversation stands, or null when it is settled.
|
|
126
|
+
*
|
|
127
|
+
* @param lines - The conversation, oldest first
|
|
128
|
+
* @returns State or null
|
|
129
|
+
*/
|
|
130
|
+
export function threadState(lines) {
|
|
131
|
+
const last = lines[lines.length - 1];
|
|
132
|
+
if (!last)
|
|
133
|
+
return null;
|
|
134
|
+
if (last.from === 'owner')
|
|
135
|
+
return 'in_progress';
|
|
136
|
+
if (ASKS.test(last.text))
|
|
137
|
+
return 'question';
|
|
138
|
+
if (ON_IT.test(last.text))
|
|
139
|
+
return 'in_progress';
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The agenda: open decision cards first, then open threads, newest first
|
|
144
|
+
* within each state, at most {@link MEETING_CONSTANTS.AGENDA_MAX}.
|
|
145
|
+
*
|
|
146
|
+
* @param s - Sources
|
|
147
|
+
* @returns Agenda entries
|
|
148
|
+
*/
|
|
149
|
+
export function buildAgenda(s) {
|
|
150
|
+
const out = [];
|
|
151
|
+
const seen = new Set();
|
|
152
|
+
const since = s.now.getTime() - C.AGENDA_WINDOW_MS;
|
|
153
|
+
for (const d of s.decisions) {
|
|
154
|
+
if (d.status !== 'open' || (d.asker !== s.agent.session && d.requestedBy !== s.agent.session))
|
|
155
|
+
continue;
|
|
156
|
+
const ch = d.card?.slackChannelId ?? d.place?.slackChannelId;
|
|
157
|
+
const ts = d.card ? (d.card.threadTs ?? d.card.messageTs) : d.place?.threadTs;
|
|
158
|
+
if (!ch || !ts)
|
|
159
|
+
continue;
|
|
160
|
+
const ref = `slack:${ch}:${ts}`;
|
|
161
|
+
if (seen.has(ref) || !parseSlackThreadRef(ref))
|
|
162
|
+
continue;
|
|
163
|
+
seen.add(ref);
|
|
164
|
+
const options = d.options.map((o) => o.label).filter(Boolean).slice(0, 4);
|
|
165
|
+
out.push({
|
|
166
|
+
threadRef: ref,
|
|
167
|
+
topic: plainWords(d.question, C.TOPIC_MAX_CHARS),
|
|
168
|
+
state: 'waiting_on_owner',
|
|
169
|
+
lastAt: d.updatedAt || d.createdAt,
|
|
170
|
+
where: 'decision card',
|
|
171
|
+
...(options.length ? { recent: [{ from: 'agent', text: plainWords(`${d.question} Options: ${options.join(' / ')}`, C.TOPIC_RECENT_MAX_CHARS), at: d.createdAt }] } : {}),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// Group the agent's owner conversations by thread.
|
|
175
|
+
const threads = new Map();
|
|
176
|
+
for (const row of s.timeline) {
|
|
177
|
+
if (row.createdAt < since)
|
|
178
|
+
continue;
|
|
179
|
+
const side = sideOf(row, s.agent.session);
|
|
180
|
+
if (!side || !row.content?.trim())
|
|
181
|
+
continue;
|
|
182
|
+
const ref = threadRefOfRow(row);
|
|
183
|
+
if (!ref)
|
|
184
|
+
continue;
|
|
185
|
+
const t = threads.get(ref) ?? { rows: [], sides: new Set() };
|
|
186
|
+
t.rows.push(row);
|
|
187
|
+
t.sides.add(side);
|
|
188
|
+
threads.set(ref, t);
|
|
189
|
+
}
|
|
190
|
+
const open = [];
|
|
191
|
+
for (const [ref, t] of threads) {
|
|
192
|
+
if (seen.has(ref))
|
|
193
|
+
continue;
|
|
194
|
+
const dm = t.rows.some((r) => r.channelType === 'dm');
|
|
195
|
+
// A room thread is on the agenda only when the owner and this agent both spoke in it.
|
|
196
|
+
if (!dm && !(t.sides.has('owner') && t.sides.has('agent')))
|
|
197
|
+
continue;
|
|
198
|
+
const rows = [...t.rows].sort((a, b) => a.createdAt - b.createdAt);
|
|
199
|
+
const lines = rows.map((r) => ({ from: sideOf(r, s.agent.session), text: plainWords(r.content, C.TOPIC_RECENT_MAX_CHARS), at: new Date(r.createdAt).toISOString() })).filter((l) => l.text);
|
|
200
|
+
const state = threadState(lines);
|
|
201
|
+
if (!state)
|
|
202
|
+
continue;
|
|
203
|
+
// A DM without threads is one long conversation: only its latest exchange is the topic.
|
|
204
|
+
const tail = ref.startsWith('chat:') && !parseChatThreadRef(ref)?.rootId ? lines.slice(-4) : lines;
|
|
205
|
+
const first = tail.find((l) => l.from === 'owner') ?? tail[0];
|
|
206
|
+
const topic = clip(first?.text ?? '', C.TOPIC_MAX_CHARS);
|
|
207
|
+
if (!topic)
|
|
208
|
+
continue;
|
|
209
|
+
open.push({ threadRef: ref, topic, state, lastAt: lines[lines.length - 1].at, where: whereOf(rows[rows.length - 1]), recent: tail.slice(-C.TOPIC_RECENT_MAX) });
|
|
210
|
+
}
|
|
211
|
+
const rank = { waiting_on_owner: 0, question: 1, in_progress: 2 };
|
|
212
|
+
open.sort((a, b) => rank[a.state] - rank[b.state] || Date.parse(b.lastAt ?? '') - Date.parse(a.lastAt ?? ''));
|
|
213
|
+
return [...out, ...open].slice(0, C.AGENDA_MAX);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* The words to search the wiki with for the pack: the team, the role and
|
|
217
|
+
* the agenda topics, at most 200 characters.
|
|
218
|
+
*
|
|
219
|
+
* @param agent - The agent
|
|
220
|
+
* @param agenda - Its agenda
|
|
221
|
+
* @returns Query, or '' when there is nothing to search for
|
|
222
|
+
*/
|
|
223
|
+
export function packWikiQuery(agent, agenda) {
|
|
224
|
+
const parts = [agent.team, agent.role, ...agenda.map((a) => a.topic)].filter((p) => !!p && !!p.trim());
|
|
225
|
+
let q = '';
|
|
226
|
+
for (const p of parts) {
|
|
227
|
+
const next = q ? `${q} ${p}` : p;
|
|
228
|
+
if (next.length > 200)
|
|
229
|
+
break;
|
|
230
|
+
q = next;
|
|
231
|
+
}
|
|
232
|
+
return q.trim();
|
|
233
|
+
}
|
|
234
|
+
/** The chosen answer of a settled decision, in words. */
|
|
235
|
+
function answerOf(d) {
|
|
236
|
+
const label = d.options.find((o) => o.key === d.chosenKey)?.label;
|
|
237
|
+
return plainWords(d.ownerWords || d.answerText || label || '', 300);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* The pack text Cloud renders, for the size estimate (close enough to
|
|
241
|
+
* Cloud's own rendering for budgeting).
|
|
242
|
+
*
|
|
243
|
+
* @param p - Pack
|
|
244
|
+
* @returns Text
|
|
245
|
+
*/
|
|
246
|
+
export function packTextForBudget(p) {
|
|
247
|
+
return JSON.stringify({ ...p, estTokens: 0 });
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Build the pack.
|
|
251
|
+
*
|
|
252
|
+
* @param s - Sources
|
|
253
|
+
* @returns The pack, within the token budget
|
|
254
|
+
*/
|
|
255
|
+
export function buildMeetingPack(s) {
|
|
256
|
+
const agentName = s.agent.name;
|
|
257
|
+
const snap = s.snapshot ?? null;
|
|
258
|
+
const me = snap?.agents.find((a) => a.session === s.agent.session);
|
|
259
|
+
const role = s.agent.role ?? me?.role;
|
|
260
|
+
const team = s.agent.team ?? me?.team;
|
|
261
|
+
const work = [];
|
|
262
|
+
if (me?.activity?.title)
|
|
263
|
+
work.push({ title: plainWords(me.activity.title, 200), status: 'in_progress', last: `since ${me.activity.since}` });
|
|
264
|
+
for (const item of snap?.items ?? []) {
|
|
265
|
+
if (item.assignee !== agentName || item.status === 'done' || item.status === 'cancelled')
|
|
266
|
+
continue;
|
|
267
|
+
const title = plainWords(item.title, 200);
|
|
268
|
+
if (!title || work.some((w) => w.title === title))
|
|
269
|
+
continue;
|
|
270
|
+
work.push({ title, status: item.status, ...(item.last ? { last: plainWords(item.last, 300) } : {}) });
|
|
271
|
+
if (work.length >= C.WORK_MAX)
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
const waiting = (snap?.waiting ?? [])
|
|
275
|
+
.filter((w) => w.from === agentName)
|
|
276
|
+
.slice(0, C.WAITING_MAX)
|
|
277
|
+
.map((w) => ({ kind: w.kind, summary: plainWords(w.summary, 300) }))
|
|
278
|
+
.filter((w) => w.summary);
|
|
279
|
+
const since = s.now.getTime() - C.AGENDA_WINDOW_MS;
|
|
280
|
+
const messages = s.timeline
|
|
281
|
+
.filter((r) => r.createdAt >= since && !!sideOf(r, s.agent.session) && (r.channelType === 'dm' || !!r.threadId || !!slackThreadOfMetadata(r.metadata)))
|
|
282
|
+
.sort((a, b) => a.createdAt - b.createdAt)
|
|
283
|
+
.slice(-C.MESSAGES_MAX)
|
|
284
|
+
.map((r) => ({ from: sideOf(r, s.agent.session), text: plainWords(r.content, C.MESSAGE_MAX_CHARS), at: new Date(r.createdAt).toISOString(), where: whereOf(r) }))
|
|
285
|
+
.filter((m) => m.text);
|
|
286
|
+
const decisionsSince = s.now.getTime() - C.DECISIONS_WINDOW_MS;
|
|
287
|
+
const decisions = s.decisions
|
|
288
|
+
.filter((d) => d.status !== 'open' && (d.asker === s.agent.session || d.requestedBy === s.agent.session) && Date.parse(d.updatedAt) >= decisionsSince)
|
|
289
|
+
.sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt))
|
|
290
|
+
.map((d) => ({ question: plainWords(d.question, 300), answer: answerOf(d), at: d.updatedAt }))
|
|
291
|
+
.filter((d) => d.question && d.answer)
|
|
292
|
+
.slice(0, C.DECISIONS_MAX);
|
|
293
|
+
const handover = s.handover ? clip(redactSecrets(s.handover).trim(), C.HANDOVER_MAX_CHARS) : '';
|
|
294
|
+
const pack = {
|
|
295
|
+
v: 1,
|
|
296
|
+
agent: { name: agentName, session: s.agent.session, ...(role ? { role } : {}), ...(team ? { team } : {}) },
|
|
297
|
+
...(handover ? { handover } : {}),
|
|
298
|
+
work,
|
|
299
|
+
waiting,
|
|
300
|
+
messages,
|
|
301
|
+
decisions,
|
|
302
|
+
agenda: buildAgenda(s),
|
|
303
|
+
wiki: s.wiki.slice(0, C.WIKI_PAGES_MAX).map((w) => ({ title: clip(w.title, 160), where: clip(w.where, 160), text: clip(redactSecrets(w.text), C.WIKI_PAGE_MAX_CHARS) })),
|
|
304
|
+
builtAt: s.now.toISOString(),
|
|
305
|
+
estTokens: 0,
|
|
306
|
+
};
|
|
307
|
+
return fitBudget(pack);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Trim a pack to the token budget: wiki pages first, then old messages,
|
|
311
|
+
* then the handover's tail.
|
|
312
|
+
*
|
|
313
|
+
* @param pack - Pack (changed in place)
|
|
314
|
+
* @returns The same pack, with `estTokens`
|
|
315
|
+
*/
|
|
316
|
+
export function fitBudget(pack) {
|
|
317
|
+
const size = () => estimateTokens(packTextForBudget(pack));
|
|
318
|
+
while (size() > C.PACK_MAX_TOKENS && pack.wiki.length)
|
|
319
|
+
pack.wiki.pop();
|
|
320
|
+
while (size() > C.PACK_MAX_TOKENS && pack.messages.length > 5)
|
|
321
|
+
pack.messages.shift();
|
|
322
|
+
while (size() > C.PACK_MAX_TOKENS && pack.handover && pack.handover.length > 500)
|
|
323
|
+
pack.handover = clip(pack.handover, Math.floor(pack.handover.length * 0.7));
|
|
324
|
+
pack.estTokens = size();
|
|
325
|
+
return pack;
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=drive-meeting-pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-meeting-pack.js","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting-pack.ts"],"names":[],"mappings":"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"}
|