feat: fix RAG pipelines, Beep Graph branding, PWA, and ambient glow UI

Pipeline fixes:
- Fix agent getting empty response from graph-rag by combining answer +
  explain data in single message (RequestResponse returns first msg)
- Fix Doc RAG pipeline: add content field to Qdrant doc payload, seed 10
  document chunks, fix type mismatches across base/flow/client
- Forward explainability events from agent's KnowledgeQuery to client
- Add "agent" to TERM_BEARING_RESPONSE_SERVICES for triple translation
- Fix embeddings env var (OLLAMA_URL), user/collection threading, edge
  scoring threshold, and various protocol mismatches

Branding:
- Rename TrustGraph → Beep Graph (title, sidebar, settings, about)
- Custom lambda + ThugLife pixel glasses SVG logo component
- Forest green color palette (brand-50 through brand-900)
- SVG favicon + PNG icons (16/32/180/192/512)
- PWA manifest with service worker for offline shell caching
- Splash screen with animated logo pulse on app load
- Ambient glow background with drifting green radial blobs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
elpresidank 2026-04-12 10:19:10 -05:00
parent 87f6e5eb05
commit ee45cb4850
42 changed files with 1690 additions and 153 deletions

View file

@ -42,6 +42,7 @@ import {
createDocumentQueryTool,
createTriplesQueryTool,
createMcpTool,
type ExplainData,
} from "./tools.js";
import { buildReActPrompt } from "./prompt.js";
import { filterToolsByGroupAndState, getNextState } from "../tool-filter.js";
@ -222,7 +223,12 @@ export class AgentService extends FlowProcessor {
* Wire up tool execute functions with live requestors from the flow context.
* Config-driven tools store placeholders; this replaces them with real impls.
*/
private wireTools(tools: AgentTool[], flowCtx: FlowContext, collection?: string): AgentTool[] {
private wireTools(
tools: AgentTool[],
flowCtx: FlowContext,
collection?: string,
onExplain?: (data: ExplainData) => void,
): AgentTool[] {
return tools.map((tool) => {
const implType = tool.config?.["type"] as string | undefined;
@ -231,6 +237,7 @@ export class AgentService extends FlowProcessor {
const live = createKnowledgeQueryTool(
flowCtx.flow.requestor<GraphRagRequest, GraphRagResponse>("graph-rag"),
collection,
onExplain,
);
return { ...tool, execute: live.execute };
}
@ -274,17 +281,24 @@ export class AgentService extends FlowProcessor {
const responseProducer = flowCtx.flow.producer<AgentResponse>("agent-response");
try {
// Accumulate explain data from tool calls for emission after completion
const explainEvents: ExplainData[] = [];
const onExplain = (data: ExplainData) => {
explainEvents.push(data);
};
// Build tools — config-driven or hardcoded fallback
let tools: AgentTool[];
if (this.configuredTools) {
tools = this.wireTools(this.configuredTools, flowCtx, msg.collection);
tools = this.wireTools(this.configuredTools, flowCtx, msg.collection, onExplain);
} else {
// Hardcoded fallback (backward compat)
tools = [
createKnowledgeQueryTool(
flowCtx.flow.requestor<GraphRagRequest, GraphRagResponse>("graph-rag"),
msg.collection,
onExplain,
),
createDocumentQueryTool(
flowCtx.flow.requestor<DocumentRagRequest, DocumentRagResponse>("doc-rag"),
@ -348,8 +362,18 @@ export class AgentService extends FlowProcessor {
});
}
// If we got a final answer, send it and return
// If we got a final answer, emit explain events then send the answer
if (parsed.finalAnswer) {
// Emit explain events collected from tool calls
for (const explain of explainEvents) {
await responseProducer.send(requestId, {
chunk_type: "explain",
content: "",
explain_id: explain.explainId,
explain_triples: explain.triples,
} as AgentResponse);
}
await responseProducer.send(requestId, {
chunk_type: "answer",
content: parsed.finalAnswer,