@sentry/junior 0.235.0 → 0.236.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-hooks-DS7k0ZWY.js → agent-hooks-Da_H0jHv.js} +8 -8
- package/dist/{agent-runner-BlDI1zV2.js → agent-runner-uP7QRc4c.js} +353 -117
- package/dist/api/schema.d.ts +223 -2
- package/dist/api/schema.js +5 -4
- package/dist/api.d.ts +8 -2
- package/dist/api.js +404 -47
- package/dist/{app-pGsR__aT.d.ts → app-MEd7wbF0.d.ts} +82 -48
- package/dist/app.d.ts +3 -3
- package/dist/app.js +162 -119
- package/dist/{types-Du-HbEun.js → automation-B9Kc1gcf.js} +304 -33
- package/dist/{briefs-C3jhszOz.js → briefs-DrjBPQFy.js} +4 -4
- package/dist/{catalog-runtime-B9u_3-GW.js → catalog-runtime-C7339Cfm.js} +1 -1
- package/dist/{checkpoint-DLcJ5mKL.js → checkpoint-DaD7_Gsb.js} +16 -9
- package/dist/cli/chat.d.ts +1 -1
- package/dist/cli/chat.js +14 -14
- package/dist/cli/check.js +4 -4
- package/dist/cli/main.js +1 -1
- package/dist/cli/plugins.d.ts +1 -1
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +3 -3
- package/dist/cli/upgrade.d.ts +1 -1
- package/dist/cli/upgrade.js +5 -5
- package/dist/{client-BSnNHO0R.js → client-Ch9Hg9NU.js} +2 -2
- package/dist/{config-Bmw4xTPK.js → config-JR9wke1W.js} +57 -17
- package/dist/{conversation-C_aYrISI.js → conversation-9Fxa1Zbq.js} +13 -1
- package/dist/{conversation-privacy-BV2dtba2.js → conversation-privacy-au02dyZK.js} +1 -1
- package/dist/{credential-sync-CukzQJ1x.js → credential-sync-BWTA3LnL.js} +14 -14
- package/dist/{executor-B9ksWZCv.js → executor-BW9XWgUQ.js} +38 -6
- package/dist/{images-CEXcQ0Id.js → images-BdG7zcNf.js} +3 -3
- package/dist/instrumentation.js +2 -2
- package/dist/{job-queue-CY1L2YRn.js → job-queue-BqXd0ZPV.js} +1 -1
- package/dist/{logging-F--48Q7Q.js → logging-B4sKwmCG.js} +1 -1
- package/dist/nitro.d.ts +2 -2
- package/dist/nitro.js +5 -5
- package/dist/{oauth-authorization-LasSG3Qc.js → oauth-authorization-BjRN99dc.js} +1 -1
- package/dist/{oauth-callback-server-D07ZzVMs.js → oauth-callback-server-B_1p98Mb.js} +2 -2
- package/dist/{pending-auth-DrG9Mkje.js → pending-auth-WqF4Gh8Z.js} +1 -1
- package/dist/{plugins-BT2l4We3.d.ts → plugins-CjfUP5gJ.d.ts} +1 -0
- package/dist/{profile-DZ2DUdd1.js → profile-BamYnmhO.js} +4 -4
- package/dist/{prompt-BM_5mAU3.js → prompt-Ctwy6hSI.js} +1 -1
- package/dist/queue-B5SnqRln.d.ts +25 -0
- package/dist/{registry-_JLY0x7b.js → registry-CXNv9fDX.js} +38 -2
- package/dist/{resolve-Cuoj3MML.js → resolve-C9ETkt4T.js} +2 -2
- package/dist/{runner-BfelmbMv.js → runner-DnBGVRnW.js} +9 -9
- package/dist/{sandbox-egress-signals-D5QUIO7Z.js → sandbox-egress-signals-DwJ7Boi_.js} +1 -1
- package/dist/{schema-CrdDxGbx.js → schema-CJiqDc5r.js} +3 -2
- package/dist/{skills-DAegjk5Y.js → skills-Dd8O9Aav.js} +3 -3
- package/dist/{spawn-DCfV7zGK.js → spawn-DFdRspSD.js} +2 -2
- package/dist/{task-queue-GcuFtzor.js → task-queue-DGQEOk1A.js} +16 -10
- package/dist/{task-runner-B0-P_3aq.js → task-runner-C5XCIDSF.js} +9 -9
- package/dist/{thread-state-TezcEhuH.js → thread-state-D3E29wZk.js} +5 -5
- package/dist/{turn-failure-response-Drhj_-t4.js → turn-failure-response-TDoj0aZz.js} +8 -8
- package/dist/{turn-lifecycle-BpIW3zOx.js → turn-lifecycle-DOnU45p7.js} +1 -1
- package/dist/{turn-session-routing-Dg8GDgyc.js → turn-session-routing-DbpZZoin.js} +1 -1
- package/dist/{validation-DAkYeKDT.js → validation-B9lMbisx.js} +1 -1
- package/dist/{version-9CB4Z-J4.js → version-CWkIGcLU.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{web-authorization-Cu33voNg.js → web-authorization-PPaoj2ns.js} +6 -6
- package/dist/{web-input-B3k0J7WB.js → web-input-CfNxXtHm.js} +86 -34
- package/dist/web-message-id-xPI_EFSC.js +239 -0
- package/dist/{work-PmkvcY9l.js → work-DNaoFrEe.js} +7 -7
- package/dist/{worker-COcaq2J6.js → worker-xeJLxYwm.js} +5 -5
- package/migrations/0045_conversation_forks.sql +3 -0
- package/migrations/0046_automation_versions.sql +71 -0
- package/migrations/meta/0045_snapshot.json +3503 -0
- package/migrations/meta/0046_snapshot.json +3707 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +4 -4
- package/dist/web-message-id-CVVCTWUb.js +0 -464
- package/dist/{package-discovery-7a9YqLhE.js → package-discovery-BVvSnQBB.js} +1 -1
- package/dist/{plugin-module-BKGOXca2.js → plugin-module-CVvEUSMH.js} +1 -1
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { b as getGatewayApiKey, c as hasCompactedConversationContext, d as unwrapCurrentInstruction, f as escapeXml, g as getProviderErrorAttributes, h as findProviderError, i as completeText, l as isCompactionSummaryText, m as createProviderError, n as GEN_AI_SERVER_ADDRESS, o as resolveGatewayModel, p as ProviderError, r as completeObject, s as COMPACTION_SUMMARY_PREFIX, t as GEN_AI_PROVIDER_NAME, u as renderCurrentInstruction, v as isProviderRetryError, x as resolveGatewayCredential, y as MISSING_GATEWAY_CREDENTIALS_ERROR } from "./client-
|
|
3
|
-
import { C as withLogContext, F as normalizeIdentityEmail, I as isRecord$3, L as toOptionalNumber, R as toOptionalString, a as extractGenAiUsageSummary, b as setTags, c as getLogContextAttributesForSpan, d as logException, f as logInfo, g as serializeGenAiAttribute, i as extractGenAiUsageAttributes, l as getTracePropagationHeaders, m as normalizeGenAiFinishReason, p as logWarn, s as getLogContextAttributes, u as logError, v as setSpanAttributes, w as withSpan, x as summarizeMessageText, y as setSpanStatus } from "./logging-
|
|
2
|
+
import { b as getGatewayApiKey, c as hasCompactedConversationContext, d as unwrapCurrentInstruction, f as escapeXml, g as getProviderErrorAttributes, h as findProviderError, i as completeText, l as isCompactionSummaryText, m as createProviderError, n as GEN_AI_SERVER_ADDRESS, o as resolveGatewayModel, p as ProviderError, r as completeObject, s as COMPACTION_SUMMARY_PREFIX, t as GEN_AI_PROVIDER_NAME, u as renderCurrentInstruction, v as isProviderRetryError, x as resolveGatewayCredential, y as MISSING_GATEWAY_CREDENTIALS_ERROR } from "./client-Ch9Hg9NU.js";
|
|
3
|
+
import { C as withLogContext, F as normalizeIdentityEmail, I as isRecord$3, L as toOptionalNumber, R as toOptionalString, a as extractGenAiUsageSummary, b as setTags, c as getLogContextAttributesForSpan, d as logException, f as logInfo, g as serializeGenAiAttribute, i as extractGenAiUsageAttributes, l as getTracePropagationHeaders, m as normalizeGenAiFinishReason, p as logWarn, s as getLogContextAttributes, u as logError, v as setSpanAttributes, w as withSpan, x as summarizeMessageText, y as setSpanStatus } from "./logging-B4sKwmCG.js";
|
|
4
4
|
import { m as startInactiveSpan, n as captureMessage, v as withActiveSpan } from "./sentry-CgWZM_kV.js";
|
|
5
|
-
import { a as toCanonicalInputMessage, c as toGenAiPayloadMetadata, i as runWithConversationPrivacy, l as toGenAiPayloadTraceAttributes, o as toCanonicalOutputMessage, r as resolveConversationPrivacy, s as toGenAiMessagesTraceAttributes, t as canExposeConversationPayload } from "./conversation-privacy-
|
|
6
|
-
import {
|
|
5
|
+
import { a as toCanonicalInputMessage, c as toGenAiPayloadMetadata, i as runWithConversationPrivacy, l as toGenAiPayloadTraceAttributes, o as toCanonicalOutputMessage, r as resolveConversationPrivacy, s as toGenAiMessagesTraceAttributes, t as canExposeConversationPayload } from "./conversation-privacy-au02dyZK.js";
|
|
6
|
+
import { i as getChatConfig, n as botConfig, v as normalizeSlackEmojiName } from "./config-JR9wke1W.js";
|
|
7
7
|
import { a as formatModelProfiles, c as profileConfig, i as formatModelProfile, l as TURN_REASONING_LEVELS, n as ModelProfileNotConfiguredError, o as modelIdForProfile, s as modelProfileSchema } from "./model-profile-BwU8mqwD.js";
|
|
8
8
|
import { b as parseSlackMessageTs, d as parseStoredSlackActor, 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-0Et9iVSB.js";
|
|
9
|
-
import { $ as readActorIdentity, $t as getConversationMessageSearchStore, A as getWorkspaceSnapshotBuilder, B as SlackActionError, C as WorkspaceValidationError, D as setWorkspaceSnapshotBuild, E as setWorkspaceSnapshot, G as isConversationScopedChannel, H as getFilePermalink, K as isDmChannel$1, M as workspaceRepoCheckoutPath, N as resolveChannelCapabilities, O as SANDBOX_RUNTIME, Qt as getConversationEventStore, S as updateWorkspace, T as loadSnapshotsForProfile, Ut as saveObjectAnnotations, V as downloadPrivateSlackFile, W as getSlackClient, Wt as createPluginAnnotations, Y as withSlackRetries, _ as deleteWorkspace, _t as getDashboardConversationLink, at as RESOURCE_WATCH_TOOL_SOURCE, b as listWorkspaces, c as getPluginTools, ct as cancelWatch, dt as createWatch, en as getConversationStore, ft as deliverWatch, g as createWorkspace, gt as JUNIOR_THREAD_STATE_TTL_MS, it as RESOURCE_SUBSCRIPTION_MAX_TTL_MS, j as tryWorkspaceRepoCheckoutPath, k as deleteWorkspaceSnapshotBuilders, l as getPluginUserPromptContributions, ln as addAgentTurnUsage, mt as listWatches, n as applyPluginFormatMarkdown, nn as getSqlExecutor, nt as getSlackToolContext, ot as STOP_WATCHING_TOOL_NAME, pn as hasAgentTurnUsage, pt as findMatchingWatches, q as normalizeSlackConversationId, r as createPluginHookRunner, rt as RESOURCE_SUBSCRIPTION_DEFAULT_TTL_MS, s as getPluginSystemPromptContributions, st as cancelSubscriptions, tn as getDb, u as getPlugins, ut as createTimerWatch, v as getWorkspace, w as invalidateReadySnapshot, wt as createPluginLogger, xn as sameDestination$1, y as getWorkspaceByName, yn as parseDestination, yt as getDashboardTaskLink, zt as matchSlackAttachments } from "./agent-hooks-
|
|
9
|
+
import { $ as readActorIdentity, $t as getConversationMessageSearchStore, A as getWorkspaceSnapshotBuilder, B as SlackActionError, C as WorkspaceValidationError, D as setWorkspaceSnapshotBuild, E as setWorkspaceSnapshot, G as isConversationScopedChannel, H as getFilePermalink, K as isDmChannel$1, M as workspaceRepoCheckoutPath, N as resolveChannelCapabilities, O as SANDBOX_RUNTIME, Qt as getConversationEventStore, S as updateWorkspace, T as loadSnapshotsForProfile, Ut as saveObjectAnnotations, V as downloadPrivateSlackFile, W as getSlackClient, Wt as createPluginAnnotations, Y as withSlackRetries, _ as deleteWorkspace, _t as getDashboardConversationLink, at as RESOURCE_WATCH_TOOL_SOURCE, b as listWorkspaces, c as getPluginTools, ct as cancelWatch, dt as createWatch, en as getConversationStore, ft as deliverWatch, g as createWorkspace, gt as JUNIOR_THREAD_STATE_TTL_MS, it as RESOURCE_SUBSCRIPTION_MAX_TTL_MS, j as tryWorkspaceRepoCheckoutPath, k as deleteWorkspaceSnapshotBuilders, l as getPluginUserPromptContributions, ln as addAgentTurnUsage, mt as listWatches, n as applyPluginFormatMarkdown, nn as getSqlExecutor, nt as getSlackToolContext, ot as STOP_WATCHING_TOOL_NAME, pn as hasAgentTurnUsage, pt as findMatchingWatches, q as normalizeSlackConversationId, r as createPluginHookRunner, rt as RESOURCE_SUBSCRIPTION_DEFAULT_TTL_MS, s as getPluginSystemPromptContributions, st as cancelSubscriptions, tn as getDb, u as getPlugins, ut as createTimerWatch, v as getWorkspace, w as invalidateReadySnapshot, wt as createPluginLogger, xn as sameDestination$1, y as getWorkspaceByName, yn as parseDestination, yt as getDashboardTaskLink, zt as matchSlackAttachments } from "./agent-hooks-Da_H0jHv.js";
|
|
10
10
|
import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
|
|
11
|
-
import {
|
|
12
|
-
import { F as
|
|
13
|
-
import { a as listReferenceFiles, c as soulPathCandidates, l as worldPathCandidates } from "./package-discovery-
|
|
14
|
-
import { a as resolveAuthTokenPlaceholder, c as fetchWithBoundedOAuthErrorBodies, d as CredentialUnavailableError, i as resolvePluginHeaderEnvRefs, l as getOAuthProviderErrorAttributes, o as resolvePluginCommandEnv, s as OAuthProviderError } from "./registry-
|
|
15
|
-
import { n as pluginCatalogRuntime } from "./catalog-runtime-
|
|
16
|
-
import { a as parseSkillInvocation, n as findSkillByName, r as loadSkillsByName, t as discoverSkills } from "./skills-
|
|
17
|
-
import {
|
|
18
|
-
import { A as SANDBOX_DATA_ROOT, C as getDefaultRedisStateAdapterFor, D as fenceLock, E as acquireActiveLock, F as sandboxSkillFile, I as sandboxSkillPathResolution, M as SANDBOX_SKILLS_ROOT, N as SANDBOX_WORKSPACE_ROOT, O as withLock, P as sandboxSkillDir, _ as workspaceSnapshotNotReadyUserMessage, a as isAbortError, b as buildNonInteractiveShellScript, c as isSandboxCommandStreamInterruptedError, d as isSnapshottingError, f as throwSandboxOperationError, g as isWorkspaceSnapshotNotReadyError, h as getWorkspaceSnapshotNotReadyError, i as ensureDockerDaemon, j as SANDBOX_REPOS_ROOT, k as sleep$2, 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-
|
|
19
|
-
import { n as canReusePendingAuthLink, t as abandonReplacedPendingAuth } from "./pending-auth-
|
|
20
|
-
import { a as NO_REPLY_MARKER, c as CooperativeTurnYieldError, i as sanitizeAssistantText, l as TurnInputCommitLostError, n as decideReply, o as isNoReplyMarker, p as isTurnInputCommitLostError, r as getAssistantReplyText, t as authorizationId } from "./oauth-authorization-
|
|
21
|
-
import { r as EVENT_AUTHOR_ID } from "./prompt-
|
|
22
|
-
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-
|
|
23
|
-
import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline, n as sendNextWorkspaceSnapshotJob, r as sendWorkspaceSnapshotJob } from "./job-queue-
|
|
24
|
-
import {
|
|
11
|
+
import { A as juniorArtifacts, D as juniorConversations, O as juniorIdentities, S as juniorConversationAnnotations, T as juniorAttachments, _ as juniorConversationBriefs, a as juniorSchedulerRuns, f as AGENT_INVOCATION_MAILBOX_STATUSES, l as juniorStats, o as juniorSchedulerTasks, s as juniorAutomationVersions, u as juniorEventAutomations } from "./executor-BW9XWgUQ.js";
|
|
12
|
+
import { F as isVisionImageMediaType, G as removedCardSchema, L as briefLinkSchema, R as briefOutcomeStatusSchema, at as sameActorIdentity, it as instructionProvenanceFor, nt as contextProvenance, q as KNOWN_CONVERSATION_EVENT_TYPES, rt as instructionActors, z as conversationBriefSchema } from "./conversation-9Fxa1Zbq.js";
|
|
13
|
+
import { a as listReferenceFiles, c as soulPathCandidates, l as worldPathCandidates } from "./package-discovery-BVvSnQBB.js";
|
|
14
|
+
import { a as resolveAuthTokenPlaceholder, c as fetchWithBoundedOAuthErrorBodies, d as CredentialUnavailableError, i as resolvePluginHeaderEnvRefs, l as getOAuthProviderErrorAttributes, o as resolvePluginCommandEnv, s as OAuthProviderError } from "./registry-CXNv9fDX.js";
|
|
15
|
+
import { n as pluginCatalogRuntime } from "./catalog-runtime-C7339Cfm.js";
|
|
16
|
+
import { a as parseSkillInvocation, i as parseSkillFile, n as findSkillByName, r as loadSkillsByName, t as discoverSkills } from "./skills-Dd8O9Aav.js";
|
|
17
|
+
import { C as isToolResultError, D as stripRuntimeTurnContext, E as retainRuntimeTurnContext, H as recordAuthorizationRequested, I as loadTurnRoute, K as recordToolExecutionStarted, L as openConversationProjection, M as loadConnectedMcpProviders, N as loadConversationProjection, O as trimTrailingAssistantMessages, R as recordAgentsInstructionsUpdated, S as isContinuablePiBoundary, T as normalizeToolNameFromResult, U as recordGuardianActionReviewed, W as recordMcpProviderConnected, _ as getTerminalAssistantMessages, _t as historyItemFromPiMessage, d as TurnSliceLimitExceededError, f as assertTurnToolCallLimit, g as getPiMessageRole, gt as getAgentContextInputLimitTokens, h as extractAssistantText, ht as getAgentContextCompactionTriggerTokens, k as TURN_CONTEXT_TAG, m as isTurnExecutionLimitExceededError, mt as estimateTextTokens, n as loadTurnCheckpoint, nt as resolveTaskTitle, q as recordTurnRoute, r as saveTurnCheckpoint, t as continuableMessages, tt as fallbackShortTitle, v as getUserMessageInstructionText, vt as piMessageFromHistoryItem, w as isToolResultMessage, x as isAssistantMessage, y as hasRuntimeTurnContext, z as recordAttachmentsDelivered } from "./checkpoint-DaD7_Gsb.js";
|
|
18
|
+
import { A as SANDBOX_DATA_ROOT, C as getDefaultRedisStateAdapterFor, D as fenceLock, E as acquireActiveLock, F as sandboxSkillFile, I as sandboxSkillPathResolution, M as SANDBOX_SKILLS_ROOT, N as SANDBOX_WORKSPACE_ROOT, O as withLock, P as sandboxSkillDir, _ as workspaceSnapshotNotReadyUserMessage, a as isAbortError, b as buildNonInteractiveShellScript, c as isSandboxCommandStreamInterruptedError, d as isSnapshottingError, f as throwSandboxOperationError, g as isWorkspaceSnapshotNotReadyError, h as getWorkspaceSnapshotNotReadyError, i as ensureDockerDaemon, j as SANDBOX_REPOS_ROOT, k as sleep$2, 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-BamYnmhO.js";
|
|
19
|
+
import { n as canReusePendingAuthLink, t as abandonReplacedPendingAuth } from "./pending-auth-WqF4Gh8Z.js";
|
|
20
|
+
import { a as NO_REPLY_MARKER, c as CooperativeTurnYieldError, i as sanitizeAssistantText, l as TurnInputCommitLostError, n as decideReply, o as isNoReplyMarker, p as isTurnInputCommitLostError, r as getAssistantReplyText, t as authorizationId } from "./oauth-authorization-BjRN99dc.js";
|
|
21
|
+
import { r as EVENT_AUTHOR_ID } from "./prompt-Ctwy6hSI.js";
|
|
22
|
+
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-C9ETkt4T.js";
|
|
23
|
+
import { a as getVercelConversationWorkQueue, f as getTurnRequestDeadline, n as sendNextWorkspaceSnapshotJob, r as sendWorkspaceSnapshotJob } from "./job-queue-BqXd0ZPV.js";
|
|
24
|
+
import { A as eventAutomationSchema, D as scheduledRunSchema, E as scheduledAutomationSchema, L as getZonedDateTimeParts, M as compileScheduleIntent, N as scheduleIntentSchema, O as automationInstructionToolSchema, R as taskOutcomeInputSchema, S as automationVersionSchema, T as SCHEDULED_AUTOMATION_SYSTEM_ACTOR, j as ScheduleIntentError, k as automationTitleSchema } from "./automation-B9Kc1gcf.js";
|
|
25
25
|
import { n as privateTraceResultAttributes } from "./private-trace-result-BLvBjy_e.js";
|
|
26
26
|
import { streamSimple } from "@earendil-works/pi-ai/compat";
|
|
27
27
|
import { createGatewayProvider } from "@ai-sdk/gateway";
|
|
@@ -397,6 +397,15 @@ async function collectFiles(params) {
|
|
|
397
397
|
//#region src/chat/repository-instructions.ts
|
|
398
398
|
const AGENTS_FILENAME = "AGENTS.md";
|
|
399
399
|
const MAX_REPOSITORY_INSTRUCTIONS_BYTES = 32768;
|
|
400
|
+
/** Repository skill directories, in priority order, relative to the Git root. */
|
|
401
|
+
const REPOSITORY_SKILL_ROOTS = [".agents/skills", ".claude/skills"];
|
|
402
|
+
const REPOSITORY_SKILLS_HEADER = [
|
|
403
|
+
"## Repository skills",
|
|
404
|
+
"",
|
|
405
|
+
"These skills come from the repository, not from `<available-skills>`. `loadSkill` cannot load them.",
|
|
406
|
+
"Before work that matches a skill description, read its `SKILL.md` with `readFile` and follow it.",
|
|
407
|
+
"Resolve relative paths in a skill against the skill directory."
|
|
408
|
+
].join("\n");
|
|
400
409
|
const AGENTS_REPLACEMENT_NOTICE = "These AGENTS.md instructions replace all previously provided AGENTS.md instructions.";
|
|
401
410
|
const AGENTS_REMOVAL_NOTICE = "The previously provided AGENTS.md instructions no longer apply.";
|
|
402
411
|
async function pathExists(fs, target) {
|
|
@@ -446,20 +455,53 @@ async function readInstructionFile(fs, filePath) {
|
|
|
446
455
|
throw error;
|
|
447
456
|
}
|
|
448
457
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
458
|
+
async function readOptionalDirectory(fs, directory) {
|
|
459
|
+
try {
|
|
460
|
+
return await fs.readdir(directory);
|
|
461
|
+
} catch (error) {
|
|
462
|
+
if (isMissingPathError(error)) return [];
|
|
463
|
+
throw error;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/** Read model-invocable skills from the repository skill directories. */
|
|
467
|
+
async function readRepositorySkills(fs, gitRoot) {
|
|
468
|
+
const roots = REPOSITORY_SKILL_ROOTS.map((root) => path.posix.join(gitRoot, root));
|
|
469
|
+
const listings = await Promise.all(roots.map(async (root) => await readOptionalDirectory(fs, root)));
|
|
470
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
471
|
+
listings.forEach((entries, index) => {
|
|
472
|
+
for (const entry of [...entries].sort()) if (!candidates.has(entry)) candidates.set(entry, path.posix.join(roots[index], entry));
|
|
473
|
+
});
|
|
474
|
+
return (await Promise.all([...candidates].map(async ([name, skillDirectory]) => {
|
|
475
|
+
if (!await directoryExists(fs, skillDirectory)) return;
|
|
476
|
+
const filePath = path.posix.join(skillDirectory, "SKILL.md");
|
|
477
|
+
const raw = await readInstructionFile(fs, filePath);
|
|
478
|
+
const parsed = raw ? parseSkillFile(raw, name) : void 0;
|
|
479
|
+
if (!parsed?.ok || parsed.skill.disableModelInvocation) return;
|
|
480
|
+
return {
|
|
481
|
+
description: parsed.skill.description.replace(/\s+/g, " ").trim(),
|
|
482
|
+
name,
|
|
483
|
+
path: filePath
|
|
484
|
+
};
|
|
485
|
+
}))).filter((skill) => Boolean(skill)).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
486
|
+
}
|
|
487
|
+
function sourceBytes(sources) {
|
|
488
|
+
return sources.reduce((total, source) => total + Buffer.byteLength(source.content, "utf8"), 0);
|
|
489
|
+
}
|
|
490
|
+
function skillListBytes(skills) {
|
|
491
|
+
return skills.reduce((total, skill) => total + repositorySkillBytes(skill), 0);
|
|
492
|
+
}
|
|
493
|
+
/** Read root-to-cwd AGENTS.md files within the byte budget. */
|
|
494
|
+
async function readAgentsSources(args) {
|
|
453
495
|
const directories = [];
|
|
454
496
|
let current = args.cwd;
|
|
455
497
|
for (;;) {
|
|
456
498
|
directories.push(current);
|
|
457
|
-
if (current === gitRoot) break;
|
|
499
|
+
if (current === args.gitRoot) break;
|
|
458
500
|
current = path.posix.dirname(current);
|
|
459
501
|
}
|
|
460
502
|
directories.reverse();
|
|
461
503
|
const sources = [];
|
|
462
|
-
let remaining = Math.max(0, args.maxBytes
|
|
504
|
+
let remaining = Math.max(0, args.maxBytes);
|
|
463
505
|
for (const directory of directories) {
|
|
464
506
|
if (remaining <= 0) break;
|
|
465
507
|
const filePath = path.posix.join(directory, AGENTS_FILENAME);
|
|
@@ -473,34 +515,69 @@ async function resolveRepositoryInstructions(args) {
|
|
|
473
515
|
});
|
|
474
516
|
remaining -= Buffer.byteLength(bounded, "utf8");
|
|
475
517
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
518
|
+
return sources;
|
|
519
|
+
}
|
|
520
|
+
/** Read repository skills that fit the byte budget, keeping each entry whole. */
|
|
521
|
+
async function readRepositorySkillsWithinBudget(args) {
|
|
522
|
+
const skills = [];
|
|
523
|
+
let remaining = args.maxBytes;
|
|
524
|
+
if (remaining <= 0) return skills;
|
|
525
|
+
for (const skill of await readRepositorySkills(args.fs, args.gitRoot)) {
|
|
526
|
+
const bytes = repositorySkillBytes(skill);
|
|
527
|
+
if (bytes > remaining) break;
|
|
528
|
+
skills.push(skill);
|
|
529
|
+
remaining -= bytes;
|
|
530
|
+
}
|
|
531
|
+
return skills;
|
|
532
|
+
}
|
|
533
|
+
function buildRepositoryInstructions(directory, sources, skills) {
|
|
534
|
+
if (sources.length === 0 && skills.length === 0) return;
|
|
482
535
|
return {
|
|
483
|
-
directory
|
|
484
|
-
fingerprint
|
|
536
|
+
directory,
|
|
537
|
+
fingerprint: createHash("sha256").update(JSON.stringify({
|
|
538
|
+
directory,
|
|
539
|
+
sources,
|
|
540
|
+
...skills.length > 0 ? { skills } : void 0
|
|
541
|
+
})).digest("hex"),
|
|
542
|
+
...skills.length > 0 ? { skills } : void 0,
|
|
485
543
|
sources,
|
|
486
|
-
text
|
|
544
|
+
text: formatRepositoryInstructions(sources, skills)
|
|
487
545
|
};
|
|
488
546
|
}
|
|
489
547
|
function formatInstructionSources(sources) {
|
|
490
548
|
if (sources.length === 1) return sources[0].content;
|
|
491
549
|
return sources.map((source) => `## ${path.posix.dirname(source.path)}\n\n${source.content}`).join("\n\n");
|
|
492
550
|
}
|
|
551
|
+
function formatRepositorySkill(skill) {
|
|
552
|
+
return `- \`${skill.name}\` (\`${skill.path}\`): ${skill.description}`;
|
|
553
|
+
}
|
|
554
|
+
function repositorySkillBytes(skill) {
|
|
555
|
+
return Buffer.byteLength(formatRepositorySkill(skill), "utf8") + 1;
|
|
556
|
+
}
|
|
557
|
+
function formatRepositoryInstructions(sources, skills) {
|
|
558
|
+
const sections = [];
|
|
559
|
+
if (sources.length > 0) sections.push(formatInstructionSources(sources));
|
|
560
|
+
if (skills.length > 0) sections.push([
|
|
561
|
+
REPOSITORY_SKILLS_HEADER,
|
|
562
|
+
"",
|
|
563
|
+
...skills.map(formatRepositorySkill)
|
|
564
|
+
].join("\n"));
|
|
565
|
+
return sections.join("\n\n");
|
|
566
|
+
}
|
|
493
567
|
/** Combine AGENTS.md bundles from one or more repository directories. */
|
|
494
568
|
function mergeRepositoryInstructions(bundles) {
|
|
495
569
|
if (bundles.length === 0) return;
|
|
496
570
|
if (bundles.length === 1) return bundles[0];
|
|
497
571
|
const sources = bundles.flatMap((bundle) => bundle.sources);
|
|
498
|
-
const
|
|
572
|
+
const skills = bundles.flatMap((bundle) => bundle.skills ?? []);
|
|
573
|
+
const text = formatRepositoryInstructions(sources, skills);
|
|
499
574
|
return {
|
|
500
575
|
fingerprint: createHash("sha256").update(JSON.stringify({
|
|
501
576
|
directories: bundles.map((bundle) => bundle.directory ?? null),
|
|
502
|
-
sources
|
|
577
|
+
sources,
|
|
578
|
+
...skills.length > 0 ? { skills } : void 0
|
|
503
579
|
})).digest("hex"),
|
|
580
|
+
...skills.length > 0 ? { skills } : void 0,
|
|
504
581
|
sources,
|
|
505
582
|
text
|
|
506
583
|
};
|
|
@@ -509,17 +586,33 @@ function mergeRepositoryInstructions(bundles) {
|
|
|
509
586
|
async function resolveRepositoryInstructionsForDirectories(args) {
|
|
510
587
|
const uniqueDirectories = [...new Set(args.directories.filter((directory) => directory === SANDBOX_WORKSPACE_ROOT || directory.startsWith(`${SANDBOX_WORKSPACE_ROOT}/`)))].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
|
|
511
588
|
let remaining = MAX_REPOSITORY_INSTRUCTIONS_BYTES;
|
|
512
|
-
const
|
|
589
|
+
const repositories = [];
|
|
513
590
|
for (const directory of uniqueDirectories) {
|
|
514
|
-
|
|
515
|
-
|
|
591
|
+
const gitRoot = await findGitRoot(args.fs, directory);
|
|
592
|
+
if (!gitRoot) continue;
|
|
593
|
+
const sources = await readAgentsSources({
|
|
516
594
|
cwd: directory,
|
|
517
595
|
fs: args.fs,
|
|
596
|
+
gitRoot,
|
|
597
|
+
maxBytes: remaining
|
|
598
|
+
});
|
|
599
|
+
remaining -= sourceBytes(sources);
|
|
600
|
+
repositories.push({
|
|
601
|
+
directory,
|
|
602
|
+
gitRoot,
|
|
603
|
+
sources
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
const bundles = [];
|
|
607
|
+
for (const repository of repositories) {
|
|
608
|
+
const skills = await readRepositorySkillsWithinBudget({
|
|
609
|
+
fs: args.fs,
|
|
610
|
+
gitRoot: repository.gitRoot,
|
|
518
611
|
maxBytes: remaining
|
|
519
612
|
});
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
613
|
+
remaining -= skillListBytes(skills);
|
|
614
|
+
const bundle = buildRepositoryInstructions(repository.directory, repository.sources, skills);
|
|
615
|
+
if (bundle) bundles.push(bundle);
|
|
523
616
|
}
|
|
524
617
|
return mergeRepositoryInstructions(bundles);
|
|
525
618
|
}
|
|
@@ -3095,6 +3188,10 @@ function normalizeSlackStatusText(text) {
|
|
|
3095
3188
|
if (!trimmed) return "";
|
|
3096
3189
|
return truncateStatusText(trimmed.replace(/(?:\.\s*)+$/, "").trim());
|
|
3097
3190
|
}
|
|
3191
|
+
/** Render a Slack user mention, which Slack shows as the person's name. */
|
|
3192
|
+
function slackMention(userId) {
|
|
3193
|
+
return `<@${userId}>`;
|
|
3194
|
+
}
|
|
3098
3195
|
//#endregion
|
|
3099
3196
|
//#region src/chat/slack/oauth-authorization-message.ts
|
|
3100
3197
|
/** Present private OAuth authorization with a clear action and text fallback. */
|
|
@@ -3984,12 +4081,14 @@ function renderTaskInput(args) {
|
|
|
3984
4081
|
const instructions = args.instructions.trim();
|
|
3985
4082
|
if (!instructions) throw new Error("Task instructions are required");
|
|
3986
4083
|
const about = args.about?.trim();
|
|
4084
|
+
const creator = args.creator?.trim();
|
|
3987
4085
|
const lines = [
|
|
3988
4086
|
"[task]",
|
|
3989
4087
|
"",
|
|
3990
4088
|
"This is a task, not a message from a person.",
|
|
3991
4089
|
"",
|
|
3992
4090
|
...about ? [`About: ${oneLine(about)}`] : [],
|
|
4091
|
+
...creator ? [`Created by: ${oneLine(creator)}. Where the instructions say "me" or "my", write this mention.`] : [],
|
|
3993
4092
|
`Instructions: ${instructions}`
|
|
3994
4093
|
];
|
|
3995
4094
|
const guidance = args.guidance?.trim();
|
|
@@ -8742,7 +8841,7 @@ var PluginMcpClient = class {
|
|
|
8742
8841
|
return [...this.listedTools];
|
|
8743
8842
|
});
|
|
8744
8843
|
}
|
|
8745
|
-
async callTool(name, args) {
|
|
8844
|
+
async callTool(name, args, signal) {
|
|
8746
8845
|
return await this.withSessionRecovery(async () => {
|
|
8747
8846
|
const client = await this.getClient();
|
|
8748
8847
|
const mcp = this.plugin.manifest.mcp;
|
|
@@ -8759,7 +8858,7 @@ var PluginMcpClient = class {
|
|
|
8759
8858
|
const result = await this.wrapAuth(() => client.callTool({
|
|
8760
8859
|
name,
|
|
8761
8860
|
arguments: args ?? {}
|
|
8762
|
-
}), "call_tool");
|
|
8861
|
+
}, void 0, signal ? { signal } : void 0), "call_tool");
|
|
8763
8862
|
await this.syncTransportSessionId();
|
|
8764
8863
|
return result;
|
|
8765
8864
|
});
|
|
@@ -9143,7 +9242,7 @@ var McpToolManager = class {
|
|
|
9143
9242
|
const argumentAttribute = serializeMcpPayload(resolvedArgs, conversationPrivacy, { privateMetadata: true });
|
|
9144
9243
|
return await withSpan(`execute_tool ${managedToolName}`, "gen_ai.execute_tool", {}, async () => {
|
|
9145
9244
|
try {
|
|
9146
|
-
const result = await client.callTool(tool.name, resolvedArgs);
|
|
9245
|
+
const result = await client.callTool(tool.name, resolvedArgs, options?.signal);
|
|
9147
9246
|
if ("isError" in result && result.isError) throw new McpToolError(extractMcpErrorMessage(result));
|
|
9148
9247
|
const resultAttribute = serializeMcpPayload(result, conversationPrivacy, { privateMetadata: true });
|
|
9149
9248
|
if (resultAttribute) setSpanAttributes({ "gen_ai.tool.call.result": resultAttribute });
|
|
@@ -9503,6 +9602,7 @@ function createCallMcpToolTool(mcpToolManager) {
|
|
|
9503
9602
|
}
|
|
9504
9603
|
const result = await mcpTool.execute(resolveMcpArguments(input), {
|
|
9505
9604
|
conversationPrivacy: options?.conversationPrivacy ?? "private",
|
|
9605
|
+
...options?.signal ? { signal: options.signal } : void 0,
|
|
9506
9606
|
...options?.toolCallId ? { toolCallId: options.toolCallId } : void 0
|
|
9507
9607
|
});
|
|
9508
9608
|
return {
|
|
@@ -10262,6 +10362,7 @@ var AutomationConflictError = class extends ToolInputError {
|
|
|
10262
10362
|
this.name = "AutomationConflictError";
|
|
10263
10363
|
}
|
|
10264
10364
|
};
|
|
10365
|
+
/** Sort object keys so equal values produce equal JSON. */
|
|
10265
10366
|
function canonicalJson$1(value) {
|
|
10266
10367
|
if (Array.isArray(value)) return value.map(canonicalJson$1);
|
|
10267
10368
|
if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, child]) => [key, canonicalJson$1(child)]));
|
|
@@ -10276,6 +10377,70 @@ function requireAutomationRevision(task, revision) {
|
|
|
10276
10377
|
if (!task || automationRevision(task) !== revision) throw new AutomationConflictError();
|
|
10277
10378
|
}
|
|
10278
10379
|
//#endregion
|
|
10380
|
+
//#region src/chat/automations/versions.ts
|
|
10381
|
+
/** Automation versions keep each saved definition so people can see how it changed. */
|
|
10382
|
+
/** Return the versioned part of an Automation. Lifecycle and run state are excluded. */
|
|
10383
|
+
function automationDefinition(task) {
|
|
10384
|
+
const common = {
|
|
10385
|
+
title: task.title?.trim() || null,
|
|
10386
|
+
instruction: task.task.text,
|
|
10387
|
+
credentialMode: task.credentialMode,
|
|
10388
|
+
destination: task.destination,
|
|
10389
|
+
outcomes: task.outcomes
|
|
10390
|
+
};
|
|
10391
|
+
return "schedule" in task ? {
|
|
10392
|
+
...common,
|
|
10393
|
+
schedule: task.schedule
|
|
10394
|
+
} : {
|
|
10395
|
+
...common,
|
|
10396
|
+
trigger: task.trigger
|
|
10397
|
+
};
|
|
10398
|
+
}
|
|
10399
|
+
/** Compare definition values after key sorting. */
|
|
10400
|
+
function sameDefinitionValue(left, right) {
|
|
10401
|
+
return JSON.stringify(canonicalJson$1(left)) === JSON.stringify(canonicalJson$1(right));
|
|
10402
|
+
}
|
|
10403
|
+
/**
|
|
10404
|
+
* Save a version when the definition changed. Call this in the same
|
|
10405
|
+
* transaction and lock as the Automation write. Without `current`, the
|
|
10406
|
+
* Automation is new, so the creator saves version 1.
|
|
10407
|
+
*/
|
|
10408
|
+
async function recordAutomationVersion(db, kind, task, current, editedBy) {
|
|
10409
|
+
const definition = automationDefinition(task);
|
|
10410
|
+
if (current && sameDefinitionValue(automationDefinition(current), definition)) return;
|
|
10411
|
+
await db.insert(juniorAutomationVersions).values({
|
|
10412
|
+
kind,
|
|
10413
|
+
automationId: task.id,
|
|
10414
|
+
version: sql`(
|
|
10415
|
+
SELECT coalesce(max(${juniorAutomationVersions.version}), 0) + 1
|
|
10416
|
+
FROM ${juniorAutomationVersions}
|
|
10417
|
+
WHERE ${juniorAutomationVersions.kind} = ${kind}
|
|
10418
|
+
AND ${juniorAutomationVersions.automationId} = ${task.id}
|
|
10419
|
+
)`,
|
|
10420
|
+
createdAtMs: Date.now(),
|
|
10421
|
+
editedBy: editedBy ?? (current ? null : task.createdBy),
|
|
10422
|
+
definition
|
|
10423
|
+
});
|
|
10424
|
+
}
|
|
10425
|
+
function parseVersionRow(kind, row) {
|
|
10426
|
+
return automationVersionSchema.parse({
|
|
10427
|
+
kind,
|
|
10428
|
+
version: row.version,
|
|
10429
|
+
createdAt: new Date(row.createdAtMs).toISOString(),
|
|
10430
|
+
editedBy: row.editedBy,
|
|
10431
|
+
definition: row.definition
|
|
10432
|
+
});
|
|
10433
|
+
}
|
|
10434
|
+
/** Read one saved definition. */
|
|
10435
|
+
async function readAutomationVersion(db, kind, automationId, version) {
|
|
10436
|
+
const [row] = await db.select().from(juniorAutomationVersions).where(and(eq(juniorAutomationVersions.kind, kind), eq(juniorAutomationVersions.automationId, automationId), eq(juniorAutomationVersions.version, version))).limit(1);
|
|
10437
|
+
return row ? parseVersionRow(kind, row) : void 0;
|
|
10438
|
+
}
|
|
10439
|
+
/** Read saved definitions, newest first. */
|
|
10440
|
+
async function listAutomationVersions(db, kind, automationId, limit) {
|
|
10441
|
+
return (await db.select().from(juniorAutomationVersions).where(and(eq(juniorAutomationVersions.kind, kind), eq(juniorAutomationVersions.automationId, automationId))).orderBy(desc(juniorAutomationVersions.version)).limit(limit)).map((row) => parseVersionRow(kind, row));
|
|
10442
|
+
}
|
|
10443
|
+
//#endregion
|
|
10279
10444
|
//#region src/chat/event-automations/store.ts
|
|
10280
10445
|
const retainedEventAutomationSchema = eventAutomationSchema.extend({
|
|
10281
10446
|
destination: slackDestinationSchema,
|
|
@@ -10327,61 +10492,84 @@ async function getEventAutomation(db, id) {
|
|
|
10327
10492
|
async function createEventAutomation(db, task) {
|
|
10328
10493
|
const parsed = eventAutomationSchema.parse(eventAutomationJsonPayload(task));
|
|
10329
10494
|
const title = task.title?.trim() || null;
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
|
|
10495
|
+
return db.transaction(async (tx) => {
|
|
10496
|
+
const inserted = await tx.insert(juniorEventAutomations).values({
|
|
10497
|
+
id: parsed.id,
|
|
10498
|
+
teamId: parsed.destination.teamId,
|
|
10499
|
+
namespace: parsed.trigger.namespace,
|
|
10500
|
+
identifier: parsed.trigger.identifier,
|
|
10501
|
+
createdAtMs: parsed.createdAtMs,
|
|
10502
|
+
status: "active",
|
|
10503
|
+
title,
|
|
10504
|
+
task: parsed
|
|
10505
|
+
}).onConflictDoNothing().returning({
|
|
10506
|
+
status: juniorEventAutomations.status,
|
|
10507
|
+
task: juniorEventAutomations.task,
|
|
10508
|
+
title: juniorEventAutomations.title
|
|
10509
|
+
});
|
|
10510
|
+
if (inserted[0]) {
|
|
10511
|
+
const created = parseEventAutomationRow(inserted[0]);
|
|
10512
|
+
await recordAutomationVersion(tx, "event", created, void 0);
|
|
10513
|
+
return created;
|
|
10514
|
+
}
|
|
10515
|
+
const existing = await getEventAutomation(tx, parsed.id);
|
|
10516
|
+
if (!existing) return {
|
|
10517
|
+
...parsed,
|
|
10518
|
+
status: "active",
|
|
10519
|
+
...title ? { title } : void 0
|
|
10520
|
+
};
|
|
10521
|
+
if (existing.status !== "deleted") return existing;
|
|
10522
|
+
const rows = await tx.update(juniorEventAutomations).set({
|
|
10523
|
+
teamId: parsed.destination.teamId,
|
|
10524
|
+
namespace: parsed.trigger.namespace,
|
|
10525
|
+
identifier: parsed.trigger.identifier,
|
|
10526
|
+
status: "active",
|
|
10527
|
+
title,
|
|
10528
|
+
task: parsed
|
|
10529
|
+
}).where(and(eq(juniorEventAutomations.id, parsed.id), eq(juniorEventAutomations.status, "deleted"))).returning({
|
|
10530
|
+
status: juniorEventAutomations.status,
|
|
10531
|
+
task: juniorEventAutomations.task,
|
|
10532
|
+
title: juniorEventAutomations.title
|
|
10533
|
+
});
|
|
10534
|
+
if (!rows[0]) return await getEventAutomation(tx, parsed.id) ?? {
|
|
10535
|
+
...parsed,
|
|
10536
|
+
status: "active",
|
|
10537
|
+
...title ? { title } : void 0
|
|
10538
|
+
};
|
|
10539
|
+
const revived = parseEventAutomationRow(rows[0]);
|
|
10540
|
+
await recordAutomationVersion(tx, "event", revived, void 0);
|
|
10541
|
+
return revived;
|
|
10358
10542
|
});
|
|
10359
|
-
return rows[0] ? parseEventAutomationRow(rows[0]) : await getEventAutomation(db, parsed.id) ?? {
|
|
10360
|
-
...parsed,
|
|
10361
|
-
status: "active",
|
|
10362
|
-
...title ? { title } : void 0
|
|
10363
|
-
};
|
|
10364
10543
|
}
|
|
10365
|
-
/**
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
return saveEventAutomation(tx, task);
|
|
10371
|
-
});
|
|
10544
|
+
/**
|
|
10545
|
+
* Replace an existing non-deleted event automation under a row lock.
|
|
10546
|
+
* Pass `editedBy` when a person changes the definition so its version names them.
|
|
10547
|
+
*/
|
|
10548
|
+
async function saveEventAutomation(db, task, expectedRevision, editedBy) {
|
|
10372
10549
|
const parsed = eventAutomationSchema.parse(eventAutomationJsonPayload(task));
|
|
10373
10550
|
const title = task.title?.trim() || null;
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10551
|
+
return db.transaction(async (tx) => {
|
|
10552
|
+
const rows = await tx.select({
|
|
10553
|
+
status: juniorEventAutomations.status,
|
|
10554
|
+
task: juniorEventAutomations.task,
|
|
10555
|
+
title: juniorEventAutomations.title
|
|
10556
|
+
}).from(juniorEventAutomations).where(eq(juniorEventAutomations.id, parsed.id)).for("update");
|
|
10557
|
+
const current = rows[0] ? parseEventAutomationRow(rows[0]) : void 0;
|
|
10558
|
+
if (expectedRevision !== void 0) requireAutomationRevision(current, expectedRevision);
|
|
10559
|
+
if (!current || current.status === "deleted") return void 0;
|
|
10560
|
+
const saved = parseEventAutomationRow((await tx.update(juniorEventAutomations).set({
|
|
10561
|
+
namespace: parsed.trigger.namespace,
|
|
10562
|
+
identifier: parsed.trigger.identifier,
|
|
10563
|
+
title,
|
|
10564
|
+
task: parsed
|
|
10565
|
+
}).where(eq(juniorEventAutomations.id, parsed.id)).returning({
|
|
10566
|
+
status: juniorEventAutomations.status,
|
|
10567
|
+
task: juniorEventAutomations.task,
|
|
10568
|
+
title: juniorEventAutomations.title
|
|
10569
|
+
}))[0]);
|
|
10570
|
+
await recordAutomationVersion(tx, "event", saved, current, editedBy);
|
|
10571
|
+
return saved;
|
|
10383
10572
|
});
|
|
10384
|
-
return rows[0] ? parseEventAutomationRow(rows[0]) : void 0;
|
|
10385
10573
|
}
|
|
10386
10574
|
/** Mark one existing event automation deleted while retaining the row for history. */
|
|
10387
10575
|
async function deleteEventAutomation(db, id) {
|
|
@@ -10697,7 +10885,7 @@ function createEventAutomationTool(context, catalog) {
|
|
|
10697
10885
|
executionMode: "sequential",
|
|
10698
10886
|
description: "Create a durable event automation in the active Slack channel or DM, never a thread. It executes the supplied instruction for every matching event. Use for whenever-this-happens-do-X automation; ordinary watch, notify, or tell-me-when requests use watchEvents instead. The automation may use the creator's connected credentials. Prefer a subscribable tool result when available.",
|
|
10699
10887
|
inputSchema: z.object({
|
|
10700
|
-
instruction:
|
|
10888
|
+
instruction: automationInstructionToolSchema,
|
|
10701
10889
|
title: z.string().trim().min(1).max(60).nullable().describe("Optional short display title. Omit or use null to generate one from the task instruction.").optional(),
|
|
10702
10890
|
trigger,
|
|
10703
10891
|
outcomes: z.array(taskOutcomeInputSchema).max(5).describe("Successful work is silent by default. Omit this field or use an empty list when the Automation should act through tools without a status message. Add send_message only when the user asks for a notification, post, digest, summary, or other visible result.").optional(),
|
|
@@ -10908,7 +11096,7 @@ function createUpdateEventAutomationTool(context, catalog) {
|
|
|
10908
11096
|
inputSchema: z.object({
|
|
10909
11097
|
automationId: z.string().min(1),
|
|
10910
11098
|
title: automationTitleSchema.optional(),
|
|
10911
|
-
instruction:
|
|
11099
|
+
instruction: automationInstructionToolSchema.nullable().optional(),
|
|
10912
11100
|
trigger: registeredEventAutomationTriggerSchema(catalog).nullable().optional(),
|
|
10913
11101
|
outcomes: z.array(taskOutcomeInputSchema).max(5).nullable().describe("Replacement messages to send after successful work. Use an empty list to send nothing. Omit or use null to leave unchanged.").optional(),
|
|
10914
11102
|
credentialMode: z.enum(["system", "creator"]).nullable().describe("Set creator to make the task's original creator credentials available, or system to disable them. Creator always means the task's createdBy actor, never the current requester. Only that original creator may enable creator mode. Omit or use null to leave unchanged.").optional()
|
|
@@ -10936,7 +11124,11 @@ function createUpdateEventAutomationTool(context, catalog) {
|
|
|
10936
11124
|
outcomes: input.outcomes ?? void 0,
|
|
10937
11125
|
credentialMode: input.credentialMode ?? void 0
|
|
10938
11126
|
}, isCreator, catalog);
|
|
10939
|
-
const saved = await saveEventAutomation(getDb(), next, automationRevision(current)
|
|
11127
|
+
const saved = await saveEventAutomation(getDb(), next, automationRevision(current), {
|
|
11128
|
+
slackUserId: actor.userId,
|
|
11129
|
+
...actor.fullName ? { fullName: actor.fullName } : void 0,
|
|
11130
|
+
...actor.userName ? { userName: actor.userName } : void 0
|
|
11131
|
+
});
|
|
10940
11132
|
if (!saved) throw new ToolInputError("Event automation was not found.");
|
|
10941
11133
|
return eventAutomationToolResult(context.conversationId, saved, catalog, actor.userId);
|
|
10942
11134
|
}
|
|
@@ -11090,10 +11282,11 @@ async function listScheduledAutomations(db) {
|
|
|
11090
11282
|
async function listScheduledAutomationsForTeam(db, teamId) {
|
|
11091
11283
|
return await readListedScheduledAutomations(db, teamId);
|
|
11092
11284
|
}
|
|
11093
|
-
async function writeScheduledAutomation(db, task, current) {
|
|
11285
|
+
async function writeScheduledAutomation(db, task, current, editedBy) {
|
|
11094
11286
|
if (current?.status === "blocked" && task.status === "active" && typeof task.nextRunAtMs === "number" && Number.isFinite(task.nextRunAtMs)) await db.delete(juniorSchedulerRuns).where(and(eq(juniorSchedulerRuns.id, scheduledRunId(task.id, task.nextRunAtMs)), eq(juniorSchedulerRuns.status, "blocked")));
|
|
11095
11287
|
if (task.status === "deleted" && current?.status !== "deleted") await skipPendingRunsForDeletedTask(db, task);
|
|
11096
11288
|
await upsertScheduledAutomation(db, task);
|
|
11289
|
+
await recordAutomationVersion(db, "scheduled", task, current, editedBy);
|
|
11097
11290
|
}
|
|
11098
11291
|
async function skipPendingRunsForDeletedTask(db, task) {
|
|
11099
11292
|
const errorMessage = `Scheduled automation ${task.id} was deleted before the run started.`;
|
|
@@ -11123,13 +11316,16 @@ async function createScheduledAutomation(db, task) {
|
|
|
11123
11316
|
return next;
|
|
11124
11317
|
});
|
|
11125
11318
|
}
|
|
11126
|
-
/**
|
|
11127
|
-
|
|
11319
|
+
/**
|
|
11320
|
+
* Save a scheduled automation and clear its blocked occurrence on reactivation.
|
|
11321
|
+
* Pass `editedBy` when a person changes the definition so its version names them.
|
|
11322
|
+
*/
|
|
11323
|
+
async function saveScheduledAutomation(db, task, expectedRevision, editedBy) {
|
|
11128
11324
|
const next = requireStoredTask(task);
|
|
11129
11325
|
await withScheduledAutomationLock(db, task.id, async (tx) => {
|
|
11130
11326
|
const current = await readScheduledAutomation(tx, task.id);
|
|
11131
11327
|
if (expectedRevision !== void 0) requireAutomationRevision(current, expectedRevision);
|
|
11132
|
-
await writeScheduledAutomation(tx, next, current);
|
|
11328
|
+
await writeScheduledAutomation(tx, next, current, editedBy);
|
|
11133
11329
|
});
|
|
11134
11330
|
return next;
|
|
11135
11331
|
}
|
|
@@ -11440,7 +11636,7 @@ function createSlackScheduleCreateAutomationTool(context) {
|
|
|
11440
11636
|
description: "Create a one-time or recurring Junior task in the active Slack channel. Store the requested future work; do not perform it or check its service access now unless the user also asks for that.",
|
|
11441
11637
|
executionMode: "sequential",
|
|
11442
11638
|
inputSchema: z.object({
|
|
11443
|
-
instruction:
|
|
11639
|
+
instruction: automationInstructionToolSchema,
|
|
11444
11640
|
title: z.string().trim().min(1).max(60).nullable().describe("Optional short display title. Omit or use null to generate one from the task instruction.").optional(),
|
|
11445
11641
|
schedule: scheduleIntentSchema.describe("When the task runs. The scheduler computes the exact next run from this intent and the server clock."),
|
|
11446
11642
|
outcomes: z.array(taskOutcomeInputSchema).max(5).describe("Successful work is silent by default. Omit this field or use an empty list when the Automation should act through tools without a status message. Add send_message only when the user asks for a reminder, post, digest, summary, or other visible result.").optional(),
|
|
@@ -11730,7 +11926,7 @@ function createSlackScheduleUpdateAutomationTool(context) {
|
|
|
11730
11926
|
inputSchema: z.object({
|
|
11731
11927
|
automationId: z.string().min(1).describe("Scheduled automation ID returned by slackScheduleListAutomations."),
|
|
11732
11928
|
title: automationTitleSchema.optional(),
|
|
11733
|
-
instruction:
|
|
11929
|
+
instruction: automationInstructionToolSchema.optional(),
|
|
11734
11930
|
schedule: scheduleIntentSchema.describe("Complete replacement schedule. Omit to keep it unchanged.").nullable().optional(),
|
|
11735
11931
|
outcomes: z.array(taskOutcomeInputSchema).max(5).describe("Replacement messages to send after successful work. Use an empty list to send nothing. Omit to keep unchanged.").optional(),
|
|
11736
11932
|
status: z.enum(["active", "blocked"]).describe("Set active to resume a blocked task, or blocked to stop dispatch.").optional(),
|
|
@@ -11777,7 +11973,7 @@ function createSlackScheduleUpdateAutomationTool(context) {
|
|
|
11777
11973
|
next.outcomes = input.outcomes === void 0 ? moveTaskOutcomes(lookup.outcomes, lookup.destination, requestedDestination) : await resolveTaskOutcomes(input.outcomes, requestedDestination, lookup.createdBy.slackUserId);
|
|
11778
11974
|
}
|
|
11779
11975
|
if (!changingDestination && !instructionChanged && !input.schedule && input.title === void 0 && status === void 0 && (input.credentialMode === void 0 || input.credentialMode === null || input.credentialMode === lookup.credentialMode) && input.outcomes === void 0 && moveDestination) return scheduleAutomationToolResult(context.conversationId, lookup, actor.slackUserId);
|
|
11780
|
-
const committed = await saveScheduledAutomation(db, next, automationRevision(lookup));
|
|
11976
|
+
const committed = await saveScheduledAutomation(db, next, automationRevision(lookup), actor);
|
|
11781
11977
|
if (changingDestination) logInfo("scheduled_automation.move.completed", scheduledAutomationAttributes(committed));
|
|
11782
11978
|
return scheduleAutomationToolResult(context.conversationId, committed, actor.slackUserId);
|
|
11783
11979
|
}
|
|
@@ -14651,9 +14847,6 @@ function explicitUserLookupError(error) {
|
|
|
14651
14847
|
if (error.code === "invalid_arguments") return `Slack rejected the user lookup arguments (${error.apiError ?? error.code}).`;
|
|
14652
14848
|
if (error.code === "feature_unavailable") return "User lookup is not available for this workspace or app installation.";
|
|
14653
14849
|
}
|
|
14654
|
-
function slackMention(userId) {
|
|
14655
|
-
return `<@${userId}>`;
|
|
14656
|
-
}
|
|
14657
14850
|
function asMatch(user) {
|
|
14658
14851
|
return {
|
|
14659
14852
|
...user,
|
|
@@ -17617,6 +17810,36 @@ function createSearchToolsTool(catalogTools) {
|
|
|
17617
17810
|
}
|
|
17618
17811
|
//#endregion
|
|
17619
17812
|
//#region src/chat/tool-support/pi-tool-adapter.ts
|
|
17813
|
+
/**
|
|
17814
|
+
* How long a preempted tool may take to return its own aborted result. Keep it
|
|
17815
|
+
* below the agent's abort settle grace, so the parked turn sees the result.
|
|
17816
|
+
*/
|
|
17817
|
+
const TOOL_ABORT_SETTLE_GRACE_MS = 2e3;
|
|
17818
|
+
/**
|
|
17819
|
+
* Stop waiting for a tool shortly after the host preempts it. A tool that
|
|
17820
|
+
* ignores the signal must not hold the turn past its deadline, or the parked
|
|
17821
|
+
* turn loses the attempt. Work that keeps running is detached; its outcome is
|
|
17822
|
+
* unknown.
|
|
17823
|
+
*/
|
|
17824
|
+
async function untilPreempted(work, signal) {
|
|
17825
|
+
if (!signal) return await work;
|
|
17826
|
+
let timer;
|
|
17827
|
+
let onAbort = () => {};
|
|
17828
|
+
const preempted = new Promise((_, reject) => {
|
|
17829
|
+
onAbort = () => {
|
|
17830
|
+
timer = setTimeout(() => reject(signal.reason), TOOL_ABORT_SETTLE_GRACE_MS);
|
|
17831
|
+
};
|
|
17832
|
+
if (signal.aborted) onAbort();
|
|
17833
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
17834
|
+
});
|
|
17835
|
+
try {
|
|
17836
|
+
return await Promise.race([work, preempted]);
|
|
17837
|
+
} finally {
|
|
17838
|
+
clearTimeout(timer);
|
|
17839
|
+
signal.removeEventListener("abort", onAbort);
|
|
17840
|
+
work.catch(() => void 0);
|
|
17841
|
+
}
|
|
17842
|
+
}
|
|
17620
17843
|
/** Wrap tool definitions into Pi Agent tool objects with logging, validation, and sandbox execution. */
|
|
17621
17844
|
function createPiAgentTools(tools, sandbox, spanContext, onStatus, sandboxTools, pluginAuthOrchestration, onToolCall, agentHooks, conversationPrivacy, onToolResult, actionReview) {
|
|
17622
17845
|
const plannedTools = planToolExposure(tools);
|
|
@@ -17678,17 +17901,17 @@ function createPiAgentTools(tools, sandbox, spanContext, onStatus, sandboxTools,
|
|
|
17678
17901
|
}
|
|
17679
17902
|
const sandboxInput = buildSandboxInput(toolName, executionInput);
|
|
17680
17903
|
const isSandbox = Boolean(sandboxTools?.supports(toolName));
|
|
17681
|
-
const result = isSandbox ?
|
|
17904
|
+
const result = await untilPreempted(isSandbox ? sandboxTools.execute({
|
|
17682
17905
|
toolName,
|
|
17683
17906
|
input: sandboxInput,
|
|
17684
17907
|
...signal ? { signal } : void 0,
|
|
17685
17908
|
...toolName === "grep" || toolName === "findFiles" ? { setToolCallSpanAttributes: setSpanAttributes } : void 0
|
|
17686
|
-
}) :
|
|
17909
|
+
}) : Promise.resolve(toolDef.execute(executionInput, {
|
|
17687
17910
|
experimental_context: sandbox,
|
|
17688
17911
|
...signal ? { signal } : void 0,
|
|
17689
17912
|
conversationPrivacy: effectiveConversationPrivacy,
|
|
17690
17913
|
toolCallId
|
|
17691
|
-
});
|
|
17914
|
+
})), signal);
|
|
17692
17915
|
const normalized = normalizeToolResult(result, {
|
|
17693
17916
|
requireStructuredResult: Boolean(toolDef.outputSchema),
|
|
17694
17917
|
toolName
|
|
@@ -18068,17 +18291,24 @@ function clientAllowsRedirectUri(clientInformation, callbackUrl) {
|
|
|
18068
18291
|
if (!Array.isArray(redirectUris)) return true;
|
|
18069
18292
|
return redirectUris.includes(callbackUrl);
|
|
18070
18293
|
}
|
|
18294
|
+
function requireEnv(name) {
|
|
18295
|
+
const value = process.env[name]?.trim();
|
|
18296
|
+
if (!value) throw new Error(`MCP OAuth client env var ${name} is unset`);
|
|
18297
|
+
return value;
|
|
18298
|
+
}
|
|
18071
18299
|
var StateBackedMcpOAuthClientProvider = class {
|
|
18072
18300
|
authSessionId;
|
|
18073
18301
|
callbackUrl;
|
|
18074
18302
|
sessionContext;
|
|
18075
18303
|
runCredentialMutation;
|
|
18304
|
+
oauthClient;
|
|
18076
18305
|
clientMetadata;
|
|
18077
|
-
constructor(authSessionId, callbackUrl, sessionContext, runCredentialMutation) {
|
|
18306
|
+
constructor(authSessionId, callbackUrl, sessionContext, runCredentialMutation, oauthClient) {
|
|
18078
18307
|
this.authSessionId = authSessionId;
|
|
18079
18308
|
this.callbackUrl = callbackUrl;
|
|
18080
18309
|
this.sessionContext = sessionContext;
|
|
18081
18310
|
this.runCredentialMutation = runCredentialMutation;
|
|
18311
|
+
this.oauthClient = oauthClient;
|
|
18082
18312
|
this.clientMetadata = createClientMetadata(callbackUrl);
|
|
18083
18313
|
}
|
|
18084
18314
|
get redirectUrl() {
|
|
@@ -18088,6 +18318,10 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
18088
18318
|
return this.authSessionId;
|
|
18089
18319
|
}
|
|
18090
18320
|
async clientInformation() {
|
|
18321
|
+
if (this.oauthClient) return {
|
|
18322
|
+
client_id: requireEnv(this.oauthClient.clientIdEnv),
|
|
18323
|
+
client_secret: requireEnv(this.oauthClient.clientSecretEnv)
|
|
18324
|
+
};
|
|
18091
18325
|
const session = await this.getCredentialContext();
|
|
18092
18326
|
const clientInformation = (await getMcpStoredOAuthCredentials(session.userId, session.provider))?.clientInformation;
|
|
18093
18327
|
if (!clientInformation) return;
|
|
@@ -18118,6 +18352,8 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
18118
18352
|
});
|
|
18119
18353
|
}
|
|
18120
18354
|
async redirectToAuthorization(authorizationUrl) {
|
|
18355
|
+
if (this.oauthClient?.scope) authorizationUrl.searchParams.set("scope", this.oauthClient.scope);
|
|
18356
|
+
for (const [key, value] of Object.entries(this.oauthClient?.authorizeParams ?? {})) authorizationUrl.searchParams.set(key, value);
|
|
18121
18357
|
const existing = await getMcpAuthSession(this.authSessionId);
|
|
18122
18358
|
if (existing?.authorizationUrl && existing.authorizationUrl !== authorizationUrl.toString()) throw new Error("MCP OAuth authorization attempt is already initialized");
|
|
18123
18359
|
await this.ensureSession({ authorizationUrl: authorizationUrl.toString() });
|
|
@@ -18211,7 +18447,7 @@ function requirePluginWithMcp(provider) {
|
|
|
18211
18447
|
}
|
|
18212
18448
|
/** Create one immutable provider authorization attempt for the active turn. */
|
|
18213
18449
|
async function createMcpOAuthClientProvider(input) {
|
|
18214
|
-
requirePluginWithMcp(input.provider);
|
|
18450
|
+
const plugin = requirePluginWithMcp(input.provider);
|
|
18215
18451
|
const baseUrl = resolveBaseUrl();
|
|
18216
18452
|
if (!baseUrl) throw new Error("Cannot determine base URL (set JUNIOR_BASE_URL or deploy to Vercel)");
|
|
18217
18453
|
return new StateBackedMcpOAuthClientProvider(input.createAuthorizationState ? await input.createAuthorizationState() : randomUUID(), `${baseUrl}${getMcpOAuthCallbackPath(input.provider)}`, {
|
|
@@ -18226,7 +18462,7 @@ async function createMcpOAuthClientProvider(input) {
|
|
|
18226
18462
|
...input.threadTs ? { threadTs: input.threadTs } : void 0,
|
|
18227
18463
|
...input.toolChannelId ? { toolChannelId: input.toolChannelId } : void 0,
|
|
18228
18464
|
...input.configuration ? { configuration: input.configuration } : void 0
|
|
18229
|
-
});
|
|
18465
|
+
}, void 0, plugin.manifest.mcp?.oauthClient);
|
|
18230
18466
|
}
|
|
18231
18467
|
/** Exchange a callback code while guarding every shared credential mutation. */
|
|
18232
18468
|
async function finalizeMcpAuthorization(provider, authSessionId, authorizationCode, runCredentialMutation) {
|
|
@@ -18237,7 +18473,7 @@ async function finalizeMcpAuthorization(provider, authSessionId, authorizationCo
|
|
|
18237
18473
|
if (session.provider !== provider) throw new Error(`MCP auth session provider mismatch: expected "${provider}", got "${session.provider}"`);
|
|
18238
18474
|
const baseUrl = resolveBaseUrl();
|
|
18239
18475
|
if (!baseUrl) throw new Error("Cannot determine base URL (set JUNIOR_BASE_URL or deploy to Vercel)");
|
|
18240
|
-
const authProvider = new StateBackedMcpOAuthClientProvider(authSessionId, `${baseUrl}${getMcpOAuthCallbackPath(provider)}`, void 0, runCredentialMutation);
|
|
18476
|
+
const authProvider = new StateBackedMcpOAuthClientProvider(authSessionId, `${baseUrl}${getMcpOAuthCallbackPath(provider)}`, void 0, runCredentialMutation, mcp.oauthClient);
|
|
18241
18477
|
const headers = mcp.headers ? resolvePluginHeaderEnvRefs(provider, mcp.headers, "MCP header") : void 0;
|
|
18242
18478
|
let providerStatus;
|
|
18243
18479
|
const transport = new StreamableHTTPClientTransport(new URL(mcp.url), {
|
|
@@ -21476,7 +21712,7 @@ function createAgentRunner(execute, options) {
|
|
|
21476
21712
|
} } : void 0
|
|
21477
21713
|
};
|
|
21478
21714
|
if (run.instruction.storedAttachments?.length) {
|
|
21479
|
-
const { loadInputImages } = await import("./images-
|
|
21715
|
+
const { loadInputImages } = await import("./images-BdG7zcNf.js").then((n) => n.n);
|
|
21480
21716
|
const storage = nextRun.environment?.attachmentStorage;
|
|
21481
21717
|
if (!storage) throw new Error("Attachment storage is unavailable.");
|
|
21482
21718
|
nextRun.instruction = {
|
|
@@ -21527,4 +21763,4 @@ async function runAgentWithTimeout(agentRunner, run, timeoutMs) {
|
|
|
21527
21763
|
}
|
|
21528
21764
|
}
|
|
21529
21765
|
//#endregion
|
|
21530
|
-
export {
|
|
21766
|
+
export { resolveTaskOutcomes as $, startConversationWork as $t, requestAttachmentDeletion as A, postSlackMessage as An, appendAndEnqueueExclusiveInboundMessage as At, scheduledAutomationRunAttributes as B, shouldEmitDevAgentTrace as Bn, deadLetterAttempt as Bt, isExperimentalFeatureEnabled as C, escapeSlackMrkdwnText as Cn, ingestEvent as Ct, renderBlockText as D, slackMention as Dn, eventGuidance as Dt, renderAttachmentText as E, normalizeSlackStatusText as En, getEventCatalog as Et, resolveSlackChannelIdFromThreadId as F, buildSteeringPiMessage as Fn, clearConsumedConversationWake as Ft, saveScheduledAutomation as G, hasRunnableConversationWork as Gt, listScheduledAutomationsForTeam as H, setConfigDefaults as Hn, ensureConversationWake as Ht, getConversationInfo as I, RetryableDeliveryError as In, clearExpiredConversationLease as It, withScheduledAutomationLock as J, recordConversationRetry as Jt, saveScheduledAutomationInLock as K, listActiveConversationIds as Kt, listThreadReplies as L, actorFromRun as Ln, completeConversationStop as Lt, parseSlackThreadId as M, slackEntitySchema as Mn, beginConversationResume as Mt, readSlackRawMessageContext as N, slackExternalRefIdSchema as Nn, cancelHumanFacingPendingMessages as Nt, collectAttachmentGarbage as O, truncateStatusText as On, pluginEventCatalog as Ot, resolveSlackChannelIdFromMessage as P, createUserTokenStore as Pn, checkInConversationWork as Pt, effectiveTaskOutcomes as Q, requestConversationWork as Qt, editScheduledAutomation as R, toolInvocationDestination as Rn, completeConversationWork as Rt, getExperimentalFeatures as S, startOAuthFlow as Sn, processWorkspaceSnapshotJob as St, lookupSlackUserProfile as T, normalizeSlackReplyMarkdown as Tn, isEventMailboxMetadata as Tt, parseScheduledAutomationRow as U, getConversation as Ut, listScheduledAutomations as V, getConfigDefaults as Vn, drainConversationMailbox as Vt, readScheduledAutomation as W, getConversationWorkState as Wt, AutomationEditError as X, removeActiveConversation as Xt, editEventAutomation as Y, releaseConversationWork as Yt, eventAutomationTriggerAvailable as Z, requestAnotherSlice as Zt, resolvePluginOAuthAccount as _, parseSandboxEgressCredentialToken as _n, agentInvocationSchema as _t, executeCredentialedEgressRequest as a, isFinalAttempt as an, listDeletedEventAutomationsCreatedBy as at, unpublishedArtifactHeaders as b, parseOAuthStatePayload as bn, AgentInvocationLimitError as bt, deleteMcpAuthSessionsForUserProvider as c, maybePostAutomatedTurnLimitNotice as cn, setEventAutomationStatus as ct, getMcpAuthSession as d, normalizeSandboxEgressTracePropagationDomains as dn, readAutomationVersion as dt, stopConversationWork as en, collectEventAutomationMatchKeys as et, getMcpStoredOAuthCredentials as f, shouldPropagateSandboxEgressTrace as fn, sameDefinitionValue as ft, readStats as g, consumeSandboxEgressPermissionDeniedSignal as gn, agentBindingSchema as gt, latestProgressStatus as h, consumeSandboxEgressAuthRequiredSignal as hn, requireAutomationRevision as ht, createContextCompactor as i, hasRunnableConversationWork$1 as in, getEventAutomation as it, storeAttachment as j, removeReactionFromMessage as jn, appendAndEnqueueInboundMessage as jt, readLiveAttachment as k, addReactionToMessage as kn, ackMessages as kt, deleteMcpServerSessionId as l, recordFinishedTurnForAutomatedLimit as ln, automationDefinition as lt, PluginCredentialFailureError as m, clearSandboxEgressSignals as mn, automationRevision as mt, runAgentWithTimeout as n, CONVERSATION_WORK_STALE_ENQUEUE_MS as nn, eventAutomationBelongsToUser as nt, finalizeMcpAuthorization as o, isInvalidConversationRecordError as on, parseEventAutomationRow as ot, putMcpStoredOAuthCredentials as p, SANDBOX_EGRESS_PROXY_PATH as pn, AutomationConflictError as pt, scheduledRunId as q, recordAttemptFailure as qt, executeAgentRun as r, hasConversationStop as rn, findMatchingEventAutomations as rt, deleteMcpAuthSession as s, renderTaskInput as sn, saveEventAutomation as st, createAgentRunner as t, CONVERSATION_WORK_CHECK_IN_INTERVAL_MS as tn, deleteEventAutomation as tt, deleteMcpStoredOAuthCredentials as u, resolveSandboxEgressProviderForHost as un, listAutomationVersions as ut, publicArtifactHeaders as v, sandboxEgressSignalsResponseSchema as vn, createAgentInvocationSchema as vt, setExperimentalFeatures as w, formatSlackLink as wn, EVENT_WAIT_MS as wt, experimental_exports as x, resolveBaseUrl as xn, getMcpProviderErrorAttributes as xt, readPublicArtifact as y, formatProviderLabel as yn, AgentInvocationBusyError as yt, logScheduledAutomationRunSkipped as z, AuthorizationFlowDisabledError as zn, countPendingConversationMessages as zt };
|