@sentry/junior 0.204.0 → 0.206.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 (66) hide show
  1. package/dist/{agent-CMyTD4DD.js → agent-C9yuiZUF.js} +277 -85
  2. package/dist/{agent-hooks-Bbcp9e33.js → agent-hooks-DNjlz2A-.js} +1084 -16
  3. package/dist/{agent-runner-DNb1A49M.js → agent-runner-E67lFrDG.js} +5 -5
  4. package/dist/api/schema.d.ts +85 -0
  5. package/dist/api/schema.js +2 -2
  6. package/dist/api.js +44 -511
  7. package/dist/{app-B1TOqBI8.d.ts → app-AxGmJHwK.d.ts} +8 -0
  8. package/dist/app.d.ts +1 -1
  9. package/dist/app.js +56 -84
  10. package/dist/{auth-pause-state-DosEalIG.js → auth-pause-state-MVZ6xvEK.js} +6 -6
  11. package/dist/briefs-CvJFQvhJ.js +398 -0
  12. package/dist/{catalog-runtime-BReos-D4.js → catalog-runtime-TBR8n4e1.js} +1 -1
  13. package/dist/{checkpoint-CNrPyRJN.js → checkpoint-BY47jJCB.js} +7 -6
  14. package/dist/cli/chat.js +14 -12
  15. package/dist/cli/check.js +3 -3
  16. package/dist/cli/init.js +1 -0
  17. package/dist/cli/main.js +5 -1
  18. package/dist/cli/plugins.js +3 -3
  19. package/dist/cli/run.d.ts +2 -1
  20. package/dist/cli/run.js +2 -1
  21. package/dist/cli/snapshot-create.js +3 -3
  22. package/dist/cli/upgrade.js +3 -3
  23. package/dist/{config-nGCW1OTG.js → client-ceE7NtvC.js} +4 -367
  24. package/dist/config-CIE83sR2.js +386 -0
  25. package/dist/{schema-Rn8-XEaN.js → conversation-AA4R1VUn.js} +580 -558
  26. package/dist/{conversation-privacy-B4voFRSm.js → conversation-privacy-Auyq26XQ.js} +1 -1
  27. package/dist/{credential-sync-kXr1hvO1.js → credential-sync-BO33aNQd.js} +22 -20
  28. package/dist/{execution-stats-DWfSihcH.js → execution-stats-SiS2FLcv.js} +4 -4
  29. package/dist/{executor-DcMSlI5c.js → executor-BfbYPW63.js} +31 -3
  30. package/dist/instrumentation.js +2 -2
  31. package/dist/{job-queue-Drn_LXlM.js → job-queue-CyTc24Es.js} +1 -1
  32. package/dist/{logging-BzAk1S_s.js → logging-D37bayDc.js} +1 -1
  33. package/dist/nitro.d.ts +1 -1
  34. package/dist/nitro.js +3 -3
  35. package/dist/{oauth-callback-server-JiftokvA.js → oauth-callback-server-BtfOeHTZ.js} +2 -2
  36. package/dist/{pending-auth-CWmSdZVg.js → pending-auth-BPUzcs7n.js} +2 -2
  37. package/dist/{profile-CrT5nXbw.js → profile-CSixooTi.js} +4 -3
  38. package/dist/prompt-3gqNY1Ka.js +552 -0
  39. package/dist/{registry-DH1xUo2N.js → registry-DiR0-xRg.js} +1 -1
  40. package/dist/{resolve-CZHnfxaS.js → resolve-Bn5q__9b.js} +2 -2
  41. package/dist/{runner-CZV2sC46.js → runner-DFx3dIJH.js} +9 -9
  42. package/dist/{sandbox-egress-signals-bHZfmhbd.js → sandbox-egress-signals-bwvjihxA.js} +1 -1
  43. package/dist/schema-8GXFfclK.js +559 -0
  44. package/dist/{skills-CIcDQSgM.js → skills-BhM5qyCF.js} +2 -2
  45. package/dist/{spawn-DdkUFRmq.js → spawn-Dk0PqdH6.js} +2 -2
  46. package/dist/{stats-DTUbAb88.js → stats-DKRP4rsY.js} +26 -12
  47. package/dist/{task-queue-CJIR4RF7.js → task-queue-CdpTvu4R.js} +3 -3
  48. package/dist/{task-runner-D-O3A-Cp.js → task-runner-alpjVSxQ.js} +10 -10
  49. package/dist/{thread-state-CRc9jTJS.js → thread-state-CRK7aA41.js} +5 -5
  50. package/dist/{turn-execution-BkinIdJF.js → turn-execution-XtyzIHog.js} +3 -3
  51. package/dist/{turn-lifecycle-DQV19VTW.js → turn-lifecycle-VbwZLfBv.js} +1 -1
  52. package/dist/{usage-D3EbSO7w.js → usage-D4A48Bdl.js} +4 -125
  53. package/dist/{validation-C2CR-OX3.js → validation-jn_46o4U.js} +1 -1
  54. package/dist/{version-DxcWdoKa.js → version-DcfJxB4z.js} +1 -1
  55. package/dist/version.js +1 -1
  56. package/dist/web-authorization-CsfLSfEs.js +38 -0
  57. package/dist/{web-input-3EPfpf55.js → web-input-BPp_sc7t.js} +6 -6
  58. package/dist/{work-fGofI7Op.js → work-Di-ubSGg.js} +9 -9
  59. package/dist/{worker-CsOLq-mR.js → worker-Cu_D5Mr8.js} +5 -4
  60. package/migrations/0040_conversation_briefs.sql +17 -0
  61. package/migrations/meta/0040_snapshot.json +3516 -0
  62. package/migrations/meta/_journal.json +7 -0
  63. package/package.json +4 -4
  64. package/dist/history-CqTuSAdI.js +0 -441
  65. package/dist/usage-schema-CKaDkH_j.js +0 -20
  66. package/dist/web-authorization-RMBxAR_t.js +0 -76
@@ -1,25 +1,28 @@
1
- import { A as createProviderError, C as MODEL_HANDOFF_SUMMARY_PREFIX, D as unwrapCurrentInstruction, E as renderCurrentInstruction, F as MISSING_GATEWAY_CREDENTIALS_ERROR, I as getGatewayApiKey, L as resolveGatewayCredential, M as getProviderErrorAttributes, O as escapeXml, P as isProviderRetryError, S as COMPACTION_SUMMARY_PREFIX, T as isCompactionSummaryText, _ as completeObject, b as resolveGatewayModel, g as GEN_AI_SERVER_ADDRESS, h as GEN_AI_PROVIDER_NAME, j as findProviderError, k as ProviderError, m as normalizeSlackEmojiName, n as botConfig, v as completeText, w as hasCompactedConversationContext, x as ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX } from "./config-nGCW1OTG.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-BzAk1S_s.js";
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-ceE7NtvC.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-D37bayDc.js";
3
3
  import { _ as withActiveSpan, m as startInactiveSpan } from "./sentry-CD3SdJl-.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-B4voFRSm.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-Auyq26XQ.js";
5
+ import { h as normalizeSlackEmojiName, n as botConfig } from "./config-CIE83sR2.js";
5
6
  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";
6
7
  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-B45_WqVX.js";
7
- import { $ as RESOURCE_SUBSCRIPTION_DEFAULT_TTL_MS, B as getSlackClient, Bt as parseDestination, C as setWorkspaceSnapshotBuild, Ct as getConversationEventStore, D as tryWorkspaceRepoCheckoutPath, Dt as getSqlExecutor, E as getWorkspaceSnapshotBuilder, Et as getDb, G as withSlackRetries, I as SlackActionError, L as downloadPrivateSlackFile, O as workspaceRepoCheckoutPath, Q as getSlackToolContext, R as getFilePermalink, S as setWorkspaceSnapshot, T as deleteWorkspaceSnapshotBuilders, Tt as getConversationStore, U as normalizeSlackConversationId, V as isConversationScopedChannel, Y as readActorIdentity, _ as listWorkspaces, _t as createPluginLogger, b as invalidateReadySnapshot, c as getPluginTools, ct as findMatchingResourceEventSubscriptions, ft as getDashboardTaskLink, g as getWorkspaceByName, h as getWorkspace, it as cancelSubscriptions, k as resolveChannelCapabilities, l as getPluginUserPromptContributions, lt as listResourceEventSubscriptions, m as deleteWorkspace, nt as STOP_WATCHING_TOOL_NAME, ot as createResourceEventSubscription, p as createWorkspace, r as createPluginHookRunner, rt as cancelResourceEventSubscription, s as getPluginSystemPromptContributions, st as deliverResourceEventSubscription, tt as RESOURCE_WATCH_TOOL_SOURCE, u as getPlugins, ut as JUNIOR_THREAD_STATE_TTL_MS, v as updateWorkspace, w as SANDBOX_RUNTIME, wt as getConversationMessageSearchStore, x as loadSnapshotsForProfile, y as WorkspaceValidationError } from "./agent-hooks-Bbcp9e33.js";
8
- import { E as juniorArtifacts, a as juniorSchedulerRuns, d as AGENT_INVOCATION_MAILBOX_STATUSES, w as juniorIdentities, x as juniorAttachments } from "./executor-DcMSlI5c.js";
9
- import { d as instructionProvenanceFor, f as sameActorIdentity, l as contextProvenance, t as KNOWN_CONVERSATION_EVENT_TYPES, u as instructionActors } from "./history-CqTuSAdI.js";
8
+ import { A as tryWorkspaceRepoCheckoutPath, B as downloadPrivateSlackFile, C as invalidateReadySnapshot, D as SANDBOX_RUNTIME, E as setWorkspaceSnapshotBuild, Ft as getConversationStore, It as getDb, J as withSlackRetries, K as normalizeSlackConversationId, Lt as getSqlExecutor, M as resolveChannelCapabilities, Nt as getConversationEventStore, O as deleteWorkspaceSnapshotBuilders, Pt as getConversationMessageSearchStore, Q as readActorIdentity, S as WorkspaceValidationError, T as setWorkspaceSnapshot, U as getSlackClient, V as getFilePermalink, W as isConversationScopedChannel, Xt as parseDestination, _ as deleteWorkspace, at as STOP_WATCHING_TOOL_NAME, b as listWorkspaces, bt as createPluginLogger, c as getPluginTools, dt as findMatchingResourceEventSubscriptions, ft as listResourceEventSubscriptions, g as createWorkspace, ht as getDashboardTaskLink, it as RESOURCE_WATCH_TOOL_SOURCE, j as workspaceRepoCheckoutPath, k as getWorkspaceSnapshotBuilder, l as getPluginUserPromptContributions, lt as createResourceEventSubscription, mt as getDashboardConversationLink, nt as RESOURCE_SUBSCRIPTION_DEFAULT_TTL_MS, ot as cancelResourceEventSubscription, pt as JUNIOR_THREAD_STATE_TTL_MS, r as createPluginHookRunner, s as getPluginSystemPromptContributions, st as cancelSubscriptions, tt as getSlackToolContext, u as getPlugins, ut as deliverResourceEventSubscription, v as getWorkspace, w as loadSnapshotsForProfile, x as updateWorkspace, y as getWorkspaceByName, z as SlackActionError } from "./agent-hooks-DNjlz2A-.js";
9
+ import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
10
+ import { D as juniorArtifacts, S as juniorAttachments, T as juniorIdentities, a as juniorSchedulerRuns, d as AGENT_INVOCATION_MAILBOX_STATUSES, g as juniorConversationBriefs, w as juniorConversations, y as juniorConversationAnnotations } from "./executor-BfbYPW63.js";
11
+ import { A as briefLinkSchema, F as KNOWN_CONVERSATION_EVENT_TYPES, G as instructionProvenanceFor, K as sameActorIdentity, M as conversationBriefSchema, U as contextProvenance, W as instructionActors, j as briefOutcomeStatusSchema } from "./conversation-AA4R1VUn.js";
10
12
  import { a as listReferenceFiles, c as soulPathCandidates, l as worldPathCandidates } from "./package-discovery-7a9YqLhE.js";
11
- import { a as resolvePluginCommandEnv, c as getOAuthProviderErrorAttributes, i as resolveAuthTokenPlaceholder, o as OAuthProviderError, s as fetchWithBoundedOAuthErrorBodies, u as CredentialUnavailableError } from "./registry-DH1xUo2N.js";
12
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BReos-D4.js";
13
- import { a as parseSkillInvocation, n as findSkillByName, r as loadSkillsByName, t as discoverSkills } from "./skills-CIcDQSgM.js";
14
- import { A as normalizeToLf$1, At as retainRuntimeTurnContext, B as openConversationProjection, C as DEFAULT_SEARCH_COMMAND_TIMEOUT_MS, Ct as hasRuntimeTurnContext, D as getRipgrepSearchLocation, Dt as isToolResultError, E as collectFiles, Et as isContinuablePiBoundary, G as recordAuthorizationRequested, H as recordAttachmentsDelivered, I as loadConnectedMcpProviders, K as recordGuardianActionReviewed, L as loadConversationProjection, M as resolveWorkspacePath, Mt as trimTrailingAssistantMessages, N as truncateText$1, Nt as TURN_CONTEXT_TAG, O as isMissingPathError, Ot as isToolResultMessage, S as resolveRepositoryInstructionsForDirectories, St as getUserMessageInstructionText, T as RIPGREP_EXCLUDED_GLOBS, Tt as isAssistantMessage, V as recordAgentsInstructionsUpdated, X as recordTurnRoute, Y as recordToolExecutionStarted, _ as AGENTS_REPLACEMENT_NOTICE, _t as historyItemFromPiMessage, b as listRepositoryDirectories, bt as getPiMessageRole, f as TurnSliceLimitExceededError, g as AGENTS_REMOVAL_NOTICE, gt as getAgentContextInputLimitTokens, h as isTurnExecutionLimitExceededError, ht as getAgentContextCompactionTriggerTokens, j as positiveInteger$1, jt as stripRuntimeTurnContext, k as missingPathSearchResult, kt as normalizeToolNameFromResult, mt as estimateTextTokens, n as loadTurnCheckpoint, p as assertTurnToolCallLimit, q as recordMcpProviderConnected, r as saveTurnCheckpoint, t as continuableMessages, v as buildAgentsInstructionsMessage, vt as piMessageFromHistoryItem, w as MAX_TEXT_CHARS, x as renderAgentsInstructions, xt as getTerminalAssistantMessages, y as findVisibleAgentsInstructions, yt as extractAssistantText, z as loadTurnRoute } from "./checkpoint-CNrPyRJN.js";
15
- import { a as hasAgentTurnUsage, c as generateShortTitle, l as resolveTaskTitle, o as ToolInputError, t as addAgentTurnUsage } from "./usage-D3EbSO7w.js";
16
- 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-CrT5nXbw.js";
17
- import { $ as workspaceSnapshotWatch, B as deleteEventTask, C as SCHEDULED_TASK_SYSTEM_ACTOR, D as eventTaskMatchesDestination, E as eventTaskListToolResultSchema, F as effectiveTaskOutcomes, Ht as juniorToolOutputSchema, I as resolveTaskOutcomes, J as saveEventTask, K as listEventTasksForTeam, L as taskOutcomeInputSchema, M as requireEventTaskSlackContext, N as requireSupportedEventTaskTrigger, O as eventTaskSuccess, P as writableEventTask, Q as workspaceSnapshotFinishedEvent, T as compactEventTask, U as getEventTask, Ut as makeStructuredToolOutput, Vt as injectContinuationToolName, X as WORKSPACE_SNAPSHOT_FAILED_EVENT, Y as getResourceEventCatalog, Z as WORKSPACE_SNAPSHOT_READY_EVENT, at as registeredEventTypeSchema, c as parseSlackThreadId, ct as requireSupportedResourceEventMatch, et as eventNamespaceSchema, f as createScheduledTask, ft as appendAndEnqueueInboundMessage, g as listScheduledTasksForTeam, i as readLiveAttachment, it as pluginSupportsEvent, j as registeredEventTaskTriggerSchema, k as eventTaskToolResultSchema, lt as resourceEventGuidance, nt as hasResourceEventCatalogEntries, ot as registeredResourceEventMatchSchema, rt as normalizeEventIdentifier, s as storeAttachments, st as registeredResourceTypeSchema, t as incrementStat, tt as hasPluginResourceEventCatalogEntries, v as readScheduledTask, y as saveScheduledTask, z as createEventTask } from "./stats-DTUbAb88.js";
18
- 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-CWmSdZVg.js";
19
- 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-DNb1A49M.js";
20
- 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-CZHnfxaS.js";
13
+ import { a as resolvePluginCommandEnv, c as getOAuthProviderErrorAttributes, i as resolveAuthTokenPlaceholder, o as OAuthProviderError, s as fetchWithBoundedOAuthErrorBodies, u as CredentialUnavailableError } from "./registry-DiR0-xRg.js";
14
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-TBR8n4e1.js";
15
+ import { a as parseSkillInvocation, n as findSkillByName, r as loadSkillsByName, t as discoverSkills } from "./skills-BhM5qyCF.js";
16
+ import { A as normalizeToLf$1, At as retainRuntimeTurnContext, B as openConversationProjection, C as DEFAULT_SEARCH_COMMAND_TIMEOUT_MS, Ct as hasRuntimeTurnContext, D as getRipgrepSearchLocation, Dt as isToolResultError, E as collectFiles, Et as isContinuablePiBoundary, G as recordAuthorizationRequested, H as recordAttachmentsDelivered, I as loadConnectedMcpProviders, K as recordGuardianActionReviewed, L as loadConversationProjection, M as resolveWorkspacePath, Mt as trimTrailingAssistantMessages, N as truncateText$1, Nt as TURN_CONTEXT_TAG, O as isMissingPathError, Ot as isToolResultMessage, S as resolveRepositoryInstructionsForDirectories, St as getUserMessageInstructionText, T as RIPGREP_EXCLUDED_GLOBS, Tt as isAssistantMessage, V as recordAgentsInstructionsUpdated, X as recordTurnRoute, Y as recordToolExecutionStarted, _ as AGENTS_REPLACEMENT_NOTICE, _t as historyItemFromPiMessage, b as listRepositoryDirectories, bt as getPiMessageRole, f as TurnSliceLimitExceededError, g as AGENTS_REMOVAL_NOTICE, gt as getAgentContextInputLimitTokens, h as isTurnExecutionLimitExceededError, ht as getAgentContextCompactionTriggerTokens, j as positiveInteger$1, jt as stripRuntimeTurnContext, k as missingPathSearchResult, kt as normalizeToolNameFromResult, mt as estimateTextTokens, n as loadTurnCheckpoint, p as assertTurnToolCallLimit, q as recordMcpProviderConnected, r as saveTurnCheckpoint, t as continuableMessages, v as buildAgentsInstructionsMessage, vt as piMessageFromHistoryItem, w as MAX_TEXT_CHARS, x as renderAgentsInstructions, xt as getTerminalAssistantMessages, y as findVisibleAgentsInstructions, yt as extractAssistantText, z as loadTurnRoute } from "./checkpoint-BY47jJCB.js";
17
+ import { a as hasAgentTurnUsage, c as generateShortTitle, l as resolveTaskTitle, o as ToolInputError, t as addAgentTurnUsage } from "./usage-D4A48Bdl.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-CSixooTi.js";
19
+ import { $ as workspaceSnapshotFinishedEvent, B as createEventTask, C as SCHEDULED_TASK_SYSTEM_ACTOR, D as eventTaskMatchesDestination, E as eventTaskListToolResultSchema, F as effectiveTaskOutcomes, Ht as injectContinuationToolName, I as moveTaskOutcomes, L as resolveTaskOutcomes, M as requireEventTaskSlackContext, N as requireSupportedEventTaskTrigger, O as eventTaskSuccess, P as writableEventTask, Q as WORKSPACE_SNAPSHOT_READY_EVENT, R as taskOutcomeInputSchema, T as compactEventTask, Ut as juniorToolOutputSchema, V as deleteEventTask, W as getEventTask, Wt as makeStructuredToolOutput, X as getResourceEventCatalog, Y as saveEventTask, Z as WORKSPACE_SNAPSHOT_FAILED_EVENT, at as pluginSupportsEvent, c as parseSlackThreadId, ct as registeredResourceTypeSchema, et as workspaceSnapshotWatch, f as createScheduledTask, g as listScheduledTasksForTeam, i as readLiveAttachment, it as normalizeEventIdentifier, j as registeredEventTaskTriggerSchema, k as eventTaskToolResultSchema, lt as requireSupportedResourceEventMatch, nt as hasPluginResourceEventCatalogEntries, ot as registeredEventTypeSchema, pt as appendAndEnqueueInboundMessage, q as listEventTasksForTeam, rt as hasResourceEventCatalogEntries, s as storeAttachments, st as registeredResourceEventMatchSchema, t as incrementStat, tt as eventNamespaceSchema, ut as resourceEventGuidance, v as readScheduledTask, y as saveScheduledTask } from "./stats-DKRP4rsY.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-BPUzcs7n.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-E67lFrDG.js";
22
+ import { r as RESOURCE_EVENT_AUTHOR_ID } from "./prompt-3gqNY1Ka.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-Bn5q__9b.js";
21
24
  import { t as getVercelConversationWorkQueue } from "./vercel-queue-DIkVcfK4.js";
22
- import { a as getTurnRequestDeadline, n as sendNextWorkspaceSnapshotJob, r as sendWorkspaceSnapshotJob } from "./job-queue-Drn_LXlM.js";
25
+ import { a as getTurnRequestDeadline, n as sendNextWorkspaceSnapshotJob, r as sendWorkspaceSnapshotJob } from "./job-queue-CyTc24Es.js";
23
26
  import { n as privateTraceResultAttributes } from "./private-trace-result-BLvBjy_e.js";
24
27
  import { streamSimple } from "@earendil-works/pi-ai/compat";
25
28
  import { createGatewayProvider } from "@ai-sdk/gateway";
@@ -29,7 +32,7 @@ import { isDeepStrictEqual } from "node:util";
29
32
  import { AsyncLocalStorage } from "node:async_hooks";
30
33
  import { z } from "zod";
31
34
  import { createHash, createHmac, randomUUID, timingSafeEqual } from "node:crypto";
32
- import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
35
+ import { and, desc, eq, gt, gte, inArray, isNull, lt, ne, notExists, or, sql } from "drizzle-orm";
33
36
  import { EgressAuthRequired, EgressPolicyDenied, PluginToolInputError, actorSchema, destinationSchema, missingToolAnnotationKeys, pluginAuthorizationSchema, pluginCredentialHeaderTransformSchema, pluginCredentialResultSchema, pluginGrantSchema, pluginProviderAccountSchema, pluginStoredTokensSchema, resourceEventSchema, resourceEventSubscriptionResultSchema, sourceSchema, stableResourceEventMatchKey, taskOutcomeSchema } from "@sentry/junior-plugin-api";
34
37
  import { alias } from "drizzle-orm/pg-core";
35
38
  import { Agent, estimateContextTokens } from "@earendil-works/pi-agent-core";
@@ -694,13 +697,25 @@ function applyProfileReasoningOverride(route, profiles) {
694
697
  reason: `profile_reasoning_override:${route.profile}:${route.reason}`
695
698
  };
696
699
  }
700
+ /**
701
+ * The fast classifier model occasionally returns a malformed object
702
+ * (`ProviderError` kind `invalid_response`, e.g. the AI SDK's
703
+ * `NoObjectGeneratedError`) even though a retry usually succeeds. Give it
704
+ * one retry before falling back to `defaultProfile`; any other error kind
705
+ * still falls back immediately.
706
+ */
707
+ const CLASSIFIER_MAX_ATTEMPTS = 2;
708
+ function isRetryableClassifierError(error) {
709
+ return error instanceof ProviderError && error.kind === "invalid_response";
710
+ }
697
711
  async function classifyTurn(args) {
698
- try {
712
+ let lastError;
713
+ for (let attempt = 1; attempt <= CLASSIFIER_MAX_ATTEMPTS; attempt++) try {
699
714
  const schema = createTurnRouteSchema(args.profiles);
700
715
  const result = await args.completeObject({
701
716
  modelId: args.fastModelId,
702
717
  schema,
703
- maxTokens: 140,
718
+ maxTokens: 5e3,
704
719
  metadata: args.metadata,
705
720
  prompt: args.prompt,
706
721
  thinkingLevel: "low",
@@ -727,14 +742,17 @@ async function classifyTurn(args) {
727
742
  source: "router"
728
743
  };
729
744
  } catch (error) {
730
- logWarn("turn.router.classifier.failed", { "exception.message": error instanceof Error ? error.message : String(error) });
731
- return {
732
- profile: args.defaultProfile,
733
- reasoningLevel: CLASSIFIER_FALLBACK_REASONING_LEVEL,
734
- reason: "classifier_error_default",
735
- source: "router"
736
- };
745
+ lastError = error;
746
+ if (attempt < CLASSIFIER_MAX_ATTEMPTS && isRetryableClassifierError(error)) continue;
747
+ break;
737
748
  }
749
+ logWarn("turn.router.classifier.failed", { "exception.message": lastError instanceof Error ? lastError.message : String(lastError) });
750
+ return {
751
+ profile: args.defaultProfile,
752
+ reasoningLevel: CLASSIFIER_FALLBACK_REASONING_LEVEL,
753
+ reason: "classifier_error_default",
754
+ source: "router"
755
+ };
738
756
  }
739
757
  /** Convert a routing bucket into the Pi Agent reasoning setting for a main turn. */
740
758
  function toPiReasoningLevel(level) {
@@ -1213,7 +1231,7 @@ function buildOutputSection(platform) {
1213
1231
  `<output format="slack-markdown">`,
1214
1232
  "- Default to the shortest complete reply—usually 1–5 sentences and under 800 characters. Include only the outcome, decisive evidence, and any blocker or required next action. If useful detail would exceed that, put it in a Slack canvas and reply with the link. An explicit user request for detail overrides this target.",
1215
1233
  "- Start with the answer or result, not internal process narration.",
1216
- "- Use Slack-flavored Markdown: **bold** section labels, `code`, [text](url) links, bullet lists, and fenced code blocks. No hash-prefixed headings and no tables. When the answer primarily lists several URLs, show each URL bare instead of as a labeled link.",
1234
+ "- Use Slack-flavored Markdown: **bold** section labels, `code`, [text](url) links, bullet lists, and fenced code blocks. No hash-prefixed headings and no tables.",
1217
1235
  "- End every turn with a final user-facing markdown response unless the Slack action rules allow a no-reply completion.",
1218
1236
  "</output>"
1219
1237
  ].join("\n");
@@ -2770,12 +2788,8 @@ async function maybePostAutomatedTurnLimitNotice(args) {
2770
2788
  //#region src/chat/task-input.ts
2771
2789
  /** Shared closing lines for the stored outcomes. */
2772
2790
  function replyContractLines(outcomes) {
2773
- if (outcomes?.length === 0) return ["Successful output is not delivered to the destination.", "Complete the work without adding a status message for people."];
2774
- return [
2775
- "When you reply, follow any reply format in the instructions.",
2776
- `If no visible reply is needed, your final assistant message must be exactly ${NO_REPLY_MARKER} and nothing else.`,
2777
- "Otherwise briefly summarize what you acted on and what you did or need next."
2778
- ];
2791
+ if (outcomes?.length === 0) return ["Do the work without writing a status message.", "No successful output will be delivered."];
2792
+ return ["When you reply, follow any reply format in the instructions.", "Briefly report what you did or what is needed next."];
2779
2793
  }
2780
2794
  function oneLine(value) {
2781
2795
  return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
@@ -2812,39 +2826,6 @@ function renderTaskInput(args) {
2812
2826
  return lines.join("\n");
2813
2827
  }
2814
2828
  //#endregion
2815
- //#region src/chat/resource-events/actor.ts
2816
- /**
2817
- * System author ID stamped on resource-event mailbox messages.
2818
- *
2819
- * Keep this stable so conversation history can recognize the same system input
2820
- * for resource-event Turns.
2821
- *
2822
- * TODO(dcramer): Delete this ID after resumes read resource-event Source.kind
2823
- * from the Turn checkpoint instead of Message author data.
2824
- */
2825
- const RESOURCE_EVENT_AUTHOR_ID = "UJRNEVENT";
2826
- /** System Message author for resource-event input. */
2827
- const RESOURCE_EVENT_MESSAGE_AUTHOR = {
2828
- fullName: "Junior event",
2829
- isBot: true,
2830
- userId: RESOURCE_EVENT_AUTHOR_ID,
2831
- userName: "junior-event"
2832
- };
2833
- /** System execution actor for every resource-event turn. */
2834
- const RESOURCE_EVENT_SYSTEM_ACTOR = {
2835
- platform: "system",
2836
- name: "resource-event"
2837
- };
2838
- /**
2839
- * Whether a saved Message started a resource-event Turn.
2840
- *
2841
- * TODO(dcramer): Delete this marker check after deployed Turn cursors all store
2842
- * Source and Actor. `eventType` only supports saved synthetic Slack input.
2843
- */
2844
- function isResourceEventConversationMessage(message) {
2845
- return Boolean(message.meta?.eventType) || message.author?.userId === "UJRNEVENT";
2846
- }
2847
- //#endregion
2848
2829
  //#region src/chat/resource-events/notification.ts
2849
2830
  /**
2850
2831
  * Render the runtime-owned conversation message for a subscribed event.
@@ -8251,7 +8232,8 @@ function requireActiveConversation(context) {
8251
8232
  return {
8252
8233
  platform: "slack",
8253
8234
  teamId: parsed.data.teamId,
8254
- channelId: parsed.data.channelId
8235
+ channelId: parsed.data.channelId,
8236
+ threadTs: parsed.data.threadTs ?? parsed.data.messageTs
8255
8237
  };
8256
8238
  }
8257
8239
  /** Require a concrete Slack actor before creating scheduler ownership state. */
@@ -8682,7 +8664,7 @@ function createSlackScheduleUpdateTaskTool(context) {
8682
8664
  status: nextStatus,
8683
8665
  statusReason: nextStatus === "blocked" ? lookup.statusReason : void 0,
8684
8666
  schedule: compiled?.schedule ?? lookup.schedule,
8685
- outcomes: input.outcomes === void 0 ? lookup.outcomes : await resolveTaskOutcomes(input.outcomes, activeDestination, lookup.createdBy.slackUserId),
8667
+ outcomes: input.outcomes === void 0 ? changingDestination ? moveTaskOutcomes(lookup.outcomes, lookup.destination, nextDestination) : lookup.outcomes : await resolveTaskOutcomes(input.outcomes, nextDestination, lookup.createdBy.slackUserId),
8686
8668
  task: { text: nextInstruction }
8687
8669
  };
8688
8670
  if (instructionChanged) {
@@ -9135,6 +9117,34 @@ function createSlackChannelListMessagesTool(context) {
9135
9117
  });
9136
9118
  }
9137
9119
  //#endregion
9120
+ //#region src/chat/slack/tools/conversation-brief-search.ts
9121
+ /** Create Slack-owned filtering and match details for Brief search. */
9122
+ function createSlackConversationBriefSearchPort(teamId) {
9123
+ return {
9124
+ channelFilterSchema: slackChannelRefParam,
9125
+ async resolveChannel(input) {
9126
+ return (await resolveSlackChannelRef({
9127
+ field: "channel_id",
9128
+ value: input,
9129
+ teamId
9130
+ })).channelId;
9131
+ },
9132
+ async describeMatch(match) {
9133
+ const reference = parseSlackThreadId(match.conversationId);
9134
+ if (!reference || reference.channelId !== match.providerDestinationId) return {};
9135
+ const permalink = await getSlackMessagePermalink({
9136
+ channelId: reference.channelId,
9137
+ messageTs: reference.threadTs
9138
+ });
9139
+ return {
9140
+ channel_id: reference.channelId,
9141
+ ...match.channelName ? { channel_name: match.channelName } : void 0,
9142
+ ...permalink ? { permalink } : void 0
9143
+ };
9144
+ }
9145
+ };
9146
+ }
9147
+ //#endregion
9138
9148
  //#region src/chat/conversations/tool-source.ts
9139
9149
  /** Deferred tool catalog source for retained Junior conversations. */
9140
9150
  const CONVERSATIONS_TOOL_SOURCE = {
@@ -9143,8 +9153,8 @@ const CONVERSATIONS_TOOL_SOURCE = {
9143
9153
  };
9144
9154
  //#endregion
9145
9155
  //#region src/chat/slack/tools/conversation-message-search.ts
9146
- const DEFAULT_LIMIT$2 = 20;
9147
- const MAX_LIMIT$1 = 50;
9156
+ const DEFAULT_LIMIT$3 = 20;
9157
+ const MAX_LIMIT$2 = 50;
9148
9158
  const conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
9149
9159
  after: z.string().datetime().optional(),
9150
9160
  annotation: z.string().min(1).optional(),
@@ -9164,17 +9174,17 @@ const conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
9164
9174
  thread_ts: z.string().min(1)
9165
9175
  }).strict())
9166
9176
  });
9167
- function parseTimestamp(field, value) {
9177
+ function parseTimestamp$1(field, value) {
9168
9178
  if (value == null || value.trim() === "") return;
9169
9179
  const parsed = Date.parse(value);
9170
9180
  if (!Number.isFinite(parsed)) throw new ToolInputError(`${field} must be a valid ISO-8601 timestamp`);
9171
9181
  return parsed;
9172
9182
  }
9173
- async function resolveSearchFilters(input) {
9183
+ async function resolveSearchFilters$1(input) {
9174
9184
  const query = input.query?.trim() || void 0;
9175
9185
  const annotation = input.annotation?.trim() || void 0;
9176
- const afterMs = parseTimestamp("after", input.after);
9177
- const beforeMs = parseTimestamp("before", input.before);
9186
+ const afterMs = parseTimestamp$1("after", input.after);
9187
+ const beforeMs = parseTimestamp$1("before", input.before);
9178
9188
  let channelId;
9179
9189
  if (input.channel_id != null && input.channel_id.trim() !== "") channelId = (await resolveSlackChannelRef({
9180
9190
  field: "channel_id",
@@ -9209,20 +9219,20 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
9209
9219
  before: z.string().datetime().nullable().describe("Include conversations active before this timestamp.").optional(),
9210
9220
  channel_id: slackChannelRefParam.nullable().optional(),
9211
9221
  query: z.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
9212
- limit: z.number().int().min(1).max(MAX_LIMIT$1).describe(`Maximum conversations. Default ${DEFAULT_LIMIT$2}; max ${MAX_LIMIT$1}.`).nullable().optional()
9222
+ limit: z.number().int().min(1).max(MAX_LIMIT$2).describe(`Maximum conversations. Default ${DEFAULT_LIMIT$3}; max ${MAX_LIMIT$2}.`).nullable().optional()
9213
9223
  }).strict(),
9214
9224
  outputSchema: conversationMessageSearchOutputSchema,
9215
9225
  execute: async (input) => {
9216
9226
  const teamId = parseSlackTeamId(scope.providerTenantId);
9217
9227
  if (!teamId) throw new ToolInputError("Cannot search retained messages without a valid Slack workspace id.");
9218
- const filters = await resolveSearchFilters({
9228
+ const filters = await resolveSearchFilters$1({
9219
9229
  ...input,
9220
9230
  teamId
9221
9231
  });
9222
9232
  const matches = await getConversationMessageSearchStore().search({
9223
9233
  currentConversationId,
9224
9234
  filters,
9225
- limit: input.limit ?? DEFAULT_LIMIT$2,
9235
+ limit: input.limit ?? DEFAULT_LIMIT$3,
9226
9236
  scope
9227
9237
  });
9228
9238
  const matchesOutput = await Promise.all(matches.map(async (match) => {
@@ -9258,7 +9268,7 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
9258
9268
  }
9259
9269
  //#endregion
9260
9270
  //#region src/chat/slack/tools/public-search.ts
9261
- const DEFAULT_LIMIT$1 = 10;
9271
+ const DEFAULT_LIMIT$2 = 10;
9262
9272
  const DEFAULT_CONTENT_TYPES = ["messages"];
9263
9273
  const CONTENT_TYPES = [
9264
9274
  "messages",
@@ -9521,7 +9531,7 @@ function createSlackPublicSearchTool(actionToken) {
9521
9531
  channel_types: ["public_channel"],
9522
9532
  content_types: normalizedContentTypes,
9523
9533
  include_bots: true,
9524
- limit: limit ?? DEFAULT_LIMIT$1,
9534
+ limit: limit ?? DEFAULT_LIMIT$2,
9525
9535
  ...normalizedAfter !== void 0 ? { after: normalizedAfter } : void 0,
9526
9536
  ...normalizedBefore !== void 0 ? { before: normalizedBefore } : void 0,
9527
9537
  ...cursor ? { cursor } : void 0,
@@ -11697,8 +11707,8 @@ function createLoadAttachmentTool(args) {
11697
11707
  }
11698
11708
  //#endregion
11699
11709
  //#region src/chat/tools/search-conversation-events.ts
11700
- const DEFAULT_LIMIT = 25;
11701
- const MAX_LIMIT = 100;
11710
+ const DEFAULT_LIMIT$1 = 25;
11711
+ const MAX_LIMIT$1 = 100;
11702
11712
  const MAX_EVENT_DATA_BYTES = 4e3;
11703
11713
  const MAX_EVENTS_JSON_BYTES = 2e4;
11704
11714
  const MAX_IDENTITY_CHARS = 256;
@@ -11734,7 +11744,7 @@ function createSearchConversationEventsTool(context) {
11734
11744
  conversation_id: z.string().trim().min(1).nullable().describe("Conversation ID to search. Omit or null for the current conversation.").optional(),
11735
11745
  after_seq: z.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
11736
11746
  before_seq: z.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
11737
- limit: z.number().int().min(1).max(MAX_LIMIT).nullable().describe(`Maximum events. Default ${DEFAULT_LIMIT}; max ${MAX_LIMIT}.`).optional(),
11747
+ limit: z.number().int().min(1).max(MAX_LIMIT$1).nullable().describe(`Maximum events. Default ${DEFAULT_LIMIT$1}; max ${MAX_LIMIT$1}.`).optional(),
11738
11748
  types: z.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
11739
11749
  }).strict(),
11740
11750
  outputSchema: searchConversationEventsOutputSchema,
@@ -11743,7 +11753,7 @@ function createSearchConversationEventsTool(context) {
11743
11753
  const conversationId = input.conversation_id?.trim() || currentConversationId;
11744
11754
  const afterSeq = input.after_seq ?? void 0;
11745
11755
  const beforeSeq = input.before_seq ?? void 0;
11746
- const limit = input.limit ?? DEFAULT_LIMIT;
11756
+ const limit = input.limit ?? DEFAULT_LIMIT$1;
11747
11757
  const types = input.types ?? void 0;
11748
11758
  if (afterSeq !== void 0 && beforeSeq !== void 0 && afterSeq >= beforeSeq) throw new ToolInputError("after_seq must be less than before_seq when both are provided");
11749
11759
  const conversationStore = getConversationStore();
@@ -11907,6 +11917,183 @@ function stripReplacementHistoryField(value) {
11907
11917
  };
11908
11918
  }
11909
11919
  //#endregion
11920
+ //#region src/chat/briefs/search.ts
11921
+ /** Search the latest Brief of each public root Conversation in one scope. */
11922
+ async function searchConversationBriefs(db, args) {
11923
+ const query = args.filters.query?.trim() || void 0;
11924
+ const tsquery = query ? sql`websearch_to_tsquery('english', ${query})` : void 0;
11925
+ const briefs = juniorConversationBriefs;
11926
+ const newer = alias(juniorConversationBriefs, "newer_briefs");
11927
+ const searchVector = sql`to_tsvector('english', ${briefs.searchText})`;
11928
+ const rank = tsquery ? sql`ts_rank_cd(${searchVector}, ${tsquery})` : sql`1`;
11929
+ const excerpt = tsquery ? sql`ts_headline('english', ${briefs.searchText}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')` : sql`${briefs.content}->>'summary'`;
11930
+ const outcomeStatus = sql`${briefs.content}->'outcome'->>'status'`;
11931
+ const conditions = [
11932
+ notExists(db.select({ one: sql`1` }).from(newer).where(and(eq(newer.conversationId, briefs.conversationId), gt(newer.version, briefs.version)))),
11933
+ isNull(juniorConversations.parentConversationId),
11934
+ ne(juniorConversations.conversationId, args.currentConversationId),
11935
+ eq(juniorDestinations.visibility, "public")
11936
+ ];
11937
+ if (args.scope.kind === "public_provider_tenant") conditions.push(eq(juniorConversations.source, args.scope.provider), eq(juniorDestinations.provider, args.scope.provider), eq(juniorDestinations.providerTenantId, args.scope.providerTenantId));
11938
+ if (tsquery) conditions.push(sql`${searchVector} @@ ${tsquery}`);
11939
+ if (args.filters.channelId) conditions.push(eq(juniorDestinations.providerDestinationId, args.filters.channelId));
11940
+ if (args.filters.status) conditions.push(sql`${outcomeStatus} = ${args.filters.status}`);
11941
+ if (args.filters.afterMs !== void 0) conditions.push(gte(briefs.createdAt, new Date(args.filters.afterMs)));
11942
+ if (args.filters.beforeMs !== void 0) conditions.push(lt(briefs.createdAt, new Date(args.filters.beforeMs)));
11943
+ if (args.filters.annotation) {
11944
+ const annotation = args.filters.annotation.toLowerCase();
11945
+ const nestedAnnotationPrefix = `${annotation}#`;
11946
+ conditions.push(sql`exists (
11947
+ select 1
11948
+ from ${juniorConversationAnnotations}
11949
+ where ${and(eq(juniorConversationAnnotations.conversationId, juniorConversations.conversationId), sql`(
11950
+ lower(${juniorConversationAnnotations.key}) = ${annotation}
11951
+ or starts_with(
11952
+ lower(${juniorConversationAnnotations.key}),
11953
+ ${nestedAnnotationPrefix}
11954
+ )
11955
+ )`)}
11956
+ )`);
11957
+ }
11958
+ return (await db.select({
11959
+ channelName: juniorDestinations.displayName,
11960
+ content: briefs.content,
11961
+ conversationId: juniorConversations.conversationId,
11962
+ excerpt: excerpt.as("excerpt"),
11963
+ providerDestinationId: juniorDestinations.providerDestinationId,
11964
+ rank: rank.as("rank"),
11965
+ title: juniorConversations.title,
11966
+ updatedAt: briefs.createdAt,
11967
+ version: briefs.version
11968
+ }).from(briefs).innerJoin(juniorConversations, eq(juniorConversations.conversationId, briefs.conversationId)).innerJoin(juniorDestinations, eq(juniorDestinations.id, juniorConversations.destinationId)).where(and(...conditions)).orderBy(desc(rank), desc(briefs.createdAt)).limit(args.limit)).map((row) => {
11969
+ const content = conversationBriefSchema.parse(row.content);
11970
+ return {
11971
+ conversationId: row.conversationId,
11972
+ excerpt: row.excerpt,
11973
+ links: content.links.slice(0, 5),
11974
+ outcomeStatus: content.outcome.status,
11975
+ providerDestinationId: row.providerDestinationId,
11976
+ summary: content.summary,
11977
+ updatedAtMs: row.updatedAt.getTime(),
11978
+ version: row.version,
11979
+ ...row.channelName ? { channelName: row.channelName } : void 0,
11980
+ ...row.title ? { title: row.title } : void 0
11981
+ };
11982
+ });
11983
+ }
11984
+ //#endregion
11985
+ //#region src/chat/tools/search-conversation-briefs.ts
11986
+ const DEFAULT_LIMIT = 10;
11987
+ const MAX_LIMIT = 25;
11988
+ const conversationBriefSearchOutputSchema = juniorToolOutputSchema.extend({
11989
+ after: z.string().datetime().optional(),
11990
+ annotation: z.string().min(1).optional(),
11991
+ before: z.string().datetime().optional(),
11992
+ channel_id: z.string().min(1).optional(),
11993
+ count: z.number().int().nonnegative(),
11994
+ matches: z.array(z.object({
11995
+ channel_id: z.string().min(1).optional(),
11996
+ channel_name: z.string().min(1).optional(),
11997
+ conversation_id: z.string().min(1),
11998
+ dashboard_url: z.string().url().optional(),
11999
+ excerpt: z.string(),
12000
+ links: z.array(briefLinkSchema).max(5),
12001
+ permalink: z.string().url().optional(),
12002
+ status: briefOutcomeStatusSchema,
12003
+ summary: z.string().min(1),
12004
+ title: z.string().min(1).optional(),
12005
+ updated_at: z.string().datetime(),
12006
+ version: z.number().int().positive()
12007
+ }).strict()),
12008
+ query: z.string().optional(),
12009
+ status: briefOutcomeStatusSchema.optional()
12010
+ });
12011
+ function parseTimestamp(field, value) {
12012
+ if (value == null || value.trim() === "") return void 0;
12013
+ const parsed = Date.parse(value);
12014
+ if (!Number.isFinite(parsed)) throw new ToolInputError(`${field} must be a valid ISO-8601 timestamp`);
12015
+ return parsed;
12016
+ }
12017
+ async function resolveSearchFilters(input, provider) {
12018
+ const query = input.query?.trim() || void 0;
12019
+ const annotation = input.annotation?.trim() || void 0;
12020
+ const afterMs = parseTimestamp("after", input.after);
12021
+ const beforeMs = parseTimestamp("before", input.before);
12022
+ let channelId;
12023
+ if (typeof input.channel_id === "string" && input.channel_id.trim() !== "") {
12024
+ if (!provider) throw new ToolInputError("channel_id is not available in this conversation.");
12025
+ channelId = await provider.resolveChannel(input.channel_id);
12026
+ }
12027
+ if (afterMs !== void 0 && beforeMs !== void 0 && afterMs >= beforeMs) throw new ToolInputError("`after` must be earlier than `before`");
12028
+ return {
12029
+ ...afterMs !== void 0 ? { afterMs } : void 0,
12030
+ ...annotation ? { annotation } : void 0,
12031
+ ...beforeMs !== void 0 ? { beforeMs } : void 0,
12032
+ ...channelId ? { channelId } : void 0,
12033
+ ...query ? { query } : void 0,
12034
+ ...input.status ? { status: input.status } : void 0
12035
+ };
12036
+ }
12037
+ /** Create a deferred tool that searches the latest public Conversation Briefs. */
12038
+ function createSearchConversationBriefsTool(scope, currentConversationId, provider) {
12039
+ return zodTool({
12040
+ description: "Search Briefs from past public conversations. Briefs preserve intent, outcomes, decisions, facts, and links after transcripts expire. Use this before searchConversationMessages for questions such as what was decided or which pull request handled the work.",
12041
+ exposure: "deferred",
12042
+ source: CONVERSATIONS_TOOL_SOURCE,
12043
+ annotations: {
12044
+ destructiveHint: false,
12045
+ idempotentHint: true,
12046
+ openWorldHint: false,
12047
+ readOnlyHint: true
12048
+ },
12049
+ inputSchema: z.object({
12050
+ after: z.string().datetime().nullable().describe("Include Briefs updated at or after this timestamp.").optional(),
12051
+ annotation: z.string().trim().min(1).max(256).nullable().describe("Linked resource key. Matches that key, or nested children that continue with #.").optional(),
12052
+ before: z.string().datetime().nullable().describe("Include Briefs updated before this timestamp.").optional(),
12053
+ ...provider ? { channel_id: provider.channelFilterSchema.nullable().optional() } : void 0,
12054
+ limit: z.number().int().min(1).max(MAX_LIMIT).nullable().describe(`Maximum conversations. Default ${DEFAULT_LIMIT}; max ${MAX_LIMIT}.`).optional(),
12055
+ query: z.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in current Briefs.").optional(),
12056
+ status: briefOutcomeStatusSchema.nullable().describe("Current Brief outcome status.").optional()
12057
+ }).strict(),
12058
+ outputSchema: conversationBriefSearchOutputSchema,
12059
+ execute: async (input) => {
12060
+ const filters = await resolveSearchFilters(input, provider);
12061
+ const matches = await searchConversationBriefs(getDb(), {
12062
+ currentConversationId,
12063
+ filters,
12064
+ limit: input.limit ?? DEFAULT_LIMIT,
12065
+ scope
12066
+ });
12067
+ const outputMatches = await Promise.all(matches.map(async (match) => {
12068
+ const providerFields = provider ? await provider.describeMatch(match) : void 0;
12069
+ const dashboardUrl = getDashboardConversationLink(match.conversationId);
12070
+ return {
12071
+ conversation_id: match.conversationId,
12072
+ status: match.outcomeStatus,
12073
+ updated_at: new Date(match.updatedAtMs).toISOString(),
12074
+ version: match.version,
12075
+ summary: match.summary,
12076
+ excerpt: match.excerpt,
12077
+ links: match.links,
12078
+ ...match.title ? { title: match.title } : void 0,
12079
+ ...dashboardUrl ? { dashboard_url: dashboardUrl } : void 0,
12080
+ ...providerFields
12081
+ };
12082
+ }));
12083
+ return {
12084
+ ...filters.afterMs !== void 0 ? { after: new Date(filters.afterMs).toISOString() } : void 0,
12085
+ ...filters.annotation ? { annotation: filters.annotation } : void 0,
12086
+ ...filters.beforeMs !== void 0 ? { before: new Date(filters.beforeMs).toISOString() } : void 0,
12087
+ ...filters.channelId ? { channel_id: filters.channelId } : void 0,
12088
+ ...filters.query ? { query: filters.query } : void 0,
12089
+ ...filters.status ? { status: filters.status } : void 0,
12090
+ count: outputMatches.length,
12091
+ matches: outputMatches
12092
+ };
12093
+ }
12094
+ });
12095
+ }
12096
+ //#endregion
11910
12097
  //#region src/chat/tools/handoff/tool.ts
11911
12098
  const HANDOFF_TOOL_NAME = "handoff";
11912
12099
  function formatHandoffProfiles(handoff) {
@@ -12875,6 +13062,11 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
12875
13062
  ...createWorkspaceTools(context)
12876
13063
  };
12877
13064
  tools.searchConversationEvents = createSearchConversationEventsTool(context);
13065
+ if (context.conversationPrivacy === "public") tools.searchConversationBriefs = createSearchConversationBriefsTool(slackContext ? {
13066
+ kind: "public_provider_tenant",
13067
+ provider: "slack",
13068
+ providerTenantId: slackContext.teamId
13069
+ } : { kind: "public" }, context.conversationId, slackContext ? createSlackConversationBriefSearchPort(slackContext.teamId) : void 0);
12878
13070
  if (context.supportsImageInput) tools.viewImage = createViewImageTool(context.workspace, context.supportsImageInput, hooks.toolOverrides?.viewImage);
12879
13071
  if (hooks.writeGeneratedArtifacts) tools.imageGenerate = createImageGenerateTool({ writeGeneratedArtifacts: hooks.writeGeneratedArtifacts }, {
12880
13072
  modelId: botConfig.imageGenerationModelId,
@@ -17506,4 +17698,4 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
17506
17698
  }
17507
17699
  }
17508
17700
  //#endregion
17509
- export { buildSteeringPiMessage as $, createAgentInvocationSchema as A, renderTaskInput as B, renderBlockText as C, getNextRunAtMs as D, scheduledTaskRunAttributes as E, ingestResourceEvent as F, shouldPropagateSandboxEgressTrace as G, recordFinishedTurnForAutomatedLimit as H, isResourceEventMailboxMetadata as I, consumeSandboxEgressAuthRequiredSignal as J, SANDBOX_EGRESS_PROXY_PATH as K, RESOURCE_EVENT_MESSAGE_AUTHOR as L, AgentInvocationLimitError as M, getMcpProviderErrorAttributes as N, agentBindingSchema as O, processWorkspaceSnapshotJob as P, createUserTokenStore as Q, RESOURCE_EVENT_SYSTEM_ACTOR as R, renderAttachmentText as S, logScheduledTaskRunSkipped as T, resolveSandboxEgressProviderForHost as U, maybePostAutomatedTurnLimitNotice as V, normalizeSandboxEgressTracePropagationDomains as W, parseSandboxEgressCredentialToken as X, consumeSandboxEgressPermissionDeniedSignal as Y, sandboxEgressSignalsResponseSchema as Z, readPublicArtifact as _, deleteMcpAuthSession as a, readAttachmentVisionSummary as b, deleteMcpStoredOAuthCredentials as c, putMcpStoredOAuthCredentials as d, isVisionImageMediaType as et, PluginCredentialFailureError as f, publicArtifactHeaders as g, resolvePluginOAuthAccount as h, finalizeMcpAuthorization as i, setConfigDefaults as it, AgentInvocationBusyError as j, agentInvocationSchema as k, getMcpAuthSession as l, latestReportedProgress as m, createContextCompactor as n, shouldEmitDevAgentTrace as nt, deleteMcpAuthSessionsForUserProvider as o, authorizationId as p, clearSandboxEgressSignals as q, executeCredentialedEgressRequest as r, getConfigDefaults as rt, deleteMcpServerSessionId as s, executeAgentRun as t, AuthorizationFlowDisabledError as tt, getMcpStoredOAuthCredentials as u, unpublishedArtifactHeaders as v, listThreadReplies as w, recordSlackAttachment as x, lookupSlackUserProfile as y, isResourceEventConversationMessage as z };
17701
+ export { shouldEmitDevAgentTrace as $, createAgentInvocationSchema as A, resolveSandboxEgressProviderForHost as B, renderBlockText as C, getNextRunAtMs as D, scheduledTaskRunAttributes as E, ingestResourceEvent as F, consumeSandboxEgressAuthRequiredSignal as G, shouldPropagateSandboxEgressTrace as H, isResourceEventMailboxMetadata as I, sandboxEgressSignalsResponseSchema as J, consumeSandboxEgressPermissionDeniedSignal as K, renderTaskInput as L, AgentInvocationLimitError as M, getMcpProviderErrorAttributes as N, agentBindingSchema as O, processWorkspaceSnapshotJob as P, AuthorizationFlowDisabledError as Q, maybePostAutomatedTurnLimitNotice as R, renderAttachmentText as S, logScheduledTaskRunSkipped as T, SANDBOX_EGRESS_PROXY_PATH as U, normalizeSandboxEgressTracePropagationDomains as V, clearSandboxEgressSignals as W, buildSteeringPiMessage as X, createUserTokenStore as Y, isVisionImageMediaType as Z, readPublicArtifact as _, deleteMcpAuthSession as a, readAttachmentVisionSummary as b, deleteMcpStoredOAuthCredentials as c, putMcpStoredOAuthCredentials as d, getConfigDefaults as et, PluginCredentialFailureError as f, publicArtifactHeaders as g, resolvePluginOAuthAccount as h, finalizeMcpAuthorization as i, AgentInvocationBusyError as j, agentInvocationSchema as k, getMcpAuthSession as l, latestReportedProgress as m, createContextCompactor as n, deleteMcpAuthSessionsForUserProvider as o, authorizationId as p, parseSandboxEgressCredentialToken as q, executeCredentialedEgressRequest as r, deleteMcpServerSessionId as s, executeAgentRun as t, setConfigDefaults as tt, getMcpStoredOAuthCredentials as u, unpublishedArtifactHeaders as v, listThreadReplies as w, recordSlackAttachment as x, lookupSlackUserProfile as y, recordFinishedTurnForAutomatedLimit as z };