@sentry/junior 0.74.1 → 0.76.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/README.md +1 -1
- package/bin/junior.mjs +4 -66
- package/dist/agent-hooks-ZOE7RIED.js +37 -0
- package/dist/api-reference.d.ts +3 -1
- package/dist/app.js +5516 -5422
- package/dist/build/copy-build-content.d.ts +1 -1
- package/dist/build/virtual-config.d.ts +2 -2
- package/dist/chat/agent-dispatch/context.d.ts +2 -3
- package/dist/chat/agent-dispatch/runner.d.ts +2 -0
- package/dist/chat/agent-dispatch/types.d.ts +2 -1
- package/dist/chat/config.d.ts +3 -0
- package/dist/chat/credentials/state-adapter-token-store.d.ts +2 -0
- package/dist/chat/credentials/subject.d.ts +3 -3
- package/dist/chat/credentials/user-token-store.d.ts +17 -12
- package/dist/chat/db.d.ts +8 -0
- package/dist/chat/mcp/auth-store.d.ts +2 -1
- package/dist/chat/mcp/oauth.d.ts +2 -1
- package/dist/chat/oauth-flow.d.ts +3 -1
- package/dist/chat/pi/client.d.ts +15 -7
- package/dist/chat/plugins/agent-hooks.d.ts +20 -13
- package/dist/chat/plugins/auth/oauth-request.d.ts +11 -7
- package/dist/chat/plugins/credential-hooks.d.ts +6 -6
- package/dist/chat/plugins/logging.d.ts +2 -2
- package/dist/chat/plugins/model.d.ts +9 -0
- package/dist/chat/plugins/package-discovery.d.ts +2 -1
- package/dist/chat/plugins/prompt.d.ts +5 -0
- package/dist/chat/plugins/registry.d.ts +4 -0
- package/dist/chat/plugins/state.d.ts +3 -5
- package/dist/chat/plugins/task-callback.d.ts +5 -0
- package/dist/chat/plugins/task-message.d.ts +23 -0
- package/dist/chat/plugins/task-queue.d.ts +5 -0
- package/dist/chat/plugins/task-runner.d.ts +12 -0
- package/dist/chat/plugins/task-signing.d.ts +31 -0
- package/dist/chat/plugins/types.d.ts +1 -0
- package/dist/chat/plugins/validation.d.ts +5 -0
- package/dist/chat/prompt.d.ts +15 -1
- package/dist/chat/requester.d.ts +6 -5
- package/dist/chat/respond-helpers.d.ts +2 -0
- package/dist/chat/respond.d.ts +13 -2
- package/dist/chat/runtime/agent-continue-runner.d.ts +4 -0
- package/dist/chat/runtime/reply-executor.d.ts +5 -1
- package/dist/chat/runtime/slack-resume.d.ts +10 -2
- package/dist/chat/runtime/slack-runtime.d.ts +6 -1
- package/dist/chat/sandbox/egress-credentials.d.ts +8 -8
- package/dist/chat/sandbox/sandbox.d.ts +2 -2
- package/dist/chat/sentry.d.ts +1 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +2 -1
- package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
- package/dist/chat/services/subscribed-decision.d.ts +2 -2
- package/dist/chat/services/turn-session-record.d.ts +11 -7
- package/dist/chat/sql/db.d.ts +3 -0
- package/dist/chat/sql/executor.d.ts +7 -0
- package/dist/chat/sql/neon.d.ts +2 -4
- package/dist/chat/sql/postgres.d.ts +6 -0
- package/dist/chat/state/turn-session.d.ts +8 -5
- package/dist/chat/task-execution/state.d.ts +7 -2
- package/dist/chat/task-execution/worker.d.ts +1 -1
- package/dist/chat/tools/agent-tools.d.ts +9 -2
- package/dist/chat/tools/slack/context.d.ts +2 -2
- package/dist/chat/tools/types.d.ts +7 -4
- package/dist/chat/vercel-queue-client.d.ts +3 -0
- package/dist/{chunk-YOHFWWBV.js → chunk-2ECJXSVQ.js} +5 -107
- package/dist/{chunk-OR6NQJ5E.js → chunk-4SCWV7TJ.js} +3 -3
- package/dist/chunk-4UO6FK4G.js +64 -0
- package/dist/chunk-56TBVRJG.js +115 -0
- package/dist/{chunk-3BYAPS6B.js → chunk-EJN6G5A2.js} +17 -11
- package/dist/{chunk-SQGMG7OD.js → chunk-HHDUKWVG.js} +508 -149
- package/dist/{chunk-6UP2Z2RZ.js → chunk-JBASI5VV.js} +7 -7
- package/dist/chunk-KNFROR7R.js +127 -0
- package/dist/{chunk-HYHKTFG2.js → chunk-KOIMO7S3.js} +186 -910
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/chunk-NFTMTIP3.js +964 -0
- package/dist/chunk-NYKJ3KON.js +1082 -0
- package/dist/{chunk-SJHUF3DP.js → chunk-OJ53FYVG.js} +2 -10
- package/dist/{chunk-KVZL5NZS.js → chunk-Q3XNY442.js} +17 -7
- package/dist/{chunk-YRDS7VKO.js → chunk-Q6XFTRV5.js} +2 -2
- package/dist/chunk-R6Z5XWY3.js +1076 -0
- package/dist/chunk-RV5RYIJW.js +56 -0
- package/dist/chunk-SG5WAA7H.js +132 -0
- package/dist/chunk-ST6YNAXG.js +54 -0
- package/dist/{chunk-GM7HTXYC.js → chunk-T77LUIX3.js} +148 -151
- package/dist/{chunk-CYUI7JU5.js → chunk-VALUBQ7R.js} +22 -30
- package/dist/chunk-XBBC6W45.js +71 -0
- package/dist/chunk-Y2CM7HXH.js +111 -0
- package/dist/{chunk-F6HWCPOC.js → chunk-Y5OFBCBZ.js} +1 -1
- package/dist/{chunk-M4FLLXXD.js → chunk-Z4CIQ3EB.js} +5 -1
- package/dist/{chunk-7Q5YOUUT.js → chunk-ZLMBNBUG.js} +146 -52
- package/dist/{chunk-2LUZA3LY.js → chunk-ZQB37HUX.js} +11 -11
- package/dist/cli/chat.js +87 -8
- package/dist/cli/check.js +8 -7
- package/dist/cli/env.js +4 -53
- package/dist/cli/init.js +6 -1
- package/dist/cli/main.js +84 -0
- package/dist/cli/plugins.js +244 -0
- package/dist/cli/run.js +5 -52
- package/dist/cli/snapshot-warmup.js +12 -11
- package/dist/cli/upgrade.js +385 -26
- package/dist/db-7A7PFRGL.js +17 -0
- package/dist/deployment.d.ts +1 -0
- package/dist/handlers/sandbox-egress-route.d.ts +4 -0
- package/dist/handlers/slack-webhook.d.ts +4 -0
- package/dist/handlers/webhooks.d.ts +6 -13
- package/dist/instrumentation.js +14 -18
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +67 -101
- package/dist/plugin-module.d.ts +21 -0
- package/dist/plugins-PZMDS7AT.js +15 -0
- package/dist/plugins.d.ts +9 -5
- package/dist/registry-OIPAJU2O.js +46 -0
- package/dist/reporting/conversations.d.ts +3 -3
- package/dist/reporting.d.ts +6 -5
- package/dist/reporting.js +42 -28
- package/dist/{runner-27NP2TEO.js → runner-KPLNHDCV.js} +77 -19
- package/dist/sentry-4CP5NNQ5.js +31 -0
- package/dist/validation-SLA6IGF7.js +15 -0
- package/dist/vercel.js +1 -1
- package/package.json +14 -11
- package/dist/chat/conversations/configured.d.ts +0 -5
- package/dist/chat/conversations/state.d.ts +0 -4
- package/dist/chunk-2KG3PWR4.js +0 -17
- package/dist/chunk-JL2SLRAT.js +0 -1970
package/dist/cli/run.js
CHANGED
|
@@ -1,55 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
error: console.error
|
|
7
|
-
};
|
|
8
|
-
function normalizeCliArgv(argv) {
|
|
9
|
-
return argv[0] === "--" ? argv.slice(1) : argv;
|
|
10
|
-
}
|
|
11
|
-
async function runCli(argv, handlers, io = DEFAULT_IO) {
|
|
12
|
-
const [command, subcommand, ...rest] = normalizeCliArgv(argv);
|
|
13
|
-
if (command === "chat") {
|
|
14
|
-
return await handlers.runChat(
|
|
15
|
-
subcommand === void 0 ? [] : [subcommand, ...rest]
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
if (command === "init") {
|
|
19
|
-
if (!subcommand || rest.length > 0) {
|
|
20
|
-
io.error(CLI_USAGE);
|
|
21
|
-
return 1;
|
|
22
|
-
}
|
|
23
|
-
await handlers.runInit(subcommand);
|
|
24
|
-
return 0;
|
|
25
|
-
}
|
|
26
|
-
if (command === "snapshot" && subcommand === "create") {
|
|
27
|
-
if (rest.length > 0) {
|
|
28
|
-
io.error(CLI_USAGE);
|
|
29
|
-
return 1;
|
|
30
|
-
}
|
|
31
|
-
await handlers.runSnapshotCreate();
|
|
32
|
-
return 0;
|
|
33
|
-
}
|
|
34
|
-
if (command === "check") {
|
|
35
|
-
if (rest.length > 0) {
|
|
36
|
-
io.error(CLI_USAGE);
|
|
37
|
-
return 1;
|
|
38
|
-
}
|
|
39
|
-
await handlers.runCheck(subcommand);
|
|
40
|
-
return 0;
|
|
41
|
-
}
|
|
42
|
-
if (command === "upgrade") {
|
|
43
|
-
if (subcommand || rest.length > 0) {
|
|
44
|
-
io.error(CLI_USAGE);
|
|
45
|
-
return 1;
|
|
46
|
-
}
|
|
47
|
-
await handlers.runUpgrade();
|
|
48
|
-
return 0;
|
|
49
|
-
}
|
|
50
|
-
io.error(CLI_USAGE);
|
|
51
|
-
return 1;
|
|
52
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
CLI_USAGE,
|
|
3
|
+
runCli
|
|
4
|
+
} from "../chunk-4UO6FK4G.js";
|
|
5
|
+
import "../chunk-MLKGABMK.js";
|
|
53
6
|
export {
|
|
54
7
|
CLI_USAGE,
|
|
55
8
|
runCli
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveRuntimeDependencySnapshot
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-JBASI5VV.js";
|
|
4
4
|
import "../chunk-G3E7SCME.js";
|
|
5
|
+
import {
|
|
6
|
+
disconnectStateAdapter
|
|
7
|
+
} from "../chunk-Y5OFBCBZ.js";
|
|
8
|
+
import "../chunk-T77LUIX3.js";
|
|
5
9
|
import {
|
|
6
10
|
getPluginProviders,
|
|
7
11
|
getPluginRuntimeDependencies,
|
|
8
12
|
getPluginRuntimePostinstall
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-3BYAPS6B.js";
|
|
17
|
-
import "../chunk-SJHUF3DP.js";
|
|
18
|
-
import "../chunk-2KG3PWR4.js";
|
|
13
|
+
} from "../chunk-ZLMBNBUG.js";
|
|
14
|
+
import "../chunk-VALUBQ7R.js";
|
|
15
|
+
import "../chunk-Q3XNY442.js";
|
|
16
|
+
import "../chunk-EJN6G5A2.js";
|
|
17
|
+
import "../chunk-OJ53FYVG.js";
|
|
18
|
+
import "../chunk-ST6YNAXG.js";
|
|
19
|
+
import "../chunk-MLKGABMK.js";
|
|
19
20
|
|
|
20
21
|
// src/cli/snapshot-warmup.ts
|
|
21
22
|
var DEFAULT_RUNTIME = "node22";
|
package/dist/cli/upgrade.js
CHANGED
|
@@ -1,33 +1,59 @@
|
|
|
1
1
|
import {
|
|
2
|
-
coerceThreadConversationState
|
|
3
|
-
} from "../chunk-M4FLLXXD.js";
|
|
4
|
-
import {
|
|
5
|
-
JUNIOR_THREAD_STATE_TTL_MS,
|
|
6
|
-
createNeonJuniorSqlExecutor,
|
|
7
|
-
createSqlStore,
|
|
8
|
-
createStateConversationStore,
|
|
9
2
|
getConversation,
|
|
3
|
+
listConversationsByActivity,
|
|
4
|
+
recordConversationActivity,
|
|
10
5
|
requestConversationWork
|
|
11
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-R6Z5XWY3.js";
|
|
12
7
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "../chunk-
|
|
8
|
+
JUNIOR_THREAD_STATE_TTL_MS,
|
|
9
|
+
coerceThreadConversationState
|
|
10
|
+
} from "../chunk-Z4CIQ3EB.js";
|
|
11
|
+
import {
|
|
12
|
+
defineJuniorPlugins,
|
|
13
|
+
pluginCatalogConfigFromEnv,
|
|
14
|
+
pluginCatalogConfigFromPluginSet,
|
|
15
|
+
pluginRuntimeRegistrationsFromPluginSet
|
|
16
|
+
} from "../chunk-SG5WAA7H.js";
|
|
17
|
+
import {
|
|
18
|
+
createPluginLogger,
|
|
19
|
+
createPluginState
|
|
20
|
+
} from "../chunk-56TBVRJG.js";
|
|
21
|
+
import {
|
|
22
|
+
createJuniorSqlExecutor,
|
|
23
|
+
createSqlStore,
|
|
24
|
+
getDb
|
|
25
|
+
} from "../chunk-NYKJ3KON.js";
|
|
16
26
|
import {
|
|
17
27
|
disconnectStateAdapter,
|
|
18
28
|
getConnectedStateContext
|
|
19
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-Y5OFBCBZ.js";
|
|
30
|
+
import {
|
|
31
|
+
parseDestination,
|
|
32
|
+
sameDestination
|
|
33
|
+
} from "../chunk-Q6XFTRV5.js";
|
|
20
34
|
import {
|
|
21
35
|
getChatConfig
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import
|
|
36
|
+
} from "../chunk-T77LUIX3.js";
|
|
37
|
+
import {
|
|
38
|
+
loadAppPluginSet
|
|
39
|
+
} from "../chunk-Y2CM7HXH.js";
|
|
40
|
+
import {
|
|
41
|
+
getPluginMigrationRoots,
|
|
42
|
+
setPluginCatalogConfig
|
|
43
|
+
} from "../chunk-ZLMBNBUG.js";
|
|
44
|
+
import "../chunk-VALUBQ7R.js";
|
|
45
|
+
import "../chunk-Q3XNY442.js";
|
|
24
46
|
import {
|
|
25
47
|
isRecord,
|
|
26
48
|
toOptionalNumber,
|
|
27
49
|
toOptionalString
|
|
28
|
-
} from "../chunk-
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
50
|
+
} from "../chunk-EJN6G5A2.js";
|
|
51
|
+
import "../chunk-OJ53FYVG.js";
|
|
52
|
+
import "../chunk-ST6YNAXG.js";
|
|
53
|
+
import "../chunk-MLKGABMK.js";
|
|
54
|
+
|
|
55
|
+
// src/cli/upgrade.ts
|
|
56
|
+
import { createJiti } from "jiti";
|
|
31
57
|
|
|
32
58
|
// src/chat/conversations/sql/backfill.ts
|
|
33
59
|
async function backfillToSql(args) {
|
|
@@ -44,6 +70,17 @@ async function backfillToSql(args) {
|
|
|
44
70
|
};
|
|
45
71
|
}
|
|
46
72
|
|
|
73
|
+
// src/chat/conversations/state.ts
|
|
74
|
+
function createStateConversationStore(state) {
|
|
75
|
+
return {
|
|
76
|
+
get: (args) => getConversation({ ...args, state }),
|
|
77
|
+
recordActivity: (args) => recordConversationActivity({ ...args, state }),
|
|
78
|
+
recordExecution: async () => {
|
|
79
|
+
},
|
|
80
|
+
listByActivity: (args) => listConversationsByActivity({ ...args, state })
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
47
84
|
// src/cli/upgrade/migrations/conversations-sql.ts
|
|
48
85
|
var CONVERSATION_BACKFILL_LIMIT = 1e4;
|
|
49
86
|
var REQUIRED_SQL_DATABASE_URL_MESSAGE = "Junior SQL database URL is required for conversation metadata upgrade. Set JUNIOR_DATABASE_URL or DATABASE_URL.";
|
|
@@ -60,8 +97,9 @@ async function migrateConversationsToSql(context, options = {}) {
|
|
|
60
97
|
let closeTarget;
|
|
61
98
|
if (!target) {
|
|
62
99
|
const databaseUrl = requireConversationSqlDatabaseUrl(context);
|
|
63
|
-
const executor =
|
|
64
|
-
connectionString: databaseUrl
|
|
100
|
+
const executor = createJuniorSqlExecutor({
|
|
101
|
+
connectionString: databaseUrl,
|
|
102
|
+
driver: context.sqlDriver ?? getChatConfig().sql.driver
|
|
65
103
|
});
|
|
66
104
|
target = createSqlStore(executor);
|
|
67
105
|
closeTarget = () => executor.close();
|
|
@@ -88,6 +126,294 @@ var sqlConversationMigration = {
|
|
|
88
126
|
run: migrateConversationsToSql
|
|
89
127
|
};
|
|
90
128
|
|
|
129
|
+
// src/cli/upgrade/migrations/upgrade-plugins.ts
|
|
130
|
+
function unique(values) {
|
|
131
|
+
return [...new Set(values)];
|
|
132
|
+
}
|
|
133
|
+
function baseCatalogConfig(context) {
|
|
134
|
+
return context.pluginCatalogConfig ?? (context.pluginSet ? pluginCatalogConfigFromPluginSet(context.pluginSet) : pluginCatalogConfigFromEnv());
|
|
135
|
+
}
|
|
136
|
+
function inlinePluginName(definition) {
|
|
137
|
+
return definition.manifest.name;
|
|
138
|
+
}
|
|
139
|
+
function mergeInlineManifests(left, right) {
|
|
140
|
+
const merged = /* @__PURE__ */ new Map();
|
|
141
|
+
for (const definition of [...left ?? [], ...right ?? []]) {
|
|
142
|
+
merged.set(inlinePluginName(definition), definition);
|
|
143
|
+
}
|
|
144
|
+
return merged.size > 0 ? [...merged.values()] : void 0;
|
|
145
|
+
}
|
|
146
|
+
function mergeCatalogConfig(base, added) {
|
|
147
|
+
if (!base) {
|
|
148
|
+
return added;
|
|
149
|
+
}
|
|
150
|
+
if (!added) {
|
|
151
|
+
return base;
|
|
152
|
+
}
|
|
153
|
+
const inlineManifests = mergeInlineManifests(
|
|
154
|
+
base.inlineManifests,
|
|
155
|
+
added.inlineManifests
|
|
156
|
+
);
|
|
157
|
+
const packages = unique([
|
|
158
|
+
...base.packages ?? [],
|
|
159
|
+
...added.packages ?? []
|
|
160
|
+
]);
|
|
161
|
+
const manifests = base.manifests || added.manifests ? { ...base.manifests, ...added.manifests } : void 0;
|
|
162
|
+
return {
|
|
163
|
+
...inlineManifests ? { inlineManifests } : {},
|
|
164
|
+
...packages.length > 0 ? { packages } : {},
|
|
165
|
+
...manifests ? { manifests } : {}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function packageNamesFromContext(context, catalog) {
|
|
169
|
+
return unique([
|
|
170
|
+
...context.pluginSet?.packageNames ?? [],
|
|
171
|
+
...catalog?.packages ?? []
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
async function resolveUpgradePlugins(context) {
|
|
175
|
+
const catalog = baseCatalogConfig(context);
|
|
176
|
+
const packageNames = packageNamesFromContext(context, catalog);
|
|
177
|
+
const registrations = context.pluginSet?.registrations ?? [];
|
|
178
|
+
const manifests = context.pluginSet?.manifests || catalog?.manifests ? {
|
|
179
|
+
...catalog?.manifests,
|
|
180
|
+
...context.pluginSet?.manifests
|
|
181
|
+
} : void 0;
|
|
182
|
+
const pluginSet = packageNames.length > 0 || registrations.length > 0 || context.pluginSet ? defineJuniorPlugins(
|
|
183
|
+
[...packageNames, ...registrations],
|
|
184
|
+
manifests ? { manifests } : {}
|
|
185
|
+
) : void 0;
|
|
186
|
+
return {
|
|
187
|
+
pluginCatalogConfig: mergeCatalogConfig(
|
|
188
|
+
catalog,
|
|
189
|
+
pluginCatalogConfigFromPluginSet(pluginSet)
|
|
190
|
+
),
|
|
191
|
+
...pluginSet ? { pluginSet } : {}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/cli/upgrade/migrations/plugin-storage.ts
|
|
196
|
+
function emptyResult() {
|
|
197
|
+
return {
|
|
198
|
+
existing: 0,
|
|
199
|
+
migrated: 0,
|
|
200
|
+
missing: 0,
|
|
201
|
+
scanned: 0
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function addResult(left, right) {
|
|
205
|
+
return {
|
|
206
|
+
existing: left.existing + right.existing,
|
|
207
|
+
migrated: left.migrated + right.migrated,
|
|
208
|
+
missing: left.missing + right.missing,
|
|
209
|
+
scanned: left.scanned + right.scanned,
|
|
210
|
+
...left.skipped !== void 0 || right.skipped !== void 0 ? { skipped: (left.skipped ?? 0) + (right.skipped ?? 0) } : {}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function dbForPlugin(context, sqlUrlDb) {
|
|
214
|
+
return context.db ?? sqlUrlDb ?? getDb();
|
|
215
|
+
}
|
|
216
|
+
async function runPluginStorageMigrations(context) {
|
|
217
|
+
const { pluginCatalogConfig, pluginSet } = await resolveUpgradePlugins(context);
|
|
218
|
+
if (!pluginSet) {
|
|
219
|
+
return emptyResult();
|
|
220
|
+
}
|
|
221
|
+
const previousConfig = setPluginCatalogConfig(pluginCatalogConfig);
|
|
222
|
+
const ownedExecutor = context.db || !context.sqlDatabaseUrl ? void 0 : createJuniorSqlExecutor({
|
|
223
|
+
connectionString: context.sqlDatabaseUrl,
|
|
224
|
+
driver: context.sqlDriver ?? getChatConfig().sql.driver
|
|
225
|
+
});
|
|
226
|
+
const sqlUrlDb = ownedExecutor ? ownedExecutor.db() : void 0;
|
|
227
|
+
try {
|
|
228
|
+
let result = emptyResult();
|
|
229
|
+
const plugins = pluginRuntimeRegistrationsFromPluginSet(pluginSet).filter((plugin) => plugin.hooks?.migrateStorage).sort(
|
|
230
|
+
(left, right) => left.manifest.name.localeCompare(right.manifest.name)
|
|
231
|
+
);
|
|
232
|
+
for (const plugin of plugins) {
|
|
233
|
+
const pluginName = plugin.manifest.name;
|
|
234
|
+
const hook = plugin.hooks?.migrateStorage;
|
|
235
|
+
if (!hook) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const db = dbForPlugin(context, sqlUrlDb);
|
|
239
|
+
const pluginResult = await hook({
|
|
240
|
+
db,
|
|
241
|
+
log: createPluginLogger(pluginName),
|
|
242
|
+
plugin: { name: pluginName },
|
|
243
|
+
state: createPluginState(pluginName, context.stateAdapter)
|
|
244
|
+
});
|
|
245
|
+
if (pluginResult) {
|
|
246
|
+
result = addResult(result, pluginResult);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
} finally {
|
|
251
|
+
setPluginCatalogConfig(previousConfig);
|
|
252
|
+
await ownedExecutor?.close();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
var pluginStorageMigration = {
|
|
256
|
+
name: "run-plugin-storage-migrations",
|
|
257
|
+
run: runPluginStorageMigrations
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// src/chat/plugins/db.ts
|
|
261
|
+
import { createHash } from "crypto";
|
|
262
|
+
import { readdirSync, readFileSync, statSync } from "fs";
|
|
263
|
+
import path from "path";
|
|
264
|
+
import { z } from "zod";
|
|
265
|
+
var PLUGIN_SCHEMA_LOCK_NAME = "junior_plugin_schema";
|
|
266
|
+
var MIGRATION_FILENAME_RE = /^[0-9]{4}_[a-z0-9_]+\.sql$/;
|
|
267
|
+
var migrationRecordSchema = z.object({
|
|
268
|
+
id: z.string().min(1),
|
|
269
|
+
checksum: z.string().min(1)
|
|
270
|
+
}).strict();
|
|
271
|
+
function checksumSql(sql) {
|
|
272
|
+
return createHash("sha256").update(sql).digest("hex");
|
|
273
|
+
}
|
|
274
|
+
function parseStoredMigrationRecord(value) {
|
|
275
|
+
return migrationRecordSchema.parse(value);
|
|
276
|
+
}
|
|
277
|
+
function assertMigrationFilename(filename) {
|
|
278
|
+
if (!filename || filename !== path.basename(filename) || !MIGRATION_FILENAME_RE.test(filename)) {
|
|
279
|
+
throw new Error(`Plugin migration filename "${filename}" is invalid`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function assertUniqueMigrationIds(migrations) {
|
|
283
|
+
const seen = /* @__PURE__ */ new Set();
|
|
284
|
+
for (const migration of migrations) {
|
|
285
|
+
if (seen.has(migration.id)) {
|
|
286
|
+
throw new Error(`Duplicate plugin migration id ${migration.id}`);
|
|
287
|
+
}
|
|
288
|
+
seen.add(migration.id);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function migrationId(pluginName, filename) {
|
|
292
|
+
return `plugin:${pluginName}/${filename}`;
|
|
293
|
+
}
|
|
294
|
+
function createMigrationTableSql() {
|
|
295
|
+
return `
|
|
296
|
+
CREATE TABLE IF NOT EXISTS junior_schema_migrations (
|
|
297
|
+
id TEXT PRIMARY KEY,
|
|
298
|
+
checksum TEXT NOT NULL,
|
|
299
|
+
applied_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
300
|
+
)
|
|
301
|
+
`;
|
|
302
|
+
}
|
|
303
|
+
async function listAppliedMigrations(executor) {
|
|
304
|
+
const rows = await executor.query(
|
|
305
|
+
"SELECT id, checksum FROM junior_schema_migrations ORDER BY id ASC"
|
|
306
|
+
);
|
|
307
|
+
const records = /* @__PURE__ */ new Map();
|
|
308
|
+
for (const row of rows) {
|
|
309
|
+
const record = parseStoredMigrationRecord(row);
|
|
310
|
+
records.set(record.id, record);
|
|
311
|
+
}
|
|
312
|
+
return records;
|
|
313
|
+
}
|
|
314
|
+
async function applyPluginMigration(executor, migration) {
|
|
315
|
+
await executor.transaction(async () => {
|
|
316
|
+
await executor.execute(migration.sql);
|
|
317
|
+
await executor.execute(
|
|
318
|
+
"INSERT INTO junior_schema_migrations (id, checksum) VALUES ($1, $2)",
|
|
319
|
+
[migration.id, migration.checksum]
|
|
320
|
+
);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function readPluginMigrations(root) {
|
|
324
|
+
const migrationsDir = root.dir;
|
|
325
|
+
let stat;
|
|
326
|
+
try {
|
|
327
|
+
stat = statSync(migrationsDir);
|
|
328
|
+
} catch {
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
if (!stat.isDirectory()) {
|
|
332
|
+
throw new Error(
|
|
333
|
+
`Plugin "${root.pluginName}" migrations path is not a directory`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
return readdirSync(migrationsDir).filter((filename) => filename.endsWith(".sql")).sort((left, right) => left.localeCompare(right)).map((filename) => {
|
|
337
|
+
assertMigrationFilename(filename);
|
|
338
|
+
const sql = readFileSync(path.join(migrationsDir, filename), "utf8");
|
|
339
|
+
if (!sql.trim()) {
|
|
340
|
+
throw new Error(
|
|
341
|
+
`Plugin "${root.pluginName}" migration "${filename}" is empty`
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
checksum: checksumSql(sql),
|
|
346
|
+
filename,
|
|
347
|
+
id: migrationId(root.pluginName, filename),
|
|
348
|
+
pluginName: root.pluginName,
|
|
349
|
+
sql
|
|
350
|
+
};
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async function migratePluginSchemas(executor, migrations) {
|
|
354
|
+
assertUniqueMigrationIds(migrations);
|
|
355
|
+
const result = {
|
|
356
|
+
existing: 0,
|
|
357
|
+
migrated: 0,
|
|
358
|
+
scanned: migrations.length
|
|
359
|
+
};
|
|
360
|
+
await executor.withLock(PLUGIN_SCHEMA_LOCK_NAME, async () => {
|
|
361
|
+
await executor.execute(createMigrationTableSql());
|
|
362
|
+
const applied = await listAppliedMigrations(executor);
|
|
363
|
+
for (const migration of migrations) {
|
|
364
|
+
const existing = applied.get(migration.id);
|
|
365
|
+
if (existing) {
|
|
366
|
+
if (existing.checksum !== migration.checksum) {
|
|
367
|
+
throw new Error(`Plugin migration ${migration.id} checksum changed`);
|
|
368
|
+
}
|
|
369
|
+
result.existing++;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
await applyPluginMigration(executor, migration);
|
|
373
|
+
result.migrated++;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// src/cli/upgrade/migrations/plugin-sql.ts
|
|
380
|
+
var REQUIRED_SQL_DATABASE_URL_MESSAGE2 = "Junior SQL database URL is required for plugin schema migration. Set JUNIOR_DATABASE_URL or DATABASE_URL.";
|
|
381
|
+
function requirePluginSqlDatabaseUrl(context) {
|
|
382
|
+
const databaseUrl = context.sqlDatabaseUrl ?? getChatConfig().sql.databaseUrl;
|
|
383
|
+
if (!databaseUrl) {
|
|
384
|
+
throw new Error(REQUIRED_SQL_DATABASE_URL_MESSAGE2);
|
|
385
|
+
}
|
|
386
|
+
return databaseUrl;
|
|
387
|
+
}
|
|
388
|
+
async function migratePluginsToSql(context) {
|
|
389
|
+
const databaseUrl = requirePluginSqlDatabaseUrl(context);
|
|
390
|
+
const { pluginCatalogConfig } = await resolveUpgradePlugins(context);
|
|
391
|
+
const previousConfig = setPluginCatalogConfig(pluginCatalogConfig);
|
|
392
|
+
const executor = createJuniorSqlExecutor({
|
|
393
|
+
connectionString: databaseUrl,
|
|
394
|
+
driver: context.sqlDriver ?? getChatConfig().sql.driver
|
|
395
|
+
});
|
|
396
|
+
try {
|
|
397
|
+
const migrations = getPluginMigrationRoots().flatMap(
|
|
398
|
+
(root) => readPluginMigrations(root)
|
|
399
|
+
);
|
|
400
|
+
const result = await migratePluginSchemas(executor, migrations);
|
|
401
|
+
return {
|
|
402
|
+
existing: result.existing,
|
|
403
|
+
migrated: result.migrated,
|
|
404
|
+
missing: 0,
|
|
405
|
+
scanned: result.scanned
|
|
406
|
+
};
|
|
407
|
+
} finally {
|
|
408
|
+
setPluginCatalogConfig(previousConfig);
|
|
409
|
+
await executor.close();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
var sqlPluginMigration = {
|
|
413
|
+
name: "migrate-plugin-sql",
|
|
414
|
+
run: migratePluginsToSql
|
|
415
|
+
};
|
|
416
|
+
|
|
91
417
|
// src/cli/upgrade/migrations/redis-conversation-state.ts
|
|
92
418
|
var CONVERSATION_PREFIX = "junior:conversation";
|
|
93
419
|
var CONVERSATION_SCHEMA_VERSION = 1;
|
|
@@ -624,10 +950,34 @@ var redisConversationStateMigration = {
|
|
|
624
950
|
var DEFAULT_IO = {
|
|
625
951
|
info: console.log
|
|
626
952
|
};
|
|
953
|
+
var localPluginLoader = createJiti(import.meta.url, { moduleCache: false });
|
|
627
954
|
var MIGRATIONS = [
|
|
628
955
|
redisConversationStateMigration,
|
|
629
|
-
sqlConversationMigration
|
|
956
|
+
sqlConversationMigration,
|
|
957
|
+
sqlPluginMigration,
|
|
958
|
+
pluginStorageMigration
|
|
630
959
|
];
|
|
960
|
+
function isMissingVirtualConfig(error) {
|
|
961
|
+
if (!(error instanceof Error)) {
|
|
962
|
+
return false;
|
|
963
|
+
}
|
|
964
|
+
const code = error.code;
|
|
965
|
+
return (code === "ERR_PACKAGE_IMPORT_NOT_DEFINED" || code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && error.message.includes("#junior/config");
|
|
966
|
+
}
|
|
967
|
+
async function resolveUpgradePluginSet() {
|
|
968
|
+
try {
|
|
969
|
+
const mod = await import("#junior/config");
|
|
970
|
+
return mod.pluginSet;
|
|
971
|
+
} catch (error) {
|
|
972
|
+
if (!isMissingVirtualConfig(error)) {
|
|
973
|
+
throw error;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return await loadAppPluginSet(
|
|
977
|
+
process.cwd(),
|
|
978
|
+
async (moduleRef) => localPluginLoader.import(moduleRef.importPath)
|
|
979
|
+
);
|
|
980
|
+
}
|
|
631
981
|
function formatMigrationResult(result) {
|
|
632
982
|
const fields = [
|
|
633
983
|
`scanned=${result.scanned}`,
|
|
@@ -641,29 +991,38 @@ function formatMigrationResult(result) {
|
|
|
641
991
|
return fields.join(" ");
|
|
642
992
|
}
|
|
643
993
|
async function runUpgradeMigrations(context) {
|
|
644
|
-
|
|
994
|
+
const plugins = await resolveUpgradePlugins(context);
|
|
995
|
+
const migrationContext = { ...context, ...plugins };
|
|
996
|
+
migrationContext.sqlDatabaseUrl ??= requireConversationSqlDatabaseUrl(migrationContext);
|
|
645
997
|
const results = [];
|
|
646
998
|
for (const migration of MIGRATIONS) {
|
|
647
|
-
|
|
648
|
-
const result = await migration.run(
|
|
649
|
-
|
|
999
|
+
migrationContext.io.info(`Running migration ${migration.name}...`);
|
|
1000
|
+
const result = await migration.run(migrationContext);
|
|
1001
|
+
migrationContext.io.info(
|
|
650
1002
|
`Finished migration ${migration.name}: ${formatMigrationResult(result)}`
|
|
651
1003
|
);
|
|
652
1004
|
results.push(result);
|
|
653
1005
|
}
|
|
654
1006
|
return results;
|
|
655
1007
|
}
|
|
656
|
-
async function runUpgrade(io = DEFAULT_IO) {
|
|
1008
|
+
async function runUpgrade(io = DEFAULT_IO, options = {}) {
|
|
657
1009
|
try {
|
|
658
1010
|
const { redisStateAdapter, stateAdapter } = await getConnectedStateContext();
|
|
1011
|
+
const pluginSet = options.pluginSet === void 0 ? await resolveUpgradePluginSet() : options.pluginSet ?? void 0;
|
|
659
1012
|
io.info("Running Junior upgrade migrations...");
|
|
660
|
-
await runUpgradeMigrations({
|
|
1013
|
+
await runUpgradeMigrations({
|
|
1014
|
+
io,
|
|
1015
|
+
pluginSet,
|
|
1016
|
+
redisStateAdapter,
|
|
1017
|
+
stateAdapter
|
|
1018
|
+
});
|
|
661
1019
|
io.info("Junior upgrade complete.");
|
|
662
1020
|
} finally {
|
|
663
1021
|
await disconnectStateAdapter();
|
|
664
1022
|
}
|
|
665
1023
|
}
|
|
666
1024
|
export {
|
|
1025
|
+
resolveUpgradePluginSet,
|
|
667
1026
|
runUpgrade,
|
|
668
1027
|
runUpgradeMigrations
|
|
669
1028
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
closeDb,
|
|
3
|
+
getConversationStore,
|
|
4
|
+
getDb
|
|
5
|
+
} from "./chunk-NYKJ3KON.js";
|
|
6
|
+
import "./chunk-Q6XFTRV5.js";
|
|
7
|
+
import "./chunk-T77LUIX3.js";
|
|
8
|
+
import "./chunk-VALUBQ7R.js";
|
|
9
|
+
import "./chunk-EJN6G5A2.js";
|
|
10
|
+
import "./chunk-OJ53FYVG.js";
|
|
11
|
+
import "./chunk-ST6YNAXG.js";
|
|
12
|
+
import "./chunk-MLKGABMK.js";
|
|
13
|
+
export {
|
|
14
|
+
closeDb,
|
|
15
|
+
getConversationStore,
|
|
16
|
+
getDb
|
|
17
|
+
};
|
package/dist/deployment.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
|
|
2
2
|
export declare const JUNIOR_HEARTBEAT_CRON_SCHEDULE = "* * * * *";
|
|
3
3
|
export declare const JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE = "/api/internal/agent/continue";
|
|
4
|
+
export declare const JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE = "/api/internal/plugin/tasks";
|
|
4
5
|
export declare const LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION = "api/internal/agent/continue.ts";
|
|
5
6
|
/** Resolve the deployment version used for release and telemetry correlation. */
|
|
6
7
|
export declare function getDeploymentServiceVersion(): string | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type SlackWebhookServices } from "@/chat/ingress/slack-webhook";
|
|
2
|
+
import type { WaitUntilFn } from "@/handlers/types";
|
|
3
|
+
/** Handle the production Slack webhook route. */
|
|
4
|
+
export declare function POST(request: Request, waitUntil: WaitUntilFn, services: SlackWebhookServices): Promise<Response>;
|
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
import type { SlackAdapter } from "@chat-adapter/slack";
|
|
2
|
-
import { type SlackWebhookServices } from "@/chat/ingress/slack-webhook";
|
|
3
2
|
import { JuniorChat } from "@/chat/ingress/junior-chat";
|
|
4
3
|
import type { WaitUntilFn } from "@/handlers/types";
|
|
5
|
-
type
|
|
4
|
+
type ChatSdkBot = JuniorChat<{
|
|
6
5
|
slack: SlackAdapter;
|
|
7
6
|
}>;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* kept for integration tests that still exercise Chat SDK fixtures directly.
|
|
14
|
-
* The optional `services` parameter carries app-scoped runtime services.
|
|
15
|
-
*/
|
|
16
|
-
export declare function handlePlatformWebhook(request: Request, platform: string, waitUntil: WaitUntilFn, legacyBot?: LegacyChatSdkBot, services?: SlackWebhookServices): Promise<Response>;
|
|
17
|
-
/** Handle a platform webhook request from the app route. */
|
|
18
|
-
export declare function POST(request: Request, platform: string, waitUntil: WaitUntilFn, services?: SlackWebhookServices): Promise<Response>;
|
|
7
|
+
type WebhookRunner = () => Promise<Response>;
|
|
8
|
+
/** Run a platform webhook with shared request tracing and error logging. */
|
|
9
|
+
export declare function handleWebhookRequest(request: Request, platform: string, run: WebhookRunner): Promise<Response>;
|
|
10
|
+
/** Handle a Chat SDK webhook fixture through the shared webhook wrapper. */
|
|
11
|
+
export declare function handleChatSdkPlatformWebhook(request: Request, platform: string, waitUntil: WaitUntilFn, chat: ChatSdkBot): Promise<Response>;
|
|
19
12
|
export {};
|