@sentry/junior 0.241.0 → 0.243.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/{admin-CJkjl-aN.js → admin-DHOGoI03.js} +1 -1
- package/dist/{agent-hooks-C5zYOaJk.js → agent-hooks-Cqo6ULp6.js} +12 -12
- package/dist/agent-invocations-BzRAZ_nj.js +176 -0
- package/dist/{agent-runner-CMZ6lFQe.js → agent-runner-BZOjoMlZ.js} +621 -69
- package/dist/api/schema.d.ts +53 -1
- package/dist/api/schema.js +4 -4
- package/dist/api.js +52 -22
- package/dist/{app-MEd7wbF0.d.ts → app-DRLh-8zs.d.ts} +5 -0
- package/dist/app.d.ts +1 -1
- package/dist/app.js +41 -24
- package/dist/{briefs-CsQbFjRi.js → briefs-C4GogKaB.js} +4 -4
- package/dist/{catalog-runtime-Tz0O2MZe.js → catalog-runtime-jazDa-oO.js} +1 -1
- package/dist/cli/chat.js +12 -12
- package/dist/cli/check.js +3 -3
- package/dist/cli/main.js +2 -2
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +3 -3
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-CRZ-i1tH.js → client-Es79bknZ.js} +2 -2
- package/dist/{config-CCI82OTD.js → config-gype19qQ.js} +7 -2
- package/dist/{conversation-DwD-vquD.js → conversation-mt3yJ09u.js} +2 -1
- package/dist/{conversation-privacy-D5Byl5eC.js → conversation-privacy-BIplVfmz.js} +1 -1
- package/dist/{credential-sync-DUpSxUum.js → credential-sync-BY97dkST.js} +14 -14
- package/dist/{executor-CewKi7EG.js → executor-C7bsEF-c.js} +5 -124
- package/dist/{history-BLTUgFYO.js → history-DlsoHsoe.js} +1 -0
- package/dist/{images-DY6Pxq4w.js → images-WmrEAtto.js} +3 -3
- package/dist/instrumentation.js +2 -2
- package/dist/{job-queue-C6o2aJQ6.js → job-queue-DQDesz8a.js} +1 -1
- package/dist/{logging-LQnLlPf8.js → logging-CdZ1LQJ7.js} +1 -1
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-authorization-Clzkm-Ts.js → oauth-authorization-Di0KlyoJ.js} +1 -1
- package/dist/{oauth-callback-server-DcYAJSEz.js → oauth-callback-server-Cmog7Q3T.js} +2 -2
- package/dist/{pending-auth-CT3ojhKe.js → pending-auth-CNAlGOyl.js} +2 -2
- package/dist/{profile-mWuVZ8ht.js → profile-qqt_2di0.js} +4 -4
- package/dist/{prompt-CMU-B4FA.js → prompt-D_cg2iqi.js} +1 -1
- package/dist/{registry-DPDH6s5G.js → registry-WOJKAIRI.js} +1 -1
- package/dist/{resolve-BAN8BSGy.js → resolve-C8VvY0lg.js} +2 -2
- package/dist/{runner-CqXZJfzk.js → runner-DojxjGmt.js} +10 -10
- package/dist/{sandbox-egress-signals-DFUUokws.js → sandbox-egress-signals-B7azPnsm.js} +1 -1
- package/dist/{schema-Cabm4jcj.js → schema-nQRsPWSr.js} +34 -3
- package/dist/{skills-BtHhSATy.js → skills-Zj-9pbSU.js} +2 -2
- package/dist/{spawn-BszkFJKJ.js → spawn-DDJ5z9IC.js} +5 -4
- package/dist/{task-queue-1LP6benz.js → task-queue-CAi-XM8x.js} +3 -3
- package/dist/{task-runner-kLN3HC-_.js → task-runner-CIP2asjP.js} +12 -11
- package/dist/{tasks-CO52vLkI.js → tasks-Qx6Fos_R.js} +49 -17
- package/dist/{thread-state-CaFRG5Mh.js → thread-state-BN_5S1bx.js} +7 -7
- package/dist/{turn-failure-response-Dmovuiq1.js → turn-failure-response-B1UW2T7a.js} +9 -9
- package/dist/{turn-lifecycle-DGqZgU6J.js → turn-lifecycle-BzeE4sVD.js} +1 -1
- package/dist/{turn-session-routing-B_v8Wbn4.js → turn-session-routing-DsvU39zW.js} +1 -1
- package/dist/{validation-B4L2Rmiw.js → validation-Dklx_nds.js} +1 -1
- package/dist/{version-DiR36OaN.js → version-BvG02ZTN.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-D6stAU7h.js → viewer-B7qDM2DM.js} +6 -8
- package/dist/{web-authorization-DLMBx2nL.js → web-authorization-Cqv7bP19.js} +6 -6
- package/dist/{web-input---xuox1t.js → web-input-CqnqSfzI.js} +227 -31
- package/dist/{work-G-HdoOSF.js → work-D_BBvd4I.js} +111 -225
- package/dist/{worker-CDUDfL9P.js → worker-BWdV_5Ys.js} +5 -5
- package/migrations/0050_agent_invocation_parent_mailbox.sql +4 -0
- package/migrations/0051_agent_invocation_parent_tool_call.sql +1 -0
- package/migrations/meta/0050_snapshot.json +3753 -0
- package/migrations/meta/0051_snapshot.json +3759 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +4 -4
- package/dist/destinations-BeBiJeEM.js +0 -29
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { d as unwrapCurrentInstruction, f as escapeXml, i as completeText, o as resolveGatewayModel } from "./client-
|
|
2
|
-
import { d as logException, o as getActiveTraceId, p as logWarn, s as getLogContextAttributes, t as buildTurnFailureResponse, v as setSpanAttributes } from "./logging-
|
|
1
|
+
import { d as unwrapCurrentInstruction, f as escapeXml, i as completeText, o as resolveGatewayModel } from "./client-Es79bknZ.js";
|
|
2
|
+
import { d as logException, o as getActiveTraceId, p as logWarn, s as getLogContextAttributes, t as buildTurnFailureResponse, v as setSpanAttributes } from "./logging-CdZ1LQJ7.js";
|
|
3
3
|
import { n as captureMessage } from "./sentry-CgWZM_kV.js";
|
|
4
|
-
import { n as botConfig, v as normalizeSlackEmojiName } from "./config-
|
|
4
|
+
import { n as botConfig, v as normalizeSlackEmojiName } from "./config-gype19qQ.js";
|
|
5
5
|
import { c as toStoredSlackActor, f as parseSlackUserId, g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
|
|
6
|
-
import { c as getConversationEventStore, f as getSqlExecutor, m as withConversationEventLock, p as createSqlConversationEventStore, u as getConversationStore, v as startLocationThread, x as addAgentTurnUsage, y as bindProviderConversation } from "./viewer-
|
|
7
|
-
import { a as juniorSchedulerRuns, o as juniorSchedulerTasks, s as juniorAutomationVersions, u as juniorEventAutomations } from "./executor-
|
|
8
|
-
import { d as instructionActors, f as instructionProvenanceFor, n as agentHistoryItemSchema, u as contextProvenance } from "./history-
|
|
9
|
-
import { p as credentialSubjectSchema } from "./registry-
|
|
10
|
-
import { Ft as SlackActionError, Ht as normalizeSlackConversationId, Jt as agentsInstructionsUpdatedEvent, Wt as withSlackRetries, Xt as authenticationUnlinkedEvent, Yt as authenticationLinkedEvent, n as applyPluginFormatMarkdown, qt as JUNIOR_NATIVE_EVENT_NAMESPACE, zt as getSlackClient } from "./agent-hooks-
|
|
11
|
-
import { H as messageCardRef } from "./conversation-
|
|
12
|
-
import { D as fenceLock, O as withLock, T as MUTATION_LOCK_TTL_MS, k as sleep, w as getStateAdapter } from "./profile-
|
|
6
|
+
import { c as getConversationEventStore, f as getSqlExecutor, m as withConversationEventLock, p as createSqlConversationEventStore, u as getConversationStore, v as startLocationThread, x as addAgentTurnUsage, y as bindProviderConversation } from "./viewer-B7qDM2DM.js";
|
|
7
|
+
import { a as juniorSchedulerRuns, o as juniorSchedulerTasks, s as juniorAutomationVersions, u as juniorEventAutomations } from "./executor-C7bsEF-c.js";
|
|
8
|
+
import { d as instructionActors, f as instructionProvenanceFor, n as agentHistoryItemSchema, u as contextProvenance } from "./history-DlsoHsoe.js";
|
|
9
|
+
import { p as credentialSubjectSchema } from "./registry-WOJKAIRI.js";
|
|
10
|
+
import { Ft as SlackActionError, Ht as normalizeSlackConversationId, Jt as agentsInstructionsUpdatedEvent, Wt as withSlackRetries, Xt as authenticationUnlinkedEvent, Yt as authenticationLinkedEvent, n as applyPluginFormatMarkdown, qt as JUNIOR_NATIVE_EVENT_NAMESPACE, zt as getSlackClient } from "./agent-hooks-Cqo6ULp6.js";
|
|
11
|
+
import { H as messageCardRef } from "./conversation-mt3yJ09u.js";
|
|
12
|
+
import { D as fenceLock, O as withLock, T as MUTATION_LOCK_TTL_MS, k as sleep, w as getStateAdapter } from "./profile-qqt_2di0.js";
|
|
13
13
|
import { A as eventAutomationSchema, D as scheduledRunSchema, E as scheduledAutomationSchema, S as automationVersionSchema } from "./automation-gznOMaQ2.js";
|
|
14
14
|
import { isDeepStrictEqual } from "node:util";
|
|
15
15
|
import { z } from "zod";
|
|
@@ -1160,6 +1160,18 @@ async function recordSubscribedReplyRoute(args) {
|
|
|
1160
1160
|
}
|
|
1161
1161
|
}]);
|
|
1162
1162
|
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Load the profile of the newest Turn route or handoff.
|
|
1165
|
+
*
|
|
1166
|
+
* The projection profile is not enough: a Turn route does not replace history.
|
|
1167
|
+
*/
|
|
1168
|
+
async function loadLastModelProfile(args) {
|
|
1169
|
+
const data = (await getConversationEventStore().query(args.conversationId, {
|
|
1170
|
+
limit: 1,
|
|
1171
|
+
types: ["turn_routed", "handoff"]
|
|
1172
|
+
})).events[0]?.data;
|
|
1173
|
+
return data?.type === "turn_routed" || data?.type === "handoff" ? data.modelProfile : void 0;
|
|
1174
|
+
}
|
|
1163
1175
|
/** Load a previously selected model profile for a resumed turn. */
|
|
1164
1176
|
async function loadTurnRoute(args) {
|
|
1165
1177
|
const event = await getConversationEventStore().loadByIdempotencyKey(args.conversationId, `turn:${args.turnId}:routed`);
|
|
@@ -2602,8 +2614,21 @@ function readBareUrl(line, start) {
|
|
|
2602
2614
|
end
|
|
2603
2615
|
};
|
|
2604
2616
|
}
|
|
2605
|
-
|
|
2606
|
-
function
|
|
2617
|
+
const BARE_SLACK_USER_ID_RE = /^@([UW](?=[A-Z0-9]*\d)[A-Z0-9]{8,})(?![\w])/;
|
|
2618
|
+
function readBareSlackUserMention(line, start) {
|
|
2619
|
+
if (line[start] !== "@" || /\w/.test(line[start - 1] ?? "")) return;
|
|
2620
|
+
const match = BARE_SLACK_USER_ID_RE.exec(line.slice(start));
|
|
2621
|
+
if (!match) return;
|
|
2622
|
+
return {
|
|
2623
|
+
text: `<@${match[1]}>`,
|
|
2624
|
+
end: start + match[0].length
|
|
2625
|
+
};
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Wrap bare http(s) URLs and bare `@U123` Slack user IDs on a single line as
|
|
2629
|
+
* Slack explicit `<url>` links and `<@U123>` mentions.
|
|
2630
|
+
*/
|
|
2631
|
+
function wrapBareReferencesOnLine(line) {
|
|
2607
2632
|
let result = "";
|
|
2608
2633
|
let i = 0;
|
|
2609
2634
|
while (i < line.length) {
|
|
@@ -2625,6 +2650,12 @@ function wrapBareUrlsOnLine(line) {
|
|
|
2625
2650
|
i = mdLink.end;
|
|
2626
2651
|
continue;
|
|
2627
2652
|
}
|
|
2653
|
+
const userMention = readBareSlackUserMention(line, i);
|
|
2654
|
+
if (userMention) {
|
|
2655
|
+
result += userMention.text;
|
|
2656
|
+
i = userMention.end;
|
|
2657
|
+
continue;
|
|
2658
|
+
}
|
|
2628
2659
|
if (line.startsWith("https://", i) || line.startsWith("http://", i)) {
|
|
2629
2660
|
const parsed = readBareUrl(line, i);
|
|
2630
2661
|
if (parsed) {
|
|
@@ -2641,12 +2672,13 @@ function wrapBareUrlsOnLine(line) {
|
|
|
2641
2672
|
/**
|
|
2642
2673
|
* Pre-wrap bare http(s) URLs outside fenced code blocks as Slack explicit
|
|
2643
2674
|
* links, preventing Slack's auto-linker from consuming adjacent formatting
|
|
2644
|
-
* markers into the URL.
|
|
2675
|
+
* markers into the URL. Bare `@U123` user IDs become `<@U123>` mentions,
|
|
2676
|
+
* because Slack shows a bare ID as literal text.
|
|
2645
2677
|
*
|
|
2646
2678
|
* Uses the same fence-toggle rule as `ensureBlockSpacing` so both passes
|
|
2647
2679
|
* agree on which lines are code.
|
|
2648
2680
|
*/
|
|
2649
|
-
function
|
|
2681
|
+
function wrapBareReferences(text) {
|
|
2650
2682
|
const lines = text.split("\n");
|
|
2651
2683
|
const out = [];
|
|
2652
2684
|
let inCodeBlock = false;
|
|
@@ -2656,7 +2688,7 @@ function wrapBareUrls(text) {
|
|
|
2656
2688
|
out.push(line);
|
|
2657
2689
|
continue;
|
|
2658
2690
|
}
|
|
2659
|
-
out.push(inCodeBlock ? line :
|
|
2691
|
+
out.push(inCodeBlock ? line : wrapBareReferencesOnLine(line));
|
|
2660
2692
|
}
|
|
2661
2693
|
return out.join("\n");
|
|
2662
2694
|
}
|
|
@@ -2698,7 +2730,7 @@ function ensureBlockSpacing(text) {
|
|
|
2698
2730
|
*/
|
|
2699
2731
|
function normalizeSlackReplyMarkdown(text) {
|
|
2700
2732
|
let normalized = applyPluginFormatMarkdown(text).replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "");
|
|
2701
|
-
normalized =
|
|
2733
|
+
normalized = wrapBareReferences(normalized);
|
|
2702
2734
|
normalized = ensureBlockSpacing(normalized);
|
|
2703
2735
|
return normalized.replace(/\n{3,}/g, "\n\n").trim();
|
|
2704
2736
|
}
|
|
@@ -3201,4 +3233,4 @@ async function saveScheduledAutomationInLock(db, task, current) {
|
|
|
3201
3233
|
await writeScheduledAutomation(db, requireStoredTask(task), current);
|
|
3202
3234
|
}
|
|
3203
3235
|
//#endregion
|
|
3204
|
-
export { persistWithRetry as $,
|
|
3236
|
+
export { persistWithRetry as $, isHumanConversationMessage as $t, formatSlackLink as A, recordAttachmentsDelivered as At, removeReactionFromMessage as B, hydrateConversationMessages as Bt, listAutomationVersions as C, loadConversationProjection as Ct, automationRevision as D, loadTurnRoute as Dt, AutomationConflictError as E, loadTurnProjection as Et, addReactionToMessage as F, recordMcpProviderConnected as Ft, loadTurnCheckpoint as G, settleConversationTitleWork as Gt, slackEntitySchema as H, projectConversationMessages as Ht, getSlackMessagePermalink as I, recordSubscribedReplyRoute as It, completeTurnRecord as J, appendThreadContextMessages as Jt, saveTurnCheckpoint as K, fallbackShortTitle as Kt, openSlackDirectMessage as L, recordToolExecutionStarted as Lt, normalizeSlackStatusText as M, recordAuthorizationCompleted as Mt, slackMention as N, recordAuthorizationRequested as Nt, requireAutomationRevision as O, openConversationProjection as Ot, truncateStatusText as P, recordGuardianActionReviewed as Pt, recordTurnSummary as Q, getConversationMessageSlackTs as Qt, postSlackEphemeralMessage as R, recordTurnRoute as Rt, automationDefinition as S, loadConnectedMcpProviders as St, sameDefinitionValue as T, loadProjection as Tt, slackExternalRefIdSchema as U, persistConversationMessageSummaries as Ut, uploadFilesToConversation as V, persistConversationMessages as Vt, continuableMessages as W, resolveConversationTitle as Wt, getTurnRecord as X, createConversationMemoryService as Xt, failTurnRecord as Y, buildConversationContext as Yt, listTurnSummaries as Z, estimateConversationContextTokens as Zt, listDeletedEventAutomationsCreatedBy as _, trimTrailingAssistantMessages as _t, readScheduledAutomation as a, estimateTextTokens as an, getPiMessageRole as at, saveEventAutomation as b, commitAcceptedReply as bt, scheduledRunId as c, historyItemFromPiMessage as cn, hasRuntimeTurnContext as ct, collectEventAutomationMatchKeys as d, isContinuablePiBoundary as dt, markConversationMessage as en, TurnSliceLimitExceededError as et, createEventAutomation as f, isToolResultError as ft, getEventAutomation as g, stripRuntimeTurnContext as gt, findMatchingEventAutomations as h, retainRuntimeTurnContext as ht, parseScheduledAutomationRow as i, upsertConversationMessage as in, extractAssistantText as it, normalizeSlackReplyMarkdown as j, recordAuthenticationLinked as jt, escapeSlackMrkdwnText as k, recordAgentsInstructionsUpdated as kt, withScheduledAutomationLock as l, piMessageFromHistoryItem as ln, instructionTextForProjection as lt, eventAutomationBelongsToUser as m, normalizeToolNameFromResult as mt, listScheduledAutomations as n, recordDeliveredAssistantMessage as nn, buildTurnErrorResponse as nt, saveScheduledAutomation as o, getAgentContextCompactionTriggerTokens as on, getTerminalAssistantMessages as ot, deleteEventAutomation as p, isToolResultMessage as pt, abandonTurnRecord as q, resolveTaskTitle as qt, listScheduledAutomationsForTeam as r, turnHasReply as rn, isTurnExecutionLimitExceededError as rt, saveScheduledAutomationInLock as s, getAgentContextInputLimitTokens as sn, getUserMessageInstructionText as st, createScheduledAutomation as t, normalizeConversationText as tn, assertTurnToolCallLimit as tt, blockEventAutomation as u, isAssistantMessage as ut, listEventAutomationsForTeam as v, TURN_CONTEXT_TAG as vt, readAutomationVersion as w, loadLastModelProfile as wt, setEventAutomationStatus as x, commitMessages as xt, parseEventAutomationRow as y, ToolInputError as yt, postSlackMessage as z, appendConversationMessages as zt };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-
|
|
2
|
-
import { d as getDb } from "./viewer-
|
|
3
|
-
import {
|
|
4
|
-
import { d as juniorLocationConfigurations } from "./executor-
|
|
5
|
-
import {
|
|
6
|
-
import { tt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-
|
|
7
|
-
import { w as getStateAdapter } from "./profile-
|
|
1
|
+
import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-CdZ1LQJ7.js";
|
|
2
|
+
import { d as getDb } from "./viewer-B7qDM2DM.js";
|
|
3
|
+
import { d as juniorDestinations } from "./agent-invocations-BzRAZ_nj.js";
|
|
4
|
+
import { d as juniorLocationConfigurations } from "./executor-C7bsEF-c.js";
|
|
5
|
+
import { Vt as persistConversationMessages } from "./tasks-Qx6Fos_R.js";
|
|
6
|
+
import { tt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-Cqo6ULp6.js";
|
|
7
|
+
import { w as getStateAdapter } from "./profile-qqt_2di0.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
10
|
import { and, eq, sql } from "drizzle-orm";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-
|
|
2
|
-
import { I as isRecord, t as buildTurnFailureResponse } from "./logging-
|
|
1
|
+
import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-Es79bknZ.js";
|
|
2
|
+
import { I as isRecord, t as buildTurnFailureResponse } from "./logging-CdZ1LQJ7.js";
|
|
3
3
|
import { g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
|
|
4
|
-
import { c as getConversationEventStore, d as getDb } from "./viewer-
|
|
5
|
-
import {
|
|
6
|
-
import { At as listConversationAnnotations } from "./agent-hooks-
|
|
7
|
-
import { G as removedCardSchema, K as resolveMessageCards, W as readMessageCardRefs } from "./conversation-
|
|
8
|
-
import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-
|
|
9
|
-
import { g as markTurnCompleted, h as markTurnClosed } from "./oauth-authorization-
|
|
10
|
-
import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-
|
|
4
|
+
import { c as getConversationEventStore, d as getDb } from "./viewer-B7qDM2DM.js";
|
|
5
|
+
import { Bt as hydrateConversationMessages, en as markConversationMessage } from "./tasks-Qx6Fos_R.js";
|
|
6
|
+
import { At as listConversationAnnotations } from "./agent-hooks-Cqo6ULp6.js";
|
|
7
|
+
import { G as removedCardSchema, K as resolveMessageCards, W as readMessageCardRefs } from "./conversation-mt3yJ09u.js";
|
|
8
|
+
import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-CNAlGOyl.js";
|
|
9
|
+
import { g as markTurnCompleted, h as markTurnClosed } from "./oauth-authorization-Di0KlyoJ.js";
|
|
10
|
+
import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-BN_5S1bx.js";
|
|
11
11
|
//#region src/chat/conversations/pending-cards.ts
|
|
12
12
|
/** Select undelivered cards and load their latest saved facts. */
|
|
13
13
|
async function loadPendingMessageCards(conversationId) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as getConversationEventStore } from "./viewer-
|
|
1
|
+
import { c as getConversationEventStore } from "./viewer-B7qDM2DM.js";
|
|
2
2
|
//#region src/chat/conversations/turn-lifecycle.ts
|
|
3
3
|
/** Persist correlated turn lifecycle facts with retry-safe terminal exclusion. */
|
|
4
4
|
var ConversationTurnLifecycleService = class {
|
|
@@ -34,7 +34,7 @@ function slackSourceForDestination(args) {
|
|
|
34
34
|
* Reads parent Conversations when this Conversation has no Destination.
|
|
35
35
|
*/
|
|
36
36
|
async function resolveConversationRouting(args) {
|
|
37
|
-
const conversationStore = args.conversationStore ?? (await import("./viewer-
|
|
37
|
+
const conversationStore = args.conversationStore ?? (await import("./viewer-B7qDM2DM.js").then((n) => n.s)).getConversationStore();
|
|
38
38
|
const chain = await loadConversationChain(args.conversationId, conversationStore);
|
|
39
39
|
let destination;
|
|
40
40
|
let source;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { n as pluginCatalogRuntime } from "./catalog-runtime-
|
|
2
|
+
import { n as pluginCatalogRuntime } from "./catalog-runtime-jazDa-oO.js";
|
|
3
3
|
import { isDeepStrictEqual } from "node:util";
|
|
4
4
|
//#region src/chat/plugins/validation.ts
|
|
5
5
|
var validation_exports = /* @__PURE__ */ __exportAll({
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as JUNIOR_VERSION } from "./version-
|
|
1
|
+
import { t as JUNIOR_VERSION } from "./version-BvG02ZTN.js";
|
|
2
2
|
export { JUNIOR_VERSION };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { F as normalizeIdentityEmail } from "./logging-
|
|
3
|
-
import { i as getChatConfig } from "./config-
|
|
2
|
+
import { F as normalizeIdentityEmail } from "./logging-CdZ1LQJ7.js";
|
|
3
|
+
import { i as getChatConfig } from "./config-gype19qQ.js";
|
|
4
4
|
import { d as parseSlackTeamId, o as parseActorUserId, u as parseSlackChannelReferenceId } from "./actor-BTtLaeWy.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { c as newConversationEventSchema, l as encodeHistoryPayload, m as usageSchema, o as decodeStoredConversationEvent, r as conversationEventDataSchema, s as historyReplacementSchema } from "./history-
|
|
5
|
+
import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, o as conversationReadColumns, s as juniorConversations } from "./agent-invocations-BzRAZ_nj.js";
|
|
6
|
+
import { _ as juniorConversationEvents, f as juniorConversationParticipants, g as juniorConversationMetrics, h as CONVERSATION_METRICS, p as juniorConversationBindings, t as createJuniorSqlExecutor, y as juniorConversationAnnotations } from "./executor-C7bsEF-c.js";
|
|
7
|
+
import { c as newConversationEventSchema, l as encodeHistoryPayload, m as usageSchema, o as decodeStoredConversationEvent, r as conversationEventDataSchema, s as historyReplacementSchema } from "./history-DlsoHsoe.js";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
import { and, asc, desc, eq, gt, gte, inArray, isNull, lt, lte, ne, or, sql } from "drizzle-orm";
|
|
10
10
|
import { destinationSchema, identitySchema, locationSchema, sourceSchema, userSchema } from "@sentry/junior-plugin-api";
|
|
@@ -731,9 +731,7 @@ var SqlStore = class {
|
|
|
731
731
|
if (existing.parentConversationId !== args.parentConversationId) throw new Error(`Conversation parent changed for ${args.childConversationId}`);
|
|
732
732
|
return;
|
|
733
733
|
}
|
|
734
|
-
|
|
735
|
-
if (!parent) throw new Error(`Conversation parent is missing for ${args.childConversationId}`);
|
|
736
|
-
if (parent.parentConversationId) throw new Error("Recursive agent delegation is not enabled");
|
|
734
|
+
if (!await this.get({ conversationId: args.parentConversationId })) throw new Error(`Conversation parent is missing for ${args.childConversationId}`);
|
|
737
735
|
const child = {
|
|
738
736
|
...emptyConversation({
|
|
739
737
|
conversationId: args.childConversationId,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as getConversationEventStore } from "./viewer-
|
|
3
|
-
import { G as loadTurnCheckpoint, X as getTurnRecord, Y as failTurnRecord } from "./tasks-
|
|
4
|
-
import { w as getStateAdapter } from "./profile-
|
|
5
|
-
import { a as getVercelConversationWorkQueue } from "./job-queue-
|
|
6
|
-
import { n as resolveTurnSessionRouting } from "./turn-session-routing-
|
|
1
|
+
import { Vt as requestConversationWork, jt as ensureConversationWake } from "./agent-runner-BZOjoMlZ.js";
|
|
2
|
+
import { c as getConversationEventStore } from "./viewer-B7qDM2DM.js";
|
|
3
|
+
import { G as loadTurnCheckpoint, X as getTurnRecord, Y as failTurnRecord } from "./tasks-Qx6Fos_R.js";
|
|
4
|
+
import { w as getStateAdapter } from "./profile-qqt_2di0.js";
|
|
5
|
+
import { a as getVercelConversationWorkQueue } from "./job-queue-DQDesz8a.js";
|
|
6
|
+
import { n as resolveTurnSessionRouting } from "./turn-session-routing-DsvU39zW.js";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
//#region src/chat/task-execution/authorized-turn.ts
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { f as escapeXml, i as completeText, r as completeObject, v as isProviderRetryError } from "./client-
|
|
3
|
-
import { C as withLogContext, I as isRecord, L as toOptionalNumber, R as toOptionalString, _ as setSentryUser, b as setTags, d as logException, f as logInfo, n as createChatSdkLogger, o as getActiveTraceId, p as logWarn, t as buildTurnFailureResponse, u as logError, v as setSpanAttributes, w as withSpan } from "./logging-
|
|
4
|
-
import { c as getSlackClientSecret, i as getChatConfig, l as getSlackSigningSecret, n as botConfig, o as getSlackBotToken, s as getSlackClientId, v as normalizeSlackEmojiName } from "./config-
|
|
1
|
+
import { $ as getLatestAgentInvocationForConversation, A as resolveSlackChannelIdFromMessage, B as effectiveTaskOutcomes, C as renderBlockText, D as storeAttachment, M as getConversationInfo, N as listThreadReplies, Nt as getConversationWorkState, O as parseSlackThreadId, Qt as recordFinishedTurnForAutomatedLimit, S as renderAttachmentText, Xt as renderTaskInput, Y as getAgentInvocation, Z as getAgentInvocationResultMessageId, Zt as maybePostAutomatedTurnLimitNotice, _n as AuthorizationFlowDisabledError, _t as pluginEventCatalog, a as buildAuthPauseResponse, at as markAgentInvocationParentMailboxAppended, bn as runDispatchOutcome, bt as appendAndEnqueueInboundMessage, et as isTerminalAgentInvocation, fn as createUserTokenStore, ft as EVENT_WAIT_MS, h as latestProgressStatus, ht as getEventCatalog, j as resolveSlackChannelIdFromThreadId, k as readSlackRawMessageContext, m as PluginCredentialFailureError, mn as RetryableDeliveryError, mt as timerWatchCredentialSubject, n as executeAgentRun, pn as buildSteeringPiMessage, pt as isEventMailboxMetadata, q as createAgentInvocationForResult, r as createContextCompactor, t as createAgentRunner, vn as deliversFinalText, xn as shouldEmitDevAgentTrace, yn as finishedRunReply, yt as appendAndEnqueueExclusiveInboundMessage, z as eventAutomationTriggerAvailable } from "./agent-runner-BZOjoMlZ.js";
|
|
2
|
+
import { f as escapeXml, i as completeText, r as completeObject, v as isProviderRetryError } from "./client-Es79bknZ.js";
|
|
3
|
+
import { C as withLogContext, I as isRecord, L as toOptionalNumber, R as toOptionalString, _ as setSentryUser, b as setTags, d as logException, f as logInfo, n as createChatSdkLogger, o as getActiveTraceId, p as logWarn, t as buildTurnFailureResponse, u as logError, v as setSpanAttributes, w as withSpan } from "./logging-CdZ1LQJ7.js";
|
|
4
|
+
import { c as getSlackClientSecret, i as getChatConfig, l as getSlackSigningSecret, n as botConfig, o as getSlackBotToken, s as getSlackClientId, v as normalizeSlackEmojiName } from "./config-gype19qQ.js";
|
|
5
5
|
import { o as modelIdForProfile, r as defaultModelId } from "./model-profile-BwU8mqwD.js";
|
|
6
6
|
import { a as isUserActor, g as parseSlackMessageTs, i as isActorUserId, l as parseSlackChannelId, n as createSlackActor, o as parseActorUserId, r as createSlackResumeActor, t as createActor } from "./actor-BTtLaeWy.js";
|
|
7
|
-
import { M as createSlackDestination, P as requireSlackDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, u as getConversationStore } from "./viewer-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { f as instructionProvenanceFor } from "./history-
|
|
11
|
-
import { d as credentialContextForActor } from "./registry-
|
|
12
|
-
import { $ as persistWithRetry, $t as
|
|
13
|
-
import { Ct as getSlackFileId, Et as recordSlackAttachment, Ft as SlackActionError, Ht as normalizeSlackConversationId, It as downloadPrivateSlackFile, Pt as lookupSlackUser, Rt as getHeaderString, St as buildSentryConversationUrl, Tt as readAttachmentVisionSummary, Ut as runWithSlackInstallationToken, Vt as isDmChannel, et as verifyTimerWatchCredentialSubject, nt as getDashboardConversationLink, o as getPluginSlackConversationLink, rt as getDashboardObjectIconLink, tt as JUNIOR_THREAD_STATE_TTL_MS, z as cancelSubscriptions, zt as getSlackClient } from "./agent-hooks-
|
|
14
|
-
import { F as isVisionImageMediaType, N as readMessageAttachments } from "./conversation-
|
|
15
|
-
import { E as acquireActiveLock, O as withLock, T as MUTATION_LOCK_TTL_MS, w as getStateAdapter } from "./profile-
|
|
16
|
-
import { a as wasPendingAuthStopped, c as getThreadStopDecision, l as buildDeterministicAssistantMessageId, o as decideSubscribedThreadReply, r as clearPendingAuth, s as getSubscribedReplyPreflightDecision, u as buildDeterministicTurnId } from "./pending-auth-
|
|
17
|
-
import { _ as markTurnFailed, c as CooperativeTurnYieldError, d as getConversationTurnBoundaryError, f as isCooperativeTurnYieldError, g as markTurnCompleted, h as markTurnClosed, l as TurnInputCommitLostError, m as isTurnInputDeferredError, p as isTurnInputCommitLostError, r as getAssistantReplyText, s as ConversationTurnBoundaryError, u as TurnInputDeferredError, v as startActiveTurn } from "./oauth-authorization-
|
|
18
|
-
import { a as EVENT_SYSTEM_ACTOR, i as EVENT_MESSAGE_AUTHOR, o as isEventConversationMessage } from "./prompt-
|
|
19
|
-
import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline } from "./job-queue-
|
|
7
|
+
import { M as createSlackDestination, P as requireSlackDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, u as getConversationStore } from "./viewer-B7qDM2DM.js";
|
|
8
|
+
import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers } from "./agent-invocations-BzRAZ_nj.js";
|
|
9
|
+
import { c as juniorAutomationExecutions, o as juniorSchedulerTasks, u as juniorEventAutomations } from "./executor-C7bsEF-c.js";
|
|
10
|
+
import { f as instructionProvenanceFor } from "./history-DlsoHsoe.js";
|
|
11
|
+
import { d as credentialContextForActor } from "./registry-WOJKAIRI.js";
|
|
12
|
+
import { $ as persistWithRetry, $t as isHumanConversationMessage, A as formatSlackLink, B as removeReactionFromMessage, Bt as hydrateConversationMessages, C as listAutomationVersions, Ct as loadConversationProjection, F as addReactionToMessage, G as loadTurnCheckpoint, It as recordSubscribedReplyRoute, J as completeTurnRecord, Jt as appendThreadContextMessages, K as saveTurnCheckpoint, Kt as fallbackShortTitle, M as normalizeSlackStatusText, Mt as recordAuthorizationCompleted, P as truncateStatusText, Q as recordTurnSummary, Qt as getConversationMessageSlackTs, S as automationDefinition, T as sameDefinitionValue, Tt as loadProjection, Ut as persistConversationMessageSummaries, Vt as persistConversationMessages, Wt as resolveConversationTitle, X as getTurnRecord, Xt as createConversationMemoryService, Y as failTurnRecord, Yt as buildConversationContext, Z as listTurnSummaries, Zt as estimateConversationContextTokens, _ as listDeletedEventAutomationsCreatedBy, _t as trimTrailingAssistantMessages, a as readScheduledAutomation, bt as commitAcceptedReply, en as markConversationMessage, g as getEventAutomation, i as parseScheduledAutomationRow, in as upsertConversationMessage, j as normalizeSlackReplyMarkdown, k as escapeSlackMrkdwnText, l as withScheduledAutomationLock, m as eventAutomationBelongsToUser, nn as recordDeliveredAssistantMessage, nt as buildTurnErrorResponse, p as deleteEventAutomation, q as abandonTurnRecord, rn as turnHasReply, s as saveScheduledAutomationInLock, tn as normalizeConversationText, xt as commitMessages, y as parseEventAutomationRow, z as postSlackMessage } from "./tasks-Qx6Fos_R.js";
|
|
13
|
+
import { Ct as getSlackFileId, Et as recordSlackAttachment, Ft as SlackActionError, Ht as normalizeSlackConversationId, It as downloadPrivateSlackFile, Pt as lookupSlackUser, Rt as getHeaderString, St as buildSentryConversationUrl, Tt as readAttachmentVisionSummary, Ut as runWithSlackInstallationToken, Vt as isDmChannel, et as verifyTimerWatchCredentialSubject, nt as getDashboardConversationLink, o as getPluginSlackConversationLink, rt as getDashboardObjectIconLink, tt as JUNIOR_THREAD_STATE_TTL_MS, z as cancelSubscriptions, zt as getSlackClient } from "./agent-hooks-Cqo6ULp6.js";
|
|
14
|
+
import { F as isVisionImageMediaType, N as readMessageAttachments } from "./conversation-mt3yJ09u.js";
|
|
15
|
+
import { E as acquireActiveLock, O as withLock, T as MUTATION_LOCK_TTL_MS, w as getStateAdapter } from "./profile-qqt_2di0.js";
|
|
16
|
+
import { a as wasPendingAuthStopped, c as getThreadStopDecision, l as buildDeterministicAssistantMessageId, o as decideSubscribedThreadReply, r as clearPendingAuth, s as getSubscribedReplyPreflightDecision, u as buildDeterministicTurnId } from "./pending-auth-CNAlGOyl.js";
|
|
17
|
+
import { _ as markTurnFailed, c as CooperativeTurnYieldError, d as getConversationTurnBoundaryError, f as isCooperativeTurnYieldError, g as markTurnCompleted, h as markTurnClosed, l as TurnInputCommitLostError, m as isTurnInputDeferredError, p as isTurnInputCommitLostError, r as getAssistantReplyText, s as ConversationTurnBoundaryError, u as TurnInputDeferredError, v as startActiveTurn } from "./oauth-authorization-Di0KlyoJ.js";
|
|
18
|
+
import { a as EVENT_SYSTEM_ACTOR, i as EVENT_MESSAGE_AUTHOR, o as isEventConversationMessage } from "./prompt-D_cg2iqi.js";
|
|
19
|
+
import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline } from "./job-queue-DQDesz8a.js";
|
|
20
20
|
import { l as automationListQuerySchema } from "./automation-gznOMaQ2.js";
|
|
21
21
|
import { r as isExperimentalFeatureEnabled } from "./experimental-Qn9rKLgx.js";
|
|
22
22
|
import { c as sumUtcHoursIntoSixHours, m as healthReportSchema, t as webMessageId } from "./web-message-id-xPI_EFSC.js";
|
|
23
|
-
import { C as readAutomationExecutionHours, D as readAutomationExecutions, E as readAutomationExecutionSummaries, O as readAutomationRuns, S as readAutomationExecutionDays, T as readAutomationExecutionStatusHours, _ as markDispatchFailed, a as confirmDispatchMailboxAppend, b as emptyAutomationRunWindows, c as getDispatchInputMessageId, f as isTerminalDispatchStatus, g as markDispatchCompleted, h as markDispatchBlocked, i as claimDispatchMailboxAppend, l as getDispatchRecord, m as markDispatchAwaitingResume, n as scheduleSessionCompletedPluginTasks, s as getDispatchConversationId, t as processPluginTask, u as getDispatchTurnId, v as markDispatchRunning, w as readAutomationExecutionStatusDays, x as readAutomationExecutionByConversationId } from "./task-runner-
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { a as persistThreadState, c as configValueSchema, i as persistThreadRuntimeState, n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState, t as getLocationConfigurationService } from "./thread-state-
|
|
27
|
-
import { a as getPausedTurnRequest, c as getTurnAuthorization, i as createPausedTurns, n as deleteWebAuthorization, s as wakePausedTurn, t as createWebAuthorization } from "./web-authorization-
|
|
28
|
-
import { n as resolveTurnSessionRouting } from "./turn-session-routing-
|
|
29
|
-
import { t as bindSpawnAgent } from "./spawn-
|
|
30
|
-
import { a as persistAuthPauseTurnState, c as getTurnUserSlackMessageTs, d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, n as getAgentTurnDiagnosticsAttributes, o as getTurnUserMessage, r as requireTurnFailureEventId, s as getTurnUserReplyAttachmentContext, t as finalizeFailedTurnReplyWithEvent, u as getInterruptionMarker } from "./turn-failure-response-
|
|
31
|
-
import { r as storeInputImages } from "./images-
|
|
23
|
+
import { C as readAutomationExecutionHours, D as readAutomationExecutions, E as readAutomationExecutionSummaries, O as readAutomationRuns, S as readAutomationExecutionDays, T as readAutomationExecutionStatusHours, _ as markDispatchFailed, a as confirmDispatchMailboxAppend, b as emptyAutomationRunWindows, c as getDispatchInputMessageId, f as isTerminalDispatchStatus, g as markDispatchCompleted, h as markDispatchBlocked, i as claimDispatchMailboxAppend, l as getDispatchRecord, m as markDispatchAwaitingResume, n as scheduleSessionCompletedPluginTasks, s as getDispatchConversationId, t as processPluginTask, u as getDispatchTurnId, v as markDispatchRunning, w as readAutomationExecutionStatusDays, x as readAutomationExecutionByConversationId } from "./task-runner-CIP2asjP.js";
|
|
24
|
+
import { n as getTurnLifecycle, t as ConversationTurnLifecycleService } from "./turn-lifecycle-BzeE4sVD.js";
|
|
25
|
+
import { i as resolveAgentInvocationId, o as AgentRunError, r as enqueueAgentInvocation, s as executeTurn, t as createAgentInvocationWorker } from "./work-D_BBvd4I.js";
|
|
26
|
+
import { a as persistThreadState, c as configValueSchema, i as persistThreadRuntimeState, n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState, t as getLocationConfigurationService } from "./thread-state-BN_5S1bx.js";
|
|
27
|
+
import { a as getPausedTurnRequest, c as getTurnAuthorization, i as createPausedTurns, n as deleteWebAuthorization, s as wakePausedTurn, t as createWebAuthorization } from "./web-authorization-Cqv7bP19.js";
|
|
28
|
+
import { n as resolveTurnSessionRouting } from "./turn-session-routing-DsvU39zW.js";
|
|
29
|
+
import { t as bindSpawnAgent } from "./spawn-DDJ5z9IC.js";
|
|
30
|
+
import { a as persistAuthPauseTurnState, c as getTurnUserSlackMessageTs, d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, n as getAgentTurnDiagnosticsAttributes, o as getTurnUserMessage, r as requireTurnFailureEventId, s as getTurnUserReplyAttachmentContext, t as finalizeFailedTurnReplyWithEvent, u as getInterruptionMarker } from "./turn-failure-response-B1UW2T7a.js";
|
|
31
|
+
import { r as storeInputImages } from "./images-WmrEAtto.js";
|
|
32
32
|
import { z } from "zod";
|
|
33
33
|
import { createHash } from "node:crypto";
|
|
34
34
|
import { and, asc, count, desc, eq, exists, inArray, ne, or, sql } from "drizzle-orm";
|
|
@@ -36,7 +36,7 @@ import { createEventSource, createLocalSource, createSlackSource, createWebSourc
|
|
|
36
36
|
import { unionAll } from "drizzle-orm/pg-core";
|
|
37
37
|
import { del, get, put } from "@vercel/blob";
|
|
38
38
|
import { Message, ThreadImpl, stringifyMarkdown } from "chat";
|
|
39
|
-
import { createSlackAdapter } from "@chat-adapter/slack";
|
|
39
|
+
import { SlackFormatConverter, createSlackAdapter } from "@chat-adapter/slack";
|
|
40
40
|
//#region src/handlers/health.ts
|
|
41
41
|
/** Build Junior's process health value for HTTP and reporting consumers. */
|
|
42
42
|
function readHealthReport() {
|
|
@@ -303,6 +303,167 @@ function createAgentDispatchConversationWorker(options) {
|
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
305
|
//#endregion
|
|
306
|
+
//#region src/chat/agent-invocations/result.ts
|
|
307
|
+
const AGENT_INVOCATION_EVENT_NAMESPACE = "junior";
|
|
308
|
+
const AGENT_INVOCATION_EVENT_TYPE_PREFIX = "agent_invocation.";
|
|
309
|
+
const AGENT_INVOCATION_RESULT_MAX_LENGTH = 12e3;
|
|
310
|
+
/**
|
|
311
|
+
* Return the Inbound message author id for results sent by one Actor.
|
|
312
|
+
* `selectContiguousTurnBatch` in `task-execution/worker.ts` puts messages in
|
|
313
|
+
* one attempt only when their author ids and sources match. Mid-Turn drains
|
|
314
|
+
* take only `interrupt` messages, and results are `defer`. So results never
|
|
315
|
+
* share a Turn and its credentials with another Actor or with watch Events.
|
|
316
|
+
* Keep this id unique per Actor if either rule changes.
|
|
317
|
+
*/
|
|
318
|
+
function resultAuthorId(actor) {
|
|
319
|
+
switch (actor.platform) {
|
|
320
|
+
case "system": return `agent-invocation:system:${actor.name}`;
|
|
321
|
+
case "slack": return `agent-invocation:slack:${actor.teamId}:${actor.userId}`;
|
|
322
|
+
default: return `agent-invocation:${actor.platform}:${actor.userId}`;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Error messages can contain text from tools or providers, so only the status
|
|
327
|
+
* is trusted. The result or error goes in external text.
|
|
328
|
+
*/
|
|
329
|
+
function trustedSummary(invocation, agent) {
|
|
330
|
+
switch (invocation.status) {
|
|
331
|
+
case "completed": return `${agent} finished its task.`;
|
|
332
|
+
case "blocked": return `${agent} is blocked.`;
|
|
333
|
+
case "failed": return `${agent} failed.`;
|
|
334
|
+
case "stopped": return `${agent} was stopped.`;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Build the parent Inbound message for one terminal agent invocation. The
|
|
339
|
+
* child result is model output, so the parent gets it as information, not
|
|
340
|
+
* instructions. Verified details leave out the task. The input of an agent
|
|
341
|
+
* invocation that receives a result holds another child's output, and the
|
|
342
|
+
* parent's own `spawnAgent` call already has the task.
|
|
343
|
+
*/
|
|
344
|
+
function buildResultInboundMessage(invocation, nowMs) {
|
|
345
|
+
const agent = invocation.agentName ? `Child agent "${invocation.agentName}"` : "Child agent";
|
|
346
|
+
const summary = trustedSummary(invocation, agent);
|
|
347
|
+
const metadata = {
|
|
348
|
+
kind: "event",
|
|
349
|
+
event: {
|
|
350
|
+
eventKey: invocation.invocationId,
|
|
351
|
+
eventType: `${AGENT_INVOCATION_EVENT_TYPE_PREFIX}${invocation.status}`,
|
|
352
|
+
identifier: invocation.invocationId,
|
|
353
|
+
namespace: AGENT_INVOCATION_EVENT_NAMESPACE,
|
|
354
|
+
trustedSummary: summary
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
return {
|
|
358
|
+
conversationId: invocation.parentConversationId,
|
|
359
|
+
createdAtMs: invocation.terminalAtMs,
|
|
360
|
+
delivery: "defer",
|
|
361
|
+
inboundMessageId: getAgentInvocationResultMessageId(invocation.invocationId),
|
|
362
|
+
input: {
|
|
363
|
+
authorId: resultAuthorId(invocation.actor),
|
|
364
|
+
metadata,
|
|
365
|
+
text: renderTaskInput({
|
|
366
|
+
about: agent,
|
|
367
|
+
instructions: "A child agent that you started has ended. Its status tells how it ended. Use its result to continue the work in this conversation. Do not repeat work that the child agent already did.",
|
|
368
|
+
trustedSummary: summary,
|
|
369
|
+
verifiedDetails: {
|
|
370
|
+
conversation_id: invocation.childConversationId,
|
|
371
|
+
...invocation.agentName ? { agent_name: invocation.agentName } : void 0,
|
|
372
|
+
status: invocation.status
|
|
373
|
+
},
|
|
374
|
+
externalText: invocation.status === "completed" ? invocation.result : invocation.errorMessage,
|
|
375
|
+
externalTextMaxLength: AGENT_INVOCATION_RESULT_MAX_LENGTH
|
|
376
|
+
})
|
|
377
|
+
},
|
|
378
|
+
receivedAtMs: nowMs,
|
|
379
|
+
source: "event"
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Append one terminal agent invocation result to the parent mailbox and wake
|
|
384
|
+
* the parent. Repeat calls are safe.
|
|
385
|
+
*
|
|
386
|
+
* Results do not go through `admitAutomatedTurn`, so the automated-turn limit
|
|
387
|
+
* never drops them. Result Turns still count toward that limit.
|
|
388
|
+
* TODO(dcramer): Add a per-parent total invocation limit as the loop guard
|
|
389
|
+
* for spawn -> result -> spawn chains (#881).
|
|
390
|
+
*/
|
|
391
|
+
async function enqueueAgentInvocationResult(invocation, options) {
|
|
392
|
+
if (invocation.parentMailboxStatus !== "pending") return;
|
|
393
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
394
|
+
await appendAndEnqueueInboundMessage({
|
|
395
|
+
message: buildResultInboundMessage(invocation, nowMs),
|
|
396
|
+
queue: options.queue,
|
|
397
|
+
queueDelayMs: EVENT_WAIT_MS,
|
|
398
|
+
state: options.state
|
|
399
|
+
});
|
|
400
|
+
await markAgentInvocationParentMailboxAppended(invocation.invocationId, nowMs);
|
|
401
|
+
}
|
|
402
|
+
function resultInvocationId(message) {
|
|
403
|
+
const metadata = message.input.metadata;
|
|
404
|
+
return isEventMailboxMetadata(metadata) && metadata.event.namespace === AGENT_INVOCATION_EVENT_NAMESPACE && metadata.event.eventType.startsWith(AGENT_INVOCATION_EVENT_TYPE_PREFIX) ? metadata.event.identifier : void 0;
|
|
405
|
+
}
|
|
406
|
+
/** Read one result message's agent invocation and check its parent. */
|
|
407
|
+
async function getResultInvocation(message, invocationId) {
|
|
408
|
+
const invocation = await getAgentInvocation(invocationId);
|
|
409
|
+
if (!invocation || !isTerminalAgentInvocation(invocation) || invocation.parentConversationId !== message.conversationId) throw new Error(`Agent invocation result ${invocationId} does not belong to ${message.conversationId}`);
|
|
410
|
+
return invocation;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Give agent invocation results that reach a child Conversation to that
|
|
414
|
+
* child. A child Conversation has no Location, so it cannot run an Event
|
|
415
|
+
* Turn. Each result starts a new agent invocation on the child instead, and
|
|
416
|
+
* that invocation reports to the child's parent. Returns undefined for work
|
|
417
|
+
* that is not a result for a child Conversation.
|
|
418
|
+
*/
|
|
419
|
+
async function startAgentInvocationsForChildResults(context, options) {
|
|
420
|
+
const messages = context.attempt.messages;
|
|
421
|
+
const invocationIds = messages.map(resultInvocationId);
|
|
422
|
+
if (messages.length === 0 || invocationIds.some((id) => !id)) return;
|
|
423
|
+
const latest = await getLatestAgentInvocationForConversation(context.conversationId);
|
|
424
|
+
if (!latest) return;
|
|
425
|
+
if (latest.status === "stopped") {
|
|
426
|
+
await context.attempt.ack();
|
|
427
|
+
return { status: "completed" };
|
|
428
|
+
}
|
|
429
|
+
for (const [index, message] of messages.entries()) {
|
|
430
|
+
const result = await getResultInvocation(message, invocationIds[index]);
|
|
431
|
+
if (result.parentMailboxStatus === "skipped") continue;
|
|
432
|
+
const invocation = await createAgentInvocationForResult({
|
|
433
|
+
input: message.input.text.trim(),
|
|
434
|
+
latest,
|
|
435
|
+
resultInvocationId: result.invocationId
|
|
436
|
+
});
|
|
437
|
+
await enqueueAgentInvocation(invocation, options);
|
|
438
|
+
}
|
|
439
|
+
await context.attempt.ack();
|
|
440
|
+
return { status: "completed" };
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Run each agent invocation result as the Actor that triggered the child, user
|
|
444
|
+
* or system. This is on purpose: the result continues that Actor's work. The
|
|
445
|
+
* Actor comes from SQL, not from mailbox metadata, so the parent Turn has the
|
|
446
|
+
* same authority it had at spawn time.
|
|
447
|
+
*
|
|
448
|
+
* TODO(dcramer): Pass the delegated credential subject of a system Actor, such
|
|
449
|
+
* as a timer watch Turn, when system Turns can spawn children that need it.
|
|
450
|
+
*/
|
|
451
|
+
async function withAgentInvocationResultActors(work) {
|
|
452
|
+
if (work.kind !== "mailbox") return work;
|
|
453
|
+
return {
|
|
454
|
+
kind: "mailbox",
|
|
455
|
+
batch: await Promise.all(work.batch.map(async (entry) => {
|
|
456
|
+
const invocationId = resultInvocationId(entry.message);
|
|
457
|
+
if (!invocationId) return entry;
|
|
458
|
+
const invocation = await getResultInvocation(entry.message, invocationId);
|
|
459
|
+
return {
|
|
460
|
+
...entry,
|
|
461
|
+
actor: invocation.actor
|
|
462
|
+
};
|
|
463
|
+
}))
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
//#endregion
|
|
306
467
|
//#region src/chat/attachments/vercel.ts
|
|
307
468
|
/** Store private conversation attachments in Vercel Blob. */
|
|
308
469
|
function createVercelAttachmentStorage() {
|
|
@@ -562,10 +723,32 @@ function readRawBlocks(raw) {
|
|
|
562
723
|
if (!raw || typeof raw !== "object") return void 0;
|
|
563
724
|
return raw.blocks;
|
|
564
725
|
}
|
|
726
|
+
function readRawText(raw) {
|
|
727
|
+
if (!raw || typeof raw !== "object") return "";
|
|
728
|
+
const text = raw.text;
|
|
729
|
+
return typeof text === "string" ? text : "";
|
|
730
|
+
}
|
|
731
|
+
const slackFormat = new SlackFormatConverter();
|
|
732
|
+
const SLACK_ENTITY_RE = /<[@#][A-Z0-9]+(?:\|[^<>]*)?>/g;
|
|
733
|
+
const ENTITY_PLACEHOLDER_RE = /\uE000(\d+)\uE001/g;
|
|
734
|
+
/**
|
|
735
|
+
* Convert Slack mrkdwn to Markdown and keep user and channel mentions as
|
|
736
|
+
* `<@U123>` and `<#C123|name>`.
|
|
737
|
+
*
|
|
738
|
+
* The SDK conversion turns `<@U123>` into a bare `@U123`. That is not a
|
|
739
|
+
* mention when the agent copies it, and it does not say what the ID is.
|
|
740
|
+
* Private-use placeholders keep each token out of the conversion.
|
|
741
|
+
*/
|
|
742
|
+
function renderSlackMrkdwn(mrkdwn) {
|
|
743
|
+
const entities = [];
|
|
744
|
+
return stringifyMarkdown(slackFormat.toAst(mrkdwn.replace(SLACK_ENTITY_RE, (entity) => `\uE000${entities.push(entity) - 1}\uE001`))).replace(ENTITY_PLACEHOLDER_RE, (_, index) => entities[Number(index)]).trim();
|
|
745
|
+
}
|
|
565
746
|
function renderTopLevelText(message) {
|
|
566
747
|
const blocks = readRawBlocks(message.raw);
|
|
567
748
|
const blockText = renderBlockText(blocks);
|
|
568
749
|
if (Array.isArray(blocks) && blocks.some((block) => block?.type === "section") && blockText) return blockText;
|
|
750
|
+
const rawText = readRawText(message.raw);
|
|
751
|
+
if (rawText.trim()) return renderSlackMrkdwn(rawText);
|
|
569
752
|
if (message.formatted.children.length > 0) return stringifyMarkdown(message.formatted).trim();
|
|
570
753
|
return message.text.trim() || blockText;
|
|
571
754
|
}
|
|
@@ -4136,7 +4319,8 @@ function resolveSlackConversationContext(input) {
|
|
|
4136
4319
|
return {
|
|
4137
4320
|
type,
|
|
4138
4321
|
...name ? { name } : void 0,
|
|
4139
|
-
...visibility ? { visibility } : void 0
|
|
4322
|
+
...visibility ? { visibility } : void 0,
|
|
4323
|
+
...input.botUserId ? { botUserId: input.botUserId } : void 0
|
|
4140
4324
|
};
|
|
4141
4325
|
}
|
|
4142
4326
|
/** Build Slack conversation facts from Junior's persisted Slack thread id. */
|
|
@@ -4361,6 +4545,7 @@ function createSlackTurn(deps) {
|
|
|
4361
4545
|
const destination = requireSlackDestination(options.destination, "Slack reply execution");
|
|
4362
4546
|
const slackChannelType = options.execution ? resolveSlackChannelTypeFromMessage(message) : await resolveSlackChannelType(message, channelId);
|
|
4363
4547
|
const slackConversation = resolveSlackConversationContext({
|
|
4548
|
+
botUserId: deps.getSlackAdapter().botUserId,
|
|
4364
4549
|
channelId,
|
|
4365
4550
|
channelName,
|
|
4366
4551
|
channelType: slackChannelType
|
|
@@ -7220,7 +7405,13 @@ function createConversationWork(options) {
|
|
|
7220
7405
|
},
|
|
7221
7406
|
runTurn: runtime.runDispatchTurn
|
|
7222
7407
|
});
|
|
7223
|
-
const invocationWorker = createAgentInvocationWorker(options.agentRunner
|
|
7408
|
+
const invocationWorker = createAgentInvocationWorker(options.agentRunner, {
|
|
7409
|
+
enqueueResult: async (invocation) => await enqueueAgentInvocationResult(invocation, {
|
|
7410
|
+
queue: options.queue,
|
|
7411
|
+
state: options.state
|
|
7412
|
+
}),
|
|
7413
|
+
maxAgentDepth: botConfig.maxAgentDepth
|
|
7414
|
+
});
|
|
7224
7415
|
const conversationTurnWorker = createConversationTurnWorker(options.agentRunner, createSlackSystemTurnDelivery({
|
|
7225
7416
|
getSlackAdapter: options.getSlackAdapter,
|
|
7226
7417
|
state: options.state
|
|
@@ -7232,8 +7423,13 @@ function createConversationWork(options) {
|
|
|
7232
7423
|
throw new Error(`Conversation ${context.conversationId} has a ${destination.platform} destination but no matching conversation worker`);
|
|
7233
7424
|
};
|
|
7234
7425
|
const run = async (context) => {
|
|
7426
|
+
const childResults = await startAgentInvocationsForChildResults(context, {
|
|
7427
|
+
queue: options.queue,
|
|
7428
|
+
state: options.state
|
|
7429
|
+
});
|
|
7430
|
+
if (childResults) return childResults;
|
|
7235
7431
|
const mailboxTurn = await resolveMailboxTurnWork(context);
|
|
7236
|
-
if (mailboxTurn) return await conversationTurnWorker(context, mailboxTurn);
|
|
7432
|
+
if (mailboxTurn) return await conversationTurnWorker(context, await withAgentInvocationResultActors(mailboxTurn));
|
|
7237
7433
|
const invocationId = await resolveAgentInvocationId(context);
|
|
7238
7434
|
if (invocationId) return await invocationWorker(context, invocationId);
|
|
7239
7435
|
const dispatchId = await resolveAgentDispatchId(context);
|
|
@@ -7466,4 +7662,4 @@ async function appendAndEnqueueWebMessage(input, options) {
|
|
|
7466
7662
|
};
|
|
7467
7663
|
}
|
|
7468
7664
|
//#endregion
|
|
7469
|
-
export { withNormalizedThreadId as A,
|
|
7665
|
+
export { withNormalizedThreadId as A, enqueueAgentDispatch as B, buildSlackInboundMessage as C, isSlackMessageStopped as D, verifySlackSignature as E, parseContent as F, readHealthReport as H, renderSlackObjectCard as I, createVercelAttachmentStorage as L, legacyWebMailboxMetadataSchema as M, THREAD_OPTOUT_ACK as N, stopSlackThread as O, startProcessingReaction as P, enqueueAgentInvocationResult as R, recordSkippedConversationMessage as S, runWithSlackInstallation as T, GET as V, readViewerAutomationRuns as _, recordWebConversationActivity as a, readViewerAutomations as b, createProductionSlackWebhookServices as c, resolveSlackConversationContextFromThreadId as d, createSlackWebApiStatusSender as f, readViewerAutomationExecutions as g, readConversationSourceTask as h, createConversationId as i, getAuthPausedConversationTurnId as j, normalizeIncomingSlackThreadId as k, getProductionSlackAdapter as l, deleteViewerTask as m, conversationTurnIdForMessage as n, webActorFromEmail as o, ViewerTaskNotFoundError as p, createAndEnqueueConversation as r, createProductionConversationWorkOptions as s, appendAndEnqueueWebMessage as t, formatSlackConversationRedactedLabel as u, readViewerAutomationSummary as v, clearSlackPendingReactions as w, resolveViewerTaskCandidate as x, readViewerAutomationVersions as y, AGENT_DISPATCH_MAX_AGE_MS as z };
|