@sentry/junior 0.266.0 → 0.268.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/{actor-tlxzqaRe.js → actor-CP9K2Idu.js} +9 -1
- package/dist/{adapter-eRFA_naf.js → adapter-04AcD2SO.js} +5 -7
- package/dist/{admin-tILpP51p.js → admin-DIU1QyG3.js} +1 -1
- package/dist/{agent-invocations-CxKldAeB.js → agent-invocations-C1RNOCs8.js} +2 -0
- package/dist/{agent-runner-BtYK7bht.js → agent-runner-CAYfFmU7.js} +2636 -601
- package/dist/api/schema.d.ts +2 -5454
- package/dist/api/schema.js +6 -5
- package/dist/api.d.ts +6 -1
- package/dist/api.js +255 -1208
- package/dist/{app-Csbi9dW7.d.ts → app-z6Uuyq3j.d.ts} +23 -4
- package/dist/app.d.ts +2 -2
- package/dist/app.js +1869 -378
- package/dist/{automation-BKpY9LPa.js → automation-CmeFBSEh.js} +42 -14
- package/dist/{briefs-DgfWMU7e.js → briefs-DQbV2jNr.js} +4 -4
- package/dist/{catalog-runtime-DAJjAbSx.js → catalog-runtime-BD9GSpc6.js} +1 -1
- package/dist/cli/chat.js +15 -15
- package/dist/cli/check.js +3 -3
- package/dist/cli/init.js +0 -1
- package/dist/cli/main.js +3 -3
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +4 -4
- package/dist/cli/upgrade.d.ts +1 -1
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-B0YZfxNy.js → client-C1yDYjoS.js} +2 -2
- package/dist/{config-C0UwYqDK.js → config-DrTeF80T.js} +32 -10
- package/dist/{connections-Bwu3VORi.js → connections-D46f8vvi.js} +12 -12
- package/dist/{conversation-DF4rUcjb.js → conversation-DSo310Ps.js} +8 -1
- package/dist/{conversation-privacy-CY7JVjxn.js → conversation-privacy-CxlOCiUo.js} +1 -1
- package/dist/{credential-sync-VGAMUTGp.js → credential-sync-sm9fegLY.js} +29 -34
- package/dist/{credentialed-enF5Bf3y.js → credentialed-lukuD-cc.js} +2933 -1026
- package/dist/db-BU4LQD8s.d.ts +6 -0
- package/dist/{executor-TnWbvL09.js → executor-4vhvsMZJ.js} +83 -6
- package/dist/instrumentation.js +6 -2
- package/dist/{assistant-reply-UyzAfZQo.js → interruption-marker-CkncDT8d.js} +8 -2
- package/dist/{job-queue-DBpHmKnd.js → job-queue-In9QKz-I.js} +128 -3
- package/dist/{web-input-B-bMjD1V.js → list-BkgnXEEB.js} +1611 -817
- package/dist/{logging-Ce0mXZ8J.js → logging-DLSpkSSr.js} +11 -3
- package/dist/{message-VZ3DFpGb.js → message-BObyg59s.js} +4 -4
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-callback-server-CpqWLjVY.js → oauth-callback-server-B-WbSdoH.js} +2 -2
- package/dist/{prompt-BcCGlmg2.js → prompt-BW9jFsqZ.js} +1 -1
- package/dist/{registry-1BEIPdbT.js → registry-BgecKva0.js} +2 -2
- package/dist/{web-message-id-CJSUiksE.js → reporting-window-DVCD_10C.js} +1 -10
- package/dist/{resolve-BSHHkEGE.js → resolve-Cpa4Bu1O.js} +3 -3
- package/dist/{result-CwOpzqdh.js → result-D3TSmZZ8.js} +9 -9
- package/dist/{runner-CEaX04kz.js → runner-DS5OKhEp.js} +11 -11
- package/dist/{sandbox-egress-signals-BwtGHwqa.js → sandbox-egress-signals-CnDjY5rx.js} +1 -1
- package/dist/{schema-RsaBHxRH.js → schema-0050HFnB.js} +82 -5
- package/dist/schema-ZngqcOWM.d.ts +5813 -0
- package/dist/{service-account-6wC76eBZ.js → service-account-CKV2WTY7.js} +3 -3
- package/dist/{service-account-Dg4lIbHm.js → service-account-DGjnDw9y.js} +3 -3
- package/dist/{session-stop-tZOw9AJD.js → session-stop-Dam1EI7B.js} +527 -134
- package/dist/{skills-DzyGN7wd.js → skills-CfAnfImD.js} +2 -2
- package/dist/{spawn-6rokq7l_.js → spawn-cmq9p4Ly.js} +2 -2
- package/dist/{store-DcKkzrdt.js → store-C5PN02QO.js} +4 -4
- package/dist/{store-CG0VJyye.d.ts → store-xMuuXRE0.d.ts} +23 -9
- package/dist/store-zPEoJPBB.js +295 -0
- package/dist/{task-queue-Bg4RS2Gy.js → task-queue-_mf28dSu.js} +10 -5
- package/dist/{task-runner-8N5LIkSg.js → task-runner-DMI2prDO.js} +25 -14
- package/dist/{tasks-DDT-J3Rf.js → tasks-SB9z-VTU.js} +1551 -54
- package/dist/{thread-state-cprEaxgl.js → thread-state-BbbPh0Sn.js} +8 -18
- package/dist/{turn-failure-response-C8sMdsdX.js → turn-failure-response-BKKmnMB5.js} +11 -16
- package/dist/{turn-lifecycle-DaBVoz7h.js → turn-lifecycle-oP0kVeGz.js} +1 -1
- package/dist/{validation-C2lllinq.js → validation--JsAGLwc.js} +1 -1
- package/dist/{version-oaLfxxnf.js → version-jHwJp4hC.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-BpE6Z3qf.js → viewer-CpXTGlep.js} +329 -230
- package/dist/web-message-id-DlHNANtd.js +132 -0
- package/dist/{work-VX1SHWha.js → work-3N-GHY9m.js} +10 -10
- package/dist/{worker-hook-y_Y.js → worker-CCdbcItd.js} +30 -19
- package/migrations/0064_any_resource_event_triggers.sql +2 -0
- package/migrations/0065_user_customization.sql +1 -0
- package/migrations/0066_review_items.sql +53 -0
- package/migrations/0067_review_item_dedupe_tenant.sql +2 -0
- package/migrations/0068_review_item_slack_cards.sql +10 -0
- package/migrations/meta/0064_snapshot.json +3505 -0
- package/migrations/meta/0065_snapshot.json +3511 -0
- package/migrations/meta/0066_snapshot.json +4099 -0
- package/migrations/meta/0067_snapshot.json +3921 -0
- package/migrations/meta/0068_snapshot.json +4176 -0
- package/migrations/meta/_journal.json +36 -1
- package/package.json +19 -4
- package/dist/db-BnRqQ7G5.d.ts +0 -5
- package/dist/images-BKQqSi5W.js +0 -64
- package/dist/store-FALy-JQb.js +0 -1424
- package/dist/turn-session-routing-a9CHX-w6.js +0 -76
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// src/api/schema/user-customization.ts
|
|
3
|
+
/** Longest customization text one user can save. */
|
|
4
|
+
const USER_CUSTOMIZATION_MAX_CHARS = 1e3;
|
|
5
|
+
/** Saved customization text. An empty string means none. */
|
|
6
|
+
const userCustomizationTextSchema = z.string().trim().max(USER_CUSTOMIZATION_MAX_CHARS);
|
|
7
|
+
/** Request and response body for the viewer's customization. */
|
|
8
|
+
const userCustomizationSchema = z.object({ customization: userCustomizationTextSchema }).strict();
|
|
9
|
+
// src/chat/tools/runtime/user-input-request.ts
|
|
10
|
+
const USER_INPUT_LIMITS = {
|
|
11
|
+
maxButtonOptions: 5,
|
|
12
|
+
maxDescriptionChars: 200,
|
|
13
|
+
maxFields: 4,
|
|
14
|
+
maxLabelChars: 75,
|
|
15
|
+
maxOptions: 10,
|
|
16
|
+
maxTextChars: 3e3,
|
|
17
|
+
maxQuestionChars: 3e3,
|
|
18
|
+
minOptions: 2
|
|
19
|
+
};
|
|
20
|
+
const labelSchema = z.string().trim().min(1).max(USER_INPUT_LIMITS.maxLabelChars);
|
|
21
|
+
const descriptionSchema = z.string().trim().min(1).max(USER_INPUT_LIMITS.maxDescriptionChars).optional();
|
|
22
|
+
const optionSchema = z.object({
|
|
23
|
+
label: labelSchema.describe("Short choice text, such as `Accept` or `Decline`. The answer uses this exact text."),
|
|
24
|
+
description: descriptionSchema.describe("Optional short note about what this choice does.")
|
|
25
|
+
});
|
|
26
|
+
const fieldBase = {
|
|
27
|
+
id: z.string().regex(/^[a-z][a-z0-9_]{0,31}$/).describe("Stable key for this field, such as `approach`."),
|
|
28
|
+
label: labelSchema.describe("Short field name, such as `Approach`."),
|
|
29
|
+
description: descriptionSchema.describe("Optional short help text for this field.")
|
|
30
|
+
};
|
|
31
|
+
const optionsSchema = z.array(optionSchema).min(USER_INPUT_LIMITS.minOptions).max(USER_INPUT_LIMITS.maxOptions).describe("Choices in display order.");
|
|
32
|
+
const userInputFieldSchema = z.discriminatedUnion("kind", [
|
|
33
|
+
z.object({
|
|
34
|
+
...fieldBase,
|
|
35
|
+
kind: z.literal("choice").describe("The person picks one option."),
|
|
36
|
+
options: optionsSchema
|
|
37
|
+
}),
|
|
38
|
+
z.object({
|
|
39
|
+
...fieldBase,
|
|
40
|
+
kind: z.literal("multi_choice").describe("The person picks any number of options."),
|
|
41
|
+
options: optionsSchema
|
|
42
|
+
}),
|
|
43
|
+
z.object({
|
|
44
|
+
...fieldBase,
|
|
45
|
+
kind: z.literal("text").describe("The person types a short answer.")
|
|
46
|
+
})
|
|
47
|
+
]);
|
|
48
|
+
const userInputRequestSchema = z.object({
|
|
49
|
+
question: z.string().trim().min(1).max(USER_INPUT_LIMITS.maxQuestionChars).describe("The question, in markdown. Include the facts the person needs to decide."),
|
|
50
|
+
fields: z.array(userInputFieldSchema).min(1).max(USER_INPUT_LIMITS.maxFields).describe("What to ask, in display order. Use one `choice` field for a simple decision.")
|
|
51
|
+
}).superRefine((request, context) => {
|
|
52
|
+
const ids = /* @__PURE__ */ new Set();
|
|
53
|
+
for (const field of request.fields) {
|
|
54
|
+
if (ids.has(field.id)) context.addIssue({
|
|
55
|
+
code: "custom",
|
|
56
|
+
message: "Each field needs a different id."
|
|
57
|
+
});
|
|
58
|
+
ids.add(field.id);
|
|
59
|
+
if (field.kind === "text") continue;
|
|
60
|
+
const labels = field.options.map((option) => option.label.toLowerCase());
|
|
61
|
+
if (new Set(labels).size !== labels.length) context.addIssue({
|
|
62
|
+
code: "custom",
|
|
63
|
+
message: "Each choice of a field needs a different label."
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* Return the single choice field of a request that a surface can show as
|
|
69
|
+
* one row of buttons, where one click is the whole answer.
|
|
70
|
+
*/
|
|
71
|
+
function buttonUserInputField(request) {
|
|
72
|
+
const [field, ...rest] = request.fields;
|
|
73
|
+
if (rest.length || field?.kind !== "choice") return void 0;
|
|
74
|
+
return field.options.length <= USER_INPUT_LIMITS.maxButtonOptions ? field : void 0;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Keep only answer values that match the request: known field ids, known
|
|
78
|
+
* option labels, one value for a `choice` field, and trimmed text.
|
|
79
|
+
*/
|
|
80
|
+
function normalizeUserInputAnswer(request, answer) {
|
|
81
|
+
const values = {};
|
|
82
|
+
for (const field of request.fields) {
|
|
83
|
+
const raw = (answer.values[field.id] ?? []).map((value) => value.trim()).filter(Boolean);
|
|
84
|
+
if (field.kind === "text") {
|
|
85
|
+
const text = raw.join("\n").slice(0, USER_INPUT_LIMITS.maxTextChars);
|
|
86
|
+
if (text) values[field.id] = [text];
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const picked = field.options.map((option) => option.label).filter((label) => raw.includes(label));
|
|
90
|
+
const kept = field.kind === "choice" ? picked.slice(0, 1) : picked;
|
|
91
|
+
if (kept.length) values[field.id] = kept;
|
|
92
|
+
}
|
|
93
|
+
const other = answer.other?.trim().slice(0, USER_INPUT_LIMITS.maxTextChars);
|
|
94
|
+
return {
|
|
95
|
+
requestId: answer.requestId,
|
|
96
|
+
values,
|
|
97
|
+
...other ? { other } : void 0
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Return true when an answer has no value and no free text. */
|
|
101
|
+
function isEmptyUserInputAnswer(answer) {
|
|
102
|
+
return !answer.other && Object.keys(answer.values).length === 0;
|
|
103
|
+
}
|
|
104
|
+
function answerLine(text) {
|
|
105
|
+
return text.split("\n").map((line) => line.trim()).filter(Boolean).join("\n");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Write an answer as the text of the person's message. Slack and the web
|
|
109
|
+
* dashboard both send this text, so the model reads one format. The first
|
|
110
|
+
* line names the request, and each field starts its own line.
|
|
111
|
+
*/
|
|
112
|
+
function formatUserInputAnswer(request, answer) {
|
|
113
|
+
const normalized = normalizeUserInputAnswer(request, answer);
|
|
114
|
+
const lines = [`Answer to request ${normalized.requestId}:`];
|
|
115
|
+
for (const field of request.fields) {
|
|
116
|
+
const values = normalized.values[field.id];
|
|
117
|
+
const value = values?.length ? values.join(", ") : "(no answer)";
|
|
118
|
+
lines.push(answerLine(`${field.label} (${field.id}): ${value}`));
|
|
119
|
+
}
|
|
120
|
+
if (normalized.other) lines.push(answerLine(`Other: ${normalized.other}`));
|
|
121
|
+
return lines.join("\n");
|
|
122
|
+
}
|
|
123
|
+
// src/chat/conversations/web-message-id.ts
|
|
124
|
+
/**
|
|
125
|
+
* Build the retry-stable Message id shared by web ingress and browser sends.
|
|
126
|
+
* Keep the existing hash and prefix so retries still address stored Messages.
|
|
127
|
+
*/
|
|
128
|
+
async function webMessageId(args) {
|
|
129
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(`${args.conversationId}\u0000${args.idempotencyKey}`));
|
|
130
|
+
return `api-msg:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 24)}`;
|
|
131
|
+
}
|
|
132
|
+
export { isEmptyUserInputAnswer as a, USER_CUSTOMIZATION_MAX_CHARS as c, formatUserInputAnswer as i, userCustomizationSchema as l, USER_INPUT_LIMITS as n, normalizeUserInputAnswer as o, buttonUserInputField as r, userInputRequestSchema as s, webMessageId as t, userCustomizationTextSchema as u };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as botConfig } from "./config-
|
|
4
|
-
import { d as
|
|
2
|
+
import { Fn as isTurnExecutionLimitExceededError, Gt as saveTurnCheckpoint, It as AuthorizationFlowDisabledError, Jt as failTurnRecord, Kt as abandonTurnRecord, Mt as PluginCredentialFailureError, Yt as getTurnRecord, et as openConversationProjection, zn as getTerminalAssistantMessages } from "./tasks-SB9z-VTU.js";
|
|
3
|
+
import { n as botConfig } from "./config-DrTeF80T.js";
|
|
4
|
+
import { d as getConversationEventStore, p as getConversationStore } from "./viewer-CpXTGlep.js";
|
|
5
5
|
import { m as sameActorIdentity, u as agentInstructionProvenance } from "./history-C84mlAwO.js";
|
|
6
|
-
import {
|
|
7
|
-
import { E as markAgentInvocationSteered, H as TurnInputCommitLostError, K as isTurnInputCommitLostError, L as agentTypeInstructions, O as reportReplacedAgentInvocation, R as agentTypeStartsWithParentHistory, S as markAgentInvocationMailboxAppended, T as markAgentInvocationRunning, W as getConversationTurnBoundaryError, _ as getLatestAgentInvocationForConversation, c as getAgentInvocation, f as getAgentInvocationMessageId, m as getAgentInvocationTurnId, n as completeAgentInvocation, r as createAgentInvocation, s as getActiveAgentInvocationForConversation, w as markAgentInvocationPaused, y as isTerminalAgentInvocation } from "./store-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { r as appendAndEnqueueInboundMessage } from "./store-
|
|
11
|
-
import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-
|
|
12
|
-
import {
|
|
6
|
+
import { Dt as recordSubagentEnded, Ft as buildSteeringPiMessage, Ht as readBlockedReport, It as withoutSavedSteeringMessages, Ot as recordSubagentStarted, Tt as stopChildAgentsOf } from "./agent-runner-CAYfFmU7.js";
|
|
7
|
+
import { E as markAgentInvocationSteered, H as TurnInputCommitLostError, K as isTurnInputCommitLostError, L as agentTypeInstructions, O as reportReplacedAgentInvocation, R as agentTypeStartsWithParentHistory, S as markAgentInvocationMailboxAppended, T as markAgentInvocationRunning, W as getConversationTurnBoundaryError, _ as getLatestAgentInvocationForConversation, c as getAgentInvocation, f as getAgentInvocationMessageId, m as getAgentInvocationTurnId, n as completeAgentInvocation, r as createAgentInvocation, s as getActiveAgentInvocationForConversation, w as markAgentInvocationPaused, y as isTerminalAgentInvocation } from "./store-C5PN02QO.js";
|
|
8
|
+
import { r as getAssistantReplyText } from "./interruption-marker-CkncDT8d.js";
|
|
9
|
+
import { C as maybePostAutomatedTurnLimitNotice, D as recordFinishedTurnForAutomatedLimit, O as resetAutomatedTurnLimit } from "./session-stop-Dam1EI7B.js";
|
|
10
|
+
import { r as appendAndEnqueueInboundMessage } from "./store-zPEoJPBB.js";
|
|
11
|
+
import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-oP0kVeGz.js";
|
|
12
|
+
import { a as persistThreadStateById, n as getPersistedSandboxState, r as getPersistedThreadState } from "./thread-state-BbbPh0Sn.js";
|
|
13
13
|
import { isDeepStrictEqual } from "node:util";
|
|
14
14
|
import { z } from "zod";
|
|
15
15
|
// src/chat/runtime/turn-execution.ts
|
|
@@ -1,34 +1,45 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
CONVERSATION_WORK_DEFER_DELAY_MS: () => CONVERSATION_WORK_DEFER_DELAY_MS,
|
|
10
|
-
processConversationWork: () => processConversationWork
|
|
11
|
-
});
|
|
12
|
-
const CONVERSATION_WORK_DEFER_DELAY_MS = 15e3;
|
|
13
|
-
const CONVERSATION_STOP_CHECK_INTERVAL_MS = 500;
|
|
14
|
-
function now(options) {
|
|
15
|
-
return options.nowMs?.() ?? Date.now();
|
|
16
|
-
}
|
|
2
|
+
import { _n as isInvalidConversationRecordError, gn as isFinalAttempt, mn as hasConversationStop } from "./tasks-SB9z-VTU.js";
|
|
3
|
+
import { y as isProviderRetryError } from "./client-C1yDYjoS.js";
|
|
4
|
+
import { i as getChatConfig } from "./config-DrTeF80T.js";
|
|
5
|
+
import { T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException } from "./logging-DLSpkSSr.js";
|
|
6
|
+
import { f as getTurnRequestDeadline, m as ConversationQueueMessageRejectedError } from "./job-queue-In9QKz-I.js";
|
|
7
|
+
import { C as requestAnotherSlice, T as startConversationWork, b as recordConversationRetry, d as countPendingConversationMessages, f as deadLetterAttempt, g as getConversationWorkState, i as beginConversationResume, l as completeConversationStop, m as ensureConversationWake, o as checkInConversationWork, p as drainConversationMailbox, s as clearConsumedConversationWake, t as ackMessages, u as completeConversationWork, x as releaseConversationWork, y as recordAttemptFailure } from "./store-zPEoJPBB.js";
|
|
8
|
+
// src/chat/task-execution/attempt-selection.ts
|
|
17
9
|
function selectContiguousTurnBatch(messages) {
|
|
18
10
|
const first = messages[0];
|
|
19
11
|
if (!first) return [];
|
|
20
12
|
const nextTurnIndex = messages.findIndex((message) => message.input.authorId !== first.input.authorId || message.source !== first.source);
|
|
21
13
|
return messages.slice(0, nextTurnIndex === -1 ? messages.length : nextTurnIndex);
|
|
22
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* True when an interrupt can start its own attempt.
|
|
17
|
+
*
|
|
18
|
+
* A steered web message must not start a second Turn while a yielded Turn
|
|
19
|
+
* waits to resume. It stays pending for that Turn's drain or the next attempt.
|
|
20
|
+
*/
|
|
21
|
+
function isAttemptInterrupt(message, work) {
|
|
22
|
+
return message.delivery === "interrupt" && !(work.execution.status === "paused" && message.source === "web");
|
|
23
|
+
}
|
|
23
24
|
/** Prioritize interrupts while keeping each attempt to one Actor and Source. */
|
|
24
25
|
function selectAttemptMessages(work) {
|
|
25
26
|
const messages = work.messages;
|
|
26
|
-
const interrupts = messages.filter((message) => message
|
|
27
|
+
const interrupts = messages.filter((message) => isAttemptInterrupt(message, work));
|
|
27
28
|
if (interrupts.length > 0) return selectContiguousTurnBatch(interrupts);
|
|
28
29
|
if (work.execution.status === "paused") return [];
|
|
29
30
|
const nonEventMessages = messages.filter((message) => message.source !== "event");
|
|
30
31
|
return selectContiguousTurnBatch(nonEventMessages.length > 0 ? nonEventMessages : messages);
|
|
31
32
|
}
|
|
33
|
+
// src/chat/task-execution/worker.ts
|
|
34
|
+
var worker_exports = /* @__PURE__ */ __exportAll({
|
|
35
|
+
CONVERSATION_WORK_DEFER_DELAY_MS: () => CONVERSATION_WORK_DEFER_DELAY_MS,
|
|
36
|
+
processConversationWork: () => processConversationWork
|
|
37
|
+
});
|
|
38
|
+
const CONVERSATION_WORK_DEFER_DELAY_MS = 15e3;
|
|
39
|
+
const CONVERSATION_STOP_CHECK_INTERVAL_MS = 500;
|
|
40
|
+
function now(options) {
|
|
41
|
+
return options.nowMs?.() ?? Date.now();
|
|
42
|
+
}
|
|
32
43
|
function nudgeIdempotencyKey(reason, conversationId, nowMs) {
|
|
33
44
|
return `${reason}:${conversationId}:${nowMs}`;
|
|
34
45
|
}
|
|
@@ -248,7 +259,7 @@ async function processConversationWorkInContext(message, options) {
|
|
|
248
259
|
const softYieldDeadlineMs = startedAtMs + (options.softYieldAfterMs ?? getChatConfig().conversationWorkSoftYieldAfterMs);
|
|
249
260
|
let attemptMessageIds = [];
|
|
250
261
|
let attemptSelectedMessageIds = /* @__PURE__ */ new Set();
|
|
251
|
-
let
|
|
262
|
+
let attemptStartInterruptIds = /* @__PURE__ */ new Set();
|
|
252
263
|
let failedWithoutProgress = false;
|
|
253
264
|
let leaseLost = false;
|
|
254
265
|
const markLeaseLost = () => {
|
|
@@ -269,7 +280,7 @@ async function processConversationWorkInContext(message, options) {
|
|
|
269
280
|
leaseToken: lease.leaseToken,
|
|
270
281
|
conversationStore: options.conversationStore,
|
|
271
282
|
handle: async (messages) => {
|
|
272
|
-
const candidates = drainOptions?.deferred ? messages : messages.filter((message) => message.delivery === "interrupt" && (attemptSelectedMessageIds.has(message.inboundMessageId) || !
|
|
283
|
+
const candidates = drainOptions?.deferred ? messages : messages.filter((message) => message.delivery === "interrupt" && (attemptSelectedMessageIds.has(message.inboundMessageId) || !attemptStartInterruptIds.has(message.inboundMessageId)));
|
|
273
284
|
if (candidates.length === 0) return [];
|
|
274
285
|
return await handle(candidates) ?? candidates.map((message) => message.inboundMessageId);
|
|
275
286
|
},
|
|
@@ -337,7 +348,7 @@ async function processConversationWorkInContext(message, options) {
|
|
|
337
348
|
const attemptMessages = selectAttemptMessages(leasedWork);
|
|
338
349
|
const runId = leasedWork.execution.runId;
|
|
339
350
|
if (!runId) throw new Error(`Conversation run is missing for ${conversationId}`);
|
|
340
|
-
|
|
351
|
+
attemptStartInterruptIds = new Set(leasedWork.messages.filter((message) => isAttemptInterrupt(message, leasedWork)).map((message) => message.inboundMessageId));
|
|
341
352
|
if (hasRun && shouldYield()) {
|
|
342
353
|
if (resumePending) return await yieldWork();
|
|
343
354
|
break;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
ALTER TABLE "junior_automations" DROP CONSTRAINT "junior_automations_trigger_check";--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "junior_automations" ADD CONSTRAINT "junior_automations_trigger_check" CHECK (("junior_automations"."kind" = 'scheduled' and "junior_automations"."namespace" is null and "junior_automations"."identifier" is null) or ("junior_automations"."kind" = 'event' and "junior_automations"."namespace" is not null and "junior_automations"."next_run_at_ms" is null and "junior_automations"."run_now_at_ms" is null and "junior_automations"."status" <> 'completed'));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "junior_users" ADD COLUMN "customization" text;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
CREATE TABLE "junior_review_item_assignees" (
|
|
2
|
+
"item_id" text NOT NULL,
|
|
3
|
+
"user_id" text NOT NULL,
|
|
4
|
+
CONSTRAINT "junior_review_item_assignees_item_id_user_id_pk" PRIMARY KEY("item_id","user_id")
|
|
5
|
+
);
|
|
6
|
+
--> statement-breakpoint
|
|
7
|
+
CREATE TABLE "junior_review_item_conversations" (
|
|
8
|
+
"item_id" text NOT NULL,
|
|
9
|
+
"conversation_id" text NOT NULL,
|
|
10
|
+
CONSTRAINT "junior_review_item_conversations_item_id_conversation_id_pk" PRIMARY KEY("item_id","conversation_id")
|
|
11
|
+
);
|
|
12
|
+
--> statement-breakpoint
|
|
13
|
+
CREATE TABLE "junior_review_items" (
|
|
14
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
15
|
+
"kind" text NOT NULL,
|
|
16
|
+
"status" text NOT NULL,
|
|
17
|
+
"visibility" text NOT NULL,
|
|
18
|
+
"title" text NOT NULL,
|
|
19
|
+
"body" text NOT NULL,
|
|
20
|
+
"request" jsonb,
|
|
21
|
+
"answer" jsonb,
|
|
22
|
+
"assigned_to_everyone" boolean DEFAULT false NOT NULL,
|
|
23
|
+
"dedupe_key" text NOT NULL,
|
|
24
|
+
"subject_id" text,
|
|
25
|
+
"subject_title" text,
|
|
26
|
+
"subject_url" text,
|
|
27
|
+
"added_by_conversation_id" text NOT NULL,
|
|
28
|
+
"provider" text,
|
|
29
|
+
"provider_tenant_id" text,
|
|
30
|
+
"automation_id" text,
|
|
31
|
+
"closed_at" timestamp with time zone,
|
|
32
|
+
"closed_by_user_id" text,
|
|
33
|
+
"close_reason" text,
|
|
34
|
+
"created_at" timestamp with time zone NOT NULL,
|
|
35
|
+
"updated_at" timestamp with time zone NOT NULL,
|
|
36
|
+
CONSTRAINT "junior_review_items_kind_check" CHECK (("junior_review_items"."kind" = 'notice' and "junior_review_items"."request" is null and "junior_review_items"."answer" is null) or ("junior_review_items"."kind" = 'action' and "junior_review_items"."request" is not null)),
|
|
37
|
+
CONSTRAINT "junior_review_items_status_check" CHECK (("junior_review_items"."status" = 'open' and "junior_review_items"."closed_at" is null) or ("junior_review_items"."status" in ('done', 'dismissed') and "junior_review_items"."closed_at" is not null)),
|
|
38
|
+
CONSTRAINT "junior_review_items_tenant_check" CHECK (("junior_review_items"."provider" is null) = ("junior_review_items"."provider_tenant_id" is null)),
|
|
39
|
+
CONSTRAINT "junior_review_items_visibility_check" CHECK ("junior_review_items"."visibility" = 'public' or not "junior_review_items"."assigned_to_everyone")
|
|
40
|
+
);
|
|
41
|
+
--> statement-breakpoint
|
|
42
|
+
ALTER TABLE "junior_review_item_assignees" ADD CONSTRAINT "junior_review_item_assignees_item_id_junior_review_items_id_fk" FOREIGN KEY ("item_id") REFERENCES "public"."junior_review_items"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
43
|
+
ALTER TABLE "junior_review_item_assignees" ADD CONSTRAINT "junior_review_item_assignees_user_id_junior_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."junior_users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
44
|
+
ALTER TABLE "junior_review_item_conversations" ADD CONSTRAINT "junior_review_item_conversations_item_id_junior_review_items_id_fk" FOREIGN KEY ("item_id") REFERENCES "public"."junior_review_items"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
45
|
+
ALTER TABLE "junior_review_item_conversations" ADD CONSTRAINT "junior_review_item_conversations_conversation_id_junior_conversations_conversation_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."junior_conversations"("conversation_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
46
|
+
ALTER TABLE "junior_review_items" ADD CONSTRAINT "junior_review_items_automation_id_junior_automations_id_fk" FOREIGN KEY ("automation_id") REFERENCES "public"."junior_automations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
47
|
+
ALTER TABLE "junior_review_items" ADD CONSTRAINT "junior_review_items_closed_by_user_id_junior_users_id_fk" FOREIGN KEY ("closed_by_user_id") REFERENCES "public"."junior_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
48
|
+
CREATE INDEX "junior_review_item_assignees_user_idx" ON "junior_review_item_assignees" USING btree ("user_id");--> statement-breakpoint
|
|
49
|
+
CREATE INDEX "junior_review_item_conversations_conversation_idx" ON "junior_review_item_conversations" USING btree ("conversation_id");--> statement-breakpoint
|
|
50
|
+
CREATE UNIQUE INDEX "junior_review_items_open_dedupe_uidx" ON "junior_review_items" USING btree ("dedupe_key") WHERE "junior_review_items"."status" = 'open';--> statement-breakpoint
|
|
51
|
+
CREATE INDEX "junior_review_items_status_idx" ON "junior_review_items" USING btree ("status","updated_at","id");--> statement-breakpoint
|
|
52
|
+
CREATE INDEX "junior_review_items_subject_idx" ON "junior_review_items" USING btree ("subject_id","status");--> statement-breakpoint
|
|
53
|
+
CREATE INDEX "junior_review_items_automation_idx" ON "junior_review_items" USING btree ("automation_id","status");
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
DROP INDEX "junior_review_items_open_dedupe_uidx";--> statement-breakpoint
|
|
2
|
+
CREATE UNIQUE INDEX "junior_review_items_open_dedupe_uidx" ON "junior_review_items" USING btree (coalesce("provider", ''),coalesce("provider_tenant_id", ''),"dedupe_key") WHERE "junior_review_items"."status" = 'open';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
CREATE TABLE "junior_review_item_slack_cards" (
|
|
2
|
+
"item_id" text NOT NULL,
|
|
3
|
+
"conversation_id" text NOT NULL,
|
|
4
|
+
"team_id" text NOT NULL,
|
|
5
|
+
"channel_id" text NOT NULL,
|
|
6
|
+
"message_ts" text NOT NULL,
|
|
7
|
+
CONSTRAINT "junior_review_item_slack_cards_item_id_conversation_id_pk" PRIMARY KEY("item_id","conversation_id")
|
|
8
|
+
);
|
|
9
|
+
--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "junior_review_item_slack_cards" ADD CONSTRAINT "junior_review_item_slack_cards_item_id_junior_review_items_id_fk" FOREIGN KEY ("item_id") REFERENCES "public"."junior_review_items"("id") ON DELETE cascade ON UPDATE no action;
|