@sentry/junior 0.239.0 → 0.241.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 (64) hide show
  1. package/dist/{admin-Cc-iA6z9.js → admin-CJkjl-aN.js} +1 -1
  2. package/dist/{agent-hooks-DzfA5m3R.js → agent-hooks-C5zYOaJk.js} +1972 -1866
  3. package/dist/{agent-runner--1wC26S6.js → agent-runner-CMZ6lFQe.js} +377 -1227
  4. package/dist/api/schema.d.ts +9 -0
  5. package/dist/api/schema.js +2 -2
  6. package/dist/api.d.ts +1 -1
  7. package/dist/api.js +22 -21
  8. package/dist/{app-FB2hmHpZ.d.ts → app-MEd7wbF0.d.ts} +1 -1
  9. package/dist/app.d.ts +1 -1
  10. package/dist/app.js +105 -31
  11. package/dist/{automation-CrQGQ2MT.js → automation-gznOMaQ2.js} +13 -255
  12. package/dist/{briefs-DGc2Thua.js → briefs-CsQbFjRi.js} +2 -2
  13. package/dist/cadence-D00SCzT1.js +256 -0
  14. package/dist/{catalog-runtime-DpB_hG_I.js → catalog-runtime-Tz0O2MZe.js} +1 -1
  15. package/dist/cli/chat.js +12 -12
  16. package/dist/cli/check.js +3 -3
  17. package/dist/cli/main.js +2 -2
  18. package/dist/cli/plugins.js +4 -4
  19. package/dist/cli/snapshot-create.js +3 -3
  20. package/dist/cli/upgrade.d.ts +1 -1
  21. package/dist/cli/upgrade.js +3 -3
  22. package/dist/{client-DNf-sJmM.js → client-CRZ-i1tH.js} +2 -2
  23. package/dist/{config-B8QN-04U.js → config-CCI82OTD.js} +2 -2
  24. package/dist/{conversation-privacy-CrYizZM3.js → conversation-privacy-D5Byl5eC.js} +1 -1
  25. package/dist/{credential-sync-BG_Yvja8.js → credential-sync-DUpSxUum.js} +14 -14
  26. package/dist/{db-CWZP77Ex.d.ts → db-Ca9Nt5ci.d.ts} +1 -1
  27. package/dist/{executor-BQV1Zc1z.js → executor-CewKi7EG.js} +4 -2
  28. package/dist/{images-C_0iwPsW.js → images-DY6Pxq4w.js} +2 -2
  29. package/dist/instrumentation.js +2 -2
  30. package/dist/{job-queue-D82gksYM.js → job-queue-C6o2aJQ6.js} +1 -1
  31. package/dist/{logging-Crg0e1jb.js → logging-LQnLlPf8.js} +1 -1
  32. package/dist/nitro.d.ts +1 -1
  33. package/dist/nitro.js +3 -3
  34. package/dist/{oauth-authorization-Bdu39G-H.js → oauth-authorization-Clzkm-Ts.js} +1 -1
  35. package/dist/{oauth-callback-server-eJfI6skP.js → oauth-callback-server-DcYAJSEz.js} +2 -2
  36. package/dist/{pending-auth-DauOaies.js → pending-auth-CT3ojhKe.js} +2 -2
  37. package/dist/{profile-XzHSfIah.js → profile-mWuVZ8ht.js} +4 -4
  38. package/dist/{registry-BJME30oR.js → registry-DPDH6s5G.js} +1 -1
  39. package/dist/{resolve-ZKXfsZuZ.js → resolve-BAN8BSGy.js} +2 -2
  40. package/dist/{runner-DkHL8vRA.js → runner-CqXZJfzk.js} +9 -9
  41. package/dist/{sandbox-egress-signals-BEQsK7ym.js → sandbox-egress-signals-DFUUokws.js} +1 -1
  42. package/dist/{schema-CxWAN2zq.js → schema-Cabm4jcj.js} +1 -1
  43. package/dist/{skills-CMl248J3.js → skills-BtHhSATy.js} +2 -2
  44. package/dist/{spawn-DrvZYrTQ.js → spawn-BszkFJKJ.js} +2 -2
  45. package/dist/{store-BxxbxBlm.d.ts → store-DoewL5mG.d.ts} +0 -7
  46. package/dist/{task-queue-BMzTARMo.js → task-queue-1LP6benz.js} +3 -3
  47. package/dist/{task-runner-CXTpWSmw.js → task-runner-kLN3HC-_.js} +54 -12
  48. package/dist/{checkpoint-CN7yMfSo.js → tasks-CO52vLkI.js} +1064 -18
  49. package/dist/{thread-state-BM1sLptE.js → thread-state-CaFRG5Mh.js} +6 -6
  50. package/dist/{turn-failure-response-ISrbka5I.js → turn-failure-response-Dmovuiq1.js} +9 -8
  51. package/dist/{turn-lifecycle-f7TPxQsc.js → turn-lifecycle-DGqZgU6J.js} +1 -1
  52. package/dist/{turn-session-routing-BcAD7onh.js → turn-session-routing-B_v8Wbn4.js} +1 -1
  53. package/dist/{validation-Bo6BHmig.js → validation-B4L2Rmiw.js} +1 -1
  54. package/dist/{version-Cv__n5ue.js → version-DiR36OaN.js} +1 -1
  55. package/dist/version.js +1 -1
  56. package/dist/{viewer-EftpWXcF.js → viewer-D6stAU7h.js} +9 -11
  57. package/dist/{web-authorization-BLDXKk2u.js → web-authorization-DLMBx2nL.js} +6 -6
  58. package/dist/{web-input-DSa6geKr.js → web-input---xuox1t.js} +136 -147
  59. package/dist/{work-WOk5DovU.js → work-G-HdoOSF.js} +7 -7
  60. package/dist/{worker-B7rtMFzw.js → worker-CDUDfL9P.js} +5 -5
  61. package/migrations/0049_event_automation_status_reason.sql +1 -0
  62. package/migrations/meta/0049_snapshot.json +3581 -0
  63. package/migrations/meta/_journal.json +8 -1
  64. package/package.json +5 -5
@@ -1,10 +1,10 @@
1
- import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-Crg0e1jb.js";
2
- import { d as getDb } from "./viewer-EftpWXcF.js";
1
+ import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-LQnLlPf8.js";
2
+ import { d as getDb } from "./viewer-D6stAU7h.js";
3
3
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
4
- import { d as juniorLocationConfigurations } from "./executor-BQV1Zc1z.js";
5
- import { X as persistConversationMessages } from "./checkpoint-CN7yMfSo.js";
6
- import { pt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-DzfA5m3R.js";
7
- import { w as getStateAdapter } from "./profile-XzHSfIah.js";
4
+ import { d as juniorLocationConfigurations } from "./executor-CewKi7EG.js";
5
+ import { Bt as persistConversationMessages } from "./tasks-CO52vLkI.js";
6
+ import { tt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-C5zYOaJk.js";
7
+ import { w as getStateAdapter } from "./profile-mWuVZ8ht.js";
8
8
  import { z } from "zod";
9
9
  import { randomUUID } from "node:crypto";
10
10
  import { and, eq, sql } from "drizzle-orm";
@@ -1,13 +1,13 @@
1
- import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-DNf-sJmM.js";
2
- import { I as isRecord, t as buildTurnFailureResponse } from "./logging-Crg0e1jb.js";
1
+ import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-CRZ-i1tH.js";
2
+ import { I as isRecord, t as buildTurnFailureResponse } from "./logging-LQnLlPf8.js";
3
3
  import { g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
4
- import { c as getConversationEventStore, d as getDb } from "./viewer-EftpWXcF.js";
5
- import { Y as hydrateConversationMessages, lt as markConversationMessage } from "./checkpoint-CN7yMfSo.js";
6
- import { Ht as listConversationAnnotations } from "./agent-hooks-DzfA5m3R.js";
4
+ import { c as getConversationEventStore, d as getDb } from "./viewer-D6stAU7h.js";
5
+ import { $t as markConversationMessage, zt as hydrateConversationMessages } from "./tasks-CO52vLkI.js";
6
+ import { At as listConversationAnnotations } from "./agent-hooks-C5zYOaJk.js";
7
7
  import { G as removedCardSchema, K as resolveMessageCards, W as readMessageCardRefs } from "./conversation-DwD-vquD.js";
8
- import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-DauOaies.js";
9
- import { g as markTurnCompleted, h as markTurnClosed } from "./oauth-authorization-Bdu39G-H.js";
10
- import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-BM1sLptE.js";
8
+ import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-CT3ojhKe.js";
9
+ import { g as markTurnCompleted, h as markTurnClosed } from "./oauth-authorization-Clzkm-Ts.js";
10
+ import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-CaFRG5Mh.js";
11
11
  //#region src/chat/conversations/pending-cards.ts
12
12
  /** Select undelivered cards and load their latest saved facts. */
13
13
  async function loadPendingMessageCards(conversationId) {
@@ -173,6 +173,7 @@ function getAgentTurnDiagnosticsAttributes(reply) {
173
173
  "app.ai.tool_error_results": reply.diagnostics.toolErrorCount,
174
174
  "app.ai.tool_call_count": reply.diagnostics.toolCalls.length,
175
175
  "app.ai.used_primary_text": reply.diagnostics.usedPrimaryText,
176
+ ...reply.automation ? { "app.automation.result": reply.automation.result } : void 0,
176
177
  ...reply.diagnostics.reasoningLevel ? { "gen_ai.request.reasoning.level": reply.diagnostics.reasoningLevel } : void 0,
177
178
  ...reply.diagnostics.stopReason ? { "gen_ai.response.finish_reasons": [reply.diagnostics.stopReason] } : void 0,
178
179
  ...reply.diagnostics.errorMessage && reply.diagnostics.outcome !== "provider_error" ? { "exception.message": reply.diagnostics.errorMessage } : void 0
@@ -1,4 +1,4 @@
1
- import { c as getConversationEventStore } from "./viewer-EftpWXcF.js";
1
+ import { c as getConversationEventStore } from "./viewer-D6stAU7h.js";
2
2
  //#region src/chat/conversations/turn-lifecycle.ts
3
3
  /** Persist correlated turn lifecycle facts with retry-safe terminal exclusion. */
4
4
  var ConversationTurnLifecycleService = class {
@@ -34,7 +34,7 @@ function slackSourceForDestination(args) {
34
34
  * Reads parent Conversations when this Conversation has no Destination.
35
35
  */
36
36
  async function resolveConversationRouting(args) {
37
- const conversationStore = args.conversationStore ?? (await import("./viewer-EftpWXcF.js").then((n) => n.s)).getConversationStore();
37
+ const conversationStore = args.conversationStore ?? (await import("./viewer-D6stAU7h.js").then((n) => n.s)).getConversationStore();
38
38
  const chain = await loadConversationChain(args.conversationId, conversationStore);
39
39
  let destination;
40
40
  let source;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { n as pluginCatalogRuntime } from "./catalog-runtime-DpB_hG_I.js";
2
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-Tz0O2MZe.js";
3
3
  import { isDeepStrictEqual } from "node:util";
4
4
  //#region src/chat/plugins/validation.ts
5
5
  var validation_exports = /* @__PURE__ */ __exportAll({
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.239.0";
2
+ var version = "0.241.0";
3
3
  //#endregion
4
4
  //#region src/version.ts
5
5
  /** Installed Junior package version, or `unknown` when package metadata is unavailable. */
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as JUNIOR_VERSION } from "./version-Cv__n5ue.js";
1
+ import { t as JUNIOR_VERSION } from "./version-DiR36OaN.js";
2
2
  export { JUNIOR_VERSION };
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { F as normalizeIdentityEmail } from "./logging-Crg0e1jb.js";
3
- import { i as getChatConfig } from "./config-B8QN-04U.js";
2
+ import { F as normalizeIdentityEmail } from "./logging-LQnLlPf8.js";
3
+ import { i as getChatConfig } from "./config-CCI82OTD.js";
4
4
  import { d as parseSlackTeamId, o as parseActorUserId, u as parseSlackChannelReferenceId } from "./actor-BTtLaeWy.js";
5
5
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
6
- import { D as juniorConversations, E as conversationReadColumns, O as juniorIdentities, S as juniorConversationAnnotations, b as juniorConversationEvents, g as juniorConversationBindings, h as juniorConversationParticipants, k as juniorUsers, t as createJuniorSqlExecutor, v as CONVERSATION_METRICS, y as juniorConversationMetrics } from "./executor-BQV1Zc1z.js";
6
+ import { D as juniorConversations, E as conversationReadColumns, O as juniorIdentities, S as juniorConversationAnnotations, b as juniorConversationEvents, g as juniorConversationBindings, h as juniorConversationParticipants, k as juniorUsers, t as createJuniorSqlExecutor, v as CONVERSATION_METRICS, y as juniorConversationMetrics } from "./executor-CewKi7EG.js";
7
7
  import { c as newConversationEventSchema, l as encodeHistoryPayload, m as usageSchema, o as decodeStoredConversationEvent, r as conversationEventDataSchema, s as historyReplacementSchema } from "./history-BLTUgFYO.js";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { and, asc, desc, eq, gt, gte, inArray, isNull, lt, lte, ne, or, sql } from "drizzle-orm";
@@ -413,10 +413,6 @@ function parseSessionSource(value) {
413
413
  async function getConversationIdByProviderConversation(executor, args) {
414
414
  return (await executor.db().select({ conversationId: juniorConversationBindings.conversationId }).from(juniorConversationBindings).where(and(eq(juniorConversationBindings.provider, args.provider), eq(juniorConversationBindings.providerTenantId, args.providerTenantId), eq(juniorConversationBindings.providerDestinationId, args.providerDestinationId), eq(juniorConversationBindings.providerConversationId, args.providerConversationId))).limit(1))[0]?.conversationId;
415
415
  }
416
- /** Return the first provider conversation bound in one destination. */
417
- async function getFirstProviderConversationId(executor, args) {
418
- return (await executor.db().select({ providerConversationId: juniorConversationBindings.providerConversationId }).from(juniorConversationBindings).where(and(eq(juniorConversationBindings.conversationId, args.conversationId), eq(juniorConversationBindings.provider, args.provider), eq(juniorConversationBindings.providerTenantId, args.providerTenantId), eq(juniorConversationBindings.providerDestinationId, args.providerDestinationId))).orderBy(asc(juniorConversationBindings.createdAt), asc(juniorConversationBindings.providerConversationId)).limit(1))[0]?.providerConversationId;
419
- }
420
416
  /** Bind provider coordinates to a durable conversation in the caller's SQL scope. */
421
417
  async function bindProviderConversation(executor, args) {
422
418
  if (((await executor.db().insert(juniorConversationBindings).values({
@@ -566,6 +562,11 @@ function visibilityFromLocationRow(row) {
566
562
  if (!row) return;
567
563
  if (row.visibility === "public" || row.visibility === "private") return row.visibility;
568
564
  }
565
+ /** Store a channel-level Location's first bound post as its thread. */
566
+ async function startLocationThread(executor, binding) {
567
+ const location = juniorConversations.location;
568
+ await executor.db().update(juniorConversations).set({ location: sql`${location} || jsonb_build_object('threadTs', ${binding.providerConversationId}::text)` }).where(and(eq(juniorConversations.conversationId, binding.conversationId), sql`${location}->>'provider' = ${binding.provider}`, sql`${location}->>'teamId' = ${binding.providerTenantId}`, sql`${location}->>'channelId' = ${binding.providerDestinationId}`, isNull(sql`${location}->>'threadTs'`)));
569
+ }
569
570
  //#endregion
570
571
  //#region src/chat/conversations/sql/store.ts
571
572
  const CONVERSATION_MUTATION_LOCK_PREFIX = "junior_conversation";
@@ -718,9 +719,6 @@ var SqlStore = class {
718
719
  async getConversationIdByProviderConversation(args) {
719
720
  return await getConversationIdByProviderConversation(this.executor, args);
720
721
  }
721
- async getFirstProviderConversationId(args) {
722
- return await getFirstProviderConversationId(this.executor, args);
723
- }
724
722
  async bindProviderConversation(args) {
725
723
  await bindProviderConversation(this.executor, args);
726
724
  }
@@ -1633,4 +1631,4 @@ async function readActorIdentity(actor) {
1633
1631
  return await readActorIdentityFromSql(getDb(), actor);
1634
1632
  }
1635
1633
  //#endregion
1636
- export { upsertLinkedIdentity as A, agentTurnUsageSchema as C, readUserTimezone as D, deleteProviderIdentityForSlackUser as E, parseDestination as M, requireSlackDestination as N, saveUserTimezone as O, sameDestination as P, agentTurnTotalTokens as S, resolveRootConversationId as T, locationFromRow as _, setUserAdminFromSql as a, addAgentTurnUsage as b, getConversationEventStore as c, getDb as d, getSqlExecutor as f, withConversationMutationLock as g, createSqlStore as h, resolveViewerUser as i, createSlackDestination as j, upsertIdentity as k, getConversationMessageSearchStore as l, withConversationEventLock as m, listAdminUsersFromSql as n, updateViewerDisplayName as o, createSqlConversationEventStore as p, readActorIdentity as r, db_exports as s, findUserByEmail as t, getConversationStore as u, bindProviderConversation as v, hasAgentTurnUsage as w, agentTurnCostUsd as x, parseSessionSource as y };
1634
+ export { upsertIdentity as A, agentTurnTotalTokens as C, deleteProviderIdentityForSlackUser as D, resolveRootConversationId as E, sameDestination as F, createSlackDestination as M, parseDestination as N, readUserTimezone as O, requireSlackDestination as P, agentTurnCostUsd as S, hasAgentTurnUsage as T, locationFromRow as _, setUserAdminFromSql as a, parseSessionSource as b, getConversationEventStore as c, getDb as d, getSqlExecutor as f, withConversationMutationLock as g, createSqlStore as h, resolveViewerUser as i, upsertLinkedIdentity as j, saveUserTimezone as k, getConversationMessageSearchStore as l, withConversationEventLock as m, listAdminUsersFromSql as n, updateViewerDisplayName as o, createSqlConversationEventStore as p, readActorIdentity as r, db_exports as s, findUserByEmail as t, getConversationStore as u, startLocationThread as v, agentTurnUsageSchema as w, addAgentTurnUsage as x, bindProviderConversation as y };
@@ -1,9 +1,9 @@
1
- import { Bt as ensureConversationWake, Xt as requestConversationWork } from "./agent-runner--1wC26S6.js";
2
- import { c as getConversationEventStore } from "./viewer-EftpWXcF.js";
3
- import { n as loadTurnCheckpoint, o as failTurnRecord, s as getTurnRecord } from "./checkpoint-CN7yMfSo.js";
4
- import { w as getStateAdapter } from "./profile-XzHSfIah.js";
5
- import { a as getVercelConversationWorkQueue } from "./job-queue-D82gksYM.js";
6
- import { n as resolveTurnSessionRouting } from "./turn-session-routing-BcAD7onh.js";
1
+ import { Tt as requestConversationWork, ht as ensureConversationWake } from "./agent-runner-CMZ6lFQe.js";
2
+ import { c as getConversationEventStore } from "./viewer-D6stAU7h.js";
3
+ import { G as loadTurnCheckpoint, X as getTurnRecord, Y as failTurnRecord } from "./tasks-CO52vLkI.js";
4
+ import { w as getStateAdapter } from "./profile-mWuVZ8ht.js";
5
+ import { a as getVercelConversationWorkQueue } from "./job-queue-C6o2aJQ6.js";
6
+ import { n as resolveTurnSessionRouting } from "./turn-session-routing-B_v8Wbn4.js";
7
7
  import { z } from "zod";
8
8
  import { randomUUID } from "node:crypto";
9
9
  //#region src/chat/task-execution/authorized-turn.ts
@@ -1,34 +1,34 @@
1
- import { $ as eventAutomationBelongsToUser, A as resolveSlackChannelIdFromMessage, B as parseScheduledAutomationRow, C as renderBlockText, Cn as normalizeSlackReplyMarkdown, Ct as timerWatchCredentialSubject, D as storeAttachment, Dn as addReactionToMessage, En as truncateStatusText, Et as pluginEventCatalog, F as lookupSlackUser, G as withScheduledAutomationLock, Ht as getConversationWorkState, J as eventAutomationTriggerAvailable, Ln as AuthorizationFlowDisabledError, M as getConversationInfo, Mn as createUserTokenStore, N as listThreadReplies, Nn as buildSteeringPiMessage, O as parseSlackThreadId, On as postSlackMessage, Ot as appendAndEnqueueExclusiveInboundMessage, Pn as RetryableDeliveryError, Q as deleteEventAutomation, Rn as shouldEmitDevAgentTrace, S as renderAttachmentText, Sn as formatSlackLink, St as isEventMailboxMetadata, U as saveScheduledAutomationInLock, V as readScheduledAutomation, Y as effectiveTaskOutcomes, a as buildAuthPauseResponse, h as latestProgressStatus, j as resolveSlackChannelIdFromThreadId, k as readSlackRawMessageContext, kn as removeReactionFromMessage, kt as appendAndEnqueueInboundMessage, lt as sameDefinitionValue, m as PluginCredentialFailureError, n as executeAgentRun, nt as listDeletedEventAutomationsCreatedBy, on as maybePostAutomatedTurnLimitNotice, ot as automationDefinition, r as createContextCompactor, rt as parseEventAutomationRow, sn as recordFinishedTurnForAutomatedLimit, st as listAutomationVersions, t as createAgentRunner, tt as getEventAutomation, wn as normalizeSlackStatusText, wt as getEventCatalog, xn as escapeSlackMrkdwnText, xt as EVENT_WAIT_MS } from "./agent-runner--1wC26S6.js";
2
- import { f as escapeXml, i as completeText, r as completeObject, v as isProviderRetryError } from "./client-DNf-sJmM.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-Crg0e1jb.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-B8QN-04U.js";
1
+ import { $ as getEventCatalog, A as resolveSlackChannelIdFromMessage, B as effectiveTaskOutcomes, C as renderBlockText, D as storeAttachment, Ft as maybePostAutomatedTurnLimitNotice, It as recordFinishedTurnForAutomatedLimit, M as getConversationInfo, N as listThreadReplies, O as parseSlackThreadId, Q as timerWatchCredentialSubject, Qt as RetryableDeliveryError, S as renderAttachmentText, X as EVENT_WAIT_MS, Xt as createUserTokenStore, Z as isEventMailboxMetadata, Zt as buildSteeringPiMessage, _t as getConversationWorkState, a as buildAuthPauseResponse, an as shouldEmitDevAgentTrace, h as latestProgressStatus, in as runDispatchOutcome, it as appendAndEnqueueInboundMessage, j as resolveSlackChannelIdFromThreadId, k as readSlackRawMessageContext, m as PluginCredentialFailureError, n as executeAgentRun, nn as deliversFinalText, r as createContextCompactor, rn as finishedRunReply, rt as appendAndEnqueueExclusiveInboundMessage, t as createAgentRunner, tn as AuthorizationFlowDisabledError, tt as pluginEventCatalog, z as eventAutomationTriggerAvailable } from "./agent-runner-CMZ6lFQe.js";
2
+ import { f as escapeXml, i as completeText, r as completeObject, v as isProviderRetryError } from "./client-CRZ-i1tH.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-LQnLlPf8.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-CCI82OTD.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 { N as requireSlackDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, j as createSlackDestination, u as getConversationStore } from "./viewer-EftpWXcF.js";
7
+ import { M as createSlackDestination, P as requireSlackDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, u as getConversationStore } from "./viewer-D6stAU7h.js";
8
8
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
9
- import { O as juniorIdentities, c as juniorAutomationExecutions, k as juniorUsers, o as juniorSchedulerTasks, u as juniorEventAutomations } from "./executor-BQV1Zc1z.js";
9
+ import { O as juniorIdentities, c as juniorAutomationExecutions, k as juniorUsers, o as juniorSchedulerTasks, u as juniorEventAutomations } from "./executor-CewKi7EG.js";
10
10
  import { f as instructionProvenanceFor } from "./history-BLTUgFYO.js";
11
- import { d as credentialContextForActor } from "./registry-BJME30oR.js";
12
- import { $ as resolveConversationTitle, A as commitAcceptedReply, G as recordSubscribedReplyRoute, N as loadConversationProjection, O as trimTrailingAssistantMessages, P as loadProjection, Q as persistConversationMessageSummaries, V as recordAuthorizationCompleted, X as persistConversationMessages, Y as hydrateConversationMessages, a as completeTurnRecord, at as createConversationMemoryService, c as listTurnSummaries, ct as isHumanConversationMessage, dt as recordDeliveredAssistantMessage, ft as turnHasReply, i as abandonTurnRecord, it as buildConversationContext, j as commitMessages, l as recordTurnSummary, lt as markConversationMessage, n as loadTurnCheckpoint, o as failTurnRecord, ot as estimateConversationContextTokens, p as buildTurnErrorResponse, pt as upsertConversationMessage, r as saveTurnCheckpoint, rt as appendThreadContextMessages, s as getTurnRecord, st as getConversationMessageSlackTs, tt as fallbackShortTitle, u as persistWithRetry, ut as normalizeConversationText } from "./checkpoint-CN7yMfSo.js";
13
- import { Ft as getSlackFileId, Lt as readAttachmentVisionSummary, Pt as buildSentryConversationUrl, Rt as recordSlackAttachment, at as getSlackClient, ct as normalizeSlackConversationId, et as verifyTimerWatchCredentialSubject, ht as getDashboardObjectIconLink, it as getHeaderString, lt as runWithSlackInstallationToken, mt as getDashboardConversationLink, nt as downloadPrivateSlackFile, o as getPluginSlackConversationLink, pt as JUNIOR_THREAD_STATE_TTL_MS, st as isDmChannel, tt as SlackActionError, z as cancelSubscriptions } from "./agent-hooks-DzfA5m3R.js";
11
+ import { d as credentialContextForActor } from "./registry-DPDH6s5G.js";
12
+ import { $ as persistWithRetry, $t as markConversationMessage, A as formatSlackLink, B as removeReactionFromMessage, Bt as persistConversationMessages, C as listAutomationVersions, Ct as loadConversationProjection, F as addReactionToMessage, Ft as recordSubscribedReplyRoute, G as loadTurnCheckpoint, Gt as fallbackShortTitle, Ht as persistConversationMessageSummaries, J as completeTurnRecord, Jt as buildConversationContext, K as saveTurnCheckpoint, M as normalizeSlackStatusText, P as truncateStatusText, Q as recordTurnSummary, Qt as isHumanConversationMessage, S as automationDefinition, T as sameDefinitionValue, Ut as resolveConversationTitle, X as getTurnRecord, Xt as estimateConversationContextTokens, Y as failTurnRecord, Yt as createConversationMemoryService, Z as listTurnSummaries, Zt as getConversationMessageSlackTs, _ as listDeletedEventAutomationsCreatedBy, _t as trimTrailingAssistantMessages, a as readScheduledAutomation, bt as commitAcceptedReply, en as normalizeConversationText, g as getEventAutomation, i as parseScheduledAutomationRow, j as normalizeSlackReplyMarkdown, jt as recordAuthorizationCompleted, k as escapeSlackMrkdwnText, l as withScheduledAutomationLock, m as eventAutomationBelongsToUser, nn as turnHasReply, nt as buildTurnErrorResponse, p as deleteEventAutomation, q as abandonTurnRecord, qt as appendThreadContextMessages, rn as upsertConversationMessage, s as saveScheduledAutomationInLock, tn as recordDeliveredAssistantMessage, wt as loadProjection, xt as commitMessages, y as parseEventAutomationRow, z as postSlackMessage, zt as hydrateConversationMessages } from "./tasks-CO52vLkI.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-C5zYOaJk.js";
14
14
  import { F as isVisionImageMediaType, N as readMessageAttachments } from "./conversation-DwD-vquD.js";
15
- import { E as acquireActiveLock, O as withLock, T as MUTATION_LOCK_TTL_MS, w as getStateAdapter } from "./profile-XzHSfIah.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-DauOaies.js";
17
- import { _ as markTurnFailed, c as CooperativeTurnYieldError, d as getConversationTurnBoundaryError, f as isCooperativeTurnYieldError, g as markTurnCompleted, h as markTurnClosed, l as TurnInputCommitLostError, m as isTurnInputDeferredError, p as isTurnInputCommitLostError, r as getAssistantReplyText, s as ConversationTurnBoundaryError, u as TurnInputDeferredError, v as startActiveTurn } from "./oauth-authorization-Bdu39G-H.js";
15
+ import { E as acquireActiveLock, O as withLock, T as MUTATION_LOCK_TTL_MS, w as getStateAdapter } from "./profile-mWuVZ8ht.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-CT3ojhKe.js";
17
+ import { _ as markTurnFailed, c as CooperativeTurnYieldError, d as getConversationTurnBoundaryError, f as isCooperativeTurnYieldError, g as markTurnCompleted, h as markTurnClosed, l as TurnInputCommitLostError, m as isTurnInputDeferredError, p as isTurnInputCommitLostError, r as getAssistantReplyText, s as ConversationTurnBoundaryError, u as TurnInputDeferredError, v as startActiveTurn } from "./oauth-authorization-Clzkm-Ts.js";
18
18
  import { a as EVENT_SYSTEM_ACTOR, i as EVENT_MESSAGE_AUTHOR, o as isEventConversationMessage } from "./prompt-CMU-B4FA.js";
19
- import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline } from "./job-queue-D82gksYM.js";
20
- import { l as automationListQuerySchema } from "./automation-CrQGQ2MT.js";
19
+ import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline } from "./job-queue-C6o2aJQ6.js";
20
+ import { l as automationListQuerySchema } from "./automation-gznOMaQ2.js";
21
21
  import { r as isExperimentalFeatureEnabled } from "./experimental-Qn9rKLgx.js";
22
22
  import { c as sumUtcHoursIntoSixHours, m as healthReportSchema, t as webMessageId } from "./web-message-id-xPI_EFSC.js";
23
- import { C as readAutomationExecutionStatusDays, D as readAutomationRuns, E as readAutomationExecutions, S as readAutomationExecutionHours, T as readAutomationExecutionSummaries, _ as markDispatchFailed, a as confirmDispatchMailboxAppend, b as readAutomationExecutionByConversationId, 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 readAutomationExecutionStatusHours, x as readAutomationExecutionDays, y as emptyAutomationRunWindows } from "./task-runner-CXTpWSmw.js";
24
- import { i as resolveAgentInvocationId, o as AgentRunError, s as executeTurn, t as createAgentInvocationWorker } from "./work-WOk5DovU.js";
25
- import { n as getTurnLifecycle, t as ConversationTurnLifecycleService } from "./turn-lifecycle-f7TPxQsc.js";
26
- import { a as persistThreadState, c as configValueSchema, i as persistThreadRuntimeState, n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState, t as getLocationConfigurationService } from "./thread-state-BM1sLptE.js";
27
- import { a as getPausedTurnRequest, c as getTurnAuthorization, i as createPausedTurns, n as deleteWebAuthorization, s as wakePausedTurn, t as createWebAuthorization } from "./web-authorization-BLDXKk2u.js";
28
- import { n as resolveTurnSessionRouting } from "./turn-session-routing-BcAD7onh.js";
29
- import { t as bindSpawnAgent } from "./spawn-DrvZYrTQ.js";
30
- import { a as persistAuthPauseTurnState, c as getTurnUserSlackMessageTs, d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, n as getAgentTurnDiagnosticsAttributes, o as getTurnUserMessage, r as requireTurnFailureEventId, s as getTurnUserReplyAttachmentContext, t as finalizeFailedTurnReplyWithEvent, u as getInterruptionMarker } from "./turn-failure-response-ISrbka5I.js";
31
- import { r as storeInputImages } from "./images-C_0iwPsW.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-kLN3HC-_.js";
24
+ import { i as resolveAgentInvocationId, o as AgentRunError, s as executeTurn, t as createAgentInvocationWorker } from "./work-G-HdoOSF.js";
25
+ import { n as getTurnLifecycle, t as ConversationTurnLifecycleService } from "./turn-lifecycle-DGqZgU6J.js";
26
+ import { a as persistThreadState, c as configValueSchema, i as persistThreadRuntimeState, n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState, t as getLocationConfigurationService } from "./thread-state-CaFRG5Mh.js";
27
+ import { a as getPausedTurnRequest, c as getTurnAuthorization, i as createPausedTurns, n as deleteWebAuthorization, s as wakePausedTurn, t as createWebAuthorization } from "./web-authorization-DLMBx2nL.js";
28
+ import { n as resolveTurnSessionRouting } from "./turn-session-routing-B_v8Wbn4.js";
29
+ import { t as bindSpawnAgent } from "./spawn-BszkFJKJ.js";
30
+ import { a as persistAuthPauseTurnState, c as getTurnUserSlackMessageTs, d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, n as getAgentTurnDiagnosticsAttributes, o as getTurnUserMessage, r as requireTurnFailureEventId, s as getTurnUserReplyAttachmentContext, t as finalizeFailedTurnReplyWithEvent, u as getInterruptionMarker } from "./turn-failure-response-Dmovuiq1.js";
31
+ import { r as storeInputImages } from "./images-DY6Pxq4w.js";
32
32
  import { z } from "zod";
33
33
  import { createHash } from "node:crypto";
34
34
  import { and, asc, count, desc, eq, exists, inArray, ne, or, sql } from "drizzle-orm";
@@ -70,7 +70,8 @@ function buildDispatchRoutingContext(dispatch) {
70
70
  metadata: dispatch.metadata,
71
71
  plugin: dispatch.plugin,
72
72
  replyAttribution: dispatch.replyAttribution,
73
- outcomes: dispatch.outcomes
73
+ outcomes: dispatch.outcomes,
74
+ ...dispatch.source.kind === "scheduled_automation" || dispatch.source.kind === "event_automation" ? { declaresResult: true } : void 0
74
75
  },
75
76
  surface: "api"
76
77
  };
@@ -188,7 +189,7 @@ async function projectDispatchTurnResult(dispatchId, result) {
188
189
  await markDispatchAwaitingResume(dispatchId);
189
190
  break;
190
191
  case "blocked":
191
- await markDispatchBlocked(dispatchId, "Dispatch requires authorization that is unavailable for background work", result.resultMessageTs);
192
+ await markDispatchBlocked(dispatchId, result.errorMessage ?? "Dispatch requires authorization that is unavailable for background work", result.resultMessageTs);
192
193
  break;
193
194
  case "failed":
194
195
  await markDispatchFailed(dispatchId, result.errorMessage ?? "Agent turn failed", result.resultMessageTs);
@@ -200,6 +201,9 @@ function getDispatchBlockingError(error) {
200
201
  const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
201
202
  return cause instanceof AuthorizationFlowDisabledError || cause instanceof PluginCredentialFailureError ? cause : void 0;
202
203
  }
204
+ function missingAuthorizationReason(dispatch, provider) {
205
+ return dispatch.credentialSubject ? `This run needs a connected ${provider} account.` : `This run uses system credentials, which have no ${provider} access. Switch it to creator credentials and connect a ${provider} account.`;
206
+ }
203
207
  async function persistBlockedDispatchTurn(dispatch, error) {
204
208
  const conversationId = getDispatchConversationId(dispatch);
205
209
  const sessionId = getDispatchTurnId(dispatch.id);
@@ -217,7 +221,7 @@ async function persistBlockedDispatchTurn(dispatch, error) {
217
221
  state: "failed",
218
222
  surface: "api"
219
223
  });
220
- await markDispatchBlocked(dispatch.id, error instanceof AuthorizationFlowDisabledError ? `Dispatch requires ${error.provider} authorization.` : error.message);
224
+ await markDispatchBlocked(dispatch.id, error instanceof AuthorizationFlowDisabledError ? missingAuthorizationReason(dispatch, error.provider) : error.message);
221
225
  }
222
226
  /** Run one dispatch start or resume under the owning conversation lease. */
223
227
  function createAgentDispatchConversationWorker(options) {
@@ -2865,7 +2869,7 @@ function viewerAutomationCollection(user) {
2865
2869
  createdAtMs: event.createdAtMs,
2866
2870
  state: sql`${event.status}`.as("state"),
2867
2871
  unavailable: sql`not (${available})`.as("unavailable"),
2868
- attention: sql`${event.status} <> 'paused' and (not (${available}) or ${lastRunNeedsAttention("event", event.id)})`.as("attention"),
2872
+ attention: sql`${event.status} <> 'paused' and (${event.status} = 'blocked' or not (${available}) or ${lastRunNeedsAttention("event", event.id)})`.as("attention"),
2869
2873
  owned: sql`${eventOwned}`.as("owned"),
2870
2874
  resource: sql`concat_ws(' ', ${event.identifier}, ${event.task}->'trigger'->>'label', ${event.namespace})`.as("resource"),
2871
2875
  ...fields(event.task, event.teamId)
@@ -3062,7 +3066,8 @@ function eventAutomationSummary(task, ownedByViewer, destination, stats, creator
3062
3066
  credentialMode: task.credentialMode,
3063
3067
  outcomes: effectiveTaskOutcomes(task.outcomes, task.destination),
3064
3068
  title: taskDisplayTitle(task.title, instruction, "Untitled event automation"),
3065
- status: task.status === "paused" ? "paused" : "active",
3069
+ status: task.status === "deleted" ? "active" : task.status,
3070
+ statusReason: task.statusReason,
3066
3071
  triggerAvailable: eventAutomationTriggerAvailable(task, getEventCatalog())
3067
3072
  };
3068
3073
  }
@@ -3365,6 +3370,93 @@ async function deleteViewerTask(user, kind, id) {
3365
3370
  await deleteEventAutomation(getDb(), id);
3366
3371
  }
3367
3372
  //#endregion
3373
+ //#region src/chat/slack/assistant-thread/status-send.ts
3374
+ /**
3375
+ * Slack's assistant loading UI accepts both `status` and `loading_messages`,
3376
+ * but product policy keeps `status` stable and generic. User-visible progress
3377
+ * copy belongs in `loading_messages`.
3378
+ */
3379
+ const SLACK_ASSISTANT_ACTIVE_STATUS = "is working on your request...";
3380
+ /**
3381
+ * Build a best-effort sender for Slack's assistant loading state.
3382
+ *
3383
+ * The `text` argument is internal progress copy. This transport maps it onto
3384
+ * Slack's loading surface and keeps the raw Slack `status` field fixed.
3385
+ */
3386
+ function createSlackAdapterStatusSender(args) {
3387
+ const adapter = args.getSlackAdapter();
3388
+ const boundToken = getSlackAdapterRequestToken(adapter);
3389
+ return async (text, loadingMessages) => {
3390
+ const channelId = args.channelId;
3391
+ const threadTs = args.threadTs;
3392
+ if (!channelId || !threadTs) return;
3393
+ const normalizedChannelId = normalizeSlackConversationId(channelId);
3394
+ if (!normalizedChannelId) return;
3395
+ const nextLoadingMessages = text ? loadingMessages ?? [text] : void 0;
3396
+ try {
3397
+ await runWithBoundSlackToken(adapter, boundToken, () => adapter.setAssistantStatus(normalizedChannelId, threadTs, text ? SLACK_ASSISTANT_ACTIVE_STATUS : "", nextLoadingMessages));
3398
+ } catch (error) {
3399
+ logAssistantStatusFailure({
3400
+ status: text,
3401
+ error,
3402
+ channelId,
3403
+ normalizedChannelId,
3404
+ threadTs
3405
+ });
3406
+ }
3407
+ };
3408
+ }
3409
+ /**
3410
+ * Build a best-effort sender for Slack's assistant loading state over raw Web
3411
+ * API calls. As with the adapter-backed path, the dynamic copy goes to
3412
+ * `loading_messages` while `status` stays fixed and generic.
3413
+ */
3414
+ function createSlackWebApiStatusSender(args) {
3415
+ const getClient = args.getSlackClient ?? getSlackClient;
3416
+ return async (text, loadingMessages) => {
3417
+ const channelId = args.channelId;
3418
+ const threadTs = args.threadTs;
3419
+ if (!channelId || !threadTs) return;
3420
+ const normalizedChannelId = normalizeSlackConversationId(channelId);
3421
+ if (!normalizedChannelId) return;
3422
+ const nextLoadingMessages = text ? loadingMessages ?? [text] : void 0;
3423
+ try {
3424
+ await getClient().assistant.threads.setStatus({
3425
+ channel_id: normalizedChannelId,
3426
+ thread_ts: threadTs,
3427
+ status: text ? SLACK_ASSISTANT_ACTIVE_STATUS : "",
3428
+ ...nextLoadingMessages ? { loading_messages: nextLoadingMessages } : void 0
3429
+ });
3430
+ } catch (error) {
3431
+ logAssistantStatusFailure({
3432
+ status: text,
3433
+ error,
3434
+ channelId,
3435
+ normalizedChannelId,
3436
+ threadTs
3437
+ });
3438
+ }
3439
+ };
3440
+ }
3441
+ function getSlackAdapterRequestToken(adapter) {
3442
+ const token = adapter.requestContext?.getStore()?.token;
3443
+ if (typeof token !== "string") return;
3444
+ return token.trim() || void 0;
3445
+ }
3446
+ async function runWithBoundSlackToken(adapter, token, task) {
3447
+ if (!token) return await task();
3448
+ return await adapter.withBotToken(token, task);
3449
+ }
3450
+ function logAssistantStatusFailure(args) {
3451
+ logWarn("assistant.status.update.failed", {
3452
+ "app.slack.status_text": args.status || "(clear)",
3453
+ "app.slack.channel_id_raw": args.channelId,
3454
+ "app.slack.channel_id": args.normalizedChannelId,
3455
+ "app.slack.thread_ts": args.threadTs,
3456
+ "exception.message": args.error instanceof Error ? args.error.message : String(args.error)
3457
+ });
3458
+ }
3459
+ //#endregion
3368
3460
  //#region src/chat/services/subscribed-reply-policy.ts
3369
3461
  function createSubscribedReplyPolicy(deps) {
3370
3462
  return async (args) => {
@@ -3906,93 +3998,6 @@ function createAssistantStatusScheduler(args) {
3906
3998
  };
3907
3999
  }
3908
4000
  //#endregion
3909
- //#region src/chat/slack/assistant-thread/status-send.ts
3910
- /**
3911
- * Slack's assistant loading UI accepts both `status` and `loading_messages`,
3912
- * but product policy keeps `status` stable and generic. User-visible progress
3913
- * copy belongs in `loading_messages`.
3914
- */
3915
- const SLACK_ASSISTANT_ACTIVE_STATUS = "is working on your request...";
3916
- /**
3917
- * Build a best-effort sender for Slack's assistant loading state.
3918
- *
3919
- * The `text` argument is internal progress copy. This transport maps it onto
3920
- * Slack's loading surface and keeps the raw Slack `status` field fixed.
3921
- */
3922
- function createSlackAdapterStatusSender(args) {
3923
- const adapter = args.getSlackAdapter();
3924
- const boundToken = getSlackAdapterRequestToken(adapter);
3925
- return async (text, loadingMessages) => {
3926
- const channelId = args.channelId;
3927
- const threadTs = args.threadTs;
3928
- if (!channelId || !threadTs) return;
3929
- const normalizedChannelId = normalizeSlackConversationId(channelId);
3930
- if (!normalizedChannelId) return;
3931
- const nextLoadingMessages = text ? loadingMessages ?? [text] : void 0;
3932
- try {
3933
- await runWithBoundSlackToken(adapter, boundToken, () => adapter.setAssistantStatus(normalizedChannelId, threadTs, text ? SLACK_ASSISTANT_ACTIVE_STATUS : "", nextLoadingMessages));
3934
- } catch (error) {
3935
- logAssistantStatusFailure({
3936
- status: text,
3937
- error,
3938
- channelId,
3939
- normalizedChannelId,
3940
- threadTs
3941
- });
3942
- }
3943
- };
3944
- }
3945
- /**
3946
- * Build a best-effort sender for Slack's assistant loading state over raw Web
3947
- * API calls. As with the adapter-backed path, the dynamic copy goes to
3948
- * `loading_messages` while `status` stays fixed and generic.
3949
- */
3950
- function createSlackWebApiStatusSender(args) {
3951
- const getClient = args.getSlackClient ?? getSlackClient;
3952
- return async (text, loadingMessages) => {
3953
- const channelId = args.channelId;
3954
- const threadTs = args.threadTs;
3955
- if (!channelId || !threadTs) return;
3956
- const normalizedChannelId = normalizeSlackConversationId(channelId);
3957
- if (!normalizedChannelId) return;
3958
- const nextLoadingMessages = text ? loadingMessages ?? [text] : void 0;
3959
- try {
3960
- await getClient().assistant.threads.setStatus({
3961
- channel_id: normalizedChannelId,
3962
- thread_ts: threadTs,
3963
- status: text ? SLACK_ASSISTANT_ACTIVE_STATUS : "",
3964
- ...nextLoadingMessages ? { loading_messages: nextLoadingMessages } : void 0
3965
- });
3966
- } catch (error) {
3967
- logAssistantStatusFailure({
3968
- status: text,
3969
- error,
3970
- channelId,
3971
- normalizedChannelId,
3972
- threadTs
3973
- });
3974
- }
3975
- };
3976
- }
3977
- function getSlackAdapterRequestToken(adapter) {
3978
- const token = adapter.requestContext?.getStore()?.token;
3979
- if (typeof token !== "string") return;
3980
- return token.trim() || void 0;
3981
- }
3982
- async function runWithBoundSlackToken(adapter, token, task) {
3983
- if (!token) return await task();
3984
- return await adapter.withBotToken(token, task);
3985
- }
3986
- function logAssistantStatusFailure(args) {
3987
- logWarn("assistant.status.update.failed", {
3988
- "app.slack.status_text": args.status || "(clear)",
3989
- "app.slack.channel_id_raw": args.channelId,
3990
- "app.slack.channel_id": args.normalizedChannelId,
3991
- "app.slack.thread_ts": args.threadTs,
3992
- "exception.message": args.error instanceof Error ? args.error.message : String(args.error)
3993
- });
3994
- }
3995
- //#endregion
3996
4001
  //#region src/chat/slack/assistant-thread/status.ts
3997
4002
  /**
3998
4003
  * Create a Slack adapter-backed session for Slack's assistant loading state.
@@ -4915,7 +4920,7 @@ function createSlackTurn(deps) {
4915
4920
  toolName: event.toolName
4916
4921
  });
4917
4922
  },
4918
- ...options.execution?.dispatch?.outcomes?.length === 0 ? void 0 : { delivery: deliverAssistantMessage },
4923
+ ...deliversFinalText(options.execution?.dispatch) ? { delivery: deliverAssistantMessage } : void 0,
4919
4924
  durability: {
4920
4925
  onInputCommitted: options.ack,
4921
4926
  drainSteeringMessages,
@@ -4946,12 +4951,10 @@ function createSlackTurn(deps) {
4946
4951
  finalResult = finalized.reply;
4947
4952
  failureEventId = finalized.eventId;
4948
4953
  failureReason = finalized.failureReason;
4949
- await deliverAssistantMessage(finalResult.text);
4950
4954
  }
4951
- const turnResult = finalResult.diagnostics.outcome === "success" ? { outcome: "completed" } : {
4952
- errorMessage: finalResult.diagnostics.errorMessage ?? `Agent turn ended with ${finalResult.diagnostics.outcome}.`,
4953
- outcome: "failed"
4954
- };
4955
+ const reply = finishedRunReply(finalResult, options.execution?.dispatch);
4956
+ if (reply !== void 0) await deliverAssistantMessage(reply);
4957
+ const turnResult = runDispatchOutcome(finalResult);
4955
4958
  runResultHandled = true;
4956
4959
  shouldPersistFailureState = false;
4957
4960
  boundaryFailureCode = "agent_run_failed";
@@ -4975,7 +4978,7 @@ function createSlackTurn(deps) {
4975
4978
  destinationVisibility,
4976
4979
  source,
4977
4980
  sliceId: 1,
4978
- dispatchOutcome: finalResult.diagnostics.outcome === "success" ? "completed" : "failed",
4981
+ dispatchOutcome: turnResult.outcome,
4979
4982
  ...options.execution?.dispatch && turnResult.errorMessage ? { errorMessage: turnResult.errorMessage } : void 0,
4980
4983
  ...acceptedDeliveryId ? { resultMessageId: acceptedDeliveryId } : void 0,
4981
4984
  messages: finalResult.piMessages,
@@ -4998,7 +5001,7 @@ function createSlackTurn(deps) {
4998
5001
  source,
4999
5002
  surface: options.execution?.surface ?? "slack",
5000
5003
  dispatchId: options.execution?.dispatch?.id,
5001
- dispatchOutcome: finalResult.diagnostics.outcome === "success" ? "completed" : "failed",
5004
+ dispatchOutcome: turnResult.outcome,
5002
5005
  ...acceptedDeliveryId ? { resultMessageId: acceptedDeliveryId } : void 0,
5003
5006
  traceId: getActiveTraceId()
5004
5007
  });
@@ -5787,7 +5790,7 @@ function buildResumedRun(args, statusSession, delivery) {
5787
5790
  if (event.type === "status") statusSession.update({ text: event.text });
5788
5791
  await priorOnEvent?.(event);
5789
5792
  },
5790
- ...savedRun.dispatch?.outcomes?.length === 0 ? void 0 : { delivery },
5793
+ ...deliversFinalText(savedRun.dispatch) ? { delivery } : void 0,
5791
5794
  durability: {
5792
5795
  ...savedRun.durability,
5793
5796
  onSandboxRefChanged: async (sandboxRef) => {
@@ -5977,8 +5980,11 @@ async function resumeSlackTurnInContext(args) {
5977
5980
  logException
5978
5981
  });
5979
5982
  const reply = finalized.reply;
5980
- const dispatchErrorMessage = run.dispatch && reply.diagnostics.outcome !== "success" ? reply.diagnostics.errorMessage ?? `Agent turn ended with ${reply.diagnostics.outcome}.` : void 0;
5981
- if (reply.diagnostics.outcome !== "success") await deliverAssistantMessage(reply.text);
5983
+ setSpanAttributes(getAgentTurnDiagnosticsAttributes(reply));
5984
+ const dispatchResult = runDispatchOutcome(reply);
5985
+ const dispatchErrorMessage = run.dispatch ? dispatchResult.errorMessage : void 0;
5986
+ const replyText = finishedRunReply(reply, run.dispatch);
5987
+ if (replyText !== void 0) await deliverAssistantMessage(replyText);
5982
5988
  runResultHandled = true;
5983
5989
  await status.clear();
5984
5990
  failureCode = "persistence_failed";
@@ -5992,7 +5998,7 @@ async function resumeSlackTurnInContext(args) {
5992
5998
  destination: run.destination,
5993
5999
  destinationVisibility: visibility,
5994
6000
  dispatchId: run.dispatch?.id,
5995
- dispatchOutcome: reply.diagnostics.outcome === "success" ? "completed" : "failed",
6001
+ dispatchOutcome: dispatchResult.outcome,
5996
6002
  ...dispatchErrorMessage ? { errorMessage: dispatchErrorMessage } : void 0,
5997
6003
  ...acceptedDeliveryId ? { resultMessageId: acceptedDeliveryId } : void 0,
5998
6004
  source: run.source,
@@ -6005,7 +6011,7 @@ async function resumeSlackTurnInContext(args) {
6005
6011
  destination: run.destination,
6006
6012
  destinationVisibility: visibility,
6007
6013
  dispatchId: run.dispatch?.id,
6008
- dispatchOutcome: reply.diagnostics.outcome === "success" ? "completed" : "failed",
6014
+ dispatchOutcome: dispatchResult.outcome,
6009
6015
  ...acceptedDeliveryId ? { resultMessageId: acceptedDeliveryId } : void 0,
6010
6016
  turnId: runArgs.turnId,
6011
6017
  sliceId: runArgs.sliceId ?? 1,
@@ -6675,23 +6681,6 @@ function captureConversationTurnFailure(args) {
6675
6681
  });
6676
6682
  return typeof eventId === "string" ? eventId : void 0;
6677
6683
  }
6678
- /**
6679
- * Reply in the thread started by a channel-level Conversation's first Message.
6680
- * Automation runs post at the channel top level, so their Watches need this.
6681
- */
6682
- async function resolveStartedThreadLocation(conversationId, location) {
6683
- if (location?.provider !== "slack" || location.threadTs) return location;
6684
- const threadTs = await getConversationStore().getFirstProviderConversationId({
6685
- conversationId,
6686
- provider: "slack",
6687
- providerDestinationId: location.channelId,
6688
- providerTenantId: location.teamId
6689
- });
6690
- return threadTs ? {
6691
- ...location,
6692
- threadTs
6693
- } : location;
6694
- }
6695
6684
  /** Return the saved timer creator subject when it is still valid here. */
6696
6685
  function resumedTimerWatchCredentialSubject(conversationId, subject) {
6697
6686
  if (subject?.binding.type !== "timer-watch") return void 0;
@@ -6816,7 +6805,7 @@ function createConversationTurnWorker(agentRunner, deliverMessage) {
6816
6805
  visibility: storedConversation?.visibility
6817
6806
  });
6818
6807
  const webActor = actor.platform === "web" ? actor : void 0;
6819
- const conversationLocation = await resolveStartedThreadLocation(context.conversationId, storedConversation?.location);
6808
+ const conversationLocation = storedConversation?.location;
6820
6809
  const deliverToProvider = Boolean(conversationLocation) && (source.kind === "event" || savedMessageIsEvent);
6821
6810
  const surface = deliverToProvider ? "slack" : "api";
6822
6811
  return await withLogContext({
@@ -7477,4 +7466,4 @@ async function appendAndEnqueueWebMessage(input, options) {
7477
7466
  };
7478
7467
  }
7479
7468
  //#endregion
7480
- export { getAuthPausedConversationTurnId as A, readHealthReport as B, clearSlackPendingReactions as C, stopSlackThread as D, isSlackMessageStopped as E, renderSlackObjectCard as F, createVercelAttachmentStorage as I, AGENT_DISPATCH_MAX_AGE_MS as L, THREAD_OPTOUT_ACK as M, startProcessingReaction as N, normalizeIncomingSlackThreadId as O, parseContent as P, enqueueAgentDispatch as R, buildSlackInboundMessage as S, verifySlackSignature as T, readViewerAutomationSummary as _, recordWebConversationActivity as a, resolveViewerTaskCandidate as b, createProductionSlackWebhookServices as c, resolveSlackConversationContextFromThreadId as d, ViewerTaskNotFoundError as f, readViewerAutomationRuns as g, readViewerAutomationExecutions as h, createConversationId as i, legacyWebMailboxMetadataSchema as j, withNormalizedThreadId as k, getProductionSlackAdapter as l, readConversationSourceTask as m, conversationTurnIdForMessage as n, webActorFromEmail as o, deleteViewerTask as p, createAndEnqueueConversation as r, createProductionConversationWorkOptions as s, appendAndEnqueueWebMessage as t, formatSlackConversationRedactedLabel as u, readViewerAutomationVersions as v, runWithSlackInstallation as w, recordSkippedConversationMessage as x, readViewerAutomations as y, GET as z };
7469
+ export { withNormalizedThreadId as A, GET as B, buildSlackInboundMessage as C, isSlackMessageStopped as D, verifySlackSignature as E, parseContent as F, renderSlackObjectCard as I, createVercelAttachmentStorage as L, legacyWebMailboxMetadataSchema as M, THREAD_OPTOUT_ACK as N, stopSlackThread as O, startProcessingReaction as P, AGENT_DISPATCH_MAX_AGE_MS as R, recordSkippedConversationMessage as S, runWithSlackInstallation as T, readHealthReport as V, readViewerAutomationRuns as _, recordWebConversationActivity as a, readViewerAutomations as b, createProductionSlackWebhookServices as c, resolveSlackConversationContextFromThreadId as d, createSlackWebApiStatusSender as f, readViewerAutomationExecutions as g, readConversationSourceTask as h, createConversationId as i, getAuthPausedConversationTurnId as j, normalizeIncomingSlackThreadId as k, getProductionSlackAdapter as l, deleteViewerTask as m, conversationTurnIdForMessage as n, webActorFromEmail as o, ViewerTaskNotFoundError as p, createAndEnqueueConversation as r, createProductionConversationWorkOptions as s, appendAndEnqueueWebMessage as t, formatSlackConversationRedactedLabel as u, readViewerAutomationSummary as v, clearSlackPendingReactions as w, resolveViewerTaskCandidate as x, readViewerAutomationVersions as y, enqueueAgentDispatch as z };