@sentry/junior 0.245.0 → 0.247.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-BEbNsG87.js → admin-BGwaqDMs.js} +1 -1
- package/dist/{agent-hooks-Caa0Qh_Q.js → agent-hooks-C72ByH0C.js} +11 -11
- package/dist/{agent-invocations-BO6ddZax.js → agent-invocations-D_YoNnAn.js} +8 -2
- package/dist/{agent-runner-BEuPFbbv.js → agent-runner-DsAFAKKs.js} +822 -2524
- package/dist/api/schema.d.ts +23 -1
- package/dist/api/schema.js +3 -3
- package/dist/api.js +82 -21
- package/dist/{app-BYB7szGb.d.ts → app-4t4mPTdS.d.ts} +8 -1
- package/dist/app.d.ts +1 -1
- package/dist/app.js +37 -68
- package/dist/assistant-reply-ChOzcTBS.js +45 -0
- package/dist/{briefs-DFAh_jTW.js → briefs-Dc7qZrhc.js} +4 -4
- package/dist/{catalog-runtime-wmq_fqff.js → catalog-runtime-DS1k7fUG.js} +1 -1
- package/dist/cli/chat.js +25 -15
- 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-Bn9SRFCi.js → client-BVnfNd3D.js} +2 -2
- package/dist/{config-_XAINZMN.js → config-CgWvImQL.js} +2 -2
- package/dist/{conversation-CvBG57Io.js → conversation-CYsbVFLx.js} +71 -1
- package/dist/{conversation-privacy-BN5SGxsF.js → conversation-privacy-D3TdVM9H.js} +1 -1
- package/dist/{credential-sync-BvaUm6HQ.js → credential-sync-DLw3jkv-.js} +14 -14
- package/dist/{executor-CFIqoCNJ.js → executor-DQazjeGA.js} +3 -3
- package/dist/{images-Ci43I3ek.js → images-C3e5E-p_.js} +4 -21
- package/dist/instrumentation.js +2 -2
- package/dist/{job-queue-CGicV7x6.js → job-queue-BEUqRhjC.js} +1 -1
- package/dist/{logging-Bs3dV81s.js → logging-CZEc8_v4.js} +1 -1
- package/dist/message-BIJa7lKh.js +59 -0
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-authorization-COzWmMjO.js → oauth-authorization-BA4Dt6a7.js} +1 -45
- package/dist/{oauth-callback-server-17c9_39v.js → oauth-callback-server-R9OSdLP1.js} +2 -2
- package/dist/{pending-auth-Bnhg7Q9k.js → pending-auth-Oo5AQhaf.js} +2 -2
- package/dist/{profile-BA471c-l.js → profile-aVLDAirh.js} +4 -4
- package/dist/{prompt-C9Q9cjD3.js → prompt-ZG1UCxjF.js} +1 -1
- package/dist/{registry-BYNOFO6e.js → registry-CtaDOOM5.js} +1 -1
- package/dist/{resolve-rpz8No2i.js → resolve-Bdw4hu7s.js} +2 -2
- package/dist/result-DNgmkASh.js +463 -0
- package/dist/{runner-C8DRk9X6.js → runner-BUSScEu5.js} +11 -10
- package/dist/{sandbox-egress-signals-B8hurjFt.js → sandbox-egress-signals-E9r8bf9G.js} +1 -1
- package/dist/{schema-WRgR9EL6.js → schema-tyd6hALh.js} +23 -3
- package/dist/session-stop-CAhBfBUT.js +782 -0
- package/dist/{skills-C4yrD2NR.js → skills-DQy-mmBC.js} +2 -2
- package/dist/{spawn-CdAaTXrY.js → spawn-DQ_MVWZ6.js} +3 -2
- package/dist/store-DjLA8GKs.js +1417 -0
- package/dist/{task-queue-BBxHzlIB.js → task-queue-BT2h_t8I.js} +3 -3
- package/dist/{task-runner-BqFapTjs.js → task-runner-CiPepjIB.js} +11 -11
- package/dist/{tasks-Ddd7OAkp.js → tasks-DMmRrIVl.js} +9 -9
- package/dist/{thread-state-DqErwbA8.js → thread-state-ehZYGpX9.js} +7 -7
- package/dist/{turn-failure-response-DtL1-fOl.js → turn-failure-response-D7J10z7l.js} +9 -9
- package/dist/{turn-lifecycle-B5pzyD6W.js → turn-lifecycle-Buswqs90.js} +1 -1
- package/dist/{turn-session-routing-D6pTU5uF.js → turn-session-routing-Bw-yiSb4.js} +1 -1
- package/dist/{validation-BAzlyNIc.js → validation-DTguegIe.js} +1 -1
- package/dist/{version-CiXDH3oe.js → version-BrZSE5du.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-wCn8xneI.js → viewer-BlAozHer.js} +4 -4
- package/dist/{web-authorization-d5MtGpfG.js → web-authorization-DwyTlkAg.js} +6 -6
- package/dist/{web-input-BZTiCtvP.js → web-input-DSYxI7Wi.js} +77 -378
- package/dist/{work-4QPqTd5_.js → work-CRBXkJoU.js} +96 -13
- package/dist/{worker-mc62tybz.js → worker-BVJKM9Ja.js} +7 -7
- package/migrations/0053_conversation_stopped_at.sql +1 -0
- package/migrations/0054_flowery_rage.sql +1 -0
- package/migrations/meta/0053_snapshot.json +3771 -0
- package/migrations/meta/0054_snapshot.json +3777 -0
- package/migrations/meta/_journal.json +14 -0
- package/package.json +5 -4
|
@@ -1,38 +1,43 @@
|
|
|
1
|
-
import { A as resolveSlackChannelIdFromMessage, B as effectiveTaskOutcomes, C as renderBlockText,
|
|
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 { A as resolveSlackChannelIdFromMessage, B as effectiveTaskOutcomes, C as renderBlockText, D as storeAttachment, Ft as createUserTokenStore, It as buildSteeringPiMessage, Lt as withoutSavedSteeringMessages, M as getConversationInfo, N as listThreadReplies, O as parseSlackThreadId, Rt as RetryableDeliveryError, S as renderAttachmentText, Ut as shouldEmitDevAgentTrace, Vt as AuthorizationFlowDisabledError, a as buildAuthPauseResponse, h as latestProgressStatus, j as resolveSlackChannelIdFromThreadId, k as readSlackRawMessageContext, m as PluginCredentialFailureError, n as executeAgentRun, r as createContextCompactor, t as createAgentRunner, z as eventAutomationTriggerAvailable } from "./agent-runner-DsAFAKKs.js";
|
|
2
|
+
import { f as escapeXml, i as completeText, r as completeObject, v as isProviderRetryError } from "./client-BVnfNd3D.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-CZEc8_v4.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-CgWvImQL.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 { c as juniorIdentities, d as juniorDestinations, l as juniorUsers } from "./agent-invocations-
|
|
9
|
-
import { c as juniorAutomationExecutions, o as juniorSchedulerTasks, u as juniorEventAutomations } from "./executor-
|
|
7
|
+
import { M as createSlackDestination, P as requireSlackDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, u as getConversationStore } from "./viewer-BlAozHer.js";
|
|
8
|
+
import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers } from "./agent-invocations-D_YoNnAn.js";
|
|
9
|
+
import { c as juniorAutomationExecutions, o as juniorSchedulerTasks, u as juniorEventAutomations } from "./executor-DQazjeGA.js";
|
|
10
10
|
import { f as instructionProvenanceFor } from "./history-Nte1oVed.js";
|
|
11
|
-
import { d as credentialContextForActor } from "./registry-
|
|
12
|
-
import { $ as listTurnSummaries, $t as estimateConversationContextTokens, Ct as commitMessages, D as sameDefinitionValue, Dt as loadProjection, Gt as persistConversationMessageSummaries, H as removeReactionFromMessage, Ht as hydrateConversationMessages, I as truncateStatusText, J as saveTurnCheckpoint, Jt as fallbackShortTitle, Kt as resolveConversationTitle, L as addReactionToMessage, M as formatSlackLink, N as normalizeSlackReplyMarkdown, P as normalizeSlackStatusText, Pt as recordAuthorizationCompleted, Q as getTurnRecord, Qt as createConversationMemoryService, Rt as recordSubscribedReplyRoute, St as commitAcceptedReply, T as listAutomationVersions, Tt as loadConversationProjection, Ut as persistConversationMessages, V as postSlackMessage, X as completeTurnRecord, Xt as appendThreadContextMessages, Y as abandonTurnRecord, Z as failTurnRecord, Zt as buildConversationContext, _ as listDeletedEventAutomationsCreatedBy, a as readScheduledAutomation, an as turnHasReply, en as getConversationMessageSlackTs, et as recordTurnSummary, g as getEventAutomation, i as parseScheduledAutomationRow, in as recordDeliveredAssistantMessage, it as buildTurnErrorResponse, j as escapeSlackMrkdwnText, l as withScheduledAutomationLock, m as eventAutomationBelongsToUser, nn as markConversationMessage, on as upsertConversationMessage, p as deleteEventAutomation, q as loadTurnCheckpoint, rn as normalizeConversationText, s as saveScheduledAutomationInLock, tn as isHumanConversationMessage, tt as persistWithRetry, w as automationDefinition, y as parseEventAutomationRow, yt as trimTrailingAssistantMessages } from "./tasks-
|
|
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 {
|
|
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 {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
11
|
+
import { d as credentialContextForActor } from "./registry-CtaDOOM5.js";
|
|
12
|
+
import { $ as listTurnSummaries, $t as estimateConversationContextTokens, Ct as commitMessages, D as sameDefinitionValue, Dt as loadProjection, Gt as persistConversationMessageSummaries, H as removeReactionFromMessage, Ht as hydrateConversationMessages, I as truncateStatusText, J as saveTurnCheckpoint, Jt as fallbackShortTitle, Kt as resolveConversationTitle, L as addReactionToMessage, M as formatSlackLink, N as normalizeSlackReplyMarkdown, P as normalizeSlackStatusText, Pt as recordAuthorizationCompleted, Q as getTurnRecord, Qt as createConversationMemoryService, Rt as recordSubscribedReplyRoute, St as commitAcceptedReply, T as listAutomationVersions, Tt as loadConversationProjection, Ut as persistConversationMessages, V as postSlackMessage, X as completeTurnRecord, Xt as appendThreadContextMessages, Y as abandonTurnRecord, Z as failTurnRecord, Zt as buildConversationContext, _ as listDeletedEventAutomationsCreatedBy, a as readScheduledAutomation, an as turnHasReply, en as getConversationMessageSlackTs, et as recordTurnSummary, g as getEventAutomation, i as parseScheduledAutomationRow, in as recordDeliveredAssistantMessage, it as buildTurnErrorResponse, j as escapeSlackMrkdwnText, l as withScheduledAutomationLock, m as eventAutomationBelongsToUser, nn as markConversationMessage, on as upsertConversationMessage, p as deleteEventAutomation, q as loadTurnCheckpoint, rn as normalizeConversationText, s as saveScheduledAutomationInLock, tn as isHumanConversationMessage, tt as persistWithRetry, w as automationDefinition, y as parseEventAutomationRow, yt as trimTrailingAssistantMessages } from "./tasks-DMmRrIVl.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-C72ByH0C.js";
|
|
14
|
+
import { L as isVisionImageMediaType, P as readMessageAttachments } from "./conversation-CYsbVFLx.js";
|
|
15
|
+
import { E as acquireActiveLock, O as withLock, T as MUTATION_LOCK_TTL_MS, w as getStateAdapter } from "./profile-aVLDAirh.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-Oo5AQhaf.js";
|
|
17
|
+
import { a as TurnInputDeferredError, c as isTurnInputCommitLostError, d as markTurnCompleted, f as markTurnFailed, i as TurnInputCommitLostError, l as isTurnInputDeferredError, n as ConversationTurnBoundaryError, o as getConversationTurnBoundaryError, p as startActiveTurn, r as CooperativeTurnYieldError, s as isCooperativeTurnYieldError, u as markTurnClosed } from "./oauth-authorization-BA4Dt6a7.js";
|
|
18
|
+
import { n as getAssistantReplyText } from "./assistant-reply-ChOzcTBS.js";
|
|
19
|
+
import { A as recordFinishedTurnForAutomatedLimit, F as finishedRunReply, P as deliversFinalText, R as runDispatchOutcome, c as timerWatchCredentialSubject, i as skipInputBeforeConversationStop, k as maybePostAutomatedTurnLimitNotice, l as getEventCatalog, s as isEventMailboxMetadata, v as automationEventCatalog } from "./session-stop-CAhBfBUT.js";
|
|
20
|
+
import { a as EVENT_SYSTEM_ACTOR, o as isEventConversationMessage } from "./prompt-ZG1UCxjF.js";
|
|
21
|
+
import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline } from "./job-queue-BEUqRhjC.js";
|
|
22
|
+
import { E as stopConversationWork, g as getConversationWorkState, h as getConversation, m as ensureConversationWake, n as appendAndEnqueueExclusiveInboundMessage, r as appendAndEnqueueInboundMessage, w as requestConversationWork } from "./store-DjLA8GKs.js";
|
|
20
23
|
import { l as automationListQuerySchema } from "./automation-gznOMaQ2.js";
|
|
21
24
|
import { r as isExperimentalFeatureEnabled } from "./experimental-Qn9rKLgx.js";
|
|
22
25
|
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 {
|
|
27
|
-
import { a as
|
|
28
|
-
import { n as
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
26
|
+
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-CiPepjIB.js";
|
|
27
|
+
import { a as withAgentInvocationResultActors, c as resolveMailboxTurnWork, f as joinMailboxText, i as startAgentInvocationsForChildInput, l as sourceFromTurnInput, o as getAuthPausedConversationTurnId, s as getEventBatchDelayMs, t as enqueueAgentInvocationResult, u as turnInputFactsFromConversationMessage } from "./result-DNgmkASh.js";
|
|
28
|
+
import { n as getTurnLifecycle, t as ConversationTurnLifecycleService } from "./turn-lifecycle-Buswqs90.js";
|
|
29
|
+
import { i as resolveAgentInvocationId, o as AgentRunError, s as executeTurn, t as createAgentInvocationWorker } from "./work-CRBXkJoU.js";
|
|
30
|
+
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-ehZYGpX9.js";
|
|
31
|
+
import { a as getPausedTurnRequest, c as getTurnAuthorization, i as createPausedTurns, n as deleteWebAuthorization, s as wakePausedTurn, t as createWebAuthorization } from "./web-authorization-DwyTlkAg.js";
|
|
32
|
+
import { n as resolveTurnSessionRouting } from "./turn-session-routing-Bw-yiSb4.js";
|
|
33
|
+
import { t as bindMessageAgent } from "./message-BIJa7lKh.js";
|
|
34
|
+
import { t as bindSpawnAgent } from "./spawn-DQ_MVWZ6.js";
|
|
35
|
+
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-D7J10z7l.js";
|
|
36
|
+
import { r as storeInputImages } from "./images-C3e5E-p_.js";
|
|
32
37
|
import { z } from "zod";
|
|
33
38
|
import { createHash } from "node:crypto";
|
|
34
39
|
import { and, asc, count, desc, eq, exists, inArray, ne, or, sql } from "drizzle-orm";
|
|
35
|
-
import {
|
|
40
|
+
import { createSlackSource, createWebSource, localDestinationSchema, objectFactFields, objectPresentation, objectTypeSchema } from "@sentry/junior-plugin-api";
|
|
36
41
|
import { unionAll } from "drizzle-orm/pg-core";
|
|
37
42
|
import { del, get, put } from "@vercel/blob";
|
|
38
43
|
import { Message, ThreadImpl, stringifyMarkdown } from "chat";
|
|
@@ -303,181 +308,6 @@ function createAgentDispatchConversationWorker(options) {
|
|
|
303
308
|
};
|
|
304
309
|
}
|
|
305
310
|
//#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 the trusted
|
|
327
|
-
* summary in the mailbox metadata has only the status.
|
|
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
|
-
* Render the parent agent input for one terminal agent invocation. A result
|
|
339
|
-
* answers work that the parent gave away, so it is not a task. The child runs
|
|
340
|
-
* as the same Actor with the same tools, so its output is passed as-is. A
|
|
341
|
-
* child cannot reach the user, so its output never gives user approval. Only
|
|
342
|
-
* the task title is shown: the parent's `spawnAgent` call already has the
|
|
343
|
-
* task.
|
|
344
|
-
*/
|
|
345
|
-
const RESULT_NEXT_STEP = {
|
|
346
|
-
completed: "Use this result to continue the work in this conversation. Do not repeat work that the child agent already did.",
|
|
347
|
-
blocked: "The child agent did not finish its task. If you still need this work, use spawnAgent again, or tell the user what is blocked.",
|
|
348
|
-
failed: "The child agent did not finish its task. If you still need this work, use spawnAgent again, or tell the user what is blocked.",
|
|
349
|
-
stopped: "The child agent was stopped before it finished. Do not start this work again unless the user asks."
|
|
350
|
-
};
|
|
351
|
-
function renderResultInput(invocation, summary) {
|
|
352
|
-
const output = (invocation.status === "completed" ? invocation.result : invocation.errorMessage).trim().slice(0, AGENT_INVOCATION_RESULT_MAX_LENGTH);
|
|
353
|
-
const outputLabel = invocation.status === "completed" ? "Result" : "Error";
|
|
354
|
-
return [
|
|
355
|
-
"[agent result]",
|
|
356
|
-
"",
|
|
357
|
-
"This is the result of a child agent that you started. It is not a message from a person, so it does not give user approval.",
|
|
358
|
-
"",
|
|
359
|
-
summary,
|
|
360
|
-
...invocation.title ? [`Task: ${invocation.title}`] : [],
|
|
361
|
-
`Child conversation: ${invocation.childConversationId}`,
|
|
362
|
-
"",
|
|
363
|
-
`${outputLabel}:`,
|
|
364
|
-
output || "(empty)",
|
|
365
|
-
"",
|
|
366
|
-
RESULT_NEXT_STEP[invocation.status]
|
|
367
|
-
].join("\n");
|
|
368
|
-
}
|
|
369
|
-
/** Build the parent Inbound message for one terminal agent invocation. */
|
|
370
|
-
function buildResultInboundMessage(invocation, nowMs) {
|
|
371
|
-
const summary = trustedSummary(invocation, invocation.agentName ? `Child agent "${invocation.agentName}"` : "Child agent");
|
|
372
|
-
const metadata = {
|
|
373
|
-
kind: "event",
|
|
374
|
-
event: {
|
|
375
|
-
eventKey: invocation.invocationId,
|
|
376
|
-
eventType: `${AGENT_INVOCATION_EVENT_TYPE_PREFIX}${invocation.status}`,
|
|
377
|
-
identifier: invocation.invocationId,
|
|
378
|
-
namespace: AGENT_INVOCATION_EVENT_NAMESPACE,
|
|
379
|
-
trustedSummary: summary
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
return {
|
|
383
|
-
conversationId: invocation.parentConversationId,
|
|
384
|
-
createdAtMs: invocation.terminalAtMs,
|
|
385
|
-
delivery: "defer",
|
|
386
|
-
inboundMessageId: getAgentInvocationResultMessageId(invocation.invocationId),
|
|
387
|
-
input: {
|
|
388
|
-
authorId: resultAuthorId(invocation.actor),
|
|
389
|
-
metadata,
|
|
390
|
-
text: renderResultInput(invocation, summary)
|
|
391
|
-
},
|
|
392
|
-
receivedAtMs: nowMs,
|
|
393
|
-
source: "event"
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Append one terminal agent invocation result to the parent mailbox and wake
|
|
398
|
-
* the parent. Repeat calls are safe.
|
|
399
|
-
*
|
|
400
|
-
* Results do not go through `admitAutomatedTurn`, so the automated-turn limit
|
|
401
|
-
* never drops them. Result Turns still count toward that limit.
|
|
402
|
-
* TODO(dcramer): Add a per-parent total invocation limit as the loop guard
|
|
403
|
-
* for spawn -> result -> spawn chains (#881).
|
|
404
|
-
*/
|
|
405
|
-
async function enqueueAgentInvocationResult(invocation, options) {
|
|
406
|
-
if (invocation.parentMailboxStatus !== "pending") return;
|
|
407
|
-
const nowMs = options.nowMs ?? Date.now();
|
|
408
|
-
await appendAndEnqueueInboundMessage({
|
|
409
|
-
message: buildResultInboundMessage(invocation, nowMs),
|
|
410
|
-
queue: options.queue,
|
|
411
|
-
queueDelayMs: EVENT_WAIT_MS,
|
|
412
|
-
state: options.state
|
|
413
|
-
});
|
|
414
|
-
await markAgentInvocationParentMailboxAppended(invocation.invocationId, nowMs);
|
|
415
|
-
}
|
|
416
|
-
function resultInvocationId(message) {
|
|
417
|
-
const metadata = message.input.metadata;
|
|
418
|
-
return isEventMailboxMetadata(metadata) && metadata.event.namespace === AGENT_INVOCATION_EVENT_NAMESPACE && metadata.event.eventType.startsWith(AGENT_INVOCATION_EVENT_TYPE_PREFIX) ? metadata.event.identifier : void 0;
|
|
419
|
-
}
|
|
420
|
-
/** Read one result message's agent invocation and check its parent. */
|
|
421
|
-
async function getResultInvocation(message, invocationId) {
|
|
422
|
-
const invocation = await getAgentInvocation(invocationId);
|
|
423
|
-
if (!invocation || !isTerminalAgentInvocation(invocation) || invocation.parentConversationId !== message.conversationId) throw new Error(`Agent invocation result ${invocationId} does not belong to ${message.conversationId}`);
|
|
424
|
-
return invocation;
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Give agent invocation results that reach a child Conversation to that
|
|
428
|
-
* child. A child Conversation has no Location, so it cannot run an Event
|
|
429
|
-
* Turn. Each result starts a new agent invocation on the child instead, and
|
|
430
|
-
* that invocation reports to the child's parent. Returns undefined for work
|
|
431
|
-
* that is not a result for a child Conversation.
|
|
432
|
-
*/
|
|
433
|
-
async function startAgentInvocationsForChildResults(context, options) {
|
|
434
|
-
const messages = context.attempt.messages;
|
|
435
|
-
const invocationIds = messages.map(resultInvocationId);
|
|
436
|
-
if (messages.length === 0 || invocationIds.some((id) => !id)) return;
|
|
437
|
-
const latest = await getLatestAgentInvocationForConversation(context.conversationId);
|
|
438
|
-
if (!latest) return;
|
|
439
|
-
if (latest.status === "stopped") {
|
|
440
|
-
await context.attempt.ack();
|
|
441
|
-
return { status: "completed" };
|
|
442
|
-
}
|
|
443
|
-
for (const [index, message] of messages.entries()) {
|
|
444
|
-
const result = await getResultInvocation(message, invocationIds[index]);
|
|
445
|
-
if (result.parentMailboxStatus === "skipped") continue;
|
|
446
|
-
const invocation = await createAgentInvocationForResult({
|
|
447
|
-
input: message.input.text.trim(),
|
|
448
|
-
latest,
|
|
449
|
-
resultInvocationId: result.invocationId
|
|
450
|
-
});
|
|
451
|
-
await enqueueAgentInvocation(invocation, options);
|
|
452
|
-
}
|
|
453
|
-
await context.attempt.ack();
|
|
454
|
-
return { status: "completed" };
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Run each agent invocation result as the Actor that triggered the child, user
|
|
458
|
-
* or system. This is on purpose: the result continues that Actor's work. The
|
|
459
|
-
* Actor comes from SQL, not from mailbox metadata, so the parent Turn has the
|
|
460
|
-
* same authority it had at spawn time.
|
|
461
|
-
*
|
|
462
|
-
* TODO(dcramer): Pass the delegated credential subject of a system Actor, such
|
|
463
|
-
* as a timer watch Turn, when system Turns can spawn children that need it.
|
|
464
|
-
*/
|
|
465
|
-
async function withAgentInvocationResultActors(work) {
|
|
466
|
-
if (work.kind !== "mailbox") return work;
|
|
467
|
-
return {
|
|
468
|
-
kind: "mailbox",
|
|
469
|
-
batch: await Promise.all(work.batch.map(async (entry) => {
|
|
470
|
-
const invocationId = resultInvocationId(entry.message);
|
|
471
|
-
if (!invocationId) return entry;
|
|
472
|
-
const invocation = await getResultInvocation(entry.message, invocationId);
|
|
473
|
-
return {
|
|
474
|
-
...entry,
|
|
475
|
-
actor: invocation.actor
|
|
476
|
-
};
|
|
477
|
-
}))
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
//#endregion
|
|
481
311
|
//#region src/chat/attachments/vercel.ts
|
|
482
312
|
/** Store private conversation attachments in Vercel Blob. */
|
|
483
313
|
function createVercelAttachmentStorage() {
|
|
@@ -1743,142 +1573,41 @@ function createSlackTurnRuntime(deps) {
|
|
|
1743
1573
|
};
|
|
1744
1574
|
}
|
|
1745
1575
|
//#endregion
|
|
1746
|
-
//#region src/chat/conversations/
|
|
1747
|
-
/**
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
}).strict();
|
|
1756
|
-
//#endregion
|
|
1757
|
-
//#region src/chat/task-execution/mailbox-turn.ts
|
|
1758
|
-
/**
|
|
1759
|
-
* Restore Turn input facts, with saved Message fallback for legacy cursors.
|
|
1760
|
-
*
|
|
1761
|
-
* TODO(dcramer): Remove Actor and Source reconstruction from the saved Message
|
|
1762
|
-
* after no deployed Turn cursor can omit either field.
|
|
1763
|
-
*/
|
|
1764
|
-
function turnInputFactsFromConversationMessage(message, args) {
|
|
1765
|
-
if (isEventConversationMessage(message)) return {
|
|
1766
|
-
actor: args.savedActor ?? EVENT_SYSTEM_ACTOR,
|
|
1767
|
-
author: message.author ?? EVENT_MESSAGE_AUTHOR,
|
|
1768
|
-
source: args.savedSource ?? (args.location ? createWebSource(args.conversationId, args.visibility === "private" ? "private" : "public") : createLocalSource(args.conversationId))
|
|
1769
|
-
};
|
|
1770
|
-
const actor = args.savedActor ?? createActor(message.author, {
|
|
1771
|
-
platform: "web",
|
|
1772
|
-
userId: message.author?.userId
|
|
1773
|
-
});
|
|
1774
|
-
if (actor?.platform !== "web") return;
|
|
1775
|
-
return {
|
|
1776
|
-
actor,
|
|
1777
|
-
author: message.author ?? { userId: actor.userId },
|
|
1778
|
-
source: args.savedSource?.kind === "web" ? args.savedSource : createWebSource(args.conversationId, args.visibility === "private" ? "private" : "public")
|
|
1779
|
-
};
|
|
1780
|
-
}
|
|
1781
|
-
/** Normalize the selected mailbox Source with current Conversation visibility. */
|
|
1782
|
-
function sourceFromTurnInput(args) {
|
|
1783
|
-
if (args.source.kind === "web") return createWebSource(args.conversationId, args.visibility === "private" ? "private" : "public");
|
|
1784
|
-
return args.source;
|
|
1785
|
-
}
|
|
1786
|
-
function hasEventActor(actors) {
|
|
1787
|
-
return Boolean(actors?.some((actor) => actor.platform === "system" && actor.name === EVENT_SYSTEM_ACTOR.name));
|
|
1788
|
-
}
|
|
1789
|
-
/** Return the active web Turn for one Conversation, if it has one. */
|
|
1790
|
-
async function getActiveConversationTurnId(conversationId) {
|
|
1791
|
-
const active = (await listTurnSummaries(conversationId)).filter((summary) => summary.surface === "api" && !summary.dispatchId && (summary.state === "paused" || summary.state === "running"));
|
|
1792
|
-
if (active.length > 1) throw new Error(`Conversation ${conversationId} has multiple active web turns`);
|
|
1793
|
-
const turnId = active[0]?.turnId;
|
|
1794
|
-
if (!turnId) return void 0;
|
|
1795
|
-
const record = await getTurnRecord(conversationId, turnId);
|
|
1796
|
-
return record && (record.source?.kind === "web" || !record.source && record.surface === "api") && !record.dispatchId && (record.state === "paused" || record.state === "running") ? turnId : void 0;
|
|
1797
|
-
}
|
|
1798
|
-
/** Return the active web or event mailbox Turn. */
|
|
1799
|
-
async function getActiveMailboxTurnId(conversationId) {
|
|
1800
|
-
const summaries = await listTurnSummaries(conversationId);
|
|
1801
|
-
const active = (await Promise.all(summaries.filter((summary) => !summary.dispatchId && (summary.state === "paused" || summary.state === "running")).map((summary) => getTurnRecord(conversationId, summary.turnId)))).filter((record) => record && !record.dispatchId && (record.source?.kind === "web" || record.source?.kind === "event" || !record.source && (record.surface === "api" || hasEventActor(record.actors))) && (record.state === "paused" || record.state === "running"));
|
|
1802
|
-
if (active.length > 1) throw new Error(`Conversation ${conversationId} has multiple active mailbox Turns`);
|
|
1803
|
-
return active[0]?.turnId;
|
|
1804
|
-
}
|
|
1805
|
-
/** Return the idle auth-paused web Turn for one Conversation. */
|
|
1806
|
-
async function getAuthPausedConversationTurnId(conversationId) {
|
|
1807
|
-
const turnId = await getActiveConversationTurnId(conversationId);
|
|
1808
|
-
if (!turnId) return void 0;
|
|
1809
|
-
const record = await getTurnRecord(conversationId, turnId);
|
|
1810
|
-
return record?.state === "paused" && record.resumeReason === "auth" ? turnId : void 0;
|
|
1811
|
-
}
|
|
1812
|
-
function parseWebMessages(messages) {
|
|
1813
|
-
if (messages.length === 0) return [];
|
|
1814
|
-
const parsed = messages.map((message) => ({
|
|
1815
|
-
message,
|
|
1816
|
-
metadata: legacyWebMailboxMetadataSchema.safeParse(message.input.metadata)
|
|
1817
|
-
}));
|
|
1818
|
-
if (parsed.every((entry) => !entry.metadata.success)) return [];
|
|
1819
|
-
if (parsed.some((entry) => !entry.metadata.success)) throw new Error("A Turn cannot combine different kinds of input");
|
|
1820
|
-
return parsed.map((entry) => {
|
|
1821
|
-
if (!entry.metadata.success) throw new Error("User message has invalid metadata");
|
|
1822
|
-
const metadata = entry.metadata.data;
|
|
1823
|
-
const actor = {
|
|
1824
|
-
platform: "web",
|
|
1825
|
-
userId: metadata.authorUserId,
|
|
1826
|
-
email: metadata.authorEmail.trim().toLowerCase(),
|
|
1827
|
-
...metadata.authorFullName ? { fullName: metadata.authorFullName } : void 0,
|
|
1828
|
-
...metadata.authorUserName ? { userName: metadata.authorUserName } : void 0
|
|
1829
|
-
};
|
|
1830
|
-
return {
|
|
1831
|
-
actor,
|
|
1832
|
-
author: {
|
|
1833
|
-
email: actor.email,
|
|
1834
|
-
...actor.fullName ? { fullName: actor.fullName } : void 0,
|
|
1835
|
-
userId: actor.userId,
|
|
1836
|
-
...actor.userName ? { userName: actor.userName } : void 0
|
|
1837
|
-
},
|
|
1838
|
-
message: entry.message,
|
|
1839
|
-
source: createWebSource(entry.message.conversationId)
|
|
1840
|
-
};
|
|
1576
|
+
//#region src/chat/conversations/stop.ts
|
|
1577
|
+
/** Stop the current Conversation Turn and wake an idle resume when needed. */
|
|
1578
|
+
async function stopConversationTurn(args) {
|
|
1579
|
+
const nowMs = args.nowMs ?? Date.now();
|
|
1580
|
+
const stop = async () => await stopConversationWork({
|
|
1581
|
+
conversationId: args.conversationId,
|
|
1582
|
+
conversationStore: args.conversationStore,
|
|
1583
|
+
nowMs,
|
|
1584
|
+
state: args.state
|
|
1841
1585
|
});
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1586
|
+
let result = await stop();
|
|
1587
|
+
if (result.status === "no_work" && await getAuthPausedConversationTurnId(args.conversationId)) {
|
|
1588
|
+
const conversation = await getConversation({
|
|
1589
|
+
conversationId: args.conversationId,
|
|
1590
|
+
state: args.state
|
|
1591
|
+
});
|
|
1592
|
+
await requestConversationWork({
|
|
1593
|
+
conversationId: args.conversationId,
|
|
1594
|
+
conversationStore: args.conversationStore,
|
|
1595
|
+
destination: conversation?.destination,
|
|
1596
|
+
nowMs,
|
|
1597
|
+
state: args.state
|
|
1598
|
+
});
|
|
1599
|
+
result = await stop();
|
|
1600
|
+
}
|
|
1601
|
+
if (result.status === "requested") await ensureConversationWake({
|
|
1602
|
+
conversationId: args.conversationId,
|
|
1603
|
+
conversationStore: args.conversationStore,
|
|
1604
|
+
idempotencyKey: `conversation-stop:${args.conversationId}:${result.runId}`,
|
|
1605
|
+
nowMs,
|
|
1606
|
+
queue: args.queue,
|
|
1607
|
+
replaceExistingWake: true,
|
|
1608
|
+
state: args.state
|
|
1859
1609
|
});
|
|
1860
|
-
|
|
1861
|
-
/**
|
|
1862
|
-
* Select web or event work from new mailbox input or a saved Turn.
|
|
1863
|
-
* Saved Actor data identifies a resumed event Turn.
|
|
1864
|
-
*/
|
|
1865
|
-
async function resolveMailboxTurnWork(context) {
|
|
1866
|
-
const batch = parseWebMessages(context.attempt.messages);
|
|
1867
|
-
if (batch.length > 0) return {
|
|
1868
|
-
kind: "mailbox",
|
|
1869
|
-
batch
|
|
1870
|
-
};
|
|
1871
|
-
const resourceBatch = parseEventMessages(context.attempt.messages);
|
|
1872
|
-
if (resourceBatch.length > 0) return {
|
|
1873
|
-
kind: "mailbox",
|
|
1874
|
-
batch: resourceBatch
|
|
1875
|
-
};
|
|
1876
|
-
if (context.attempt.messages.length > 0) return;
|
|
1877
|
-
const turnId = await getActiveMailboxTurnId(context.conversationId);
|
|
1878
|
-
return turnId ? {
|
|
1879
|
-
kind: "resume",
|
|
1880
|
-
turnId
|
|
1881
|
-
} : void 0;
|
|
1610
|
+
return result;
|
|
1882
1611
|
}
|
|
1883
1612
|
//#endregion
|
|
1884
1613
|
//#region src/chat/ingress/message-router.ts
|
|
@@ -3690,6 +3419,7 @@ function createJuniorRuntimeServices(overrides = {}) {
|
|
|
3690
3419
|
downloadFile: overrides.visionContext?.downloadFile ?? downloadPrivateSlackFile
|
|
3691
3420
|
});
|
|
3692
3421
|
const agentRunner = overrides.agentRunner ?? createAgentRunner(executeAgentRun, {
|
|
3422
|
+
bindMessageAgent: (request) => bindMessageAgent(request, { queue: getVercelConversationWorkQueue }),
|
|
3693
3423
|
bindSpawnAgent: (request) => bindSpawnAgent(request, { queue: getVercelConversationWorkQueue }),
|
|
3694
3424
|
tracePropagation: overrides.sandbox?.tracePropagation
|
|
3695
3425
|
});
|
|
@@ -4393,17 +4123,6 @@ async function resolveDestinationVisibility(args) {
|
|
|
4393
4123
|
}
|
|
4394
4124
|
//#endregion
|
|
4395
4125
|
//#region src/chat/providers/slack/input.ts
|
|
4396
|
-
/**
|
|
4397
|
-
* Return a stable key for one steering message. Resolved attachments may change
|
|
4398
|
-
* when Junior retries a mailbox delivery, so only the message time and text
|
|
4399
|
-
* form the key.
|
|
4400
|
-
*/
|
|
4401
|
-
function steeringMessageKey(message) {
|
|
4402
|
-
if (message.role !== "user") return;
|
|
4403
|
-
const first = Array.isArray(message.content) ? message.content[0] : void 0;
|
|
4404
|
-
const text = first && typeof first === "object" && "text" in first ? String(first.text ?? "") : "";
|
|
4405
|
-
return `${message.timestamp}:${text}`;
|
|
4406
|
-
}
|
|
4407
4126
|
function renderRecentThreadMessageLines(conversationContext, messages) {
|
|
4408
4127
|
const messagesForContext = messages.filter((queued) => {
|
|
4409
4128
|
if (queued.explicitMention) return false;
|
|
@@ -4498,11 +4217,7 @@ async function saveSteeringMessages(args) {
|
|
|
4498
4217
|
if (!lock) return false;
|
|
4499
4218
|
try {
|
|
4500
4219
|
const projection = await loadConversationProjection({ conversationId: args.conversationId });
|
|
4501
|
-
const
|
|
4502
|
-
const missing = args.messages.filter((entry) => {
|
|
4503
|
-
const key = steeringMessageKey(entry.message);
|
|
4504
|
-
return key === void 0 || !savedKeys.has(key);
|
|
4505
|
-
});
|
|
4220
|
+
const missing = withoutSavedSteeringMessages(projection.messages, args.messages, (entry) => entry.message);
|
|
4506
4221
|
if (missing.length === 0) return true;
|
|
4507
4222
|
await commitMessages({
|
|
4508
4223
|
conversationId: args.conversationId,
|
|
@@ -5037,11 +4752,7 @@ function createSlackTurn(deps) {
|
|
|
5037
4752
|
throw new TurnInputDeferredError();
|
|
5038
4753
|
}
|
|
5039
4754
|
if (batchedSteeringMessages.length > 0) {
|
|
5040
|
-
const
|
|
5041
|
-
const newSteeringMessages = batchedSteeringMessages.map((entry) => entry.message).filter((batchedMessage) => {
|
|
5042
|
-
const key = steeringMessageKey(batchedMessage);
|
|
5043
|
-
return key === void 0 || !presentKeys.has(key);
|
|
5044
|
-
});
|
|
4755
|
+
const newSteeringMessages = withoutSavedSteeringMessages(piMessages ?? [], batchedSteeringMessages.map((entry) => entry.message), (message) => message);
|
|
5045
4756
|
if (newSteeringMessages.length > 0) piMessages = [...piMessages ?? [], ...newSteeringMessages];
|
|
5046
4757
|
}
|
|
5047
4758
|
status.update();
|
|
@@ -6846,12 +6557,6 @@ async function commitAssistantMessage(args) {
|
|
|
6846
6557
|
}
|
|
6847
6558
|
}
|
|
6848
6559
|
//#endregion
|
|
6849
|
-
//#region src/chat/task-execution/mailbox-input.ts
|
|
6850
|
-
/** Join non-empty mailbox Message text for one Turn. */
|
|
6851
|
-
function joinMailboxText(messages) {
|
|
6852
|
-
return messages.map((message) => message.input.text.trim()).filter(Boolean).join("\n\n");
|
|
6853
|
-
}
|
|
6854
|
-
//#endregion
|
|
6855
6560
|
//#region src/chat/conversations/destination.ts
|
|
6856
6561
|
function requireLocalDestination(conversationId) {
|
|
6857
6562
|
const parsed = localDestinationSchema.safeParse({
|
|
@@ -6874,10 +6579,6 @@ function resolveConversationDestination(args) {
|
|
|
6874
6579
|
//#endregion
|
|
6875
6580
|
//#region src/chat/task-execution/conversation-turn.ts
|
|
6876
6581
|
/** Run a mailbox Turn and store its assistant Messages. */
|
|
6877
|
-
/** Extra debounce time added per additional event already batched. */
|
|
6878
|
-
const EVENT_WAIT_PER_EXTRA_MESSAGE_MS = 5e3;
|
|
6879
|
-
/** Upper bound on the debounce window regardless of batch size. */
|
|
6880
|
-
const EVENT_MAX_WAIT_MS = 6e4;
|
|
6881
6582
|
function stableHex$1(...parts) {
|
|
6882
6583
|
return createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 24);
|
|
6883
6584
|
}
|
|
@@ -6941,15 +6642,11 @@ async function completeCancelledConversationTurn(args) {
|
|
|
6941
6642
|
function createConversationTurnWorker(agentRunner, deliverMessage) {
|
|
6942
6643
|
return async (context, resolved) => {
|
|
6943
6644
|
if (resolved.kind === "mailbox") {
|
|
6944
|
-
const
|
|
6945
|
-
if (
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
status: "deferred",
|
|
6950
|
-
delayMs
|
|
6951
|
-
};
|
|
6952
|
-
}
|
|
6645
|
+
const delayMs = getEventBatchDelayMs(resolved.batch.map((entry) => entry.message));
|
|
6646
|
+
if (delayMs > 0) return {
|
|
6647
|
+
status: "deferred",
|
|
6648
|
+
delayMs
|
|
6649
|
+
};
|
|
6953
6650
|
}
|
|
6954
6651
|
const lifecycle = new ConversationTurnLifecycleService(getConversationEventStore());
|
|
6955
6652
|
const isResume = resolved.kind === "resume";
|
|
@@ -7446,11 +7143,13 @@ function createConversationWork(options) {
|
|
|
7446
7143
|
throw new Error(`Conversation ${context.conversationId} has a ${destination.platform} destination but no matching conversation worker`);
|
|
7447
7144
|
};
|
|
7448
7145
|
const run = async (context) => {
|
|
7449
|
-
const
|
|
7146
|
+
const skipped = await skipInputBeforeConversationStop(context);
|
|
7147
|
+
if (skipped) return skipped;
|
|
7148
|
+
const childInput = await startAgentInvocationsForChildInput(context, {
|
|
7450
7149
|
queue: options.queue,
|
|
7451
7150
|
state: options.state
|
|
7452
7151
|
});
|
|
7453
|
-
if (
|
|
7152
|
+
if (childInput) return childInput;
|
|
7454
7153
|
const mailboxTurn = await resolveMailboxTurnWork(context);
|
|
7455
7154
|
if (mailboxTurn) return await conversationTurnWorker(context, await withAgentInvocationResultActors(mailboxTurn));
|
|
7456
7155
|
const invocationId = await resolveAgentInvocationId(context);
|
|
@@ -7685,4 +7384,4 @@ async function appendAndEnqueueWebMessage(input, options) {
|
|
|
7685
7384
|
};
|
|
7686
7385
|
}
|
|
7687
7386
|
//#endregion
|
|
7688
|
-
export { withNormalizedThreadId as A,
|
|
7387
|
+
export { withNormalizedThreadId as A, readHealthReport as B, buildSlackInboundMessage as C, isSlackMessageStopped as D, verifySlackSignature as E, renderSlackObjectCard as F, createVercelAttachmentStorage as I, AGENT_DISPATCH_MAX_AGE_MS as L, THREAD_OPTOUT_ACK as M, startProcessingReaction as N, stopSlackThread as O, parseContent as P, enqueueAgentDispatch as R, recordSkippedConversationMessage as S, runWithSlackInstallation as T, 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, stopConversationTurn 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, GET as z };
|