@sentry/junior 0.156.0 → 0.158.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-hooks-CCAR46PQ.js → agent-hooks-BOWFTDE5.js} +10 -10
- package/dist/api/conversations/attachments.d.ts +32 -0
- package/dist/api/conversations/priority.d.ts +22 -0
- package/dist/api/conversations/routes.d.ts +4 -1
- package/dist/api/conversations/user-message-activity.d.ts +3 -0
- package/dist/api/locations/detail.d.ts +3 -1
- package/dist/api/schema/conversation.d.ts +14 -4
- package/dist/api/schema/location.d.ts +3 -1
- package/dist/api/schema/person.d.ts +3 -1
- package/dist/api/schema/task.d.ts +8 -8
- package/dist/api/schema.js +1 -1
- package/dist/api.js +350 -187
- package/dist/app.js +35 -54
- package/dist/{catalog-runtime-3SNKYCBG.js → catalog-runtime-7GZ25WTR.js} +5 -5
- package/dist/chat/agent-invocations/types.d.ts +12 -12
- package/dist/chat/attachments/storage.d.ts +2 -0
- package/dist/chat/attachments/store.d.ts +16 -0
- package/dist/chat/event-tasks/tool-support.d.ts +1 -1
- package/dist/chat/event-tasks/types.d.ts +1 -1
- package/dist/chat/plugins/unfinished-work.d.ts +6 -1
- package/dist/chat/scheduled-tasks/tool-support.d.ts +5 -5
- package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -2
- package/dist/chat/task-execution/slack-work.d.ts +2 -2
- package/dist/{chunk-4ZZDTHFC.js → chunk-3A7VXSPJ.js} +8 -8
- package/dist/{chunk-7RAETIYO.js → chunk-4JAOLUDB.js} +6 -6
- package/dist/{chunk-KCA5MKHU.js → chunk-4Q6QVTKA.js} +351 -5
- package/dist/{chunk-TN4LVILT.js → chunk-4XJ2WSTI.js} +5 -5
- package/dist/{chunk-OGZPRMZA.js → chunk-6GJCOUTA.js} +1 -1
- package/dist/{chunk-6CINHXIL.js → chunk-A7EDLNGU.js} +4 -4
- package/dist/{chunk-IIO5PFZX.js → chunk-AF4PHIP6.js} +3 -3
- package/dist/{chunk-IZEBHYI4.js → chunk-BNFGY66A.js} +1 -1
- package/dist/{chunk-3L2PMOSR.js → chunk-C3FYJZSA.js} +4 -4
- package/dist/{chunk-X5NZQH5U.js → chunk-CZCMFRUQ.js} +16 -0
- package/dist/{chunk-CK2H7CFO.js → chunk-DTVTBZNP.js} +1 -1
- package/dist/{chunk-WD7SEUZO.js → chunk-EQ6Y37MD.js} +1 -1
- package/dist/{chunk-53W3LZEW.js → chunk-EXITAVHO.js} +64 -361
- package/dist/{chunk-ZNWRYNCA.js → chunk-FA32YRZ3.js} +5 -5
- package/dist/{chunk-GKC43TLS.js → chunk-FAJ6SMEE.js} +2 -2
- package/dist/{chunk-GSBPZHLQ.js → chunk-IEM3GFXL.js} +9 -9
- package/dist/{chunk-KBGMYLSV.js → chunk-IXYGGJRA.js} +1 -1
- package/dist/{chunk-OMQJB7YN.js → chunk-JEXQQLEC.js} +18 -18
- package/dist/{chunk-PMFGVLDU.js → chunk-KAFYW3O6.js} +35 -10
- package/dist/{chunk-X7W45B5G.js → chunk-KSZXVR5G.js} +1 -1
- package/dist/{chunk-SRJA6QLM.js → chunk-LUSAAJJA.js} +2 -2
- package/dist/{chunk-3FFUC32L.js → chunk-NOEERHHR.js} +6 -6
- package/dist/{chunk-MC57E5U5.js → chunk-PHQDXC27.js} +1 -1
- package/dist/{chunk-A6WPDFHQ.js → chunk-RCIKTZZF.js} +1 -1
- package/dist/{chunk-NTNU6T2D.js → chunk-ROOTB7J7.js} +2 -2
- package/dist/{chunk-TNXGMFWV.js → chunk-SAJPQLTY.js} +1 -1
- package/dist/{chunk-SE3D225X.js → chunk-SSU65ZTZ.js} +1 -1
- package/dist/{chunk-6JUU7J2B.js → chunk-UJ6N32ZM.js} +4 -4
- package/dist/{chunk-MJE7XKWP.js → chunk-UPPU3FQU.js} +1 -1
- package/dist/{chunk-JUJR6WTL.js → chunk-UQJO35BP.js} +4 -4
- package/dist/{chunk-AIJRG227.js → chunk-VURJ2NSF.js} +1 -1
- package/dist/{chunk-CN2XSVKF.js → chunk-X4BLYIMV.js} +6 -6
- package/dist/{chunk-EDJ64P2P.js → chunk-YEZS4TEY.js} +1 -1
- package/dist/cli/chat.js +30 -30
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/agent-invocations.d.ts +4 -4
- package/dist/db/schema.d.ts +4 -4
- package/dist/{db-TYUUKGJX.js → db-HFWTPYT7.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-AWVDKPR5.js → oauth-callback-server-J3NW4QL5.js} +23 -23
- package/dist/{runner-JUQXMACC.js → runner-CL6QHML5.js} +14 -15
- package/dist/{skills-4GZTZX4V.js → skills-WZWKZIFQ.js} +6 -6
- package/dist/spawn-TQJWADG4.js +37 -0
- package/dist/{validation-DRLNJRND.js → validation-4HVSSLJV.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-TGIXRRJY.js → work-UF4KXPVG.js} +17 -17
- package/dist/worker-HI7I2W2U.js +24 -0
- package/package.json +5 -5
- package/dist/spawn-32SSRWU4.js +0 -37
- package/dist/worker-IFXZOYED.js +0 -24
|
@@ -3,38 +3,38 @@ import {
|
|
|
3
3
|
} from "./chunk-RF6J3DIO.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveBaseUrl
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4JAOLUDB.js";
|
|
7
7
|
import {
|
|
8
8
|
isExperimentalFeatureEnabled
|
|
9
9
|
} from "./chunk-5IDFPCON.js";
|
|
10
10
|
import {
|
|
11
11
|
createPluginLogger,
|
|
12
12
|
getPlugins
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NOEERHHR.js";
|
|
14
14
|
import {
|
|
15
15
|
getSlackClient,
|
|
16
16
|
withSlackRetries
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ROOTB7J7.js";
|
|
18
18
|
import {
|
|
19
19
|
getDb,
|
|
20
20
|
parseDestination
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-AF4PHIP6.js";
|
|
22
22
|
import {
|
|
23
23
|
sleep
|
|
24
24
|
} from "./chunk-EM225ITJ.js";
|
|
25
25
|
import {
|
|
26
26
|
acquireActiveLock,
|
|
27
27
|
getStateAdapter
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-PHQDXC27.js";
|
|
29
29
|
import {
|
|
30
30
|
pluginCatalogRuntime
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-YEZS4TEY.js";
|
|
32
32
|
import {
|
|
33
33
|
fetchWithBoundedOAuthErrorBodies
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-EQ6Y37MD.js";
|
|
35
35
|
import {
|
|
36
36
|
isRecord
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-KSZXVR5G.js";
|
|
38
38
|
|
|
39
39
|
// src/chat/capabilities/router.ts
|
|
40
40
|
var ProviderCredentialRouter = class {
|
|
@@ -4,19 +4,19 @@ import {
|
|
|
4
4
|
isDmChannel,
|
|
5
5
|
normalizeSlackConversationId,
|
|
6
6
|
withSlackRetries
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ROOTB7J7.js";
|
|
8
8
|
import {
|
|
9
9
|
parseDestination
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-AF4PHIP6.js";
|
|
11
11
|
import {
|
|
12
12
|
getStateAdapter
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PHQDXC27.js";
|
|
14
14
|
import {
|
|
15
15
|
normalizeSlackEmojiName
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-FAJ6SMEE.js";
|
|
17
17
|
import {
|
|
18
18
|
pluginCatalogRuntime
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-YEZS4TEY.js";
|
|
20
20
|
import {
|
|
21
21
|
parseSlackMessageTs,
|
|
22
22
|
parseSlackUserId
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
isRecord,
|
|
26
26
|
logInfo,
|
|
27
27
|
logWarn
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-KSZXVR5G.js";
|
|
29
29
|
|
|
30
30
|
// src/chat/slack/outbound.ts
|
|
31
31
|
var MAX_SLACK_MESSAGE_TEXT_CHARS = 4e4;
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ToolInputError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C3FYJZSA.js";
|
|
4
4
|
import {
|
|
5
5
|
canRouteResourceEvents,
|
|
6
6
|
getPlugins
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-NOEERHHR.js";
|
|
8
8
|
import {
|
|
9
9
|
getDb
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-AF4PHIP6.js";
|
|
11
11
|
import {
|
|
12
|
+
juniorAttachments,
|
|
13
|
+
juniorConversations,
|
|
12
14
|
juniorEventTasks,
|
|
13
15
|
juniorSchedulerRuns,
|
|
14
16
|
juniorSchedulerTasks,
|
|
15
17
|
juniorStats
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-VURJ2NSF.js";
|
|
17
19
|
import {
|
|
18
20
|
juniorDestinations
|
|
19
21
|
} from "./chunk-VFUK3X5B.js";
|
|
20
22
|
import {
|
|
21
23
|
logInfo
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-KSZXVR5G.js";
|
|
23
25
|
|
|
24
26
|
// src/chat/event-tasks/store.ts
|
|
25
27
|
import { and, asc, desc, eq, inArray, or, sql } from "drizzle-orm";
|
|
@@ -1553,6 +1555,346 @@ function createSchedulerSqlStore(db) {
|
|
|
1553
1555
|
return new SqlSchedulerStore(db);
|
|
1554
1556
|
}
|
|
1555
1557
|
|
|
1558
|
+
// src/chat/attachments/store.ts
|
|
1559
|
+
import { createHash, randomUUID } from "crypto";
|
|
1560
|
+
import { and as and4, asc as asc4, eq as eq3, inArray as inArray3, isNotNull as isNotNull2, isNull, or as or3 } from "drizzle-orm";
|
|
1561
|
+
var ATTACHMENT_GC_BATCH_LIMIT = 200;
|
|
1562
|
+
function attachmentDigest(file) {
|
|
1563
|
+
return createHash("sha256").update(file.data).digest("hex");
|
|
1564
|
+
}
|
|
1565
|
+
function attachmentId(args) {
|
|
1566
|
+
return createHash("sha256").update(
|
|
1567
|
+
[
|
|
1568
|
+
args.conversationId,
|
|
1569
|
+
args.provider,
|
|
1570
|
+
args.sha256,
|
|
1571
|
+
args.filename,
|
|
1572
|
+
args.contentType
|
|
1573
|
+
].join("\0")
|
|
1574
|
+
).digest("hex");
|
|
1575
|
+
}
|
|
1576
|
+
function attachmentKey(args) {
|
|
1577
|
+
return `conversations/${args.conversationId}/attachments/${args.attachmentId}/${args.writeId}/${args.filename}`;
|
|
1578
|
+
}
|
|
1579
|
+
async function bestEffortDelete(storage, key) {
|
|
1580
|
+
try {
|
|
1581
|
+
await storage.delete([key]);
|
|
1582
|
+
} catch {
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
async function isConversationPurged(db, conversationId) {
|
|
1586
|
+
const [row] = await db.db().select({
|
|
1587
|
+
transcriptPurgedAt: juniorConversations.transcriptPurgedAt
|
|
1588
|
+
}).from(juniorConversations).where(eq3(juniorConversations.conversationId, conversationId));
|
|
1589
|
+
return row?.transcriptPurgedAt != null;
|
|
1590
|
+
}
|
|
1591
|
+
function purgedConversationError(conversationId) {
|
|
1592
|
+
return new Error(
|
|
1593
|
+
`Cannot store attachment for purged conversation ${conversationId}`
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
async function assertConversationNotPurged(db, conversationId) {
|
|
1597
|
+
if (await isConversationPurged(db, conversationId)) {
|
|
1598
|
+
throw purgedConversationError(conversationId);
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
async function rejectPurgedAttachmentWrite(args) {
|
|
1602
|
+
await args.db.db().update(juniorAttachments).set({ deleteRequestedAt: args.now }).where(eq3(juniorAttachments.id, args.id));
|
|
1603
|
+
await bestEffortDelete(args.storage, args.storageKey);
|
|
1604
|
+
throw purgedConversationError(args.conversationId);
|
|
1605
|
+
}
|
|
1606
|
+
async function reuseLiveAttachment(args) {
|
|
1607
|
+
await bestEffortDelete(args.storage, args.storageKey);
|
|
1608
|
+
await assertConversationNotPurged(args.db, args.conversationId);
|
|
1609
|
+
return { id: args.id };
|
|
1610
|
+
}
|
|
1611
|
+
async function storeAttachment(args) {
|
|
1612
|
+
const now = new Date(args.nowMs ?? Date.now());
|
|
1613
|
+
const sha256 = attachmentDigest(args.file);
|
|
1614
|
+
const id = attachmentId({
|
|
1615
|
+
conversationId: args.conversationId,
|
|
1616
|
+
contentType: args.file.mimeType,
|
|
1617
|
+
filename: args.file.filename,
|
|
1618
|
+
provider: args.storage.provider,
|
|
1619
|
+
sha256
|
|
1620
|
+
});
|
|
1621
|
+
const [existing] = await args.db.db().select({
|
|
1622
|
+
contentType: juniorAttachments.contentType,
|
|
1623
|
+
conversationId: juniorAttachments.conversationId,
|
|
1624
|
+
deleteRequestedAt: juniorAttachments.deleteRequestedAt,
|
|
1625
|
+
filename: juniorAttachments.filename,
|
|
1626
|
+
id: juniorAttachments.id,
|
|
1627
|
+
provider: juniorAttachments.provider,
|
|
1628
|
+
sha256: juniorAttachments.sha256,
|
|
1629
|
+
storageKey: juniorAttachments.storageKey
|
|
1630
|
+
}).from(juniorAttachments).where(eq3(juniorAttachments.id, id));
|
|
1631
|
+
if (existing) {
|
|
1632
|
+
if (existing.contentType !== args.file.mimeType || existing.conversationId !== args.conversationId || existing.filename !== args.file.filename || existing.provider !== args.storage.provider || existing.sha256 !== sha256) {
|
|
1633
|
+
throw new Error(`Attachment write conflicts with ${existing.id}`);
|
|
1634
|
+
}
|
|
1635
|
+
if (existing.deleteRequestedAt === null) {
|
|
1636
|
+
await assertConversationNotPurged(args.db, args.conversationId);
|
|
1637
|
+
return { id: existing.id };
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
await assertConversationNotPurged(args.db, args.conversationId);
|
|
1641
|
+
const storageKey = attachmentKey({
|
|
1642
|
+
attachmentId: id,
|
|
1643
|
+
conversationId: args.conversationId,
|
|
1644
|
+
filename: args.file.filename,
|
|
1645
|
+
writeId: randomUUID()
|
|
1646
|
+
});
|
|
1647
|
+
await args.storage.put({
|
|
1648
|
+
body: args.file.data,
|
|
1649
|
+
contentType: args.file.mimeType,
|
|
1650
|
+
key: storageKey
|
|
1651
|
+
});
|
|
1652
|
+
if (existing?.deleteRequestedAt != null) {
|
|
1653
|
+
if (await isConversationPurged(args.db, args.conversationId)) {
|
|
1654
|
+
await bestEffortDelete(args.storage, storageKey);
|
|
1655
|
+
throw purgedConversationError(args.conversationId);
|
|
1656
|
+
}
|
|
1657
|
+
const oldStorageKey = existing.storageKey;
|
|
1658
|
+
const revived2 = await args.db.db().update(juniorAttachments).set({
|
|
1659
|
+
deleteRequestedAt: null,
|
|
1660
|
+
storageKey
|
|
1661
|
+
}).where(
|
|
1662
|
+
and4(
|
|
1663
|
+
eq3(juniorAttachments.id, id),
|
|
1664
|
+
isNotNull2(juniorAttachments.deleteRequestedAt)
|
|
1665
|
+
)
|
|
1666
|
+
).returning({ id: juniorAttachments.id });
|
|
1667
|
+
if (revived2.length > 0) {
|
|
1668
|
+
if (await isConversationPurged(args.db, args.conversationId)) {
|
|
1669
|
+
await rejectPurgedAttachmentWrite({
|
|
1670
|
+
conversationId: args.conversationId,
|
|
1671
|
+
db: args.db,
|
|
1672
|
+
id,
|
|
1673
|
+
now,
|
|
1674
|
+
storage: args.storage,
|
|
1675
|
+
storageKey
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
if (oldStorageKey !== storageKey) {
|
|
1679
|
+
await bestEffortDelete(args.storage, oldStorageKey);
|
|
1680
|
+
}
|
|
1681
|
+
return { id };
|
|
1682
|
+
}
|
|
1683
|
+
const [afterRace2] = await args.db.db().select({
|
|
1684
|
+
deleteRequestedAt: juniorAttachments.deleteRequestedAt,
|
|
1685
|
+
id: juniorAttachments.id,
|
|
1686
|
+
storageKey: juniorAttachments.storageKey
|
|
1687
|
+
}).from(juniorAttachments).where(eq3(juniorAttachments.id, id));
|
|
1688
|
+
if (afterRace2?.deleteRequestedAt === null) {
|
|
1689
|
+
return reuseLiveAttachment({
|
|
1690
|
+
conversationId: args.conversationId,
|
|
1691
|
+
db: args.db,
|
|
1692
|
+
id: afterRace2.id,
|
|
1693
|
+
storage: args.storage,
|
|
1694
|
+
storageKey
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
let inserted = [];
|
|
1699
|
+
try {
|
|
1700
|
+
inserted = await args.db.db().insert(juniorAttachments).values({
|
|
1701
|
+
id,
|
|
1702
|
+
conversationId: args.conversationId,
|
|
1703
|
+
provider: args.storage.provider,
|
|
1704
|
+
storageKey,
|
|
1705
|
+
filename: args.file.filename,
|
|
1706
|
+
contentType: args.file.mimeType,
|
|
1707
|
+
bytes: args.file.bytes,
|
|
1708
|
+
sha256,
|
|
1709
|
+
createdAt: now
|
|
1710
|
+
}).onConflictDoNothing({ target: juniorAttachments.id }).returning({ id: juniorAttachments.id });
|
|
1711
|
+
} catch (error) {
|
|
1712
|
+
await bestEffortDelete(args.storage, storageKey);
|
|
1713
|
+
throw error;
|
|
1714
|
+
}
|
|
1715
|
+
if (inserted.length > 0) {
|
|
1716
|
+
if (await isConversationPurged(args.db, args.conversationId)) {
|
|
1717
|
+
await rejectPurgedAttachmentWrite({
|
|
1718
|
+
conversationId: args.conversationId,
|
|
1719
|
+
db: args.db,
|
|
1720
|
+
id,
|
|
1721
|
+
now,
|
|
1722
|
+
storage: args.storage,
|
|
1723
|
+
storageKey
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
return { id };
|
|
1727
|
+
}
|
|
1728
|
+
const [row] = await args.db.db().select({
|
|
1729
|
+
deleteRequestedAt: juniorAttachments.deleteRequestedAt,
|
|
1730
|
+
id: juniorAttachments.id,
|
|
1731
|
+
storageKey: juniorAttachments.storageKey
|
|
1732
|
+
}).from(juniorAttachments).where(eq3(juniorAttachments.id, id));
|
|
1733
|
+
if (!row) {
|
|
1734
|
+
await bestEffortDelete(args.storage, storageKey);
|
|
1735
|
+
throw new Error(`Attachment row missing after write for ${id}`);
|
|
1736
|
+
}
|
|
1737
|
+
if (row.deleteRequestedAt === null) {
|
|
1738
|
+
return reuseLiveAttachment({
|
|
1739
|
+
conversationId: args.conversationId,
|
|
1740
|
+
db: args.db,
|
|
1741
|
+
id: row.id,
|
|
1742
|
+
storage: args.storage,
|
|
1743
|
+
storageKey
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
if (await isConversationPurged(args.db, args.conversationId)) {
|
|
1747
|
+
await bestEffortDelete(args.storage, storageKey);
|
|
1748
|
+
throw purgedConversationError(args.conversationId);
|
|
1749
|
+
}
|
|
1750
|
+
const revived = await args.db.db().update(juniorAttachments).set({
|
|
1751
|
+
deleteRequestedAt: null,
|
|
1752
|
+
storageKey
|
|
1753
|
+
}).where(
|
|
1754
|
+
and4(
|
|
1755
|
+
eq3(juniorAttachments.id, id),
|
|
1756
|
+
isNotNull2(juniorAttachments.deleteRequestedAt)
|
|
1757
|
+
)
|
|
1758
|
+
).returning({ id: juniorAttachments.id });
|
|
1759
|
+
if (revived.length > 0) {
|
|
1760
|
+
if (await isConversationPurged(args.db, args.conversationId)) {
|
|
1761
|
+
await rejectPurgedAttachmentWrite({
|
|
1762
|
+
conversationId: args.conversationId,
|
|
1763
|
+
db: args.db,
|
|
1764
|
+
id,
|
|
1765
|
+
now,
|
|
1766
|
+
storage: args.storage,
|
|
1767
|
+
storageKey
|
|
1768
|
+
});
|
|
1769
|
+
}
|
|
1770
|
+
if (row.storageKey !== storageKey) {
|
|
1771
|
+
await bestEffortDelete(args.storage, row.storageKey);
|
|
1772
|
+
}
|
|
1773
|
+
return { id };
|
|
1774
|
+
}
|
|
1775
|
+
const [afterRace] = await args.db.db().select({
|
|
1776
|
+
deleteRequestedAt: juniorAttachments.deleteRequestedAt,
|
|
1777
|
+
id: juniorAttachments.id
|
|
1778
|
+
}).from(juniorAttachments).where(eq3(juniorAttachments.id, id));
|
|
1779
|
+
if (afterRace?.deleteRequestedAt === null) {
|
|
1780
|
+
return reuseLiveAttachment({
|
|
1781
|
+
conversationId: args.conversationId,
|
|
1782
|
+
db: args.db,
|
|
1783
|
+
id: afterRace.id,
|
|
1784
|
+
storage: args.storage,
|
|
1785
|
+
storageKey
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
await bestEffortDelete(args.storage, storageKey);
|
|
1789
|
+
throw new Error(`Attachment ${id} disappeared while reviving`);
|
|
1790
|
+
}
|
|
1791
|
+
async function readLiveAttachment(args) {
|
|
1792
|
+
const [row] = await args.db.db().select({
|
|
1793
|
+
bytes: juniorAttachments.bytes,
|
|
1794
|
+
contentType: juniorAttachments.contentType,
|
|
1795
|
+
conversationId: juniorAttachments.conversationId,
|
|
1796
|
+
deleteRequestedAt: juniorAttachments.deleteRequestedAt,
|
|
1797
|
+
filename: juniorAttachments.filename,
|
|
1798
|
+
id: juniorAttachments.id,
|
|
1799
|
+
provider: juniorAttachments.provider,
|
|
1800
|
+
storageKey: juniorAttachments.storageKey
|
|
1801
|
+
}).from(juniorAttachments).where(
|
|
1802
|
+
and4(
|
|
1803
|
+
eq3(juniorAttachments.id, args.attachmentId),
|
|
1804
|
+
eq3(juniorAttachments.conversationId, args.conversationId),
|
|
1805
|
+
isNull(juniorAttachments.deleteRequestedAt)
|
|
1806
|
+
)
|
|
1807
|
+
);
|
|
1808
|
+
if (!row) return null;
|
|
1809
|
+
if (await isConversationPurged(args.db, args.conversationId)) {
|
|
1810
|
+
return null;
|
|
1811
|
+
}
|
|
1812
|
+
return {
|
|
1813
|
+
bytes: row.bytes,
|
|
1814
|
+
contentType: row.contentType,
|
|
1815
|
+
conversationId: row.conversationId,
|
|
1816
|
+
filename: row.filename,
|
|
1817
|
+
id: row.id,
|
|
1818
|
+
provider: row.provider,
|
|
1819
|
+
storageKey: row.storageKey
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
async function storeAttachments(args) {
|
|
1823
|
+
const stored = [];
|
|
1824
|
+
for (const file of args.files) {
|
|
1825
|
+
stored.push(
|
|
1826
|
+
await storeAttachment({
|
|
1827
|
+
conversationId: args.conversationId,
|
|
1828
|
+
db: args.db,
|
|
1829
|
+
file,
|
|
1830
|
+
...args.nowMs !== void 0 ? { nowMs: args.nowMs } : {},
|
|
1831
|
+
storage: args.storage
|
|
1832
|
+
})
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
return stored;
|
|
1836
|
+
}
|
|
1837
|
+
async function requestAttachmentDeletion(db, conversationIds, nowMs) {
|
|
1838
|
+
if (conversationIds.length === 0) return;
|
|
1839
|
+
await db.db().update(juniorAttachments).set({ deleteRequestedAt: new Date(nowMs) }).where(
|
|
1840
|
+
and4(
|
|
1841
|
+
inArray3(juniorAttachments.conversationId, conversationIds),
|
|
1842
|
+
isNull(juniorAttachments.deleteRequestedAt)
|
|
1843
|
+
)
|
|
1844
|
+
);
|
|
1845
|
+
}
|
|
1846
|
+
async function collectAttachmentGarbage(args) {
|
|
1847
|
+
void args.nowMs;
|
|
1848
|
+
const rows = await args.db.db().select({
|
|
1849
|
+
id: juniorAttachments.id,
|
|
1850
|
+
storageKey: juniorAttachments.storageKey
|
|
1851
|
+
}).from(juniorAttachments).innerJoin(
|
|
1852
|
+
juniorConversations,
|
|
1853
|
+
eq3(
|
|
1854
|
+
juniorAttachments.conversationId,
|
|
1855
|
+
juniorConversations.conversationId
|
|
1856
|
+
)
|
|
1857
|
+
).where(
|
|
1858
|
+
and4(
|
|
1859
|
+
eq3(juniorAttachments.provider, args.storage.provider),
|
|
1860
|
+
or3(
|
|
1861
|
+
isNotNull2(juniorAttachments.deleteRequestedAt),
|
|
1862
|
+
isNotNull2(juniorConversations.transcriptPurgedAt)
|
|
1863
|
+
)
|
|
1864
|
+
)
|
|
1865
|
+
).orderBy(asc4(juniorAttachments.createdAt), asc4(juniorAttachments.id)).limit(args.limit ?? ATTACHMENT_GC_BATCH_LIMIT);
|
|
1866
|
+
if (rows.length === 0) return { deleted: 0 };
|
|
1867
|
+
await args.storage.delete(rows.map((row) => row.storageKey));
|
|
1868
|
+
const stillEligible = await args.db.db().select({ id: juniorAttachments.id }).from(juniorAttachments).innerJoin(
|
|
1869
|
+
juniorConversations,
|
|
1870
|
+
eq3(
|
|
1871
|
+
juniorAttachments.conversationId,
|
|
1872
|
+
juniorConversations.conversationId
|
|
1873
|
+
)
|
|
1874
|
+
).where(
|
|
1875
|
+
and4(
|
|
1876
|
+
inArray3(
|
|
1877
|
+
juniorAttachments.id,
|
|
1878
|
+
rows.map((row) => row.id)
|
|
1879
|
+
),
|
|
1880
|
+
or3(
|
|
1881
|
+
isNotNull2(juniorAttachments.deleteRequestedAt),
|
|
1882
|
+
isNotNull2(juniorConversations.transcriptPurgedAt)
|
|
1883
|
+
)
|
|
1884
|
+
)
|
|
1885
|
+
);
|
|
1886
|
+
if (stillEligible.length === 0) return { deleted: 0 };
|
|
1887
|
+
const removed = await args.db.db().delete(juniorAttachments).where(
|
|
1888
|
+
inArray3(
|
|
1889
|
+
juniorAttachments.id,
|
|
1890
|
+
stillEligible.map((row) => row.id)
|
|
1891
|
+
)
|
|
1892
|
+
).returning({
|
|
1893
|
+
id: juniorAttachments.id
|
|
1894
|
+
});
|
|
1895
|
+
return { deleted: removed.length };
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1556
1898
|
export {
|
|
1557
1899
|
juniorToolOutputSchema,
|
|
1558
1900
|
injectContinuationToolName,
|
|
@@ -1591,6 +1933,10 @@ export {
|
|
|
1591
1933
|
SCHEDULED_TASK_SYSTEM_ACTOR,
|
|
1592
1934
|
listPublicScheduledTasksForTeams,
|
|
1593
1935
|
createSchedulerSqlStore,
|
|
1936
|
+
readLiveAttachment,
|
|
1937
|
+
storeAttachments,
|
|
1938
|
+
requestAttachmentDeletion,
|
|
1939
|
+
collectAttachmentGarbage,
|
|
1594
1940
|
incrementStat,
|
|
1595
1941
|
readStats
|
|
1596
1942
|
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
persistConversationMessages
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C3FYJZSA.js";
|
|
4
4
|
import {
|
|
5
5
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
6
6
|
} from "./chunk-3Y47VMHV.js";
|
|
7
7
|
import {
|
|
8
8
|
getDb
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-AF4PHIP6.js";
|
|
10
10
|
import {
|
|
11
11
|
juniorLocationConfigurations
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-VURJ2NSF.js";
|
|
13
13
|
import {
|
|
14
14
|
getStateAdapter
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-PHQDXC27.js";
|
|
16
16
|
import {
|
|
17
17
|
juniorDestinations
|
|
18
18
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
isRecord,
|
|
21
21
|
toOptionalNumber,
|
|
22
22
|
toOptionalString
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-KSZXVR5G.js";
|
|
24
24
|
|
|
25
25
|
// src/chat/conversations/turn-lifecycle.ts
|
|
26
26
|
var ConversationTurnLifecycleService = class {
|
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
getConversationStore,
|
|
9
9
|
parseDestination,
|
|
10
10
|
sameDestination
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-AF4PHIP6.js";
|
|
12
12
|
import {
|
|
13
13
|
getDefaultRedisStateAdapterFor,
|
|
14
14
|
getStateAdapter
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-PHQDXC27.js";
|
|
16
16
|
import {
|
|
17
17
|
getChatConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-FAJ6SMEE.js";
|
|
19
19
|
import {
|
|
20
20
|
parseStoredSlackActor
|
|
21
21
|
} from "./chunk-V7YE4WCP.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
isRecord,
|
|
24
24
|
toOptionalNumber,
|
|
25
25
|
toOptionalString
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-KSZXVR5G.js";
|
|
27
27
|
|
|
28
28
|
// src/chat/task-execution/state.ts
|
|
29
29
|
import { randomUUID } from "crypto";
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
juniorConversations,
|
|
7
7
|
juniorIdentities,
|
|
8
8
|
juniorUsers
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VURJ2NSF.js";
|
|
10
10
|
import {
|
|
11
11
|
TURN_REASONING_LEVELS,
|
|
12
12
|
getChatConfig,
|
|
13
13
|
modelProfileSchema
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FAJ6SMEE.js";
|
|
15
15
|
import {
|
|
16
16
|
juniorDestinations
|
|
17
17
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "./chunk-V7YE4WCP.js";
|
|
23
23
|
import {
|
|
24
24
|
normalizeIdentityEmail
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-KSZXVR5G.js";
|
|
26
26
|
|
|
27
27
|
// src/chat/conversations/sql/store.ts
|
|
28
28
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
instructionProvenanceFor,
|
|
14
14
|
sanitizePostgresJson,
|
|
15
15
|
withConversationEventLock
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AF4PHIP6.js";
|
|
17
17
|
import {
|
|
18
18
|
SANDBOX_WORKSPACE_ROOT,
|
|
19
19
|
sleep
|
|
@@ -23,14 +23,14 @@ import {
|
|
|
23
23
|
fenceLock,
|
|
24
24
|
getStateAdapter,
|
|
25
25
|
withLock
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-PHQDXC27.js";
|
|
27
27
|
import {
|
|
28
28
|
botConfig,
|
|
29
29
|
completeText,
|
|
30
30
|
escapeXml,
|
|
31
31
|
resolveGatewayModel,
|
|
32
32
|
unwrapCurrentInstruction
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-FAJ6SMEE.js";
|
|
34
34
|
import {
|
|
35
35
|
parseSlackMessageTs,
|
|
36
36
|
toStoredSlackActor
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
logException,
|
|
41
41
|
logWarn,
|
|
42
42
|
setSpanAttributes
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-KSZXVR5G.js";
|
|
44
44
|
|
|
45
45
|
// src/chat/turn-context-tag.ts
|
|
46
46
|
var TURN_CONTEXT_TAG = "runtime-turn-context";
|
|
@@ -56,6 +56,10 @@ var conversationSurfaceSchema = z2.enum([
|
|
|
56
56
|
]);
|
|
57
57
|
var conversationUsageSchema = usageSchema;
|
|
58
58
|
var conversationParamsSchema = z2.object({ conversationId: z2.string().min(1) }).strict();
|
|
59
|
+
var conversationAttachmentParamsSchema = z2.object({
|
|
60
|
+
attachmentId: z2.string().min(1),
|
|
61
|
+
conversationId: z2.string().min(1)
|
|
62
|
+
}).strict();
|
|
59
63
|
var conversationDetailQuerySchema = z2.object({
|
|
60
64
|
limit: z2.coerce.number().int().min(1).max(1e3).default(500)
|
|
61
65
|
}).strict();
|
|
@@ -176,6 +180,17 @@ var conversationSummaryReportSchema = z2.object({
|
|
|
176
180
|
sourceUrl: z2.string().url().optional(),
|
|
177
181
|
traceId: z2.string().optional(),
|
|
178
182
|
assignedWork: z2.boolean().optional(),
|
|
183
|
+
finishedWorkAt: z2.string().datetime().optional(),
|
|
184
|
+
/**
|
|
185
|
+
* Dashboard Priority membership for this conversation summary.
|
|
186
|
+
* Present on the conversation feed. Clients must not recompute it.
|
|
187
|
+
*
|
|
188
|
+
* True only when:
|
|
189
|
+
* - unfinished work was last seen within 48 hours
|
|
190
|
+
* - finished assigned work has conversation activity after the finish time
|
|
191
|
+
* - there is no known work and the conversation was last seen within 3 hours
|
|
192
|
+
*/
|
|
193
|
+
isPriority: z2.boolean().optional(),
|
|
179
194
|
unfinishedWork: z2.boolean().optional()
|
|
180
195
|
}).strict();
|
|
181
196
|
var conversationReportMessageEventDataSchema = z2.object({
|
|
@@ -782,6 +797,7 @@ var statsReportSchema = z8.object({
|
|
|
782
797
|
export {
|
|
783
798
|
apiErrorSchema,
|
|
784
799
|
conversationParamsSchema,
|
|
800
|
+
conversationAttachmentParamsSchema,
|
|
785
801
|
conversationDetailQuerySchema,
|
|
786
802
|
conversationEventsQuerySchema,
|
|
787
803
|
conversationFeedQuerySchema,
|