feat(goose): complete v1.49 phase3 closeout gates and context fusion plan

Expand Goose v1.49 smoke coverage (memory chat, portal resume, page e2e,
multiturn provider), add canary memory policy lock, refresh baselines, and
ignore one-off evidence artifacts. Document headroom-based context runtime
fusion plan; include auth, scheduled-task, and wechat intent fixes on branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-09-09 18:11:39 +08:00
parent 1274943f33
commit 1d165bc6e3
52 changed files with 3565 additions and 840 deletions
+24 -1
View File
@@ -29,7 +29,7 @@ import {
} from './scripts/goose-v149-canary.mjs';
import { createImgproxySigner } from './imgproxy-signer.mjs';
import { isDirectChatSessionId } from './direct-chat-service.mjs';
import { ensureGooseUserMessageMetadata } from './goose-message.mjs';
import { ensureGooseUserMessageMetadata, ensureGooseConversationMetadata } from './goose-message.mjs';
import { filterMemoriesByQuery, resolveMemoriesWithLegacyFallback } from './memory-legacy-fallback.mjs';
import {
collectPageDataDeliveryArtifacts,
@@ -1977,6 +1977,28 @@ export function createTkmindProxy({
};
}
async function replaceSessionConversationForUser(userId, sessionId, conversation) {
if (!userId || !sessionId) throw new Error('缺少会话信息');
const owns = await sessionStore.validateOwnership(userId, sessionId);
if (!owns) throw new Error('无权访问该会话');
const messages = ensureGooseConversationMetadata(conversation);
const target = await resolveTarget(sessionId);
const update = await apiFetch(
target,
apiSecret,
`/sessions/${encodeURIComponent(sessionId)}`,
{
method: 'PUT',
body: JSON.stringify({ conversation: messages }),
},
);
if (!update.ok) {
const text = await update.text().catch(() => '');
throw new Error(text || `更新会话对话失败 (${update.status})`);
}
return { ok: true, status: update.status, messageCount: messages.length };
}
async function repairSessionToolHistory(sessionId) {
if (!sessionId) return { changed: false, updated: false };
const target = await resolveTarget(sessionId);
@@ -3095,6 +3117,7 @@ export function createTkmindProxy({
getRuntimeStatus,
submitSessionReplyForUser,
submitSessionReplyAndAwaitFinishForUser,
replaceSessionConversationForUser,
apiFetch: async (pathname, init) => apiFetch(await pickTarget(), apiSecret, pathname, init),
apiFetchTo: (target, pathname, init) => apiFetch(target, apiSecret, pathname, init),
};