@sentry/junior 0.177.0 → 0.178.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-IYHCN7CO.js → agent-hooks-PBT4NNBV.js} +12 -12
- package/dist/api/conversations/archive.d.ts +5 -2
- package/dist/api/conversations/list.d.ts +0 -1
- package/dist/api/conversations/membership.d.ts +14 -0
- package/dist/api/conversations/projection.d.ts +2 -1
- package/dist/api/locations/detail.d.ts +1 -1
- package/dist/api/people/shared.d.ts +2 -2
- package/dist/api/schema/conversation.d.ts +4 -4
- package/dist/api/schema/location.d.ts +1 -1
- package/dist/api/schema/person.d.ts +1 -1
- package/dist/api/schema.js +1 -1
- package/dist/api.js +245 -166
- package/dist/app.js +35 -35
- package/dist/{catalog-runtime-2TD4CXSB.js → catalog-runtime-M7QGKPFZ.js} +5 -5
- package/dist/chat/agent/sandbox.d.ts +2 -0
- package/dist/chat/conversations/sql/participants.d.ts +1 -0
- package/dist/chat/conversations/store.d.ts +0 -1
- package/dist/chat/sandbox/errors.d.ts +4 -0
- package/dist/chat/sandbox/noninteractive-command.d.ts +1 -0
- package/dist/chat/sandbox/prepare-workspace.d.ts +27 -3
- package/dist/chat/sandbox/sandbox.d.ts +2 -0
- package/dist/chat/sandbox/session.d.ts +2 -0
- package/dist/chat/sandbox/snapshot/builder-sandbox.d.ts +5 -0
- package/dist/chat/sandbox/snapshot/install.d.ts +2 -2
- package/dist/chat/sandbox/snapshot/span.d.ts +3 -0
- package/dist/chat/sandbox/snapshot/store.d.ts +20 -17
- package/dist/chat/sandbox/snapshot/waiting-error.d.ts +15 -0
- package/dist/chat/sandbox/snapshot/workspace.d.ts +17 -0
- package/dist/chat/services/workspace-snapshot-wait.d.ts +27 -0
- package/dist/chat/workspaces/types.d.ts +1 -0
- package/dist/{chunk-3FWXQZJJ.js → chunk-22T3HB44.js} +1 -1
- package/dist/{chunk-DLTP6TUJ.js → chunk-3ZZEPLLB.js} +2 -2
- package/dist/{chunk-7ZFESKJ2.js → chunk-4K6VNP3S.js} +9 -9
- package/dist/{chunk-N4YEVOEC.js → chunk-534BO42N.js} +45 -276
- package/dist/{chunk-6NZRKJWU.js → chunk-6OYVH66J.js} +1 -1
- package/dist/{chunk-J2EWL6GJ.js → chunk-ABLODWPO.js} +1 -1
- package/dist/{chunk-ORMJY4RG.js → chunk-AGJ4OQ2V.js} +1 -1
- package/dist/{chunk-Q362TECJ.js → chunk-AQHSXA3J.js} +331 -2
- package/dist/{chunk-4SVAFAI2.js → chunk-AVRWMQ4U.js} +1 -1
- package/dist/{chunk-I7PKGMKI.js → chunk-BFLMRTPD.js} +6 -6
- package/dist/{chunk-ZCYABD7N.js → chunk-BHHWCNXI.js} +5 -5
- package/dist/{chunk-LFZODSAY.js → chunk-BUGO42R6.js} +4 -4
- package/dist/{chunk-7B6NW4P7.js → chunk-D3UJTX4U.js} +1 -1
- package/dist/{chunk-2IMQLZHS.js → chunk-FQ6BMP5P.js} +767 -81
- package/dist/{chunk-4TWDRU64.js → chunk-G3CQEUHI.js} +5 -5
- package/dist/{chunk-VGDOEKO2.js → chunk-H6ZXBFGX.js} +1 -1
- package/dist/{chunk-SNPQGTHJ.js → chunk-IQRPDKPJ.js} +1 -1
- package/dist/{chunk-CAWBLVBY.js → chunk-JVXZ3WDH.js} +6 -6
- package/dist/{chunk-7PZDAXIK.js → chunk-KEQAA42D.js} +1 -1
- package/dist/{chunk-UB5YB2ED.js → chunk-LAOP4EPL.js} +6 -6
- package/dist/{chunk-WYO2HXY5.js → chunk-OGRD5PFM.js} +1 -1
- package/dist/{chunk-AFOFVEXP.js → chunk-PRDKO3QB.js} +124 -13
- package/dist/{chunk-QLLOX7JY.js → chunk-QCCLDJHB.js} +8 -8
- package/dist/{chunk-FVVYHML7.js → chunk-RE4XWXBV.js} +6 -6
- package/dist/{chunk-4TRHPYTL.js → chunk-RGV6KHDM.js} +4 -4
- package/dist/{chunk-DGGIKWYQ.js → chunk-RGXOLPWO.js} +1 -1
- package/dist/{chunk-ELEAIRTG.js → chunk-TKB25A3L.js} +2 -2
- package/dist/{chunk-6KGMMVHF.js → chunk-U3UDPGZG.js} +2 -2
- package/dist/{chunk-7CVYXUOJ.js → chunk-UGWBJAGN.js} +1 -1
- package/dist/{chunk-LVL5NG5G.js → chunk-UMG7M32G.js} +19 -19
- package/dist/{chunk-LPMLAJYR.js → chunk-XCNS3CXE.js} +11 -17
- package/dist/{chunk-PA7QDS7P.js → chunk-XWUJWHFD.js} +204 -100
- package/dist/{chunk-WCQUKX74.js → chunk-ZCHHVTMF.js} +14 -5
- package/dist/cli/chat.js +31 -30
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/conversation-participants.d.ts +17 -0
- package/dist/db/schema/conversations.d.ts +629 -1
- package/dist/db/schema/snapshots.d.ts +1 -1
- package/dist/db/schema.d.ts +18 -1
- package/dist/{db-A3CB76US.js → db-QVYOWATH.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-64QMI3IB.js → oauth-callback-server-PLPAFXO6.js} +23 -23
- package/dist/{runner-EIAE2BGD.js → runner-AGNEIOZS.js} +15 -15
- package/dist/{skills-ZADWFKDG.js → skills-U5KQ66EM.js} +6 -6
- package/dist/spawn-ZRYYZP2B.js +37 -0
- package/dist/{validation-4I6AF4CV.js → validation-QE4U45KS.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-BS6BZ66U.js → work-ATAXAHJJ.js} +18 -18
- package/dist/worker-LIL5AOER.js +24 -0
- package/migrations/0033_workspace_snapshot_active_build.sql +1 -0
- package/migrations/0034_strong_randall.sql +31 -0
- package/migrations/meta/0033_snapshot.json +2914 -0
- package/migrations/meta/0034_snapshot.json +3038 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +5 -5
- package/dist/spawn-DVUOUFFC.js +0 -37
- package/dist/worker-RS5PWTCE.js +0 -24
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
conversationReadColumns,
|
|
2
3
|
createJuniorSqlExecutor,
|
|
3
4
|
juniorConversationAnnotations,
|
|
4
5
|
juniorConversationBindings,
|
|
@@ -7,12 +8,12 @@ import {
|
|
|
7
8
|
juniorConversations,
|
|
8
9
|
juniorIdentities,
|
|
9
10
|
juniorUsers
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZCHHVTMF.js";
|
|
11
12
|
import {
|
|
12
13
|
TURN_REASONING_LEVELS,
|
|
13
14
|
getChatConfig,
|
|
14
15
|
modelProfileSchema
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-3ZZEPLLB.js";
|
|
16
17
|
import {
|
|
17
18
|
juniorDestinations
|
|
18
19
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
} from "./chunk-M63DETLL.js";
|
|
24
25
|
import {
|
|
25
26
|
normalizeIdentityEmail
|
|
26
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-UGWBJAGN.js";
|
|
27
28
|
|
|
28
29
|
// src/chat/conversations/sql/store.ts
|
|
29
30
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -240,7 +241,8 @@ async function recordConversationParticipant(executor, args) {
|
|
|
240
241
|
juniorConversationParticipants.rootConversationId
|
|
241
242
|
],
|
|
242
243
|
set: {
|
|
243
|
-
lastMessageAt: sql2`greatest(${juniorConversationParticipants.lastMessageAt}, excluded.last_message_at)
|
|
244
|
+
lastMessageAt: sql2`greatest(${juniorConversationParticipants.lastMessageAt}, excluded.last_message_at)`,
|
|
245
|
+
...args.restoreArchive ? { archivedAt: null } : {}
|
|
244
246
|
}
|
|
245
247
|
});
|
|
246
248
|
}
|
|
@@ -596,7 +598,6 @@ function conversationFromRow(readRow) {
|
|
|
596
598
|
...destination ? { destination } : {},
|
|
597
599
|
...location ? { location } : {},
|
|
598
600
|
...actor ? { actor } : {},
|
|
599
|
-
...msFromDate(row.archivedAt) !== void 0 ? { archivedAtMs: msFromDate(row.archivedAt) } : {},
|
|
600
601
|
...row.channelName ? { channelName: row.channelName } : {},
|
|
601
602
|
...source ? { source } : {},
|
|
602
603
|
...sessionSource ? { sessionSource } : {},
|
|
@@ -813,7 +814,7 @@ var SqlStore = class {
|
|
|
813
814
|
}
|
|
814
815
|
async listByActivity(args = {}) {
|
|
815
816
|
const rows = await this.executor.db().select({
|
|
816
|
-
conversation:
|
|
817
|
+
conversation: conversationReadColumns(),
|
|
817
818
|
destination: juniorDestinations,
|
|
818
819
|
actorIdentity: juniorIdentities,
|
|
819
820
|
actorUserDisplayName: juniorUsers.displayName
|
|
@@ -896,7 +897,7 @@ var SqlStore = class {
|
|
|
896
897
|
}
|
|
897
898
|
async readConversationRow(conversationId) {
|
|
898
899
|
const rows = await this.executor.db().select({
|
|
899
|
-
conversation:
|
|
900
|
+
conversation: conversationReadColumns(),
|
|
900
901
|
destination: juniorDestinations,
|
|
901
902
|
actorIdentity: juniorIdentities,
|
|
902
903
|
actorUserDisplayName: juniorUsers.displayName
|
|
@@ -1053,7 +1054,6 @@ import {
|
|
|
1053
1054
|
gt,
|
|
1054
1055
|
gte,
|
|
1055
1056
|
inArray as inArray2,
|
|
1056
|
-
isNotNull,
|
|
1057
1057
|
lt,
|
|
1058
1058
|
lte,
|
|
1059
1059
|
sql as sql6
|
|
@@ -1757,14 +1757,6 @@ var SqlConversationEventStore = class {
|
|
|
1757
1757
|
newestCreatedAtMs,
|
|
1758
1758
|
options
|
|
1759
1759
|
);
|
|
1760
|
-
if (options.activity !== "preserve" && pending.some((event) => eventUnarchivesConversation(event.data))) {
|
|
1761
|
-
await this.executor.db().update(juniorConversations).set({ archivedAt: null }).where(
|
|
1762
|
-
and6(
|
|
1763
|
-
eq6(juniorConversations.conversationId, conversationId),
|
|
1764
|
-
isNotNull(juniorConversations.archivedAt)
|
|
1765
|
-
)
|
|
1766
|
-
);
|
|
1767
|
-
}
|
|
1768
1760
|
const cursor = await this.readCursor(conversationId);
|
|
1769
1761
|
const historyVersion = cursor.maxHistoryVersion ?? 0;
|
|
1770
1762
|
let seq = cursor.nextSeq;
|
|
@@ -1791,7 +1783,8 @@ var SqlConversationEventStore = class {
|
|
|
1791
1783
|
await recordConversationParticipant(this.executor, {
|
|
1792
1784
|
actorIdentityId,
|
|
1793
1785
|
conversationId,
|
|
1794
|
-
atMs: event.createdAtMs
|
|
1786
|
+
atMs: event.createdAtMs,
|
|
1787
|
+
restoreArchive: eventUnarchivesConversation(event.data)
|
|
1795
1788
|
});
|
|
1796
1789
|
}
|
|
1797
1790
|
}
|
|
@@ -2156,6 +2149,7 @@ export {
|
|
|
2156
2149
|
upsertIdentity,
|
|
2157
2150
|
upsertLinkedIdentity,
|
|
2158
2151
|
deleteProviderIdentityForSlackUser,
|
|
2152
|
+
resolveRootConversationId,
|
|
2159
2153
|
parseSessionSource,
|
|
2160
2154
|
bindProviderConversation,
|
|
2161
2155
|
locationFromRow,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getConversationEventStore,
|
|
6
6
|
getDb,
|
|
7
7
|
getSqlExecutor
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XCNS3CXE.js";
|
|
9
9
|
import {
|
|
10
10
|
juniorConversationAnnotations,
|
|
11
11
|
juniorConversationEvents,
|
|
@@ -14,23 +14,25 @@ import {
|
|
|
14
14
|
juniorUsers,
|
|
15
15
|
juniorWorkspaceRepos,
|
|
16
16
|
juniorWorkspaces
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZCHHVTMF.js";
|
|
18
18
|
import {
|
|
19
19
|
SANDBOX_WORKSPACE_ROOT,
|
|
20
|
+
getVercelSandboxCredentials,
|
|
20
21
|
hash,
|
|
22
|
+
isSandboxMissingError,
|
|
21
23
|
runNonInteractiveCommand,
|
|
22
24
|
sleep
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-AQHSXA3J.js";
|
|
24
26
|
import {
|
|
25
27
|
getStateAdapter
|
|
26
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-H6ZXBFGX.js";
|
|
27
29
|
import {
|
|
28
30
|
botConfig,
|
|
29
31
|
completeObject,
|
|
30
32
|
embedTexts,
|
|
31
33
|
getSlackBotToken,
|
|
32
34
|
standardModelId
|
|
33
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-3ZZEPLLB.js";
|
|
34
36
|
import {
|
|
35
37
|
isActorUserId,
|
|
36
38
|
parseActorUserId,
|
|
@@ -46,7 +48,7 @@ import {
|
|
|
46
48
|
setSpanAttributes,
|
|
47
49
|
setSpanStatus,
|
|
48
50
|
withSpan
|
|
49
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-UGWBJAGN.js";
|
|
50
52
|
|
|
51
53
|
// src/chat/plugins/agent-hooks.ts
|
|
52
54
|
import {
|
|
@@ -1664,15 +1666,65 @@ function workspaceRepoCheckoutPath(repo) {
|
|
|
1664
1666
|
}
|
|
1665
1667
|
|
|
1666
1668
|
// src/chat/workspaces/store.ts
|
|
1667
|
-
import { randomUUID as
|
|
1668
|
-
import { and as and5, asc as
|
|
1669
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1670
|
+
import { and as and5, asc as asc3, eq as eq5, sql as sql2 } from "drizzle-orm";
|
|
1671
|
+
|
|
1672
|
+
// src/chat/sandbox/snapshot/builder-sandbox.ts
|
|
1673
|
+
import { Sandbox } from "@vercel/sandbox";
|
|
1674
|
+
async function getWorkspaceSnapshotBuilder(name, signal) {
|
|
1675
|
+
const credentials = getVercelSandboxCredentials();
|
|
1676
|
+
return await Sandbox.get({
|
|
1677
|
+
name,
|
|
1678
|
+
resume: true,
|
|
1679
|
+
signal,
|
|
1680
|
+
...credentials ?? {}
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
async function deleteWorkspaceSnapshotBuilders(names) {
|
|
1684
|
+
const credentials = getVercelSandboxCredentials();
|
|
1685
|
+
let hasError = false;
|
|
1686
|
+
let firstError;
|
|
1687
|
+
for (const name of new Set(names)) {
|
|
1688
|
+
try {
|
|
1689
|
+
const sandbox = await Sandbox.get({
|
|
1690
|
+
name,
|
|
1691
|
+
resume: false,
|
|
1692
|
+
...credentials ?? {}
|
|
1693
|
+
});
|
|
1694
|
+
await sandbox.delete();
|
|
1695
|
+
} catch (error) {
|
|
1696
|
+
if (!isSandboxMissingError(error)) {
|
|
1697
|
+
if (!hasError) firstError = error;
|
|
1698
|
+
hasError = true;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
if (hasError) throw firstError;
|
|
1703
|
+
}
|
|
1669
1704
|
|
|
1670
1705
|
// src/chat/sandbox/snapshot/runtime.ts
|
|
1671
1706
|
var SANDBOX_RUNTIME = "node22";
|
|
1672
1707
|
|
|
1673
1708
|
// src/chat/sandbox/snapshot/store.ts
|
|
1674
|
-
import {
|
|
1675
|
-
|
|
1709
|
+
import { and as and4, asc as asc2, desc as desc2, eq as eq4, ne, or } from "drizzle-orm";
|
|
1710
|
+
function builderNames(rows) {
|
|
1711
|
+
return [
|
|
1712
|
+
...new Set(
|
|
1713
|
+
rows.map((row) => row.sandboxName).filter((name) => Boolean(name))
|
|
1714
|
+
)
|
|
1715
|
+
];
|
|
1716
|
+
}
|
|
1717
|
+
function sameWorkspaceRecipe(stored, expected) {
|
|
1718
|
+
if (stored.setupScript !== expected.setupScript || stored.repos.length !== expected.repos.length) {
|
|
1719
|
+
return false;
|
|
1720
|
+
}
|
|
1721
|
+
const expectedRepos = new Set(
|
|
1722
|
+
expected.repos.map((repo) => JSON.stringify([repo.provider, repo.repo]))
|
|
1723
|
+
);
|
|
1724
|
+
return stored.repos.every(
|
|
1725
|
+
(repo) => expectedRepos.has(JSON.stringify([repo.provider, repo.repo]))
|
|
1726
|
+
);
|
|
1727
|
+
}
|
|
1676
1728
|
function snapshotFromRow(row) {
|
|
1677
1729
|
if (row.status !== "ready" || !row.snapshotId || !row.generatedAt || row.buildDurationMs == null) {
|
|
1678
1730
|
throw new Error(`Invalid ready Workspace snapshot row: ${row.id}`);
|
|
@@ -1689,6 +1741,7 @@ function snapshotBuildFromRow(row) {
|
|
|
1689
1741
|
throw new Error(`Invalid Workspace snapshot build row: ${row.id}`);
|
|
1690
1742
|
}
|
|
1691
1743
|
return {
|
|
1744
|
+
id: row.id,
|
|
1692
1745
|
status: row.status,
|
|
1693
1746
|
phase: row.buildPhase,
|
|
1694
1747
|
profileHash: row.profileHash,
|
|
@@ -1710,99 +1763,131 @@ async function loadSnapshotsForProfile(db, workspaceId, profileHash) {
|
|
|
1710
1763
|
];
|
|
1711
1764
|
const [readyRows, buildRows] = await Promise.all([
|
|
1712
1765
|
db.select().from(juniorSnapshots).where(and4(profile, eq4(juniorSnapshots.status, "ready"))).orderBy(...order).limit(1),
|
|
1713
|
-
db.select().from(juniorSnapshots).where(and4(profile, ne(juniorSnapshots.status, "ready"))).orderBy(...order).limit(1)
|
|
1766
|
+
db.select().from(juniorSnapshots).where(and4(profile, ne(juniorSnapshots.status, "ready"))).orderBy(asc2(juniorSnapshots.status), ...order).limit(1)
|
|
1714
1767
|
]);
|
|
1715
1768
|
return {
|
|
1716
1769
|
ready: readyRows[0] ? snapshotFromRow(readyRows[0]) : null,
|
|
1717
1770
|
build: buildRows[0] ? snapshotBuildFromRow(buildRows[0]) : null
|
|
1718
1771
|
};
|
|
1719
1772
|
}
|
|
1720
|
-
async function
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
ne(juniorSnapshots.status, "ready")
|
|
1725
|
-
)
|
|
1726
|
-
).returning({
|
|
1727
|
-
sandboxName: juniorSnapshots.buildSandboxName
|
|
1728
|
-
});
|
|
1729
|
-
return deleted.map((row) => row.sandboxName).filter((name) => Boolean(name));
|
|
1773
|
+
async function clearWorkspaceSnapshots(db, workspaceId) {
|
|
1774
|
+
await db.select({ id: juniorWorkspaces.id }).from(juniorWorkspaces).where(eq4(juniorWorkspaces.id, workspaceId)).for("update");
|
|
1775
|
+
const deleted = await db.delete(juniorSnapshots).where(eq4(juniorSnapshots.workspaceId, workspaceId)).returning({ sandboxName: juniorSnapshots.buildSandboxName });
|
|
1776
|
+
return builderNames(deleted);
|
|
1730
1777
|
}
|
|
1731
|
-
async function
|
|
1778
|
+
async function invalidateReadySnapshot(params) {
|
|
1732
1779
|
const executor = getSqlExecutor();
|
|
1733
|
-
await executor.transaction(async () => {
|
|
1780
|
+
return await executor.transaction(async () => {
|
|
1734
1781
|
const db = executor.db();
|
|
1735
|
-
const
|
|
1736
|
-
if (!workspaceRows[0]) return;
|
|
1737
|
-
const now = /* @__PURE__ */ new Date();
|
|
1738
|
-
const existing = await db.select().from(juniorSnapshots).where(
|
|
1782
|
+
const deleted = await db.delete(juniorSnapshots).where(
|
|
1739
1783
|
and4(
|
|
1740
|
-
eq4(juniorSnapshots.workspaceId, workspaceId),
|
|
1741
|
-
eq4(juniorSnapshots.profileHash,
|
|
1784
|
+
eq4(juniorSnapshots.workspaceId, params.workspaceId),
|
|
1785
|
+
eq4(juniorSnapshots.profileHash, params.profileHash),
|
|
1786
|
+
eq4(juniorSnapshots.status, "ready"),
|
|
1787
|
+
eq4(juniorSnapshots.snapshotId, params.snapshotId)
|
|
1742
1788
|
)
|
|
1743
|
-
).
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
buildSandboxName: null,
|
|
1754
|
-
buildCommandId: null,
|
|
1755
|
-
buildError: null,
|
|
1756
|
-
updatedAt: now
|
|
1757
|
-
}).where(eq4(juniorSnapshots.id, current.id));
|
|
1758
|
-
return;
|
|
1759
|
-
}
|
|
1760
|
-
if (current && current.status === "ready" && current.snapshotId === snapshot.id) {
|
|
1761
|
-
await db.update(juniorSnapshots).set({
|
|
1762
|
-
buildDurationMs: snapshot.buildDurationMs,
|
|
1763
|
-
generatedAt: snapshot.generatedAt,
|
|
1764
|
-
buildStartedAt: null,
|
|
1765
|
-
buildPhase: null,
|
|
1766
|
-
buildSandboxName: null,
|
|
1767
|
-
buildCommandId: null,
|
|
1768
|
-
buildError: null,
|
|
1769
|
-
updatedAt: now
|
|
1770
|
-
}).where(eq4(juniorSnapshots.id, current.id));
|
|
1771
|
-
return;
|
|
1772
|
-
}
|
|
1773
|
-
await db.insert(juniorSnapshots).values({
|
|
1774
|
-
id: randomUUID2(),
|
|
1775
|
-
workspaceId,
|
|
1776
|
-
profileHash: snapshot.profileHash,
|
|
1789
|
+
).returning({ sandboxName: juniorSnapshots.buildSandboxName });
|
|
1790
|
+
return deleted[0]?.sandboxName ?? null;
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
async function setWorkspaceSnapshot(workspaceId, snapshot, options) {
|
|
1794
|
+
const executor = getSqlExecutor();
|
|
1795
|
+
return await executor.transaction(async () => {
|
|
1796
|
+
const db = executor.db();
|
|
1797
|
+
const now = /* @__PURE__ */ new Date();
|
|
1798
|
+
const updated = await db.update(juniorSnapshots).set({
|
|
1777
1799
|
status: "ready",
|
|
1778
1800
|
snapshotId: snapshot.id,
|
|
1779
1801
|
buildDurationMs: snapshot.buildDurationMs,
|
|
1780
1802
|
generatedAt: snapshot.generatedAt,
|
|
1781
1803
|
buildStartedAt: null,
|
|
1782
|
-
|
|
1804
|
+
buildPhase: null,
|
|
1783
1805
|
buildCommandId: null,
|
|
1784
1806
|
buildError: null,
|
|
1785
|
-
createdAt: now,
|
|
1786
1807
|
updatedAt: now
|
|
1787
|
-
})
|
|
1808
|
+
}).where(
|
|
1809
|
+
and4(
|
|
1810
|
+
eq4(juniorSnapshots.id, options.buildId),
|
|
1811
|
+
eq4(juniorSnapshots.workspaceId, workspaceId),
|
|
1812
|
+
eq4(juniorSnapshots.profileHash, snapshot.profileHash),
|
|
1813
|
+
eq4(juniorSnapshots.status, "building")
|
|
1814
|
+
)
|
|
1815
|
+
).returning({ id: juniorSnapshots.id });
|
|
1816
|
+
if (updated.length === 0) {
|
|
1817
|
+
return { written: false, replacedBuilderNames: [] };
|
|
1818
|
+
}
|
|
1819
|
+
const replaced = await db.delete(juniorSnapshots).where(
|
|
1820
|
+
and4(
|
|
1821
|
+
eq4(juniorSnapshots.workspaceId, workspaceId),
|
|
1822
|
+
eq4(juniorSnapshots.profileHash, snapshot.profileHash),
|
|
1823
|
+
ne(juniorSnapshots.id, options.buildId),
|
|
1824
|
+
or(
|
|
1825
|
+
eq4(juniorSnapshots.status, "failed"),
|
|
1826
|
+
eq4(juniorSnapshots.status, "ready")
|
|
1827
|
+
)
|
|
1828
|
+
)
|
|
1829
|
+
).returning({ sandboxName: juniorSnapshots.buildSandboxName });
|
|
1830
|
+
return {
|
|
1831
|
+
written: true,
|
|
1832
|
+
replacedBuilderNames: builderNames(replaced)
|
|
1833
|
+
};
|
|
1788
1834
|
});
|
|
1789
1835
|
}
|
|
1790
|
-
async function
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
await
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1836
|
+
async function setWorkspaceSnapshotBuild(workspaceId, build, options = {}) {
|
|
1837
|
+
const executor = getSqlExecutor();
|
|
1838
|
+
return await executor.transaction(async () => {
|
|
1839
|
+
const db = executor.db();
|
|
1840
|
+
const now = /* @__PURE__ */ new Date();
|
|
1841
|
+
const updated = await db.update(juniorSnapshots).set({
|
|
1842
|
+
status: build.status,
|
|
1843
|
+
buildStartedAt: build.startedAt,
|
|
1844
|
+
buildPhase: build.phase,
|
|
1845
|
+
buildSandboxName: build.sandboxName,
|
|
1846
|
+
buildCommandId: build.commandId,
|
|
1847
|
+
buildError: build.error,
|
|
1848
|
+
updatedAt: now
|
|
1849
|
+
}).where(
|
|
1850
|
+
and4(
|
|
1851
|
+
eq4(juniorSnapshots.id, build.id),
|
|
1852
|
+
eq4(juniorSnapshots.workspaceId, workspaceId),
|
|
1853
|
+
eq4(juniorSnapshots.profileHash, build.profileHash),
|
|
1854
|
+
eq4(juniorSnapshots.status, "building")
|
|
1855
|
+
)
|
|
1856
|
+
).returning({ id: juniorSnapshots.id });
|
|
1857
|
+
if (updated.length > 0) {
|
|
1858
|
+
return true;
|
|
1859
|
+
}
|
|
1860
|
+
if (!options.insertIfMissing) return false;
|
|
1861
|
+
const workspaceRows = await db.select({ setupScript: juniorWorkspaces.setupScript }).from(juniorWorkspaces).where(eq4(juniorWorkspaces.id, workspaceId)).for("update");
|
|
1862
|
+
const workspace = workspaceRows[0];
|
|
1863
|
+
if (!workspace) return false;
|
|
1864
|
+
if (options.expectedRecipe) {
|
|
1865
|
+
const repos = await db.select({
|
|
1866
|
+
provider: juniorWorkspaceRepos.provider,
|
|
1867
|
+
repo: juniorWorkspaceRepos.repo
|
|
1868
|
+
}).from(juniorWorkspaceRepos).where(eq4(juniorWorkspaceRepos.workspaceId, workspaceId));
|
|
1869
|
+
if (!sameWorkspaceRecipe({ ...workspace, repos }, options.expectedRecipe)) {
|
|
1870
|
+
return false;
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
const inserted = await db.insert(juniorSnapshots).values({
|
|
1874
|
+
id: build.id,
|
|
1875
|
+
workspaceId,
|
|
1876
|
+
profileHash: build.profileHash,
|
|
1877
|
+
status: build.status,
|
|
1878
|
+
snapshotId: null,
|
|
1879
|
+
buildDurationMs: null,
|
|
1880
|
+
generatedAt: null,
|
|
1881
|
+
buildStartedAt: build.startedAt,
|
|
1882
|
+
buildPhase: build.phase,
|
|
1883
|
+
buildSandboxName: build.sandboxName,
|
|
1884
|
+
buildCommandId: build.commandId,
|
|
1885
|
+
buildError: build.error,
|
|
1886
|
+
createdAt: now,
|
|
1887
|
+
updatedAt: now
|
|
1888
|
+
}).onConflictDoNothing().returning({ id: juniorSnapshots.id });
|
|
1889
|
+
return inserted.length > 0;
|
|
1890
|
+
});
|
|
1806
1891
|
}
|
|
1807
1892
|
|
|
1808
1893
|
// src/chat/workspaces/validation.ts
|
|
@@ -1914,8 +1999,8 @@ async function workspaceWithSnapshot(db, row, repos) {
|
|
|
1914
1999
|
}
|
|
1915
2000
|
async function loadWorkspaceRepos(db, workspaceId) {
|
|
1916
2001
|
return await db.select().from(juniorWorkspaceRepos).where(eq5(juniorWorkspaceRepos.workspaceId, workspaceId)).orderBy(
|
|
1917
|
-
|
|
1918
|
-
|
|
2002
|
+
asc3(juniorWorkspaceRepos.provider),
|
|
2003
|
+
asc3(juniorWorkspaceRepos.repo)
|
|
1919
2004
|
);
|
|
1920
2005
|
}
|
|
1921
2006
|
async function replaceWorkspaceRepos(db, workspaceId, repos) {
|
|
@@ -1946,13 +2031,24 @@ function isUniqueViolation(error) {
|
|
|
1946
2031
|
}
|
|
1947
2032
|
return false;
|
|
1948
2033
|
}
|
|
2034
|
+
async function cleanupSnapshotBuilders(workspaceId, names) {
|
|
2035
|
+
if (names.length === 0) return;
|
|
2036
|
+
try {
|
|
2037
|
+
await deleteWorkspaceSnapshotBuilders(names);
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
logException(error, "sandbox.workspace_snapshot.builder.delete_failed", {
|
|
2040
|
+
"app.workspace.id": workspaceId,
|
|
2041
|
+
"app.sandbox.snapshot.builder_count": names.length
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
1949
2045
|
async function listWorkspaces(db) {
|
|
1950
2046
|
const [workspaces, repos] = await Promise.all([
|
|
1951
|
-
db.select().from(juniorWorkspaces).orderBy(
|
|
2047
|
+
db.select().from(juniorWorkspaces).orderBy(asc3(juniorWorkspaces.name)),
|
|
1952
2048
|
db.select().from(juniorWorkspaceRepos).orderBy(
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
2049
|
+
asc3(juniorWorkspaceRepos.workspaceId),
|
|
2050
|
+
asc3(juniorWorkspaceRepos.provider),
|
|
2051
|
+
asc3(juniorWorkspaceRepos.repo)
|
|
1956
2052
|
)
|
|
1957
2053
|
]);
|
|
1958
2054
|
return workspaces.map(
|
|
@@ -1975,7 +2071,7 @@ async function listWorkspaceNamesByRepository(db, input) {
|
|
|
1975
2071
|
// Recipes store the provided repo casing; identity is case-insensitive.
|
|
1976
2072
|
sql2`lower(${juniorWorkspaceRepos.repo}) = lower(${repo})`
|
|
1977
2073
|
)
|
|
1978
|
-
).orderBy(
|
|
2074
|
+
).orderBy(asc3(juniorWorkspaces.name));
|
|
1979
2075
|
return rows.map((row) => row.name);
|
|
1980
2076
|
}
|
|
1981
2077
|
async function getWorkspaceByName(db, name) {
|
|
@@ -2002,7 +2098,7 @@ async function createWorkspace(input) {
|
|
|
2002
2098
|
const recipe = normalizeWorkspaceRecipe(input);
|
|
2003
2099
|
const executor = getSqlExecutor();
|
|
2004
2100
|
const now = /* @__PURE__ */ new Date();
|
|
2005
|
-
const id =
|
|
2101
|
+
const id = randomUUID2();
|
|
2006
2102
|
try {
|
|
2007
2103
|
await executor.transaction(async () => {
|
|
2008
2104
|
const db = executor.db();
|
|
@@ -2030,7 +2126,7 @@ async function updateWorkspace(id, input) {
|
|
|
2030
2126
|
const executor = getSqlExecutor();
|
|
2031
2127
|
const now = /* @__PURE__ */ new Date();
|
|
2032
2128
|
try {
|
|
2033
|
-
const
|
|
2129
|
+
const result = await executor.transaction(async () => {
|
|
2034
2130
|
const db = executor.db();
|
|
2035
2131
|
const existingRows = await db.select().from(juniorWorkspaces).where(eq5(juniorWorkspaces.id, id)).limit(1);
|
|
2036
2132
|
const existing = existingRows[0];
|
|
@@ -2043,12 +2139,11 @@ async function updateWorkspace(id, input) {
|
|
|
2043
2139
|
updatedAt: now
|
|
2044
2140
|
}).where(eq5(juniorWorkspaces.id, id)).returning();
|
|
2045
2141
|
await replaceWorkspaceRepos(db, id, recipe.repos);
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
}
|
|
2049
|
-
return rows[0];
|
|
2142
|
+
const builderNames2 = snapshotChanged ? await clearWorkspaceSnapshots(db, id) : [];
|
|
2143
|
+
return { builderNames: builderNames2, workspace: rows[0] };
|
|
2050
2144
|
});
|
|
2051
|
-
if (!
|
|
2145
|
+
if (!result) return void 0;
|
|
2146
|
+
await cleanupSnapshotBuilders(id, result.builderNames);
|
|
2052
2147
|
} catch (error) {
|
|
2053
2148
|
if (isUniqueViolation(error)) {
|
|
2054
2149
|
throw new WorkspaceValidationError(
|
|
@@ -2061,10 +2156,14 @@ async function updateWorkspace(id, input) {
|
|
|
2061
2156
|
}
|
|
2062
2157
|
async function deleteWorkspace(id) {
|
|
2063
2158
|
const executor = getSqlExecutor();
|
|
2064
|
-
|
|
2065
|
-
const
|
|
2066
|
-
|
|
2159
|
+
const result = await executor.transaction(async () => {
|
|
2160
|
+
const db = executor.db();
|
|
2161
|
+
const builderNames2 = await clearWorkspaceSnapshots(db, id);
|
|
2162
|
+
const rows = await db.delete(juniorWorkspaces).where(eq5(juniorWorkspaces.id, id)).returning({ id: juniorWorkspaces.id });
|
|
2163
|
+
return { builderNames: builderNames2, deleted: rows.length > 0 };
|
|
2067
2164
|
});
|
|
2165
|
+
await cleanupSnapshotBuilders(id, result.builderNames);
|
|
2166
|
+
return result.deleted;
|
|
2068
2167
|
}
|
|
2069
2168
|
|
|
2070
2169
|
// src/chat/plugins/agent-hooks.ts
|
|
@@ -3341,8 +3440,13 @@ export {
|
|
|
3341
3440
|
resolveChannelCapabilities,
|
|
3342
3441
|
tryWorkspaceRepoCheckoutPath,
|
|
3343
3442
|
workspaceRepoCheckoutPath,
|
|
3443
|
+
getWorkspaceSnapshotBuilder,
|
|
3444
|
+
deleteWorkspaceSnapshotBuilders,
|
|
3344
3445
|
SANDBOX_RUNTIME,
|
|
3345
|
-
|
|
3446
|
+
loadSnapshotsForProfile,
|
|
3447
|
+
invalidateReadySnapshot,
|
|
3448
|
+
setWorkspaceSnapshot,
|
|
3449
|
+
setWorkspaceSnapshotBuild,
|
|
3346
3450
|
WorkspaceValidationError,
|
|
3347
3451
|
listWorkspaces,
|
|
3348
3452
|
getWorkspaceByName,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_SQL_STATEMENT_TIMEOUT_MS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3ZZEPLLB.js";
|
|
4
4
|
import {
|
|
5
5
|
juniorDestinations,
|
|
6
6
|
timestamptz
|
|
@@ -56,7 +56,7 @@ var juniorArtifacts = pgTable(
|
|
|
56
56
|
import { index as index4, integer as integer3, pgTable as pgTable5, text as text5 } from "drizzle-orm/pg-core";
|
|
57
57
|
|
|
58
58
|
// src/db/schema/conversations.ts
|
|
59
|
-
import { sql as sql2 } from "drizzle-orm";
|
|
59
|
+
import { getTableColumns, sql as sql2 } from "drizzle-orm";
|
|
60
60
|
import {
|
|
61
61
|
index as index3,
|
|
62
62
|
integer as integer2,
|
|
@@ -181,7 +181,8 @@ var juniorConversations = pgTable4(
|
|
|
181
181
|
executionDurationMs: integer2("execution_duration_ms").notNull().default(0),
|
|
182
182
|
executionUsage: jsonb2("execution_usage_json").$type(),
|
|
183
183
|
metricRunId: text4("metric_run_id"),
|
|
184
|
-
|
|
184
|
+
// Keep the legacy column in the schema. Runtime code must not read or write it.
|
|
185
|
+
legacyArchivedAt: timestamptz("archived_at")
|
|
185
186
|
},
|
|
186
187
|
(table) => [
|
|
187
188
|
index3("junior_conversations_last_activity_idx").on(
|
|
@@ -210,6 +211,11 @@ var juniorConversations = pgTable4(
|
|
|
210
211
|
index3("junior_conversations_root_idx").on(table.rootConversationId)
|
|
211
212
|
]
|
|
212
213
|
);
|
|
214
|
+
function conversationReadColumns() {
|
|
215
|
+
const { legacyArchivedAt, ...columns } = getTableColumns(juniorConversations);
|
|
216
|
+
void legacyArchivedAt;
|
|
217
|
+
return columns;
|
|
218
|
+
}
|
|
213
219
|
|
|
214
220
|
// src/db/schema/attachments.ts
|
|
215
221
|
var juniorAttachments = pgTable5(
|
|
@@ -387,7 +393,8 @@ var juniorConversationParticipants = pgTable10(
|
|
|
387
393
|
{
|
|
388
394
|
userId: text10("user_id").notNull().references(() => juniorUsers.id),
|
|
389
395
|
rootConversationId: text10("root_conversation_id").notNull().references(() => juniorConversations.conversationId),
|
|
390
|
-
lastMessageAt: timestamptz("last_message_at").notNull()
|
|
396
|
+
lastMessageAt: timestamptz("last_message_at").notNull(),
|
|
397
|
+
archivedAt: timestamptz("archived_at")
|
|
391
398
|
},
|
|
392
399
|
(table) => [
|
|
393
400
|
primaryKey4({
|
|
@@ -693,7 +700,7 @@ var juniorSnapshots = pgTable18(
|
|
|
693
700
|
snapshotId: text18("snapshot_id"),
|
|
694
701
|
buildDurationMs: integer6("build_duration_ms"),
|
|
695
702
|
generatedAt: timestamptz("generated_at"),
|
|
696
|
-
//
|
|
703
|
+
// Builder references for check-in and snapshot-owner cleanup.
|
|
697
704
|
buildStartedAt: timestamptz("build_started_at"),
|
|
698
705
|
buildPhase: text18("build_phase").$type(),
|
|
699
706
|
buildSandboxName: text18("build_sandbox_name"),
|
|
@@ -731,6 +738,7 @@ var juniorSnapshots = pgTable18(
|
|
|
731
738
|
table.profileHash,
|
|
732
739
|
table.status
|
|
733
740
|
),
|
|
741
|
+
uniqueIndex8("junior_snapshots_active_build_uidx").on(table.workspaceId, table.profileHash).where(sql6`${table.status} = 'building'`),
|
|
734
742
|
index13("junior_snapshots_workspace_status_idx").on(
|
|
735
743
|
table.workspaceId,
|
|
736
744
|
table.status
|
|
@@ -1018,6 +1026,7 @@ export {
|
|
|
1018
1026
|
juniorUsers,
|
|
1019
1027
|
juniorIdentities,
|
|
1020
1028
|
juniorConversations,
|
|
1029
|
+
conversationReadColumns,
|
|
1021
1030
|
juniorAttachments,
|
|
1022
1031
|
juniorConversationAnnotations,
|
|
1023
1032
|
juniorApiTokens,
|