mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-18 13:21:55 +00:00
refactor: rename tools
This commit is contained in:
@@ -40,12 +40,12 @@ async function loadEngine262() {
|
||||
*/
|
||||
export function createEvaluateInEngine262Tool() {
|
||||
return new DynamicStructuredTool({
|
||||
name: "evaluate_in_engine262",
|
||||
name: "ask262_evaluate_in_engine262",
|
||||
description:
|
||||
"Executes JavaScript code in the engine262 JavaScript engine and captures which ECMAScript specification sections are hit during execution. Returns the full marks array as JSON. Useful for understanding how specific JavaScript operations map to the ECMAScript spec.",
|
||||
schema: evaluateSchema,
|
||||
func: async ({ code }) => {
|
||||
console.log(`[Tool: evaluate_in_engine262] Executing code...`);
|
||||
console.log(`[Tool: ask262_evaluate_in_engine262] Executing code...`);
|
||||
|
||||
try {
|
||||
const engine = await loadEngine262();
|
||||
@@ -130,7 +130,7 @@ export function createEvaluateInEngine262Tool() {
|
||||
const marks = ask262Debug.marks;
|
||||
|
||||
console.log(
|
||||
`[Tool: evaluate_in_engine262] Captured ${marks.length} unique marks`,
|
||||
`[Tool: ask262_evaluate_in_engine262] Captured ${marks.length} unique marks`,
|
||||
);
|
||||
|
||||
// Filter and group marks by important flag
|
||||
@@ -146,7 +146,7 @@ export function createEvaluateInEngine262Tool() {
|
||||
// Return compressed JSON
|
||||
return JSON.stringify(result);
|
||||
} catch (error) {
|
||||
console.error(`[Tool: evaluate_in_engine262] Error: ${error}`);
|
||||
console.error(`[Tool: ask262_evaluate_in_engine262] Error: ${error}`);
|
||||
return `Error executing code in engine262: ${error instanceof Error ? error.message : String(error)}`;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Section chunk retriever tool.
|
||||
* Get section content tool.
|
||||
* Retrieves all text chunks from a specific specification section by sectionid.
|
||||
*/
|
||||
|
||||
@@ -7,24 +7,26 @@ import type { Table } from "@lancedb/lancedb";
|
||||
import { DynamicStructuredTool } from "@langchain/core/tools";
|
||||
import { z } from "zod";
|
||||
|
||||
const sectionRetrieverSchema = z.object({
|
||||
const getSectionContentSchema = z.object({
|
||||
sectionId: z
|
||||
.string()
|
||||
.describe("The section ID (e.g., 'sec-if-statement') to fetch chunks for"),
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates the section retriever tool.
|
||||
* Creates the get section content tool.
|
||||
* Retrieves all text chunks from a specific specification section by sectionid.
|
||||
* Supports recursive fetching - if a section has children, it will fetch all descendants.
|
||||
* @param table - LanceDB table containing spec vectors
|
||||
*/
|
||||
export function createSectionRetrieverTool(table: Table) {
|
||||
export function createGetSectionContentTool(table: Table) {
|
||||
return new DynamicStructuredTool({
|
||||
name: "fetch_section_chunks",
|
||||
name: "ask262_get_section_content",
|
||||
description:
|
||||
"Retrieves all text chunks from a specific specification section by sectionid. " +
|
||||
"Supports recursive fetching - if a section has children, it will fetch all descendants. " +
|
||||
"Use this to get complete content when you see 'Subsection available' or 'partial section' references.",
|
||||
schema: sectionRetrieverSchema,
|
||||
schema: getSectionContentSchema,
|
||||
func: async ({ sectionId }) => {
|
||||
const allDocs: string[] = [];
|
||||
const queue: string[] = [sectionId];
|
||||
@@ -21,12 +21,12 @@ const graphExplorerSchema = z.object({
|
||||
*/
|
||||
export function createGraphExplorerTool(graph: Graph) {
|
||||
return new DynamicStructuredTool({
|
||||
name: "graph_explorer",
|
||||
name: "ask262_graph_explorer",
|
||||
description:
|
||||
"Explores structural relationships between specification sections and implementation code (functions). Use this to find which spec section a function implements.",
|
||||
schema: graphExplorerSchema,
|
||||
func: async ({ query }) => {
|
||||
console.log(`[Tool: graph_explorer] Querying for: ${query}`);
|
||||
console.log(`[Tool: ask262_graph_explorer] Querying for: ${query}`);
|
||||
|
||||
let nodeId = query;
|
||||
if (!graph.hasNode(nodeId)) {
|
||||
@@ -54,7 +54,7 @@ export function createGraphExplorerTool(graph: Graph) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return `No information found in graph for ${query}. Use spec_retriever to search text.`;
|
||||
return `No information found in graph for ${query}. Use ask262_search_spec_sections to search text.`;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
export { createEvaluateInEngine262Tool } from "./evaluateInEngine262";
|
||||
export { createGetSectionContentTool } from "./getSectionContent";
|
||||
export { createGraphExplorerTool } from "./graphExplorer";
|
||||
export { type RerankResult, rerankDocuments } from "./reranker";
|
||||
export { createSectionRetrieverTool } from "./sectionRetriever";
|
||||
export { createSpecRetrieverTool } from "./specRetriever";
|
||||
export { createSearchSpecSectionsTool } from "./searchSpecSections";
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Search specification sections tool.
|
||||
* Performs semantic vector search to find relevant specification sections by query.
|
||||
*/
|
||||
|
||||
import type { Table } from "@lancedb/lancedb";
|
||||
import { DynamicStructuredTool } from "@langchain/core/tools";
|
||||
import type { OllamaEmbeddings } from "@langchain/ollama";
|
||||
import { z } from "zod";
|
||||
|
||||
const searchSpecSchema = z.object({
|
||||
query: z
|
||||
.string()
|
||||
.describe("The search query to find relevant specification sections"),
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates the search spec sections tool.
|
||||
* Performs semantic vector search to find relevant spec sections.
|
||||
* @param table - LanceDB table containing spec vectors
|
||||
* @param embeddings - Ollama embeddings instance
|
||||
*/
|
||||
export function createSearchSpecSectionsTool(
|
||||
table: Table,
|
||||
embeddings: OllamaEmbeddings,
|
||||
) {
|
||||
return new DynamicStructuredTool({
|
||||
name: "ask262_search_spec_sections",
|
||||
description:
|
||||
"Searches the ECMAScript specification for sections relevant to a query. Returns JSON array with sectionId, sectionTitle, score, partIndex, totalParts, and content. partIndex and totalParts indicate which chunk of a multi-part section this is (0-indexed, partIndex+1/totalParts), null if single-part.",
|
||||
schema: searchSpecSchema,
|
||||
func: async ({ query }) => {
|
||||
// Generate embedding for the query
|
||||
const queryVector = await embeddings.embedQuery(query);
|
||||
|
||||
// Search using LanceDB directly, limit to top 5 results
|
||||
const results = await table.search(queryVector).limit(5).toArray();
|
||||
|
||||
console.log(
|
||||
`[ask262_search_spec_sections] Query: "${query.slice(0, 50)}..." - Fetched ${results.length} results`,
|
||||
);
|
||||
|
||||
// Return documents with metadata as JSON
|
||||
const output = results.map((r: Record<string, unknown>) => ({
|
||||
sectionId: String(r.sectionid || "unknown"),
|
||||
sectionTitle: String(r.sectiontitle || "unknown"),
|
||||
score: Number(r._distance || 0),
|
||||
partIndex: r.partindex ?? null,
|
||||
totalParts: r.totalparts ?? null,
|
||||
content: String(r.text || ""),
|
||||
}));
|
||||
|
||||
return JSON.stringify(output);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/**
|
||||
* Specification retriever tool.
|
||||
* Queries the language specification for text content about specific sections or topics.
|
||||
*/
|
||||
|
||||
import type { Table } from "@lancedb/lancedb";
|
||||
import { DynamicStructuredTool } from "@langchain/core/tools";
|
||||
import type { OllamaEmbeddings } from "@langchain/ollama";
|
||||
import { z } from "zod";
|
||||
import { rerankDocuments } from "./reranker";
|
||||
|
||||
const specRetrieverSchema = z.object({
|
||||
query: z
|
||||
.string()
|
||||
.describe("The search query to find relevant specification sections"),
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates the spec retriever tool.
|
||||
* @param table - LanceDB table containing spec vectors
|
||||
* @param embeddings - Ollama embeddings instance
|
||||
*/
|
||||
export function createSpecRetrieverTool(
|
||||
table: Table,
|
||||
embeddings: OllamaEmbeddings,
|
||||
) {
|
||||
return new DynamicStructuredTool({
|
||||
name: "spec_retriever",
|
||||
description:
|
||||
"Queries the language specification for text content about specific sections or topics. Fetches up to 10 initial matches and uses a reranker to dynamically select the most relevant 3-5 documents based on query relevance.",
|
||||
schema: specRetrieverSchema,
|
||||
func: async ({ query }) => {
|
||||
// Generate embedding for the query
|
||||
const queryVector = await embeddings.embedQuery(query);
|
||||
|
||||
// Search using LanceDB directly
|
||||
const results = await table.search(queryVector).limit(10).toArray();
|
||||
|
||||
// Create document objects with metadata
|
||||
const documents = results.map((r: Record<string, unknown>) => ({
|
||||
pageContent: String(r.text || ""),
|
||||
metadata: {
|
||||
source: r.source,
|
||||
sectionid: r.sectionid,
|
||||
sectiontitle: r.sectiontitle,
|
||||
type: r.type,
|
||||
parentsectionid: r.parentsectionid,
|
||||
childrensectionids: r.childrensectionids,
|
||||
partindex: r.partindex,
|
||||
totalparts: r.totalparts,
|
||||
},
|
||||
}));
|
||||
|
||||
// Rerank documents
|
||||
const reranked = await rerankDocuments(query, documents);
|
||||
|
||||
// Sort by score and filter to most relevant
|
||||
reranked.sort((a, b) => b.score - a.score);
|
||||
|
||||
// Dynamic selection: take top documents with score > 0.5, or at least top 3
|
||||
const threshold = 0.5;
|
||||
const minDocs = 3;
|
||||
const maxDocs = 5;
|
||||
|
||||
const selected = reranked.filter(
|
||||
(r, i) => i < minDocs || (i < maxDocs && r.score > threshold),
|
||||
);
|
||||
|
||||
console.log(
|
||||
`[spec_retriever] Query: "${query.slice(0, 50)}..." - Fetched ${documents.length}, reranked to ${selected.length} (scores: ${selected.map((s) => s.score.toFixed(2)).join(", ")})`,
|
||||
);
|
||||
|
||||
// Return documents with metadata
|
||||
return selected
|
||||
.map((r) => {
|
||||
const meta = r.document.metadata;
|
||||
const sectionId = meta?.sectionid || "unknown";
|
||||
const sectionTitle = meta?.sectiontitle || "unknown";
|
||||
const partInfo =
|
||||
meta?.partindex !== null && meta?.partindex !== undefined
|
||||
? ` [part ${(meta.partindex as number) + 1}/${meta.totalparts}]`
|
||||
: "";
|
||||
return `--- Section: ${sectionId} | "${sectionTitle}"${partInfo} (score: ${r.score.toFixed(2)}) ---\n${r.document.pageContent}`;
|
||||
})
|
||||
.join("\n\n");
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user