crewly 1.20.276 → 1.20.277
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 +85 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +85 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/briefing/briefing.controller.d.ts +23 -0
- package/dist/backend/backend/src/controllers/briefing/briefing.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/briefing/briefing.controller.js +79 -0
- package/dist/backend/backend/src/controllers/briefing/briefing.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/talk/talk-live-token.controller.d.ts +34 -0
- package/dist/backend/backend/src/controllers/talk/talk-live-token.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/talk/talk-live-token.controller.js +72 -0
- package/dist/backend/backend/src/controllers/talk/talk-live-token.controller.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +69 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +6 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/briefing/briefing-state.store.d.ts +45 -0
- package/dist/backend/backend/src/services/briefing/briefing-state.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing-state.store.js +93 -0
- package/dist/backend/backend/src/services/briefing/briefing-state.store.js.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing.service.d.ts +214 -0
- package/dist/backend/backend/src/services/briefing/briefing.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing.service.js +585 -0
- package/dist/backend/backend/src/services/briefing/briefing.service.js.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing.types.d.ts +172 -0
- package/dist/backend/backend/src/services/briefing/briefing.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing.types.js +27 -0
- package/dist/backend/backend/src/services/briefing/briefing.types.js.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing.utils.d.ts +71 -0
- package/dist/backend/backend/src/services/briefing/briefing.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/briefing/briefing.utils.js +134 -0
- package/dist/backend/backend/src/services/briefing/briefing.utils.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +8 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +14 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +24 -2
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/talk/talk-live-token.service.d.ts +166 -0
- package/dist/backend/backend/src/services/talk/talk-live-token.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/talk/talk-live-token.service.js +285 -0
- package/dist/backend/backend/src/services/talk/talk-live-token.service.js.map +1 -0
- package/dist/backend/backend/src/types/decision.types.d.ts +3 -3
- package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +85 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +85 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +14 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +24 -2
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/cli/backend/src/types/decision.types.d.ts +3 -3
- package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive mode briefing API (specs/2026-10-08-drive-mode.md), mounted at
|
|
3
|
+
* `/api/briefing` and reached from the portal over the relay.
|
|
4
|
+
*
|
|
5
|
+
* - `GET /` — the owner's queue, ordered by urgency then age
|
|
6
|
+
* - `POST /:id/answer` — `{ optionKey? , text?, confirm?, confirmToken? }`
|
|
7
|
+
* - `POST /:id/skip` — `{ dismiss? }` — next (hide for a while) / drop it
|
|
8
|
+
* - `POST /:id/later` — `{ at?: ISO }` — remind later (default tomorrow morning)
|
|
9
|
+
* - `POST /:id/ask` — `{ question }` — hand a follow-up to the agent
|
|
10
|
+
*
|
|
11
|
+
* Owner only: an agent gets 403, a caller without an owner credential 401.
|
|
12
|
+
* Nothing the owner says is logged.
|
|
13
|
+
*
|
|
14
|
+
* @module controllers/briefing/briefing.controller
|
|
15
|
+
*/
|
|
16
|
+
import { Router } from 'express';
|
|
17
|
+
import { BRIEFING_CONSTANTS } from '../../constants.js';
|
|
18
|
+
import { rejectNonOwner } from '../../middleware/caller-identity.middleware.js';
|
|
19
|
+
import { BriefingError } from '../../services/briefing/briefing.types.js';
|
|
20
|
+
import { getBriefingService } from '../../services/briefing/briefing.service.js';
|
|
21
|
+
const C = BRIEFING_CONSTANTS;
|
|
22
|
+
/**
|
|
23
|
+
* Run an owner-only handler and map its errors.
|
|
24
|
+
*
|
|
25
|
+
* @param req - Request
|
|
26
|
+
* @param res - Response
|
|
27
|
+
* @param fn - Handler given the running service
|
|
28
|
+
*/
|
|
29
|
+
async function handle(req, res, fn) {
|
|
30
|
+
if (rejectNonOwner(req, res, { success: false, code: C.CODES.OWNER_ONLY, error: 'Only the owner can use Drive mode.' }))
|
|
31
|
+
return;
|
|
32
|
+
const service = getBriefingService();
|
|
33
|
+
if (!service) {
|
|
34
|
+
res.status(503).json({ success: false, code: C.CODES.NOT_READY, error: 'Drive mode is not ready yet — Crewly is still starting.' });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
res.json({ success: true, data: await fn(service) });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error instanceof BriefingError) {
|
|
42
|
+
res.status(error.status).json({ success: false, code: error.code, error: error.message });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
res.status(500).json({ success: false, code: C.CODES.FAILED, error: 'That did not work.' });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The request body as an object.
|
|
50
|
+
*
|
|
51
|
+
* @param req - Request
|
|
52
|
+
* @returns Body
|
|
53
|
+
*/
|
|
54
|
+
function body(req) {
|
|
55
|
+
return req.body && typeof req.body === 'object' ? req.body : {};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create the briefing router.
|
|
59
|
+
*
|
|
60
|
+
* @returns Express router
|
|
61
|
+
*/
|
|
62
|
+
export function createBriefingRouter() {
|
|
63
|
+
const router = Router();
|
|
64
|
+
router.get('/', (req, res) => handle(req, res, (s) => s.queue()));
|
|
65
|
+
router.post('/:id/answer', (req, res) => handle(req, res, (s) => {
|
|
66
|
+
const b = body(req);
|
|
67
|
+
return s.answer(req.params.id, {
|
|
68
|
+
optionKey: b.optionKey,
|
|
69
|
+
text: b.text,
|
|
70
|
+
confirm: b.confirm === true,
|
|
71
|
+
confirmToken: b.confirmToken,
|
|
72
|
+
});
|
|
73
|
+
}));
|
|
74
|
+
router.post('/:id/skip', (req, res) => handle(req, res, (s) => s.skip(req.params.id, { dismiss: body(req).dismiss === true })));
|
|
75
|
+
router.post('/:id/later', (req, res) => handle(req, res, (s) => s.later(req.params.id, { at: body(req).at })));
|
|
76
|
+
router.post('/:id/ask', (req, res) => handle(req, res, (s) => s.ask(req.params.id, body(req).question)));
|
|
77
|
+
return router;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=briefing.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"briefing.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/briefing/briefing.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAwB,MAAM,6CAA6C,CAAC;AAEvG,MAAM,CAAC,GAAG,kBAAkB,CAAC;AAE7B;;;;;;GAMG;AACH,KAAK,UAAU,MAAM,CAAC,GAAY,EAAE,GAAa,EAAE,EAAkD;IACpG,IAAI,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;QAAE,OAAO;IAChI,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,yDAAyD,EAAE,CAAC,CAAC;QACpI,OAAO;IACR,CAAC;IACD,IAAI,CAAC;QACJ,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;YACpC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1F,OAAO;QACR,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAC7F,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,SAAS,IAAI,CAAC,GAAY;IACzB,OAAO,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,GAAG,CAAC,IAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IACnC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CACvC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;YAC9B,SAAS,EAAE,CAAC,CAAC,SAA+B;YAC5C,IAAI,EAAE,CAAC,CAAC,IAA0B;YAClC,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,IAAI;YAC3B,YAAY,EAAE,CAAC,CAAC,YAAkC;SAClD,CAAC,CAAC;IACJ,CAAC,CAAC,CACF,CAAC;IACF,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChI,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/G,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACzG,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive mode voice token (specs/2026-10-08-drive-mode.md §3), mounted at
|
|
3
|
+
* `/api/talk/live-token` and reached from the portal over the relay.
|
|
4
|
+
*
|
|
5
|
+
* - `GET /status` — `{ hasKey, model }` (no network)
|
|
6
|
+
* - `POST /` — `{ language? }` → a Gemini Live ephemeral token locked to the briefer
|
|
7
|
+
*
|
|
8
|
+
* Owner only: an agent gets 403, a caller without an owner credential 401.
|
|
9
|
+
* The API key never leaves this machine; the token is never logged.
|
|
10
|
+
*
|
|
11
|
+
* @module controllers/talk/talk-live-token.controller
|
|
12
|
+
*/
|
|
13
|
+
import { Router, type Request, type Response } from 'express';
|
|
14
|
+
/**
|
|
15
|
+
* GET /api/talk/live-token/status
|
|
16
|
+
*
|
|
17
|
+
* @param req - Request
|
|
18
|
+
* @param res - Response
|
|
19
|
+
*/
|
|
20
|
+
export declare function getLiveTokenStatus(req: Request, res: Response): void;
|
|
21
|
+
/**
|
|
22
|
+
* POST /api/talk/live-token — mint one token.
|
|
23
|
+
*
|
|
24
|
+
* @param req - Request (`{ language? }`)
|
|
25
|
+
* @param res - Response
|
|
26
|
+
*/
|
|
27
|
+
export declare function mintLiveToken(req: Request, res: Response): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Create the live-token router.
|
|
30
|
+
*
|
|
31
|
+
* @returns Express router
|
|
32
|
+
*/
|
|
33
|
+
export declare function createTalkLiveTokenRouter(): Router;
|
|
34
|
+
//# sourceMappingURL=talk-live-token.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"talk-live-token.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/talk/talk-live-token.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkB9D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAIpE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAKlD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive mode voice token (specs/2026-10-08-drive-mode.md §3), mounted at
|
|
3
|
+
* `/api/talk/live-token` and reached from the portal over the relay.
|
|
4
|
+
*
|
|
5
|
+
* - `GET /status` — `{ hasKey, model }` (no network)
|
|
6
|
+
* - `POST /` — `{ language? }` → a Gemini Live ephemeral token locked to the briefer
|
|
7
|
+
*
|
|
8
|
+
* Owner only: an agent gets 403, a caller without an owner credential 401.
|
|
9
|
+
* The API key never leaves this machine; the token is never logged.
|
|
10
|
+
*
|
|
11
|
+
* @module controllers/talk/talk-live-token.controller
|
|
12
|
+
*/
|
|
13
|
+
import { Router } from 'express';
|
|
14
|
+
import { TALK_LIVE_CONSTANTS } from '../../constants.js';
|
|
15
|
+
import { rejectNonOwner } from '../../middleware/caller-identity.middleware.js';
|
|
16
|
+
import { getTalkLiveTokenService, parseLiveLanguage, TalkLiveTokenError } from '../../services/talk/talk-live-token.service.js';
|
|
17
|
+
const C = TALK_LIVE_CONSTANTS;
|
|
18
|
+
/**
|
|
19
|
+
* Refuse callers that are not the owner.
|
|
20
|
+
*
|
|
21
|
+
* @param req - Request
|
|
22
|
+
* @param res - Response
|
|
23
|
+
* @returns True when refused (response written)
|
|
24
|
+
*/
|
|
25
|
+
function refuseNonOwner(req, res) {
|
|
26
|
+
return rejectNonOwner(req, res, { success: false, code: C.CODES.OWNER_ONLY, error: 'Only the owner can use Drive mode.' });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* GET /api/talk/live-token/status
|
|
30
|
+
*
|
|
31
|
+
* @param req - Request
|
|
32
|
+
* @param res - Response
|
|
33
|
+
*/
|
|
34
|
+
export function getLiveTokenStatus(req, res) {
|
|
35
|
+
if (refuseNonOwner(req, res))
|
|
36
|
+
return;
|
|
37
|
+
const service = getTalkLiveTokenService();
|
|
38
|
+
res.json({ success: true, data: { hasKey: service.hasKey(), model: service.buildSetup(C.DEFAULT_LANGUAGE).model.replace(/^models\//, '') } });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* POST /api/talk/live-token — mint one token.
|
|
42
|
+
*
|
|
43
|
+
* @param req - Request (`{ language? }`)
|
|
44
|
+
* @param res - Response
|
|
45
|
+
*/
|
|
46
|
+
export async function mintLiveToken(req, res) {
|
|
47
|
+
if (refuseNonOwner(req, res))
|
|
48
|
+
return;
|
|
49
|
+
const language = parseLiveLanguage((req.body ?? {}).language);
|
|
50
|
+
try {
|
|
51
|
+
res.json({ success: true, data: await getTalkLiveTokenService().mint(language) });
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error instanceof TalkLiveTokenError) {
|
|
55
|
+
res.status(error.status).json({ success: false, code: error.code, error: error.message });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
res.status(500).json({ success: false, code: C.CODES.FAILED, error: 'Could not start the voice session.' });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create the live-token router.
|
|
63
|
+
*
|
|
64
|
+
* @returns Express router
|
|
65
|
+
*/
|
|
66
|
+
export function createTalkLiveTokenRouter() {
|
|
67
|
+
const router = Router();
|
|
68
|
+
router.get('/status', getLiveTokenStatus);
|
|
69
|
+
router.post('/', mintLiveToken);
|
|
70
|
+
return router;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=talk-live-token.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"talk-live-token.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/talk/talk-live-token.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEhI,MAAM,CAAC,GAAG,mBAAmB,CAAC;AAE9B;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,GAAY,EAAE,GAAa;IAClD,OAAO,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC,CAAC;AAC5H,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY,EAAE,GAAa;IAC7D,IAAI,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC;QAAE,OAAO;IACrC,MAAM,OAAO,GAAG,uBAAuB,EAAE,CAAC;IAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/I,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAY,EAAE,GAAa;IAC9D,IAAI,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC;QAAE,OAAO;IACrC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC9D,IAAI,CAAC;QACJ,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,uBAAuB,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;YACzC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1F,OAAO;QACR,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC,CAAC;IAC7G,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB;IACxC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":";AA4CA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -76,7 +76,8 @@ import { parseInboundOrigin } from './services/orc/orc-reply-route.service.js';
|
|
|
76
76
|
import { parseSlackThreadKey } from './services/slack/slack-thread-key.js';
|
|
77
77
|
import { LIVENESS_MONITOR_CONSTANTS, INPUT_CIRCUIT_CONSTANTS, INPUT_BLOCKED_RETRY_CONSTANTS } from './constants.js';
|
|
78
78
|
import { InputBlockedRetryService } from './services/messaging/input-blocked-retry.service.js';
|
|
79
|
-
import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, AUTO_UPDATE_CONSTANTS, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS, TICKET_CONSTANTS, UNASSIGNED_ROUTE_CONSTANTS, CLOUD_TALK_CONSTANTS, STANDING_ANSWERS_CONSTANTS, TICKET_AUTOPILOT_CONSTANTS, EXPERIMENT_CONSTANTS, WORK_ITEM_DESTINATION_CONSTANTS, CODEX_USAGE_SYNC_CONSTANTS, ANTIGRAVITY_USAGE_SYNC_CONSTANTS, OWNER_AUTH_CONSTANTS, CREWLY_APPS_CONSTANTS } from './constants.js';
|
|
79
|
+
import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, AUTO_UPDATE_CONSTANTS, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS, TICKET_CONSTANTS, UNASSIGNED_ROUTE_CONSTANTS, CLOUD_TALK_CONSTANTS, STANDING_ANSWERS_CONSTANTS, TICKET_AUTOPILOT_CONSTANTS, EXPERIMENT_CONSTANTS, WORK_ITEM_DESTINATION_CONSTANTS, CODEX_USAGE_SYNC_CONSTANTS, ANTIGRAVITY_USAGE_SYNC_CONSTANTS, OWNER_AUTH_CONSTANTS, CREWLY_APPS_CONSTANTS, SLACK_AGENT_DM_CONSTANTS, BRIEFING_CONSTANTS } from './constants.js';
|
|
80
|
+
import { randomUUID } from 'crypto';
|
|
80
81
|
import { PtyActivityTrackerService } from './services/agent/pty-activity-tracker.service.js';
|
|
81
82
|
import { InFlightTurnTracker } from './services/restart/in-flight-turn-tracker.service.js';
|
|
82
83
|
import { TicketIntakeService, setTicketIntakeService, resolveTicketIdForSession, } from './services/v3/ticket-intake.service.js';
|
|
@@ -2437,6 +2438,73 @@ export class CrewlyServer {
|
|
|
2437
2438
|
// this holder at request time, so it picks up broadcast +
|
|
2438
2439
|
// dispatch without a re-mount.
|
|
2439
2440
|
setChatV2RealtimeDeps({ gateway: chatGateway, dispatcher: chatDispatcher });
|
|
2441
|
+
// Drive mode briefing (specs/2026-10-08-drive-mode.md): the owner's
|
|
2442
|
+
// queue across agents for the phone's voice briefer. Answers reuse the
|
|
2443
|
+
// existing paths — the decision service, the agent's conversation (a
|
|
2444
|
+
// Talk-style owner turn tagged voice) and the ticket review.
|
|
2445
|
+
try {
|
|
2446
|
+
const [{ BriefingService, setBriefingService }, { BriefingStateStore }, { DecisionService }, { OpenItemsService }, { getTicketIntakeService }, { getTicketReviewService }, { buildAgentRoster }, { intakeChatV2OwnerMessage },] = await Promise.all([
|
|
2447
|
+
import('./services/briefing/briefing.service.js'),
|
|
2448
|
+
import('./services/briefing/briefing-state.store.js'),
|
|
2449
|
+
import('./services/decisions/decision.service.js'),
|
|
2450
|
+
import('./services/open-items/open-items.service.js'),
|
|
2451
|
+
import('./services/v3/ticket-intake.service.js'),
|
|
2452
|
+
import('./services/v3/ticket-review.service.js'),
|
|
2453
|
+
import('./services/cloud/agent-roster.utils.js'),
|
|
2454
|
+
import('./services/v3/ticket-channel-hooks.js'),
|
|
2455
|
+
]);
|
|
2456
|
+
const owner = { userId: SLACK_AGENT_DM_CONSTANTS.OWNER_USER_ID, source: 'oss' };
|
|
2457
|
+
setBriefingService(new BriefingService({
|
|
2458
|
+
decisions: () => DecisionService.getInstance(),
|
|
2459
|
+
listRequests: () => RequestService.getInstance().listAll(),
|
|
2460
|
+
listReviewTickets: async () => {
|
|
2461
|
+
const intake = getTicketIntakeService();
|
|
2462
|
+
if (!intake)
|
|
2463
|
+
return [];
|
|
2464
|
+
const candidates = (await RequestService.getInstance().listAll()).filter((r) => typeof r.ticketNumber === 'number' && r.requiresConfirmation && r.status !== 'done' && r.status !== 'cancelled');
|
|
2465
|
+
const rows = await Promise.all(candidates.map((r) => intake.toListItem(r)));
|
|
2466
|
+
return rows.filter((row) => row.column === 'to_review');
|
|
2467
|
+
},
|
|
2468
|
+
review: () => getTicketReviewService(),
|
|
2469
|
+
dismissOpenItem: async (requestId, itemId) => {
|
|
2470
|
+
const openItems = OpenItemsService.getInstance();
|
|
2471
|
+
if (!openItems)
|
|
2472
|
+
throw new Error('open items are not ready');
|
|
2473
|
+
return openItems.skipItem(requestId, itemId);
|
|
2474
|
+
},
|
|
2475
|
+
roster: async () => buildAgentRoster(await this.storageService.getTeams()),
|
|
2476
|
+
postOwnerMessage: async (target, text) => {
|
|
2477
|
+
const channelId = target.channelId ?? chatService.ensureDmChannel({ agentSession: target.agentSession, principal: owner }).channel.id;
|
|
2478
|
+
const { message } = chatService.recordTurn({
|
|
2479
|
+
channelId,
|
|
2480
|
+
senderType: 'user',
|
|
2481
|
+
senderId: owner.userId,
|
|
2482
|
+
content: text,
|
|
2483
|
+
...(target.threadId ? { threadId: target.threadId } : {}),
|
|
2484
|
+
clientMessageId: `voice-${randomUUID()}`,
|
|
2485
|
+
// Talk's source keeps the reply on the owner's Talk surface; `inputMode` says it was spoken.
|
|
2486
|
+
metadata: { source: 'cloud-talk', inputMode: 'voice', via: 'drive-mode' },
|
|
2487
|
+
});
|
|
2488
|
+
const channel = chatService.getChannel(channelId, owner);
|
|
2489
|
+
const toDispatch = await intakeChatV2OwnerMessage(getTicketIntakeService(), channel, message, CLOUD_TALK_CONSTANTS.INTAKE_ORIGIN);
|
|
2490
|
+
await chatDispatcher.dispatchMessage(channel, toDispatch);
|
|
2491
|
+
return { channelId, ...(message.threadId ? { threadId: message.threadId } : {}) };
|
|
2492
|
+
},
|
|
2493
|
+
findAgentReply: async (agentSession, channelId, threadId, sinceMs) => {
|
|
2494
|
+
const { items } = chatService.getAgentTimeline({ agentSession, principal: owner, limit: BRIEFING_CONSTANTS.LOOKUP_SCAN_LIMIT });
|
|
2495
|
+
const reply = items
|
|
2496
|
+
.filter((m) => m.channelId === channelId && m.senderType === 'agent' && m.createdAt > sinceMs && (!threadId || m.threadId === threadId || m.id === threadId))
|
|
2497
|
+
.sort((a, b) => a.createdAt - b.createdAt)[0];
|
|
2498
|
+
return reply ? { text: reply.content, at: new Date(reply.createdAt).toISOString() } : null;
|
|
2499
|
+
},
|
|
2500
|
+
store: new BriefingStateStore(),
|
|
2501
|
+
}));
|
|
2502
|
+
}
|
|
2503
|
+
catch (briefingErr) {
|
|
2504
|
+
this.logger.warn('Drive mode briefing wiring skipped', {
|
|
2505
|
+
error: briefingErr instanceof Error ? briefingErr.message : String(briefingErr),
|
|
2506
|
+
});
|
|
2507
|
+
}
|
|
2440
2508
|
this.logger.info('chat-v2 WebSocket gateway + dispatcher started', {
|
|
2441
2509
|
path: '/ws/chat',
|
|
2442
2510
|
authMode: jwtSecret ? 'jwt' : 'dev-anonymous',
|