feat(agent-memory): UI fuer Agent-Memories mit semantischer Suche — Modul 8/16
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
Drittes Modul via Phase-Q-Manifest-Architektur: Registrierung komplett ueber das agent_memory-Plugin-Manifest (page_route /agent-memory + menu_item, Brain-Icon) — routes/index.tsx unangetastet. Komponenten-Map mit 40 Eintraegen. Zusaetzlicher Fix: Sidebar-ICON_MAP um Brain, Store, Tags erweitert — Marketplace (Store) und Tags zeigten bisher Fallback-Icons, weil die Manifest-Icons nicht in der kuratierten Map standen. Backend existierte vollstaendig (create mit Embedding, list mit agent_id-Pflichtfilter + Typ + Pagination, semantische Suche via pgvector, update mit Embedding-Regeneration, delete; agent_memory:read/write), Frontend hatte 0% Abdeckung. - api/agentMemory.ts: TanStack-Hooks (useAgentMemories mit enabled-Gating, useAgentMemorySearch, create/update/delete) - pages/AgentMemory.tsx: Agent-Picker (Pflichtfeld — Backend filtert zwingend nach agent_id), Pick-Agent-Prompt, semantische Suche mit Relevanz-Score-Badges und Clear, Memory-Karten mit Typ-Badges (fact/context/pattern/instruction), Create/Edit-Dialog, Delete mit Confirm — Aktionen hinter agent_memory:write - i18n agentMemory.* + nav.agentMemory de/en Verifikation: Vitest 11/11 (Agent-Picker-Pflicht, Pick-Prompt, Badges, Suche mit Score + Clear, Create/Edit prefilled, Delete mit+ohne Confirm, Gating, Empty/Error) · tsc exit 0 · production build exit 0 · Backend-Regressionen (route-order, m5-miniapps) 10/10 · compileall sauber · Manifest-Check OK.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Agent Memory API client — persistent agent memories with pgvector
|
||||
* semantic search.
|
||||
*
|
||||
* Backend: /api/v1/agent-memory (create, list, search, update, delete).
|
||||
* Memories store facts, context, patterns and instructions for AI agents.
|
||||
* Permissions: agent_memory:read (list/search) / agent_memory:write
|
||||
* (create, update, delete).
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { apiGet, apiPost, apiPatch, apiDelete } from '@/api/client';
|
||||
|
||||
export interface AgentMemory {
|
||||
id: string;
|
||||
agent_id: string;
|
||||
memory_type: string;
|
||||
content: string;
|
||||
owner_id: string | null;
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
/** Similarity score — only set by semantic search results. */
|
||||
score?: number;
|
||||
}
|
||||
|
||||
export interface AgentMemoryListResponse {
|
||||
items: AgentMemory[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface AgentMemoryCreatePayload {
|
||||
agent_id: string;
|
||||
memory_type: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface AgentMemoryUpdatePayload {
|
||||
content?: string;
|
||||
memory_type?: string;
|
||||
}
|
||||
|
||||
export interface AgentMemoryListParams {
|
||||
agentId: string;
|
||||
memoryType?: string;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export interface AgentMemorySearchParams {
|
||||
agentId: string;
|
||||
query: string;
|
||||
memoryType?: string;
|
||||
limit?: number;
|
||||
minScore?: number;
|
||||
}
|
||||
|
||||
// ─── Query hooks ─────────────────────────────────────────────
|
||||
|
||||
export function useAgentMemories(params: AgentMemoryListParams) {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.set('agent_id', params.agentId);
|
||||
if (params.memoryType) searchParams.set('memory_type', params.memoryType);
|
||||
if (params.page) searchParams.set('page', String(params.page));
|
||||
if (params.pageSize) searchParams.set('page_size', String(params.pageSize));
|
||||
|
||||
return useQuery<AgentMemoryListResponse>({
|
||||
queryKey: ['agent-memories', params.agentId, params.memoryType, params.page, params.pageSize],
|
||||
queryFn: () => apiGet<AgentMemoryListResponse>(`/agent-memory?${searchParams.toString()}`),
|
||||
enabled: !!params.agentId,
|
||||
});
|
||||
}
|
||||
|
||||
export function useAgentMemorySearch(params: AgentMemorySearchParams) {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.set('agent_id', params.agentId);
|
||||
searchParams.set('query', params.query);
|
||||
if (params.memoryType) searchParams.set('memory_type', params.memoryType);
|
||||
if (params.limit) searchParams.set('limit', String(params.limit));
|
||||
if (params.minScore !== undefined) searchParams.set('min_score', String(params.minScore));
|
||||
|
||||
return useQuery<AgentMemoryListResponse>({
|
||||
queryKey: ['agent-memories', 'search', params.agentId, params.query, params.memoryType],
|
||||
queryFn: () => apiGet<AgentMemoryListResponse>(`/agent-memory/search?${searchParams.toString()}`),
|
||||
enabled: !!params.agentId && !!params.query,
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Mutation hooks ──────────────────────────────────────────
|
||||
|
||||
function useInvalidateMemories() {
|
||||
const qc = useQueryClient();
|
||||
return () => {
|
||||
qc.invalidateQueries({ queryKey: ['agent-memories'] });
|
||||
};
|
||||
}
|
||||
|
||||
export function useCreateAgentMemory() {
|
||||
const invalidate = useInvalidateMemories();
|
||||
return useMutation<AgentMemory, Error, AgentMemoryCreatePayload>({
|
||||
mutationFn: (data) => apiPost<AgentMemory>('/agent-memory', data),
|
||||
onSuccess: invalidate,
|
||||
});
|
||||
}
|
||||
|
||||
export function useUpdateAgentMemory() {
|
||||
const invalidate = useInvalidateMemories();
|
||||
return useMutation<
|
||||
AgentMemory,
|
||||
Error,
|
||||
{ memoryId: string; payload: AgentMemoryUpdatePayload }
|
||||
>({
|
||||
mutationFn: ({ memoryId, payload }) =>
|
||||
apiPatch<AgentMemory>(`/agent-memory/${memoryId}`, payload),
|
||||
onSuccess: invalidate,
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteAgentMemory() {
|
||||
const invalidate = useInvalidateMemories();
|
||||
return useMutation<void, Error, string>({
|
||||
mutationFn: (memoryId) => apiDelete(`/agent-memory/${memoryId}`),
|
||||
onSuccess: invalidate,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user