@sentry/junior 0.223.0 → 0.224.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.
Files changed (52) hide show
  1. package/dist/{agent-hooks-DZU5nsd1.js → agent-hooks-DNLBwmsh.js} +6 -6
  2. package/dist/{agent-Bzbf92vv.js → agent-runner-9g6TQk9y.js} +809 -34
  3. package/dist/api.js +14 -14
  4. package/dist/app.js +1507 -59
  5. package/dist/{briefs-BJPfCrlT.js → briefs-CjXnGKzZ.js} +2 -2
  6. package/dist/{catalog-runtime-BthunUDD.js → catalog-runtime-CVZ9TEuK.js} +1 -1
  7. package/dist/{checkpoint-Deu-OVb3.js → checkpoint-Ceck_fLO.js} +7 -7
  8. package/dist/cli/chat.js +14 -15
  9. package/dist/cli/check.js +3 -3
  10. package/dist/cli/main.js +1 -1
  11. package/dist/cli/plugins.js +3 -3
  12. package/dist/cli/snapshot-create.js +3 -3
  13. package/dist/cli/upgrade.js +3 -3
  14. package/dist/{client-DjC6-6iU.js → client-B27ufhzl.js} +2 -2
  15. package/dist/{config-CtoUVs72.js → config-BAhl7-RC.js} +2 -2
  16. package/dist/{conversation-privacy-xS1t92xa.js → conversation-privacy-C-4JQzKD.js} +1 -1
  17. package/dist/credential-sync-BXHIxbtS.js +940 -0
  18. package/dist/{execution-stats-CrXs9vSH.js → execution-stats-DikPOxJ1.js} +3 -3
  19. package/dist/{executor-AOhG9X1t.js → executor-BG2Armby.js} +1 -1
  20. package/dist/instrumentation.js +2 -2
  21. package/dist/{job-queue-CNd9cpIy.js → job-queue-D4oAVrL9.js} +1 -1
  22. package/dist/{logging-DiN3o3nB.js → logging-iY0ssa2q.js} +1 -1
  23. package/dist/nitro.js +3 -3
  24. package/dist/{pending-auth-D7vmttn_.js → oauth-authorization-BIijVS2N.js} +6 -48
  25. package/dist/{oauth-callback-server-Ca0VLUEw.js → oauth-callback-server-DPkK3kzi.js} +4 -4
  26. package/dist/{profile-BsNrw8lj.js → profile-6KWhg_-U.js} +5 -9
  27. package/dist/{registry-Dankt-Pl.js → registry-Ctgdjt-W.js} +1 -1
  28. package/dist/{resolve-B38CpJe2.js → resolve-CB45ZukQ.js} +2 -2
  29. package/dist/{runner-Ck5rEjCm.js → runner-BwKCqoF3.js} +8 -9
  30. package/dist/{sandbox-egress-signals-BOfFkvly.js → sandbox-egress-signals-Cmy8ODat.js} +1 -1
  31. package/dist/{short-title-BHd_jUFX.js → short-title-xEkZwkcV.js} +2 -2
  32. package/dist/{skills-DbP4TDft.js → skills-c2bMDVRS.js} +2 -2
  33. package/dist/{spawn-DzXc_PKO.js → spawn-Cg6lyjE7.js} +2 -2
  34. package/dist/{stats-pNGp3G5q.js → stats-DP9zl3Jg.js} +6 -6
  35. package/dist/{task-queue-Cy9y1foT.js → task-queue-SL4uLfBB.js} +3 -3
  36. package/dist/{task-runner-DI1FBJFJ.js → task-runner-fntmnqzx.js} +8 -83
  37. package/dist/{thread-state-DXgxOYpZ.js → thread-state-Wfr0GdKS.js} +5 -5
  38. package/dist/{auth-pause-state-Bn2vX4PA.js → turn-failure-response-DLjSEm-R.js} +73 -72
  39. package/dist/{turn-lifecycle-Bjf6y2GO.js → turn-lifecycle-5_jvLqRz.js} +1 -1
  40. package/dist/turn-session-routing-CQaysLoe.js +77 -0
  41. package/dist/{validation-D5CIslEu.js → validation-CnZkCN7o.js} +1 -1
  42. package/dist/{version-_ZQFlslB.js → version-C6lA-h_o.js} +1 -1
  43. package/dist/version.js +1 -1
  44. package/dist/{web-authorization-6mmfS_o-.js → web-authorization-Bbx999_q.js} +1 -1
  45. package/dist/{web-input-BJpWm6go.js → web-input-BoE1xE-K.js} +7 -7
  46. package/dist/{work-DvIlJR3C.js → work-4Nhz9mVv.js} +52 -10
  47. package/dist/{worker-D1qidg-Y.js → worker-CdWPsNL2.js} +5 -5
  48. package/package.json +4 -4
  49. package/dist/agent-runner-2VQ9WhkG.js +0 -679
  50. package/dist/credential-sync-CKdXEUDO.js +0 -2811
  51. package/dist/experimental-CIXf7Uye.js +0 -46
  52. package/dist/turn-execution-BNOXrZ-M.js +0 -47
@@ -1,28 +1,28 @@
1
- import { C as resolveGatewayCredential, S as getGatewayApiKey, _ as findProviderError, b as isProviderRetryError, c as COMPACTION_SUMMARY_PREFIX, d as isCompactionSummaryText, f as renderCurrentInstruction, g as createProviderError, h as ProviderError, i as completeText, l as MODEL_HANDOFF_SUMMARY_PREFIX, m as escapeXml, n as GEN_AI_SERVER_ADDRESS, o as resolveGatewayModel, p as unwrapCurrentInstruction, r as completeObject, s as ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX, t as GEN_AI_PROVIDER_NAME, u as hasCompactedConversationContext, v as getProviderErrorAttributes, x as MISSING_GATEWAY_CREDENTIALS_ERROR } from "./client-DjC6-6iU.js";
2
- import { C as withSpan, F as isRecord$2, P as normalizeIdentityEmail, S as withLogContext, _ as setSpanAttributes, a as extractGenAiUsageSummary, b as summarizeMessageText, c as getTracePropagationHeaders, d as logInfo, f as logWarn, h as serializeGenAiAttribute, i as extractGenAiUsageAttributes, l as logError, p as normalizeGenAiFinishReason, s as getLogContextAttributesForSpan, u as logException, v as setSpanStatus, y as setTags } from "./logging-DiN3o3nB.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
+ import { C as resolveGatewayCredential, S as getGatewayApiKey, _ as findProviderError, b as isProviderRetryError, c as COMPACTION_SUMMARY_PREFIX, d as isCompactionSummaryText, f as renderCurrentInstruction, g as createProviderError, h as ProviderError, i as completeText, l as MODEL_HANDOFF_SUMMARY_PREFIX, m as escapeXml, n as GEN_AI_SERVER_ADDRESS, o as resolveGatewayModel, p as unwrapCurrentInstruction, r as completeObject, s as ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX, t as GEN_AI_PROVIDER_NAME, u as hasCompactedConversationContext, v as getProviderErrorAttributes, x as MISSING_GATEWAY_CREDENTIALS_ERROR } from "./client-B27ufhzl.js";
3
+ import { C as withSpan, F as isRecord$2, P as normalizeIdentityEmail, S as withLogContext, _ as setSpanAttributes, a as extractGenAiUsageSummary, b as summarizeMessageText, c as getTracePropagationHeaders, d as logInfo, f as logWarn, h as serializeGenAiAttribute, i as extractGenAiUsageAttributes, l as logError, p as normalizeGenAiFinishReason, s as getLogContextAttributesForSpan, u as logException, v as setSpanStatus, y as setTags } from "./logging-iY0ssa2q.js";
3
4
  import { m as startInactiveSpan, v as withActiveSpan } from "./sentry-CgWZM_kV.js";
4
- import { a as toCanonicalInputMessage, c as toGenAiPayloadMetadata, i as runWithConversationPrivacy, l as toGenAiPayloadTraceAttributes, o as toCanonicalOutputMessage, r as resolveConversationPrivacy, s as toGenAiMessagesTraceAttributes, t as canExposeConversationPayload } from "./conversation-privacy-xS1t92xa.js";
5
- import { h as normalizeSlackEmojiName, n as botConfig } from "./config-CtoUVs72.js";
5
+ import { a as toCanonicalInputMessage, c as toGenAiPayloadMetadata, i as runWithConversationPrivacy, l as toGenAiPayloadTraceAttributes, o as toCanonicalOutputMessage, r as resolveConversationPrivacy, s as toGenAiMessagesTraceAttributes, t as canExposeConversationPayload } from "./conversation-privacy-C-4JQzKD.js";
6
+ import { h as normalizeSlackEmojiName, n as botConfig } from "./config-BAhl7-RC.js";
6
7
  import { a as modelIdForProfile, c as TURN_REASONING_LEVELS, i as formatModelProfiles, o as modelProfileSchema, r as formatModelProfile, s as profileConfig, t as ModelProfileNotConfiguredError } from "./model-profile-CZmVoGdX.js";
7
8
  import { _ as parseSlackMessageTs, g as parseSlackUserId, h as parseSlackTeamId, i as credentialUserSubjectId, l as isUserActor, m as parseSlackChannelReferenceId, n as credentialContextSchema, p as parseSlackChannelId, t as credentialContextForActor } from "./context-Bplcgypl.js";
8
- import { A as tryWorkspaceRepoCheckoutPath, B as downloadPrivateSlackFile, C as invalidateReadySnapshot, D as SANDBOX_RUNTIME, E as setWorkspaceSnapshotBuild, Ft as saveObjectAnnotations, Gt as getConversationMessageSearchStore, It as createPluginAnnotations, J as withSlackRetries, Jt as getSqlExecutor, K as normalizeSlackConversationId, Kt as getConversationStore, M as resolveChannelCapabilities, O as deleteWorkspaceSnapshotBuilders, Q as readActorIdentity, S as WorkspaceValidationError, T as setWorkspaceSnapshot, U as getSlackClient, V as getFilePermalink, W as isConversationScopedChannel, Wt as getConversationEventStore, _ as deleteWorkspace, at as STOP_WATCHING_TOOL_NAME, b as listWorkspaces, bt as createPluginLogger, c as getPluginTools, dt as findMatchingWatches, fn as parseDestination, ft as listWatches, g as createWorkspace, ht as getDashboardTaskLink, it as RESOURCE_WATCH_TOOL_SOURCE, j as workspaceRepoCheckoutPath, k as getWorkspaceSnapshotBuilder, l as getPluginUserPromptContributions, lt as createWatch, mt as getDashboardConversationLink, nn as addAgentTurnUsage, nt as RESOURCE_SUBSCRIPTION_DEFAULT_TTL_MS, on as hasAgentTurnUsage, ot as cancelSubscriptions, pt as JUNIOR_THREAD_STATE_TTL_MS, qt as getDb, r as createPluginHookRunner, s as getPluginSystemPromptContributions, st as cancelWatch, tt as getSlackToolContext, u as getPlugins, ut as deliverWatch, v as getWorkspace, w as loadSnapshotsForProfile, x as updateWorkspace, y as getWorkspaceByName, z as SlackActionError } from "./agent-hooks-DZU5nsd1.js";
9
+ import { A as tryWorkspaceRepoCheckoutPath, B as downloadPrivateSlackFile, C as invalidateReadySnapshot, D as SANDBOX_RUNTIME, E as setWorkspaceSnapshotBuild, Ft as saveObjectAnnotations, G as isDmChannel$1, Gt as getConversationMessageSearchStore, It as createPluginAnnotations, J as withSlackRetries, Jt as getSqlExecutor, K as normalizeSlackConversationId, Kt as getConversationStore, M as resolveChannelCapabilities, O as deleteWorkspaceSnapshotBuilders, Q as readActorIdentity, S as WorkspaceValidationError, T as setWorkspaceSnapshot, U as getSlackClient, V as getFilePermalink, W as isConversationScopedChannel, Wt as getConversationEventStore, _ as deleteWorkspace, at as STOP_WATCHING_TOOL_NAME, b as listWorkspaces, bt as createPluginLogger, c as getPluginTools, dt as findMatchingWatches, fn as parseDestination, ft as listWatches, g as createWorkspace, ht as getDashboardTaskLink, it as RESOURCE_WATCH_TOOL_SOURCE, j as workspaceRepoCheckoutPath, k as getWorkspaceSnapshotBuilder, l as getPluginUserPromptContributions, lt as createWatch, mt as getDashboardConversationLink, n as applyPluginFormatMarkdown, nn as addAgentTurnUsage, nt as RESOURCE_SUBSCRIPTION_DEFAULT_TTL_MS, on as hasAgentTurnUsage, ot as cancelSubscriptions, pt as JUNIOR_THREAD_STATE_TTL_MS, qt as getDb, r as createPluginHookRunner, s as getPluginSystemPromptContributions, st as cancelWatch, tt as getSlackToolContext, u as getPlugins, ut as deliverWatch, v as getWorkspace, w as loadSnapshotsForProfile, x as updateWorkspace, y as getWorkspaceByName, z as SlackActionError } from "./agent-hooks-DNLBwmsh.js";
9
10
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
10
- import { D as juniorIdentities, E as juniorConversations, a as juniorSchedulerRuns, d as AGENT_INVOCATION_MAILBOX_STATUSES, g as juniorConversationBriefs, k as juniorArtifacts, w as juniorAttachments, x as juniorConversationAnnotations } from "./executor-AOhG9X1t.js";
11
+ import { D as juniorIdentities, E as juniorConversations, a as juniorSchedulerRuns, d as AGENT_INVOCATION_MAILBOX_STATUSES, g as juniorConversationBriefs, k as juniorArtifacts, w as juniorAttachments, x as juniorConversationAnnotations } from "./executor-BG2Armby.js";
11
12
  import { F as briefLinkSchema, I as briefOutcomeStatusSchema, J as instructionActors, L as conversationBriefSchema, X as sameActorIdentity, Y as instructionProvenanceFor, j as messageCardRefSchema, q as contextProvenance, z as KNOWN_CONVERSATION_EVENT_TYPES } from "./conversation-1HUoZr2l.js";
12
13
  import { a as listReferenceFiles, c as soulPathCandidates, l as worldPathCandidates } from "./package-discovery-7a9YqLhE.js";
13
- import { a as resolveAuthTokenPlaceholder, c as fetchWithBoundedOAuthErrorBodies, d as CredentialUnavailableError, i as resolvePluginHeaderEnvRefs, l as getOAuthProviderErrorAttributes, o as resolvePluginCommandEnv, s as OAuthProviderError } from "./registry-Dankt-Pl.js";
14
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BthunUDD.js";
15
- import { a as parseSkillInvocation, n as findSkillByName, r as loadSkillsByName, t as discoverSkills } from "./skills-DbP4TDft.js";
16
- import { A as TURN_CONTEXT_TAG, C as isContinuablePiBoundary, D as retainRuntimeTurnContext, E as normalizeToolNameFromResult, H as recordAuthorizationRequested, I as loadTurnRoute, K as recordToolExecutionStarted, L as openConversationProjection, N as loadConnectedMcpProviders, O as stripRuntimeTurnContext, P as loadConversationProjection, R as recordAgentsInstructionsUpdated, S as isAssistantMessage, T as isToolResultMessage, U as recordGuardianActionReviewed, W as recordMcpProviderConnected, _ as getPiMessageRole, b as hasRuntimeTurnContext, dt as estimateTextTokens, f as TurnSliceLimitExceededError, ft as getAgentContextCompactionTriggerTokens, g as extractAssistantText, h as isTurnExecutionLimitExceededError, ht as piMessageFromHistoryItem, k as trimTrailingAssistantMessages, mt as historyItemFromPiMessage, n as loadTurnCheckpoint, p as assertTurnToolCallLimit, pt as getAgentContextInputLimitTokens, q as recordTurnRoute, r as saveTurnCheckpoint, t as continuableMessages, v as getTerminalAssistantMessages, w as isToolResultError, y as getUserMessageInstructionText, z as recordAttachmentsDelivered } from "./checkpoint-Deu-OVb3.js";
17
- import { n as generateShortTitle, r as resolveTaskTitle, t as fallbackShortTitle } from "./short-title-BHd_jUFX.js";
18
- import { A as sleep$1, D as fenceLock, E as acquireActiveLock, F as sandboxSkillDir, I as sandboxSkillFile, L as sandboxSkillPathResolution, M as SANDBOX_REPOS_ROOT, N as SANDBOX_SKILLS_ROOT, P as SANDBOX_WORKSPACE_ROOT, _ as workspaceSnapshotNotReadyUserMessage, a as isAbortError, b as buildNonInteractiveShellScript, c as isSandboxCommandStreamInterruptedError, d as isSnapshottingError, f as throwSandboxOperationError, g as isWorkspaceSnapshotNotReadyError, h as getWorkspaceSnapshotNotReadyError, i as ensureDockerDaemon, j as SANDBOX_DATA_ROOT, k as withLock, l as isSandboxMissingError, m as WorkspaceSnapshotNotReadyError, n as hash, o as isAlreadyExistsError, p as wrapSandboxSetupError, r as isStale, s as isSandboxApiTransientError, t as create, u as isSandboxUnavailableError, v as getVercelSandboxCredentials, w as getStateAdapter, x as runNonInteractiveCommand, y as buildCommandScript } from "./profile-BsNrw8lj.js";
19
- import { $ as workspaceSnapshotFinishedEvent, B as createEventAutomation, C as SCHEDULED_AUTOMATION_SYSTEM_ACTOR, D as eventAutomationMatchesDestination, E as eventAutomationListToolResultSchema, F as effectiveTaskOutcomes, Gt as makeStructuredToolOutput, I as moveTaskOutcomes, Jt as ToolInputError, L as resolveTaskOutcomes, M as requireEventAutomationSlackContext, N as requireSupportedEventAutomationTrigger, O as eventAutomationToolResult, P as writableEventAutomation, Q as WORKSPACE_SNAPSHOT_READY_EVENT, R as taskOutcomeInputSchema, T as compactEventAutomation, Ut as injectContinuationToolName, V as deleteEventAutomation, W as getEventAutomation, Wt as juniorToolOutputSchema, X as getEventCatalog, Y as saveEventAutomation, Z as WORKSPACE_SNAPSHOT_FAILED_EVENT, at as normalizeCatalogEventIdentifier, c as parseSlackThreadId, ct as registeredEventTypeSchema, et as workspaceSnapshotWatch, f as createScheduledAutomation, g as listScheduledAutomationsForTeam, i as readLiveAttachment, it as hasPluginEventCatalogEntries, j as registeredEventAutomationTriggerSchema, k as eventAutomationToolResultSchema, lt as registeredResourceTypeSchema, nt as eventNamespaceSchema, ot as pluginSupportsEvent, pt as appendAndEnqueueInboundMessage, q as listEventAutomationsForTeam, rt as hasEventCatalogEntries, s as storeAttachments, st as registeredEventMatchSchema, t as incrementStat, tt as eventGuidance, ut as requireSupportedEventMatch, v as readScheduledAutomation, y as saveScheduledAutomation } from "./stats-pNGp3G5q.js";
20
- import { _ as isTurnInputCommitLostError, c as sanitizeAssistantText, f as CooperativeTurnYieldError, l as NO_REPLY_MARKER, n as canReusePendingAuthLink, o as decideReply, p as TurnInputCommitLostError, s as getAssistantReplyText, t as abandonReplacedPendingAuth, u as isNoReplyMarker } from "./pending-auth-D7vmttn_.js";
21
- import { C as toolInvocationDestination, S as surfaceFromRun, _ as uploadFilesToConversation, b as assertRunConsistency, h as postSlackMessage, i as formatProviderLabel, m as getSlackMessagePermalink, o as resolveBaseUrl, p as addReactionToMessage, r as deliverOAuthAuthorization, s as startOAuthFlow, v as RetryableDeliveryError, x as isAgentRunFeatureDisabled, y as actorFromRun } from "./agent-runner-2VQ9WhkG.js";
14
+ import { a as resolveAuthTokenPlaceholder, c as fetchWithBoundedOAuthErrorBodies, d as CredentialUnavailableError, i as resolvePluginHeaderEnvRefs, l as getOAuthProviderErrorAttributes, o as resolvePluginCommandEnv, s as OAuthProviderError } from "./registry-Ctgdjt-W.js";
15
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-CVZ9TEuK.js";
16
+ import { a as parseSkillInvocation, n as findSkillByName, r as loadSkillsByName, t as discoverSkills } from "./skills-c2bMDVRS.js";
17
+ import { C as isToolResultError, D as stripRuntimeTurnContext, E as retainRuntimeTurnContext, F as loadTurnRoute, G as recordToolExecutionStarted, H as recordGuardianActionReviewed, I as openConversationProjection, K as recordTurnRoute, L as recordAgentsInstructionsUpdated, M as loadConnectedMcpProviders, N as loadConversationProjection, O as trimTrailingAssistantMessages, R as recordAttachmentsDelivered, S as isContinuablePiBoundary, T as normalizeToolNameFromResult, U as recordMcpProviderConnected, V as recordAuthorizationRequested, _ as getTerminalAssistantMessages, d as TurnSliceLimitExceededError, dt as getAgentContextCompactionTriggerTokens, f as assertTurnToolCallLimit, ft as getAgentContextInputLimitTokens, g as getPiMessageRole, h as extractAssistantText, i as abandonTurnRecord, k as TURN_CONTEXT_TAG, m as isTurnExecutionLimitExceededError, mt as piMessageFromHistoryItem, n as loadTurnCheckpoint, pt as historyItemFromPiMessage, r as saveTurnCheckpoint, t as continuableMessages, ut as estimateTextTokens, v as getUserMessageInstructionText, w as isToolResultMessage, x as isAssistantMessage, y as hasRuntimeTurnContext } from "./checkpoint-Ceck_fLO.js";
18
+ import { n as generateShortTitle, r as resolveTaskTitle, t as fallbackShortTitle } from "./short-title-xEkZwkcV.js";
19
+ import { A as SANDBOX_DATA_ROOT, D as fenceLock, E as acquireActiveLock, F as sandboxSkillFile, I as sandboxSkillPathResolution, M as SANDBOX_SKILLS_ROOT, N as SANDBOX_WORKSPACE_ROOT, O as withLock, P as sandboxSkillDir, _ as workspaceSnapshotNotReadyUserMessage, a as isAbortError, b as buildNonInteractiveShellScript, c as isSandboxCommandStreamInterruptedError, d as isSnapshottingError, f as throwSandboxOperationError, g as isWorkspaceSnapshotNotReadyError, h as getWorkspaceSnapshotNotReadyError, i as ensureDockerDaemon, j as SANDBOX_REPOS_ROOT, k as sleep$1, l as isSandboxMissingError, m as WorkspaceSnapshotNotReadyError, n as hash, o as isAlreadyExistsError, p as wrapSandboxSetupError, r as isStale, s as isSandboxApiTransientError, t as create, u as isSandboxUnavailableError, v as getVercelSandboxCredentials, w as getStateAdapter, x as runNonInteractiveCommand, y as buildCommandScript } from "./profile-6KWhg_-U.js";
20
+ import { $ as workspaceSnapshotFinishedEvent, B as createEventAutomation, C as SCHEDULED_AUTOMATION_SYSTEM_ACTOR, D as eventAutomationMatchesDestination, E as eventAutomationListToolResultSchema, F as effectiveTaskOutcomes, Gt as makeStructuredToolOutput, I as moveTaskOutcomes, Jt as ToolInputError, L as resolveTaskOutcomes, M as requireEventAutomationSlackContext, N as requireSupportedEventAutomationTrigger, O as eventAutomationToolResult, P as writableEventAutomation, Q as WORKSPACE_SNAPSHOT_READY_EVENT, R as taskOutcomeInputSchema, T as compactEventAutomation, Ut as injectContinuationToolName, V as deleteEventAutomation, W as getEventAutomation, Wt as juniorToolOutputSchema, X as getEventCatalog, Y as saveEventAutomation, Z as WORKSPACE_SNAPSHOT_FAILED_EVENT, at as normalizeCatalogEventIdentifier, c as parseSlackThreadId, ct as registeredEventTypeSchema, et as workspaceSnapshotWatch, f as createScheduledAutomation, g as listScheduledAutomationsForTeam, i as readLiveAttachment, it as hasPluginEventCatalogEntries, j as registeredEventAutomationTriggerSchema, k as eventAutomationToolResultSchema, lt as registeredResourceTypeSchema, nt as eventNamespaceSchema, ot as pluginSupportsEvent, pt as appendAndEnqueueInboundMessage, q as listEventAutomationsForTeam, qt as buildDeterministicTurnId, rt as hasEventCatalogEntries, s as storeAttachments, st as registeredEventMatchSchema, t as incrementStat, tt as eventGuidance, ut as requireSupportedEventMatch, v as readScheduledAutomation, y as saveScheduledAutomation } from "./stats-DP9zl3Jg.js";
21
+ import { a as NO_REPLY_MARKER, c as CooperativeTurnYieldError, i as sanitizeAssistantText, l as TurnInputCommitLostError, n as decideReply, o as isNoReplyMarker, p as isTurnInputCommitLostError, r as getAssistantReplyText, t as authorizationId } from "./oauth-authorization-BIijVS2N.js";
22
22
  import { r as EVENT_AUTHOR_ID } from "./prompt-90miy8VV.js";
23
- import { a as createSandboxSession, c as postinstall, d as getSandboxResources, i as bindSandboxFileSystem, l as setSnapshotSpanAttributes, n as isMissingError, o as stopSession, r as resolve$1, s as dependencies } from "./resolve-B38CpJe2.js";
23
+ import { a as createSandboxSession, c as postinstall, d as getSandboxResources, i as bindSandboxFileSystem, l as setSnapshotSpanAttributes, n as isMissingError, o as stopSession, r as resolve$1, s as dependencies } from "./resolve-CB45ZukQ.js";
24
24
  import { t as getVercelConversationWorkQueue } from "./vercel-queue-DIkVcfK4.js";
25
- import { a as getTurnRequestDeadline, n as sendNextWorkspaceSnapshotJob, r as sendWorkspaceSnapshotJob } from "./job-queue-CNd9cpIy.js";
25
+ import { a as getTurnRequestDeadline, n as sendNextWorkspaceSnapshotJob, r as sendWorkspaceSnapshotJob } from "./job-queue-D4oAVrL9.js";
26
26
  import { n as privateTraceResultAttributes } from "./private-trace-result-BLvBjy_e.js";
27
27
  import { streamSimple } from "@earendil-works/pi-ai/compat";
28
28
  import { createGatewayProvider } from "@ai-sdk/gateway";
@@ -31,7 +31,7 @@ import path from "node:path";
31
31
  import { isDeepStrictEqual } from "node:util";
32
32
  import { AsyncLocalStorage } from "node:async_hooks";
33
33
  import { z } from "zod";
34
- import { createHash, createHmac, randomUUID, timingSafeEqual } from "node:crypto";
34
+ import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
35
35
  import { and, desc, eq, gt, gte, inArray, isNull, lt, ne, notExists, or, sql } from "drizzle-orm";
36
36
  import { EgressAuthRequired, EgressPolicyDenied, PluginToolInputError, actorSchema, destinationSchema, eventSchema, missingToolAnnotationKeys, ownedObjectAnnotationSchema, pluginAuthorizationSchema, pluginCredentialHeaderTransformSchema, pluginCredentialResultSchema, pluginGrantSchema, pluginProviderAccountSchema, pluginStoredTokensSchema, sourceSchema, stableEventMatchKey, watchResultSchema } from "@sentry/junior-plugin-api";
37
37
  import { alias } from "drizzle-orm/pg-core";
@@ -1140,6 +1140,73 @@ var AuthorizationFlowDisabledError = class extends Error {
1140
1140
  }
1141
1141
  };
1142
1142
  //#endregion
1143
+ //#region src/chat/agent/types.ts
1144
+ /** Resume the agent turn after a transient or ambiguous delivery failure. */
1145
+ var RetryableDeliveryError = class extends Error {
1146
+ constructor(cause) {
1147
+ super("Assistant delivery was transient or ambiguous", { cause });
1148
+ this.name = "RetryableDeliveryError";
1149
+ }
1150
+ };
1151
+ /** Return whether one optional agent capability is disabled for this run. */
1152
+ function isAgentRunFeatureDisabled(disabledFeatures, feature) {
1153
+ return disabledFeatures?.includes(feature) ?? false;
1154
+ }
1155
+ /** Resolve the explicit actor, dispatch actor, or credential actor for this run. */
1156
+ function actorFromRun(run) {
1157
+ if (run.dispatch?.actor) return run.dispatch.actor;
1158
+ if (run.actor) return run.actor;
1159
+ if (run.credentialContext && !("type" in run.credentialContext.actor)) return run.credentialContext.actor;
1160
+ }
1161
+ /** Reject contradictory provider coordinates before the run touches state. */
1162
+ function assertRunConsistency(run) {
1163
+ const { destination, source } = run;
1164
+ switch (source.kind) {
1165
+ case "slack":
1166
+ if (destination.platform !== "slack") throw new TypeError("Run source and destination platforms do not match");
1167
+ if (source.teamId !== destination.teamId) throw new TypeError("Slack source and destination teams do not match");
1168
+ break;
1169
+ case "local":
1170
+ if (destination.platform !== "local") throw new TypeError("Run source and destination platforms do not match");
1171
+ if (source.conversationId !== destination.conversationId) throw new TypeError("Source and destination conversation IDs do not match");
1172
+ if (run.surface !== "internal" && destination.conversationId !== run.conversationId) throw new TypeError("Source, destination, and run conversation IDs do not match");
1173
+ break;
1174
+ case "web":
1175
+ if (run.surface !== "internal" && source.conversationId !== run.conversationId) throw new TypeError("Web source and run conversation IDs do not match");
1176
+ switch (destination.platform) {
1177
+ case "local":
1178
+ if (source.conversationId !== destination.conversationId) throw new TypeError("Source and destination conversation IDs do not match");
1179
+ if (run.surface !== "internal" && destination.conversationId !== run.conversationId) throw new TypeError("Source, destination, and run conversation IDs do not match");
1180
+ }
1181
+ break;
1182
+ case "event":
1183
+ case "scheduled_automation":
1184
+ case "event_automation":
1185
+ case "plugin_dispatch":
1186
+ case "agent_invocation": return;
1187
+ }
1188
+ const actor = run.dispatch?.actor ?? run.actor;
1189
+ if (!actor || actor.platform === "system") return;
1190
+ if (actor.platform !== source.kind) throw new TypeError(`Actor platform "${actor.platform}" does not match Source kind "${source.kind}"`);
1191
+ if (actor.platform === "slack" && source.kind === "slack" && actor.teamId !== source.teamId) throw new TypeError("Slack Actor team does not match Source team");
1192
+ }
1193
+ /** Route tool side effects to the tool channel when one overrides the destination. */
1194
+ function toolInvocationDestination(run) {
1195
+ if (run.destination.platform !== "slack" || !run.toolChannelId) return run.destination;
1196
+ return {
1197
+ platform: "slack",
1198
+ teamId: run.destination.teamId,
1199
+ channelId: run.toolChannelId
1200
+ };
1201
+ }
1202
+ /** Infer the run surface when the caller did not state one. */
1203
+ function surfaceFromRun(run) {
1204
+ if (run.surface) return run.surface;
1205
+ if (run.source.kind === "slack") return "slack";
1206
+ if (run.source.kind === "web") return "api";
1207
+ return "internal";
1208
+ }
1209
+ //#endregion
1143
1210
  //#region src/chat/tool-support/action-review-history.ts
1144
1211
  const MAX_VISIBLE_HISTORY_CHARS = 12e3;
1145
1212
  const priorRejectionSchema = z.object({
@@ -2524,6 +2591,570 @@ function formatSandboxCommandResult(params) {
2524
2591
  });
2525
2592
  }
2526
2593
  //#endregion
2594
+ //#region src/chat/slack/outbound.ts
2595
+ const MAX_SLACK_MESSAGE_TEXT_CHARS = 4e4;
2596
+ function requireSlackConversationId(channelId, action) {
2597
+ const normalized = normalizeSlackConversationId(channelId);
2598
+ if (!normalized) throw new Error(`${action} requires a valid channel ID`);
2599
+ return normalized;
2600
+ }
2601
+ function requireSlackThreadTimestamp(threadTs, action) {
2602
+ const normalized = threadTs.trim();
2603
+ if (!normalized) throw new Error(`${action} requires a thread timestamp`);
2604
+ return normalized;
2605
+ }
2606
+ function requireSlackMessageTimestamp(timestamp, action) {
2607
+ const normalized = parseSlackMessageTs(timestamp);
2608
+ if (!normalized) throw new Error(`${action} requires a target message timestamp`);
2609
+ return normalized;
2610
+ }
2611
+ function requireSlackMessageText(text, action) {
2612
+ if (text.trim().length === 0) throw new Error(`${action} requires non-empty text`);
2613
+ if (text.length > MAX_SLACK_MESSAGE_TEXT_CHARS) throw new Error(`${action} text exceeds Slack's 40000 character truncation limit`);
2614
+ return text;
2615
+ }
2616
+ /** Resolve a Slack message permalink without making read-only workflows fail on lookup errors. */
2617
+ async function getSlackMessagePermalink(args) {
2618
+ try {
2619
+ return (await withSlackRetries(() => getSlackClient().chat.getPermalink({
2620
+ channel: args.channelId,
2621
+ message_ts: args.messageTs
2622
+ }), 3, {
2623
+ action: "chat.getPermalink",
2624
+ idempotent: true,
2625
+ spanAttributes: {
2626
+ "app.slack.channel_id": args.channelId,
2627
+ "app.slack.message_ts": args.messageTs
2628
+ }
2629
+ })).permalink;
2630
+ } catch {
2631
+ return;
2632
+ }
2633
+ }
2634
+ /** Post Slack `mrkdwn` text to a conversation or thread via the shared outbound boundary. */
2635
+ async function postSlackMessage(input) {
2636
+ const channelId = requireSlackConversationId(input.channelId, "Slack message posting");
2637
+ const text = requireSlackMessageText(input.text, "Slack message posting");
2638
+ const threadTs = input.threadTs ? requireSlackThreadTimestamp(input.threadTs, "Slack thread message posting") : void 0;
2639
+ const response = await withSlackRetries(() => getSlackClient().chat.postMessage({
2640
+ channel: channelId,
2641
+ text,
2642
+ unfurl_links: false,
2643
+ unfurl_media: false,
2644
+ ...input.blocks?.length ? { blocks: input.blocks } : void 0,
2645
+ ...input.entities?.length ? { metadata: { entities: input.entities } } : void 0,
2646
+ ...threadTs ? { thread_ts: threadTs } : void 0
2647
+ }), 3, {
2648
+ action: "chat.postMessage",
2649
+ spanAttributes: {
2650
+ "app.slack.channel_id": channelId,
2651
+ ...threadTs ? { "app.slack.thread_ts": threadTs } : void 0
2652
+ }
2653
+ });
2654
+ const messageTs = parseSlackMessageTs(response.ts);
2655
+ if (!messageTs) throw new Error("Slack message posted without ts");
2656
+ return {
2657
+ ts: messageTs,
2658
+ ...input.includePermalink ? { permalink: await getSlackMessagePermalink({
2659
+ channelId,
2660
+ messageTs
2661
+ }) } : void 0
2662
+ };
2663
+ }
2664
+ /**
2665
+ * Post an ephemeral Slack message. Delivery is best-effort on Slack's side, but
2666
+ * request validation and Web API behavior are centralized here.
2667
+ */
2668
+ async function postSlackEphemeralMessage(input) {
2669
+ const channelId = requireSlackConversationId(input.channelId, "Slack ephemeral message posting");
2670
+ const userId = parseSlackUserId(input.userId);
2671
+ if (!userId) throw new Error("Slack ephemeral message posting requires a user ID");
2672
+ const text = requireSlackMessageText(input.text, "Slack ephemeral message posting");
2673
+ const threadTs = input.threadTs ? requireSlackThreadTimestamp(input.threadTs, "Slack ephemeral thread message posting") : void 0;
2674
+ return { messageTs: (await withSlackRetries(() => getSlackClient().chat.postEphemeral({
2675
+ channel: channelId,
2676
+ user: userId,
2677
+ text,
2678
+ ...input.blocks?.length ? { blocks: input.blocks } : void 0,
2679
+ ...threadTs ? { thread_ts: threadTs } : void 0
2680
+ }), 3, {
2681
+ action: "chat.postEphemeral",
2682
+ spanAttributes: {
2683
+ "app.slack.channel_id": channelId,
2684
+ "app.slack.user_id": userId,
2685
+ ...threadTs ? { "app.slack.thread_ts": threadTs } : void 0
2686
+ }
2687
+ })).message_ts };
2688
+ }
2689
+ /** Upload files into a Slack conversation or thread via the shared outbound file boundary. */
2690
+ async function uploadFilesToConversation(input) {
2691
+ const channelId = requireSlackConversationId(input.channelId, "Slack file upload");
2692
+ const threadTs = input.threadTs ? requireSlackThreadTimestamp(input.threadTs, "Slack file upload") : void 0;
2693
+ if (input.files.length === 0) throw new Error("Slack file upload requires at least one file");
2694
+ const fileUploads = input.files.map((file) => {
2695
+ const filename = file.filename.trim();
2696
+ if (!filename) throw new Error("Slack file upload requires every file to have a filename");
2697
+ return {
2698
+ file: file.data,
2699
+ filename
2700
+ };
2701
+ });
2702
+ return { files: ((await withSlackRetries(() => getSlackClient().filesUploadV2({
2703
+ channel_id: channelId,
2704
+ ...threadTs ? { thread_ts: threadTs } : void 0,
2705
+ file_uploads: fileUploads
2706
+ }), 3, {
2707
+ action: "filesUploadV2",
2708
+ spanAttributes: {
2709
+ "app.slack.channel_id": channelId,
2710
+ ...threadTs ? { "app.slack.thread_ts": threadTs } : void 0
2711
+ }
2712
+ })).files ?? []).flatMap((completion) => (completion.files ?? []).map((file) => file.id ? { id: file.id } : {})) };
2713
+ }
2714
+ /** Add a reaction to a Slack message, treating `already_reacted` as idempotent success. */
2715
+ async function addReactionToMessage(input) {
2716
+ const channelId = requireSlackConversationId(input.channelId, "Slack reaction");
2717
+ const timestamp = requireSlackMessageTimestamp(input.timestamp, "Slack reaction");
2718
+ const emoji = normalizeSlackEmojiName(input.emoji);
2719
+ if (!emoji) throw new Error("Slack reaction requires a valid emoji alias name");
2720
+ try {
2721
+ await withSlackRetries(() => getSlackClient().reactions.add({
2722
+ channel: channelId,
2723
+ timestamp,
2724
+ name: emoji
2725
+ }), 3, {
2726
+ action: "reactions.add",
2727
+ idempotent: true,
2728
+ spanAttributes: {
2729
+ "app.slack.channel_id": channelId,
2730
+ "app.slack.message_ts": timestamp,
2731
+ "app.slack.reaction": emoji
2732
+ }
2733
+ });
2734
+ } catch (error) {
2735
+ if (error instanceof SlackActionError && error.code === "already_reacted") return { ok: true };
2736
+ throw error;
2737
+ }
2738
+ return { ok: true };
2739
+ }
2740
+ /** Remove a reaction from a Slack message, treating `no_reaction` as idempotent success. */
2741
+ async function removeReactionFromMessage(input) {
2742
+ const channelId = requireSlackConversationId(input.channelId, "Slack reaction removal");
2743
+ const timestamp = requireSlackMessageTimestamp(input.timestamp, "Slack reaction removal");
2744
+ const emoji = normalizeSlackEmojiName(input.emoji);
2745
+ if (!emoji) throw new Error("Slack reaction removal requires a valid emoji alias name");
2746
+ try {
2747
+ await withSlackRetries(() => getSlackClient().reactions.remove({
2748
+ channel: channelId,
2749
+ timestamp,
2750
+ name: emoji
2751
+ }), 3, {
2752
+ action: "reactions.remove",
2753
+ idempotent: true,
2754
+ spanAttributes: {
2755
+ "app.slack.channel_id": channelId,
2756
+ "app.slack.message_ts": timestamp,
2757
+ "app.slack.reaction": emoji
2758
+ }
2759
+ });
2760
+ } catch (error) {
2761
+ if (error instanceof SlackActionError && error.code === "no_reaction") return { ok: true };
2762
+ throw error;
2763
+ }
2764
+ return { ok: true };
2765
+ }
2766
+ //#endregion
2767
+ //#region src/chat/slack/status-format.ts
2768
+ const SLACK_STATUS_MAX_LENGTH = 50;
2769
+ /** Truncate a status string to fit Slack's 50-char assistant status limit. */
2770
+ function truncateStatusText(text) {
2771
+ const trimmed = text.trim();
2772
+ if (!trimmed) return "";
2773
+ if (trimmed.length <= SLACK_STATUS_MAX_LENGTH) return trimmed;
2774
+ return `${trimmed.slice(0, 47).trimEnd()}...`;
2775
+ }
2776
+ //#endregion
2777
+ //#region src/chat/slack/mrkdwn.ts
2778
+ /** Escape dynamic text for Slack mrkdwn without changing intended formatting. */
2779
+ function escapeSlackMrkdwnText(text) {
2780
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
2781
+ }
2782
+ /** Escape a URL for Slack explicit link syntax while preserving query semantics. */
2783
+ function escapeSlackLinkUrl(url) {
2784
+ return url.replaceAll("&", "&amp;").replaceAll("<", "%3C").replaceAll(">", "%3E");
2785
+ }
2786
+ /** Build a Slack explicit link from dynamic URL and label values. */
2787
+ function formatSlackLink(url, label) {
2788
+ return `<${escapeSlackLinkUrl(url)}|${escapeSlackMrkdwnText(label)}>`;
2789
+ }
2790
+ function readInlineCodeSpan(line, start) {
2791
+ if (line[start] !== "`") return;
2792
+ let n = 1;
2793
+ while (line[start + n] === "`") n++;
2794
+ const marker = "`".repeat(n);
2795
+ let search = start + n;
2796
+ while (search < line.length) {
2797
+ const close = line.indexOf(marker, search);
2798
+ if (close === -1) return;
2799
+ const after = close + n;
2800
+ if (line[after] !== "`") return {
2801
+ text: line.slice(start, after),
2802
+ end: after
2803
+ };
2804
+ search = after + 1;
2805
+ }
2806
+ }
2807
+ function readExistingSlackAngleToken(line, start) {
2808
+ if (line[start] !== "<") return;
2809
+ const close = line.indexOf(">", start + 1);
2810
+ if (close === -1) return;
2811
+ const body = line.slice(start + 1, close);
2812
+ if (/^(?:https?:\/\/|@|#|!)/.test(body)) return {
2813
+ text: line.slice(start, close + 1),
2814
+ end: close + 1
2815
+ };
2816
+ }
2817
+ function readMarkdownLink(line, start) {
2818
+ if (line[start] !== "[") return;
2819
+ const labelEnd = line.indexOf("](", start + 1);
2820
+ if (labelEnd === -1) return;
2821
+ const destStart = labelEnd + 2;
2822
+ if (!line.startsWith("http://", destStart) && !line.startsWith("https://", destStart)) return;
2823
+ const closeParens = line.indexOf(")", destStart);
2824
+ if (closeParens === -1) return;
2825
+ return {
2826
+ text: line.slice(start, closeParens + 1),
2827
+ end: closeParens + 1
2828
+ };
2829
+ }
2830
+ function hasUnmatchedClosingParen(text) {
2831
+ let balance = 0;
2832
+ for (const ch of text) if (ch === "(") balance++;
2833
+ else if (ch === ")") balance--;
2834
+ return balance < 0;
2835
+ }
2836
+ function readBareUrl(line, start) {
2837
+ let end = start;
2838
+ while (end < line.length) {
2839
+ const ch = line[end];
2840
+ if (/\s/.test(ch) || ch === "<" || ch === ">" || ch === "\"" || ch === "`" || ch === "|" || ch === "*") break;
2841
+ end++;
2842
+ }
2843
+ if (end === start) return;
2844
+ let raw = line.slice(start, end);
2845
+ let suffix = "";
2846
+ const peel = () => {
2847
+ suffix = raw.slice(-1) + suffix;
2848
+ raw = raw.slice(0, -1);
2849
+ };
2850
+ const shouldPeel = () => raw.endsWith("_") || /[.,!?;:]$/.test(raw) || raw.endsWith(")") && hasUnmatchedClosingParen(raw);
2851
+ while (raw.length > 0 && shouldPeel()) peel();
2852
+ if (!/^https?:\/\/.+/.test(raw)) return;
2853
+ return {
2854
+ url: raw,
2855
+ suffix,
2856
+ end
2857
+ };
2858
+ }
2859
+ /** Wrap bare http(s) URLs on a single line as Slack explicit `<url>` links. */
2860
+ function wrapBareUrlsOnLine(line) {
2861
+ let result = "";
2862
+ let i = 0;
2863
+ while (i < line.length) {
2864
+ const codeSpan = readInlineCodeSpan(line, i);
2865
+ if (codeSpan) {
2866
+ result += codeSpan.text;
2867
+ i = codeSpan.end;
2868
+ continue;
2869
+ }
2870
+ const angleToken = readExistingSlackAngleToken(line, i);
2871
+ if (angleToken) {
2872
+ result += angleToken.text;
2873
+ i = angleToken.end;
2874
+ continue;
2875
+ }
2876
+ const mdLink = readMarkdownLink(line, i);
2877
+ if (mdLink) {
2878
+ result += mdLink.text;
2879
+ i = mdLink.end;
2880
+ continue;
2881
+ }
2882
+ if (line.startsWith("https://", i) || line.startsWith("http://", i)) {
2883
+ const parsed = readBareUrl(line, i);
2884
+ if (parsed) {
2885
+ result += `<${parsed.url}>${parsed.suffix}`;
2886
+ i = parsed.end;
2887
+ continue;
2888
+ }
2889
+ }
2890
+ result += line[i];
2891
+ i++;
2892
+ }
2893
+ return result;
2894
+ }
2895
+ /**
2896
+ * Pre-wrap bare http(s) URLs outside fenced code blocks as Slack explicit
2897
+ * links, preventing Slack's auto-linker from consuming adjacent formatting
2898
+ * markers into the URL.
2899
+ *
2900
+ * Uses the same fence-toggle rule as `ensureBlockSpacing` so both passes
2901
+ * agree on which lines are code.
2902
+ */
2903
+ function wrapBareUrls(text) {
2904
+ const lines = text.split("\n");
2905
+ const out = [];
2906
+ let inCodeBlock = false;
2907
+ for (const line of lines) {
2908
+ if (line.trimStart().startsWith("```")) {
2909
+ inCodeBlock = !inCodeBlock;
2910
+ out.push(line);
2911
+ continue;
2912
+ }
2913
+ out.push(inCodeBlock ? line : wrapBareUrlsOnLine(line));
2914
+ }
2915
+ return out.join("\n");
2916
+ }
2917
+ /** Insert blank lines between content blocks so Slack renders them with visual separation. */
2918
+ function ensureBlockSpacing(text) {
2919
+ const codeBlockPattern = /^```/;
2920
+ const listItemPattern = /^[-*•]\s|^\d+\.\s/;
2921
+ const lines = text.split("\n");
2922
+ const result = [];
2923
+ let inCodeBlock = false;
2924
+ for (let i = 0; i < lines.length; i++) {
2925
+ const line = lines[i];
2926
+ if (codeBlockPattern.test(line.trimStart())) {
2927
+ if (!inCodeBlock) {
2928
+ const prev = result.length > 0 ? result[result.length - 1] : void 0;
2929
+ if (prev !== void 0 && prev.trim() !== "") result.push("");
2930
+ }
2931
+ inCodeBlock = !inCodeBlock;
2932
+ result.push(line);
2933
+ continue;
2934
+ }
2935
+ if (inCodeBlock) {
2936
+ result.push(line);
2937
+ continue;
2938
+ }
2939
+ const prev = result.length > 0 ? result[result.length - 1] : void 0;
2940
+ if (prev !== void 0 && prev.trim() !== "" && line.trim() !== "" && !(listItemPattern.test(prev.trimStart()) && listItemPattern.test(line.trimStart()))) result.push("");
2941
+ result.push(line);
2942
+ }
2943
+ return result.join("\n");
2944
+ }
2945
+ /**
2946
+ * Normalize model-authored Slack markdown for delivery via `markdown_text`
2947
+ * or `{ type: "markdown" }` blocks.
2948
+ *
2949
+ * Plugins may first rewrite ordinary Markdown. Core then applies Slack-only
2950
+ * delivery shaping: bare URL wrapping and block spacing. Slack reply delivery
2951
+ * owns chunking and continuation markers separately.
2952
+ */
2953
+ function normalizeSlackReplyMarkdown(text) {
2954
+ let normalized = applyPluginFormatMarkdown(text).replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "");
2955
+ normalized = wrapBareUrls(normalized);
2956
+ normalized = ensureBlockSpacing(normalized);
2957
+ return normalized.replace(/\n{3,}/g, "\n\n").trim();
2958
+ }
2959
+ /** Normalize assistant status text before handing it to Slack. */
2960
+ function normalizeSlackStatusText(text) {
2961
+ const trimmed = text.trim();
2962
+ if (!trimmed) return "";
2963
+ return truncateStatusText(trimmed.replace(/(?:\.\s*)+$/, "").trim());
2964
+ }
2965
+ //#endregion
2966
+ //#region src/chat/slack/oauth-authorization-message.ts
2967
+ /** Present private OAuth authorization with a clear action and text fallback. */
2968
+ function buildSlackOAuthAuthorizationMessage(args) {
2969
+ return {
2970
+ text: `${formatSlackLink(args.authorizationUrl, args.label)}. ${args.completionText}`,
2971
+ blocks: [{
2972
+ type: "section",
2973
+ text: {
2974
+ type: "mrkdwn",
2975
+ text: `*${escapeSlackMrkdwnText(args.label)}*\n${escapeSlackMrkdwnText(args.completionText)}`
2976
+ },
2977
+ accessory: {
2978
+ type: "button",
2979
+ text: {
2980
+ type: "plain_text",
2981
+ text: "Connect"
2982
+ },
2983
+ style: "primary",
2984
+ url: args.authorizationUrl,
2985
+ action_id: "oauth_connect"
2986
+ }
2987
+ }]
2988
+ };
2989
+ }
2990
+ //#endregion
2991
+ //#region src/chat/oauth-flow.ts
2992
+ const OAUTH_STATE_TTL_MS = 6e5;
2993
+ function optionalString(value) {
2994
+ return typeof value === "string" ? value : void 0;
2995
+ }
2996
+ /** Parse OAuth callback state that was persisted before a provider redirect. */
2997
+ function parseOAuthStatePayload(value) {
2998
+ if (!isRecord$2(value)) return;
2999
+ if (typeof value.userId !== "string" || typeof value.provider !== "string") return;
3000
+ const actor = value.actor === void 0 ? void 0 : actorSchema.safeParse(value.actor);
3001
+ if (value.actor !== void 0 && (!actor || !actor.success)) return;
3002
+ const destination = parseDestination(value.destination);
3003
+ if (value.destination !== void 0 && !destination) return;
3004
+ const source = value.source === void 0 ? void 0 : sourceSchema.safeParse(value.source);
3005
+ if (value.source !== void 0 && (!source || !source.success)) return;
3006
+ return {
3007
+ userId: value.userId,
3008
+ provider: value.provider,
3009
+ ...actor?.success ? { actor: actor.data } : void 0,
3010
+ ...optionalString(value.channelId) ? { channelId: optionalString(value.channelId) } : void 0,
3011
+ ...destination ? { destination } : void 0,
3012
+ ...source?.success ? { source: source.data } : void 0,
3013
+ ...optionalString(value.threadTs) ? { threadTs: optionalString(value.threadTs) } : void 0,
3014
+ ...optionalString(value.resumeConversationId) ? { resumeConversationId: optionalString(value.resumeConversationId) } : void 0,
3015
+ ...optionalString(value.resumeSessionId) ? { resumeSessionId: optionalString(value.resumeSessionId) } : void 0,
3016
+ ...optionalString(value.scope) ? { scope: optionalString(value.scope) } : void 0
3017
+ };
3018
+ }
3019
+ /** Return the manifest-owned display label for a provider. */
3020
+ function formatProviderLabel(provider) {
3021
+ const displayName = pluginCatalogRuntime.getDisplayName(provider);
3022
+ if (!displayName) throw new Error(`Unknown plugin provider display name: "${provider}"`);
3023
+ return displayName;
3024
+ }
3025
+ /** Resolve the public base URL from environment variables (JUNIOR_BASE_URL or Vercel). */
3026
+ function resolveBaseUrl() {
3027
+ const explicit = process.env.JUNIOR_BASE_URL?.trim();
3028
+ if (explicit) return explicit;
3029
+ const vercelProd = process.env.VERCEL_PROJECT_PRODUCTION_URL?.trim();
3030
+ if (vercelProd) return `https://${vercelProd}`;
3031
+ const vercelUrl = process.env.VERCEL_URL?.trim();
3032
+ if (vercelUrl) return `https://${vercelUrl}`;
3033
+ }
3034
+ /**
3035
+ * Authorization links must only be visible to the requesting user.
3036
+ * Try in-context private delivery first, then fall back to a DM.
3037
+ */
3038
+ async function deliverPrivateMessage(input) {
3039
+ let client;
3040
+ try {
3041
+ client = getSlackClient();
3042
+ } catch {
3043
+ logWarn("oauth.private_delivery.skipped", { "app.reason": "missing_bot_token" });
3044
+ return false;
3045
+ }
3046
+ if (input.channelId) try {
3047
+ if (isDmChannel$1(input.channelId)) await postSlackMessage({
3048
+ channelId: input.channelId,
3049
+ text: input.text,
3050
+ blocks: input.blocks,
3051
+ threadTs: input.threadTs
3052
+ });
3053
+ else await postSlackEphemeralMessage({
3054
+ channelId: input.channelId,
3055
+ userId: input.userId,
3056
+ text: input.text,
3057
+ blocks: input.blocks,
3058
+ threadTs: input.threadTs
3059
+ });
3060
+ return "in_context";
3061
+ } catch (error) {
3062
+ logWarn("oauth.private_delivery.failed", {
3063
+ "app.slack.error": error instanceof Error ? error.message : String(error),
3064
+ "app.slack.channel": input.channelId
3065
+ });
3066
+ }
3067
+ try {
3068
+ const dmChannelId = (await withSlackRetries(() => client.conversations.open({ users: input.userId }), 3, {
3069
+ action: "conversations.open",
3070
+ spanAttributes: { "app.slack.user_id": input.userId }
3071
+ })).channel?.id;
3072
+ if (!dmChannelId) {
3073
+ logWarn("oauth.dm.fallback.failed", { "app.reason": "no_dm_channel_id" });
3074
+ return false;
3075
+ }
3076
+ await postSlackMessage({
3077
+ channelId: dmChannelId,
3078
+ text: input.text,
3079
+ blocks: input.blocks
3080
+ });
3081
+ return "fallback_dm";
3082
+ } catch (error) {
3083
+ logWarn("oauth.dm.fallback.failed", { "app.slack.error": error instanceof Error ? error.message : String(error) });
3084
+ return false;
3085
+ }
3086
+ }
3087
+ /** Present one OAuth request through the active surface's private delivery. */
3088
+ async function deliverOAuthAuthorization(request, input) {
3089
+ if (input.authorization) {
3090
+ await input.authorization.deliver(request);
3091
+ return "in_context";
3092
+ }
3093
+ return await deliverPrivateMessage({
3094
+ channelId: input.channelId,
3095
+ threadTs: input.threadTs,
3096
+ userId: input.userId,
3097
+ ...buildSlackOAuthAuthorizationMessage(request)
3098
+ });
3099
+ }
3100
+ /** Initiate an OAuth authorization code flow for a provider and deliver the auth link to the user. */
3101
+ async function startOAuthFlow(provider, input) {
3102
+ const providerConfig = pluginCatalogRuntime.getOAuthConfig(provider);
3103
+ if (!providerConfig) return {
3104
+ ok: false,
3105
+ error: `Provider "${provider}" does not support OAuth authorization`
3106
+ };
3107
+ const clientId = process.env[providerConfig.clientIdEnv]?.trim();
3108
+ if (!clientId) return {
3109
+ ok: false,
3110
+ error: `Missing ${providerConfig.clientIdEnv} environment variable`
3111
+ };
3112
+ const baseUrl = resolveBaseUrl();
3113
+ if (!baseUrl) return {
3114
+ ok: false,
3115
+ error: "Cannot determine base URL (set JUNIOR_BASE_URL or deploy to Vercel)"
3116
+ };
3117
+ const state = input.authorization ? await input.authorization.createState() : randomBytes(32).toString("hex");
3118
+ const requestedScope = input.scope ?? providerConfig.scope;
3119
+ await getStateAdapter().set(`oauth-state:${state}`, {
3120
+ userId: input.actorId,
3121
+ provider,
3122
+ ...input.actor ? { actor: input.actor } : void 0,
3123
+ ...input.channelId ? { channelId: input.channelId } : void 0,
3124
+ ...input.destination ? { destination: input.destination } : void 0,
3125
+ ...input.source ? { source: input.source } : void 0,
3126
+ ...input.threadTs ? { threadTs: input.threadTs } : void 0,
3127
+ ...input.resumeConversationId ? { resumeConversationId: input.resumeConversationId } : void 0,
3128
+ ...input.resumeSessionId ? { resumeSessionId: input.resumeSessionId } : void 0,
3129
+ ...requestedScope ? { scope: requestedScope } : void 0
3130
+ }, OAUTH_STATE_TTL_MS);
3131
+ const authorizeParams = new URLSearchParams({
3132
+ client_id: clientId,
3133
+ state,
3134
+ redirect_uri: `${baseUrl}${providerConfig.callbackPath}`,
3135
+ response_type: "code"
3136
+ });
3137
+ if (requestedScope) authorizeParams.set("scope", requestedScope);
3138
+ for (const [key, value] of Object.entries(providerConfig.authorizeParams ?? {})) authorizeParams.set(key, value);
3139
+ logInfo("jr_rpc.oauth.started", {
3140
+ "app.credential.provider": provider,
3141
+ ...input.activeSkillName ? { "app.skill.name": input.activeSkillName } : void 0
3142
+ });
3143
+ return {
3144
+ ok: true,
3145
+ delivery: await deliverOAuthAuthorization({
3146
+ authorizationUrl: `${providerConfig.authorizeEndpoint}?${authorizeParams.toString()}`,
3147
+ label: `Connect to ${formatProviderLabel(provider)}`,
3148
+ completionText: input.resumeSessionId ? "Once you've authorized, Junior will continue automatically." : "Once you've authorized, you'll see a confirmation in Slack."
3149
+ }, {
3150
+ authorization: input.authorization,
3151
+ channelId: input.channelId,
3152
+ threadTs: input.threadTs,
3153
+ userId: input.actorId
3154
+ })
3155
+ };
3156
+ }
3157
+ //#endregion
2527
3158
  //#region src/chat/sandbox/egress/schemas.ts
2528
3159
  const finiteNumberSchema = z.number().refine(Number.isFinite);
2529
3160
  const httpStatusSchema = z.number().int().min(100).max(599);
@@ -10220,13 +10851,12 @@ function createSendFilesTool(context, state, materializeFile, attachments) {
10220
10851
  files: materializedFiles,
10221
10852
  storage: attachments.storage
10222
10853
  }) : [];
10223
- const uploads = materializedFiles.map((file) => ({
10224
- data: file.data,
10225
- filename: file.filename
10226
- }));
10227
10854
  await uploadFilesToConversation({
10228
10855
  channelId: activeChannelId,
10229
- files: uploads,
10856
+ files: materializedFiles.map((file) => ({
10857
+ data: file.data,
10858
+ filename: file.filename
10859
+ })),
10230
10860
  ...threadTs ? { threadTs } : void 0
10231
10861
  });
10232
10862
  const delivered = stored.map((attachment, index) => {
@@ -13802,10 +14432,51 @@ function buildSandboxInput(toolName, params) {
13802
14432
  return params;
13803
14433
  }
13804
14434
  //#endregion
13805
- //#region src/chat/oauth-authorization.ts
13806
- /** Build the stable event identity shared by authorization request and completion. */
13807
- function authorizationId(args) {
13808
- return `${args.sessionId}:${args.kind}:${args.provider}`;
14435
+ //#region src/chat/services/pending-auth.ts
14436
+ const AUTH_LINK_REUSE_WINDOW_MS = 6e5;
14437
+ const NON_REQUEST_SKIPPED_REASON_PREFIXES = ["directed_to_other_party:", "side_conversation:"];
14438
+ function isSkippedNonRequest(reason) {
14439
+ return NON_REQUEST_SKIPPED_REASON_PREFIXES.some((prefix) => reason?.startsWith(prefix));
14440
+ }
14441
+ /** Decide whether the same agent-run session can reuse its fresh auth link. */
14442
+ function canReusePendingAuthLink(args) {
14443
+ const { pendingAuth } = args;
14444
+ if (!pendingAuth) return false;
14445
+ return pendingAuth.kind === args.kind && pendingAuth.provider === args.provider && pendingAuth.actorId === args.actorId && pendingAuth.scope === args.scope && pendingAuth.sessionId === args.sessionId && pendingAuth.linkSentAtMs + AUTH_LINK_REUSE_WINDOW_MS > (args.nowMs ?? Date.now());
14446
+ }
14447
+ function getConversationPendingAuth(args) {
14448
+ const pendingAuth = args.conversation.processing.pendingAuth;
14449
+ if (!pendingAuth) return;
14450
+ if (pendingAuth.kind !== args.kind || pendingAuth.provider !== args.provider || pendingAuth.actorId !== args.actorId || pendingAuth.scope !== args.scope) return;
14451
+ return pendingAuth;
14452
+ }
14453
+ function clearPendingAuth(conversation, sessionId) {
14454
+ if (!conversation.processing.pendingAuth) return;
14455
+ if (sessionId && conversation.processing.pendingAuth.sessionId !== sessionId) return;
14456
+ conversation.processing.pendingAuth = void 0;
14457
+ }
14458
+ /** Mark the prior blocked turn abandoned after a new auth attempt replaces it. */
14459
+ async function abandonReplacedPendingAuth(args) {
14460
+ if (args.previousPendingAuth && args.previousPendingAuth.sessionId !== args.nextPendingAuth.sessionId && args.conversationId) await abandonTurnRecord({
14461
+ conversationId: args.conversationId,
14462
+ turnId: args.previousPendingAuth.sessionId,
14463
+ errorMessage: "Abandoned by a newer auth-blocked request in the same conversation."
14464
+ });
14465
+ }
14466
+ /**
14467
+ * Decide whether an auth callback still belongs to the latest real human
14468
+ * request, ignoring bot-authored and passive bystander rows while treating
14469
+ * failed human turns and opt-outs as newer freshness blockers.
14470
+ */
14471
+ function isPendingAuthLatestRequest(conversation, pendingAuth) {
14472
+ for (let index = conversation.messages.length - 1; index >= 0; index -= 1) {
14473
+ const message = conversation.messages[index];
14474
+ if (message?.role !== "user") continue;
14475
+ if (message.author?.isBot) continue;
14476
+ if (isSkippedNonRequest(message.meta?.skippedReason)) continue;
14477
+ return buildDeterministicTurnId(message.id) === pendingAuth.sessionId;
14478
+ }
14479
+ return false;
13809
14480
  }
13810
14481
  //#endregion
13811
14482
  //#region src/chat/services/plugin-auth-orchestration.ts
@@ -15251,12 +15922,11 @@ function createMcpAuthOrchestration(input) {
15251
15922
  const authSession = await getMcpAuthSession(authSessionId);
15252
15923
  if (!authSession?.authorizationUrl) throw new Error(`Missing MCP authorization URL for plugin "${provider}"`);
15253
15924
  await recordPendingAuth(nextPendingAuth);
15254
- const authorizationRequest = {
15925
+ if (!await deliverOAuthAuthorization({
15255
15926
  authorizationUrl: authSession.authorizationUrl,
15256
- label: `Click here to link your ${providerLabel} MCP access`,
15927
+ label: `Connect to ${providerLabel}`,
15257
15928
  completionText: "Once you've authorized, Junior will continue automatically."
15258
- };
15259
- if (!await deliverOAuthAuthorization(authorizationRequest, {
15929
+ }, {
15260
15930
  authorization: input.authorization,
15261
15931
  channelId: authSession.channelId,
15262
15932
  threadTs: authSession.threadTs,
@@ -17397,7 +18067,7 @@ function applyHandoff(args) {
17397
18067
  * assistant message through the delivery port; the result carries diagnostics,
17398
18068
  * artifacts, and transcript state for destination-owned completion.
17399
18069
  */
17400
- const AGENT_ABORT_SETTLE_GRACE_MS = 5e3;
18070
+ const AGENT_ABORT_SETTLE_GRACE_MS$1 = 5e3;
17401
18071
  async function readRunConversationVisibility(conversationId) {
17402
18072
  const conversationStore = getConversationStore();
17403
18073
  const conversation = await conversationStore.get({ conversationId });
@@ -18126,7 +18796,7 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
18126
18796
  "app.ai.turn_timeout_ms": turnTimeoutBudgetMs,
18127
18797
  "app.ai.turn_deadline_remaining_ms": Math.max(0, turnDeadlineAtMs - Date.now())
18128
18798
  });
18129
- if (!await waitForAbortSettlement(run, AGENT_ABORT_SETTLE_GRACE_MS)) logWarn("agent.turn.abort_settle.timed_out", { "app.ai.abort_settle_grace_ms": AGENT_ABORT_SETTLE_GRACE_MS });
18799
+ if (!await waitForAbortSettlement(run, AGENT_ABORT_SETTLE_GRACE_MS$1)) logWarn("agent.turn.abort_settle.timed_out", { "app.ai.abort_settle_grace_ms": AGENT_ABORT_SETTLE_GRACE_MS$1 });
18130
18800
  runResume.captureResumeSnapshot(runResume.getResumeSnapshot(currentAgentMessages()));
18131
18801
  }
18132
18802
  const pendingAuthPause = getPendingAuthPause();
@@ -18348,4 +19018,109 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
18348
19018
  }
18349
19019
  }
18350
19020
  //#endregion
18351
- export { AuthorizationFlowDisabledError as $, createAgentInvocationSchema as A, recordFinishedTurnForAutomatedLimit as B, renderBlockText as C, getNextRunAtMs as D, scheduledAutomationRunAttributes as E, ingestEvent as F, clearSandboxEgressSignals as G, normalizeSandboxEgressTracePropagationDomains as H, EVENT_WAIT_MS as I, parseSandboxEgressCredentialToken as J, consumeSandboxEgressAuthRequiredSignal as K, isEventMailboxMetadata as L, AgentInvocationLimitError as M, getMcpProviderErrorAttributes as N, agentBindingSchema as O, processWorkspaceSnapshotJob as P, isVisionImageMediaType as Q, renderTaskInput as R, renderAttachmentText as S, logScheduledAutomationRunSkipped as T, shouldPropagateSandboxEgressTrace as U, resolveSandboxEgressProviderForHost as V, SANDBOX_EGRESS_PROXY_PATH as W, createUserTokenStore as X, sandboxEgressSignalsResponseSchema as Y, buildSteeringPiMessage as Z, readPublicArtifact as _, deleteMcpAuthSession as a, readAttachmentVisionSummary as b, deleteMcpStoredOAuthCredentials as c, putMcpStoredOAuthCredentials as d, shouldEmitDevAgentTrace as et, PluginCredentialFailureError as f, publicArtifactHeaders as g, resolvePluginOAuthAccount as h, finalizeMcpAuthorization as i, AgentInvocationBusyError as j, agentInvocationSchema as k, getMcpAuthSession as l, latestProgressStatus as m, createContextCompactor as n, setConfigDefaults as nt, deleteMcpAuthSessionsForUserProvider as o, authorizationId as p, consumeSandboxEgressPermissionDeniedSignal as q, executeCredentialedEgressRequest as r, deleteMcpServerSessionId as s, executeAgentRun as t, getConfigDefaults as tt, getMcpStoredOAuthCredentials as u, unpublishedArtifactHeaders as v, listThreadReplies as w, recordSlackAttachment as x, lookupSlackUserProfile as y, maybePostAutomatedTurnLimitNotice as z };
19021
+ //#region src/chat/experimental.ts
19022
+ var experimental_exports = /* @__PURE__ */ __exportAll({
19023
+ EXPERIMENTAL_FEATURES: () => EXPERIMENTAL_FEATURES,
19024
+ getExperimentalFeatures: () => getExperimentalFeatures,
19025
+ isExperimentalFeatureEnabled: () => isExperimentalFeatureEnabled,
19026
+ setExperimentalFeatures: () => setExperimentalFeatures
19027
+ });
19028
+ /**
19029
+ * Known unstable product features that must be opted into explicitly.
19030
+ * Add new keys here as features graduate from private experiments; remove them
19031
+ * once they become stable defaults.
19032
+ */
19033
+ const EXPERIMENTAL_FEATURES = ["passive-routing", "subagents"];
19034
+ const EXPERIMENTAL_FEATURE_SET = new Set(EXPERIMENTAL_FEATURES);
19035
+ let configuredExperimental = {};
19036
+ function isExperimentalFeature(value) {
19037
+ return EXPERIMENTAL_FEATURE_SET.has(value);
19038
+ }
19039
+ /** Replace app-level experimental opt-ins and return the previous setting. */
19040
+ function setExperimentalFeatures(config) {
19041
+ const previous = { ...configuredExperimental };
19042
+ if (config === void 0) {
19043
+ configuredExperimental = {};
19044
+ return previous;
19045
+ }
19046
+ const next = {};
19047
+ for (const [rawName, enabled] of Object.entries(config)) {
19048
+ if (enabled === void 0) continue;
19049
+ if (typeof enabled !== "boolean") throw new Error(`experimental.${rawName} must be a boolean when provided`);
19050
+ if (!isExperimentalFeature(rawName)) throw new Error(`experimental.${rawName} is not a known experimental feature. Known features: ${EXPERIMENTAL_FEATURES.join(", ")}`);
19051
+ next[rawName] = enabled;
19052
+ }
19053
+ configuredExperimental = next;
19054
+ return previous;
19055
+ }
19056
+ /** Return a copy of the app-level experimental opt-ins configured by createApp(). */
19057
+ function getExperimentalFeatures() {
19058
+ return { ...configuredExperimental };
19059
+ }
19060
+ /** Return whether one experimental feature is enabled via createApp({ experimental }). */
19061
+ function isExperimentalFeatureEnabled(feature) {
19062
+ return configuredExperimental[feature] === true;
19063
+ }
19064
+ //#endregion
19065
+ //#region src/chat/runtime/agent-runner.ts
19066
+ const AGENT_ABORT_SETTLE_GRACE_MS = 5e3;
19067
+ /** Compose the agent executor with stable host dependencies. */
19068
+ function createAgentRunner(execute, options) {
19069
+ const attachmentStorage = options?.attachmentStorage;
19070
+ const streamFn = options?.streamFn;
19071
+ const tracePropagation = options?.tracePropagation;
19072
+ const bindSpawnAgent = options?.bindSpawnAgent;
19073
+ const canBindSpawn = Boolean(bindSpawnAgent) && isExperimentalFeatureEnabled("subagents");
19074
+ return { run: async (run) => {
19075
+ const spawnAgent = bindSpawnAgent && canBindSpawn && !isAgentRunFeatureDisabled(run.disabledFeatures, "subagents") ? bindSpawnAgent(run) : void 0;
19076
+ return await execute({
19077
+ ...run,
19078
+ environment: {
19079
+ ...run.environment,
19080
+ attachmentStorage: run.environment?.attachmentStorage ?? attachmentStorage,
19081
+ sandboxTracePropagation: run.environment?.sandboxTracePropagation ?? tracePropagation
19082
+ },
19083
+ ...spawnAgent ? { durability: {
19084
+ ...run.durability,
19085
+ spawnAgent
19086
+ } } : void 0
19087
+ }, streamFn);
19088
+ } };
19089
+ }
19090
+ async function waitForAgentSettlement(runPromise) {
19091
+ let timeoutId;
19092
+ const settleGrace = new Promise((resolve) => {
19093
+ timeoutId = setTimeout(resolve, AGENT_ABORT_SETTLE_GRACE_MS);
19094
+ timeoutId.unref?.();
19095
+ });
19096
+ await Promise.race([runPromise.then(() => void 0, () => void 0), settleGrace]);
19097
+ if (timeoutId) clearTimeout(timeoutId);
19098
+ }
19099
+ /** Abort a timed-out agent run and wait briefly for its work to settle. */
19100
+ async function runAgentWithTimeout(agentRunner, run, timeoutMs) {
19101
+ if (typeof timeoutMs !== "number") return await agentRunner.run(run);
19102
+ const timeoutError = /* @__PURE__ */ new Error(`executeAgentRun timed out after ${timeoutMs}ms`);
19103
+ const abortController = new AbortController();
19104
+ const signal = run.signal ? AbortSignal.any([run.signal, abortController.signal]) : abortController.signal;
19105
+ const runPromise = agentRunner.run({
19106
+ ...run,
19107
+ signal
19108
+ });
19109
+ let timeoutId;
19110
+ const timeoutPromise = new Promise((_, reject) => {
19111
+ timeoutId = setTimeout(() => {
19112
+ abortController.abort(timeoutError);
19113
+ reject(timeoutError);
19114
+ }, timeoutMs);
19115
+ });
19116
+ try {
19117
+ return await Promise.race([runPromise, timeoutPromise]);
19118
+ } catch (error) {
19119
+ if (abortController.signal.aborted) await waitForAgentSettlement(runPromise);
19120
+ throw error;
19121
+ } finally {
19122
+ if (timeoutId) clearTimeout(timeoutId);
19123
+ }
19124
+ }
19125
+ //#endregion
19126
+ export { clearSandboxEgressSignals as $, renderAttachmentText as A, AgentInvocationLimitError as B, resolvePluginOAuthAccount as C, shouldEmitDevAgentTrace as Ct, lookupSlackUserProfile as D, unpublishedArtifactHeaders as E, getNextRunAtMs as F, isEventMailboxMetadata as G, processWorkspaceSnapshotJob as H, agentBindingSchema as I, recordFinishedTurnForAutomatedLimit as J, renderTaskInput as K, agentInvocationSchema as L, listThreadReplies as M, logScheduledAutomationRunSkipped as N, readAttachmentVisionSummary as O, scheduledAutomationRunAttributes as P, SANDBOX_EGRESS_PROXY_PATH as Q, createAgentInvocationSchema as R, latestProgressStatus as S, AuthorizationFlowDisabledError as St, readPublicArtifact as T, setConfigDefaults as Tt, ingestEvent as U, getMcpProviderErrorAttributes as V, EVENT_WAIT_MS as W, normalizeSandboxEgressTracePropagationDomains as X, resolveSandboxEgressProviderForHost as Y, shouldPropagateSandboxEgressTrace as Z, putMcpStoredOAuthCredentials as _, buildSteeringPiMessage as _t, isExperimentalFeatureEnabled as a, parseOAuthStatePayload as at, getConversationPendingAuth as b, actorFromRun as bt, createContextCompactor as c, escapeSlackMrkdwnText as ct, deleteMcpAuthSession as d, normalizeSlackStatusText as dt, consumeSandboxEgressAuthRequiredSignal as et, deleteMcpAuthSessionsForUserProvider as f, truncateStatusText as ft, getMcpStoredOAuthCredentials as g, createUserTokenStore as gt, getMcpAuthSession as h, removeReactionFromMessage as ht, getExperimentalFeatures as i, formatProviderLabel as it, renderBlockText as j, recordSlackAttachment as k, executeCredentialedEgressRequest as l, formatSlackLink as lt, deleteMcpStoredOAuthCredentials as m, postSlackMessage as mt, runAgentWithTimeout as n, parseSandboxEgressCredentialToken as nt, setExperimentalFeatures as o, resolveBaseUrl as ot, deleteMcpServerSessionId as p, addReactionToMessage as pt, maybePostAutomatedTurnLimitNotice as q, experimental_exports as r, sandboxEgressSignalsResponseSchema as rt, executeAgentRun as s, startOAuthFlow as st, createAgentRunner as t, consumeSandboxEgressPermissionDeniedSignal as tt, finalizeMcpAuthorization as u, normalizeSlackReplyMarkdown as ut, PluginCredentialFailureError as v, isVisionImageMediaType as vt, publicArtifactHeaders as w, getConfigDefaults as wt, isPendingAuthLatestRequest as x, toolInvocationDestination as xt, clearPendingAuth as y, RetryableDeliveryError as yt, AgentInvocationBusyError as z };