refactor: Business logic and dependencies updates
- 核心服务代码更新 (db, server, auth, proxy) - Agent 相关模块更新 (mindspace, experience) - 前端组件和 hooks 更新 - 数据库 schema 更新 - 依赖版本更新
This commit is contained in:
+53
-4
@@ -6,6 +6,7 @@ import { evaluateProxyRequest, isNativeH5ApiPath } from './policies.mjs';
|
||||
import { buildSandboxSessionConstraints } from './user-publish.mjs';
|
||||
import { buildTaskRoutingAgentText } from './user-memory-profile.mjs';
|
||||
import { reconcileAgentSession } from './session-reconcile.mjs';
|
||||
import { createImgproxySigner } from './imgproxy-signer.mjs';
|
||||
|
||||
const insecureDispatcher = new Agent({
|
||||
connect: { rejectUnauthorized: false },
|
||||
@@ -158,6 +159,7 @@ export async function buildVisionPayload({
|
||||
publishLayout,
|
||||
localFetchAsset,
|
||||
llmProviderService,
|
||||
imgproxySigner = null,
|
||||
}) {
|
||||
if (!localFetchAsset || !llmProviderService || !userId) return null;
|
||||
const rawImageUrls = extractImageUrlsFromMessage(userMessage);
|
||||
@@ -166,10 +168,39 @@ export async function buildVisionPayload({
|
||||
const imageItems = [];
|
||||
for (const rawUrl of rawImageUrls) {
|
||||
try {
|
||||
const match = rawUrl.match(/\/mindspace\/v1\/assets\/([^/?#]+)\/download/);
|
||||
const match = rawUrl.match(/\/mindspace\/v1\/assets\/([^/?#]+)(?:\/download)?/);
|
||||
if (!match) continue;
|
||||
const assetId = decodeURIComponent(match[1]);
|
||||
const { buffer, mimeType } = await localFetchAsset(userId, assetId);
|
||||
|
||||
let buffer;
|
||||
let mimeType = 'image/jpeg';
|
||||
|
||||
if (imgproxySigner) {
|
||||
try {
|
||||
const visionUrl = imgproxySigner.buildUrl(
|
||||
process.env.IMGPROXY_BASE_URL || 'https://img.tkmind.cn',
|
||||
`users/${userId}/assets/${assetId}`,
|
||||
'vision'
|
||||
);
|
||||
const visionResponse = await undiciFetch(visionUrl);
|
||||
if (visionResponse.ok) {
|
||||
buffer = Buffer.from(await visionResponse.arrayBuffer());
|
||||
mimeType = visionResponse.headers.get('content-type') || 'image/jpeg';
|
||||
} else {
|
||||
throw new Error(`Vision fetch failed: ${visionResponse.status}`);
|
||||
}
|
||||
} catch (visionErr) {
|
||||
console.warn(`Vision fetch fallback for asset ${assetId}:`, visionErr instanceof Error ? visionErr.message : visionErr);
|
||||
const asset = await localFetchAsset(userId, assetId);
|
||||
buffer = asset.buffer;
|
||||
mimeType = asset.mimeType;
|
||||
}
|
||||
} else {
|
||||
const asset = await localFetchAsset(userId, assetId);
|
||||
buffer = asset.buffer;
|
||||
mimeType = asset.mimeType;
|
||||
}
|
||||
|
||||
let relativePath = rawUrl;
|
||||
try {
|
||||
const parsed = new URL(rawUrl);
|
||||
@@ -240,6 +271,19 @@ export function createTkmindProxy({ apiTarget, apiTargets, apiSecret, userAuth,
|
||||
const primaryTarget = targets[0] ?? apiTarget ?? '';
|
||||
let rrIdx = 0;
|
||||
|
||||
let imgproxySigner = null;
|
||||
if (process.env.IMGPROXY_BASE_URL && process.env.IMGPROXY_SIGNING_KEY && process.env.IMGPROXY_SIGNING_SALT) {
|
||||
try {
|
||||
imgproxySigner = createImgproxySigner(
|
||||
process.env.IMGPROXY_SIGNING_KEY,
|
||||
process.env.IMGPROXY_SIGNING_SALT,
|
||||
);
|
||||
console.log('[TKMindProxy] imgproxy signer initialized');
|
||||
} catch (err) {
|
||||
console.warn('[TKMindProxy] imgproxy signer init failed:', err instanceof Error ? err.message : err);
|
||||
}
|
||||
}
|
||||
|
||||
async function targetHealthy(target) {
|
||||
try {
|
||||
const upstream = await apiFetch(target, apiSecret, '/status', {
|
||||
@@ -265,7 +309,11 @@ export function createTkmindProxy({ apiTarget, apiTargets, apiSecret, userAuth,
|
||||
async function resolveTarget(sessionId) {
|
||||
if (targets.length <= 1 || !sessionId) return primaryTarget;
|
||||
try {
|
||||
const node = await userAuth.getSessionNode(sessionId);
|
||||
const { target, node } = await userAuth.getSessionTarget(sessionId);
|
||||
// Prefer the pinned URL: stable across reordering/resizing the target list.
|
||||
// Only honor it if that upstream is still configured; otherwise fall back to
|
||||
// the legacy integer index, then to primary.
|
||||
if (target && targets.includes(target)) return target;
|
||||
return targets[node] ?? primaryTarget;
|
||||
} catch {
|
||||
return primaryTarget;
|
||||
@@ -323,6 +371,7 @@ export function createTkmindProxy({ apiTarget, apiTargets, apiSecret, userAuth,
|
||||
publishLayout,
|
||||
localFetchAsset,
|
||||
llmProviderService,
|
||||
imgproxySigner,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -416,7 +465,7 @@ export function createTkmindProxy({ apiTarget, apiTargets, apiSecret, userAuth,
|
||||
await userAuth.registerAgentSession(
|
||||
req.currentUser.id,
|
||||
session.id,
|
||||
Math.max(0, targets.indexOf(startTarget)),
|
||||
startTarget,
|
||||
);
|
||||
if (sessionPolicy.gooseMode) {
|
||||
const modeRes = await apiFetch(startTarget, apiSecret, '/agent/update_session', {
|
||||
|
||||
Reference in New Issue
Block a user