Merge branch 'main' of github.com:QVerisAI/QVerisBot
This commit is contained in:
commit
d0408c3dbf
@ -206,6 +206,10 @@ export function buildAgentSystemPrompt(params: {
|
||||
session_status:
|
||||
"Show a /status-equivalent status card (usage + time + Reasoning/Verbose/Elevated); use for model-use questions (📊 session_status); optional per-session model override",
|
||||
image: "Analyze an image with the configured image model",
|
||||
qveris_search:
|
||||
"Search for third-party API tools by capability description (e.g. 'weather forecast', 'stock prices'). Describe what you want to accomplish, not specific params. Returns tool_id, params, and examples.",
|
||||
qveris_execute:
|
||||
"Execute a discovered third-party tool. Requires tool_id and search_id from qveris_search. Pass params as JSON string in params_to_tool. Consider stats (success_rate, avg_execution_time) when selecting tools.",
|
||||
};
|
||||
|
||||
const toolOrder = [
|
||||
@ -220,6 +224,8 @@ export function buildAgentSystemPrompt(params: {
|
||||
"process",
|
||||
"web_search",
|
||||
"web_fetch",
|
||||
"qveris_search",
|
||||
"qveris_execute",
|
||||
"browser",
|
||||
"canvas",
|
||||
"nodes",
|
||||
|
||||
@ -12,7 +12,6 @@ const DEFAULT_QVERIS_BASE_URL = "https://qveris.ai/api/v1";
|
||||
const DEFAULT_TIMEOUT_SECONDS = 60;
|
||||
const DEFAULT_MAX_RESPONSE_SIZE = 20480;
|
||||
const DEFAULT_SEARCH_LIMIT = 10;
|
||||
const DEFAULT_PRE_SEARCH_BYTE_THRESHOLD = 100;
|
||||
|
||||
// ============================================================================
|
||||
// Types
|
||||
@ -72,13 +71,6 @@ interface QverisExecutionResponse {
|
||||
credits_used?: number;
|
||||
}
|
||||
|
||||
/** Mapping from sanitized function name to original tool info */
|
||||
interface QverisToolMapping {
|
||||
functionName: string;
|
||||
toolId: string;
|
||||
searchId: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Config Resolution
|
||||
// ============================================================================
|
||||
@ -116,14 +108,6 @@ function resolveSearchLimit(config?: QverisConfig): number {
|
||||
return config?.searchLimit ?? DEFAULT_SEARCH_LIMIT;
|
||||
}
|
||||
|
||||
function resolvePreSearchEnabled(config?: QverisConfig): boolean {
|
||||
return config?.preSearchEnabled !== false;
|
||||
}
|
||||
|
||||
function resolvePreSearchByteThreshold(config?: QverisConfig): number {
|
||||
return config?.preSearchByteThreshold ?? DEFAULT_PRE_SEARCH_BYTE_THRESHOLD;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// API Client
|
||||
// ============================================================================
|
||||
@ -246,141 +230,6 @@ const QverisExecuteSchema = Type.Object({
|
||||
),
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Pre-Search Handler
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* PreSearchToolHandler manages the pre-search flow:
|
||||
* 1. Determines if pre-search should be performed based on first query length
|
||||
* 2. Performs pre-search and stores results
|
||||
* 3. Provides tool mappings for execution
|
||||
*/
|
||||
class PreSearchToolHandler {
|
||||
private searchId: string = "";
|
||||
private toolMappings = new Map<string, QverisToolMapping>();
|
||||
private preSearchedTools: QverisSearchResultTool[] = [];
|
||||
private preSearchPerformed: boolean = false;
|
||||
private preSearchEnabled: boolean = false;
|
||||
private byteThreshold: number;
|
||||
|
||||
constructor(byteThreshold: number = DEFAULT_PRE_SEARCH_BYTE_THRESHOLD) {
|
||||
this.byteThreshold = byteThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if pre-search should be performed
|
||||
* Conditions:
|
||||
* 1. First query length in bytes <= threshold
|
||||
*/
|
||||
shouldPreSearch(firstQuery: string): boolean {
|
||||
const byteLength = new TextEncoder().encode(firstQuery).length;
|
||||
return byteLength <= this.byteThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pre-search using the query
|
||||
*/
|
||||
async preSearch(params: {
|
||||
query: string;
|
||||
sessionId: string;
|
||||
apiKey: string;
|
||||
baseUrl: string;
|
||||
timeoutSeconds: number;
|
||||
searchLimit: number;
|
||||
}): Promise<QverisSearchResponse | null> {
|
||||
if (this.preSearchPerformed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await qverisSearch({
|
||||
query: params.query,
|
||||
sessionId: params.sessionId,
|
||||
limit: params.searchLimit,
|
||||
apiKey: params.apiKey,
|
||||
baseUrl: params.baseUrl,
|
||||
timeoutSeconds: params.timeoutSeconds,
|
||||
});
|
||||
|
||||
if (result.results && result.results.length > 0) {
|
||||
this.searchId = result.search_id;
|
||||
this.preSearchedTools = result.results;
|
||||
|
||||
// Store mappings for execution
|
||||
for (const tool of result.results) {
|
||||
const functionName = sanitizeToolName(tool.tool_id);
|
||||
this.toolMappings.set(functionName, {
|
||||
functionName,
|
||||
toolId: tool.tool_id,
|
||||
searchId: result.search_id,
|
||||
});
|
||||
}
|
||||
|
||||
this.preSearchEnabled = true;
|
||||
}
|
||||
|
||||
this.preSearchPerformed = true;
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.preSearchPerformed = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
isPreSearchEnabled(): boolean {
|
||||
return this.preSearchEnabled && this.preSearchedTools.length > 0;
|
||||
}
|
||||
|
||||
getPreSearchedTools(): QverisSearchResultTool[] {
|
||||
return this.preSearchedTools;
|
||||
}
|
||||
|
||||
getSearchId(): string {
|
||||
return this.searchId;
|
||||
}
|
||||
|
||||
isPreSearchedTool(toolName: string): boolean {
|
||||
return this.toolMappings.has(toolName);
|
||||
}
|
||||
|
||||
getToolMapping(functionName: string): QverisToolMapping | undefined {
|
||||
return this.toolMappings.get(functionName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize tool ID to create a valid function name
|
||||
*/
|
||||
function sanitizeToolName(toolId: string): string {
|
||||
if (!toolId || typeof toolId !== "string") {
|
||||
toolId = "unknown_tool";
|
||||
}
|
||||
|
||||
// Replace invalid characters with underscore
|
||||
let sanitized = toolId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
||||
|
||||
// Remove leading hyphens and numbers
|
||||
sanitized = sanitized.replace(/^[-0-9]+/, "");
|
||||
|
||||
// If empty after sanitization, use a default name
|
||||
if (!sanitized || sanitized === "_") {
|
||||
sanitized = "tool_" + Date.now().toString(36);
|
||||
}
|
||||
|
||||
// Ensure starts with letter or underscore
|
||||
if (sanitized.startsWith("-")) {
|
||||
sanitized = "_" + sanitized.substring(1);
|
||||
}
|
||||
|
||||
// Truncate to 64 characters
|
||||
if (sanitized.length > 64) {
|
||||
sanitized = sanitized.substring(0, 64);
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Tool Creation
|
||||
// ============================================================================
|
||||
|
||||
Loading…
Reference in New Issue
Block a user