@sentry/junior 0.271.0 → 0.273.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/{adapter-Bqbtr1RV.js → adapter-umap1cth.js} +1 -1
- package/dist/{admin-CWBjzyN0.js → admin-0o6E_3lo.js} +1 -1
- package/dist/{agent-runner-BiHsH8O_.js → agent-runner-D7Qz-lGO.js} +899 -631
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +5 -5
- package/dist/api.d.ts +1 -1
- package/dist/api.js +62 -537
- package/dist/{app-C81xfpNa.d.ts → app-BcyhJq8x.d.ts} +4 -9
- package/dist/app.d.ts +1 -1
- package/dist/app.js +673 -134
- package/dist/{assistant-reply-DgtX9DaJ.js → assistant-reply-wZ7i4OFa.js} +1 -1
- package/dist/{automation-Dwh_xcqM.js → automation-yffXcZt9.js} +1 -1
- package/dist/{briefs-0FeSJHQ3.js → briefs-CgMnlpIp.js} +4 -4
- package/dist/{catalog-runtime-Bw9kjGVu.js → catalog-runtime-TygDsPOU.js} +1 -1
- package/dist/cli/chat.js +15 -15
- package/dist/cli/check.js +3 -3
- package/dist/cli/init.js +1 -1
- package/dist/cli/main.js +3 -3
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +4 -4
- package/dist/cli/upgrade.d.ts +1 -1
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-B0jlQSgO.js → client-DhqbV0Fe.js} +63 -5
- package/dist/{reporting-schema-CZREhYc-.js → common-Eu6sx09c.js} +4 -1
- package/dist/{config-DrAeD8sr.js → config-C6FTd7PX.js} +7 -15
- package/dist/{connections-BzN2K0G9.js → connections-Dq72KajR.js} +11 -11
- package/dist/{conversation-AhOVzN_k.js → conversation-T4oabbBi.js} +22 -1
- package/dist/{conversation-privacy-D1NhUxyo.js → conversation-privacy-BeRgrsph.js} +1 -1
- package/dist/{credential-sync-DpNWl4yy.js → credential-sync-BmCbHAp4.js} +15 -16
- package/dist/{db-DSabI7jJ.d.ts → db-DOzBGLn5.d.ts} +11 -1
- package/dist/{executor-C2cRw0hZ.js → executor-BafgvQcc.js} +25 -7
- package/dist/instrumentation.js +114 -3
- package/dist/{job-queue-CEeLYkSj.js → job-queue-C4lphW9Y.js} +3 -3
- package/dist/{logging-DuwXUuIY.js → logging-CNs1e04n.js} +6 -1
- package/dist/message-CETC5lsl.js +186 -0
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-callback-server-oM5TJt34.js → oauth-callback-server-DcQZsKMm.js} +2 -2
- package/dist/{credentialed-mh7HBqey.js → projection-BOpi891B.js} +4576 -49
- package/dist/{prompt-BPSdXYXV.js → prompt-B1ySjUyf.js} +1 -1
- package/dist/{registry-BPtbAVFo.js → registry-B-yUrv3h.js} +2 -2
- package/dist/{resolve-D44G1jJm.js → resolve-DqVtd4Q9.js} +3 -3
- package/dist/{result-CvP8c5bb.js → result-DQwTiLTw.js} +16 -12
- package/dist/{runner-FIGIKvk2.js → runner-Dco5qMq6.js} +11 -11
- package/dist/{sandbox-egress-signals-C_JzucwP.js → sandbox-egress-signals-DFc_9Mcv.js} +1 -1
- package/dist/{schema-DKZgO-xf.js → schema-5xHDGlBW.js} +10 -9
- package/dist/{schema-DPCvePop.d.ts → schema-9OGdsaxF.d.ts} +28 -3
- package/dist/{service-account-1mJGRAvx.js → service-account-CWfk9Cs-.js} +3 -3
- package/dist/{service-account-CHO3YXpt.js → service-account-smdPFWNy.js} +3 -3
- package/dist/{session-stop-DuUB1rwQ.js → session-stop-DaT_7tYa.js} +50 -24
- package/dist/{skills-DHK7L9Eo.js → skills-BbtJSF2-.js} +2 -2
- package/dist/{spawn-CKl_ySIq.js → spawn-Ceikdjkp.js} +2 -2
- package/dist/{list-DjJJ5K0x.js → stop-dKUc-x2K.js} +1017 -469
- package/dist/{store-Di0E4EvU.js → store-C1xuZcLd.js} +48 -31
- package/dist/{store-BF2XEeQz.js → store-DaxUuOmD.js} +3 -3
- package/dist/{task-queue-CC7IFtbT.js → task-queue-ymAh_-P1.js} +4 -4
- package/dist/{task-runner-DKZtMFwa.js → task-runner-vlH6pEm3.js} +6 -6
- package/dist/{thread-state-BQ1T3eeF.js → thread-state-BkUpE9Ae.js} +4 -5
- package/dist/{turn-failure-response-B5eSFoHn.js → turn-failure-response-DIsD7ip_.js} +7 -8
- package/dist/{turn-lifecycle-CTLEIEOn.js → turn-lifecycle-BdPKdPS8.js} +1 -1
- package/dist/turn-session-routing-BdCTDq9m.js +1625 -0
- package/dist/{validation-Cjo-3yt3.js → validation-BQjCfh84.js} +1 -1
- package/dist/{version-D30MBLLw.js → version-BpiFGZZW.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-D3jhuP66.js → viewer-C6Y1aXjZ.js} +49 -21
- package/dist/{work-CL9QwQcl.js → work-ChPh_YEh.js} +27 -39
- package/dist/{worker-S2P7IJDI.js → worker-Be_sK_ou.js} +6 -6
- package/migrations/0072_conversation_read_positions.sql +10 -0
- package/migrations/meta/0072_snapshot.json +4064 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +4 -4
- package/dist/message-CRe3WBKc.js +0 -59
- package/dist/turn-session-routing-BFVp8TbU.js +0 -6072
- package/migrations/AGENTS.md +0 -8
- package/dist/{oauth-relay-CTygMkNx.js → oauth-relay-C6ZAyJgf.js} +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import { n as pluginCatalogRuntime } from "./catalog-runtime-
|
|
2
|
+
import { n as pluginCatalogRuntime } from "./catalog-runtime-TygDsPOU.js";
|
|
3
3
|
import { isDeepStrictEqual } from "node:util";
|
|
4
4
|
// src/chat/plugins/validation.ts
|
|
5
5
|
var validation_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.
|
|
2
|
+
var version = "0.273.0";
|
|
3
3
|
// src/version.ts
|
|
4
4
|
/** Installed Junior package version, or `unknown` when package metadata is unavailable. */
|
|
5
5
|
const JUNIOR_VERSION = typeof version === "string" && version.trim() ? version : "unknown";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as JUNIOR_VERSION } from "./version-
|
|
1
|
+
export { t as JUNIOR_VERSION } from "./version-BpiFGZZW.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import { i as getChatConfig } from "./config-
|
|
3
|
-
import { L as GOOGLE_IDENTITY_PROVIDER, h as logWarn, z as normalizeIdentityEmail } from "./logging-
|
|
2
|
+
import { i as getChatConfig } from "./config-C6FTd7PX.js";
|
|
3
|
+
import { L as GOOGLE_IDENTITY_PROVIDER, h as logWarn, z as normalizeIdentityEmail } from "./logging-CNs1e04n.js";
|
|
4
4
|
import { a as isSlackUserId, d as parseSlackChannelReferenceId, f as parseSlackTeamId, s as parseActorUserId } from "./actor-B4DYygOB.js";
|
|
5
5
|
import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, o as conversationReadColumns, s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
|
|
6
|
-
import {
|
|
6
|
+
import { S as juniorConversationAnnotations, b as juniorConversationEvents, g as juniorConversationBindings, h as juniorConversationParticipants, t as createJuniorSqlExecutor, v as CONVERSATION_METRICS, y as juniorConversationMetrics } from "./executor-BafgvQcc.js";
|
|
7
7
|
import { d as newConversationEventSchema, f as encodeHistoryPayload, l as decodeStoredConversationEvent, n as detectImageMediaType, o as conversationEventDataSchema, u as historyReplacementSchema, v as usageSchema } from "./media-U6Tuz6Mi.js";
|
|
8
8
|
import { a as withLock } from "./locks-D-0h111u.js";
|
|
9
9
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -995,6 +995,9 @@ var SqlStore = class {
|
|
|
995
995
|
if (!row) return;
|
|
996
996
|
if (row.visibility === "public" || row.visibility === "private") return row.visibility;
|
|
997
997
|
}
|
|
998
|
+
async recordDestinationVisibility(args) {
|
|
999
|
+
await this.upsertDestination(destinationUpsertFromDestination(args), args.nowMs ?? Date.now());
|
|
1000
|
+
}
|
|
998
1001
|
async findSlackDestinationByName(args) {
|
|
999
1002
|
const normalized = args.channelName.trim().replace(/^#/, "").toLowerCase();
|
|
1000
1003
|
if (!normalized) return;
|
|
@@ -1406,20 +1409,33 @@ var SqlConversationEventStore = class {
|
|
|
1406
1409
|
nowMs: event.createdAtMs
|
|
1407
1410
|
});
|
|
1408
1411
|
rows.push(insertFromEvent(conversationId, seq++, historyVersion, event, actorIdentityId));
|
|
1409
|
-
if (actorIdentityId) await recordConversationParticipant(this.executor, {
|
|
1410
|
-
actorIdentityId,
|
|
1411
|
-
conversationId,
|
|
1412
|
-
atMs: event.createdAtMs,
|
|
1413
|
-
restoreArchive: eventUnarchivesConversation(event.data)
|
|
1414
|
-
});
|
|
1415
1412
|
}
|
|
1416
1413
|
await this.executor.db().insert(juniorConversationEvents).values(rows);
|
|
1414
|
+
for (const event of pending) if (event.data.type === "turn_started") await this.recordTurnInputParticipants(conversationId, event.data.inputMessageIds);
|
|
1417
1415
|
return rows.map((row) => ({
|
|
1418
1416
|
seq: row.seq,
|
|
1419
1417
|
historyVersion: row.historyVersion
|
|
1420
1418
|
}));
|
|
1421
1419
|
});
|
|
1422
1420
|
}
|
|
1421
|
+
/**
|
|
1422
|
+
* Add the authors of Turn input messages to the conversation.
|
|
1423
|
+
* Only people who start a Turn join it. Thread context, such as backfilled
|
|
1424
|
+
* or skipped messages, keeps its author without membership.
|
|
1425
|
+
*/
|
|
1426
|
+
async recordTurnInputParticipants(conversationId, inputMessageIds) {
|
|
1427
|
+
const rows = await this.executor.db().select().from(juniorConversationEvents).where(and(eq(juniorConversationEvents.conversationId, conversationId), eq(juniorConversationEvents.type, "message"), inArray(sql`${juniorConversationEvents.payload}->>'messageId'`, [...inputMessageIds])));
|
|
1428
|
+
for (const row of rows) {
|
|
1429
|
+
const { data } = eventFromRow(row);
|
|
1430
|
+
if (!row.actorIdentityId || data.type !== "message") continue;
|
|
1431
|
+
await recordConversationParticipant(this.executor, {
|
|
1432
|
+
actorIdentityId: row.actorIdentityId,
|
|
1433
|
+
conversationId,
|
|
1434
|
+
atMs: row.createdAt.getTime(),
|
|
1435
|
+
restoreArchive: eventUnarchivesConversation(data)
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1423
1439
|
async replaceHistory(conversationId, replacement) {
|
|
1424
1440
|
const parsed = historyReplacementSchema.parse(replacement);
|
|
1425
1441
|
await withConversationEventLock(this.executor, conversationId, async () => {
|
|
@@ -1727,8 +1743,14 @@ function parseAvatarUrl(value, provider) {
|
|
|
1727
1743
|
const host = url.hostname.toLowerCase();
|
|
1728
1744
|
return hosts.some((allowed) => host === allowed || host.endsWith(`.${allowed}`)) ? url.href : void 0;
|
|
1729
1745
|
}
|
|
1730
|
-
function
|
|
1731
|
-
return
|
|
1746
|
+
function avatarUrlHash(url) {
|
|
1747
|
+
return createHash("sha256").update(url).digest("hex");
|
|
1748
|
+
}
|
|
1749
|
+
function avatarVersion(url) {
|
|
1750
|
+
return avatarUrlHash(url).slice(0, 16);
|
|
1751
|
+
}
|
|
1752
|
+
function avatarPath(identityId, avatarUrl) {
|
|
1753
|
+
return `/api/people/avatars/${encodeURIComponent(identityId)}?v=${avatarVersion(avatarUrl)}`;
|
|
1732
1754
|
}
|
|
1733
1755
|
/**
|
|
1734
1756
|
* Read the photo path of each user: the Slack photo, then the Google photo.
|
|
@@ -1737,6 +1759,7 @@ function avatarPath(identityId) {
|
|
|
1737
1759
|
async function readUserAvatarUrls(db, userIds) {
|
|
1738
1760
|
if (userIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1739
1761
|
const rows = await db.select({
|
|
1762
|
+
avatarUrl: juniorIdentities.avatarUrl,
|
|
1740
1763
|
identityId: juniorIdentities.id,
|
|
1741
1764
|
provider: juniorIdentities.provider,
|
|
1742
1765
|
updatedAt: juniorIdentities.updatedAt,
|
|
@@ -1745,7 +1768,7 @@ async function readUserAvatarUrls(db, userIds) {
|
|
|
1745
1768
|
const rank = (row) => AVATAR_PROVIDERS.indexOf(row.provider);
|
|
1746
1769
|
rows.sort((left, right) => rank(left) - rank(right) || right.updatedAt.getTime() - left.updatedAt.getTime());
|
|
1747
1770
|
const avatars = /* @__PURE__ */ new Map();
|
|
1748
|
-
for (const row of rows) if (row.userId && !avatars.has(row.userId)) avatars.set(row.userId, avatarPath(row.identityId));
|
|
1771
|
+
for (const row of rows) if (row.userId && row.avatarUrl && !avatars.has(row.userId)) avatars.set(row.userId, avatarPath(row.identityId, row.avatarUrl));
|
|
1749
1772
|
return avatars;
|
|
1750
1773
|
}
|
|
1751
1774
|
/**
|
|
@@ -1754,7 +1777,7 @@ async function readUserAvatarUrls(db, userIds) {
|
|
|
1754
1777
|
*/
|
|
1755
1778
|
function identityAvatarUrl(row, userAvatarUrls) {
|
|
1756
1779
|
if (row.userId) return userAvatarUrls.get(row.userId);
|
|
1757
|
-
return row.avatarUrl ? avatarPath(row.identityId) : void 0;
|
|
1780
|
+
return row.avatarUrl ? avatarPath(row.identityId, row.avatarUrl) : void 0;
|
|
1758
1781
|
}
|
|
1759
1782
|
async function readBoundedBody(response, maxBytes) {
|
|
1760
1783
|
if (!response.body) return /* @__PURE__ */ new Uint8Array();
|
|
@@ -1818,9 +1841,10 @@ async function fetchAvatarImage(url, provider) {
|
|
|
1818
1841
|
};
|
|
1819
1842
|
}
|
|
1820
1843
|
/**
|
|
1821
|
-
* Read the saved photo of one Identity. Junior fetches it
|
|
1822
|
-
* once and keeps it in the state cache for a day. Return
|
|
1823
|
-
* Identity has no photo or the provider does not return
|
|
1844
|
+
* Read the saved photo of one Identity and its version. Junior fetches it
|
|
1845
|
+
* from the provider once and keeps it in the state cache for a day. Return
|
|
1846
|
+
* undefined when the Identity has no photo or the provider does not return
|
|
1847
|
+
* one.
|
|
1824
1848
|
*/
|
|
1825
1849
|
async function readAvatarImage(db, state, identityId) {
|
|
1826
1850
|
const [row] = await db.select({
|
|
@@ -1828,15 +1852,19 @@ async function readAvatarImage(db, state, identityId) {
|
|
|
1828
1852
|
provider: juniorIdentities.provider
|
|
1829
1853
|
}).from(juniorIdentities).where(and(eq(juniorIdentities.id, identityId), eq(juniorIdentities.kind, "user"))).limit(1);
|
|
1830
1854
|
const url = row ? parseAvatarUrl(row.avatarUrl, row.provider) : void 0;
|
|
1831
|
-
if (!row || !url) return void 0;
|
|
1832
|
-
const key = `avatar:${
|
|
1833
|
-
|
|
1855
|
+
if (!row?.avatarUrl || !url) return void 0;
|
|
1856
|
+
const key = `avatar:${avatarUrlHash(url)}`;
|
|
1857
|
+
const image = await createCache(state, "core").getOrLoad(key, async () => {
|
|
1834
1858
|
const loaded = await fetchAvatarImage(url, row.provider);
|
|
1835
1859
|
return {
|
|
1836
1860
|
value: loaded,
|
|
1837
1861
|
ttlMs: loaded ? AVATAR_CACHE_TTL_MS : AVATAR_FAILURE_TTL_MS
|
|
1838
1862
|
};
|
|
1839
|
-
})
|
|
1863
|
+
});
|
|
1864
|
+
return image ? {
|
|
1865
|
+
image,
|
|
1866
|
+
version: avatarVersion(row.avatarUrl)
|
|
1867
|
+
} : void 0;
|
|
1840
1868
|
}
|
|
1841
1869
|
// src/chat/plugins/viewer.ts
|
|
1842
1870
|
function identityFromRow(row) {
|
|
@@ -1950,4 +1978,4 @@ async function readIdentityByIdFromSql(db, identityId) {
|
|
|
1950
1978
|
async function readIdentityById(identityId) {
|
|
1951
1979
|
return await readIdentityByIdFromSql(getDb(), identityId);
|
|
1952
1980
|
}
|
|
1953
|
-
export {
|
|
1981
|
+
export { sameDestination as $, locationFromRow as A, saveUserTimezone as B, getSqlExecutor as C, loadConversationSlackTenantIds as D, withConversationEventLock as E, deleteProviderIdentityForSlackUser as F, agentTurnCostUsd as G, bindProviderConversation as H, deleteProviderIdentityForUser as I, hasAgentTurnUsage as J, agentTurnTotalTokens as K, findUserByVerifiedEmails as L, SYSTEM_IDENTITY_ID as M, resolveActorIdentityId as N, createSqlStore as O, saveActorAvatar as P, requireSlackDestination as Q, readUserTimezone as R, getDb as S, eventFromRow as T, parseSessionSource as U, upsertLinkedIdentity as V, addAgentTurnUsage as W, createSlackDestination as X, resolveRootConversationId as Y, parseDestination as Z, closeDb as _, readActorIdentityFromSql as a, getConversationMessageSearchStore as b, readViewerAvatarUrl as c, updateViewerDisplayName as d, identityAvatarUrl as f, createCache as g, readUserAvatarUrls as h, readActorIdentity as i, startLocationThread as j, withConversationMutationLock as k, resolveViewerUser as l, readAvatarImage as m, findUserByEmailFromSql as n, readIdentityById as o, parseAvatarUrl as p, agentTurnUsageSchema as q, listAdminUsersFromSql as r, readIdentityByIdFromSql as s, findUserByEmail as t, setUserAdminFromSql as u, db_exports as v, createSqlConversationEventStore as w, getConversationStore as x, getConversationEventStore as y, recordGoogleSignIn as z };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as botConfig } from "./config-
|
|
3
|
-
import {
|
|
1
|
+
import { G as AuthorizationFlowDisabledError, La as loadForkHistory, V as PluginCredentialFailureError, Wt as isTurnExecutionLimitExceededError, Yt as getTerminalAssistantMessages, et as saveTurnCheckpoint, it as getTurnRecord, l as openConversationProjection, rt as failTurnRecord, tt as abandonTurnRecord } from "./projection-BOpi891B.js";
|
|
2
|
+
import { n as botConfig } from "./config-C6FTd7PX.js";
|
|
3
|
+
import { M as SYSTEM_IDENTITY_ID, x as getConversationStore, y as getConversationEventStore } from "./viewer-C6Y1aXjZ.js";
|
|
4
4
|
import { _ as sameActorIdentity, p as agentInstructionProvenance } from "./media-U6Tuz6Mi.js";
|
|
5
|
-
import { Dt as
|
|
6
|
-
import {
|
|
7
|
-
import { n as getAssistantReplyText } from "./assistant-reply-
|
|
8
|
-
import {
|
|
9
|
-
import { r as appendAndEnqueueInboundMessage } from "./store-
|
|
10
|
-
import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-
|
|
11
|
-
import { a as persistThreadStateById, n as getPersistedSandboxState, r as getPersistedThreadState } from "./thread-state-
|
|
5
|
+
import { Dt as buildSteeringPiMessage, Ot as withoutSavedSteeringMessages, Pt as readBlockedReport, _t as stopChildAgentsOf, bt as recordSubagentStarted, yt as recordSubagentEnded } from "./agent-runner-D7Qz-lGO.js";
|
|
6
|
+
import { B as agentTypeStartsWithParentHistory, E as markAgentInvocationSteered, J as isTurnInputCommitLostError, K as getConversationTurnBoundaryError, O as reportReplacedAgentInvocation, S as markAgentInvocationMailboxAppended, T as markAgentInvocationRunning, W as TurnInputCommitLostError, d as getAgentInvocationMessageId, g as getLatestAgentInvocationForConversation, n as completeAgentInvocation, o as getActiveAgentInvocationForConversation, p as getAgentInvocationTurnId, r as createAgentInvocation, s as getAgentInvocation, v as isTerminalAgentInvocation, w as markAgentInvocationPaused, y as listActiveAgentInvocationsForConversation, z as agentTypeInstructions } from "./store-C1xuZcLd.js";
|
|
7
|
+
import { n as getAssistantReplyText } from "./assistant-reply-wZ7i4OFa.js";
|
|
8
|
+
import { A as recordFinishedTurnForAutomatedLimit, j as resetAutomatedTurnLimit, w as maybePostAutomatedTurnLimitNotice } from "./session-stop-DaT_7tYa.js";
|
|
9
|
+
import { r as appendAndEnqueueInboundMessage } from "./store-DaxUuOmD.js";
|
|
10
|
+
import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-BdPKdPS8.js";
|
|
11
|
+
import { a as persistThreadStateById, n as getPersistedSandboxState, r as getPersistedThreadState } from "./thread-state-BkUpE9Ae.js";
|
|
12
12
|
import { isDeepStrictEqual } from "node:util";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
// src/chat/runtime/turn-execution.ts
|
|
@@ -56,34 +56,6 @@ async function finishTurn(conversationId, turnId, saved) {
|
|
|
56
56
|
outcome: saved.outcome
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
// src/chat/agent-invocations/fork-history.ts
|
|
60
|
-
/**
|
|
61
|
-
* Cut parent history for a fork: everything before the parent's message that
|
|
62
|
-
* started the fork, through the last point where every tool call has its
|
|
63
|
-
* result. A model request with an unanswered tool call fails, and the parent
|
|
64
|
-
* can commit its history in the middle of a tool round.
|
|
65
|
-
*/
|
|
66
|
-
function forkHistoryFrom(messages, parentToolCallId) {
|
|
67
|
-
const spawnIndex = parentToolCallId ? messages.findIndex((message) => message.role === "assistant" && message.content.some((part) => part.type === "toolCall" && part.id === parentToolCallId)) : -1;
|
|
68
|
-
const before = spawnIndex >= 0 ? messages.slice(0, spawnIndex) : messages;
|
|
69
|
-
const pending = /* @__PURE__ */ new Set();
|
|
70
|
-
let end = 0;
|
|
71
|
-
for (const [index, message] of before.entries()) {
|
|
72
|
-
if (message.role === "assistant") {
|
|
73
|
-
for (const part of message.content) if (part.type === "toolCall") pending.add(part.id);
|
|
74
|
-
} else if (message.role === "toolResult") pending.delete(message.toolCallId);
|
|
75
|
-
if (pending.size === 0) end = index + 1;
|
|
76
|
-
}
|
|
77
|
-
return before.slice(0, end);
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Load the start history of a fork child from its parent Conversation. The
|
|
81
|
-
* child commits it as its own history in its first checkpoint, so later
|
|
82
|
-
* agent invocations of the child read it from the child Conversation.
|
|
83
|
-
*/
|
|
84
|
-
async function loadForkHistory(invocation) {
|
|
85
|
-
return forkHistoryFrom((await openConversationProjection({ conversationId: invocation.parentConversationId })).messages, invocation.parentToolCallId);
|
|
86
|
-
}
|
|
87
59
|
// src/chat/agent-invocations/work.ts
|
|
88
60
|
const agentInvocationMailboxMetadataSchema = z.object({
|
|
89
61
|
agentInvocationId: z.string().min(1),
|
|
@@ -264,7 +236,7 @@ async function persistTerminalLifecycle(terminal) {
|
|
|
264
236
|
await finishTurn(terminal.childConversationId, turnId, agentInvocationTurnEnd(terminal));
|
|
265
237
|
}
|
|
266
238
|
/** Stop an invocation whose worker died, or project its terminal turn result. */
|
|
267
|
-
async function projectTerminalTurn(invocation) {
|
|
239
|
+
async function projectTerminalTurn(invocation, options = {}) {
|
|
268
240
|
let turn = await getTurnRecord(invocation.childConversationId, getAgentInvocationTurnId(invocation.invocationId));
|
|
269
241
|
if (!turn) return;
|
|
270
242
|
if (turn.state === "running") {
|
|
@@ -281,6 +253,7 @@ async function projectTerminalTurn(invocation) {
|
|
|
281
253
|
const failed = turn.state !== "completed" || Boolean(turn.errorMessage);
|
|
282
254
|
const blocked = turn.turnStartMessageIndex === void 0 ? void 0 : readBlockedReport(turn.piMessages.slice(turn.turnStartMessageIndex));
|
|
283
255
|
return await completeAgentInvocation({
|
|
256
|
+
...options,
|
|
284
257
|
invocationId: invocation.invocationId,
|
|
285
258
|
...failed ? {
|
|
286
259
|
errorMessage: turn.errorMessage ?? "Agent invocation failed",
|
|
@@ -294,6 +267,20 @@ async function projectTerminalTurn(invocation) {
|
|
|
294
267
|
}
|
|
295
268
|
});
|
|
296
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* End an agent invocation that is still running or paused while other work
|
|
272
|
+
* of its child starts. A saved finished Turn gives its result. Otherwise it
|
|
273
|
+
* fails. The newer work does not continue this task, so the result goes to
|
|
274
|
+
* the parent on its own.
|
|
275
|
+
*/
|
|
276
|
+
async function endOtherActiveAgentInvocation(invocation) {
|
|
277
|
+
return await projectTerminalTurn(invocation, { reportNow: true }) ?? await completeAgentInvocation({
|
|
278
|
+
invocationId: invocation.invocationId,
|
|
279
|
+
errorMessage: "This task was not resumed. Newer work for this child agent started, so this task ended without a result.",
|
|
280
|
+
reportNow: true,
|
|
281
|
+
status: "failed"
|
|
282
|
+
});
|
|
283
|
+
}
|
|
297
284
|
/** Classify authorization failures that terminally block background work. */
|
|
298
285
|
function blockingInvocationError(error) {
|
|
299
286
|
const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
|
|
@@ -428,6 +415,7 @@ function createAgentInvocationWorker(agentRunner, options = {}) {
|
|
|
428
415
|
await acknowledge();
|
|
429
416
|
return { status: "completed" };
|
|
430
417
|
}
|
|
418
|
+
for (const active of await listActiveAgentInvocationsForConversation(invocation.childConversationId)) if (active.invocationId !== invocation.invocationId) await finish(await endOtherActiveAgentInvocation(active));
|
|
431
419
|
invocation = await markAgentInvocationRunning(invocation.invocationId) ?? invocation;
|
|
432
420
|
if (isTerminalAgentInvocation(invocation)) {
|
|
433
421
|
await finish(invocation);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { i as getChatConfig } from "./config-
|
|
5
|
-
import { T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException } from "./logging-
|
|
6
|
-
import { f as getTurnRequestDeadline, m as ConversationQueueMessageRejectedError } from "./job-queue-
|
|
7
|
-
import { C as requestAnotherSlice, T as startConversationWork, b as recordConversationRetry, d as countPendingConversationMessages, f as deadLetterAttempt, g as getConversationWorkState, i as beginConversationResume, l as completeConversationStop, m as ensureConversationWake, o as checkInConversationWork, p as drainConversationMailbox, s as clearConsumedConversationWake, t as ackMessages, u as completeConversationWork, x as releaseConversationWork, y as recordAttemptFailure } from "./store-
|
|
2
|
+
import { Ct as hasConversationStop, Et as isInvalidConversationRecordError, Tt as isFinalAttempt } from "./projection-BOpi891B.js";
|
|
3
|
+
import { b as isProviderRetryError } from "./client-DhqbV0Fe.js";
|
|
4
|
+
import { i as getChatConfig } from "./config-C6FTd7PX.js";
|
|
5
|
+
import { T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException } from "./logging-CNs1e04n.js";
|
|
6
|
+
import { f as getTurnRequestDeadline, m as ConversationQueueMessageRejectedError } from "./job-queue-C4lphW9Y.js";
|
|
7
|
+
import { C as requestAnotherSlice, T as startConversationWork, b as recordConversationRetry, d as countPendingConversationMessages, f as deadLetterAttempt, g as getConversationWorkState, i as beginConversationResume, l as completeConversationStop, m as ensureConversationWake, o as checkInConversationWork, p as drainConversationMailbox, s as clearConsumedConversationWake, t as ackMessages, u as completeConversationWork, x as releaseConversationWork, y as recordAttemptFailure } from "./store-DaxUuOmD.js";
|
|
8
8
|
// src/chat/task-execution/attempt-selection.ts
|
|
9
9
|
function selectContiguousTurnBatch(messages) {
|
|
10
10
|
const first = messages[0];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
CREATE TABLE "junior_conversation_read_positions" (
|
|
2
|
+
"user_id" text NOT NULL,
|
|
3
|
+
"conversation_id" text NOT NULL,
|
|
4
|
+
"last_read_seq" integer NOT NULL,
|
|
5
|
+
"updated_at" timestamp with time zone NOT NULL,
|
|
6
|
+
CONSTRAINT "junior_conversation_read_positions_user_conversation_pk" PRIMARY KEY("user_id","conversation_id")
|
|
7
|
+
);
|
|
8
|
+
--> statement-breakpoint
|
|
9
|
+
ALTER TABLE "junior_conversation_read_positions" ADD CONSTRAINT "junior_conversation_read_positions_user_id_junior_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."junior_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "junior_conversation_read_positions" ADD CONSTRAINT "junior_conversation_read_positions_conversation_id_junior_conversations_conversation_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."junior_conversations"("conversation_id") ON DELETE no action ON UPDATE no action;
|