mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-01 09:29:38 +02:00
Add typed flow spec accessors
This commit is contained in:
parent
abb6f3aed0
commit
44110c5bb4
19 changed files with 457 additions and 223 deletions
|
|
@ -71,6 +71,8 @@ export class McpToolRuntime extends Context.Service<
|
|||
McpToolRuntimeService
|
||||
>()("@trustgraph/flow/agent/mcp-tool/service/McpToolRuntime") {}
|
||||
|
||||
const McpToolResponseProducer = makeProducerSpec<ToolResponse>("mcp-tool-response");
|
||||
|
||||
const mcpToolError = (
|
||||
operation: string,
|
||||
cause: unknown,
|
||||
|
|
@ -246,7 +248,7 @@ const onMcpToolRequest = Effect.fn("McpToolService.onRequest")(function* (
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const responseProducer = yield* flowCtx.flow.producerEffect<ToolResponse>("mcp-tool-response");
|
||||
const responseProducer = yield* flowCtx.flow.producerEffect(McpToolResponseProducer);
|
||||
const runtime = yield* McpToolRuntime;
|
||||
|
||||
const result = yield* parametersFromJson(msg.name, msg.parameters).pipe(
|
||||
|
|
@ -284,7 +286,7 @@ export const makeMcpToolSpecs = (): ReadonlyArray<Spec<McpToolRuntime>> => [
|
|||
"mcp-tool-request",
|
||||
onMcpToolRequest,
|
||||
),
|
||||
makeProducerSpec<ToolResponse>("mcp-tool-response"),
|
||||
McpToolResponseProducer,
|
||||
];
|
||||
|
||||
export const makeMcpToolConfigHandlers = (): ReadonlyArray<
|
||||
|
|
|
|||
|
|
@ -71,6 +71,33 @@ class AgentToolExecutionError extends S.TaggedErrorClass<AgentToolExecutionError
|
|||
},
|
||||
) {}
|
||||
|
||||
const AgentResponseProducer = makeProducerSpec<AgentResponse>("agent-response");
|
||||
const AgentLlmClient = makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
);
|
||||
const AgentGraphRagClient = makeRequestResponseSpec<GraphRagRequest, GraphRagResponse>(
|
||||
"graph-rag",
|
||||
"graph-rag-request",
|
||||
"graph-rag-response",
|
||||
);
|
||||
const AgentDocRagClient = makeRequestResponseSpec<DocumentRagRequest, DocumentRagResponse>(
|
||||
"doc-rag",
|
||||
"document-rag-request",
|
||||
"document-rag-response",
|
||||
);
|
||||
const AgentTriplesClient = makeRequestResponseSpec<TriplesQueryRequest, TriplesQueryResponse>(
|
||||
"triples",
|
||||
"triples-request",
|
||||
"triples-response",
|
||||
);
|
||||
const AgentMcpToolClient = makeRequestResponseSpec<ToolRequest, ToolResponse>(
|
||||
"mcp-tool",
|
||||
"mcp-tool-request",
|
||||
"mcp-tool-response",
|
||||
);
|
||||
|
||||
const UnknownRecord = S.Record(S.String, S.Unknown);
|
||||
const ToolArgumentConfig = S.StructWithRest(
|
||||
S.Struct({
|
||||
|
|
@ -248,10 +275,10 @@ const wireTools = Effect.fn("AgentService.wireTools")(function* (
|
|||
collection: string | undefined,
|
||||
onExplain: (data: ExplainData) => void,
|
||||
) {
|
||||
const graphRag = yield* flowCtx.flow.requestorEffect<GraphRagRequest, GraphRagResponse>("graph-rag");
|
||||
const docRag = yield* flowCtx.flow.requestorEffect<DocumentRagRequest, DocumentRagResponse>("doc-rag");
|
||||
const triples = yield* flowCtx.flow.requestorEffect<TriplesQueryRequest, TriplesQueryResponse>("triples");
|
||||
const mcpTool = yield* flowCtx.flow.requestorEffect<ToolRequest, ToolResponse>("mcp-tool");
|
||||
const graphRag = yield* flowCtx.flow.requestorEffect(AgentGraphRagClient);
|
||||
const docRag = yield* flowCtx.flow.requestorEffect(AgentDocRagClient);
|
||||
const triples = yield* flowCtx.flow.requestorEffect(AgentTriplesClient);
|
||||
const mcpTool = yield* flowCtx.flow.requestorEffect(AgentMcpToolClient);
|
||||
|
||||
return tools.map((tool) => {
|
||||
const rawImplType = tool.config?.type;
|
||||
|
|
@ -300,9 +327,9 @@ const defaultTools = Effect.fn("AgentService.defaultTools")(function* (
|
|||
collection: string | undefined,
|
||||
onExplain: (data: ExplainData) => void,
|
||||
) {
|
||||
const graphRag = yield* flowCtx.flow.requestorEffect<GraphRagRequest, GraphRagResponse>("graph-rag");
|
||||
const docRag = yield* flowCtx.flow.requestorEffect<DocumentRagRequest, DocumentRagResponse>("doc-rag");
|
||||
const triples = yield* flowCtx.flow.requestorEffect<TriplesQueryRequest, TriplesQueryResponse>("triples");
|
||||
const graphRag = yield* flowCtx.flow.requestorEffect(AgentGraphRagClient);
|
||||
const docRag = yield* flowCtx.flow.requestorEffect(AgentDocRagClient);
|
||||
const triples = yield* flowCtx.flow.requestorEffect(AgentTriplesClient);
|
||||
|
||||
return [
|
||||
createKnowledgeQueryTool(
|
||||
|
|
@ -346,7 +373,7 @@ const onAgentRequest = Effect.fn("AgentService.onRequest")(function* (
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const responseProducer = yield* flowCtx.flow.producerEffect<AgentResponse>("agent-response");
|
||||
const responseProducer = yield* flowCtx.flow.producerEffect(AgentResponseProducer);
|
||||
|
||||
yield* Effect.gen(function* () {
|
||||
const runtime = yield* AgentRuntime;
|
||||
|
|
@ -367,10 +394,7 @@ const onAgentRequest = Effect.fn("AgentService.onRequest")(function* (
|
|||
msg.question,
|
||||
);
|
||||
|
||||
const llmClient = yield* flowCtx.flow.requestorEffect<
|
||||
TextCompletionRequest,
|
||||
TextCompletionResponse
|
||||
>("llm");
|
||||
const llmClient = yield* flowCtx.flow.requestorEffect(AgentLlmClient);
|
||||
|
||||
let conversation = initialPrompt;
|
||||
|
||||
|
|
@ -472,32 +496,12 @@ export const makeAgentSpecs = (): ReadonlyArray<Spec<AgentRuntime>> => [
|
|||
"agent-request",
|
||||
onAgentRequest,
|
||||
),
|
||||
makeProducerSpec<AgentResponse>("agent-response"),
|
||||
makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
),
|
||||
makeRequestResponseSpec<GraphRagRequest, GraphRagResponse>(
|
||||
"graph-rag",
|
||||
"graph-rag-request",
|
||||
"graph-rag-response",
|
||||
),
|
||||
makeRequestResponseSpec<DocumentRagRequest, DocumentRagResponse>(
|
||||
"doc-rag",
|
||||
"document-rag-request",
|
||||
"document-rag-response",
|
||||
),
|
||||
makeRequestResponseSpec<TriplesQueryRequest, TriplesQueryResponse>(
|
||||
"triples",
|
||||
"triples-request",
|
||||
"triples-response",
|
||||
),
|
||||
makeRequestResponseSpec<ToolRequest, ToolResponse>(
|
||||
"mcp-tool",
|
||||
"mcp-tool-request",
|
||||
"mcp-tool-response",
|
||||
),
|
||||
AgentResponseProducer,
|
||||
AgentLlmClient,
|
||||
AgentGraphRagClient,
|
||||
AgentDocRagClient,
|
||||
AgentTriplesClient,
|
||||
AgentMcpToolClient,
|
||||
];
|
||||
|
||||
export const makeAgentConfigHandlers = (): ReadonlyArray<
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ const DEFAULT_CHUNK_SIZE = 2000;
|
|||
const DEFAULT_CHUNK_OVERLAP = 100;
|
||||
const ChunkSizeParameter = makeParameterSpec("chunk-size", S.Number);
|
||||
const ChunkOverlapParameter = makeParameterSpec("chunk-overlap", S.Number);
|
||||
const ChunkOutputProducer = makeProducerSpec<Chunk>("chunk-output");
|
||||
const ChunkTriplesProducer = makeProducerSpec<Triples>("chunk-triples");
|
||||
|
||||
const onChunkMessage = Effect.fn("ChunkingService.onMessage")(function* (
|
||||
msg: TextDocument,
|
||||
|
|
@ -62,7 +64,7 @@ const onChunkMessage = Effect.fn("ChunkingService.onMessage")(function* (
|
|||
`[ChunkingService] Split document ${msg.documentId} into ${chunks.length} chunks (size=${chunkSize}, overlap=${chunkOverlap})`,
|
||||
);
|
||||
|
||||
const outputProducer = yield* flowCtx.flow.producerEffect<Chunk>("chunk-output");
|
||||
const outputProducer = yield* flowCtx.flow.producerEffect(ChunkOutputProducer);
|
||||
|
||||
yield* Effect.forEach(
|
||||
chunks,
|
||||
|
|
@ -83,8 +85,8 @@ export const makeChunkingSpecs = (): ReadonlyArray<
|
|||
"chunk-input",
|
||||
onChunkMessage,
|
||||
),
|
||||
makeProducerSpec<Chunk>("chunk-output"),
|
||||
makeProducerSpec<Triples>("chunk-triples"),
|
||||
ChunkOutputProducer,
|
||||
ChunkTriplesProducer,
|
||||
ChunkSizeParameter,
|
||||
ChunkOverlapParameter,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -96,6 +96,14 @@ const loadPageText = Effect.fn("loadPageText")(function*(
|
|||
.join(" ");
|
||||
});
|
||||
|
||||
const DecodeOutputProducer = makeProducerSpec<TextDocument>("decode-output");
|
||||
const DecodeTriplesProducer = makeProducerSpec<Triples>("decode-triples");
|
||||
const LibrarianClient = makeRequestResponseSpec<LibrarianRequest, LibrarianResponse>(
|
||||
"librarian-client",
|
||||
"librarian-request",
|
||||
"librarian-response",
|
||||
);
|
||||
|
||||
const onPdfDecodeMessage = Effect.fn("PdfDecoderService.onMessage")(function* (
|
||||
msg: Document,
|
||||
properties: Record<string, string>,
|
||||
|
|
@ -107,9 +115,7 @@ const onPdfDecodeMessage = Effect.fn("PdfDecoderService.onMessage")(function* (
|
|||
const { documentId } = msg;
|
||||
const user = msg.metadata.user;
|
||||
|
||||
const librarian = yield* flowCtx.flow.requestorEffect<LibrarianRequest, LibrarianResponse>(
|
||||
"librarian-client",
|
||||
);
|
||||
const librarian = yield* flowCtx.flow.requestorEffect(LibrarianClient);
|
||||
|
||||
const metadataResp = yield* librarian.request({
|
||||
operation: "get-document-metadata",
|
||||
|
|
@ -152,8 +158,8 @@ const onPdfDecodeMessage = Effect.fn("PdfDecoderService.onMessage")(function* (
|
|||
|
||||
yield* Effect.log(`[PdfDecoder] Document ${documentId}: ${pdf.numPages} pages`);
|
||||
|
||||
const outputProducer = yield* flowCtx.flow.producerEffect<TextDocument>("decode-output");
|
||||
const triplesProducer = yield* flowCtx.flow.producerEffect<Triples>("decode-triples");
|
||||
const outputProducer = yield* flowCtx.flow.producerEffect(DecodeOutputProducer);
|
||||
const triplesProducer = yield* flowCtx.flow.producerEffect(DecodeTriplesProducer);
|
||||
|
||||
for (let i = 1; i <= pdf.numPages; i++) {
|
||||
const pageText = yield* loadPageText(documentId, i, pdf);
|
||||
|
|
@ -219,13 +225,9 @@ const onPdfDecodeMessage = Effect.fn("PdfDecoderService.onMessage")(function* (
|
|||
|
||||
export const makePdfDecoderSpecs = (): ReadonlyArray<Spec<never>> => [
|
||||
makeConsumerSpec<Document, PdfDecoderHandlerError>("decode-input", onPdfDecodeMessage),
|
||||
makeProducerSpec<TextDocument>("decode-output"),
|
||||
makeProducerSpec<Triples>("decode-triples"),
|
||||
makeRequestResponseSpec<LibrarianRequest, LibrarianResponse>(
|
||||
"librarian-client",
|
||||
"librarian-request",
|
||||
"librarian-response",
|
||||
),
|
||||
DecodeOutputProducer,
|
||||
DecodeTriplesProducer,
|
||||
LibrarianClient,
|
||||
];
|
||||
|
||||
export type PdfDecoderService = FlowProcessorRuntime;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,19 @@ type KnowledgeExtractHandlerError =
|
|||
type PromptClient = EffectRequestResponse<PromptRequest, PromptResponse>;
|
||||
type LlmClient = EffectRequestResponse<TextCompletionRequest, TextCompletionResponse>;
|
||||
|
||||
const ExtractTriplesProducer = makeProducerSpec<Triples>("extract-triples");
|
||||
const ExtractEntityContextsProducer = makeProducerSpec<EntityContexts>("extract-entity-contexts");
|
||||
const PromptClientSpec = makeRequestResponseSpec<PromptRequest, PromptResponse>(
|
||||
"prompt-client",
|
||||
"prompt-request",
|
||||
"prompt-response",
|
||||
);
|
||||
const LlmClientSpec = makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm-client",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
);
|
||||
|
||||
const requestPrompt = Effect.fn("KnowledgeExtract.requestPrompt")(function* (
|
||||
promptClient: PromptClient,
|
||||
name: string,
|
||||
|
|
@ -153,10 +166,10 @@ const onKnowledgeExtractMessage = Effect.fn("KnowledgeExtractService.onMessage")
|
|||
const text = msg.chunk;
|
||||
if (text.trim().length === 0) return;
|
||||
|
||||
const promptClient = yield* flowCtx.flow.requestorEffect<PromptRequest, PromptResponse>("prompt-client");
|
||||
const llmClient = yield* flowCtx.flow.requestorEffect<TextCompletionRequest, TextCompletionResponse>("llm-client");
|
||||
const triplesProducer = yield* flowCtx.flow.producerEffect<Triples>("extract-triples");
|
||||
const entityContextsProducer = yield* flowCtx.flow.producerEffect<EntityContexts>("extract-entity-contexts");
|
||||
const promptClient = yield* flowCtx.flow.requestorEffect(PromptClientSpec);
|
||||
const llmClient = yield* flowCtx.flow.requestorEffect(LlmClientSpec);
|
||||
const triplesProducer = yield* flowCtx.flow.producerEffect(ExtractTriplesProducer);
|
||||
const entityContextsProducer = yield* flowCtx.flow.producerEffect(ExtractEntityContextsProducer);
|
||||
|
||||
const allTriples: Triple[] = [];
|
||||
const allEntityContexts: EntityContext[] = [];
|
||||
|
|
@ -270,18 +283,10 @@ export const makeKnowledgeExtractSpecs = (): ReadonlyArray<Spec<never>> => [
|
|||
"extract-input",
|
||||
onKnowledgeExtractMessage,
|
||||
),
|
||||
makeProducerSpec<Triples>("extract-triples"),
|
||||
makeProducerSpec<EntityContexts>("extract-entity-contexts"),
|
||||
makeRequestResponseSpec<PromptRequest, PromptResponse>(
|
||||
"prompt-client",
|
||||
"prompt-request",
|
||||
"prompt-response",
|
||||
),
|
||||
makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm-client",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
),
|
||||
ExtractTriplesProducer,
|
||||
ExtractEntityContextsProducer,
|
||||
PromptClientSpec,
|
||||
LlmClientSpec,
|
||||
];
|
||||
|
||||
export type KnowledgeExtractService = FlowProcessorRuntime;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ const programRuntimes = new WeakMap<PromptTemplateConfig, PromptTemplateRuntime>
|
|||
const makePromptTemplateRuntime = (config: PromptTemplateConfig): PromptTemplateRuntime => {
|
||||
const templates = new Map<string, PromptTemplate>();
|
||||
const configKey = config.configKey ?? "prompt";
|
||||
const PromptResponseProducer = makeProducerSpec<PromptResponse>("prompt-response");
|
||||
|
||||
const onPromptConfig = Effect.fn("PromptTemplateService.onConfig")(function* (
|
||||
pushedConfig: Record<string, unknown>,
|
||||
|
|
@ -114,7 +115,7 @@ const makePromptTemplateRuntime = (config: PromptTemplateConfig): PromptTemplate
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const responseProducer = yield* flowCtx.flow.producerEffect<PromptResponse>("prompt-response");
|
||||
const responseProducer = yield* flowCtx.flow.producerEffect(PromptResponseProducer);
|
||||
const template = templates.get(msg.name);
|
||||
if (template === undefined) {
|
||||
yield* responseProducer.send(requestId, {
|
||||
|
|
@ -142,7 +143,7 @@ const makePromptTemplateRuntime = (config: PromptTemplateConfig): PromptTemplate
|
|||
"prompt-request",
|
||||
onRequest,
|
||||
),
|
||||
makeProducerSpec<PromptResponse>("prompt-response"),
|
||||
PromptResponseProducer,
|
||||
],
|
||||
configHandlers: [onPromptConfig],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import {
|
|||
type QdrantDocQueryConfig,
|
||||
} from "./qdrant-doc.js";
|
||||
|
||||
const DocumentEmbeddingsResponseProducer = makeProducerSpec<DocumentEmbeddingsResponse>("document-embeddings-response");
|
||||
|
||||
const onDocEmbeddingsQueryMessage = Effect.fn("DocEmbeddingsQueryService.onMessage")(function* (
|
||||
msg: DocumentEmbeddingsRequest,
|
||||
properties: Record<string, string>,
|
||||
|
|
@ -38,7 +40,7 @@ const onDocEmbeddingsQueryMessage = Effect.fn("DocEmbeddingsQueryService.onMessa
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const producer = yield* flowCtx.flow.producerEffect<DocumentEmbeddingsResponse>("document-embeddings-response");
|
||||
const producer = yield* flowCtx.flow.producerEffect(DocumentEmbeddingsResponseProducer);
|
||||
const query = yield* QdrantDocEmbeddingsQueryService;
|
||||
const collection = msg.collection ?? "default";
|
||||
const allChunks: DocumentEmbeddingsResponse["chunks"] = [];
|
||||
|
|
@ -85,7 +87,7 @@ export const makeDocEmbeddingsQuerySpecs = (): ReadonlyArray<Spec<QdrantDocEmbed
|
|||
FlowResourceNotFoundError | MessagingDeliveryError,
|
||||
QdrantDocEmbeddingsQueryService
|
||||
>("document-embeddings-request", onDocEmbeddingsQueryMessage),
|
||||
makeProducerSpec<DocumentEmbeddingsResponse>("document-embeddings-response"),
|
||||
DocumentEmbeddingsResponseProducer,
|
||||
];
|
||||
|
||||
export type DocEmbeddingsQueryService = FlowProcessorRuntime<QdrantDocEmbeddingsQueryService>;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import {
|
|||
type QdrantGraphQueryConfig,
|
||||
} from "./qdrant-graph.js";
|
||||
|
||||
const GraphEmbeddingsResponseProducer = makeProducerSpec<GraphEmbeddingsResponse>("graph-embeddings-response");
|
||||
|
||||
const onGraphEmbeddingsQueryMessage = Effect.fn("GraphEmbeddingsQueryService.onMessage")(function* (
|
||||
msg: GraphEmbeddingsRequest,
|
||||
properties: Record<string, string>,
|
||||
|
|
@ -38,7 +40,7 @@ const onGraphEmbeddingsQueryMessage = Effect.fn("GraphEmbeddingsQueryService.onM
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const producer = yield* flowCtx.flow.producerEffect<GraphEmbeddingsResponse>("graph-embeddings-response");
|
||||
const producer = yield* flowCtx.flow.producerEffect(GraphEmbeddingsResponseProducer);
|
||||
const query = yield* QdrantGraphEmbeddingsQueryService;
|
||||
const user = msg.user ?? "default";
|
||||
const collection = msg.collection ?? "default";
|
||||
|
|
@ -86,7 +88,7 @@ export const makeGraphEmbeddingsQuerySpecs = (): ReadonlyArray<Spec<QdrantGraphE
|
|||
FlowResourceNotFoundError | MessagingDeliveryError,
|
||||
QdrantGraphEmbeddingsQueryService
|
||||
>("graph-embeddings-request", onGraphEmbeddingsQueryMessage),
|
||||
makeProducerSpec<GraphEmbeddingsResponse>("graph-embeddings-response"),
|
||||
GraphEmbeddingsResponseProducer,
|
||||
];
|
||||
|
||||
export type GraphEmbeddingsQueryService = FlowProcessorRuntime<QdrantGraphEmbeddingsQueryService>;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import {
|
|||
type FalkorDBQueryConfig,
|
||||
} from "./falkordb.js";
|
||||
|
||||
const TriplesResponseProducer = makeProducerSpec<TriplesQueryResponse>("triples-response");
|
||||
|
||||
const onTriplesQueryMessage = Effect.fn("TriplesQueryService.onMessage")(function* (
|
||||
msg: TriplesQueryRequest,
|
||||
properties: Record<string, string>,
|
||||
|
|
@ -38,7 +40,7 @@ const onTriplesQueryMessage = Effect.fn("TriplesQueryService.onMessage")(functio
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const producer = yield* flowCtx.flow.producerEffect<TriplesQueryResponse>("triples-response");
|
||||
const producer = yield* flowCtx.flow.producerEffect(TriplesResponseProducer);
|
||||
const query = yield* FalkorDBTriplesQueryService;
|
||||
const triples = yield* query.queryTriples(
|
||||
msg.s,
|
||||
|
|
@ -72,7 +74,7 @@ export const makeTriplesQuerySpecs = (): ReadonlyArray<Spec<FalkorDBTriplesQuery
|
|||
FlowResourceNotFoundError | MessagingDeliveryError,
|
||||
FalkorDBTriplesQueryService
|
||||
>("triples-request", onTriplesQueryMessage),
|
||||
makeProducerSpec<TriplesQueryResponse>("triples-response"),
|
||||
TriplesResponseProducer,
|
||||
];
|
||||
|
||||
export type TriplesQueryService = FlowProcessorRuntime<FalkorDBTriplesQueryService>;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,28 @@ import {
|
|||
type DocumentRagClients,
|
||||
} from "./document-rag.js";
|
||||
|
||||
const DocumentRagResponseProducer = makeProducerSpec<DocumentRagResponse>("document-rag-response");
|
||||
const DocumentRagLlmClient = makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
);
|
||||
const DocumentRagEmbeddingsClient = makeRequestResponseSpec<EmbeddingsRequest, EmbeddingsResponse>(
|
||||
"embeddings",
|
||||
"embeddings-request",
|
||||
"embeddings-response",
|
||||
);
|
||||
const DocumentRagDocEmbeddingsClient = makeRequestResponseSpec<DocumentEmbeddingsRequest, DocumentEmbeddingsResponse>(
|
||||
"doc-embeddings",
|
||||
"document-embeddings-request",
|
||||
"document-embeddings-response",
|
||||
);
|
||||
const DocumentRagPromptClient = makeRequestResponseSpec<PromptRequest, PromptResponse>(
|
||||
"prompt",
|
||||
"prompt-request",
|
||||
"prompt-response",
|
||||
);
|
||||
|
||||
const onDocumentRagRequest = Effect.fn("DocumentRagService.onRequest")(function* (
|
||||
msg: DocumentRagRequest,
|
||||
properties: Record<string, string>,
|
||||
|
|
@ -48,14 +70,14 @@ const onDocumentRagRequest = Effect.fn("DocumentRagService.onRequest")(function*
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const producer = yield* flowCtx.flow.producerEffect<DocumentRagResponse>("document-rag-response");
|
||||
const producer = yield* flowCtx.flow.producerEffect(DocumentRagResponseProducer);
|
||||
const engine = yield* DocumentRagEngine;
|
||||
|
||||
const clients: DocumentRagClients = {
|
||||
llm: yield* flowCtx.flow.requestorEffect<TextCompletionRequest, TextCompletionResponse>("llm"),
|
||||
embeddings: yield* flowCtx.flow.requestorEffect<EmbeddingsRequest, EmbeddingsResponse>("embeddings"),
|
||||
docEmbeddings: yield* flowCtx.flow.requestorEffect<DocumentEmbeddingsRequest, DocumentEmbeddingsResponse>("doc-embeddings"),
|
||||
prompt: yield* flowCtx.flow.requestorEffect<PromptRequest, PromptResponse>("prompt"),
|
||||
llm: yield* flowCtx.flow.requestorEffect(DocumentRagLlmClient),
|
||||
embeddings: yield* flowCtx.flow.requestorEffect(DocumentRagEmbeddingsClient),
|
||||
docEmbeddings: yield* flowCtx.flow.requestorEffect(DocumentRagDocEmbeddingsClient),
|
||||
prompt: yield* flowCtx.flow.requestorEffect(DocumentRagPromptClient),
|
||||
};
|
||||
|
||||
const response = yield* engine.query(
|
||||
|
|
@ -90,27 +112,11 @@ export const makeDocumentRagSpecs = (): ReadonlyArray<Spec<DocumentRagEngine>> =
|
|||
"document-rag-request",
|
||||
onDocumentRagRequest,
|
||||
),
|
||||
makeProducerSpec<DocumentRagResponse>("document-rag-response"),
|
||||
makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
),
|
||||
makeRequestResponseSpec<EmbeddingsRequest, EmbeddingsResponse>(
|
||||
"embeddings",
|
||||
"embeddings-request",
|
||||
"embeddings-response",
|
||||
),
|
||||
makeRequestResponseSpec<DocumentEmbeddingsRequest, DocumentEmbeddingsResponse>(
|
||||
"doc-embeddings",
|
||||
"document-embeddings-request",
|
||||
"document-embeddings-response",
|
||||
),
|
||||
makeRequestResponseSpec<PromptRequest, PromptResponse>(
|
||||
"prompt",
|
||||
"prompt-request",
|
||||
"prompt-response",
|
||||
),
|
||||
DocumentRagResponseProducer,
|
||||
DocumentRagLlmClient,
|
||||
DocumentRagEmbeddingsClient,
|
||||
DocumentRagDocEmbeddingsClient,
|
||||
DocumentRagPromptClient,
|
||||
];
|
||||
|
||||
export type DocumentRagService = FlowProcessorRuntime<DocumentRagEngine>;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,33 @@ import {
|
|||
type GraphRagConfig,
|
||||
} from "./graph-rag.js";
|
||||
|
||||
const GraphRagResponseProducer = makeProducerSpec<GraphRagResponse>("graph-rag-response");
|
||||
const GraphRagLlmClient = makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
);
|
||||
const GraphRagEmbeddingsClient = makeRequestResponseSpec<EmbeddingsRequest, EmbeddingsResponse>(
|
||||
"embeddings",
|
||||
"embeddings-request",
|
||||
"embeddings-response",
|
||||
);
|
||||
const GraphRagGraphEmbeddingsClient = makeRequestResponseSpec<GraphEmbeddingsRequest, GraphEmbeddingsResponse>(
|
||||
"graph-embeddings",
|
||||
"graph-embeddings-request",
|
||||
"graph-embeddings-response",
|
||||
);
|
||||
const GraphRagTriplesClient = makeRequestResponseSpec<TriplesQueryRequest, TriplesQueryResponse>(
|
||||
"triples",
|
||||
"triples-request",
|
||||
"triples-response",
|
||||
);
|
||||
const GraphRagPromptClient = makeRequestResponseSpec<PromptRequest, PromptResponse>(
|
||||
"prompt",
|
||||
"prompt-request",
|
||||
"prompt-response",
|
||||
);
|
||||
|
||||
const graphRagConfigFromRequest = (msg: GraphRagRequest): GraphRagConfig => ({
|
||||
...(msg.entityLimit !== undefined ? { entityLimit: msg.entityLimit } : {}),
|
||||
...(msg.tripleLimit !== undefined ? { tripleLimit: msg.tripleLimit } : {}),
|
||||
|
|
@ -58,17 +85,17 @@ const onGraphRagRequest = Effect.fn("GraphRagService.onRequest")(function* (
|
|||
const requestId = properties.id;
|
||||
if (requestId === undefined || requestId.length === 0) return;
|
||||
|
||||
const producer = yield* flowCtx.flow.producerEffect<GraphRagResponse>("graph-rag-response");
|
||||
const producer = yield* flowCtx.flow.producerEffect(GraphRagResponseProducer);
|
||||
const engine = yield* GraphRagEngine;
|
||||
|
||||
yield* Effect.log(`[GraphRagService] Received request ${requestId}: "${msg.query?.slice(0, 60)}..." collection=${msg.collection}`);
|
||||
|
||||
const clients: GraphRagClients = {
|
||||
llm: yield* flowCtx.flow.requestorEffect<TextCompletionRequest, TextCompletionResponse>("llm"),
|
||||
embeddings: yield* flowCtx.flow.requestorEffect<EmbeddingsRequest, EmbeddingsResponse>("embeddings"),
|
||||
graphEmbeddings: yield* flowCtx.flow.requestorEffect<GraphEmbeddingsRequest, GraphEmbeddingsResponse>("graph-embeddings"),
|
||||
triples: yield* flowCtx.flow.requestorEffect<TriplesQueryRequest, TriplesQueryResponse>("triples"),
|
||||
prompt: yield* flowCtx.flow.requestorEffect<PromptRequest, PromptResponse>("prompt"),
|
||||
llm: yield* flowCtx.flow.requestorEffect(GraphRagLlmClient),
|
||||
embeddings: yield* flowCtx.flow.requestorEffect(GraphRagEmbeddingsClient),
|
||||
graphEmbeddings: yield* flowCtx.flow.requestorEffect(GraphRagGraphEmbeddingsClient),
|
||||
triples: yield* flowCtx.flow.requestorEffect(GraphRagTriplesClient),
|
||||
prompt: yield* flowCtx.flow.requestorEffect(GraphRagPromptClient),
|
||||
};
|
||||
|
||||
const result = yield* engine.query(
|
||||
|
|
@ -118,32 +145,12 @@ export const makeGraphRagSpecs = (): ReadonlyArray<Spec<GraphRagEngine>> => [
|
|||
"graph-rag-request",
|
||||
onGraphRagRequest,
|
||||
),
|
||||
makeProducerSpec<GraphRagResponse>("graph-rag-response"),
|
||||
makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
"text-completion-request",
|
||||
"text-completion-response",
|
||||
),
|
||||
makeRequestResponseSpec<EmbeddingsRequest, EmbeddingsResponse>(
|
||||
"embeddings",
|
||||
"embeddings-request",
|
||||
"embeddings-response",
|
||||
),
|
||||
makeRequestResponseSpec<GraphEmbeddingsRequest, GraphEmbeddingsResponse>(
|
||||
"graph-embeddings",
|
||||
"graph-embeddings-request",
|
||||
"graph-embeddings-response",
|
||||
),
|
||||
makeRequestResponseSpec<TriplesQueryRequest, TriplesQueryResponse>(
|
||||
"triples",
|
||||
"triples-request",
|
||||
"triples-response",
|
||||
),
|
||||
makeRequestResponseSpec<PromptRequest, PromptResponse>(
|
||||
"prompt",
|
||||
"prompt-request",
|
||||
"prompt-response",
|
||||
),
|
||||
GraphRagResponseProducer,
|
||||
GraphRagLlmClient,
|
||||
GraphRagEmbeddingsClient,
|
||||
GraphRagGraphEmbeddingsClient,
|
||||
GraphRagTriplesClient,
|
||||
GraphRagPromptClient,
|
||||
];
|
||||
|
||||
export type GraphRagService = FlowProcessorRuntime<GraphRagEngine>;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ type GraphEmbeddingsStoreError =
|
|||
| MessagingTimeoutError
|
||||
| QdrantGraphEmbeddingsStoreError;
|
||||
|
||||
const EmbeddingsClient = makeRequestResponseSpec<EmbeddingsRequest, EmbeddingsResponse>(
|
||||
"embeddings-client",
|
||||
"embeddings-request",
|
||||
"embeddings-response",
|
||||
);
|
||||
|
||||
const onGraphEmbeddingsStoreMessage = Effect.fn("GraphEmbeddingsStoreService.onMessage")(function* (
|
||||
msg: EntityContexts,
|
||||
_properties: Record<string, string>,
|
||||
|
|
@ -49,8 +55,7 @@ const onGraphEmbeddingsStoreMessage = Effect.fn("GraphEmbeddingsStoreService.onM
|
|||
): Effect.fn.Return<void, GraphEmbeddingsStoreError, GraphEmbeddingsStoreRequirements> {
|
||||
if (msg.entities.length === 0) return;
|
||||
|
||||
const embeddingsClient =
|
||||
yield* flowCtx.flow.requestorEffect<EmbeddingsRequest, EmbeddingsResponse>("embeddings-client");
|
||||
const embeddingsClient = yield* flowCtx.flow.requestorEffect(EmbeddingsClient);
|
||||
|
||||
const user = msg.metadata?.user ?? "default";
|
||||
const collection = msg.metadata?.collection ?? "default";
|
||||
|
|
@ -83,11 +88,7 @@ export const makeGraphEmbeddingsStoreSpecs = (): ReadonlyArray<Spec<GraphEmbeddi
|
|||
"store-graph-embeddings-input",
|
||||
onGraphEmbeddingsStoreMessage,
|
||||
),
|
||||
makeRequestResponseSpec<EmbeddingsRequest, EmbeddingsResponse>(
|
||||
"embeddings-client",
|
||||
"embeddings-request",
|
||||
"embeddings-response",
|
||||
),
|
||||
EmbeddingsClient,
|
||||
];
|
||||
|
||||
export type GraphEmbeddingsStoreService = FlowProcessorRuntime<GraphEmbeddingsStoreRequirements>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue