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,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DriveMeetingService — the machine side of a voice 1:1 meeting with one
|
|
3
|
+
* agent (Meetings P2b, crewly#1415). Cloud hosts the meeting; this machine
|
|
4
|
+
* answers what only it can, for that agent only:
|
|
5
|
+
*
|
|
6
|
+
* - `buildPack` (`op:'meeting_pack'`): the agent's meeting pack — role,
|
|
7
|
+
* team, handover, work, the last owner↔agent messages, recent decisions,
|
|
8
|
+
* the agenda of open threads and relevant wiki pages
|
|
9
|
+
* (drive-meeting-pack.ts);
|
|
10
|
+
* - `searchWiki` (`op:'wiki_search'`): BM25 over the agent's own team and
|
|
11
|
+
* project vaults, top snippets in plain words, with the time it took;
|
|
12
|
+
* - `writeBack` (a delivery carrying `writeBack`): a decision, answer, task
|
|
13
|
+
* or note from the meeting is written into the thread it belongs to — a
|
|
14
|
+
* Slack thread (posted by the agent's bot, recorded in Crewly chat), a
|
|
15
|
+
* Crewly chat thread, or the open decision card it answers — and the
|
|
16
|
+
* agent gets it like any message from the owner. A new topic starts a
|
|
17
|
+
* new thread, which later write-backs on that topic reuse.
|
|
18
|
+
*
|
|
19
|
+
* Nothing the owner or the agent says is written to this machine's server
|
|
20
|
+
* logs: only counts, sizes and timings.
|
|
21
|
+
*
|
|
22
|
+
* @module services/drive/drive-meeting.service
|
|
23
|
+
*/
|
|
24
|
+
import { MEETING_CONSTANTS } from '../../constants.js';
|
|
25
|
+
import { type ComponentLogger } from '../core/logger.service.js';
|
|
26
|
+
import type { BriefingSnapshot } from './drive-briefing.contract.js';
|
|
27
|
+
import type { DriveMeetingPackFetch, DriveWikiFetch, DriveWriteBack } from './drive-cloud.contract.js';
|
|
28
|
+
import { type MeetingDecisionSource, type MeetingPackWire, type MeetingTimelineRow } from './drive-meeting-pack.js';
|
|
29
|
+
/** A vault the agent may read. */
|
|
30
|
+
export interface MeetingVault {
|
|
31
|
+
vaultPath: string;
|
|
32
|
+
label: string;
|
|
33
|
+
}
|
|
34
|
+
/** A wiki hit, as the machine reads it. */
|
|
35
|
+
export interface MeetingWikiPageHit {
|
|
36
|
+
title: string;
|
|
37
|
+
where: string;
|
|
38
|
+
text: string;
|
|
39
|
+
/** The page file, for the pack's longer excerpt */
|
|
40
|
+
absPath?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Collaborators (wired in index.ts; fakes in tests). */
|
|
43
|
+
export interface DriveMeetingDeps {
|
|
44
|
+
/** The agent's chat timeline since a time (its DMs, rooms and threads) */
|
|
45
|
+
timeline: (agentSession: string, sinceMs: number) => Promise<MeetingTimelineRow[]>;
|
|
46
|
+
/** Owner decision cards (open and settled) */
|
|
47
|
+
decisions: () => Promise<MeetingDecisionSource[]>;
|
|
48
|
+
/** The latest status snapshot (work and waiting items), when there is one */
|
|
49
|
+
snapshot?: () => Promise<BriefingSnapshot | null>;
|
|
50
|
+
/** The agent's latest handover text, when there is one */
|
|
51
|
+
handover: (agentSession: string) => Promise<string | null>;
|
|
52
|
+
/** The vaults the agent may read: its teams' and their projects' (never the global wiki) */
|
|
53
|
+
vaults: (agentSession: string) => Promise<MeetingVault[]>;
|
|
54
|
+
/** BM25 over those vaults as that agent reads them (page visibility by its role), best first */
|
|
55
|
+
searchWiki: (vaults: MeetingVault[], query: string, agentSession: string) => Promise<MeetingWikiPageHit[]>;
|
|
56
|
+
/** A page's text (frontmatter removed), for the pack */
|
|
57
|
+
readPage?: (absPath: string) => Promise<string | null>;
|
|
58
|
+
/** Settle an open decision card with the owner's words; false when the words settle nothing */
|
|
59
|
+
answerDecision?: (decisionId: string, text: string) => Promise<boolean>;
|
|
60
|
+
/** The agent's Slack DM, when it has one its own bot can post in */
|
|
61
|
+
slackDmOf: (agentSession: string) => {
|
|
62
|
+
slackChannelId: string;
|
|
63
|
+
chatChannelId: string;
|
|
64
|
+
} | null;
|
|
65
|
+
/** The Crewly chat channel a Slack conversation is mirrored into */
|
|
66
|
+
chatChannelOfSlack: (slackChannelId: string) => {
|
|
67
|
+
chatChannelId: string;
|
|
68
|
+
dm: boolean;
|
|
69
|
+
} | null;
|
|
70
|
+
/** The chat thread root of a Slack thread in a room (rooms thread their Slack threads; DMs do not) */
|
|
71
|
+
slackRootId: (chatChannelId: string, threadTs: string) => string | null;
|
|
72
|
+
/** Post in Slack as the agent (its bot in a DM; in a room the agent's identity); returns the message ts */
|
|
73
|
+
postSlack: (input: {
|
|
74
|
+
agentSession: string;
|
|
75
|
+
slackChannelId: string;
|
|
76
|
+
threadTs?: string;
|
|
77
|
+
text: string;
|
|
78
|
+
}) => Promise<string | null>;
|
|
79
|
+
/** The owner's DM channel with the agent in Crewly chat */
|
|
80
|
+
ownerDmChannel: (agentSession: string) => string;
|
|
81
|
+
/** Record the owner's turn in Crewly chat and deliver it to the agent */
|
|
82
|
+
recordOwnerTurn: (input: {
|
|
83
|
+
agentSession: string;
|
|
84
|
+
channelId: string;
|
|
85
|
+
threadId?: string;
|
|
86
|
+
text: string;
|
|
87
|
+
metadata: MeetingRowMetadata;
|
|
88
|
+
}) => Promise<{
|
|
89
|
+
messageId: string;
|
|
90
|
+
}>;
|
|
91
|
+
now?: () => Date;
|
|
92
|
+
logger?: ComponentLogger;
|
|
93
|
+
}
|
|
94
|
+
/** Metadata on a chat row a write-back records. */
|
|
95
|
+
export interface MeetingRowMetadata {
|
|
96
|
+
source: typeof MEETING_CONSTANTS.SOURCE;
|
|
97
|
+
[key: string]: unknown;
|
|
98
|
+
}
|
|
99
|
+
/** What a write-back did. */
|
|
100
|
+
export interface MeetingWriteBackResult {
|
|
101
|
+
/** The thread it went into (a new topic's new thread included) */
|
|
102
|
+
threadRef?: string;
|
|
103
|
+
via: 'decision' | 'slack' | 'chat';
|
|
104
|
+
}
|
|
105
|
+
/** The machine side of a 1:1 meeting — see module docs. */
|
|
106
|
+
export declare class DriveMeetingService {
|
|
107
|
+
private readonly deps;
|
|
108
|
+
private readonly logger;
|
|
109
|
+
private readonly now;
|
|
110
|
+
/** New-topic threads by `<sessionId>\u0000<topic>`, so a second write-back reuses the first one's thread */
|
|
111
|
+
private readonly newThreads;
|
|
112
|
+
/**
|
|
113
|
+
* @param deps - Collaborators
|
|
114
|
+
*/
|
|
115
|
+
constructor(deps: DriveMeetingDeps);
|
|
116
|
+
/**
|
|
117
|
+
* Build the meeting pack for one agent. Each source is read on its own; a
|
|
118
|
+
* failing one is left empty, never the whole pack.
|
|
119
|
+
*
|
|
120
|
+
* @param req - Who the meeting is with
|
|
121
|
+
* @returns The pack (within the token budget)
|
|
122
|
+
*/
|
|
123
|
+
buildPack(req: DriveMeetingPackFetch): Promise<MeetingPackWire>;
|
|
124
|
+
/**
|
|
125
|
+
* Live wiki search for the meeting: BM25 over the agent's own vaults.
|
|
126
|
+
*
|
|
127
|
+
* @param req - Agent + query
|
|
128
|
+
* @returns Top hits in plain words, and how long the search took (ms)
|
|
129
|
+
*/
|
|
130
|
+
searchWiki(req: DriveWikiFetch): Promise<{
|
|
131
|
+
hits: Array<{
|
|
132
|
+
title: string;
|
|
133
|
+
where: string;
|
|
134
|
+
text: string;
|
|
135
|
+
}>;
|
|
136
|
+
ms: number;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Write one meeting outcome into the thread it belongs to and hand it to
|
|
140
|
+
* the agent.
|
|
141
|
+
*
|
|
142
|
+
* @param input - Session, agent, the owner's words and where they go
|
|
143
|
+
* @returns Where it was written
|
|
144
|
+
*/
|
|
145
|
+
writeBack(input: {
|
|
146
|
+
sessionId: string;
|
|
147
|
+
agentSession: string;
|
|
148
|
+
text: string;
|
|
149
|
+
writeBack: DriveWriteBack;
|
|
150
|
+
}): Promise<MeetingWriteBackResult>;
|
|
151
|
+
/** Post in a Slack thread as the agent and record it in Crewly chat. */
|
|
152
|
+
private writeSlack;
|
|
153
|
+
/** Settle the agent's open card in that thread, when there is one and the words answer it. */
|
|
154
|
+
private settleCard;
|
|
155
|
+
private remember;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=drive-meeting.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-meeting.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACvG,OAAO,EAOL,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AAIjC,kCAAkC;AAClC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACnF,8CAA8C;IAC9C,SAAS,EAAE,MAAM,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAClD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClD,0DAA0D;IAC1D,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3D,4FAA4F;IAC5F,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1D,gGAAgG;IAChG,UAAU,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC3G,wDAAwD;IACxD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvD,+FAA+F;IAC/F,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,oEAAoE;IACpE,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9F,oEAAoE;IACpE,kBAAkB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9F,sGAAsG;IACtG,WAAW,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACxE,2GAA2G;IAC3G,SAAS,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChI,2DAA2D;IAC3D,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,yEAAyE;IACzE,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,kBAAkB,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvK,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,mDAAmD;AACnD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,iBAAiB,CAAC,MAAM,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,6BAA6B;AAC7B,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;CACpC;AASD,2DAA2D;AAC3D,qBAAa,mBAAmB;IASlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IARjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,4GAA4G;IAC5G,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IAExD;;OAEG;gBAC0B,IAAI,EAAE,gBAAgB;IAKnD;;;;;;OAMG;IACG,SAAS,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IAsCrE;;;;;OAKG;IACG,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAa3H;;;;;;OAMG;IACG,SAAS,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmD7I,wEAAwE;YAC1D,UAAU;IAgBxB,8FAA8F;YAChF,UAAU;IAaxB,OAAO,CAAC,QAAQ;CAQjB"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DriveMeetingService — the machine side of a voice 1:1 meeting with one
|
|
3
|
+
* agent (Meetings P2b, crewly#1415). Cloud hosts the meeting; this machine
|
|
4
|
+
* answers what only it can, for that agent only:
|
|
5
|
+
*
|
|
6
|
+
* - `buildPack` (`op:'meeting_pack'`): the agent's meeting pack — role,
|
|
7
|
+
* team, handover, work, the last owner↔agent messages, recent decisions,
|
|
8
|
+
* the agenda of open threads and relevant wiki pages
|
|
9
|
+
* (drive-meeting-pack.ts);
|
|
10
|
+
* - `searchWiki` (`op:'wiki_search'`): BM25 over the agent's own team and
|
|
11
|
+
* project vaults, top snippets in plain words, with the time it took;
|
|
12
|
+
* - `writeBack` (a delivery carrying `writeBack`): a decision, answer, task
|
|
13
|
+
* or note from the meeting is written into the thread it belongs to — a
|
|
14
|
+
* Slack thread (posted by the agent's bot, recorded in Crewly chat), a
|
|
15
|
+
* Crewly chat thread, or the open decision card it answers — and the
|
|
16
|
+
* agent gets it like any message from the owner. A new topic starts a
|
|
17
|
+
* new thread, which later write-backs on that topic reuse.
|
|
18
|
+
*
|
|
19
|
+
* Nothing the owner or the agent says is written to this machine's server
|
|
20
|
+
* logs: only counts, sizes and timings.
|
|
21
|
+
*
|
|
22
|
+
* @module services/drive/drive-meeting.service
|
|
23
|
+
*/
|
|
24
|
+
import { performance } from 'node:perf_hooks';
|
|
25
|
+
import { MEETING_CONSTANTS } from '../../constants.js';
|
|
26
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
27
|
+
import { clip } from '../briefing/briefing.utils.js';
|
|
28
|
+
import { redactSecrets } from '../../utils/secret-redactor.js';
|
|
29
|
+
import { buildMeetingPack, packWikiQuery, parseChatThreadRef, parseSlackThreadRef, plainWords, buildAgenda, } from './drive-meeting-pack.js';
|
|
30
|
+
const C = MEETING_CONSTANTS;
|
|
31
|
+
const KIND_LABEL = {
|
|
32
|
+
decision: 'Decision',
|
|
33
|
+
answer: 'Answer',
|
|
34
|
+
task: 'New task',
|
|
35
|
+
note: 'Note',
|
|
36
|
+
};
|
|
37
|
+
/** The machine side of a 1:1 meeting — see module docs. */
|
|
38
|
+
export class DriveMeetingService {
|
|
39
|
+
deps;
|
|
40
|
+
logger;
|
|
41
|
+
now;
|
|
42
|
+
/** New-topic threads by `<sessionId>\u0000<topic>`, so a second write-back reuses the first one's thread */
|
|
43
|
+
newThreads = new Map();
|
|
44
|
+
/**
|
|
45
|
+
* @param deps - Collaborators
|
|
46
|
+
*/
|
|
47
|
+
constructor(deps) {
|
|
48
|
+
this.deps = deps;
|
|
49
|
+
this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('DriveMeeting');
|
|
50
|
+
this.now = deps.now ?? (() => new Date());
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build the meeting pack for one agent. Each source is read on its own; a
|
|
54
|
+
* failing one is left empty, never the whole pack.
|
|
55
|
+
*
|
|
56
|
+
* @param req - Who the meeting is with
|
|
57
|
+
* @returns The pack (within the token budget)
|
|
58
|
+
*/
|
|
59
|
+
async buildPack(req) {
|
|
60
|
+
const started = performance.now();
|
|
61
|
+
const now = this.now();
|
|
62
|
+
const agent = { session: req.agentSession, name: req.name, ...(req.role ? { role: req.role } : {}), ...(req.team ? { team: req.team } : {}) };
|
|
63
|
+
const [timeline, decisions, snapshot, handover] = await Promise.all([
|
|
64
|
+
read(() => this.deps.timeline(req.agentSession, now.getTime() - C.AGENDA_WINDOW_MS), []),
|
|
65
|
+
read(() => this.deps.decisions(), []),
|
|
66
|
+
read(async () => (this.deps.snapshot ? this.deps.snapshot() : null), null),
|
|
67
|
+
read(() => this.deps.handover(req.agentSession), null),
|
|
68
|
+
]);
|
|
69
|
+
// Wiki pages for the team and the agenda topics.
|
|
70
|
+
const agenda = buildAgenda({ now, agent, timeline, decisions });
|
|
71
|
+
const query = packWikiQuery(agent, agenda);
|
|
72
|
+
let wiki = [];
|
|
73
|
+
if (query) {
|
|
74
|
+
const vaults = await read(() => this.deps.vaults(req.agentSession), []);
|
|
75
|
+
const hits = vaults.length ? await read(() => this.deps.searchWiki(vaults, query, req.agentSession), []) : [];
|
|
76
|
+
wiki = await Promise.all(hits.slice(0, C.WIKI_PAGES_MAX).map(async (h) => {
|
|
77
|
+
const page = h.absPath && this.deps.readPage ? await read(() => this.deps.readPage(h.absPath), null) : null;
|
|
78
|
+
return { title: h.title, where: h.where, text: clip((page ?? h.text).trim(), C.WIKI_PAGE_MAX_CHARS) };
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
const pack = buildMeetingPack({ now, agent, handover, snapshot, timeline, decisions, wiki });
|
|
82
|
+
this.logger.info('Meeting pack built', {
|
|
83
|
+
agent: req.agentSession,
|
|
84
|
+
ms: Math.round(performance.now() - started),
|
|
85
|
+
estTokens: pack.estTokens,
|
|
86
|
+
agenda: pack.agenda.length,
|
|
87
|
+
messages: pack.messages.length,
|
|
88
|
+
work: pack.work.length,
|
|
89
|
+
wiki: pack.wiki.length,
|
|
90
|
+
handover: !!pack.handover,
|
|
91
|
+
});
|
|
92
|
+
return pack;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Live wiki search for the meeting: BM25 over the agent's own vaults.
|
|
96
|
+
*
|
|
97
|
+
* @param req - Agent + query
|
|
98
|
+
* @returns Top hits in plain words, and how long the search took (ms)
|
|
99
|
+
*/
|
|
100
|
+
async searchWiki(req) {
|
|
101
|
+
const started = performance.now();
|
|
102
|
+
const vaults = await read(() => this.deps.vaults(req.agentSession), []);
|
|
103
|
+
const raw = vaults.length ? await read(() => this.deps.searchWiki(vaults, req.query, req.agentSession), []) : [];
|
|
104
|
+
const hits = raw
|
|
105
|
+
.slice(0, C.WIKI_HITS_MAX)
|
|
106
|
+
.map((h) => ({ title: clip(h.title, 160), where: clip(h.where, 160), text: plainWords(h.text, C.WIKI_HIT_MAX_CHARS) }))
|
|
107
|
+
.filter((h) => h.title && h.text);
|
|
108
|
+
const ms = Math.round(performance.now() - started);
|
|
109
|
+
this.logger.info('Meeting wiki search', { agent: req.agentSession, vaults: vaults.length, hits: hits.length, ms });
|
|
110
|
+
return { hits, ms };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Write one meeting outcome into the thread it belongs to and hand it to
|
|
114
|
+
* the agent.
|
|
115
|
+
*
|
|
116
|
+
* @param input - Session, agent, the owner's words and where they go
|
|
117
|
+
* @returns Where it was written
|
|
118
|
+
*/
|
|
119
|
+
async writeBack(input) {
|
|
120
|
+
const w = input.writeBack;
|
|
121
|
+
const words = clip(redactSecrets(input.text.trim()), C.WRITE_BACK_MAX_CHARS);
|
|
122
|
+
const key = `${input.sessionId}\u0000${(w.newTopic ?? w.topic).toLowerCase()}`;
|
|
123
|
+
const ref = w.threadRef ?? this.newThreads.get(key);
|
|
124
|
+
const line = `From our voice meeting — ${KIND_LABEL[w.kind]}: ${words}`;
|
|
125
|
+
const meta = { source: C.SOURCE, via: C.VIA, inputMode: 'voice', meetingSessionId: input.sessionId, meetingKind: w.kind };
|
|
126
|
+
if (ref) {
|
|
127
|
+
const slack = parseSlackThreadRef(ref);
|
|
128
|
+
if (slack) {
|
|
129
|
+
// An open card in that thread: the owner's words settle it.
|
|
130
|
+
if ((w.kind === 'decision' || w.kind === 'answer') && (await this.settleCard(input.agentSession, ref, words))) {
|
|
131
|
+
return { threadRef: ref, via: 'decision' };
|
|
132
|
+
}
|
|
133
|
+
await this.writeSlack(input.agentSession, slack.slackChannelId, slack.threadTs, line, meta);
|
|
134
|
+
return { threadRef: ref, via: 'slack' };
|
|
135
|
+
}
|
|
136
|
+
const chat = parseChatThreadRef(ref);
|
|
137
|
+
if (chat) {
|
|
138
|
+
await this.deps.recordOwnerTurn({ agentSession: input.agentSession, channelId: chat.channelId, ...(chat.rootId ? { threadId: chat.rootId } : {}), text: line, metadata: meta });
|
|
139
|
+
return { threadRef: ref, via: 'chat' };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// A new topic: a new thread, in Slack when the agent has a DM there.
|
|
143
|
+
const topic = clip(w.newTopic ?? w.topic, C.TOPIC_MAX_CHARS);
|
|
144
|
+
const opening = `${topic}\n${line}`;
|
|
145
|
+
const dm = this.deps.slackDmOf(input.agentSession);
|
|
146
|
+
let made = null;
|
|
147
|
+
if (dm) {
|
|
148
|
+
const ts = await this.deps.postSlack({ agentSession: input.agentSession, slackChannelId: dm.slackChannelId, text: opening }).catch(() => null);
|
|
149
|
+
if (ts) {
|
|
150
|
+
await this.deps.recordOwnerTurn({
|
|
151
|
+
agentSession: input.agentSession,
|
|
152
|
+
channelId: dm.chatChannelId,
|
|
153
|
+
text: opening,
|
|
154
|
+
metadata: { ...meta, slackChannelId: dm.slackChannelId, slackTs: ts, slackThreadTs: ts, slackAlreadyPosted: true },
|
|
155
|
+
});
|
|
156
|
+
made = { threadRef: `slack:${dm.slackChannelId}:${ts}`, via: 'slack' };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!made) {
|
|
160
|
+
const channelId = this.deps.ownerDmChannel(input.agentSession);
|
|
161
|
+
const { messageId } = await this.deps.recordOwnerTurn({ agentSession: input.agentSession, channelId, text: opening, metadata: meta });
|
|
162
|
+
made = { threadRef: `chat:${channelId}:${messageId}`, via: 'chat' };
|
|
163
|
+
}
|
|
164
|
+
if (made.threadRef)
|
|
165
|
+
this.remember(key, made.threadRef);
|
|
166
|
+
return made;
|
|
167
|
+
}
|
|
168
|
+
/** Post in a Slack thread as the agent and record it in Crewly chat. */
|
|
169
|
+
async writeSlack(agentSession, slackChannelId, threadTs, text, meta) {
|
|
170
|
+
const ts = await this.deps.postSlack({ agentSession, slackChannelId, threadTs, text }).catch((err) => {
|
|
171
|
+
this.logger.warn('Meeting write-back: Slack post failed', { agent: agentSession, error: err instanceof Error ? err.message : String(err) });
|
|
172
|
+
return null;
|
|
173
|
+
});
|
|
174
|
+
const chat = this.deps.chatChannelOfSlack(slackChannelId);
|
|
175
|
+
const slackMeta = { ...meta, slackChannelId, slackThreadTs: threadTs, ...(ts ? { slackTs: ts, slackAlreadyPosted: true } : {}) };
|
|
176
|
+
if (chat) {
|
|
177
|
+
const root = chat.dm ? null : this.deps.slackRootId(chat.chatChannelId, threadTs);
|
|
178
|
+
await this.deps.recordOwnerTurn({ agentSession, channelId: chat.chatChannelId, ...(root ? { threadId: root } : {}), text, metadata: slackMeta });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// Not mirrored here: the agent still gets it, in its DM.
|
|
182
|
+
await this.deps.recordOwnerTurn({ agentSession, channelId: this.deps.ownerDmChannel(agentSession), text, metadata: slackMeta });
|
|
183
|
+
}
|
|
184
|
+
/** Settle the agent's open card in that thread, when there is one and the words answer it. */
|
|
185
|
+
async settleCard(agentSession, ref, words) {
|
|
186
|
+
if (!this.deps.answerDecision)
|
|
187
|
+
return false;
|
|
188
|
+
const decisions = await read(() => this.deps.decisions(), []);
|
|
189
|
+
const card = decisions.find((d) => {
|
|
190
|
+
if (d.status !== 'open' || (d.asker !== agentSession && d.requestedBy !== agentSession))
|
|
191
|
+
return false;
|
|
192
|
+
const ch = d.card?.slackChannelId ?? d.place?.slackChannelId;
|
|
193
|
+
const ts = d.card ? (d.card.threadTs ?? d.card.messageTs) : d.place?.threadTs;
|
|
194
|
+
return !!ch && !!ts && `slack:${ch}:${ts}` === ref;
|
|
195
|
+
});
|
|
196
|
+
if (!card)
|
|
197
|
+
return false;
|
|
198
|
+
return this.deps.answerDecision(card.id, words).catch(() => false);
|
|
199
|
+
}
|
|
200
|
+
remember(key, ref) {
|
|
201
|
+
this.newThreads.set(key, ref);
|
|
202
|
+
while (this.newThreads.size > C.NEW_THREADS_MAX) {
|
|
203
|
+
const oldest = this.newThreads.keys().next().value;
|
|
204
|
+
if (oldest === undefined)
|
|
205
|
+
break;
|
|
206
|
+
this.newThreads.delete(oldest);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/** Read a source; a failure gives the fallback. */
|
|
211
|
+
async function read(fn, fallback) {
|
|
212
|
+
try {
|
|
213
|
+
return await fn();
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return fallback;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=drive-meeting.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-meeting.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the sources of a 1:1 meeting (Meetings P2b, crewly#1415) from this
|
|
3
|
+
* machine: which wiki vaults an agent may read, its latest handover, wiki
|
|
4
|
+
* hits as meeting pages, and decision cards in the shape the pack uses. The
|
|
5
|
+
* glue that binds these to the running services lives in index.ts.
|
|
6
|
+
*
|
|
7
|
+
* Privacy: an agent's vaults are its own teams' vaults and those teams'
|
|
8
|
+
* project vaults — never the global wiki, never another team's.
|
|
9
|
+
*
|
|
10
|
+
* @module services/drive/drive-meeting.wiring
|
|
11
|
+
*/
|
|
12
|
+
import type { Team } from '../../types/index.js';
|
|
13
|
+
import type { OwnerDecision } from '../../types/decision.types.js';
|
|
14
|
+
import type { WikiSearchHit } from '../wiki/wiki-search.service.js';
|
|
15
|
+
import type { MeetingDecisionSource } from './drive-meeting-pack.js';
|
|
16
|
+
import type { MeetingVault, MeetingWikiPageHit } from './drive-meeting.service.js';
|
|
17
|
+
/**
|
|
18
|
+
* The teams an agent is a member of.
|
|
19
|
+
*
|
|
20
|
+
* @param teams - Every team
|
|
21
|
+
* @param agentSession - The agent
|
|
22
|
+
* @returns Its teams, with its role in each
|
|
23
|
+
*/
|
|
24
|
+
export declare function teamsOfAgent(teams: readonly Team[], agentSession: string): Array<{
|
|
25
|
+
team: Team;
|
|
26
|
+
role?: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* The vaults an agent may read: each of its teams' vaults, then those teams'
|
|
30
|
+
* project vaults (deduplicated).
|
|
31
|
+
*
|
|
32
|
+
* @param teams - Every team
|
|
33
|
+
* @param projects - Every project
|
|
34
|
+
* @param agentSession - The agent
|
|
35
|
+
* @param crewlyHome - CREWLY_HOME
|
|
36
|
+
* @returns Vaults with labels (team / project names)
|
|
37
|
+
*/
|
|
38
|
+
export declare function vaultsOfAgent(teams: readonly Team[], projects: ReadonlyArray<{
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
path: string;
|
|
42
|
+
}>, agentSession: string, crewlyHome: string): MeetingVault[];
|
|
43
|
+
/**
|
|
44
|
+
* A wiki hit as a meeting page: a readable title, where it is, its matching
|
|
45
|
+
* lines, and the page file.
|
|
46
|
+
*
|
|
47
|
+
* @param hit - BM25 hit
|
|
48
|
+
* @returns Page hit
|
|
49
|
+
*/
|
|
50
|
+
export declare function wikiHitToPage(hit: WikiSearchHit): MeetingWikiPageHit;
|
|
51
|
+
/**
|
|
52
|
+
* Remove a page's YAML frontmatter.
|
|
53
|
+
*
|
|
54
|
+
* @param text - Page text
|
|
55
|
+
* @returns The body
|
|
56
|
+
*/
|
|
57
|
+
export declare function stripFrontmatter(text: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* A wiki page's body, clipped, or null when it cannot be read.
|
|
60
|
+
*
|
|
61
|
+
* @param absPath - Page file
|
|
62
|
+
* @returns The body
|
|
63
|
+
*/
|
|
64
|
+
export declare function readWikiPage(absPath: string): Promise<string | null>;
|
|
65
|
+
/**
|
|
66
|
+
* The agent's newest handover text, or null.
|
|
67
|
+
*
|
|
68
|
+
* @param handoverDir - Handover directory
|
|
69
|
+
* @param agentSession - The agent
|
|
70
|
+
* @returns Text (title line removed), clipped
|
|
71
|
+
*/
|
|
72
|
+
export declare function readLatestHandover(handoverDir: string, agentSession: string): Promise<string | null>;
|
|
73
|
+
/**
|
|
74
|
+
* A decision card in the shape the pack uses.
|
|
75
|
+
*
|
|
76
|
+
* @param d - Owner decision
|
|
77
|
+
* @returns Pack source
|
|
78
|
+
*/
|
|
79
|
+
export declare function decisionSource(d: OwnerDecision): MeetingDecisionSource;
|
|
80
|
+
//# sourceMappingURL=drive-meeting.wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-meeting.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAQnF;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAO/G;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,QAAQ,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACnE,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,YAAY,EAAE,CAkBhB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,kBAAkB,CASpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO1E;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS1G;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAgBtE"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the sources of a 1:1 meeting (Meetings P2b, crewly#1415) from this
|
|
3
|
+
* machine: which wiki vaults an agent may read, its latest handover, wiki
|
|
4
|
+
* hits as meeting pages, and decision cards in the shape the pack uses. The
|
|
5
|
+
* glue that binds these to the running services lives in index.ts.
|
|
6
|
+
*
|
|
7
|
+
* Privacy: an agent's vaults are its own teams' vaults and those teams'
|
|
8
|
+
* project vaults — never the global wiki, never another team's.
|
|
9
|
+
*
|
|
10
|
+
* @module services/drive/drive-meeting.wiring
|
|
11
|
+
*/
|
|
12
|
+
import { promises as fs } from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { MEETING_CONSTANTS } from '../../constants.js';
|
|
15
|
+
import { resolveMemberSessionName } from '../../utils/member-session-name.utils.js';
|
|
16
|
+
import { latestHandoverFile } from '../agent/runtime-session-recovery.js';
|
|
17
|
+
/** Where team vaults live under the Crewly home. */
|
|
18
|
+
const TEAMS_DIR = 'teams';
|
|
19
|
+
const WIKI_DIR = 'wiki';
|
|
20
|
+
/** A project's vault, under its root. */
|
|
21
|
+
const PROJECT_VAULT = path.join('.crewly', 'wiki');
|
|
22
|
+
/**
|
|
23
|
+
* The teams an agent is a member of.
|
|
24
|
+
*
|
|
25
|
+
* @param teams - Every team
|
|
26
|
+
* @param agentSession - The agent
|
|
27
|
+
* @returns Its teams, with its role in each
|
|
28
|
+
*/
|
|
29
|
+
export function teamsOfAgent(teams, agentSession) {
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const team of teams) {
|
|
32
|
+
const m = (team.members ?? []).find((x) => x?.id && resolveMemberSessionName(team.name, x) === agentSession);
|
|
33
|
+
if (m)
|
|
34
|
+
out.push({ team, ...(m.role ? { role: String(m.role) } : {}) });
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The vaults an agent may read: each of its teams' vaults, then those teams'
|
|
40
|
+
* project vaults (deduplicated).
|
|
41
|
+
*
|
|
42
|
+
* @param teams - Every team
|
|
43
|
+
* @param projects - Every project
|
|
44
|
+
* @param agentSession - The agent
|
|
45
|
+
* @param crewlyHome - CREWLY_HOME
|
|
46
|
+
* @returns Vaults with labels (team / project names)
|
|
47
|
+
*/
|
|
48
|
+
export function vaultsOfAgent(teams, projects, agentSession, crewlyHome) {
|
|
49
|
+
const out = [];
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
const add = (vaultPath, label) => {
|
|
52
|
+
const key = path.resolve(vaultPath);
|
|
53
|
+
if (seen.has(key))
|
|
54
|
+
return;
|
|
55
|
+
seen.add(key);
|
|
56
|
+
out.push({ vaultPath: key, label });
|
|
57
|
+
};
|
|
58
|
+
const mine = teamsOfAgent(teams, agentSession);
|
|
59
|
+
for (const { team } of mine)
|
|
60
|
+
add(path.join(crewlyHome, TEAMS_DIR, team.id, WIKI_DIR), team.name);
|
|
61
|
+
for (const { team } of mine) {
|
|
62
|
+
for (const id of team.projectIds ?? []) {
|
|
63
|
+
const p = projects.find((x) => x.id === id);
|
|
64
|
+
if (p?.path && path.isAbsolute(p.path))
|
|
65
|
+
add(path.join(p.path, PROJECT_VAULT), p.name);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A wiki hit as a meeting page: a readable title, where it is, its matching
|
|
72
|
+
* lines, and the page file.
|
|
73
|
+
*
|
|
74
|
+
* @param hit - BM25 hit
|
|
75
|
+
* @returns Page hit
|
|
76
|
+
*/
|
|
77
|
+
export function wikiHitToPage(hit) {
|
|
78
|
+
const base = path.basename(hit.relativePath).replace(/\.md$/i, '');
|
|
79
|
+
const title = base.replace(/[-_]+/g, ' ').trim() || hit.relativePath;
|
|
80
|
+
return {
|
|
81
|
+
title,
|
|
82
|
+
where: hit.vaultLabel ? `${hit.vaultLabel}/${hit.relativePath}` : hit.relativePath,
|
|
83
|
+
text: hit.snippets.map((s) => s.text).join(' … '),
|
|
84
|
+
...(hit.vaultPath ? { absPath: path.join(hit.vaultPath, hit.relativePath) } : {}),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Remove a page's YAML frontmatter.
|
|
89
|
+
*
|
|
90
|
+
* @param text - Page text
|
|
91
|
+
* @returns The body
|
|
92
|
+
*/
|
|
93
|
+
export function stripFrontmatter(text) {
|
|
94
|
+
return text.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '').trim();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A wiki page's body, clipped, or null when it cannot be read.
|
|
98
|
+
*
|
|
99
|
+
* @param absPath - Page file
|
|
100
|
+
* @returns The body
|
|
101
|
+
*/
|
|
102
|
+
export async function readWikiPage(absPath) {
|
|
103
|
+
try {
|
|
104
|
+
const raw = await fs.readFile(absPath, 'utf8');
|
|
105
|
+
return stripFrontmatter(raw).slice(0, MEETING_CONSTANTS.WIKI_PAGE_MAX_CHARS * 2);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The agent's newest handover text, or null.
|
|
113
|
+
*
|
|
114
|
+
* @param handoverDir - Handover directory
|
|
115
|
+
* @param agentSession - The agent
|
|
116
|
+
* @returns Text (title line removed), clipped
|
|
117
|
+
*/
|
|
118
|
+
export async function readLatestHandover(handoverDir, agentSession) {
|
|
119
|
+
const file = latestHandoverFile(handoverDir, agentSession);
|
|
120
|
+
if (!file)
|
|
121
|
+
return null;
|
|
122
|
+
try {
|
|
123
|
+
const raw = await fs.readFile(file.path, 'utf8');
|
|
124
|
+
return raw.replace(/^#[^\n]*\n/, '').trim().slice(0, MEETING_CONSTANTS.HANDOVER_MAX_CHARS * 2) || null;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A decision card in the shape the pack uses.
|
|
132
|
+
*
|
|
133
|
+
* @param d - Owner decision
|
|
134
|
+
* @returns Pack source
|
|
135
|
+
*/
|
|
136
|
+
export function decisionSource(d) {
|
|
137
|
+
return {
|
|
138
|
+
id: d.id,
|
|
139
|
+
question: d.question,
|
|
140
|
+
status: d.status,
|
|
141
|
+
asker: d.asker,
|
|
142
|
+
requestedBy: d.requestedBy,
|
|
143
|
+
options: d.options.map((o) => ({ key: o.key, label: o.label })),
|
|
144
|
+
...(d.card ? { card: { slackChannelId: d.card.slackChannelId, messageTs: d.card.messageTs, ...(d.card.threadTs ? { threadTs: d.card.threadTs } : {}) } } : {}),
|
|
145
|
+
...(d.place ? { place: d.place } : {}),
|
|
146
|
+
...(d.chosenKey ? { chosenKey: d.chosenKey } : {}),
|
|
147
|
+
...(d.answerText ? { answerText: d.answerText } : {}),
|
|
148
|
+
...(d.ownerWords ? { ownerWords: d.ownerWords } : {}),
|
|
149
|
+
createdAt: d.createdAt,
|
|
150
|
+
updatedAt: d.updatedAt,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=drive-meeting.wiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-meeting.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAK1E,oDAAoD;AACpD,MAAM,SAAS,GAAG,OAAO,CAAC;AAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC;AACxB,yCAAyC;AACzC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAsB,EAAE,YAAoB;IACvE,MAAM,GAAG,GAAyC,EAAE,CAAC;IACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC;QAC7G,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAsB,EACtB,QAAmE,EACnE,YAAoB,EACpB,UAAkB;IAElB,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAG,CAAC,SAAiB,EAAE,KAAa,EAAQ,EAAE;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO;QAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC/C,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACjG,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YACvC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAkB;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,YAAY,CAAC;IACrE,OAAO;QACL,KAAK;QACL,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY;QAClF,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACjD,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,WAAmB,EAAE,YAAoB;IAChF,MAAM,IAAI,GAAG,kBAAkB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,kBAAkB,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;IACzG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,CAAgB;IAC7C,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9J,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,SAAS,EAAE,CAAC,CAAC,SAAS;KACvB,CAAC;AACJ,CAAC"}
|