@sentry/junior 0.252.0 → 0.254.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{admin-C_-XEdym.js → admin-D7kYbu5l.js} +1 -1
- package/dist/{agent-hooks-DcoKnnxn.js → agent-hooks-DfPubHYm.js} +9 -9
- package/dist/{agent-invocations-D_YoNnAn.js → agent-invocations-BY60iNw-.js} +0 -4
- package/dist/{agent-runner-B-7S_DCS.js → agent-runner-BWmnJ0dD.js} +21 -21
- package/dist/api/schema.js +1 -1
- package/dist/api.js +23 -23
- package/dist/app.js +113 -83
- package/dist/{assistant-reply-DbPLvsnL.js → assistant-reply-B3J6ogAM.js} +1 -1
- package/dist/{briefs-D4SMqc-r.js → briefs-B_fgUFD2.js} +2 -2
- package/dist/{catalog-runtime-BQQiwwA7.js → catalog-runtime-TG5WF66H.js} +1 -1
- package/dist/cli/chat.js +15 -15
- package/dist/cli/check.js +3 -3
- package/dist/cli/main.js +2 -2
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +3 -3
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-ROZeVjq0.js → client-oBgOmQV6.js} +2 -2
- package/dist/{config-DNNkxfGS.js → config-CRlLncIj.js} +2 -2
- package/dist/{connections-DJV6mLrH.js → connections-BZAuDnYm.js} +9 -9
- package/dist/{conversation-privacy-B19umzIL.js → conversation-privacy-Dui3hTO-.js} +1 -1
- package/dist/{credential-sync-CEd2F5PS.js → credential-sync-9HiSpphh.js} +14 -14
- package/dist/{executor-_4bdoCxe.js → executor-B88oEqok.js} +41 -92
- package/dist/{images-BAN7DHuO.js → images-k8HewSp_.js} +2 -2
- package/dist/instrumentation.js +2 -2
- package/dist/{job-queue-DSQx1qFY.js → job-queue-B6KaQXY6.js} +1 -1
- package/dist/{logging-COUsTFIL.js → logging-B3nJLXT7.js} +1 -1
- package/dist/{message-CtDDEwwV.js → message-C9Wx3Rxx.js} +3 -3
- package/dist/nitro.js +3 -3
- package/dist/{oauth-callback-server-CCiKrS0s.js → oauth-callback-server-CetsCZng.js} +2 -2
- package/dist/{pending-auth-DDx3EU4M.js → pending-auth-m8aJlwP_.js} +2 -2
- package/dist/{profile-DP4LKL6V.js → profile-Dh73O6lZ.js} +4 -4
- package/dist/{registry-CeEpPna6.js → registry-C-jns0Be.js} +1 -1
- package/dist/{resolve-B5ma3igH.js → resolve-CDYCpS_U.js} +2 -2
- package/dist/{result-Da0RVuWG.js → result-sih-x_yN.js} +6 -6
- package/dist/{runner-se1W_jGZ.js → runner-CA43p74t.js} +9 -9
- package/dist/{sandbox-egress-signals-CS959-wm.js → sandbox-egress-signals-CxHHTu8e.js} +1 -1
- package/dist/{schema-C9Vnyb_f.js → schema-C-a9U34c.js} +1 -1
- package/dist/{session-stop-DlRDisF5.js → session-stop-DenN1GuJ.js} +11 -11
- package/dist/{skills-CSzgs0EC.js → skills-D_XDFkSx.js} +2 -2
- package/dist/{spawn-DT9fMjtd.js → spawn-CcWYt3Tl.js} +2 -2
- package/dist/{store-Dx1U69mm.js → store-CIs0Tr31.js} +6 -6
- package/dist/{task-queue-BX9YrIsw.js → task-queue-DAY-aQLX.js} +3 -3
- package/dist/{task-runner-CO55Olal.js → task-runner-BE6Jgt2u.js} +145 -127
- package/dist/{tasks-DwGlFX9i.js → tasks-DO9VM9cu.js} +15 -26
- package/dist/{thread-state-Ces6tXmB.js → thread-state-FreaCOZD.js} +7 -7
- package/dist/{turn-failure-response-B4VCvEQf.js → turn-failure-response-CJSt2ZSf.js} +7 -7
- package/dist/{turn-lifecycle-B1VV58Yo.js → turn-lifecycle-BXclEcfZ.js} +1 -1
- package/dist/{turn-session-routing-Dw2Kamg9.js → turn-session-routing-CItfUsjQ.js} +1 -1
- package/dist/{validation-yJF9LKOv.js → validation-MW8dmhF9.js} +1 -1
- package/dist/{version-CZYqvIFh.js → version-DcWD8xpq.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-D96vo_42.js → viewer-CGZiUVMU.js} +4 -13
- package/dist/{web-input-5mls-41-.js → web-input-Dpqh0oBt.js} +44 -52
- package/dist/{work-D2M2-zCO.js → work-DbA9xNO1.js} +9 -9
- package/dist/{worker-BwCpf8tB.js → worker-DuCs9-3G.js} +5 -5
- package/migrations/0056_automation_runs.sql +69 -0
- package/migrations/0057_drop_legacy_automation_tables.sql +10 -0
- package/migrations/meta/0056_snapshot.json +4280 -0
- package/migrations/meta/0057_snapshot.json +3618 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +5 -5
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { d as logException, f as logInfo, p as logWarn } from "./logging-
|
|
3
|
-
import { n as botConfig } from "./config-
|
|
4
|
-
import { f as getSqlExecutor, u as getConversationStore } from "./viewer-
|
|
5
|
-
import { s as juniorConversations } from "./agent-invocations-
|
|
6
|
-
import "./executor-
|
|
7
|
-
import { p as credentialSubjectSchema } from "./registry-
|
|
8
|
-
import { V as postSlackMessage, _t as isToolResultError, ht as isAssistantMessage, vt as isToolResultMessage, wt as ToolInputError, yt as normalizeToolNameFromResult } from "./tasks-
|
|
9
|
-
import { it as JUNIOR_THREAD_STATE_TTL_MS, rt as verifyTimerWatchCredentialSubject, u as getPlugins } from "./agent-hooks-
|
|
10
|
-
import { w as getStateAdapter } from "./profile-
|
|
11
|
-
import { r as sanitizeAssistantText } from "./assistant-reply-
|
|
2
|
+
import { d as logException, f as logInfo, p as logWarn } from "./logging-B3nJLXT7.js";
|
|
3
|
+
import { n as botConfig } from "./config-CRlLncIj.js";
|
|
4
|
+
import { f as getSqlExecutor, u as getConversationStore } from "./viewer-CGZiUVMU.js";
|
|
5
|
+
import { s as juniorConversations } from "./agent-invocations-BY60iNw-.js";
|
|
6
|
+
import "./executor-B88oEqok.js";
|
|
7
|
+
import { p as credentialSubjectSchema } from "./registry-C-jns0Be.js";
|
|
8
|
+
import { V as postSlackMessage, _t as isToolResultError, ht as isAssistantMessage, vt as isToolResultMessage, wt as ToolInputError, yt as normalizeToolNameFromResult } from "./tasks-DO9VM9cu.js";
|
|
9
|
+
import { it as JUNIOR_THREAD_STATE_TTL_MS, rt as verifyTimerWatchCredentialSubject, u as getPlugins } from "./agent-hooks-DfPubHYm.js";
|
|
10
|
+
import { w as getStateAdapter } from "./profile-Dh73O6lZ.js";
|
|
11
|
+
import { r as sanitizeAssistantText } from "./assistant-reply-B3J6ogAM.js";
|
|
12
12
|
import { r as EVENT_AUTHOR_ID } from "./prompt-C04mP1hu.js";
|
|
13
|
-
import { r as appendAndEnqueueInboundMessage } from "./store-
|
|
13
|
+
import { r as appendAndEnqueueInboundMessage } from "./store-CIs0Tr31.js";
|
|
14
14
|
import { z } from "zod";
|
|
15
15
|
import { eq, inArray } from "drizzle-orm";
|
|
16
16
|
import { eventMatchSchema, normalizeEventIdentifier, objectTypeSchema } from "@sentry/junior-plugin-api";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { p as logWarn } from "./logging-
|
|
2
|
+
import { p as logWarn } from "./logging-B3nJLXT7.js";
|
|
3
3
|
import { s as skillRoots } from "./package-discovery-BVvSnQBB.js";
|
|
4
|
-
import { n as pluginCatalogRuntime } from "./catalog-runtime-
|
|
4
|
+
import { n as pluginCatalogRuntime } from "./catalog-runtime-TG5WF66H.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import fs from "node:fs/promises";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { Ht as toolInvocationDestination, Vt as actorFromRun } from "./agent-runner-
|
|
3
|
-
import { n as createAndEnqueueAgentInvocation } from "./work-
|
|
2
|
+
import { Ht as toolInvocationDestination, Vt as actorFromRun } from "./agent-runner-BWmnJ0dD.js";
|
|
3
|
+
import { n as createAndEnqueueAgentInvocation } from "./work-DbA9xNO1.js";
|
|
4
4
|
//#region src/chat/agent-invocations/spawn.ts
|
|
5
5
|
var spawn_exports = /* @__PURE__ */ __exportAll({ bindSpawnAgent: () => bindSpawnAgent });
|
|
6
6
|
/** Bind a Run's Actor and credentials to new Agent invocations. */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-
|
|
2
|
-
import { i as getChatConfig } from "./config-
|
|
1
|
+
import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-B3nJLXT7.js";
|
|
2
|
+
import { i as getChatConfig } from "./config-CRlLncIj.js";
|
|
3
3
|
import { s as parseStoredSlackActor } from "./actor-BTtLaeWy.js";
|
|
4
|
-
import { F as sameDestination, N as parseDestination, u as getConversationStore } from "./viewer-
|
|
5
|
-
import { it as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-
|
|
6
|
-
import { C as getDefaultRedisStateAdapterFor, w as getStateAdapter } from "./profile-
|
|
7
|
-
import "./job-queue-
|
|
4
|
+
import { F as sameDestination, N as parseDestination, u as getConversationStore } from "./viewer-CGZiUVMU.js";
|
|
5
|
+
import { it as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-DfPubHYm.js";
|
|
6
|
+
import { C as getDefaultRedisStateAdapterFor, w as getStateAdapter } from "./profile-Dh73O6lZ.js";
|
|
7
|
+
import "./job-queue-B6KaQXY6.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
10
|
import { destinationSchema } from "@sentry/junior-plugin-api";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as logWarn } from "./logging-
|
|
2
|
-
import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as createVercelQueueClient, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-
|
|
1
|
+
import { p as logWarn } from "./logging-B3nJLXT7.js";
|
|
2
|
+
import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as createVercelQueueClient, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-B6KaQXY6.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { handleCallback, registerDevConsumer } from "@vercel/queue";
|
|
@@ -115,7 +115,7 @@ function pluginTaskCallback() {
|
|
|
115
115
|
maxDeliveries: PLUGIN_TASK_MAX_DELIVERIES,
|
|
116
116
|
onRejected: logPluginTaskQueueMessageRejected,
|
|
117
117
|
run: async (message) => {
|
|
118
|
-
const { processPluginTask } = await import("./task-runner-
|
|
118
|
+
const { processPluginTask } = await import("./task-runner-BE6Jgt2u.js").then((n) => n.r);
|
|
119
119
|
await processPluginTask(message);
|
|
120
120
|
},
|
|
121
121
|
topic: PLUGIN_TASK_QUEUE_TOPIC,
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { h as runBestEffort, p as logWarn } from "./logging-
|
|
2
|
+
import { h as runBestEffort, p as logWarn } from "./logging-B3nJLXT7.js";
|
|
3
3
|
import { g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
|
|
4
|
-
import { C as agentTurnTotalTokens, S as agentTurnCostUsd, d as getDb, r as readActorIdentity, u as getConversationStore } from "./viewer-
|
|
5
|
-
import { s as juniorConversations } from "./agent-invocations-
|
|
6
|
-
import {
|
|
4
|
+
import { C as agentTurnTotalTokens, S as agentTurnCostUsd, d as getDb, r as readActorIdentity, u as getConversationStore } from "./viewer-CGZiUVMU.js";
|
|
5
|
+
import { s as juniorConversations } from "./agent-invocations-BY60iNw-.js";
|
|
6
|
+
import { o as juniorAutomationRuns, s as juniorAutomations } from "./executor-B88oEqok.js";
|
|
7
7
|
import { m as sameActorIdentity } from "./history-9pO1Zd4Y.js";
|
|
8
|
-
import { p as credentialSubjectSchema } from "./registry-
|
|
9
|
-
import { Gt as hydrateConversationMessages, M as formatSlackLink, Q as getTurnRecord, V as postSlackMessage, Zt as fallbackShortTitle, _t as isToolResultError, a as readScheduledAutomation, g as getEventAutomation, j as escapeSlackMrkdwnText, mt as instructionTextForProjection, u as blockEventAutomation, ut as getPiMessageRole, vt as isToolResultMessage, xt as stripRuntimeTurnContext, yt as normalizeToolNameFromResult, z as openSlackDirectMessage } from "./tasks-
|
|
10
|
-
import { St as createPluginConversationEvents, dt as createPluginModel, ft as createPluginLogger, it as JUNIOR_THREAD_STATE_TTL_MS, lt as createPluginState, p as coreTaskRegistrations, st as getDashboardTaskLink, u as getPlugins, ut as createPluginEmbedder } from "./agent-hooks-
|
|
11
|
-
import { w as getStateAdapter } from "./profile-
|
|
12
|
-
import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-
|
|
13
|
-
import { t as resolveConversationRouting } from "./turn-session-routing-
|
|
14
|
-
import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-
|
|
8
|
+
import { p as credentialSubjectSchema } from "./registry-C-jns0Be.js";
|
|
9
|
+
import { Gt as hydrateConversationMessages, M as formatSlackLink, Q as getTurnRecord, V as postSlackMessage, Zt as fallbackShortTitle, _t as isToolResultError, a as readScheduledAutomation, g as getEventAutomation, j as escapeSlackMrkdwnText, mt as instructionTextForProjection, u as blockEventAutomation, ut as getPiMessageRole, vt as isToolResultMessage, xt as stripRuntimeTurnContext, yt as normalizeToolNameFromResult, z as openSlackDirectMessage } from "./tasks-DO9VM9cu.js";
|
|
10
|
+
import { St as createPluginConversationEvents, dt as createPluginModel, ft as createPluginLogger, it as JUNIOR_THREAD_STATE_TTL_MS, lt as createPluginState, p as coreTaskRegistrations, st as getDashboardTaskLink, u as getPlugins, ut as createPluginEmbedder } from "./agent-hooks-DfPubHYm.js";
|
|
11
|
+
import { w as getStateAdapter } from "./profile-Dh73O6lZ.js";
|
|
12
|
+
import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-FreaCOZD.js";
|
|
13
|
+
import { t as resolveConversationRouting } from "./turn-session-routing-CItfUsjQ.js";
|
|
14
|
+
import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-DAY-aQLX.js";
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
import { createHash } from "node:crypto";
|
|
17
|
-
import { and, asc, count, desc, eq, gte, inArray, lte, max,
|
|
17
|
+
import { and, asc, count, desc, eq, gte, inArray, isNotNull, lte, max, sql } from "drizzle-orm";
|
|
18
18
|
import { destinationSchema, destinationVisibilitySchema, isSlackDestination, pluginRunContextSchema, replyAttributionSchema, sourceSchema, taskOutcomeSchema } from "@sentry/junior-plugin-api";
|
|
19
19
|
//#region src/api/conversations/aggregate.ts
|
|
20
20
|
function usageTokenValue(source, field) {
|
|
@@ -100,12 +100,15 @@ function conversationActiveDaysColumn() {
|
|
|
100
100
|
}
|
|
101
101
|
//#endregion
|
|
102
102
|
//#region src/chat/automations/execution-stats.ts
|
|
103
|
-
const AUTOMATION_EXECUTION_TYPES = ["scheduled", "event"];
|
|
104
103
|
const AUTOMATION_EXECUTION_STATUSES = [
|
|
105
104
|
"blocked",
|
|
106
105
|
"completed",
|
|
107
106
|
"failed"
|
|
108
107
|
];
|
|
108
|
+
/** An execution is a run with an outcome. Skipped runs are not executions. */
|
|
109
|
+
function isExecution() {
|
|
110
|
+
return and(inArray(juniorAutomationRuns.status, [...AUTOMATION_EXECUTION_STATUSES]), isNotNull(juniorAutomationRuns.completedAtMs));
|
|
111
|
+
}
|
|
109
112
|
function addUsd(current, next) {
|
|
110
113
|
return Math.round((current + next) * 0xe8d4a51000) / 0xe8d4a51000;
|
|
111
114
|
}
|
|
@@ -138,60 +141,76 @@ function emptyStatusDay(date) {
|
|
|
138
141
|
failed: 0
|
|
139
142
|
};
|
|
140
143
|
}
|
|
141
|
-
/**
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Return the Conversation id when that Conversation exists, else null. A
|
|
146
|
+
* dispatch can end before it creates its Conversation, and the run's
|
|
147
|
+
* `conversation_id` is a foreign key.
|
|
148
|
+
*/
|
|
149
|
+
function existingConversationId(conversationId) {
|
|
150
|
+
return sql`(select ${juniorConversations.conversationId} from ${juniorConversations} where ${juniorConversations.conversationId} = ${conversationId})`;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Record the outcome of one Automation run. A run that already has an outcome
|
|
154
|
+
* keeps it. A failed write is logged, and the heartbeat settles a started
|
|
155
|
+
* event run later.
|
|
156
|
+
*/
|
|
157
|
+
async function recordAutomationExecution(automationId, options) {
|
|
144
158
|
const nowMs = options.nowMs ?? Date.now();
|
|
145
159
|
const status = options.status ?? "completed";
|
|
160
|
+
const outcome = {
|
|
161
|
+
completedAtMs: nowMs,
|
|
162
|
+
errorMessage: options.errorMessage ?? null,
|
|
163
|
+
status
|
|
164
|
+
};
|
|
146
165
|
try {
|
|
147
|
-
await getDb().insert(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
166
|
+
await getDb().insert(juniorAutomationRuns).values({
|
|
167
|
+
id: options.executionId,
|
|
168
|
+
automationId,
|
|
169
|
+
conversationId: options.conversationId ? existingConversationId(options.conversationId) : null,
|
|
170
|
+
...outcome
|
|
171
|
+
}).onConflictDoUpdate({
|
|
172
|
+
target: juniorAutomationRuns.id,
|
|
173
|
+
set: {
|
|
174
|
+
...outcome,
|
|
175
|
+
conversationId: sql`coalesce(${juniorAutomationRuns.conversationId}, excluded.conversation_id)`
|
|
176
|
+
},
|
|
177
|
+
setWhere: inArray(juniorAutomationRuns.status, ["pending", "running"])
|
|
178
|
+
});
|
|
160
179
|
} catch (error) {
|
|
161
180
|
logWarn("task.execution.stat_failed", {
|
|
162
181
|
error,
|
|
163
182
|
"app.task.execution.id": options.executionId,
|
|
164
|
-
"app.task.execution.namespace": namespace,
|
|
165
183
|
"app.task.execution.status": status,
|
|
166
|
-
"app.task.execution.task_id": automationId
|
|
167
|
-
"app.task.execution.type": type
|
|
184
|
+
"app.task.execution.task_id": automationId
|
|
168
185
|
});
|
|
169
186
|
}
|
|
170
187
|
}
|
|
171
|
-
/** Load usage analytics for
|
|
172
|
-
async function readAutomationExecutionSummaries(
|
|
188
|
+
/** Load usage analytics for the given automations. */
|
|
189
|
+
async function readAutomationExecutionSummaries(automationIds, options = {}) {
|
|
190
|
+
if (automationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
173
191
|
const nowMs = options.nowMs ?? Date.now();
|
|
174
192
|
const oneDayAgoMs = nowMs - 864e5;
|
|
175
193
|
const sevenDaysAgoMs = nowMs - 6048e5;
|
|
176
194
|
const thirtyDaysAgoMs = nowMs - 2592e6;
|
|
177
195
|
const ninetyDaysAgoMs = nowMs - 7776e6;
|
|
178
196
|
const db = getDb();
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
197
|
+
const selected = and(isExecution(), inArray(juniorAutomationRuns.automationId, automationIds));
|
|
198
|
+
const latest = db.selectDistinctOn([juniorAutomationRuns.automationId], {
|
|
199
|
+
status: juniorAutomationRuns.status,
|
|
200
|
+
conversationId: juniorAutomationRuns.conversationId,
|
|
201
|
+
automationId: juniorAutomationRuns.automationId
|
|
202
|
+
}).from(juniorAutomationRuns).where(selected).orderBy(juniorAutomationRuns.automationId, desc(juniorAutomationRuns.completedAtMs), desc(juniorAutomationRuns.id)).as("latest_task_execution");
|
|
184
203
|
const rows = await db.select({
|
|
185
204
|
lastRunStatus: latest.status,
|
|
186
205
|
lastConversationId: latest.conversationId,
|
|
187
|
-
lastExecutedAtMs: max(
|
|
188
|
-
runsLast1Day: sql`count(*) filter (where ${
|
|
189
|
-
runsLast7Days: sql`count(*) filter (where ${
|
|
190
|
-
runsLast30Days: sql`count(*) filter (where ${
|
|
191
|
-
runsLast90Days: sql`count(*) filter (where ${
|
|
192
|
-
automationId:
|
|
206
|
+
lastExecutedAtMs: max(juniorAutomationRuns.completedAtMs),
|
|
207
|
+
runsLast1Day: sql`count(*) filter (where ${juniorAutomationRuns.completedAtMs} >= ${oneDayAgoMs})::int`,
|
|
208
|
+
runsLast7Days: sql`count(*) filter (where ${juniorAutomationRuns.completedAtMs} >= ${sevenDaysAgoMs})::int`,
|
|
209
|
+
runsLast30Days: sql`count(*) filter (where ${juniorAutomationRuns.completedAtMs} >= ${thirtyDaysAgoMs})::int`,
|
|
210
|
+
runsLast90Days: sql`count(*) filter (where ${juniorAutomationRuns.completedAtMs} >= ${ninetyDaysAgoMs})::int`,
|
|
211
|
+
automationId: juniorAutomationRuns.automationId,
|
|
193
212
|
totalRuns: sql`count(*)::int`
|
|
194
|
-
}).from(
|
|
213
|
+
}).from(juniorAutomationRuns).innerJoin(latest, eq(latest.automationId, juniorAutomationRuns.automationId)).where(selected).groupBy(juniorAutomationRuns.automationId, latest.conversationId, latest.status);
|
|
195
214
|
return new Map(rows.map((row) => [row.automationId, {
|
|
196
215
|
lastRunStatus: row.lastRunStatus,
|
|
197
216
|
...row.lastConversationId ? { lastConversationId: row.lastConversationId } : void 0,
|
|
@@ -210,14 +229,13 @@ async function readAutomationExecutionDays(dayCount = 90, options = {}) {
|
|
|
210
229
|
const end = utcDate(options.nowMs ?? Date.now());
|
|
211
230
|
const endMs = Date.parse(`${end}T23:59:59.999Z`);
|
|
212
231
|
const startMs = Date.parse(`${end}T00:00:00.000Z`) - (dayCount - 1) * 864e5;
|
|
213
|
-
const executionDate = sql`to_char(to_timestamp(${
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}).from(juniorAutomationExecutions).leftJoin(juniorConversations, eq(juniorConversations.conversationId, juniorAutomationExecutions.conversationId)).where(and(gte(juniorAutomationExecutions.executedAtMs, startMs), lte(juniorAutomationExecutions.executedAtMs, endMs), eq(juniorAutomationExecutions.status, "completed"), options.access)).groupBy(executionDate, juniorAutomationExecutions.kind).orderBy(asc(executionDate), asc(juniorAutomationExecutions.kind));
|
|
232
|
+
const executionDate = sql`to_char(to_timestamp(${juniorAutomationRuns.completedAtMs} / 1000.0) at time zone 'UTC', 'YYYY-MM-DD')`;
|
|
233
|
+
const rows = await readCompletedExecutionBuckets({
|
|
234
|
+
access: options.access,
|
|
235
|
+
bucket: executionDate,
|
|
236
|
+
endMs,
|
|
237
|
+
startMs
|
|
238
|
+
});
|
|
221
239
|
const byDate = /* @__PURE__ */ new Map();
|
|
222
240
|
for (let offset = 0; offset < dayCount; offset += 1) {
|
|
223
241
|
const date = utcDate(startMs + offset * 864e5);
|
|
@@ -239,14 +257,13 @@ async function readAutomationExecutionHours(hourCount = 168, options = {}) {
|
|
|
239
257
|
end.setUTCMinutes(0, 0, 0);
|
|
240
258
|
const endMs = end.getTime() + 3599999;
|
|
241
259
|
const startMs = end.getTime() - (hourCount - 1) * 36e5;
|
|
242
|
-
const executionHour = sql`to_char(to_timestamp(${
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}).from(juniorAutomationExecutions).leftJoin(juniorConversations, eq(juniorConversations.conversationId, juniorAutomationExecutions.conversationId)).where(and(gte(juniorAutomationExecutions.executedAtMs, startMs), lte(juniorAutomationExecutions.executedAtMs, endMs), eq(juniorAutomationExecutions.status, "completed"), options.access)).groupBy(executionHour, juniorAutomationExecutions.kind).orderBy(asc(executionHour), asc(juniorAutomationExecutions.kind));
|
|
260
|
+
const executionHour = sql`to_char(to_timestamp(${juniorAutomationRuns.completedAtMs} / 1000.0) at time zone 'UTC', 'YYYY-MM-DD"T"HH24')`;
|
|
261
|
+
const rows = await readCompletedExecutionBuckets({
|
|
262
|
+
access: options.access,
|
|
263
|
+
bucket: executionHour,
|
|
264
|
+
endMs,
|
|
265
|
+
startMs
|
|
266
|
+
});
|
|
250
267
|
const byHour = /* @__PURE__ */ new Map();
|
|
251
268
|
for (let offset = 0; offset < hourCount; offset += 1) {
|
|
252
269
|
const date = new Date(startMs + offset * 36e5).toISOString().slice(0, 13);
|
|
@@ -261,82 +278,75 @@ async function readAutomationExecutionHours(hourCount = 168, options = {}) {
|
|
|
261
278
|
}
|
|
262
279
|
return [...byHour.values()];
|
|
263
280
|
}
|
|
264
|
-
/**
|
|
281
|
+
/** Count completed executions and their cost per time bucket and kind. */
|
|
282
|
+
async function readCompletedExecutionBuckets(args) {
|
|
283
|
+
const conversationCost = conversationUsageCostExpr(juniorConversations.usage);
|
|
284
|
+
return await getDb().select({
|
|
285
|
+
count: count(),
|
|
286
|
+
costUsd: sql`SUM(${conversationCost})::double precision`,
|
|
287
|
+
date: args.bucket,
|
|
288
|
+
kind: juniorAutomations.kind
|
|
289
|
+
}).from(juniorAutomationRuns).innerJoin(juniorAutomations, eq(juniorAutomations.id, juniorAutomationRuns.automationId)).leftJoin(juniorConversations, eq(juniorConversations.conversationId, juniorAutomationRuns.conversationId)).where(and(gte(juniorAutomationRuns.completedAtMs, args.startMs), lte(juniorAutomationRuns.completedAtMs, args.endMs), eq(juniorAutomationRuns.status, "completed"), args.access)).groupBy(args.bucket, juniorAutomations.kind).orderBy(asc(args.bucket), asc(juniorAutomations.kind));
|
|
290
|
+
}
|
|
291
|
+
/** Load the Automation run linked to one conversation, if any. */
|
|
265
292
|
async function readAutomationExecutionByConversationId(args) {
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (!row) return void 0;
|
|
272
|
-
if (row.kind !== "scheduled" && row.kind !== "event") return void 0;
|
|
273
|
-
return {
|
|
274
|
-
kind: row.kind,
|
|
275
|
-
automationId: row.automationId
|
|
276
|
-
};
|
|
293
|
+
const [row] = await getDb().select({
|
|
294
|
+
kind: juniorAutomations.kind,
|
|
295
|
+
automationId: juniorAutomationRuns.automationId
|
|
296
|
+
}).from(juniorAutomationRuns).innerJoin(juniorAutomations, eq(juniorAutomations.id, juniorAutomationRuns.automationId)).where(eq(juniorAutomationRuns.conversationId, args.conversationId)).limit(1);
|
|
297
|
+
return row;
|
|
277
298
|
}
|
|
278
299
|
/**
|
|
279
300
|
* Load the display name of the Automation linked to each untitled
|
|
280
|
-
* conversation.
|
|
281
|
-
*
|
|
282
|
-
*
|
|
301
|
+
* conversation. Like the Automation list, the name falls back to the first
|
|
302
|
+
* line of the instruction. Titled conversations and conversations without a
|
|
303
|
+
* linked Automation are absent from the result.
|
|
283
304
|
*/
|
|
284
305
|
async function readAutomationTitlesByConversationId(conversations) {
|
|
285
306
|
const titles = /* @__PURE__ */ new Map();
|
|
286
307
|
const untitledIds = conversations.flatMap((conversation) => conversation.title ? [] : [conversation.conversationId]);
|
|
287
308
|
if (untitledIds.length === 0) return titles;
|
|
288
309
|
const rows = await getDb().select({
|
|
289
|
-
conversationId:
|
|
310
|
+
conversationId: juniorAutomationRuns.conversationId,
|
|
290
311
|
instruction: juniorAutomations.instruction,
|
|
291
312
|
title: juniorAutomations.title
|
|
292
|
-
}).from(
|
|
293
|
-
const seen = /* @__PURE__ */ new Set();
|
|
313
|
+
}).from(juniorAutomationRuns).innerJoin(juniorAutomations, eq(juniorAutomations.id, juniorAutomationRuns.automationId)).where(inArray(juniorAutomationRuns.conversationId, untitledIds));
|
|
294
314
|
for (const row of rows) {
|
|
295
|
-
if (!row.conversationId || seen.has(row.conversationId)) continue;
|
|
296
|
-
seen.add(row.conversationId);
|
|
297
315
|
const title = row.title?.trim() || fallbackShortTitle(row.instruction, "");
|
|
298
|
-
if (title) titles.set(row.conversationId, title);
|
|
316
|
+
if (row.conversationId && title) titles.set(row.conversationId, title);
|
|
299
317
|
}
|
|
300
318
|
return titles;
|
|
301
319
|
}
|
|
302
320
|
/** Load newest-first executions for one automation, with conversation titles when present. */
|
|
303
321
|
async function readAutomationExecutions(args) {
|
|
304
|
-
const namespace = args.namespace ?? "junior";
|
|
305
322
|
return (await getDb().select({
|
|
306
|
-
conversationId:
|
|
323
|
+
conversationId: juniorAutomationRuns.conversationId,
|
|
307
324
|
durationMs: juniorConversations.durationMs,
|
|
308
|
-
executedAtMs:
|
|
309
|
-
executionId:
|
|
310
|
-
status:
|
|
325
|
+
executedAtMs: juniorAutomationRuns.completedAtMs,
|
|
326
|
+
executionId: juniorAutomationRuns.id,
|
|
327
|
+
status: juniorAutomationRuns.status,
|
|
311
328
|
title: juniorConversations.title,
|
|
312
329
|
usage: juniorConversations.usage
|
|
313
|
-
}).from(
|
|
330
|
+
}).from(juniorAutomationRuns).leftJoin(juniorConversations, eq(juniorConversations.conversationId, juniorAutomationRuns.conversationId)).where(and(isExecution(), eq(juniorAutomationRuns.automationId, args.automationId))).orderBy(desc(juniorAutomationRuns.completedAtMs), desc(juniorAutomationRuns.id)).limit(args.limit)).map((row) => mapAutomationExecutionRecord(row));
|
|
314
331
|
}
|
|
315
|
-
/** Load newest-first executions for the supplied viewer-visible
|
|
332
|
+
/** Load newest-first executions for the supplied viewer-visible automations. */
|
|
316
333
|
async function readAutomationRuns(args) {
|
|
317
|
-
|
|
318
|
-
const conversationIds = [...new Set((args.conversationIds ?? []).filter((conversationId) => conversationId.trim().length > 0))];
|
|
319
|
-
if (automations.length === 0 && conversationIds.length === 0) return [];
|
|
320
|
-
const namespace = args.namespace ?? "junior";
|
|
321
|
-
const selectors = [...automations.map((task) => and(eq(juniorAutomationExecutions.kind, task.kind), eq(juniorAutomationExecutions.automationId, task.automationId))), ...conversationIds.length > 0 ? [inArray(juniorAutomationExecutions.conversationId, conversationIds)] : []];
|
|
334
|
+
if (args.automationIds.length === 0) return [];
|
|
322
335
|
return (await getDb().select({
|
|
323
|
-
conversationId:
|
|
336
|
+
conversationId: juniorAutomationRuns.conversationId,
|
|
324
337
|
durationMs: juniorConversations.durationMs,
|
|
325
|
-
executedAtMs:
|
|
326
|
-
executionId:
|
|
327
|
-
kind:
|
|
328
|
-
status:
|
|
329
|
-
automationId:
|
|
338
|
+
executedAtMs: juniorAutomationRuns.completedAtMs,
|
|
339
|
+
executionId: juniorAutomationRuns.id,
|
|
340
|
+
kind: juniorAutomations.kind,
|
|
341
|
+
status: juniorAutomationRuns.status,
|
|
342
|
+
automationId: juniorAutomationRuns.automationId,
|
|
330
343
|
title: juniorConversations.title,
|
|
331
344
|
usage: juniorConversations.usage
|
|
332
|
-
}).from(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
automationId: row.automationId
|
|
338
|
-
}];
|
|
339
|
-
});
|
|
345
|
+
}).from(juniorAutomationRuns).innerJoin(juniorAutomations, eq(juniorAutomations.id, juniorAutomationRuns.automationId)).leftJoin(juniorConversations, eq(juniorConversations.conversationId, juniorAutomationRuns.conversationId)).where(and(isExecution(), inArray(juniorAutomationRuns.automationId, args.automationIds))).orderBy(desc(juniorAutomationRuns.completedAtMs), desc(juniorAutomationRuns.id)).limit(args.limit)).map((row) => ({
|
|
346
|
+
...mapAutomationExecutionRecord(row),
|
|
347
|
+
kind: row.kind,
|
|
348
|
+
automationId: row.automationId
|
|
349
|
+
}));
|
|
340
350
|
}
|
|
341
351
|
function mapAutomationExecutionRecord(row) {
|
|
342
352
|
const title = row.title?.trim();
|
|
@@ -357,16 +367,16 @@ function mapAutomationExecutionRecord(row) {
|
|
|
357
367
|
/** Load a fixed trailing window of terminal executions for one automation by status. */
|
|
358
368
|
async function readAutomationExecutionStatusDays(args) {
|
|
359
369
|
const dayCount = args.dayCount ?? 90;
|
|
360
|
-
const namespace = args.namespace ?? "junior";
|
|
361
370
|
const end = utcDate(args.nowMs ?? Date.now());
|
|
362
371
|
const endMs = Date.parse(`${end}T23:59:59.999Z`);
|
|
363
372
|
const startMs = Date.parse(`${end}T00:00:00.000Z`) - (dayCount - 1) * 864e5;
|
|
364
|
-
const executionDate = sql`to_char(to_timestamp(${
|
|
365
|
-
const rows = await
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
373
|
+
const executionDate = sql`to_char(to_timestamp(${juniorAutomationRuns.completedAtMs} / 1000.0) at time zone 'UTC', 'YYYY-MM-DD')`;
|
|
374
|
+
const rows = await readExecutionStatusBuckets({
|
|
375
|
+
automationId: args.automationId,
|
|
376
|
+
bucket: executionDate,
|
|
377
|
+
endMs,
|
|
378
|
+
startMs
|
|
379
|
+
});
|
|
370
380
|
const byDate = /* @__PURE__ */ new Map();
|
|
371
381
|
for (let offset = 0; offset < dayCount; offset += 1) {
|
|
372
382
|
const date = utcDate(startMs + offset * 864e5);
|
|
@@ -384,18 +394,18 @@ async function readAutomationExecutionStatusDays(args) {
|
|
|
384
394
|
/** Load a fixed trailing window of terminal executions for one automation by hour. */
|
|
385
395
|
async function readAutomationExecutionStatusHours(args) {
|
|
386
396
|
const hourCount = args.hourCount ?? 168;
|
|
387
|
-
const namespace = args.namespace ?? "junior";
|
|
388
397
|
const nowMs = args.nowMs ?? Date.now();
|
|
389
398
|
const end = new Date(nowMs);
|
|
390
399
|
end.setUTCMinutes(0, 0, 0);
|
|
391
400
|
const endMs = end.getTime() + 3599999;
|
|
392
401
|
const startMs = end.getTime() - (hourCount - 1) * 36e5;
|
|
393
|
-
const executionHour = sql`to_char(to_timestamp(${
|
|
394
|
-
const rows = await
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
402
|
+
const executionHour = sql`to_char(to_timestamp(${juniorAutomationRuns.completedAtMs} / 1000.0) at time zone 'UTC', 'YYYY-MM-DD"T"HH24')`;
|
|
403
|
+
const rows = await readExecutionStatusBuckets({
|
|
404
|
+
automationId: args.automationId,
|
|
405
|
+
bucket: executionHour,
|
|
406
|
+
endMs,
|
|
407
|
+
startMs
|
|
408
|
+
});
|
|
399
409
|
const byHour = /* @__PURE__ */ new Map();
|
|
400
410
|
for (let offset = 0; offset < hourCount; offset += 1) {
|
|
401
411
|
const date = new Date(startMs + offset * 36e5).toISOString().slice(0, 13);
|
|
@@ -410,6 +420,14 @@ async function readAutomationExecutionStatusHours(args) {
|
|
|
410
420
|
}
|
|
411
421
|
return [...byHour.values()];
|
|
412
422
|
}
|
|
423
|
+
/** Count one automation's executions per time bucket and status. */
|
|
424
|
+
async function readExecutionStatusBuckets(args) {
|
|
425
|
+
return await getDb().select({
|
|
426
|
+
count: count(),
|
|
427
|
+
date: args.bucket,
|
|
428
|
+
status: juniorAutomationRuns.status
|
|
429
|
+
}).from(juniorAutomationRuns).where(and(isExecution(), eq(juniorAutomationRuns.automationId, args.automationId), gte(juniorAutomationRuns.completedAtMs, args.startMs), lte(juniorAutomationRuns.completedAtMs, args.endMs))).groupBy(args.bucket, juniorAutomationRuns.status).orderBy(asc(args.bucket), asc(juniorAutomationRuns.status));
|
|
430
|
+
}
|
|
413
431
|
//#endregion
|
|
414
432
|
//#region src/chat/automations/blocked-notice.ts
|
|
415
433
|
function buildBlockedNoticeText(automationId, title, reason) {
|
|
@@ -686,9 +704,9 @@ async function recordEventAutomationExecution(previous, next, status) {
|
|
|
686
704
|
if (next.plugin !== "junior") return;
|
|
687
705
|
const eventAutomationId = next.metadata?.eventAutomationId;
|
|
688
706
|
if (!eventAutomationId) return;
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
707
|
+
await recordAutomationExecution(eventAutomationId, {
|
|
708
|
+
conversationId: getDispatchConversationId(next),
|
|
709
|
+
errorMessage: next.errorMessage,
|
|
692
710
|
executionId: next.id,
|
|
693
711
|
nowMs: next.updatedAtMs,
|
|
694
712
|
status
|
|
@@ -1019,4 +1037,4 @@ async function processPluginTask(message, options = {}) {
|
|
|
1019
1037
|
});
|
|
1020
1038
|
}
|
|
1021
1039
|
//#endregion
|
|
1022
|
-
export {
|
|
1040
|
+
export { readAutomationRuns as A, readAutomationExecutionByConversationId as C, readAutomationExecutionStatusHours as D, readAutomationExecutionStatusDays as E, conversationRangeColumns as F, recordAutomationExecution as M, conversationActiveDaysColumn as N, readAutomationExecutionSummaries as O, conversationAggregateColumns as P, existingConversationId as S, readAutomationExecutionHours as T, markDispatchCompleted as _, confirmDispatchMailboxAppend as a, notifyAutomationBlocked as b, getDispatchIdForConversation as c, getDispatchTurnId as d, getPluginDispatchProjection as f, markDispatchBlocked as g, markDispatchAwaitingResume as h, claimDispatchMailboxAppend as i, readAutomationTitlesByConversationId as j, readAutomationExecutions as k, getDispatchInputMessageId as l, listPendingDispatchMailboxAppends as m, scheduleSessionCompletedPluginTasks as n, createOrGetDispatch as o, isTerminalDispatchStatus as p, task_runner_exports as r, getDispatchConversationId as s, processPluginTask as t, getDispatchRecord as u, markDispatchFailed as v, readAutomationExecutionDays as w, emptyAutomationRunWindows as x, markDispatchRunning as y };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { d as unwrapCurrentInstruction, f as escapeXml, i as completeText, o as resolveGatewayModel } from "./client-
|
|
2
|
-
import { d as logException, o as getActiveTraceId, p as logWarn, s as getLogContextAttributes, t as buildTurnFailureResponse, v as setSpanAttributes } from "./logging-
|
|
1
|
+
import { d as unwrapCurrentInstruction, f as escapeXml, i as completeText, o as resolveGatewayModel } from "./client-oBgOmQV6.js";
|
|
2
|
+
import { d as logException, o as getActiveTraceId, p as logWarn, s as getLogContextAttributes, t as buildTurnFailureResponse, v as setSpanAttributes } from "./logging-B3nJLXT7.js";
|
|
3
3
|
import { n as captureMessage } from "./sentry-CgWZM_kV.js";
|
|
4
|
-
import { n as botConfig, v as normalizeSlackEmojiName } from "./config-
|
|
4
|
+
import { n as botConfig, v as normalizeSlackEmojiName } from "./config-CRlLncIj.js";
|
|
5
5
|
import { c as toStoredSlackActor, f as parseSlackUserId, g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
|
|
6
|
-
import { c as getConversationEventStore, f as getSqlExecutor, m as withConversationEventLock, p as createSqlConversationEventStore, u as getConversationStore, v as startLocationThread, x as addAgentTurnUsage, y as bindProviderConversation } from "./viewer-
|
|
7
|
-
import { a as
|
|
6
|
+
import { c as getConversationEventStore, f as getSqlExecutor, m as withConversationEventLock, p as createSqlConversationEventStore, u as getConversationStore, v as startLocationThread, x as addAgentTurnUsage, y as bindProviderConversation } from "./viewer-CGZiUVMU.js";
|
|
7
|
+
import { a as juniorAutomationVersions, o as juniorAutomationRuns, s as juniorAutomations } from "./executor-B88oEqok.js";
|
|
8
8
|
import { d as contextProvenance, f as instructionActors, n as agentHistoryItemSchema, p as instructionProvenanceFor } from "./history-9pO1Zd4Y.js";
|
|
9
|
-
import { p as credentialSubjectSchema } from "./registry-
|
|
10
|
-
import { $t as authenticationUnlinkedEvent, Gt as normalizeSlackConversationId, Ht as getSlackClient, Qt as authenticationLinkedEvent, Rt as SlackActionError, Xt as JUNIOR_NATIVE_EVENT_NAMESPACE, Zt as agentsInstructionsUpdatedEvent, n as applyPluginFormatMarkdown, qt as withSlackRetries } from "./agent-hooks-
|
|
9
|
+
import { p as credentialSubjectSchema } from "./registry-C-jns0Be.js";
|
|
10
|
+
import { $t as authenticationUnlinkedEvent, Gt as normalizeSlackConversationId, Ht as getSlackClient, Qt as authenticationLinkedEvent, Rt as SlackActionError, Xt as JUNIOR_NATIVE_EVENT_NAMESPACE, Zt as agentsInstructionsUpdatedEvent, n as applyPluginFormatMarkdown, qt as withSlackRetries } from "./agent-hooks-DfPubHYm.js";
|
|
11
11
|
import { G as messageCardRef } from "./conversation-T18Xlkx9.js";
|
|
12
|
-
import { D as fenceLock, O as withLock, T as MUTATION_LOCK_TTL_MS, k as sleep, w as getStateAdapter } from "./profile-
|
|
13
|
-
import { A as eventAutomationSchema,
|
|
12
|
+
import { D as fenceLock, O as withLock, T as MUTATION_LOCK_TTL_MS, k as sleep, w as getStateAdapter } from "./profile-Dh73O6lZ.js";
|
|
13
|
+
import { A as eventAutomationSchema, E as scheduledAutomationSchema, S as automationVersionSchema } from "./automation-gznOMaQ2.js";
|
|
14
14
|
import { isDeepStrictEqual } from "node:util";
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
import { createHash } from "node:crypto";
|
|
@@ -3240,28 +3240,17 @@ async function listScheduledAutomationsForTeam(db, teamId) {
|
|
|
3240
3240
|
return await readListedScheduledAutomations(db, teamId);
|
|
3241
3241
|
}
|
|
3242
3242
|
async function writeScheduledAutomation(db, task, current, editedBy) {
|
|
3243
|
-
if (current?.status === "blocked" && task.status === "active" && typeof task.nextRunAtMs === "number" && Number.isFinite(task.nextRunAtMs)) await db.delete(
|
|
3243
|
+
if (current?.status === "blocked" && task.status === "active" && typeof task.nextRunAtMs === "number" && Number.isFinite(task.nextRunAtMs)) await db.delete(juniorAutomationRuns).where(and(eq(juniorAutomationRuns.id, scheduledRunId(task.id, task.nextRunAtMs)), eq(juniorAutomationRuns.status, "blocked")));
|
|
3244
3244
|
if (task.status === "deleted" && current?.status !== "deleted") await skipPendingRunsForDeletedTask(db, task);
|
|
3245
3245
|
await upsertScheduledAutomation(db, task);
|
|
3246
3246
|
await recordAutomationVersion(db, task, current, editedBy);
|
|
3247
3247
|
}
|
|
3248
3248
|
async function skipPendingRunsForDeletedTask(db, task) {
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
const next = scheduledRunSchema.parse({
|
|
3255
|
-
...parsed.data,
|
|
3256
|
-
completedAtMs: task.updatedAtMs,
|
|
3257
|
-
errorMessage,
|
|
3258
|
-
status: "skipped"
|
|
3259
|
-
});
|
|
3260
|
-
await db.update(juniorSchedulerRuns).set({
|
|
3261
|
-
record: next,
|
|
3262
|
-
status: next.status
|
|
3263
|
-
}).where(and(eq(juniorSchedulerRuns.id, next.id), eq(juniorSchedulerRuns.status, "pending")));
|
|
3264
|
-
}
|
|
3249
|
+
await db.update(juniorAutomationRuns).set({
|
|
3250
|
+
completedAtMs: task.updatedAtMs,
|
|
3251
|
+
errorMessage: `Scheduled automation ${task.id} was deleted before the run started.`,
|
|
3252
|
+
status: "skipped"
|
|
3253
|
+
}).where(and(eq(juniorAutomationRuns.automationId, task.id), eq(juniorAutomationRuns.status, "pending")));
|
|
3265
3254
|
}
|
|
3266
3255
|
/** Create a scheduled automation once under its retry-stable task lock. */
|
|
3267
3256
|
async function createScheduledAutomation(db, task) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-
|
|
2
|
-
import { d as getDb } from "./viewer-
|
|
3
|
-
import { d as juniorDestinations } from "./agent-invocations-
|
|
4
|
-
import {
|
|
5
|
-
import { Kt as persistConversationMessages } from "./tasks-
|
|
6
|
-
import { it as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-
|
|
7
|
-
import { w as getStateAdapter } from "./profile-
|
|
1
|
+
import { I as isRecord, L as toOptionalNumber, R as toOptionalString } from "./logging-B3nJLXT7.js";
|
|
2
|
+
import { d as getDb } from "./viewer-CGZiUVMU.js";
|
|
3
|
+
import { d as juniorDestinations } from "./agent-invocations-BY60iNw-.js";
|
|
4
|
+
import { l as juniorLocationConfigurations } from "./executor-B88oEqok.js";
|
|
5
|
+
import { Kt as persistConversationMessages } from "./tasks-DO9VM9cu.js";
|
|
6
|
+
import { it as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-DfPubHYm.js";
|
|
7
|
+
import { w as getStateAdapter } from "./profile-Dh73O6lZ.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
10
|
import { and, eq, sql } from "drizzle-orm";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-
|
|
2
|
-
import { I as isRecord, t as buildTurnFailureResponse } from "./logging-
|
|
1
|
+
import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-oBgOmQV6.js";
|
|
2
|
+
import { I as isRecord, t as buildTurnFailureResponse } from "./logging-B3nJLXT7.js";
|
|
3
3
|
import { g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
|
|
4
|
-
import { c as getConversationEventStore, d as getDb } from "./viewer-
|
|
5
|
-
import { Gt as hydrateConversationMessages, an as markConversationMessage } from "./tasks-
|
|
6
|
-
import { Nt as listConversationAnnotations } from "./agent-hooks-
|
|
4
|
+
import { c as getConversationEventStore, d as getDb } from "./viewer-CGZiUVMU.js";
|
|
5
|
+
import { Gt as hydrateConversationMessages, an as markConversationMessage } from "./tasks-DO9VM9cu.js";
|
|
6
|
+
import { Nt as listConversationAnnotations } from "./agent-hooks-DfPubHYm.js";
|
|
7
7
|
import { J as removedCardSchema, Y as resolveMessageCards, q as readMessageCardRefs } from "./conversation-T18Xlkx9.js";
|
|
8
|
-
import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-
|
|
8
|
+
import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-m8aJlwP_.js";
|
|
9
9
|
import { d as markTurnCompleted, u as markTurnClosed } from "./oauth-authorization-BA4Dt6a7.js";
|
|
10
|
-
import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-
|
|
10
|
+
import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-FreaCOZD.js";
|
|
11
11
|
//#region src/chat/conversations/pending-cards.ts
|
|
12
12
|
/** Select undelivered cards and load their latest saved facts. */
|
|
13
13
|
async function loadPendingMessageCards(conversationId) {
|