@sentry/junior 0.74.1 → 0.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-hooks-2HEB4C3Q.js +33 -0
- package/dist/api-reference.d.ts +1 -1
- package/dist/app.js +5211 -5316
- package/dist/build/copy-build-content.d.ts +1 -1
- package/dist/chat/agent-dispatch/context.d.ts +2 -3
- package/dist/chat/agent-dispatch/types.d.ts +2 -1
- package/dist/chat/config.d.ts +2 -0
- package/dist/chat/conversations/configured.d.ts +2 -0
- package/dist/chat/credentials/subject.d.ts +3 -3
- package/dist/chat/plugins/agent-hooks.d.ts +13 -13
- package/dist/chat/plugins/credential-hooks.d.ts +6 -6
- package/dist/chat/plugins/db.d.ts +31 -0
- package/dist/chat/plugins/logging.d.ts +2 -2
- package/dist/chat/plugins/package-discovery.d.ts +2 -1
- package/dist/chat/plugins/registry.d.ts +4 -0
- package/dist/chat/plugins/state.d.ts +3 -5
- package/dist/chat/plugins/types.d.ts +1 -0
- package/dist/chat/plugins/validation.d.ts +5 -0
- package/dist/chat/prompt.d.ts +11 -1
- package/dist/chat/respond.d.ts +10 -1
- 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/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/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 +2 -2
- package/dist/chat/tools/types.d.ts +3 -0
- package/dist/{chunk-7Q5YOUUT.js → chunk-2RWFUS5F.js} +47 -10
- package/dist/{chunk-YRDS7VKO.js → chunk-62FUNJYS.js} +3 -54
- package/dist/{chunk-M4FLLXXD.js → chunk-74HO27II.js} +1 -1
- package/dist/chunk-BNJIEFQC.js +115 -0
- package/dist/{chunk-YOHFWWBV.js → chunk-C3AM4Z4J.js} +1 -103
- package/dist/chunk-D7NFH5GD.js +570 -0
- package/dist/chunk-EE6PJWY4.js +130 -0
- package/dist/{chunk-CYUI7JU5.js → chunk-EIYL7I4S.js} +1 -1
- package/dist/{chunk-GM7HTXYC.js → chunk-FCZO7LAR.js} +13 -2
- package/dist/{chunk-2LUZA3LY.js → chunk-JEELK46E.js} +5 -5
- package/dist/chunk-MCMROINU.js +12 -0
- package/dist/chunk-NPVUAXUE.js +694 -0
- package/dist/{chunk-OR6NQJ5E.js → chunk-OJODNL2P.js} +3 -3
- package/dist/{chunk-3BYAPS6B.js → chunk-OK4KKR7B.js} +1 -11
- package/dist/chunk-OZSPLAQ4.js +71 -0
- package/dist/{chunk-KVZL5NZS.js → chunk-Q3XNY442.js} +17 -7
- package/dist/{chunk-SQGMG7OD.js → chunk-TQ74BATR.js} +100 -58
- package/dist/{chunk-JL2SLRAT.js → chunk-UJ7OTHPO.js} +76 -312
- package/dist/{chunk-HYHKTFG2.js → chunk-VNTLUFTY.js} +80 -843
- package/dist/chunk-WBZ4M5N5.js +59 -0
- package/dist/{chunk-6UP2Z2RZ.js → chunk-XJHDZUGD.js} +7 -7
- package/dist/chunk-Y2CM7HXH.js +111 -0
- package/dist/{chunk-F6HWCPOC.js → chunk-ZNNTSPNF.js} +1 -1
- package/dist/cli/chat.js +52 -2
- package/dist/cli/check.js +6 -5
- package/dist/cli/snapshot-warmup.js +10 -9
- package/dist/cli/upgrade.js +256 -16
- package/dist/db-A3ILH67H.js +20 -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/nitro.js +34 -89
- package/dist/plugin-module.d.ts +21 -0
- package/dist/plugins-OMJKLRJ2.js +13 -0
- package/dist/plugins.d.ts +6 -4
- package/dist/registry-NLZFIW23.js +46 -0
- package/dist/reporting/conversations.d.ts +3 -3
- package/dist/reporting.d.ts +6 -5
- package/dist/reporting.js +23 -17
- package/dist/{runner-27NP2TEO.js → runner-LUQZ5G67.js} +18 -13
- package/dist/validation-VMCPP3YO.js +15 -0
- package/package.json +11 -9
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeSlackConversationId
|
|
3
|
+
} from "./chunk-62FUNJYS.js";
|
|
4
|
+
import {
|
|
5
|
+
isSlackConversationId,
|
|
6
|
+
isSlackTeamId
|
|
7
|
+
} from "./chunk-MCMROINU.js";
|
|
8
|
+
|
|
9
|
+
// src/chat/destination.ts
|
|
10
|
+
import {
|
|
11
|
+
destinationSchema
|
|
12
|
+
} from "@sentry/junior-plugin-api";
|
|
13
|
+
function createSlackDestination(input) {
|
|
14
|
+
const channelId = normalizeSlackConversationId(input.channelId);
|
|
15
|
+
const teamId = input.teamId?.trim();
|
|
16
|
+
if (!channelId || !teamId) {
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
if (!isSlackConversationId(channelId) || !isSlackTeamId(teamId)) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
return { platform: "slack", teamId, channelId };
|
|
23
|
+
}
|
|
24
|
+
function parseDestination(value) {
|
|
25
|
+
const parsed = destinationSchema.safeParse(value);
|
|
26
|
+
return parsed.success ? parsed.data : void 0;
|
|
27
|
+
}
|
|
28
|
+
function requireSlackDestination(destination, action) {
|
|
29
|
+
if (destination?.platform === "slack") {
|
|
30
|
+
return destination;
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`${action} requires a Slack destination`);
|
|
33
|
+
}
|
|
34
|
+
function sameDestination(left, right) {
|
|
35
|
+
if (left.platform !== right.platform) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (left.platform === "local" && right.platform === "local") {
|
|
39
|
+
return left.conversationId === right.conversationId;
|
|
40
|
+
}
|
|
41
|
+
if (left.platform === "slack" && right.platform === "slack") {
|
|
42
|
+
return left.teamId === right.teamId && left.channelId === right.channelId;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
function destinationKey(destination) {
|
|
47
|
+
if (destination.platform === "local") {
|
|
48
|
+
return destination.conversationId;
|
|
49
|
+
}
|
|
50
|
+
return `slack:${destination.teamId}:${destination.channelId}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
createSlackDestination,
|
|
55
|
+
parseDestination,
|
|
56
|
+
requireSlackDestination,
|
|
57
|
+
sameDestination,
|
|
58
|
+
destinationKey
|
|
59
|
+
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SANDBOX_WORKSPACE_ROOT
|
|
3
3
|
} from "./chunk-G3E7SCME.js";
|
|
4
|
-
import {
|
|
5
|
-
getPluginRuntimeDependencies,
|
|
6
|
-
getPluginRuntimePostinstall
|
|
7
|
-
} from "./chunk-7Q5YOUUT.js";
|
|
8
4
|
import {
|
|
9
5
|
getStateAdapter
|
|
10
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZNNTSPNF.js";
|
|
11
7
|
import {
|
|
12
8
|
toOptionalTrimmed
|
|
13
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FCZO7LAR.js";
|
|
10
|
+
import {
|
|
11
|
+
getPluginRuntimeDependencies,
|
|
12
|
+
getPluginRuntimePostinstall
|
|
13
|
+
} from "./chunk-2RWFUS5F.js";
|
|
14
14
|
import {
|
|
15
15
|
withSpan
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-OK4KKR7B.js";
|
|
17
17
|
|
|
18
18
|
// src/chat/sandbox/runtime-dependency-snapshots.ts
|
|
19
19
|
import { createHash } from "crypto";
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// src/plugin-module.ts
|
|
2
|
+
import { statSync } from "fs";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
var PLUGIN_MODULE_EXTENSIONS = [
|
|
7
|
+
"",
|
|
8
|
+
".ts",
|
|
9
|
+
".tsx",
|
|
10
|
+
".mts",
|
|
11
|
+
".mjs",
|
|
12
|
+
".js",
|
|
13
|
+
".cjs"
|
|
14
|
+
];
|
|
15
|
+
function resolveRelativePluginModule(cwd, specifier) {
|
|
16
|
+
const basePath = path.resolve(cwd, specifier);
|
|
17
|
+
for (const extension of PLUGIN_MODULE_EXTENSIONS) {
|
|
18
|
+
const candidate = `${basePath}${extension}`;
|
|
19
|
+
try {
|
|
20
|
+
if (statSync(candidate).isFile()) {
|
|
21
|
+
return candidate;
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const extension of PLUGIN_MODULE_EXTENSIONS) {
|
|
27
|
+
const candidate = path.join(basePath, `index${extension}`);
|
|
28
|
+
try {
|
|
29
|
+
if (statSync(candidate).isFile()) {
|
|
30
|
+
return candidate;
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`Plugin module "${specifier}" could not be resolved`);
|
|
36
|
+
}
|
|
37
|
+
function resolvePluginModule(cwd, input) {
|
|
38
|
+
const moduleSpecifier = typeof input === "string" ? input : input.module;
|
|
39
|
+
const exportName = typeof input === "string" ? "plugins" : input.exportName ?? "plugins";
|
|
40
|
+
if (!moduleSpecifier.trim()) {
|
|
41
|
+
throw new Error("Plugin module specifier must not be empty");
|
|
42
|
+
}
|
|
43
|
+
if (moduleSpecifier.startsWith(".") || path.isAbsolute(moduleSpecifier)) {
|
|
44
|
+
const resolvedPath2 = resolveRelativePluginModule(cwd, moduleSpecifier);
|
|
45
|
+
return {
|
|
46
|
+
exportName,
|
|
47
|
+
importPath: resolvedPath2,
|
|
48
|
+
importUrl: pathToFileURL(resolvedPath2).href,
|
|
49
|
+
kind: "file",
|
|
50
|
+
sourceSpecifier: moduleSpecifier
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const requireFromApp = createRequire(path.join(cwd, "package.json"));
|
|
54
|
+
const resolvedPath = requireFromApp.resolve(moduleSpecifier);
|
|
55
|
+
return {
|
|
56
|
+
exportName,
|
|
57
|
+
importPath: resolvedPath,
|
|
58
|
+
importUrl: pathToFileURL(resolvedPath).href,
|
|
59
|
+
kind: "package",
|
|
60
|
+
sourceSpecifier: moduleSpecifier
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function assertPluginSet(value, source) {
|
|
64
|
+
if (!value || typeof value !== "object" || !Array.isArray(value.packageNames) || !Array.isArray(value.registrations)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Plugin module ${source} must export a defineJuniorPlugins(...) set`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const pluginSet = value;
|
|
70
|
+
const invalidPackageName = pluginSet.packageNames?.find(
|
|
71
|
+
(packageName) => typeof packageName !== "string"
|
|
72
|
+
);
|
|
73
|
+
if (invalidPackageName !== void 0) {
|
|
74
|
+
throw new Error(`Plugin module ${source} must export string package names`);
|
|
75
|
+
}
|
|
76
|
+
const invalidRegistration = pluginSet.registrations?.find(
|
|
77
|
+
(registration) => !registration || typeof registration !== "object" || !("manifest" in registration) || !registration.manifest || typeof registration.manifest !== "object" || !("name" in registration.manifest) || typeof registration.manifest.name !== "string"
|
|
78
|
+
);
|
|
79
|
+
if (invalidRegistration) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Plugin module ${source} must export plugin registrations with manifest names`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
async function loadPluginSetFromModule(moduleRef, importModule = async (ref) => await import(ref.importUrl)) {
|
|
87
|
+
const mod = await importModule(moduleRef);
|
|
88
|
+
const value = moduleRef.exportName === "default" ? mod.default : mod[moduleRef.exportName];
|
|
89
|
+
return assertPluginSet(
|
|
90
|
+
value,
|
|
91
|
+
`${moduleRef.importUrl}#${moduleRef.exportName}`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
async function loadAppPluginSet(cwd, importModule) {
|
|
95
|
+
let pluginModule;
|
|
96
|
+
try {
|
|
97
|
+
pluginModule = resolvePluginModule(cwd, "./plugins");
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (error instanceof Error && error.message === 'Plugin module "./plugins" could not be resolved') {
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
return await loadPluginSetFromModule(pluginModule, importModule);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
resolvePluginModule,
|
|
109
|
+
loadPluginSetFromModule,
|
|
110
|
+
loadAppPluginSet
|
|
111
|
+
};
|
package/dist/cli/chat.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadAppPluginSet
|
|
3
|
+
} from "../chunk-Y2CM7HXH.js";
|
|
1
4
|
import "../chunk-2KG3PWR4.js";
|
|
2
5
|
|
|
3
6
|
// src/cli/chat.ts
|
|
@@ -8,6 +11,7 @@ import {
|
|
|
8
11
|
} from "process";
|
|
9
12
|
import { randomUUID } from "crypto";
|
|
10
13
|
import * as readline from "readline/promises";
|
|
14
|
+
import { createJiti } from "jiti";
|
|
11
15
|
|
|
12
16
|
// src/chat/local/conversation.ts
|
|
13
17
|
import { createHash } from "crypto";
|
|
@@ -40,6 +44,7 @@ var DEFAULT_IO = {
|
|
|
40
44
|
output: defaultStdout,
|
|
41
45
|
write: (text) => writeStream(defaultStdout, text)
|
|
42
46
|
};
|
|
47
|
+
var localPluginLoader = createJiti(import.meta.url, { moduleCache: false });
|
|
43
48
|
var ChatOutputError = class extends Error {
|
|
44
49
|
constructor(error) {
|
|
45
50
|
super(errorMessage(error));
|
|
@@ -87,6 +92,49 @@ function defaultStateAdapterForLocalChat() {
|
|
|
87
92
|
}
|
|
88
93
|
process.env.JUNIOR_STATE_ADAPTER = "memory";
|
|
89
94
|
}
|
|
95
|
+
async function loadLocalPluginSet() {
|
|
96
|
+
return await loadAppPluginSet(
|
|
97
|
+
process.cwd(),
|
|
98
|
+
async (moduleRef) => localPluginLoader.import(moduleRef.importPath)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
async function configureLocalChatPlugins() {
|
|
102
|
+
const [
|
|
103
|
+
pluginsModule,
|
|
104
|
+
agentHooksModule,
|
|
105
|
+
registryModule,
|
|
106
|
+
validationModule,
|
|
107
|
+
databaseModule
|
|
108
|
+
] = await Promise.all([
|
|
109
|
+
import("../plugins-OMJKLRJ2.js"),
|
|
110
|
+
import("../agent-hooks-2HEB4C3Q.js"),
|
|
111
|
+
import("../registry-NLZFIW23.js"),
|
|
112
|
+
import("../validation-VMCPP3YO.js"),
|
|
113
|
+
import("../db-A3ILH67H.js")
|
|
114
|
+
]);
|
|
115
|
+
const pluginSet = await loadLocalPluginSet();
|
|
116
|
+
const plugins = pluginsModule.pluginHookRegistrationsFromPluginSet(pluginSet);
|
|
117
|
+
const pluginConfig = pluginSet ? pluginsModule.pluginCatalogConfigFromPluginSet(pluginSet) : pluginsModule.pluginCatalogConfigFromEnv();
|
|
118
|
+
const shouldValidatePluginCatalog = Boolean(pluginConfig) || Boolean(pluginSet?.registrations.length);
|
|
119
|
+
agentHooksModule.validatePlugins(plugins);
|
|
120
|
+
const previousPluginCatalogConfig = registryModule.setPluginCatalogConfig(pluginConfig);
|
|
121
|
+
try {
|
|
122
|
+
if (shouldValidatePluginCatalog) {
|
|
123
|
+
registryModule.getPluginCatalogSignature();
|
|
124
|
+
validationModule.validatePluginRegistrations(
|
|
125
|
+
pluginSet?.registrations ?? []
|
|
126
|
+
);
|
|
127
|
+
validationModule.validatePluginEgressCredentialHooks(
|
|
128
|
+
pluginSet?.registrations ?? []
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
databaseModule.validatePluginDatabaseRequirements(plugins);
|
|
132
|
+
agentHooksModule.setPlugins(plugins);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
registryModule.setPluginCatalogConfig(previousPluginCatalogConfig);
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
90
138
|
function parseChatArgs(argv) {
|
|
91
139
|
if (argv.length === 0) {
|
|
92
140
|
return { mode: "interactive" };
|
|
@@ -120,8 +168,9 @@ function newRunConversationId() {
|
|
|
120
168
|
}
|
|
121
169
|
async function runPrompt(options, io) {
|
|
122
170
|
defaultStateAdapterForLocalChat();
|
|
171
|
+
await configureLocalChatPlugins();
|
|
123
172
|
const conversationId = newRunConversationId();
|
|
124
|
-
const { runLocalAgentTurn } = await import("../runner-
|
|
173
|
+
const { runLocalAgentTurn } = await import("../runner-LUQZ5G67.js");
|
|
125
174
|
const result = await runLocalAgentTurn(
|
|
126
175
|
{
|
|
127
176
|
conversationId,
|
|
@@ -140,8 +189,9 @@ async function runPrompt(options, io) {
|
|
|
140
189
|
}
|
|
141
190
|
async function runInteractive(io) {
|
|
142
191
|
defaultStateAdapterForLocalChat();
|
|
192
|
+
await configureLocalChatPlugins();
|
|
143
193
|
const conversationId = newRunConversationId();
|
|
144
|
-
const { runLocalAgentTurn } = await import("../runner-
|
|
194
|
+
const { runLocalAgentTurn } = await import("../runner-LUQZ5G67.js");
|
|
145
195
|
const rl = readline.createInterface({
|
|
146
196
|
input: io.input,
|
|
147
197
|
output: io.output,
|
package/dist/cli/check.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseSkillFile
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-OJODNL2P.js";
|
|
4
4
|
import {
|
|
5
5
|
parseInlinePluginManifest,
|
|
6
6
|
parsePluginManifest
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-2RWFUS5F.js";
|
|
8
|
+
import "../chunk-Q3XNY442.js";
|
|
9
|
+
import "../chunk-EIYL7I4S.js";
|
|
10
|
+
import "../chunk-MCMROINU.js";
|
|
11
|
+
import "../chunk-OK4KKR7B.js";
|
|
11
12
|
import {
|
|
12
13
|
JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
|
|
13
14
|
JUNIOR_HEARTBEAT_ROUTE,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveRuntimeDependencySnapshot
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-XJHDZUGD.js";
|
|
4
4
|
import "../chunk-G3E7SCME.js";
|
|
5
|
+
import {
|
|
6
|
+
disconnectStateAdapter
|
|
7
|
+
} from "../chunk-ZNNTSPNF.js";
|
|
8
|
+
import "../chunk-FCZO7LAR.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-GM7HTXYC.js";
|
|
15
|
-
import "../chunk-CYUI7JU5.js";
|
|
16
|
-
import "../chunk-3BYAPS6B.js";
|
|
13
|
+
} from "../chunk-2RWFUS5F.js";
|
|
14
|
+
import "../chunk-Q3XNY442.js";
|
|
15
|
+
import "../chunk-EIYL7I4S.js";
|
|
16
|
+
import "../chunk-MCMROINU.js";
|
|
17
|
+
import "../chunk-OK4KKR7B.js";
|
|
17
18
|
import "../chunk-SJHUF3DP.js";
|
|
18
19
|
import "../chunk-2KG3PWR4.js";
|
|
19
20
|
|
package/dist/cli/upgrade.js
CHANGED
|
@@ -1,34 +1,63 @@
|
|
|
1
1
|
import {
|
|
2
2
|
coerceThreadConversationState
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-74HO27II.js";
|
|
4
|
+
import {
|
|
5
|
+
defineJuniorPlugins,
|
|
6
|
+
pluginCatalogConfigFromEnv,
|
|
7
|
+
pluginCatalogConfigFromPluginSet,
|
|
8
|
+
pluginHookRegistrationsFromPluginSet
|
|
9
|
+
} from "../chunk-EE6PJWY4.js";
|
|
4
10
|
import {
|
|
5
11
|
JUNIOR_THREAD_STATE_TTL_MS,
|
|
6
|
-
createNeonJuniorSqlExecutor,
|
|
7
12
|
createSqlStore,
|
|
8
13
|
createStateConversationStore,
|
|
9
14
|
getConversation,
|
|
10
15
|
requestConversationWork
|
|
11
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-UJ7OTHPO.js";
|
|
12
17
|
import {
|
|
13
18
|
parseDestination,
|
|
14
19
|
sameDestination
|
|
15
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-WBZ4M5N5.js";
|
|
21
|
+
import {
|
|
22
|
+
createPluginLogger,
|
|
23
|
+
createPluginState
|
|
24
|
+
} from "../chunk-BNJIEFQC.js";
|
|
25
|
+
import "../chunk-62FUNJYS.js";
|
|
26
|
+
import {
|
|
27
|
+
createJuniorSqlExecutor,
|
|
28
|
+
createPluginDbForExecutor,
|
|
29
|
+
getPluginDbForRegistration,
|
|
30
|
+
migratePluginSchemas,
|
|
31
|
+
readPluginMigrations
|
|
32
|
+
} from "../chunk-D7NFH5GD.js";
|
|
33
|
+
import {
|
|
34
|
+
loadAppPluginSet
|
|
35
|
+
} from "../chunk-Y2CM7HXH.js";
|
|
16
36
|
import {
|
|
17
37
|
disconnectStateAdapter,
|
|
18
38
|
getConnectedStateContext
|
|
19
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-ZNNTSPNF.js";
|
|
20
40
|
import {
|
|
21
41
|
getChatConfig
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import
|
|
42
|
+
} from "../chunk-FCZO7LAR.js";
|
|
43
|
+
import {
|
|
44
|
+
getPluginMigrationRoots,
|
|
45
|
+
setPluginCatalogConfig
|
|
46
|
+
} from "../chunk-2RWFUS5F.js";
|
|
47
|
+
import "../chunk-Q3XNY442.js";
|
|
48
|
+
import "../chunk-EIYL7I4S.js";
|
|
49
|
+
import "../chunk-MCMROINU.js";
|
|
24
50
|
import {
|
|
25
51
|
isRecord,
|
|
26
52
|
toOptionalNumber,
|
|
27
53
|
toOptionalString
|
|
28
|
-
} from "../chunk-
|
|
54
|
+
} from "../chunk-OK4KKR7B.js";
|
|
29
55
|
import "../chunk-SJHUF3DP.js";
|
|
30
56
|
import "../chunk-2KG3PWR4.js";
|
|
31
57
|
|
|
58
|
+
// src/cli/upgrade.ts
|
|
59
|
+
import { createJiti } from "jiti";
|
|
60
|
+
|
|
32
61
|
// src/chat/conversations/sql/backfill.ts
|
|
33
62
|
async function backfillToSql(args) {
|
|
34
63
|
const limit = Math.max(0, args.limit ?? 500);
|
|
@@ -60,8 +89,9 @@ async function migrateConversationsToSql(context, options = {}) {
|
|
|
60
89
|
let closeTarget;
|
|
61
90
|
if (!target) {
|
|
62
91
|
const databaseUrl = requireConversationSqlDatabaseUrl(context);
|
|
63
|
-
const executor =
|
|
64
|
-
connectionString: databaseUrl
|
|
92
|
+
const executor = createJuniorSqlExecutor({
|
|
93
|
+
connectionString: databaseUrl,
|
|
94
|
+
driver: context.sqlDriver ?? getChatConfig().sql.driver
|
|
65
95
|
});
|
|
66
96
|
target = createSqlStore(executor);
|
|
67
97
|
closeTarget = () => executor.close();
|
|
@@ -88,6 +118,183 @@ var sqlConversationMigration = {
|
|
|
88
118
|
run: migrateConversationsToSql
|
|
89
119
|
};
|
|
90
120
|
|
|
121
|
+
// src/cli/upgrade/migrations/upgrade-plugins.ts
|
|
122
|
+
function unique(values) {
|
|
123
|
+
return [...new Set(values)];
|
|
124
|
+
}
|
|
125
|
+
function baseCatalogConfig(context) {
|
|
126
|
+
return context.pluginCatalogConfig ?? (context.pluginSet ? pluginCatalogConfigFromPluginSet(context.pluginSet) : pluginCatalogConfigFromEnv());
|
|
127
|
+
}
|
|
128
|
+
function inlinePluginName(definition) {
|
|
129
|
+
return definition.manifest.name;
|
|
130
|
+
}
|
|
131
|
+
function mergeInlineManifests(left, right) {
|
|
132
|
+
const merged = /* @__PURE__ */ new Map();
|
|
133
|
+
for (const definition of [...left ?? [], ...right ?? []]) {
|
|
134
|
+
merged.set(inlinePluginName(definition), definition);
|
|
135
|
+
}
|
|
136
|
+
return merged.size > 0 ? [...merged.values()] : void 0;
|
|
137
|
+
}
|
|
138
|
+
function mergeCatalogConfig(base, added) {
|
|
139
|
+
if (!base) {
|
|
140
|
+
return added;
|
|
141
|
+
}
|
|
142
|
+
if (!added) {
|
|
143
|
+
return base;
|
|
144
|
+
}
|
|
145
|
+
const inlineManifests = mergeInlineManifests(
|
|
146
|
+
base.inlineManifests,
|
|
147
|
+
added.inlineManifests
|
|
148
|
+
);
|
|
149
|
+
const packages = unique([
|
|
150
|
+
...base.packages ?? [],
|
|
151
|
+
...added.packages ?? []
|
|
152
|
+
]);
|
|
153
|
+
const manifests = base.manifests || added.manifests ? { ...base.manifests, ...added.manifests } : void 0;
|
|
154
|
+
return {
|
|
155
|
+
...inlineManifests ? { inlineManifests } : {},
|
|
156
|
+
...packages.length > 0 ? { packages } : {},
|
|
157
|
+
...manifests ? { manifests } : {}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function packageNamesFromContext(context, catalog) {
|
|
161
|
+
return unique([
|
|
162
|
+
...context.pluginSet?.packageNames ?? [],
|
|
163
|
+
...catalog?.packages ?? []
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
async function resolveUpgradePlugins(context) {
|
|
167
|
+
const catalog = baseCatalogConfig(context);
|
|
168
|
+
const packageNames = packageNamesFromContext(context, catalog);
|
|
169
|
+
const registrations = context.pluginSet?.registrations ?? [];
|
|
170
|
+
const manifests = context.pluginSet?.manifests || catalog?.manifests ? {
|
|
171
|
+
...catalog?.manifests,
|
|
172
|
+
...context.pluginSet?.manifests
|
|
173
|
+
} : void 0;
|
|
174
|
+
const pluginSet = packageNames.length > 0 || registrations.length > 0 || context.pluginSet ? defineJuniorPlugins(
|
|
175
|
+
[...packageNames, ...registrations],
|
|
176
|
+
manifests ? { manifests } : {}
|
|
177
|
+
) : void 0;
|
|
178
|
+
return {
|
|
179
|
+
pluginCatalogConfig: mergeCatalogConfig(
|
|
180
|
+
catalog,
|
|
181
|
+
pluginCatalogConfigFromPluginSet(pluginSet)
|
|
182
|
+
),
|
|
183
|
+
...pluginSet ? { pluginSet } : {}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/cli/upgrade/migrations/plugin-storage.ts
|
|
188
|
+
function emptyResult() {
|
|
189
|
+
return {
|
|
190
|
+
existing: 0,
|
|
191
|
+
migrated: 0,
|
|
192
|
+
missing: 0,
|
|
193
|
+
scanned: 0
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function addResult(left, right) {
|
|
197
|
+
return {
|
|
198
|
+
existing: left.existing + right.existing,
|
|
199
|
+
migrated: left.migrated + right.migrated,
|
|
200
|
+
missing: left.missing + right.missing,
|
|
201
|
+
scanned: left.scanned + right.scanned,
|
|
202
|
+
...left.skipped !== void 0 || right.skipped !== void 0 ? { skipped: (left.skipped ?? 0) + (right.skipped ?? 0) } : {}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function dbForPlugin(context, plugin, sqlUrlDb) {
|
|
206
|
+
if (!plugin.database) {
|
|
207
|
+
return void 0;
|
|
208
|
+
}
|
|
209
|
+
return context.pluginDb ?? sqlUrlDb ?? getPluginDbForRegistration(plugin);
|
|
210
|
+
}
|
|
211
|
+
async function runPluginStorageMigrations(context) {
|
|
212
|
+
const { pluginCatalogConfig, pluginSet } = await resolveUpgradePlugins(context);
|
|
213
|
+
if (!pluginSet) {
|
|
214
|
+
return emptyResult();
|
|
215
|
+
}
|
|
216
|
+
const previousConfig = setPluginCatalogConfig(pluginCatalogConfig);
|
|
217
|
+
const ownedExecutor = context.pluginDb || !context.sqlDatabaseUrl ? void 0 : createJuniorSqlExecutor({
|
|
218
|
+
connectionString: context.sqlDatabaseUrl,
|
|
219
|
+
driver: context.sqlDriver ?? getChatConfig().sql.driver
|
|
220
|
+
});
|
|
221
|
+
const sqlUrlDb = ownedExecutor ? createPluginDbForExecutor(ownedExecutor) : void 0;
|
|
222
|
+
try {
|
|
223
|
+
let result = emptyResult();
|
|
224
|
+
const plugins = pluginHookRegistrationsFromPluginSet(pluginSet).filter((plugin) => plugin.hooks?.migrateStorage).sort(
|
|
225
|
+
(left, right) => left.manifest.name.localeCompare(right.manifest.name)
|
|
226
|
+
);
|
|
227
|
+
for (const plugin of plugins) {
|
|
228
|
+
const pluginName = plugin.manifest.name;
|
|
229
|
+
const hook = plugin.hooks?.migrateStorage;
|
|
230
|
+
if (!hook) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const db = dbForPlugin(context, plugin, sqlUrlDb);
|
|
234
|
+
if (!db) {
|
|
235
|
+
throw new Error(
|
|
236
|
+
`Plugin "${pluginName}" storage migration requires database access`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
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/cli/upgrade/migrations/plugin-sql.ts
|
|
261
|
+
var REQUIRED_SQL_DATABASE_URL_MESSAGE2 = "Junior SQL database URL is required for plugin schema migration. Set JUNIOR_DATABASE_URL or DATABASE_URL.";
|
|
262
|
+
function requirePluginSqlDatabaseUrl(context) {
|
|
263
|
+
const databaseUrl = context.sqlDatabaseUrl ?? getChatConfig().sql.databaseUrl;
|
|
264
|
+
if (!databaseUrl) {
|
|
265
|
+
throw new Error(REQUIRED_SQL_DATABASE_URL_MESSAGE2);
|
|
266
|
+
}
|
|
267
|
+
return databaseUrl;
|
|
268
|
+
}
|
|
269
|
+
async function migratePluginsToSql(context) {
|
|
270
|
+
const databaseUrl = requirePluginSqlDatabaseUrl(context);
|
|
271
|
+
const { pluginCatalogConfig } = await resolveUpgradePlugins(context);
|
|
272
|
+
const previousConfig = setPluginCatalogConfig(pluginCatalogConfig);
|
|
273
|
+
const executor = createJuniorSqlExecutor({
|
|
274
|
+
connectionString: databaseUrl,
|
|
275
|
+
driver: context.sqlDriver ?? getChatConfig().sql.driver
|
|
276
|
+
});
|
|
277
|
+
try {
|
|
278
|
+
const migrations = getPluginMigrationRoots().flatMap(
|
|
279
|
+
(root) => readPluginMigrations(root)
|
|
280
|
+
);
|
|
281
|
+
const result = await migratePluginSchemas(executor, migrations);
|
|
282
|
+
return {
|
|
283
|
+
existing: result.existing,
|
|
284
|
+
migrated: result.migrated,
|
|
285
|
+
missing: 0,
|
|
286
|
+
scanned: result.scanned
|
|
287
|
+
};
|
|
288
|
+
} finally {
|
|
289
|
+
setPluginCatalogConfig(previousConfig);
|
|
290
|
+
await executor.close();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
var sqlPluginMigration = {
|
|
294
|
+
name: "migrate-plugin-sql",
|
|
295
|
+
run: migratePluginsToSql
|
|
296
|
+
};
|
|
297
|
+
|
|
91
298
|
// src/cli/upgrade/migrations/redis-conversation-state.ts
|
|
92
299
|
var CONVERSATION_PREFIX = "junior:conversation";
|
|
93
300
|
var CONVERSATION_SCHEMA_VERSION = 1;
|
|
@@ -624,10 +831,34 @@ var redisConversationStateMigration = {
|
|
|
624
831
|
var DEFAULT_IO = {
|
|
625
832
|
info: console.log
|
|
626
833
|
};
|
|
834
|
+
var localPluginLoader = createJiti(import.meta.url, { moduleCache: false });
|
|
627
835
|
var MIGRATIONS = [
|
|
628
836
|
redisConversationStateMigration,
|
|
629
|
-
sqlConversationMigration
|
|
837
|
+
sqlConversationMigration,
|
|
838
|
+
sqlPluginMigration,
|
|
839
|
+
pluginStorageMigration
|
|
630
840
|
];
|
|
841
|
+
function isMissingVirtualConfig(error) {
|
|
842
|
+
if (!(error instanceof Error)) {
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
845
|
+
const code = error.code;
|
|
846
|
+
return (code === "ERR_PACKAGE_IMPORT_NOT_DEFINED" || code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && error.message.includes("#junior/config");
|
|
847
|
+
}
|
|
848
|
+
async function resolveUpgradePluginSet() {
|
|
849
|
+
try {
|
|
850
|
+
const mod = await import("#junior/config");
|
|
851
|
+
return mod.pluginSet;
|
|
852
|
+
} catch (error) {
|
|
853
|
+
if (!isMissingVirtualConfig(error)) {
|
|
854
|
+
throw error;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return await loadAppPluginSet(
|
|
858
|
+
process.cwd(),
|
|
859
|
+
async (moduleRef) => localPluginLoader.import(moduleRef.importPath)
|
|
860
|
+
);
|
|
861
|
+
}
|
|
631
862
|
function formatMigrationResult(result) {
|
|
632
863
|
const fields = [
|
|
633
864
|
`scanned=${result.scanned}`,
|
|
@@ -641,12 +872,14 @@ function formatMigrationResult(result) {
|
|
|
641
872
|
return fields.join(" ");
|
|
642
873
|
}
|
|
643
874
|
async function runUpgradeMigrations(context) {
|
|
644
|
-
|
|
875
|
+
const plugins = await resolveUpgradePlugins(context);
|
|
876
|
+
const migrationContext = { ...context, ...plugins };
|
|
877
|
+
migrationContext.sqlDatabaseUrl ??= requireConversationSqlDatabaseUrl(migrationContext);
|
|
645
878
|
const results = [];
|
|
646
879
|
for (const migration of MIGRATIONS) {
|
|
647
|
-
|
|
648
|
-
const result = await migration.run(
|
|
649
|
-
|
|
880
|
+
migrationContext.io.info(`Running migration ${migration.name}...`);
|
|
881
|
+
const result = await migration.run(migrationContext);
|
|
882
|
+
migrationContext.io.info(
|
|
650
883
|
`Finished migration ${migration.name}: ${formatMigrationResult(result)}`
|
|
651
884
|
);
|
|
652
885
|
results.push(result);
|
|
@@ -656,14 +889,21 @@ async function runUpgradeMigrations(context) {
|
|
|
656
889
|
async function runUpgrade(io = DEFAULT_IO) {
|
|
657
890
|
try {
|
|
658
891
|
const { redisStateAdapter, stateAdapter } = await getConnectedStateContext();
|
|
892
|
+
const pluginSet = await resolveUpgradePluginSet();
|
|
659
893
|
io.info("Running Junior upgrade migrations...");
|
|
660
|
-
await runUpgradeMigrations({
|
|
894
|
+
await runUpgradeMigrations({
|
|
895
|
+
io,
|
|
896
|
+
pluginSet,
|
|
897
|
+
redisStateAdapter,
|
|
898
|
+
stateAdapter
|
|
899
|
+
});
|
|
661
900
|
io.info("Junior upgrade complete.");
|
|
662
901
|
} finally {
|
|
663
902
|
await disconnectStateAdapter();
|
|
664
903
|
}
|
|
665
904
|
}
|
|
666
905
|
export {
|
|
906
|
+
resolveUpgradePluginSet,
|
|
667
907
|
runUpgrade,
|
|
668
908
|
runUpgradeMigrations
|
|
669
909
|
};
|