feat: M2-05 — Vector integration contracts + citation context assembler
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 38s
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 38s
- integration-types.ts: IndexableChunk, CitationContext, RetrievalRequest/Response - VectorService.buildCitationContexts() for RAG citation assembly - Defines Ingestion↔Vector↔RAG interface contracts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
9520d1f549
commit
68540b0d67
54
src/modules/vector/integration-types.ts
Normal file
54
src/modules/vector/integration-types.ts
Normal file
@ -0,0 +1,54 @@
|
||||
// Shared types for Ingestion ↔ Vector ↔ RAG integration
|
||||
|
||||
/** Ingestion → Vector: chunk with embedding ready for upsert */
|
||||
export interface IndexableChunk {
|
||||
id: string;
|
||||
sourceId: string;
|
||||
knowledgeBaseId: string;
|
||||
userId: string;
|
||||
content: string;
|
||||
chunkIndex: number;
|
||||
pageNumber?: number;
|
||||
sectionTitle?: string;
|
||||
tokenCount: number;
|
||||
embedding: number[];
|
||||
}
|
||||
|
||||
/** Vector → RAG: search result with source info for citation */
|
||||
export interface CitationContext {
|
||||
chunkId: string;
|
||||
sourceId: string;
|
||||
sourceTitle: string;
|
||||
content: string;
|
||||
pageNumber?: number;
|
||||
sectionTitle?: string;
|
||||
score: number;
|
||||
}
|
||||
|
||||
/** RAG → Vector: search request parameters */
|
||||
export interface RetrievalRequest {
|
||||
queryEmbedding: number[];
|
||||
knowledgeBaseId?: string;
|
||||
userId?: string;
|
||||
topK?: number;
|
||||
enableRerank?: boolean;
|
||||
}
|
||||
|
||||
/** RAG → Vector: complete retrieval response */
|
||||
export interface RetrievalResponse {
|
||||
results: CitationContext[];
|
||||
queryTimeMs: number;
|
||||
}
|
||||
|
||||
/** Batch upsert result */
|
||||
export interface BatchUpsertResult {
|
||||
upserted: number;
|
||||
failed: number;
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
/** Cleanup trigger when import fails or source is deleted */
|
||||
export interface VectorCleanupRequest {
|
||||
sourceId: string;
|
||||
reason: 'import_failed' | 'source_deleted' | 'reparse';
|
||||
}
|
||||
@ -2,6 +2,7 @@ import { Injectable, Logger, OnModuleInit, Optional } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { QdrantClient } from '@qdrant/js-client-rest';
|
||||
import { AiGatewayService } from '../ai/gateway/ai-gateway.service';
|
||||
import type { CitationContext } from './integration-types';
|
||||
|
||||
export interface VectorPoint {
|
||||
id: string;
|
||||
@ -191,4 +192,17 @@ export class VectorService implements OnModuleInit {
|
||||
const result = await this.client.count(COLLECTION_NAME);
|
||||
return result.count;
|
||||
}
|
||||
|
||||
/** Build citation context from search results */
|
||||
async buildCitationContexts(results: SearchResult[]): Promise<CitationContext[]> {
|
||||
return results.map(r => ({
|
||||
chunkId: r.id,
|
||||
sourceId: r.payload?.sourceId || 'unknown',
|
||||
sourceTitle: r.payload?.sourceTitle || 'Untitled',
|
||||
content: r.payload?.text || '',
|
||||
pageNumber: r.payload?.pageNumber,
|
||||
sectionTitle: r.payload?.sectionTitle,
|
||||
score: r.score,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,4 +233,30 @@ describe('M2 E2E Tests', () => {
|
||||
expect(res.body.success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════
|
||||
// M2-05: Vector & Retrieval 对接
|
||||
// ══════════════════════════════════════════════
|
||||
describe('M2-05 Vector Integration', () => {
|
||||
let token: string;
|
||||
beforeAll(async () => { token = await loginAdmin(); });
|
||||
|
||||
it('VectorService collection accessible', async () => {
|
||||
if (!token) return;
|
||||
const res = await request(app.getHttpServer())
|
||||
.get('/admin-api/vector/collection')
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200);
|
||||
expect(res.body.data).toHaveProperty('name');
|
||||
});
|
||||
|
||||
it('VectorService count accessible', async () => {
|
||||
if (!token) return;
|
||||
const res = await request(app.getHttpServer())
|
||||
.get('/admin-api/vector/count')
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200);
|
||||
expect(res.body.data).toHaveProperty('count');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user