mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-09-25 14:31:33 +08:00
format decomp files
This commit is contained in:
parent
19c36b18a6
commit
d83cce88cb
@ -100,7 +100,8 @@ Format your answer as a valid JSON array without markdown code blocks, like this
|
|||||||
maxTokens: SEARCH_CONSTANTS.LIMITS.QUERY_PROCESSOR_MAX_TOKENS,
|
maxTokens: SEARCH_CONSTANTS.LIMITS.QUERY_PROCESSOR_MAX_TOKENS,
|
||||||
bypassFormatter: true,
|
bypassFormatter: true,
|
||||||
expectsJsonResponse: true,
|
expectsJsonResponse: true,
|
||||||
_bypassContextProcessing: true // Prevent recursive calls
|
_bypassContextProcessing: true, // Prevent recursive calls
|
||||||
|
enableTools: false // Explicitly disable tools for this request
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the response from the LLM
|
// Get the response from the LLM
|
||||||
@ -167,69 +168,33 @@ Format your answer as a valid JSON array without markdown code blocks, like this
|
|||||||
// Try to get LLM service if not provided
|
// Try to get LLM service if not provided
|
||||||
const service = llmService || await this.getLLMService();
|
const service = llmService || await this.getLLMService();
|
||||||
|
|
||||||
// For when no LLM service is available, use the basic approach
|
// If no LLM service is available, use basic decomposition
|
||||||
if (!service) {
|
if (!service) {
|
||||||
if (!service) {
|
log.info(`No LLM service available for query decomposition, using original query`);
|
||||||
log.info(`No LLM service available for query decomposition, using original query`);
|
return this.createBasicDecomposition(query, complexity);
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`Using basic decomposition approach (complexity: ${complexity})`);
|
|
||||||
|
|
||||||
const mainSubQuery = {
|
|
||||||
id: this.generateSubQueryId(),
|
|
||||||
text: query,
|
|
||||||
reason: "Direct question that can be answered without decomposition",
|
|
||||||
isAnswered: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add a generic exploration query for context
|
|
||||||
const genericQuery = {
|
|
||||||
id: this.generateSubQueryId(),
|
|
||||||
text: `What information is related to ${query}?`,
|
|
||||||
reason: "General exploration to find related content",
|
|
||||||
isAnswered: false
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
originalQuery: query,
|
|
||||||
subQueries: [mainSubQuery, genericQuery],
|
|
||||||
status: 'pending',
|
|
||||||
complexity
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For when the LLM available, we can use more advanced decomposition
|
// With LLM service available, always use advanced decomposition regardless of complexity
|
||||||
if (service) {
|
try {
|
||||||
try {
|
log.info(`Using advanced LLM-based decomposition for query (complexity: ${complexity})`);
|
||||||
// Try to use LLM for advanced decomposition
|
const enhancedSubQueries = await this.createLLMSubQueries(query, context, service);
|
||||||
log.info(`Using advanced LLM-based decomposition for complex query (complexity: ${complexity})`);
|
|
||||||
const enhancedSubQueries = await this.createLLMSubQueries(query, context, service);
|
|
||||||
|
|
||||||
if (enhancedSubQueries && enhancedSubQueries.length > 0) {
|
if (enhancedSubQueries && enhancedSubQueries.length > 0) {
|
||||||
log.info(`LLM decomposed query into ${enhancedSubQueries.length} sub-queries: ${JSON.stringify(enhancedSubQueries)}`);
|
log.info(`LLM decomposed query into ${enhancedSubQueries.length} sub-queries`);
|
||||||
return {
|
return {
|
||||||
originalQuery: query,
|
originalQuery: query,
|
||||||
subQueries: enhancedSubQueries,
|
subQueries: enhancedSubQueries,
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
complexity
|
complexity
|
||||||
};
|
};
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
log.error(`Error during LLM-based decomposition: ${error.message}, falling back to basic decomposition`);
|
|
||||||
// Continue to fallback with basic decomposition
|
|
||||||
}
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error during LLM-based decomposition: ${error.message}, falling back to basic decomposition`);
|
||||||
|
// Fall through to basic decomposition
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to basic decomposition
|
// Fallback to basic decomposition
|
||||||
const subQueries = this.createSubQueries(query, context);
|
return this.createBasicDecomposition(query, complexity);
|
||||||
log.info(`Decomposed query into ${subQueries.length} sub-queries`);
|
|
||||||
|
|
||||||
return {
|
|
||||||
originalQuery: query,
|
|
||||||
subQueries,
|
|
||||||
status: 'pending',
|
|
||||||
complexity
|
|
||||||
};
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
log.error(`Error decomposing query: ${error.message}`);
|
log.error(`Error decomposing query: ${error.message}`);
|
||||||
|
|
||||||
@ -248,6 +213,39 @@ Format your answer as a valid JSON array without markdown code blocks, like this
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a basic decomposition of a query without using LLM
|
||||||
|
*
|
||||||
|
* @param query The original query
|
||||||
|
* @param complexity The assessed complexity
|
||||||
|
* @returns A basic decomposed query
|
||||||
|
*/
|
||||||
|
private createBasicDecomposition(query: string, complexity: number): DecomposedQuery {
|
||||||
|
log.info(`Using basic decomposition approach (complexity: ${complexity})`);
|
||||||
|
|
||||||
|
const mainSubQuery = {
|
||||||
|
id: this.generateSubQueryId(),
|
||||||
|
text: query,
|
||||||
|
reason: "Direct question that can be answered without decomposition",
|
||||||
|
isAnswered: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add a generic exploration query for context
|
||||||
|
const genericQuery = {
|
||||||
|
id: this.generateSubQueryId(),
|
||||||
|
text: `What information is related to ${query}?`,
|
||||||
|
reason: "General exploration to find related content",
|
||||||
|
isAnswered: false
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
originalQuery: query,
|
||||||
|
subQueries: [mainSubQuery, genericQuery],
|
||||||
|
status: 'pending',
|
||||||
|
complexity
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use LLM to create advanced sub-queries from a complex query
|
* Use LLM to create advanced sub-queries from a complex query
|
||||||
*
|
*
|
||||||
@ -267,25 +265,42 @@ Format your answer as a valid JSON array without markdown code blocks, like this
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Build a prompt from existing templates in the constants
|
// Create a much better prompt for more effective query decomposition
|
||||||
const contextPart = context ? `\nContext: ${context}` : '';
|
const prompt = `Decompose the following query into 3-5 specific search queries that would help find comprehensive information.
|
||||||
|
|
||||||
// Use existing templates from QUERY_DECOMPOSITION_STRINGS to build the prompt
|
Your task is to identify the main concepts and break them down into specific, targeted search queries.
|
||||||
const prompt = `I need to break down a complex query into sub-queries.
|
|
||||||
Query: ${query}${contextPart}
|
|
||||||
|
|
||||||
Please analyze this query and identify the key aspects that need to be addressed.`;
|
DO NOT simply rephrase the original query or create a generic "what's related to X" pattern.
|
||||||
|
DO create specific queries that explore different aspects of the topic.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
If the query is "How does Docker compare to Kubernetes?", good sub-queries would be:
|
||||||
|
- "Docker container architecture and features"
|
||||||
|
- "Kubernetes container orchestration capabilities"
|
||||||
|
- "Docker vs Kubernetes performance comparison"
|
||||||
|
- "When to use Docker versus Kubernetes"
|
||||||
|
|
||||||
|
Format your response as a JSON array of objects with 'text' and 'reason' properties.
|
||||||
|
Example: [
|
||||||
|
{"text": "Docker container architecture", "reason": "Understanding Docker's core technology"},
|
||||||
|
{"text": "Kubernetes orchestration features", "reason": "Exploring Kubernetes' main capabilities"}
|
||||||
|
]
|
||||||
|
|
||||||
|
${context ? `\nContext: ${context}` : ''}
|
||||||
|
|
||||||
|
Query: ${query}`;
|
||||||
|
|
||||||
const messages = [
|
const messages = [
|
||||||
{ role: "system" as const, content: prompt }
|
{ role: "system" as const, content: prompt }
|
||||||
];
|
];
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
temperature: SEARCH_CONSTANTS.TEMPERATURE.QUERY_PROCESSOR,
|
temperature: 0.7, // Higher temperature for more creative decomposition
|
||||||
maxTokens: SEARCH_CONSTANTS.LIMITS.QUERY_PROCESSOR_MAX_TOKENS,
|
maxTokens: SEARCH_CONSTANTS.LIMITS.QUERY_PROCESSOR_MAX_TOKENS,
|
||||||
bypassFormatter: true,
|
bypassFormatter: true,
|
||||||
expectsJsonResponse: true,
|
expectsJsonResponse: true,
|
||||||
_bypassContextProcessing: true // Prevent recursive calls
|
_bypassContextProcessing: true, // Prevent recursive calls
|
||||||
|
enableTools: false // Explicitly disable tools for this request
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the response from the LLM
|
// Get the response from the LLM
|
||||||
@ -300,6 +315,11 @@ Please analyze this query and identify the key aspects that need to be addressed
|
|||||||
reason?: string;
|
reason?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log the response for debugging
|
||||||
|
log.info(`Received response from LLM for query decomposition, extracting JSON...`);
|
||||||
|
|
||||||
|
log.info(`Response: ${responseText}`);
|
||||||
|
|
||||||
// Extract JSON from the response
|
// Extract JSON from the response
|
||||||
const extractedData = JsonExtractor.extract<RawSubQuery[]>(responseText, {
|
const extractedData = JsonExtractor.extract<RawSubQuery[]>(responseText, {
|
||||||
extractArrays: true,
|
extractArrays: true,
|
||||||
@ -307,15 +327,74 @@ Please analyze this query and identify the key aspects that need to be addressed
|
|||||||
useFallbacks: true
|
useFallbacks: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Array.isArray(extractedData) && extractedData.length > 0) {
|
// Validate the extracted data
|
||||||
// Convert the raw data to SubQuery objects
|
if (!Array.isArray(extractedData)) {
|
||||||
return extractedData.map(item => ({
|
log.error(`Failed to extract array from LLM response, got: ${typeof extractedData}`);
|
||||||
id: this.generateSubQueryId(),
|
return this.createSubQueries(query, context);
|
||||||
text: item.text,
|
|
||||||
reason: item.reason || "Sub-aspect of the main question",
|
|
||||||
isAnswered: false
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extractedData.length === 0) {
|
||||||
|
log.error(`Extracted array is empty, falling back to basic decomposition`);
|
||||||
|
return this.createSubQueries(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(`Successfully extracted ${extractedData.length} items using regex pattern`);
|
||||||
|
|
||||||
|
// Validate each sub-query to ensure it has a text property
|
||||||
|
const validSubQueries = extractedData.filter(item => {
|
||||||
|
if (!item || typeof item !== 'object') {
|
||||||
|
log.error(`Invalid sub-query item: ${JSON.stringify(item)}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.text || typeof item.text !== 'string') {
|
||||||
|
log.error(`Sub-query missing text property: ${JSON.stringify(item)}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (validSubQueries.length === 0) {
|
||||||
|
log.error(`No valid sub-queries found after validation, falling back to basic decomposition`);
|
||||||
|
return this.createSubQueries(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validSubQueries.length < extractedData.length) {
|
||||||
|
log.info(`Some invalid sub-queries were filtered out: ${extractedData.length} -> ${validSubQueries.length}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the raw data to SubQuery objects
|
||||||
|
let subQueries = validSubQueries.map(item => ({
|
||||||
|
id: this.generateSubQueryId(),
|
||||||
|
text: item.text,
|
||||||
|
reason: item.reason || "Sub-aspect of the main question",
|
||||||
|
isAnswered: false
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Make sure we have at least the original query
|
||||||
|
const hasOriginalQuery = subQueries.some(sq => {
|
||||||
|
// Check if either sq.text or query is null/undefined before using toLowerCase
|
||||||
|
if (!sq.text) return false;
|
||||||
|
const sqText = sq.text.toLowerCase();
|
||||||
|
const originalQuery = query.toLowerCase();
|
||||||
|
|
||||||
|
return sqText.includes(originalQuery) || originalQuery.includes(sqText);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!hasOriginalQuery) {
|
||||||
|
subQueries.unshift({
|
||||||
|
id: this.generateSubQueryId(),
|
||||||
|
text: query,
|
||||||
|
reason: "Original query",
|
||||||
|
isAnswered: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log the extracted sub-queries for debugging
|
||||||
|
log.info(`Successfully extracted ${subQueries.length} sub-queries from LLM response`);
|
||||||
|
|
||||||
|
return subQueries;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
log.error(`Error extracting sub-queries from LLM response: ${error.message}`);
|
log.error(`Error extracting sub-queries from LLM response: ${error.message}`);
|
||||||
// Fall through to traditional decomposition
|
// Fall through to traditional decomposition
|
||||||
|
@ -9,139 +9,139 @@ import type BAttribute from '../../../becca/entities/battribute.js';
|
|||||||
* Interface for the AI service used by agent tools
|
* Interface for the AI service used by agent tools
|
||||||
*/
|
*/
|
||||||
export interface LLMServiceInterface {
|
export interface LLMServiceInterface {
|
||||||
generateChatCompletion(messages: Array<{
|
generateChatCompletion(messages: Array<{
|
||||||
role: 'user' | 'assistant' | 'system';
|
role: 'user' | 'assistant' | 'system';
|
||||||
content: string;
|
content: string;
|
||||||
}>, options?: {
|
}>, options?: {
|
||||||
temperature?: number;
|
temperature?: number;
|
||||||
maxTokens?: number;
|
maxTokens?: number;
|
||||||
model?: string;
|
model?: string;
|
||||||
stream?: boolean;
|
stream?: boolean;
|
||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
}): Promise<ChatResponse>;
|
}): Promise<ChatResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for tool initialization
|
* Interface for tool initialization
|
||||||
*/
|
*/
|
||||||
export interface AgentToolInitializationParams {
|
export interface AgentToolInitializationParams {
|
||||||
aiServiceManager: LLMServiceInterface;
|
aiServiceManager: LLMServiceInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for agent tool manager
|
* Interface for agent tool manager
|
||||||
*/
|
*/
|
||||||
export interface IAgentToolsManager {
|
export interface IAgentToolsManager {
|
||||||
initialize(aiServiceManager: LLMServiceInterface): Promise<void>;
|
initialize(aiServiceManager: LLMServiceInterface): Promise<void>;
|
||||||
isInitialized(): boolean;
|
isInitialized(): boolean;
|
||||||
getAllTools(): {
|
getAllTools(): {
|
||||||
vectorSearch: IVectorSearchTool;
|
vectorSearch: IVectorSearchTool;
|
||||||
noteNavigator: INoteNavigatorTool;
|
noteNavigator: INoteNavigatorTool;
|
||||||
queryDecomposition: IQueryDecompositionTool;
|
queryDecomposition: IQueryDecompositionTool;
|
||||||
contextualThinking: IContextualThinkingTool;
|
contextualThinking: IContextualThinkingTool;
|
||||||
};
|
};
|
||||||
getVectorSearchTool(): IVectorSearchTool;
|
getVectorSearchTool(): IVectorSearchTool;
|
||||||
getNoteNavigatorTool(): INoteNavigatorTool;
|
getNoteNavigatorTool(): INoteNavigatorTool;
|
||||||
getQueryDecompositionTool(): IQueryDecompositionTool;
|
getQueryDecompositionTool(): IQueryDecompositionTool;
|
||||||
getContextualThinkingTool(): IContextualThinkingTool;
|
getContextualThinkingTool(): IContextualThinkingTool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for context service used by vector search
|
* Interface for context service used by vector search
|
||||||
*/
|
*/
|
||||||
export interface IContextService {
|
export interface IContextService {
|
||||||
findRelevantNotesMultiQuery(queries: string[], contextNoteId: string | null, limit: number): Promise<VectorSearchResult[]>;
|
findRelevantNotesMultiQuery(queries: string[], contextNoteId: string | null, limit: number): Promise<VectorSearchResult[]>;
|
||||||
processQuery(userQuestion: string, llmService: LLMServiceInterface, contextNoteId: string | null, showThinking: boolean): Promise<{
|
processQuery(userQuestion: string, llmService: LLMServiceInterface, contextNoteId: string | null, showThinking: boolean): Promise<{
|
||||||
context: string;
|
context: string;
|
||||||
sources: Array<{
|
sources: Array<{
|
||||||
noteId: string;
|
noteId: string;
|
||||||
title: string;
|
title: string;
|
||||||
similarity: number;
|
similarity: number;
|
||||||
|
}>;
|
||||||
|
thinking?: string;
|
||||||
}>;
|
}>;
|
||||||
thinking?: string;
|
|
||||||
}>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for vector search tool
|
* Interface for vector search tool
|
||||||
*/
|
*/
|
||||||
export interface IVectorSearchTool {
|
export interface IVectorSearchTool {
|
||||||
setContextService(contextService: IContextService): void;
|
setContextService(contextService: IContextService): void;
|
||||||
search(
|
search(
|
||||||
query: string,
|
query: string,
|
||||||
contextNoteId?: string,
|
contextNoteId?: string,
|
||||||
searchOptions?: {
|
searchOptions?: {
|
||||||
limit?: number;
|
limit?: number;
|
||||||
threshold?: number;
|
threshold?: number;
|
||||||
includeContent?: boolean;
|
includeContent?: boolean;
|
||||||
}
|
}
|
||||||
): Promise<VectorSearchResult[]>;
|
): Promise<VectorSearchResult[]>;
|
||||||
searchNotes(query: string, options?: {
|
searchNotes(query: string, options?: {
|
||||||
parentNoteId?: string;
|
parentNoteId?: string;
|
||||||
maxResults?: number;
|
maxResults?: number;
|
||||||
similarityThreshold?: number;
|
similarityThreshold?: number;
|
||||||
}): Promise<VectorSearchResult[]>;
|
}): Promise<VectorSearchResult[]>;
|
||||||
searchContentChunks(query: string, options?: {
|
searchContentChunks(query: string, options?: {
|
||||||
noteId?: string;
|
noteId?: string;
|
||||||
maxResults?: number;
|
maxResults?: number;
|
||||||
similarityThreshold?: number;
|
similarityThreshold?: number;
|
||||||
}): Promise<VectorSearchResult[]>;
|
}): Promise<VectorSearchResult[]>;
|
||||||
explainResults(query: string, results: VectorSearchResult[]): string;
|
explainResults(query: string, results: VectorSearchResult[]): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for note navigator tool
|
* Interface for note navigator tool
|
||||||
*/
|
*/
|
||||||
export interface INoteNavigatorTool {
|
export interface INoteNavigatorTool {
|
||||||
getNoteInfo(noteId: string): NoteInfo | null;
|
getNoteInfo(noteId: string): NoteInfo | null;
|
||||||
getNotePathsFromRoot(noteId: string): NotePathInfo[];
|
getNotePathsFromRoot(noteId: string): NotePathInfo[];
|
||||||
getNoteHierarchy(noteId: string, depth?: number): NoteHierarchyLevel | null;
|
getNoteHierarchy(noteId: string, depth?: number): NoteHierarchyLevel | null;
|
||||||
getNoteAttributes(noteId: string): BAttribute[];
|
getNoteAttributes(noteId: string): BAttribute[];
|
||||||
findPathBetweenNotes(fromNoteId: string, toNoteId: string): NotePathInfo | null;
|
findPathBetweenNotes(fromNoteId: string, toNoteId: string): NotePathInfo | null;
|
||||||
searchNotesByTitle(searchTerm: string, limit?: number): NoteInfo[];
|
searchNotesByTitle(searchTerm: string, limit?: number): NoteInfo[];
|
||||||
getNoteClones(noteId: string): Promise<NoteInfo[]>;
|
getNoteClones(noteId: string): Promise<NoteInfo[]>;
|
||||||
getNoteContextDescription(noteId: string): Promise<string>;
|
getNoteContextDescription(noteId: string): Promise<string>;
|
||||||
getNoteStructure(noteId: string): Promise<{
|
getNoteStructure(noteId: string): Promise<{
|
||||||
noteId: string;
|
noteId: string;
|
||||||
title: string;
|
title: string;
|
||||||
type: string;
|
type: string;
|
||||||
childCount: number;
|
childCount: number;
|
||||||
attributes: Array<{name: string, value: string}>;
|
attributes: Array<{ name: string, value: string }>;
|
||||||
parentPath: Array<{title: string, noteId: string}>;
|
parentPath: Array<{ title: string, noteId: string }>;
|
||||||
}>;
|
}>;
|
||||||
getChildNotes(noteId: string, limit?: number): Promise<Array<{noteId: string, title: string}>>;
|
getChildNotes(noteId: string, limit?: number): Promise<Array<{ noteId: string, title: string }>>;
|
||||||
getParentNotes(noteId: string): Promise<Array<{noteId: string, title: string}>>;
|
getParentNotes(noteId: string): Promise<Array<{ noteId: string, title: string }>>;
|
||||||
getLinkedNotes(noteId: string, limit?: number): Promise<Array<{noteId: string, title: string, direction: 'from'|'to'}>>;
|
getLinkedNotes(noteId: string, limit?: number): Promise<Array<{ noteId: string, title: string, direction: 'from' | 'to' }>>;
|
||||||
getNotePath(noteId: string): Promise<string>;
|
getNotePath(noteId: string): Promise<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for query decomposition tool
|
* Interface for query decomposition tool
|
||||||
*/
|
*/
|
||||||
export interface IQueryDecompositionTool {
|
export interface IQueryDecompositionTool {
|
||||||
decomposeQuery(query: string, context?: string): DecomposedQuery;
|
decomposeQuery(query: string, context?: string): DecomposedQuery;
|
||||||
updateSubQueryAnswer(decomposedQuery: DecomposedQuery, subQueryId: string, answer: string): DecomposedQuery;
|
updateSubQueryAnswer(decomposedQuery: DecomposedQuery, subQueryId: string, answer: string): DecomposedQuery;
|
||||||
synthesizeAnswer(decomposedQuery: DecomposedQuery): string;
|
synthesizeAnswer(decomposedQuery: DecomposedQuery): string;
|
||||||
getQueryStatus(decomposedQuery: DecomposedQuery): string;
|
getQueryStatus(decomposedQuery: DecomposedQuery): string;
|
||||||
assessQueryComplexity(query: string): number;
|
assessQueryComplexity(query: string): number;
|
||||||
generateSubQueryId(): string;
|
generateSubQueryId(): string;
|
||||||
createSubQueries(query: string, context?: string): SubQuery[];
|
createSubQueries(query: string, context?: string): SubQuery[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for contextual thinking tool
|
* Interface for contextual thinking tool
|
||||||
*/
|
*/
|
||||||
export interface IContextualThinkingTool {
|
export interface IContextualThinkingTool {
|
||||||
startThinking(query: string): string;
|
startThinking(query: string): string;
|
||||||
addThinkingStep(
|
addThinkingStep(
|
||||||
processId: string,
|
processId: string,
|
||||||
step: Omit<ThinkingStep, 'id'>,
|
step: Omit<ThinkingStep, 'id'>,
|
||||||
parentId?: string
|
parentId?: string
|
||||||
): string;
|
): string;
|
||||||
completeThinking(processId?: string): ThinkingProcess | null;
|
completeThinking(processId?: string): ThinkingProcess | null;
|
||||||
getThinkingProcess(processId: string): ThinkingProcess | null;
|
getThinkingProcess(processId: string): ThinkingProcess | null;
|
||||||
getActiveThinkingProcess(): ThinkingProcess | null;
|
getActiveThinkingProcess(): ThinkingProcess | null;
|
||||||
visualizeThinking(thinkingId: string): string;
|
visualizeThinking(thinkingId: string): string;
|
||||||
getThinkingSummary(thinkingId: string): string;
|
getThinkingSummary(thinkingId: string): string;
|
||||||
resetActiveThinking(): void;
|
resetActiveThinking(): void;
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@ import type { ToolCall } from '../tools/tool_interfaces.js';
|
|||||||
* Model metadata interface to track provider information
|
* Model metadata interface to track provider information
|
||||||
*/
|
*/
|
||||||
export interface ModelMetadata {
|
export interface ModelMetadata {
|
||||||
// The provider that supports this model
|
// The provider that supports this model
|
||||||
provider: 'openai' | 'anthropic' | 'ollama' | 'local';
|
provider: 'openai' | 'anthropic' | 'ollama' | 'local';
|
||||||
// The actual model identifier used by the provider's API
|
// The actual model identifier used by the provider's API
|
||||||
modelId: string;
|
modelId: string;
|
||||||
// Display name for UI (optional)
|
// Display name for UI (optional)
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
// Model capabilities
|
// Model capabilities
|
||||||
capabilities?: {
|
capabilities?: {
|
||||||
contextWindow?: number;
|
contextWindow?: number;
|
||||||
supportsTools?: boolean;
|
supportsTools?: boolean;
|
||||||
supportsVision?: boolean;
|
supportsVision?: boolean;
|
||||||
supportsStreaming?: boolean;
|
supportsStreaming?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,196 +25,196 @@ export interface ModelMetadata {
|
|||||||
* but not necessarily sent directly to APIs
|
* but not necessarily sent directly to APIs
|
||||||
*/
|
*/
|
||||||
export interface ProviderConfig {
|
export interface ProviderConfig {
|
||||||
// Internal configuration
|
// Internal configuration
|
||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
// Provider metadata for model routing
|
// Provider metadata for model routing
|
||||||
providerMetadata?: ModelMetadata;
|
providerMetadata?: ModelMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OpenAI-specific options, structured to match the OpenAI API
|
* OpenAI-specific options, structured to match the OpenAI API
|
||||||
*/
|
*/
|
||||||
export interface OpenAIOptions extends ProviderConfig {
|
export interface OpenAIOptions extends ProviderConfig {
|
||||||
// Connection settings (not sent to API)
|
// Connection settings (not sent to API)
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
|
|
||||||
// Direct API parameters as they appear in requests
|
// Direct API parameters as they appear in requests
|
||||||
model: string;
|
model: string;
|
||||||
messages?: Message[];
|
messages?: Message[];
|
||||||
temperature?: number;
|
temperature?: number;
|
||||||
max_tokens?: number;
|
max_tokens?: number;
|
||||||
stream?: boolean;
|
stream?: boolean;
|
||||||
top_p?: number;
|
top_p?: number;
|
||||||
frequency_penalty?: number;
|
frequency_penalty?: number;
|
||||||
presence_penalty?: number;
|
presence_penalty?: number;
|
||||||
tools?: any[];
|
tools?: any[];
|
||||||
tool_choice?: string | object;
|
tool_choice?: string | object;
|
||||||
|
|
||||||
// Internal control flags (not sent directly to API)
|
// Internal control flags (not sent directly to API)
|
||||||
enableTools?: boolean;
|
enableTools?: boolean;
|
||||||
// Streaming callback handler
|
// Streaming callback handler
|
||||||
streamCallback?: (text: string, isDone: boolean, originalChunk?: any) => Promise<void> | void;
|
streamCallback?: (text: string, isDone: boolean, originalChunk?: any) => Promise<void> | void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anthropic-specific options, structured to match the Anthropic API
|
* Anthropic-specific options, structured to match the Anthropic API
|
||||||
*/
|
*/
|
||||||
export interface AnthropicOptions extends ProviderConfig {
|
export interface AnthropicOptions extends ProviderConfig {
|
||||||
// Connection settings (not sent to API)
|
// Connection settings (not sent to API)
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
apiVersion?: string;
|
apiVersion?: string;
|
||||||
betaVersion?: string;
|
betaVersion?: string;
|
||||||
|
|
||||||
// Direct API parameters as they appear in requests
|
// Direct API parameters as they appear in requests
|
||||||
model: string;
|
model: string;
|
||||||
messages?: any[];
|
messages?: any[];
|
||||||
system?: string;
|
system?: string;
|
||||||
temperature?: number;
|
temperature?: number;
|
||||||
max_tokens?: number;
|
max_tokens?: number;
|
||||||
stream?: boolean;
|
stream?: boolean;
|
||||||
top_p?: number;
|
top_p?: number;
|
||||||
|
|
||||||
// Internal parameters (not sent directly to API)
|
// Internal parameters (not sent directly to API)
|
||||||
formattedMessages?: { messages: any[], system: string };
|
formattedMessages?: { messages: any[], system: string };
|
||||||
// Streaming callback handler
|
// Streaming callback handler
|
||||||
streamCallback?: (text: string, isDone: boolean, originalChunk?: any) => Promise<void> | void;
|
streamCallback?: (text: string, isDone: boolean, originalChunk?: any) => Promise<void> | void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ollama-specific options, structured to match the Ollama API
|
* Ollama-specific options, structured to match the Ollama API
|
||||||
*/
|
*/
|
||||||
export interface OllamaOptions extends ProviderConfig {
|
export interface OllamaOptions extends ProviderConfig {
|
||||||
// Connection settings (not sent to API)
|
// Connection settings (not sent to API)
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
|
|
||||||
// Direct API parameters as they appear in requests
|
// Direct API parameters as they appear in requests
|
||||||
model: string;
|
model: string;
|
||||||
messages?: Message[];
|
messages?: Message[];
|
||||||
stream?: boolean;
|
stream?: boolean;
|
||||||
options?: {
|
options?: {
|
||||||
temperature?: number;
|
temperature?: number;
|
||||||
num_ctx?: number;
|
num_ctx?: number;
|
||||||
top_p?: number;
|
top_p?: number;
|
||||||
top_k?: number;
|
top_k?: number;
|
||||||
num_predict?: number; // equivalent to max_tokens
|
num_predict?: number; // equivalent to max_tokens
|
||||||
response_format?: { type: string };
|
response_format?: { type: string };
|
||||||
};
|
};
|
||||||
tools?: any[];
|
tools?: any[];
|
||||||
|
|
||||||
// Internal control flags (not sent directly to API)
|
// Internal control flags (not sent directly to API)
|
||||||
enableTools?: boolean;
|
enableTools?: boolean;
|
||||||
bypassFormatter?: boolean;
|
bypassFormatter?: boolean;
|
||||||
preserveSystemPrompt?: boolean;
|
preserveSystemPrompt?: boolean;
|
||||||
expectsJsonResponse?: boolean;
|
expectsJsonResponse?: boolean;
|
||||||
toolExecutionStatus?: any[];
|
toolExecutionStatus?: any[];
|
||||||
// Streaming callback handler
|
// Streaming callback handler
|
||||||
streamCallback?: (text: string, isDone: boolean, originalChunk?: any) => Promise<void> | void;
|
streamCallback?: (text: string, isDone: boolean, originalChunk?: any) => Promise<void> | void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create OpenAI options from generic options and config
|
* Create OpenAI options from generic options and config
|
||||||
*/
|
*/
|
||||||
export function createOpenAIOptions(
|
export function createOpenAIOptions(
|
||||||
opts: ChatCompletionOptions = {},
|
opts: ChatCompletionOptions = {},
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
defaultModel: string
|
defaultModel: string
|
||||||
): OpenAIOptions {
|
): OpenAIOptions {
|
||||||
return {
|
return {
|
||||||
// Connection settings
|
// Connection settings
|
||||||
apiKey,
|
apiKey,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
|
||||||
// API parameters
|
// API parameters
|
||||||
model: opts.model || defaultModel,
|
model: opts.model || defaultModel,
|
||||||
temperature: opts.temperature,
|
temperature: opts.temperature,
|
||||||
max_tokens: opts.maxTokens,
|
max_tokens: opts.maxTokens,
|
||||||
stream: opts.stream,
|
stream: opts.stream,
|
||||||
top_p: opts.topP,
|
top_p: opts.topP,
|
||||||
frequency_penalty: opts.frequencyPenalty,
|
frequency_penalty: opts.frequencyPenalty,
|
||||||
presence_penalty: opts.presencePenalty,
|
presence_penalty: opts.presencePenalty,
|
||||||
tools: opts.tools,
|
tools: opts.tools,
|
||||||
|
|
||||||
// Internal configuration
|
// Internal configuration
|
||||||
systemPrompt: opts.systemPrompt,
|
systemPrompt: opts.systemPrompt,
|
||||||
enableTools: opts.enableTools,
|
enableTools: opts.enableTools,
|
||||||
// Pass through streaming callback
|
// Pass through streaming callback
|
||||||
streamCallback: opts.streamCallback,
|
streamCallback: opts.streamCallback,
|
||||||
// Include provider metadata
|
// Include provider metadata
|
||||||
providerMetadata: opts.providerMetadata,
|
providerMetadata: opts.providerMetadata,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Anthropic options from generic options and config
|
* Create Anthropic options from generic options and config
|
||||||
*/
|
*/
|
||||||
export function createAnthropicOptions(
|
export function createAnthropicOptions(
|
||||||
opts: ChatCompletionOptions = {},
|
opts: ChatCompletionOptions = {},
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
defaultModel: string,
|
defaultModel: string,
|
||||||
apiVersion: string,
|
apiVersion: string,
|
||||||
betaVersion: string
|
betaVersion: string
|
||||||
): AnthropicOptions {
|
): AnthropicOptions {
|
||||||
return {
|
return {
|
||||||
// Connection settings
|
// Connection settings
|
||||||
apiKey,
|
apiKey,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
apiVersion,
|
apiVersion,
|
||||||
betaVersion,
|
betaVersion,
|
||||||
|
|
||||||
// API parameters
|
// API parameters
|
||||||
model: opts.model || defaultModel,
|
model: opts.model || defaultModel,
|
||||||
temperature: opts.temperature,
|
temperature: opts.temperature,
|
||||||
max_tokens: opts.maxTokens,
|
max_tokens: opts.maxTokens,
|
||||||
stream: opts.stream,
|
stream: opts.stream,
|
||||||
top_p: opts.topP,
|
top_p: opts.topP,
|
||||||
|
|
||||||
// Internal configuration
|
// Internal configuration
|
||||||
systemPrompt: opts.systemPrompt,
|
systemPrompt: opts.systemPrompt,
|
||||||
// Pass through streaming callback
|
// Pass through streaming callback
|
||||||
streamCallback: opts.streamCallback,
|
streamCallback: opts.streamCallback,
|
||||||
// Include provider metadata
|
// Include provider metadata
|
||||||
providerMetadata: opts.providerMetadata,
|
providerMetadata: opts.providerMetadata,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Ollama options from generic options and config
|
* Create Ollama options from generic options and config
|
||||||
*/
|
*/
|
||||||
export function createOllamaOptions(
|
export function createOllamaOptions(
|
||||||
opts: ChatCompletionOptions = {},
|
opts: ChatCompletionOptions = {},
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
defaultModel: string,
|
defaultModel: string,
|
||||||
contextWindow: number
|
contextWindow: number
|
||||||
): OllamaOptions {
|
): OllamaOptions {
|
||||||
return {
|
return {
|
||||||
// Connection settings
|
// Connection settings
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
|
||||||
// API parameters
|
// API parameters
|
||||||
model: opts.model || defaultModel,
|
model: opts.model || defaultModel,
|
||||||
stream: opts.stream,
|
stream: opts.stream,
|
||||||
options: {
|
options: {
|
||||||
temperature: opts.temperature,
|
temperature: opts.temperature,
|
||||||
num_ctx: contextWindow,
|
num_ctx: contextWindow,
|
||||||
num_predict: opts.maxTokens,
|
num_predict: opts.maxTokens,
|
||||||
response_format: opts.expectsJsonResponse ? { type: "json_object" } : undefined
|
response_format: opts.expectsJsonResponse ? { type: "json_object" } : undefined
|
||||||
},
|
},
|
||||||
tools: opts.tools,
|
tools: opts.tools,
|
||||||
|
|
||||||
// Internal configuration
|
// Internal configuration
|
||||||
systemPrompt: opts.systemPrompt,
|
systemPrompt: opts.systemPrompt,
|
||||||
enableTools: opts.enableTools,
|
enableTools: opts.enableTools,
|
||||||
bypassFormatter: opts.bypassFormatter,
|
bypassFormatter: opts.bypassFormatter,
|
||||||
preserveSystemPrompt: opts.preserveSystemPrompt,
|
preserveSystemPrompt: opts.preserveSystemPrompt,
|
||||||
expectsJsonResponse: opts.expectsJsonResponse,
|
expectsJsonResponse: opts.expectsJsonResponse,
|
||||||
toolExecutionStatus: opts.toolExecutionStatus,
|
toolExecutionStatus: opts.toolExecutionStatus,
|
||||||
// Pass through streaming callback
|
// Pass through streaming callback
|
||||||
streamCallback: opts.streamCallback,
|
streamCallback: opts.streamCallback,
|
||||||
// Include provider metadata
|
// Include provider metadata
|
||||||
providerMetadata: opts.providerMetadata,
|
providerMetadata: opts.providerMetadata,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ export async function createEmbeddingProviderConfig(
|
|||||||
dateCreated, utcDateCreated, dateModified, utcDateModified)
|
dateCreated, utcDateCreated, dateModified, utcDateModified)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
[providerId, name, priority, JSON.stringify(config),
|
[providerId, name, priority, JSON.stringify(config),
|
||||||
now, utcNow, now, utcNow]
|
now, utcNow, now, utcNow]
|
||||||
);
|
);
|
||||||
|
|
||||||
return providerId;
|
return providerId;
|
||||||
@ -460,8 +460,8 @@ export function getAnthropicOptions(
|
|||||||
supportsStreaming: true,
|
supportsStreaming: true,
|
||||||
// Anthropic models typically have large context windows
|
// Anthropic models typically have large context windows
|
||||||
contextWindow: modelName.includes('claude-3-opus') ? 200000 :
|
contextWindow: modelName.includes('claude-3-opus') ? 200000 :
|
||||||
modelName.includes('claude-3-sonnet') ? 180000 :
|
modelName.includes('claude-3-sonnet') ? 180000 :
|
||||||
modelName.includes('claude-3.5-sonnet') ? 200000 : 100000
|
modelName.includes('claude-3.5-sonnet') ? 200000 : 100000
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user