first commit
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
// Store - Application state management
|
||||
const Store = {
|
||||
currentDoc: null,
|
||||
currentSession: null,
|
||||
documents: [],
|
||||
sessions: [],
|
||||
memories: [],
|
||||
findings: [],
|
||||
pageChunks: [],
|
||||
currentPage: 0,
|
||||
polygonsVisible: true,
|
||||
textVisible: true,
|
||||
chunkLabelsVisible: true,
|
||||
};
|
||||
|
||||
// ── API Helper ──
|
||||
async function api(endpoint, options = {}) {
|
||||
const defaultOpts = {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
};
|
||||
const merged = { ...defaultOpts, ...options };
|
||||
if (options.body && typeof options.body === 'object' && !(options.body instanceof FormData)) {
|
||||
merged.body = JSON.stringify(options.body);
|
||||
}
|
||||
const url = endpoint.startsWith('http') ? endpoint : `/api${endpoint}`;
|
||||
const resp = await fetch(url, merged);
|
||||
if (!resp.ok) {
|
||||
const text = await resp.text();
|
||||
throw new Error(`${resp.status}: ${text}`);
|
||||
}
|
||||
const ct = resp.headers.get('content-type') || '';
|
||||
if (ct.includes('json')) return resp.json();
|
||||
return resp;
|
||||
}
|
||||
|
||||
// ── Document Store ──
|
||||
const DocStore = {
|
||||
async load() {
|
||||
const res = await api('/documents');
|
||||
Store.documents = res.documents || [];
|
||||
return Store.documents;
|
||||
},
|
||||
|
||||
async getChunks(docId, page) {
|
||||
const params = new URLSearchParams();
|
||||
if (page !== undefined) params.set('page', page);
|
||||
const res = await api(`/documents/${docId}/chunks?${params}`);
|
||||
Store.pageChunks = res.chunks || [];
|
||||
return Store.pageChunks;
|
||||
},
|
||||
|
||||
async upload(file) {
|
||||
const fd = new FormData();
|
||||
fd.append('file', file);
|
||||
const res = await api('/documents/upload', { method: 'POST', body: fd });
|
||||
return res;
|
||||
},
|
||||
|
||||
async uploadUrl(url, filename) {
|
||||
const res = await api('/documents/upload', {
|
||||
method: 'POST',
|
||||
body: { pdf_url: url, filename },
|
||||
});
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
// ── Research Store ──
|
||||
const ResearchStore = {
|
||||
async run(query, skillNames) {
|
||||
const res = await api('/research/run', {
|
||||
method: 'POST',
|
||||
body: { query, skills: skillNames, doc_id: Store.currentDoc },
|
||||
});
|
||||
return res;
|
||||
},
|
||||
|
||||
async createSession(query) {
|
||||
const res = await api('/research/session', {
|
||||
method: 'POST',
|
||||
body: query,
|
||||
});
|
||||
return res;
|
||||
},
|
||||
|
||||
async semanticSearch(query, limit = 20) {
|
||||
const res = await api('/research/semantic', {
|
||||
method: 'POST',
|
||||
body: { query, doc_id: Store.currentDoc, limit },
|
||||
});
|
||||
return res;
|
||||
},
|
||||
|
||||
async textSearch(query, limit = 20) {
|
||||
const res = await api('/research/text-search', {
|
||||
method: 'POST',
|
||||
body: { query, doc_id: Store.currentDoc, limit },
|
||||
});
|
||||
return res;
|
||||
},
|
||||
|
||||
async getFindings(sessionId) {
|
||||
const res = await api(`/research/findings?session_id=${sessionId || ''}`);
|
||||
Store.findings = res.findings || [];
|
||||
return Store.findings;
|
||||
},
|
||||
|
||||
async getMemories(sessionId) {
|
||||
const res = await api(`/research/memories?session_id=${sessionId || ''}`);
|
||||
Store.memories = res.memories || [];
|
||||
return Store.memories;
|
||||
},
|
||||
|
||||
async saveFinding(sessionId, query, response) {
|
||||
await api('/research/run', {
|
||||
method: 'POST',
|
||||
body: { query, doc_id: sessionId },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// ── Memory Store ──
|
||||
const MemoryStore = {
|
||||
async save(content, type = 'fact', importance = 3, sourceDocId) {
|
||||
const res = await api('/memories/save', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
session_id: Store.currentSession,
|
||||
content,
|
||||
memory_type: type,
|
||||
importance,
|
||||
source_doc_id: sourceDocId,
|
||||
},
|
||||
});
|
||||
return res;
|
||||
},
|
||||
|
||||
async search(query, limit = 10) {
|
||||
const res = await api('/memories/search', {
|
||||
method: 'POST',
|
||||
body: { query, limit },
|
||||
});
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
// ── Agent Store ──
|
||||
const AgentStore = {
|
||||
async getSkills() {
|
||||
const res = await api('/agents/skills');
|
||||
return res.skills;
|
||||
},
|
||||
|
||||
async chat(message, model) {
|
||||
const res = await api('/ollama/chat', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
model: model || 'gpt-oss:20b',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
},
|
||||
});
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
// ── Viewer Store ──
|
||||
const ViewerStore = {
|
||||
async getPolygonView(docId, page) {
|
||||
const res = await api(`/documents/${docId}/polygon-view?page=${page}`);
|
||||
return res;
|
||||
},
|
||||
|
||||
async getPageText(docId, page) {
|
||||
const res = await api(`/documents/${docId}/page-text?page=${page}`);
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
// ── Health Store ──
|
||||
const HealthStore = {
|
||||
async check() {
|
||||
const res = await api('/health');
|
||||
return res;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user