feat(admin): surface Memory V2 candidate auto-review in management UI
Clarify active/canary/shadow modes and show auto-review metrics so operators do not need to manually approve every user memory. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -57,14 +57,14 @@ const CAPABILITIES: Array<{
|
|||||||
key: 'candidateMemory',
|
key: 'candidateMemory',
|
||||||
label: '候选记忆',
|
label: '候选记忆',
|
||||||
icon: 'C',
|
icon: 'C',
|
||||||
description: '控制候选提取模式、接纳阈值与待处理数量。',
|
description: '控制候选提取模式、自动接纳阈值与待处理数量。',
|
||||||
fields: [
|
fields: [
|
||||||
{ key: 'enabled', label: '启用候选记忆', type: 'boolean' },
|
{ key: 'enabled', label: '启用候选记忆', type: 'boolean' },
|
||||||
{ key: 'mode', label: '运行模式', type: 'select', options: [
|
{ key: 'mode', label: '运行模式', type: 'select', options: [
|
||||||
{ value: 'off', label: 'Off' },
|
{ value: 'off', label: 'Off · 关闭' },
|
||||||
{ value: 'shadow', label: 'Shadow' },
|
{ value: 'active', label: 'Active · 规则通过后自动接纳(推荐)' },
|
||||||
{ value: 'canary', label: 'Canary' },
|
{ value: 'canary', label: 'Canary · 仅高置信度自动接纳' },
|
||||||
{ value: 'active', label: 'Active' },
|
{ value: 'shadow', label: 'Shadow · 全部人工审核' },
|
||||||
] },
|
] },
|
||||||
{ key: 'minImportance', label: '最低重要度', type: 'number' },
|
{ key: 'minImportance', label: '最低重要度', type: 'number' },
|
||||||
{ key: 'minConfidence', label: '最低置信度', type: 'number' },
|
{ key: 'minConfidence', label: '最低置信度', type: 'number' },
|
||||||
@@ -314,7 +314,7 @@ function defaultConfig(): MemoryV2AdminConfig {
|
|||||||
timeoutMs: '1500',
|
timeoutMs: '1500',
|
||||||
fallbackRoute: 'agent_orchestration',
|
fallbackRoute: 'agent_orchestration',
|
||||||
},
|
},
|
||||||
candidateMemory: { enabled: false, mode: 'off', minImportance: '0.7', minConfidence: '0.8', maxPending: '500', persistenceEnabled: false },
|
candidateMemory: { enabled: false, mode: 'active', minImportance: '0.7', minConfidence: '0.8', maxPending: '500', persistenceEnabled: false },
|
||||||
policy: { enabled: false, saveExplicit: true, rejectSensitive: true, requireEvidence: true, retentionDays: '365' },
|
policy: { enabled: false, saveExplicit: true, rejectSensitive: true, requireEvidence: true, retentionDays: '365' },
|
||||||
retriever: { enabled: false, episodicEnabled: true, semanticEnabled: true, preferenceEnabled: true, goalEnabled: true, limit: '12', tokenBudget: '1800', timeoutMs: '1200' },
|
retriever: { enabled: false, episodicEnabled: true, semanticEnabled: true, preferenceEnabled: true, goalEnabled: true, limit: '12', tokenBudget: '1800', timeoutMs: '1200' },
|
||||||
lifecycle: { enabled: false, dedupeEnabled: true, conflictReview: true, decayEnabled: false, forgettingEnabled: true, compactIntervalHours: '24' },
|
lifecycle: { enabled: false, dedupeEnabled: true, conflictReview: true, decayEnabled: false, forgettingEnabled: true, compactIntervalHours: '24' },
|
||||||
@@ -954,8 +954,10 @@ export function MemoryV2Page() {
|
|||||||
<span>
|
<span>
|
||||||
{String(runtimeStatus.memory.personalMemory.health?.state ?? 'unknown')}
|
{String(runtimeStatus.memory.personalMemory.health?.state ?? 'unknown')}
|
||||||
{' · '}模式 {runtimeStatus.memory.personalMemory.effectiveMode ?? 'off'}
|
{' · '}模式 {runtimeStatus.memory.personalMemory.effectiveMode ?? 'off'}
|
||||||
|
{runtimeStatus.memory.personalMemory.autoReviewEnabled ? ' · 自动审核' : ' · 人工审核'}
|
||||||
{' · '}候选 {runtimeStatus.memory.personalMemory.pendingCandidates ?? 0}
|
{' · '}候选 {runtimeStatus.memory.personalMemory.pendingCandidates ?? 0}
|
||||||
{' · '}接纳 {runtimeStatus.memory.personalMemory.health?.accepted ?? 0}
|
{' · '}接纳 {runtimeStatus.memory.personalMemory.health?.accepted ?? 0}
|
||||||
|
{' · '}自动接纳 {runtimeStatus.memory.personalMemory.health?.autoReviewed ?? 0}
|
||||||
{' · '}拒绝 {runtimeStatus.memory.personalMemory.health?.rejected ?? 0}
|
{' · '}拒绝 {runtimeStatus.memory.personalMemory.health?.rejected ?? 0}
|
||||||
{' · '}去重 {runtimeStatus.memory.personalMemory.health?.deduped ?? 0}
|
{' · '}去重 {runtimeStatus.memory.personalMemory.health?.deduped ?? 0}
|
||||||
</span>
|
</span>
|
||||||
@@ -992,6 +994,9 @@ export function MemoryV2Page() {
|
|||||||
{' · '}已接纳 {candidatePayload?.counts?.accepted ?? 0}
|
{' · '}已接纳 {candidatePayload?.counts?.accepted ?? 0}
|
||||||
{' · '}已拒绝 {candidatePayload?.counts?.rejected ?? 0}
|
{' · '}已拒绝 {candidatePayload?.counts?.rejected ?? 0}
|
||||||
</p>
|
</p>
|
||||||
|
<p className="model-center-card-note">
|
||||||
|
Active 模式下规则通过的候选会自动接纳。此处仅显示 Shadow / Canary 模式下仍需人工确认的例外项。
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" className="ghost-btn" onClick={() => void load()} disabled={loading || candidateBusyId !== null}>
|
<button type="button" className="ghost-btn" onClick={() => void load()} disabled={loading || candidateBusyId !== null}>
|
||||||
刷新候选
|
刷新候选
|
||||||
@@ -1000,7 +1005,7 @@ export function MemoryV2Page() {
|
|||||||
|
|
||||||
{candidateError && <p className="banner banner-error">{candidateError}</p>}
|
{candidateError && <p className="banner banner-error">{candidateError}</p>}
|
||||||
{!candidateError && (candidatePayload?.items.length ?? 0) === 0 && (
|
{!candidateError && (candidatePayload?.items.length ?? 0) === 0 && (
|
||||||
<p className="model-center-card-note">当前没有待审核候选。Shadow Pipeline 观察到稳定决策、偏好或目标后会写入这里。</p>
|
<p className="model-center-card-note">当前没有待审核候选。Active 模式下候选会自动接纳;Shadow / Canary 模式下低置信度项会出现在这里。</p>
|
||||||
)}
|
)}
|
||||||
<div className="memory-v2-candidate-list">
|
<div className="memory-v2-candidate-list">
|
||||||
{(candidatePayload?.items ?? []).map((candidate) => (
|
{(candidatePayload?.items ?? []).map((candidate) => (
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ export type MemoryV2RuntimeStatusResponse = {
|
|||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
requestedMode?: string;
|
requestedMode?: string;
|
||||||
effectiveMode?: string;
|
effectiveMode?: string;
|
||||||
|
autoReviewEnabled?: boolean;
|
||||||
phase?: string;
|
phase?: string;
|
||||||
injectionEnabled?: boolean;
|
injectionEnabled?: boolean;
|
||||||
persistence?: string;
|
persistence?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user