Files
memind/mindspace-runtime-config.mjs
T

164 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import path from 'node:path';
import { DEFAULT_MAX_FILE_BYTES } from './mindspace.mjs';
import { createMindSpaceServiceFacade } from './mindspace-service.mjs';
import { createLocalMindSpaceStorageAdapter } from './mindspace-storage-adapter.mjs';
import { normalizeWorkspaceRelativePath } from './mindspace-workspace-relative-path.mjs';
import {
buildPublicUrl,
PUBLISH_ROOT_DIR,
resolveGoosedSandboxRoot,
resolvePublicBaseUrl,
resolvePublishDir,
} from './user-publish.mjs';
export function resolvePortalH5Root(codeRoot, env = process.env) {
const configuredRoot = String(env.MEMIND_PORTAL_H5_ROOT ?? '').trim();
return path.resolve(configuredRoot || codeRoot);
}
export function resolvePageWorkspaceRelativePath(row) {
const fromColumn = normalizeWorkspaceRelativePath(row?.workspace_relative_path);
if (fromColumn) return fromColumn;
let snapshot = row?.source_snapshot_json;
if (typeof snapshot === 'string') {
try {
snapshot = JSON.parse(snapshot);
} catch {
snapshot = null;
}
}
return normalizeWorkspaceRelativePath(snapshot?.relative_path);
}
export function isPublicWorkspaceHtmlRelativePath(relativePath) {
const normalized = normalizeWorkspaceRelativePath(relativePath);
return Boolean(normalized?.startsWith('public/') && normalized.toLowerCase().endsWith('.html'));
}
/** MindSpace 工作区静态页 canonical 公网 URL/MindSpace/<用户ID>/public/... */
export function resolveWorkspaceMindSpacePublicUrl({
h5Root,
env = process.env,
userId,
relativePath,
} = {}) {
const normalized = normalizeWorkspaceRelativePath(relativePath);
if (!userId || !normalized || !isPublicWorkspaceHtmlRelativePath(normalized)) return null;
return buildMindSpacePublicUrlForUser({
h5Root: h5Root ?? process.cwd(),
env,
user: userId,
relativePath: normalized,
});
}
export function resolveMindSpaceStorageRoot(h5Root, env = process.env) {
return path.resolve(env.MINDSPACE_STORAGE_ROOT ?? path.join(h5Root, 'data', 'mindspace'));
}
export function resolveMindSpaceRuntimeConfig(h5Root, env = process.env) {
return {
storageRoot: resolveMindSpaceStorageRoot(h5Root, env),
publicBaseUrl: resolvePublicBaseUrl(env),
};
}
export function resolveMindSpaceServerRuntimeOptions(h5Root, env = process.env) {
const runtime = resolveMindSpaceRuntimeConfig(h5Root, env);
return {
...runtime,
adapterKind: String(env.MINDSPACE_SERVER_ADAPTER ?? 'local').trim().toLowerCase() || 'local',
publishRoot: resolveMindSpacePublishRoot(h5Root),
maxFileBytes: Number(env.MINDSPACE_MAX_FILE_BYTES ?? DEFAULT_MAX_FILE_BYTES),
aiDailyLimit: Number(env.MINDSPACE_FREE_AI_DAILY_LIMIT ?? 10),
publicPageLimit: Number(env.MINDSPACE_FREE_PUBLIC_PAGE_LIMIT ?? 5),
monthlyViewLimit: Number(env.MINDSPACE_FREE_MONTHLY_VIEW_LIMIT ?? 1000),
experienceEnabled: env.MINDSPACE_EXPERIENCE_ENABLED !== 'false',
agentWorker: {
enabled: env.MINDSPACE_AGENT_WORKER_ENABLED === 'true',
concurrency: Math.max(1, Number(env.MINDSPACE_AGENT_WORKER_CONCURRENCY ?? 2)),
pollMs: Math.max(200, Number(env.MINDSPACE_AGENT_WORKER_POLL_MS ?? 1000)),
staleMs: Math.max(10_000, Number(env.MINDSPACE_AGENT_WORKER_STALE_MS ?? 5 * 60 * 1000)),
ssePollMs: Math.max(500, Number(env.MINDSPACE_AGENT_SSE_POLL_MS ?? 1000)),
},
remote: {
baseUrl: String(env.MINDSPACE_REMOTE_BASE_URL ?? '').trim(),
authToken: String(env.MINDSPACE_REMOTE_AUTH_TOKEN ?? '').trim(),
operationBasePath: String(env.MINDSPACE_REMOTE_OPERATION_BASE_PATH ?? '/mindspace/v1/adapter')
.trim(),
timeoutMs: Math.max(1000, Number(env.MINDSPACE_REMOTE_TIMEOUT_MS ?? 15_000)),
},
};
}
export function resolveMindSpacePublishRoot(h5Root) {
return path.resolve(h5Root, PUBLISH_ROOT_DIR);
}
export function resolveMindSpaceUserPublishDir(h5Root, user) {
return path.resolve(resolvePublishDir(h5Root, user));
}
export function buildMindSpacePublicRoutePath(ownerKey, segments = []) {
const userId = String(ownerKey ?? '').trim();
if (!userId) {
throw new Error('MindSpace public route requires an owner key');
}
const cleanSegments = Array.isArray(segments)
? segments.map((segment) => encodeURIComponent(String(segment ?? '')))
: [];
return `/${PUBLISH_ROOT_DIR}/${encodeURIComponent(userId)}${cleanSegments.length ? `/${cleanSegments.join('/')}` : '/'}`;
}
export function buildMindSpacePublicUrlForUser({ h5Root, env = process.env, user, relativePath = '' } = {}) {
const ownerKey =
typeof user === 'string' || typeof user === 'number'
? String(user)
: String(user?.id ?? '').trim();
if (!ownerKey) {
throw new Error('MindSpace public URL requires a user id');
}
const { publicBaseUrl } = resolveMindSpaceRuntimeConfig(h5Root, env);
return buildPublicUrl(publicBaseUrl, ownerKey, relativePath);
}
export function buildMindSpaceWorkspaceRef(user) {
const ownerKey =
typeof user === 'string' || typeof user === 'number'
? String(user)
: String(user?.id ?? '').trim();
if (!ownerKey) {
throw new Error('MindSpace workspace ref requires a user id');
}
return `mindspace://users/${encodeURIComponent(ownerKey)}/workspace`;
}
export function resolveMindSpaceAgentWorkspaceCapability({ h5Root, env = process.env, user } = {}) {
return {
workspaceRoot: resolveMindSpaceUserPublishDir(h5Root, user),
sandboxRoot: resolveGoosedSandboxRoot(h5Root, user, env),
workspaceRef: buildMindSpaceWorkspaceRef(user),
};
}
export function createMindSpaceLocalRuntime({
h5Root,
env = process.env,
conversationPackageBackfill,
conversationPackagePublicHtmlHydrator,
logger = console,
} = {}) {
const config = resolveMindSpaceRuntimeConfig(h5Root, env);
return {
...config,
storageAdapter: createLocalMindSpaceStorageAdapter(config.storageRoot),
serviceFacade: createMindSpaceServiceFacade({
storageAdapter: createLocalMindSpaceStorageAdapter(config.storageRoot),
publicBaseUrl: config.publicBaseUrl,
conversationPackageBackfill,
conversationPackagePublicHtmlHydrator,
logger,
}),
};
}