@samanhappy/mcphub 1.0.38 → 1.0.40
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/betterAuth.js +23 -0
- package/dist/betterAuth.js.map +1 -1
- package/dist/controllers/smartRoutingController.js +408 -0
- package/dist/controllers/smartRoutingController.js.map +1 -0
- package/dist/dao/CredentialBindingDao.js +5 -0
- package/dist/dao/CredentialBindingDao.js.map +1 -1
- package/dist/dao/CredentialBindingDaoDbImpl.js +7 -0
- package/dist/dao/CredentialBindingDaoDbImpl.js.map +1 -1
- package/dist/db/connection.js +38 -11
- package/dist/db/connection.js.map +1 -1
- package/dist/db/groupSchema.js +2 -2
- package/dist/db/groupSchema.js.map +1 -1
- package/dist/db/repositories/ActivityRepository.js +2 -2
- package/dist/db/repositories/ActivityRepository.js.map +1 -1
- package/dist/db/repositories/BaseRepository.js +4 -1
- package/dist/db/repositories/BaseRepository.js.map +1 -1
- package/dist/db/repositories/BearerKeyRepository.js +3 -1
- package/dist/db/repositories/BearerKeyRepository.js.map +1 -1
- package/dist/db/repositories/BuiltinPromptRepository.js +2 -2
- package/dist/db/repositories/BuiltinPromptRepository.js.map +1 -1
- package/dist/db/repositories/BuiltinResourceRepository.js +2 -2
- package/dist/db/repositories/BuiltinResourceRepository.js.map +1 -1
- package/dist/db/repositories/GroupRepository.js +2 -2
- package/dist/db/repositories/GroupRepository.js.map +1 -1
- package/dist/db/repositories/OAuthClientRepository.js +2 -2
- package/dist/db/repositories/OAuthClientRepository.js.map +1 -1
- package/dist/db/repositories/OAuthTokenRepository.js +3 -1
- package/dist/db/repositories/OAuthTokenRepository.js.map +1 -1
- package/dist/db/repositories/ServerRepository.js +2 -2
- package/dist/db/repositories/ServerRepository.js.map +1 -1
- package/dist/db/repositories/UserConfigRepository.js +2 -2
- package/dist/db/repositories/UserConfigRepository.js.map +1 -1
- package/dist/db/repositories/UserRepository.js +3 -1
- package/dist/db/repositories/UserRepository.js.map +1 -1
- package/dist/db/repositories/VectorEmbeddingRepository.js +35 -3
- package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
- package/dist/middlewares/auth.js +1 -1
- package/dist/middlewares/auth.js.map +1 -1
- package/dist/middlewares/index.js +8 -1
- package/dist/middlewares/index.js.map +1 -1
- package/dist/routes/index.js +4 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/services/mcpOAuthProvider.js +7 -0
- package/dist/services/mcpOAuthProvider.js.map +1 -1
- package/dist/services/mcpService.js +178 -20
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/principalRuntimeService.js +1 -3
- package/dist/services/principalRuntimeService.js.map +1 -1
- package/dist/services/vectorSearchService.js +29 -10
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/cacheUtils.js +345 -1
- package/dist/utils/cacheUtils.js.map +1 -1
- package/dist/utils/packageUpdate.js +242 -0
- package/dist/utils/packageUpdate.js.map +1 -0
- package/dist/utils/serialization.js +14 -2
- package/dist/utils/serialization.js.map +1 -1
- package/dist/utils/serverConfigPersistence.js +18 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/dist/utils/upstreamError.js +60 -0
- package/dist/utils/upstreamError.js.map +1 -0
- package/dist/utils/withTimeout.js +25 -0
- package/dist/utils/withTimeout.js.map +1 -0
- package/frontend/dist/assets/{ActivityPage-BZNq-eGE.js → ActivityPage-B5DanW8q.js} +2 -2
- package/frontend/dist/assets/{ActivityPage-BZNq-eGE.js.map → ActivityPage-B5DanW8q.js.map} +1 -1
- package/frontend/dist/assets/CopyClientConfigDialog-C6U6_eyy.js +4 -0
- package/frontend/dist/assets/CopyClientConfigDialog-C6U6_eyy.js.map +1 -0
- package/frontend/dist/assets/{CredentialsPage-7kyDJLsX.js → CredentialsPage-CXK8Xkao.js} +2 -2
- package/frontend/dist/assets/{CredentialsPage-7kyDJLsX.js.map → CredentialsPage-CXK8Xkao.js.map} +1 -1
- package/frontend/dist/assets/Dashboard-LIC6BqIA.js +2 -0
- package/frontend/dist/assets/{Dashboard-CElNx820.js.map → Dashboard-LIC6BqIA.js.map} +1 -1
- package/frontend/dist/assets/EndpointCopy-CeZbEsF2.js +2 -0
- package/frontend/dist/assets/EndpointCopy-CeZbEsF2.js.map +1 -0
- package/frontend/dist/assets/GroupsPage-DwVaRIap.js +33 -0
- package/frontend/dist/assets/GroupsPage-DwVaRIap.js.map +1 -0
- package/frontend/dist/assets/{LoginPage-D23s7oM0.js → LoginPage-CPqSMwWO.js} +2 -2
- package/frontend/dist/assets/{LoginPage-D23s7oM0.js.map → LoginPage-CPqSMwWO.js.map} +1 -1
- package/frontend/dist/assets/{LogsPage-BuQMkmV-.js → LogsPage-eCHGem9T.js} +2 -2
- package/frontend/dist/assets/{LogsPage-BuQMkmV-.js.map → LogsPage-eCHGem9T.js.map} +1 -1
- package/frontend/dist/assets/{MarketPage-g9vEYzIq.js → MarketPage-RqD2-rxq.js} +2 -2
- package/frontend/dist/assets/{MarketPage-g9vEYzIq.js.map → MarketPage-RqD2-rxq.js.map} +1 -1
- package/frontend/dist/assets/{OAuthConsentPage-BiX1lpJR.js → OAuthConsentPage-DJITYpCM.js} +2 -2
- package/frontend/dist/assets/{OAuthConsentPage-BiX1lpJR.js.map → OAuthConsentPage-DJITYpCM.js.map} +1 -1
- package/frontend/dist/assets/{PromptsPage-g8SRFY6s.js → PromptsPage-DQ02iDOJ.js} +2 -2
- package/frontend/dist/assets/{PromptsPage-g8SRFY6s.js.map → PromptsPage-DQ02iDOJ.js.map} +1 -1
- package/frontend/dist/assets/{ResourcesPage-Ddhxi9Sf.js → ResourcesPage-mUU0DVus.js} +2 -2
- package/frontend/dist/assets/{ResourcesPage-Ddhxi9Sf.js.map → ResourcesPage-mUU0DVus.js.map} +1 -1
- package/frontend/dist/assets/ServersPage-DsS8j6tl.js +39 -0
- package/frontend/dist/assets/ServersPage-DsS8j6tl.js.map +1 -0
- package/frontend/dist/assets/SettingsPage-CIeF1sDE.js +12 -0
- package/frontend/dist/assets/SettingsPage-CIeF1sDE.js.map +1 -0
- package/frontend/dist/assets/{StatusDot-CdzMqjTi.js → StatusDot-Bcv2BwIL.js} +2 -2
- package/frontend/dist/assets/{StatusDot-CdzMqjTi.js.map → StatusDot-Bcv2BwIL.js.map} +1 -1
- package/frontend/dist/assets/{ToggleGroup-CJd8X_31.js → ToggleGroup-C_7sDUlr.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-CJd8X_31.js.map → ToggleGroup-C_7sDUlr.js.map} +1 -1
- package/frontend/dist/assets/{UsersPage-CkP_x9Rt.js → UsersPage-ufaG2-Ag.js} +2 -2
- package/frontend/dist/assets/{UsersPage-CkP_x9Rt.js.map → UsersPage-ufaG2-Ag.js.map} +1 -1
- package/frontend/dist/assets/clipboard-BukcCPLt.js +2 -0
- package/frontend/dist/assets/clipboard-BukcCPLt.js.map +1 -0
- package/frontend/dist/assets/{icons-vendor-VW-UwEhw.js → icons-vendor-CNEaJWqW.js} +79 -59
- package/frontend/dist/assets/icons-vendor-CNEaJWqW.js.map +1 -0
- package/frontend/dist/assets/index-C8aAOWR7.js +3 -0
- package/frontend/dist/assets/{index-Bu4XuAH4.js.map → index-C8aAOWR7.js.map} +1 -1
- package/frontend/dist/assets/index-D4Vy78bV.css +1 -0
- package/frontend/dist/assets/{resourceService-w-cZ31FD.js → resourceService-CN5cMjQ0.js} +2 -2
- package/frontend/dist/assets/{resourceService-w-cZ31FD.js.map → resourceService-CN5cMjQ0.js.map} +1 -1
- package/frontend/dist/assets/{useCostData-C72NC0PQ.js → useCostData-B9XzWVsV.js} +2 -2
- package/frontend/dist/assets/{useCostData-C72NC0PQ.js.map → useCostData-B9XzWVsV.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-J_hwKZA6.js +2 -0
- package/frontend/dist/assets/{useSettingsData-JTEMu74D.js.map → useSettingsData-J_hwKZA6.js.map} +1 -1
- package/frontend/dist/assets/variableDetection-Dxw0g2ON.js +16 -0
- package/frontend/dist/assets/variableDetection-Dxw0g2ON.js.map +1 -0
- package/frontend/dist/index.html +3 -3
- package/package.json +2 -1
- package/frontend/dist/assets/Dashboard-CElNx820.js +0 -2
- package/frontend/dist/assets/EndpointCopy-8jW5Xtka.js +0 -2
- package/frontend/dist/assets/EndpointCopy-8jW5Xtka.js.map +0 -1
- package/frontend/dist/assets/GroupsPage-dUkvX_iB.js +0 -33
- package/frontend/dist/assets/GroupsPage-dUkvX_iB.js.map +0 -1
- package/frontend/dist/assets/ServersPage-DAmKvrPV.js +0 -39
- package/frontend/dist/assets/ServersPage-DAmKvrPV.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-DZXjQZXS.js +0 -12
- package/frontend/dist/assets/SettingsPage-DZXjQZXS.js.map +0 -1
- package/frontend/dist/assets/icons-vendor-VW-UwEhw.js.map +0 -1
- package/frontend/dist/assets/index-B3OqAhGz.css +0 -1
- package/frontend/dist/assets/index-Bu4XuAH4.js +0 -3
- package/frontend/dist/assets/toolDescription-Dw3sa28K.js +0 -2
- package/frontend/dist/assets/toolDescription-Dw3sa28K.js.map +0 -1
- package/frontend/dist/assets/useSettingsData-JTEMu74D.js +0 -2
- package/frontend/dist/assets/variableDetection-DfhNyFy-.js +0 -16
- package/frontend/dist/assets/variableDetection-DfhNyFy-.js.map +0 -1
package/dist/betterAuth.js
CHANGED
|
@@ -50,6 +50,18 @@ if (runtimeConfig.providers.oidc.enabled &&
|
|
|
50
50
|
scopes: runtimeConfig.providers.oidc.scopes,
|
|
51
51
|
pkce: runtimeConfig.providers.oidc.pkce,
|
|
52
52
|
prompt: runtimeConfig.providers.oidc.prompt,
|
|
53
|
+
// Some OIDC issuers (e.g. self-hosted GitLab < 16.0) do not include
|
|
54
|
+
// a `name` claim in the ID token; better-auth only exposes it via
|
|
55
|
+
// the userinfo endpoint, which it skips whenever an id_token is
|
|
56
|
+
// present. Synthesize a display name from the remaining claims so
|
|
57
|
+
// that sign-in succeeds for such issuers.
|
|
58
|
+
mapProfileToUser: (profile) => ({
|
|
59
|
+
name: profile.name ||
|
|
60
|
+
profile.nickname ||
|
|
61
|
+
profile.preferred_username ||
|
|
62
|
+
(typeof profile.email === 'string' && profile.email.split('@')[0]) ||
|
|
63
|
+
`oidc-${String(profile.id ?? profile.sub ?? '')}`,
|
|
64
|
+
}),
|
|
53
65
|
},
|
|
54
66
|
],
|
|
55
67
|
}));
|
|
@@ -86,8 +98,19 @@ const databaseUrl = process.env.DB_URL;
|
|
|
86
98
|
if (!databaseUrl) {
|
|
87
99
|
throw new Error('DB_URL is required for Better Auth PostgreSQL storage.');
|
|
88
100
|
}
|
|
101
|
+
// Keep the Better Auth pool aligned with the main TypeORM pool so a DB
|
|
102
|
+
// incident cannot make Better Auth requests queue forever: pg defaults have no
|
|
103
|
+
// connection timeout (wait indefinitely) and a max of 10 on top of TypeORM's
|
|
104
|
+
// pool. Postgres-side safety valves (0 = PostgreSQL default / disabled) stop a
|
|
105
|
+
// hung query or idle-in-transaction session from holding a connection
|
|
106
|
+
// indefinitely (#1205).
|
|
89
107
|
const pool = new Pool({
|
|
90
108
|
connectionString: databaseUrl,
|
|
109
|
+
max: parseInt(process.env.DB_POOL_SIZE || '10', 10),
|
|
110
|
+
connectionTimeoutMillis: parseInt(process.env.DB_CONNECTION_TIMEOUT || '60000', 10),
|
|
111
|
+
idleTimeoutMillis: parseInt(process.env.DB_POOL_IDLE_TIMEOUT || '30000', 10),
|
|
112
|
+
statement_timeout: parseInt(process.env.DB_STATEMENT_TIMEOUT || '0', 10),
|
|
113
|
+
idle_in_transaction_session_timeout: parseInt(process.env.DB_IDLE_IN_TRANSACTION_TIMEOUT || '0', 10),
|
|
91
114
|
});
|
|
92
115
|
const database = new PostgresDialect({
|
|
93
116
|
pool,
|
package/dist/betterAuth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"betterAuth.js","sourceRoot":"","sources":["../src/betterAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,aAAa,EAAE,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC5F,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,mBAAmB,GAAG,GAAG,EAAE;IAC/B,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;IACnD,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,OAAO,YAAY,EAAE,CAAC,YAAY,IAAI,IAAI,CAAC;IAC7C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC;AAC3C,MAAM,aAAa,GAAG,8BAA8B,CAAC,YAAY,CAAC,CAAC;AACnE,MAAM,eAAe,GAA+D,EAAE,CAAC;AACvF,MAAM,OAAO,GAAU,EAAE,CAAC;AAC1B,IACE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO;IACtC,OAAO,CAAC,GAAG,CAAC,gBAAgB;IAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAChC,CAAC;IACD,eAAe,CAAC,MAAM,GAAG;QACvB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;QACtC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;KAC/C,CAAC;AACJ,CAAC;AACD,IACE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO;IACtC,OAAO,CAAC,GAAG,CAAC,gBAAgB;IAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAChC,CAAC;IACD,eAAe,CAAC,MAAM,GAAG;QACvB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;QACtC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;KAC/C,CAAC;AACJ,CAAC;AACD,IACE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO;IACpC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY;IACzC,OAAO,CAAC,GAAG,CAAC,cAAc;IAC1B,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAC9B,CAAC;IACD,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;QACX,MAAM,EAAE;YACN;gBACE,UAAU,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU;gBACnD,YAAY,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY;gBACvD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;gBACpC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;gBAC5C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM;gBAC3C,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI;gBACvC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"betterAuth.js","sourceRoot":"","sources":["../src/betterAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { getSmartRoutingConfig } from '../utils/smartRouting.js';
|
|
2
|
+
import { hasCredentialTemplate } from '../utils/credentialTemplate.js';
|
|
3
|
+
import { requireAdmin } from '../utils/requireAdmin.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import { getCredentialBindingDao, getUserDao } from '../dao/DaoFactory.js';
|
|
6
|
+
import { getAppDataSource, getDatabaseHealth, initializeDatabase, isDatabaseConnected, } from '../db/connection.js';
|
|
7
|
+
import { saveToolsAsVectorEmbeddings } from '../services/vectorSearchService.js';
|
|
8
|
+
import { getServerToolsForPrincipal, getServersInfo } from '../services/mcpService.js';
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the effective embedding model that the vector store is (or will be)
|
|
11
|
+
* persisted with. Mirrors the resolution in vectorSearchService.saveToolsAsVectorEmbeddings
|
|
12
|
+
* so the reported model matches what is actually written to vector_embeddings.
|
|
13
|
+
*/
|
|
14
|
+
const resolvePersistedEmbeddingModel = (config) => {
|
|
15
|
+
const provider = config.embeddingProvider || 'openai';
|
|
16
|
+
if (provider === 'azure_openai') {
|
|
17
|
+
return config.azureOpenaiEmbeddingModel?.trim() || 'text-embedding-3-small';
|
|
18
|
+
}
|
|
19
|
+
return config.embeddingModel?.trim() || null;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Read aggregate statistics from the vector_embeddings table.
|
|
23
|
+
* Returns null when the query fails so callers can degrade gracefully instead
|
|
24
|
+
* of returning a 500 for a purely informational endpoint.
|
|
25
|
+
*/
|
|
26
|
+
const queryVectorStoreStats = async () => {
|
|
27
|
+
try {
|
|
28
|
+
const dataSource = getAppDataSource();
|
|
29
|
+
const [overview, byModel, byServer, freshness, dims] = await Promise.all([
|
|
30
|
+
dataSource.query(`SELECT
|
|
31
|
+
count(*) FILTER (WHERE content_type = 'tool') AS tool_rows,
|
|
32
|
+
count(*) FILTER (WHERE content_type = 'server') AS server_rows,
|
|
33
|
+
count(*) AS total_rows,
|
|
34
|
+
count(DISTINCT metadata::jsonb->>'serverName') AS distinct_servers
|
|
35
|
+
FROM vector_embeddings`),
|
|
36
|
+
dataSource.query(`SELECT model,
|
|
37
|
+
count(*) FILTER (WHERE content_type = 'tool') AS tool_count,
|
|
38
|
+
count(*) FILTER (WHERE content_type = 'server') AS server_count
|
|
39
|
+
FROM vector_embeddings
|
|
40
|
+
GROUP BY model
|
|
41
|
+
ORDER BY model`),
|
|
42
|
+
dataSource.query(`SELECT metadata::jsonb->>'serverName' AS server_name, count(*) AS tool_count
|
|
43
|
+
FROM vector_embeddings
|
|
44
|
+
WHERE content_type = 'tool'
|
|
45
|
+
GROUP BY 1
|
|
46
|
+
ORDER BY tool_count DESC
|
|
47
|
+
LIMIT 500`),
|
|
48
|
+
dataSource.query(`SELECT to_char(min(updated_at), 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') AS oldest,
|
|
49
|
+
to_char(max(updated_at), 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') AS newest
|
|
50
|
+
FROM vector_embeddings`),
|
|
51
|
+
dataSource.query(`SELECT atttypmod AS dimensions
|
|
52
|
+
FROM pg_attribute
|
|
53
|
+
WHERE attrelid = 'vector_embeddings'::regclass
|
|
54
|
+
AND attname = 'embedding'`),
|
|
55
|
+
]);
|
|
56
|
+
const rawDimensions = dims?.[0]?.dimensions;
|
|
57
|
+
const dimValue = Number(rawDimensions);
|
|
58
|
+
const dimensions = rawDimensions !== undefined && rawDimensions !== null && Number.isFinite(dimValue)
|
|
59
|
+
? dimValue
|
|
60
|
+
: null;
|
|
61
|
+
return {
|
|
62
|
+
totalRows: Number(overview?.[0]?.total_rows ?? 0),
|
|
63
|
+
toolRows: Number(overview?.[0]?.tool_rows ?? 0),
|
|
64
|
+
serverRows: Number(overview?.[0]?.server_rows ?? 0),
|
|
65
|
+
distinctServers: Number(overview?.[0]?.distinct_servers ?? 0),
|
|
66
|
+
dimensions,
|
|
67
|
+
byModel: (byModel ?? []).map((row) => ({
|
|
68
|
+
model: String(row.model ?? ''),
|
|
69
|
+
toolCount: Number(row.tool_count ?? 0),
|
|
70
|
+
serverCount: Number(row.server_count ?? 0),
|
|
71
|
+
})),
|
|
72
|
+
byServer: (byServer ?? []).map((row) => ({
|
|
73
|
+
serverName: String(row.server_name ?? ''),
|
|
74
|
+
toolCount: Number(row.tool_count ?? 0),
|
|
75
|
+
})),
|
|
76
|
+
oldestUpdatedAt: freshness?.[0]?.oldest ?? null,
|
|
77
|
+
newestUpdatedAt: freshness?.[0]?.newest ?? null,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
logger.warn('Failed to collect vector store statistics:', error);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Serializes reindex passes inside this process. Overlapping runs would
|
|
87
|
+
* interleave their DELETE and re-embed work — leaving partially indexed servers
|
|
88
|
+
* behind — and double-spend embedding quota, so a second caller is rejected
|
|
89
|
+
* with 409 instead of racing the run in flight.
|
|
90
|
+
*/
|
|
91
|
+
let reindexInFlight = false;
|
|
92
|
+
/**
|
|
93
|
+
* GET /api/smart-routing/performance
|
|
94
|
+
*
|
|
95
|
+
* Returns a read-only snapshot of smart routing health and the vector store:
|
|
96
|
+
* resolved embedding configuration, database connection state, row counts,
|
|
97
|
+
* per-model/per-server breakdown, and sync freshness.
|
|
98
|
+
*
|
|
99
|
+
* Admin-only: the dashboard renders this section behind the admin-only
|
|
100
|
+
* `settings:smart_routing` permission, and the snapshot exposes global
|
|
101
|
+
* operational state (database configuration, index coverage).
|
|
102
|
+
*/
|
|
103
|
+
export const getSmartRoutingPerformance = async (req, res) => {
|
|
104
|
+
if (!(await requireAdmin(req, res)))
|
|
105
|
+
return;
|
|
106
|
+
try {
|
|
107
|
+
const smartRoutingConfig = await getSmartRoutingConfig();
|
|
108
|
+
const databaseHealth = getDatabaseHealth();
|
|
109
|
+
// Only reach into the database when smart routing is enabled and a DB URL
|
|
110
|
+
// is configured; otherwise report the disabled/unconfigured state as-is.
|
|
111
|
+
const dbAvailable = smartRoutingConfig.enabled &&
|
|
112
|
+
Boolean(smartRoutingConfig.dbUrl || process.env.DB_URL);
|
|
113
|
+
let vectorStore = null;
|
|
114
|
+
if (dbAvailable) {
|
|
115
|
+
if (!isDatabaseConnected()) {
|
|
116
|
+
try {
|
|
117
|
+
await initializeDatabase();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
logger.warn('Failed to initialize database for performance stats:', error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (isDatabaseConnected()) {
|
|
124
|
+
vectorStore = await queryVectorStoreStats();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Coverage is measured against every enabled server, not only the ones this
|
|
128
|
+
// principal happens to see connected: servers that require personal
|
|
129
|
+
// credentials are never connected globally, so a "connected" baseline would
|
|
130
|
+
// silently hide them from the index report.
|
|
131
|
+
let enabledServerNames = [];
|
|
132
|
+
let connectedServers = 0;
|
|
133
|
+
let personalCredentialServers = 0;
|
|
134
|
+
try {
|
|
135
|
+
const servers = await getServersInfo();
|
|
136
|
+
const enabled = servers.filter((server) => server.enabled !== false);
|
|
137
|
+
enabledServerNames = enabled.map((server) => server.name);
|
|
138
|
+
connectedServers = enabled.filter((server) => server.status === 'connected').length;
|
|
139
|
+
personalCredentialServers = enabled.filter((server) => hasCredentialTemplate(server.config)).length;
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
logger.warn('Failed to resolve servers for performance stats:', error);
|
|
143
|
+
}
|
|
144
|
+
const indexedServerSet = new Set((vectorStore?.byServer ?? []).map((entry) => entry.serverName));
|
|
145
|
+
const missingIndexServers = enabledServerNames.filter((name) => !indexedServerSet.has(name));
|
|
146
|
+
const provider = smartRoutingConfig.embeddingProvider || 'openai';
|
|
147
|
+
const data = {
|
|
148
|
+
enabled: smartRoutingConfig.enabled,
|
|
149
|
+
reindexing: reindexInFlight,
|
|
150
|
+
config: {
|
|
151
|
+
provider,
|
|
152
|
+
model: resolvePersistedEmbeddingModel(smartRoutingConfig),
|
|
153
|
+
configuredDimensions: typeof smartRoutingConfig.embeddingDimensions === 'number'
|
|
154
|
+
? smartRoutingConfig.embeddingDimensions
|
|
155
|
+
: null,
|
|
156
|
+
},
|
|
157
|
+
database: {
|
|
158
|
+
connected: databaseHealth.connected,
|
|
159
|
+
healthy: databaseHealth.healthy,
|
|
160
|
+
lastError: databaseHealth.lastError,
|
|
161
|
+
},
|
|
162
|
+
vectorStore: {
|
|
163
|
+
available: vectorStore !== null,
|
|
164
|
+
...(vectorStore ?? {
|
|
165
|
+
totalRows: 0,
|
|
166
|
+
toolRows: 0,
|
|
167
|
+
serverRows: 0,
|
|
168
|
+
distinctServers: 0,
|
|
169
|
+
dimensions: null,
|
|
170
|
+
byModel: [],
|
|
171
|
+
byServer: [],
|
|
172
|
+
oldestUpdatedAt: null,
|
|
173
|
+
newestUpdatedAt: null,
|
|
174
|
+
}),
|
|
175
|
+
},
|
|
176
|
+
coverage: {
|
|
177
|
+
totalServers: enabledServerNames.length,
|
|
178
|
+
connectedServers,
|
|
179
|
+
personalCredentialServers,
|
|
180
|
+
indexedServers: indexedServerSet.size,
|
|
181
|
+
missingIndexServerCount: missingIndexServers.length,
|
|
182
|
+
missingIndexServers: missingIndexServers.slice(0, 100),
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
const response = { success: true, data };
|
|
186
|
+
res.json(response);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
logger.error('Failed to collect smart routing performance stats:', error);
|
|
190
|
+
res.status(500).json({ success: false, message: 'Failed to collect smart routing performance stats' });
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Usernames holding a personal credential binding for a server, ordered with
|
|
195
|
+
* the server owner first so indexing favours the account that defines it.
|
|
196
|
+
*/
|
|
197
|
+
const listBindingUsernames = async (serverName, owner) => {
|
|
198
|
+
try {
|
|
199
|
+
const usernames = await getCredentialBindingDao().listUsernames(serverName);
|
|
200
|
+
const unique = [
|
|
201
|
+
...new Set(usernames.filter((name) => typeof name === 'string' && name.trim().length > 0)),
|
|
202
|
+
];
|
|
203
|
+
unique.sort((a, b) => {
|
|
204
|
+
if (a === owner)
|
|
205
|
+
return -1;
|
|
206
|
+
if (b === owner)
|
|
207
|
+
return 1;
|
|
208
|
+
return a.localeCompare(b);
|
|
209
|
+
});
|
|
210
|
+
return unique;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
logger.warn(`Failed to list credential bindings for server "${serverName}":`, error);
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* Collect the union of tools that the binding principals can see for a server.
|
|
219
|
+
* Principals are resolved sequentially because each one may spawn its own
|
|
220
|
+
* upstream connection; a reindex pass should not fan out across all of them.
|
|
221
|
+
*/
|
|
222
|
+
const collectToolsForPrincipals = async (serverName, usernames) => {
|
|
223
|
+
const merged = new Map();
|
|
224
|
+
const principals = [];
|
|
225
|
+
const errors = [];
|
|
226
|
+
for (const username of usernames) {
|
|
227
|
+
try {
|
|
228
|
+
const user = await getUserDao().findByUsername(username);
|
|
229
|
+
if (!user) {
|
|
230
|
+
errors.push(`${username}: user not found`);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const tools = await getServerToolsForPrincipal(serverName, {
|
|
234
|
+
username,
|
|
235
|
+
isAdmin: Boolean(user.isAdmin),
|
|
236
|
+
credentialEligible: true,
|
|
237
|
+
});
|
|
238
|
+
for (const tool of tools) {
|
|
239
|
+
if (tool?.name && !merged.has(tool.name)) {
|
|
240
|
+
merged.set(tool.name, tool);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
principals.push(username);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
errors.push(`${username}: ${error?.message ? String(error.message) : 'unknown error'}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { tools: [...merged.values()], principals, errors };
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* POST /api/smart-routing/reindex
|
|
253
|
+
*
|
|
254
|
+
* Force a full rebuild of all vector embeddings: every row in
|
|
255
|
+
* vector_embeddings is cleared, then every enabled server is re-embedded.
|
|
256
|
+
*
|
|
257
|
+
* Servers that declare a personal credential template are never connected
|
|
258
|
+
* globally — their runtime only exists for principals that bound their own
|
|
259
|
+
* credentials. Those servers are therefore indexed on behalf of the users who
|
|
260
|
+
* hold a binding (the server owner first), and the union of the tools those
|
|
261
|
+
* principals can see is what gets embedded. A server with no binding at all is
|
|
262
|
+
* reported as skipped instead of being silently dropped from the index.
|
|
263
|
+
*
|
|
264
|
+
* Progress is streamed to authenticated clients through the existing
|
|
265
|
+
* embedding-sync-progress SSE events emitted by saveToolsAsVectorEmbeddings.
|
|
266
|
+
* Response is sent only when the whole pass finishes (synchronous execution).
|
|
267
|
+
*
|
|
268
|
+
* Admin-only, and serialized: it clears a global table and spends embedding
|
|
269
|
+
* quota, so a second concurrent call is answered with 409.
|
|
270
|
+
*/
|
|
271
|
+
export const reindexSmartRouting = async (req, res) => {
|
|
272
|
+
if (!(await requireAdmin(req, res)))
|
|
273
|
+
return;
|
|
274
|
+
if (reindexInFlight) {
|
|
275
|
+
res.status(409).json({
|
|
276
|
+
success: false,
|
|
277
|
+
message: 'A reindex pass is already running',
|
|
278
|
+
});
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
reindexInFlight = true;
|
|
282
|
+
try {
|
|
283
|
+
const smartRoutingConfig = await getSmartRoutingConfig();
|
|
284
|
+
if (!smartRoutingConfig.enabled) {
|
|
285
|
+
res.status(400).json({ success: false, message: 'Smart routing is not enabled' });
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (!smartRoutingConfig.dbUrl && !process.env.DB_URL) {
|
|
289
|
+
res.status(400).json({ success: false, message: 'Database (DB_URL) is not configured' });
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (!isDatabaseConnected()) {
|
|
293
|
+
await initializeDatabase();
|
|
294
|
+
}
|
|
295
|
+
// 1. Clear the existing index so every tool is regenerated from scratch.
|
|
296
|
+
logger.log('Reindex: clearing all vector embeddings');
|
|
297
|
+
await getAppDataSource().query('DELETE FROM vector_embeddings');
|
|
298
|
+
// 2. Re-embed every enabled server.
|
|
299
|
+
const servers = await getServersInfo();
|
|
300
|
+
const results = [];
|
|
301
|
+
let totalTools = 0;
|
|
302
|
+
let syncedServers = 0;
|
|
303
|
+
let failedServers = 0;
|
|
304
|
+
let skippedServers = 0;
|
|
305
|
+
for (const server of servers) {
|
|
306
|
+
if (server.enabled === false) {
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
let tools;
|
|
310
|
+
let principals;
|
|
311
|
+
if (hasCredentialTemplate(server.config)) {
|
|
312
|
+
// Personal-credential server: borrow the principals that can reach it.
|
|
313
|
+
const usernames = await listBindingUsernames(server.name, server.config?.owner);
|
|
314
|
+
if (usernames.length === 0) {
|
|
315
|
+
skippedServers += 1;
|
|
316
|
+
results.push({
|
|
317
|
+
serverName: server.name,
|
|
318
|
+
toolCount: 0,
|
|
319
|
+
ok: false,
|
|
320
|
+
skipped: true,
|
|
321
|
+
error: 'No user has bound personal credentials for this server',
|
|
322
|
+
});
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
const collected = await collectToolsForPrincipals(server.name, usernames);
|
|
326
|
+
principals = collected.principals;
|
|
327
|
+
tools = collected.tools;
|
|
328
|
+
if (tools.length === 0) {
|
|
329
|
+
failedServers += 1;
|
|
330
|
+
results.push({
|
|
331
|
+
serverName: server.name,
|
|
332
|
+
toolCount: 0,
|
|
333
|
+
ok: false,
|
|
334
|
+
principals,
|
|
335
|
+
error: collected.errors.join('; ') ||
|
|
336
|
+
'No tools could be resolved with the bound personal credentials',
|
|
337
|
+
});
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
if (server.status !== 'connected') {
|
|
343
|
+
skippedServers += 1;
|
|
344
|
+
results.push({
|
|
345
|
+
serverName: server.name,
|
|
346
|
+
toolCount: 0,
|
|
347
|
+
ok: false,
|
|
348
|
+
skipped: true,
|
|
349
|
+
error: `Server is not connected (status: ${server.status ?? 'unknown'})`,
|
|
350
|
+
});
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
tools = server.tools ?? [];
|
|
354
|
+
if (tools.length === 0) {
|
|
355
|
+
skippedServers += 1;
|
|
356
|
+
results.push({
|
|
357
|
+
serverName: server.name,
|
|
358
|
+
toolCount: 0,
|
|
359
|
+
ok: false,
|
|
360
|
+
skipped: true,
|
|
361
|
+
error: 'Server exposes no tools',
|
|
362
|
+
});
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
try {
|
|
367
|
+
await saveToolsAsVectorEmbeddings(server.name, tools, { reportProgress: true });
|
|
368
|
+
syncedServers += 1;
|
|
369
|
+
totalTools += tools.length;
|
|
370
|
+
results.push({
|
|
371
|
+
serverName: server.name,
|
|
372
|
+
toolCount: tools.length,
|
|
373
|
+
ok: true,
|
|
374
|
+
...(principals ? { principals } : {}),
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
failedServers += 1;
|
|
379
|
+
logger.error(`Reindex failed for server "${server.name}":`, error);
|
|
380
|
+
results.push({
|
|
381
|
+
serverName: server.name,
|
|
382
|
+
toolCount: tools.length,
|
|
383
|
+
ok: false,
|
|
384
|
+
...(principals ? { principals } : {}),
|
|
385
|
+
error: error?.message ? String(error.message) : 'Unknown error',
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const data = {
|
|
390
|
+
syncedServers,
|
|
391
|
+
failedServers,
|
|
392
|
+
skippedServers,
|
|
393
|
+
totalTools,
|
|
394
|
+
results,
|
|
395
|
+
};
|
|
396
|
+
logger.log('Reindex completed', { syncedServers, failedServers, skippedServers, totalTools });
|
|
397
|
+
const response = { success: true, data };
|
|
398
|
+
res.json(response);
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
logger.error('Failed to rebuild smart routing index:', error);
|
|
402
|
+
res.status(500).json({ success: false, message: 'Failed to rebuild smart routing index' });
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
reindexInFlight = false;
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
//# sourceMappingURL=smartRoutingController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smartRoutingController.js","sourceRoot":"","sources":["../../src/controllers/smartRoutingController.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,11 @@ export class CredentialBindingDaoImpl {
|
|
|
36
36
|
return (this.readAll().find((item) => item.serverName === serverName && item.username === username) ??
|
|
37
37
|
null);
|
|
38
38
|
}
|
|
39
|
+
async listUsernames(serverName) {
|
|
40
|
+
return this.readAll()
|
|
41
|
+
.filter((item) => item.serverName === serverName)
|
|
42
|
+
.map((item) => item.username);
|
|
43
|
+
}
|
|
39
44
|
async save(binding) {
|
|
40
45
|
const bindings = this.readAll().filter((item) => item.serverName !== binding.serverName || item.username !== binding.username);
|
|
41
46
|
this.write([...bindings, binding]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CredentialBindingDao.js","sourceRoot":"","sources":["../../src/dao/CredentialBindingDao.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"CredentialBindingDao.js","sourceRoot":"","sources":["../../src/dao/CredentialBindingDao.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,13 @@ export class CredentialBindingDaoDbImpl {
|
|
|
10
10
|
async get(serverName, username) {
|
|
11
11
|
return this.repository.findOneBy({ serverName, username });
|
|
12
12
|
}
|
|
13
|
+
async listUsernames(serverName) {
|
|
14
|
+
const rows = await this.repository.find({
|
|
15
|
+
where: { serverName },
|
|
16
|
+
select: { username: true },
|
|
17
|
+
});
|
|
18
|
+
return rows.map((row) => row.username);
|
|
19
|
+
}
|
|
13
20
|
async save(binding) {
|
|
14
21
|
await this.repository.upsert(binding, ['serverName', 'username']);
|
|
15
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CredentialBindingDaoDbImpl.js","sourceRoot":"","sources":["../../src/dao/CredentialBindingDaoDbImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAIxE,MAAM,OAAO,0BAA0B;IACrC,IAAY,UAAU;QACpB,OAAO,gBAAgB,EAAE,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAkB,EAAE,QAAgB;QAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAgC;QACzC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAkD;QAC7D,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"CredentialBindingDaoDbImpl.js","sourceRoot":"","sources":["../../src/dao/CredentialBindingDaoDbImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAIxE,MAAM,OAAO,0BAA0B;IACrC,IAAY,UAAU;QACpB,OAAO,gBAAgB,EAAE,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAkB,EAAE,QAAgB;QAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,UAAkB;QACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACtC,KAAK,EAAE,EAAE,UAAU,EAAE;YACrB,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;SAC3B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAgC;QACzC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAkD;QAC7D,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;CACF"}
|