crewly 1.20.381 → 1.20.383

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.
Files changed (49) hide show
  1. package/dist/backend/backend/src/constants.d.ts +49 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +49 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/index.d.ts.map +1 -1
  6. package/dist/backend/backend/src/index.js +96 -12
  7. package/dist/backend/backend/src/index.js.map +1 -1
  8. package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts +16 -2
  9. package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts.map +1 -1
  10. package/dist/backend/backend/src/services/drive/drive-agent.service.js +60 -5
  11. package/dist/backend/backend/src/services/drive/drive-agent.service.js.map +1 -1
  12. package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts +61 -1
  13. package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts.map +1 -1
  14. package/dist/backend/backend/src/services/drive/drive-cloud.contract.js +72 -3
  15. package/dist/backend/backend/src/services/drive/drive-cloud.contract.js.map +1 -1
  16. package/dist/backend/backend/src/services/drive/drive-meeting-pack.d.ts +233 -0
  17. package/dist/backend/backend/src/services/drive/drive-meeting-pack.d.ts.map +1 -0
  18. package/dist/backend/backend/src/services/drive/drive-meeting-pack.js +327 -0
  19. package/dist/backend/backend/src/services/drive/drive-meeting-pack.js.map +1 -0
  20. package/dist/backend/backend/src/services/drive/drive-meeting.service.d.ts +157 -0
  21. package/dist/backend/backend/src/services/drive/drive-meeting.service.d.ts.map +1 -0
  22. package/dist/backend/backend/src/services/drive/drive-meeting.service.js +219 -0
  23. package/dist/backend/backend/src/services/drive/drive-meeting.service.js.map +1 -0
  24. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.d.ts +80 -0
  25. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.d.ts.map +1 -0
  26. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.js +153 -0
  27. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.js.map +1 -0
  28. package/dist/backend/backend/src/services/monitoring/model-pricing.d.ts +32 -5
  29. package/dist/backend/backend/src/services/monitoring/model-pricing.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/monitoring/model-pricing.js +54 -23
  31. package/dist/backend/backend/src/services/monitoring/model-pricing.js.map +1 -1
  32. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +2 -2
  33. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/monitoring/token-usage.service.js +8 -3
  35. package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  36. package/dist/backend/build-info.json +2 -2
  37. package/dist/cli/backend/src/constants.d.ts +49 -0
  38. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  39. package/dist/cli/backend/src/constants.js +49 -0
  40. package/dist/cli/backend/src/constants.js.map +1 -1
  41. package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts +32 -5
  42. package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts.map +1 -1
  43. package/dist/cli/backend/src/services/monitoring/model-pricing.js +54 -23
  44. package/dist/cli/backend/src/services/monitoring/model-pricing.js.map +1 -1
  45. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +2 -2
  46. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  47. package/dist/cli/backend/src/services/monitoring/token-usage.service.js +8 -3
  48. package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  49. 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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"}