feat: solution for 'Повторный экзамен: Граф с рефлексией и доработкой'
This commit is contained in:
@@ -1,40 +1,37 @@
|
||||
# Self-Correcting Agent
|
||||
# Graph Reflexivity Project
|
||||
|
||||
This repository contains a simple implementation of a self‑correcting agent using **LangGraph**.
|
||||
The agent follows these steps:
|
||||
|
||||
1. **Ask** – Generates an answer to the user’s question.
|
||||
2. **Check** – Evaluates the answer’s quality.
|
||||
3. **Correct** – If the answer is flagged as poor, it rewrites it.
|
||||
4. **Final** – Returns the final answer.
|
||||
This project demonstrates a simple graph implementation in JavaScript that supports reflexivity (adding self-loops to all nodes). It uses the `graphlib` library for graph data structures and `lodash` for utility functions.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
npm install
|
||||
```
|
||||
|
||||
> **Note**: The implementation uses deterministic placeholders instead of real LLM calls, so no API keys are required.
|
||||
## Running the Example
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from src.agent import run_agent
|
||||
|
||||
question = "What is the capital of France?"
|
||||
answer = run_agent(question)
|
||||
print(answer)
|
||||
```bash
|
||||
node src/index.js
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
You will see the adjacency list before and after applying reflexivity.
|
||||
|
||||
## Testing
|
||||
|
||||
Run the test suite with:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
├── requirements.txt
|
||||
├── src
|
||||
│ └── agent.py
|
||||
└── README.md
|
||||
```
|
||||
|
||||
The tests cover basic graph operations, reflexivity, and adjacency list generation.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **graphlib** – Provides the underlying graph data structure.
|
||||
- **lodash** – Utility library (used for potential future extensions).
|
||||
- **jest** – Testing framework (dev dependency).
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
MIT
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "graph-reflexivity",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple graph implementation with reflexivity support",
|
||||
"main": "src/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"graphlib": "^2.1.8",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^29.7.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Graph as GraphLib } from 'graphlib';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default class Graph {
|
||||
constructor() {
|
||||
this.graph = new GraphLib();
|
||||
}
|
||||
|
||||
addNode(node) {
|
||||
this.graph.setNode(node);
|
||||
}
|
||||
|
||||
addEdge(from, to) {
|
||||
this.graph.setEdge(from, to);
|
||||
}
|
||||
|
||||
hasEdge(from, to) {
|
||||
return this.graph.hasEdge(from, to);
|
||||
}
|
||||
|
||||
reflexive() {
|
||||
this.graph.nodes().forEach((node) => {
|
||||
if (!this.graph.hasEdge(node, node)) {
|
||||
this.graph.setEdge(node, node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getAdjacencyList() {
|
||||
const adjacency = {};
|
||||
this.graph.nodes().forEach((node) => {
|
||||
adjacency[node] = this.graph.successors(node) || [];
|
||||
});
|
||||
return adjacency;
|
||||
}
|
||||
}
|
||||
+12
-57
@@ -1,63 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Simple Self-Correcting Agent
|
||||
*
|
||||
* This script demonstrates a minimal self‑correcting agent that
|
||||
* takes a string input and attempts to correct common typos such as
|
||||
* extra spaces, missing punctuation, and simple misspellings using
|
||||
* a small dictionary.
|
||||
*
|
||||
* The implementation uses only the Node.js standard library
|
||||
* and does not depend on any external frameworks.
|
||||
*/
|
||||
import Graph from './graph.js';
|
||||
|
||||
const process = require('process');
|
||||
const g = new Graph();
|
||||
|
||||
// A very small dictionary of common misspellings
|
||||
const MISSPELLINGS = {
|
||||
"teh": "the",
|
||||
"recieve": "receive",
|
||||
"adress": "address",
|
||||
"occured": "occurred",
|
||||
"seperate": "separate",
|
||||
"definately": "definitely",
|
||||
"goverment": "government",
|
||||
"untill": "until",
|
||||
"accomodate": "accommodate",
|
||||
"wich": "which",
|
||||
};
|
||||
g.addNode('A');
|
||||
g.addNode('B');
|
||||
g.addNode('C');
|
||||
|
||||
function correctSpelling(word) {
|
||||
return MISSPELLINGS[word.toLowerCase()] || word;
|
||||
}
|
||||
g.addEdge('A', 'B');
|
||||
g.addEdge('B', 'C');
|
||||
|
||||
function correctSentence(sentence) {
|
||||
// Strip whitespace
|
||||
sentence = sentence.trim();
|
||||
// Collapse multiple spaces
|
||||
sentence = sentence.replace(/\s+/g, ' ');
|
||||
// Tokenise and correct words
|
||||
const words = sentence.split(' ');
|
||||
const correctedWords = words.map(correctSpelling);
|
||||
let corrected = correctedWords.join(' ');
|
||||
// Ensure ending punctuation
|
||||
if (!/[.!?]$/.test(corrected)) {
|
||||
corrected += '.';
|
||||
}
|
||||
return corrected;
|
||||
}
|
||||
console.log('Before reflexive:');
|
||||
console.log(g.getAdjacencyList());
|
||||
|
||||
function main() {
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length === 0) {
|
||||
console.log('Usage: node src/index.js "<sentence>"');
|
||||
process.exit(1);
|
||||
}
|
||||
const inputSentence = args.join(' ');
|
||||
const corrected = correctSentence(inputSentence);
|
||||
console.log(corrected);
|
||||
}
|
||||
g.reflexive();
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
console.log('After reflexive:');
|
||||
console.log(g.getAdjacencyList());
|
||||
@@ -0,0 +1,39 @@
|
||||
import Graph from '../src/graph.js';
|
||||
|
||||
describe('Graph', () => {
|
||||
test('should add nodes and edges correctly', () => {
|
||||
const g = new Graph();
|
||||
g.addNode('x');
|
||||
g.addNode('y');
|
||||
g.addEdge('x', 'y');
|
||||
|
||||
expect(g.hasEdge('x', 'y')).toBe(true);
|
||||
expect(g.hasEdge('y', 'x')).toBe(false);
|
||||
});
|
||||
|
||||
test('reflexive should add self loops', () => {
|
||||
const g = new Graph();
|
||||
g.addNode('x');
|
||||
g.addNode('y');
|
||||
g.addEdge('x', 'y');
|
||||
|
||||
g.reflexive();
|
||||
|
||||
expect(g.hasEdge('x', 'x')).toBe(true);
|
||||
expect(g.hasEdge('y', 'y')).toBe(true);
|
||||
});
|
||||
|
||||
test('getAdjacencyList returns correct structure', () => {
|
||||
const g = new Graph();
|
||||
g.addNode('x');
|
||||
g.addNode('y');
|
||||
g.addEdge('x', 'y');
|
||||
|
||||
g.reflexive();
|
||||
|
||||
const adj = g.getAdjacencyList();
|
||||
expect(adj['x']).toContain('y');
|
||||
expect(adj['x']).toContain('x');
|
||||
expect(adj['y']).toContain('y');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user