mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-18 21:31:46 +00:00
agent.ts - add comments
This commit is contained in:
@@ -12,11 +12,14 @@ import {
|
|||||||
|
|
||||||
import { GRAPH_FILE, STORAGE_DIR } from "./constants";
|
import { GRAPH_FILE, STORAGE_DIR } from "./constants";
|
||||||
|
|
||||||
// Configure Settings
|
// Configure LlamaIndex to use local Ollama embeddings for semantic search
|
||||||
|
// This enables the query engine to perform similarity searches without external APIs
|
||||||
Settings.embedModel = new OllamaEmbedding({
|
Settings.embedModel = new OllamaEmbedding({
|
||||||
model: "nomic-embed-text-v2-moe",
|
model: "nomic-embed-text-v2-moe",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load API configuration from config.json
|
||||||
|
// Expects NVIDIA_API_KEY and NVIDIA_API_BASE for accessing NVIDIA's API endpoint
|
||||||
const config = JSON.parse(fs.readFileSync("./config.json", "utf-8"));
|
const config = JSON.parse(fs.readFileSync("./config.json", "utf-8"));
|
||||||
const apiKey = config.NVIDIA_API_KEY;
|
const apiKey = config.NVIDIA_API_KEY;
|
||||||
const baseURL = config.NVIDIA_API_BASE;
|
const baseURL = config.NVIDIA_API_BASE;
|
||||||
@@ -25,6 +28,8 @@ if (!apiKey) {
|
|||||||
console.warn("Please set NVIDIA_API_KEY in config.json.");
|
console.warn("Please set NVIDIA_API_KEY in config.json.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize the LLM using NVIDIA's OpenAI-compatible API endpoint
|
||||||
|
// Model: openai/gpt-oss-120b with temperature 0 for deterministic responses
|
||||||
const llm = new OpenAI({
|
const llm = new OpenAI({
|
||||||
model: "openai/gpt-oss-120b",
|
model: "openai/gpt-oss-120b",
|
||||||
apiKey: apiKey,
|
apiKey: apiKey,
|
||||||
@@ -33,8 +38,17 @@ const llm = new OpenAI({
|
|||||||
});
|
});
|
||||||
Settings.llm = llm;
|
Settings.llm = llm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function that initializes and runs the ECMAScript specification agent.
|
||||||
|
*
|
||||||
|
* The agent combines two information sources:
|
||||||
|
* 1. Vector search index (spec_retriever) - for semantic text search across spec sections
|
||||||
|
* 2. Graph knowledge base (graph_explorer) - for structural relationships between sections and code
|
||||||
|
*/
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log("Loading indices and graph...");
|
console.log("Loading indices and graph...");
|
||||||
|
|
||||||
|
// Load the vector index from disk containing embedded spec sections
|
||||||
const storageContext = await storageContextFromDefaults({
|
const storageContext = await storageContextFromDefaults({
|
||||||
persistDir: STORAGE_DIR,
|
persistDir: STORAGE_DIR,
|
||||||
});
|
});
|
||||||
@@ -43,12 +57,18 @@ async function main() {
|
|||||||
storageContext,
|
storageContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load the knowledge graph mapping spec sections to implementation functions
|
||||||
const graphData = JSON.parse(fs.readFileSync(GRAPH_FILE, "utf-8"));
|
const graphData = JSON.parse(fs.readFileSync(GRAPH_FILE, "utf-8"));
|
||||||
const graph = new Graph({ multi: true });
|
const graph = new Graph({ multi: true });
|
||||||
graph.import(graphData);
|
graph.import(graphData);
|
||||||
|
|
||||||
|
// Create a query engine with top-3 similarity results for text retrieval
|
||||||
const queryEngine = index.asQueryEngine({ similarityTopK: 3 });
|
const queryEngine = index.asQueryEngine({ similarityTopK: 3 });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tool for retrieving specification text via vector similarity search.
|
||||||
|
* Used to get detailed content of specific sections based on semantic queries.
|
||||||
|
*/
|
||||||
const queryEngineTool = new QueryEngineTool({
|
const queryEngineTool = new QueryEngineTool({
|
||||||
queryEngine,
|
queryEngine,
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -58,6 +78,11 @@ async function main() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tool for exploring the knowledge graph connecting spec sections to implementation.
|
||||||
|
* Enables structural navigation: finding which spec section a function implements
|
||||||
|
* or which functions implement a spec section.
|
||||||
|
*/
|
||||||
const graphTool = {
|
const graphTool = {
|
||||||
metadata: {
|
metadata: {
|
||||||
name: "graph_explorer",
|
name: "graph_explorer",
|
||||||
@@ -76,6 +101,8 @@ async function main() {
|
|||||||
},
|
},
|
||||||
call: async ({ query }: { query: string }) => {
|
call: async ({ query }: { query: string }) => {
|
||||||
console.log(`[Tool: graph_explorer] Querying for: ${query}`);
|
console.log(`[Tool: graph_explorer] Querying for: ${query}`);
|
||||||
|
|
||||||
|
// Try exact node match, or prepend 'func-' prefix for function names
|
||||||
let nodeId = query;
|
let nodeId = query;
|
||||||
if (!graph.hasNode(nodeId)) {
|
if (!graph.hasNode(nodeId)) {
|
||||||
if (graph.hasNode(`func-${query}`)) {
|
if (graph.hasNode(`func-${query}`)) {
|
||||||
@@ -84,24 +111,39 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (graph.hasNode(nodeId)) {
|
if (graph.hasNode(nodeId)) {
|
||||||
|
// Collect node info and all connected nodes
|
||||||
const neighbors = graph.neighbors(nodeId);
|
const neighbors = graph.neighbors(nodeId);
|
||||||
const nodeAttr = graph.getNodeAttributes(nodeId);
|
const nodeAttr = graph.getNodeAttributes(nodeId);
|
||||||
|
|
||||||
let result = `Information for ${nodeId} (${nodeAttr.type}):\n`;
|
let result = `Information for ${nodeId} (${nodeAttr.type}):\n`;
|
||||||
if (nodeAttr.title) result += `- Title: ${nodeAttr.title}\n`;
|
if (nodeAttr.title) result += `- Title: ${nodeAttr.title}\n`;
|
||||||
if (nodeAttr.file) result += `- File: ${nodeAttr.file}\n`;
|
if (nodeAttr.file) result += `- File: ${nodeAttr.file}\n`;
|
||||||
result += `\nConnected parts:\n`;
|
result += `\nConnected parts:\n`;
|
||||||
|
|
||||||
|
// List all connected nodes with their relationship types
|
||||||
neighbors.forEach((neighbor) => {
|
neighbors.forEach((neighbor) => {
|
||||||
const attr = graph.getNodeAttributes(neighbor);
|
const attr = graph.getNodeAttributes(neighbor);
|
||||||
const edges = graph.edges(nodeId, neighbor);
|
const edges = graph.edges(nodeId, neighbor);
|
||||||
const edgeAttr = graph.getEdgeAttributes(edges[0]);
|
const edgeAttr = graph.getEdgeAttributes(edges[0]);
|
||||||
result += `- ${neighbor} (${attr.type}) via ${edgeAttr.type}${attr.title ? `: ${attr.title}` : ""}\n`;
|
result += `- ${neighbor} (${attr.type}) via ${edgeAttr.type}${attr.title ? `: ${attr.title}` : ""}\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
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 spec_retriever to search text.`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ReAct agent that reasons about ECMAScript specification.
|
||||||
|
*
|
||||||
|
* The agent follows this workflow:
|
||||||
|
* 1. For function queries: graph_explorer → spec_retriever → explanation
|
||||||
|
* 2. For section queries: spec_retriever → explanation
|
||||||
|
*
|
||||||
|
* Critical constraints ensure tool-based answers rather than internal knowledge.
|
||||||
|
*/
|
||||||
const agent = new ReActAgent({
|
const agent = new ReActAgent({
|
||||||
tools: [queryEngineTool, graphTool],
|
tools: [queryEngineTool, graphTool],
|
||||||
llm: llm,
|
llm: llm,
|
||||||
@@ -120,11 +162,13 @@ CRITICAL INSTRUCTIONS:
|
|||||||
|
|
||||||
console.log("Agent is ready!");
|
console.log("Agent is ready!");
|
||||||
|
|
||||||
|
// Accept user query from command line argument, or use default question
|
||||||
const message =
|
const message =
|
||||||
process.argv[2] ||
|
process.argv[2] ||
|
||||||
"Which spec section does Evaluate_IfStatement implement? and what does that section say?";
|
"Which spec section does Evaluate_IfStatement implement? and what does that section say?";
|
||||||
console.log(`User: ${message}`);
|
console.log(`User: ${message}`);
|
||||||
|
|
||||||
|
// Execute the agent with the user's query
|
||||||
const response = await agent.chat({
|
const response = await agent.chat({
|
||||||
message: message,
|
message: message,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user