Saturday, October 17, 2026

Unix Pipes and grep

 

Unix  Pipes and grep

The objective is to use pipes (|), grep, find, wc, uniq, and output redirection to solve the exercises and save both the commands and their outputs in lab5_q2.txt.

(a) What does who | grep A20\* do?

who | grep A20\*
  • who displays users currently logged in.

  • | sends the output of who to grep.

  • grep A20\* searches for lines matching the pattern A20*.

Important: In basic grep regular expressions, \* means zero or more occurrences of the preceding character, 0. Therefore, this pattern matches A2 followed by zero or more zeros, such as A2, A20, or A200. It does not mean “any text starting with A20.”

If the intention is to find lines containing text beginning with A20, use:

who | grep 'A20'

If the intention is to match a username beginning with A20, use:

who | grep '^A20'

(b) Count files under /usr/include whose names start with l, contain a number, and end with .h

find /usr/include -type f -name 'l*[0-9]*.h' | wc -l

Explanation:

  • find /usr/include searches recursively.

  • -type f selects regular files.

  • -name 'l*[0-9]*.h' matches filenames beginning with l, containing at least one digit, and ending with .h.

  • wc -l counts the matching file paths.

(c) Find French F1 drivers from 2017 and 2018, using uniq

Assuming each line contains the driver's nationality and the driver name appears first, try:

grep -i 'French' /home/lab_files/F1_drivers_2017 /home/lab_files/F1_drivers_2018 | sort | uniq

This searches both files, selects lines containing French, sorts the results, and removes identical duplicate lines.

Note: uniq removes duplicate lines, not duplicate driver names appearing in different team/year records. If the same driver has different records in 2017 and 2018, the file format determines how to extract the driver name alone. You can inspect the data using:

head /home/lab_files/F1_drivers_2017

Save the commands and their outputs in lab5_q2.txt

Run this block in your terminal. It records each command and its output in the requested file.

{
    echo "Part (a): who | grep A20\*"
    who | grep A20\*

    echo
    echo "Part (b): find /usr/include -type f -name 'l*[0-9]*.h' | wc -l"
    find /usr/include -type f -name 'l*[0-9]*.h' | wc -l

    echo
    echo "Part (c): French F1 drivers"
    grep -i 'French' /home/lab_files/F1_drivers_2017 /home/lab_files/F1_drivers_2018 | sort | uniq
} > lab5_q2.txt 2>&1

Verify the saved file:

cat lab5_q2.txt

The output will depend on the files and logged-in users on your lab machine. The block above records the commands' results, including error messages, but does not print the command text automatically beyond the headings. If your instructor requires the literal commands as well as their outputs, use this version instead:

{
    echo 'Command: who | grep A20\*'
    who | grep A20\*

    echo 'Command: find /usr/include -type f -name "l*[0-9]*.h" | wc -l'
    find /usr/include -type f -name 'l*[0-9]*.h' | wc -l

    echo "Command: grep -i 'French' /home/lab_files/F1_drivers_2017 /home/lab_files/F1_drivers_2018 | sort | uniq"
    grep -i 'French' /home/lab_files/F1_drivers_2017 /home/lab_files/F1_drivers_2018 | sort | uniq
} > lab5_q2.txt 2>&1

For the shortest command in part (c): the pipeline above is concise, but to ensure each driver appears only once even when their team details differ, I would need to see the first few lines of the two F1 files to identify the correct driver-name column.

is it 1 or l? find /usr/include -type f -name 'l*[0-9]*.h' | wc -l

It is a lowercase letter l, not the number 1.

find /usr/include -type f -name 'l*[0-9]*.h' | wc -l

In the pattern 'l*[0-9]*.h':

  • l — lowercase letter l, as in lion.

  • * — any sequence of characters (including none).

  • [0-9] — any single digit from 0 to 9.

  • *.h — any sequence of characters followed by .h.

So the filename must start with lowercase l, contain at least one digit, and end with .h.

1. Processes, Pipes, Grep and Email

(a) List all running processes in full format

ps -ef

Explanation:

  • ps — displays process information.

  • -e — selects all processes.

  • -f — displays the full-format listing, including user, PID, parent PID, start time, and command.

(b) Display only the SSH processes using a pipe and text filter

ps -ef | grep 'ssh'

Explanation:

  • ps -ef — lists all processes in full format.

  • | (pipe) — passes the output of ps -ef to the next command.

  • grep 'ssh' — displays only lines containing the text ssh.

Note: This command may also display the grep 'ssh' command itself. To exclude that line, you can use:

ps -ef | grep '[s]sh'

(c) Redirect the SSH process listing to a file

Replace studentID with your actual student ID.

ps -ef | grep '[s]sh' > ssh_list_studentID.txt

For example, if your student ID is student123:

ps -ef | grep '[s]sh' > ssh_list_student123.txt

Explanation:

  • > — redirects the command output to a file.

  • If the file does not exist, it is created.

  • If the file already exists, its previous contents are overwritten.

Summary

Question

Command

(a) All processes in full format

ps -ef

(b) Only SSH-related processes

ps -ef \| grep '[s]sh'

(c) Save results to a file

ps -ef \| grep '[s]sh' > ssh_list_studentID.txt

Important: The filter matches any command line containing ssh, including related commands such as sshd.

(a) Copy mid_semester_revision.txt to your home folder

Run this command in Terminal 1:

cp /home/lab_files/mid_semester_revision.txt ~/

Explanation:

  • cp — copies a file.

  • /home/lab_files/mid_semester_revision.txt — source file path.

  • ~/ — your home directory.

Verify that the file was copied:

ls -l ~/mid_semester_revision.txt

(b) Open a second terminal and answer the questions using VI

Terminal 1

  1. Open the copied file in the VI editor:

    vi ~/mid_semester_revision.txt
  2. Read the questions in the file.

  3. Keep this terminal open while you work.

Terminal 2

  1. Open a second terminal window or tab.

  2. Log in with your student account if required by your lab environment.

  3. Test Linux commands here before using them in Terminal 1.

For example, test:

ps -ef
who
grep --help

Use the appropriate commands for the questions in the revision file.

Useful VI commands

Key/command

Purpose

i

Enter insert mode to type answers

Esc

Return to command mode

:w

Save changes

:wq

Save and exit

:q!

Exit without saving

Important: You should edit the copied file in your home folder, not the original file in /home/lab_files.



AGENTIC AI PROJECT

Intelligent GitHub Issue Refinement & Duplicate Detection System

1. Project Objective

What are we building?

We are building an Agentic AI system that helps a developer before submitting a new issue to a large GitHub repository.

The system will:

  1. Accept a GitHub issue title and description.
  2. Detect spelling and grammar problems.
  3. Correct the language.
  4. Refine the issue into a professional technical report.
  5. Search historical GitHub issues.
  6. Retrieve semantically similar issues using RAG.
  7. Ask an LLM-based agent to determine whether the issue is actually a duplicate.
  8. Produce one final recommendation:
DUPLICATE
POSSIBLE_DUPLICATE
READY_TO_PUBLISH

The application does not actually create the GitHub issue. Its responsibility ends with the recommendation

Understand the Agentic Nature

This is not simply an LLM chatbot.

The project contains:

LLM
 +
Tools
 +
RAG
 +
Persistent Knowledge
 +
State
 +
Conditional Routing
 +
Agentic Workflow

Pasted markdown

LLM

Provides language understanding and reasoning.

Embedding Model

Converts text into vectors.

Vector Database

Stores and searches historical issue embeddings.

RAG

Provides relevant historical issues to the LLM.

Tools

Interact with external systems such as GitHub and the vector database.

Agents

Perform specialized responsibilities.

Agentic Workflow

Coordinates:

Agents
Tools
State
Transitions
Conditions 

Decisions 


Below is a practical reference solution for the uploaded problem statement, using:

  • Python
  • LangGraph for agentic workflow
  • LangChain
  • Ollama
  • Qwen for LLM reasoning
  • nomic-embed-text for embeddings
  • Chroma for vector storage
  • GitHub REST API for issue collection

The solution follows the original architecture: GitHub ingestion → normalization → embeddings → vector search → language correction → refinement → duplicate analysis → final decision. Pasted markdown


1. Solution Architecture

We will implement the project in two pipelines.

Pipeline 1 – Offline Knowledge Base

GitHub Repository
       |
       v
GitHub API
       |
       v
Issue Collector
       |
       v
issues.json
       |
       v
Normalize Issues
       |
       v
Embedding Model
       |
       v
Chroma Vector DB

Pipeline 2 – Online Agentic Workflow

User Issue
    |
    v
Issue Intake
    |
    v
Language Agent
    |
    v
Correction
    |
    v
Refinement Agent
    |
    v
Embedding
    |
    v
Vector Search
    |
    v
Top-K Candidates
    |
    v
Duplicate Analysis Agent
    |
    v
Decision
    |
    +------ DUPLICATE
    |
    +------ POSSIBLE_DUPLICATE
    |
    +------ READY_TO_PUBLISH

This follows the required architecture where vector similarity retrieves candidates, while the LLM performs the final duplicate reasoning. Pasted markdown


2. Project Structure

Create the following project:

github-issue-agent/
│
├── .env
├── requirements.txt
├── README.md
│
├── data/
│   ├── issues.json
│   └── sync_state.json
│
├── config/
│   └── settings.py
│
├── models/
│   └── schemas.py
│
├── ingestion/
│   ├── github_client.py
│   ├── issue_collector.py
│   └── synchronizer.py
│
├── rag/
│   ├── embeddings.py
│   ├── indexer.py
│   └── retriever.py
│
├── agents/
│   ├── language_agent.py
│   ├── refinement_agent.py
│   └── duplicate_agent.py
│
├── workflow/
│   ├── state.py
│   ├── nodes.py
│   └── graph.py
│
└── app/
    └── main.py

This also keeps ingestion, RAG, agents, workflow and models separate as required by the problem statement. Pasted markdown


3. Step 1 – Create Virtual Environment

What?

Create an isolated Python environment.

Why?

The project has several Python dependencies. A virtual environment prevents dependency conflicts with other projects.

How?

python -m venv .venv

Windows:

.venv\Scripts\activate

Linux/macOS:

source .venv/bin/activate

4. Step 2 – Install Packages

Create requirements.txt.

langchain
langchain-core
langchain-community
langchain-ollama
langchain-chroma
langgraph
chromadb
pydantic
python-dotenv
requests

Install:

pip install -r requirements.txt

5. Step 3 – Install Ollama Models

What?

We use Ollama for local LLM and embedding generation.

Why?

The problem statement recommends Ollama with models such as Qwen/Llama and nomic-embed-text. Pasted markdown

Install/pull models:

ollama pull qwen3
ollama pull nomic-embed-text

Verify:

ollama list

You should see something similar to:

NAME
qwen3
nomic-embed-text

6. Step 4 – Configuration

Create:

config/settings.py
import osfrom dotenv import load_dotenv# Load values from .envload_dotenv()# GitHub repository to analyzeGITHUB_REPOSITORY = os.getenv(    "GITHUB_REPOSITORY",    "kubernetes/kubernetes")# Number of issues to retrieve during the demoISSUE_LIMIT = int(    os.getenv("ISSUE_LIMIT", "100"))# Local Ollama modelsLLM_MODEL = os.getenv(    "LLM_MODEL",    "qwen3")EMBEDDING_MODEL = os.getenv(    "EMBEDDING_MODEL",    "nomic-embed-text")# Number of candidates retrieved from ChromaTOP_K = int(    os.getenv("TOP_K", "10"))# Vector similarity thresholdSIMILARITY_THRESHOLD = float(    os.getenv("SIMILARITY_THRESHOLD", "0.75")

7. Step 5 – Environment File

Create .env.

GITHUB_REPOSITORY=kubernetes/kubernetes

ISSUE_LIMIT=100

LLM_MODEL=qwen3

EMBEDDING_MODEL=nomic-embed-text

TOP_K=10

SIMILARITY_THRESHOLD=0.75

CHROMA_DIRECTORY=./data/chroma

If you use a GitHub token:

GITHUB_TOKEN=your_token_here

Do not commit .env to Git.


8. Step 6 – Define Issue Schema

What?

Define the structure of an issue.

Why?

GitHub API data should be converted into a predictable application model.

Create:

models/schemas.py
from pydantic import BaseModelfrom typing import List, Optionalclass GitHubIssue(BaseModel):    """    Represents a normalized GitHub issue.    """    id: int    number: int    title: str    body: str = ""    state: str    labels: List[str] = []    created_at: str    updated_at: str    url: strclass DuplicateResult(BaseModel):    """    Structured result returned by the Duplicate Analysis Agent.    """    status: str    issue_number: Optional[int] = None

Structured output is important because the original problem statement recommends structured JSON/Pydantic-style responses. Pasted markdown


9. Step 7 – GitHub Client

Create:

ingestion/github_client.py
import requestsfrom config.settings import GITHUB_TOKENclass GitHubClient:    """    Responsible only for communicating with GitHub.    """    BASE_URL = "https://api.github.com"    def __init__(self):        self.session = requests.Session()        # Add authentication if a GitHub token is available.        if GITHUB_TOKEN:            self.session.headers.update({                "Authorization": f"Bearer {GITHUB_TOKEN}"            })        self.session.headers.update({            "Accept": "application/vnd.github+json"        })    def get_issues(        self,        repository: str,        limit: int = 100    ):        """        Retrieve issues from a public GitHub repository.        We request both open and closed issues because        historical issues are required for duplicate detection.        """

10. Step 8 – Collect GitHub Issues

Create:

ingestion/issue_collector.py
import jsonfrom pathlib import Pathfrom ingestion.github_client import GitHubClientfrom config.settings import (    GITHUB_REPOSITORY,    ISSUE_LIMIT)def collect_issues():    client = GitHubClient()    print(        f"Collecting issues from "        f"{GITHUB_REPOSITORY}..."    )    raw_issues = client.get_issues(        GITHUB_REPOSITORY,        ISSUE_LIMIT    )    normalized = []    for issue in raw_issues:        # GitHub's /issues endpoint can also return pull requests.        # We only want actual issues.        if "pull_request" in issue:            continue        normalized.append({            "id": issue["id"],            "number": issue["number"],

Run:

python ingestion/issue_collector.py

Expected:

Collecting issues from kubernetes/kubernetes...
Issues saved: 95

The original specification requires the collected dataset to become the source dataset for RAG. Pasted markdown


11. Step 9 – Understand Normalization

A raw GitHub issue may look like:

Title:
Pod fails to restart after node failure

Body:
After the worker node recovers...

We convert it into a searchable document:

Issue ID: 12345

Title:
Pod fails to restart after node failure

Description:
After the worker node recovers...

Labels:
kind/bug, sig/node

Why?

The embedding model needs meaningful text representing the issue.


12. Step 10 – Create Embedding Service

Create:

rag/embeddings.py
from langchain_ollama import OllamaEmbeddingsfrom config.settings import EMBEDDING_MODELdef create_embedding_model():    """    Create the embedding model.    Ollama runs the model locally, so the application    does not need to send issue text to an external    embedding service.    """    return OllamaEmbeddings(        model=EMBEDDING_MODEL    )

13. Step 11 – Create RAG Documents

Create:

rag/indexer.py
import jsonfrom langchain_core.documents import Documentfrom langchain_chroma import Chromafrom rag.embeddings import create_embedding_modelfrom config.settings import CHROMA_DIRECTORYdef load_issues():    with open(        "data/issues.json",        "r",        encoding="utf-8"    ) as file:        return json.load(file)def create_documents():    issues = load_issues()    documents = []    for issue in issues:        # Combine the important parts of the issue        # into one searchable text document.        content = f"""Issue ID: {issue['number']}Title:{issue['title']}

14. Step 12 – Build the Vector Database

Run:

python rag/indexer.py

Conceptually:

Issue
  |
  v
Text
  |
  v
Embedding Model
  |
  v
Vector
  |
  v
Chroma

For example:

"Pod fails to restart"
          |
          v
[0.021, -0.153, 0.481, ...]

The embedding model converts issue content into vectors, while the vector database stores and searches those vectors. Pasted markdown


15. Step 13 – Create the Retriever

Create:

rag/retriever.py
from langchain_chroma import Chromafrom rag.embeddings import create_embedding_modelfrom config.settings import (    CHROMA_DIRECTORY,    TOP_K)def get_vector_store():    embeddings = create_embedding_model()    return Chroma(        persist_directory=CHROMA_DIRECTORY,        embedding_function=embeddings,        collection_name="github_issues"    )def search_similar_issues(query: str):    vector_store = get_vector_store()    # Retrieve the Top-K semantically similar issues.    results = vector_store.similarity_search_with_score(        query,        k=TOP_K    )    return results

16. Important RAG Principle

Suppose we have:

50,000 historical issues

We should not do this:

50,000 Issues
      |
      v
     LLM

Instead:

50,000 Issues
      |
      v
Vector Database
      |
      v
New Issue Embedding
      |
      v
Vector Search
      |
      v
Top 10 Candidates
      |
      v
LLM

This is one of the most important design principles in the assignment. Pasted markdown


17. Step 14 – Create Agent State

Create:

workflow/state.py
from typing import TypedDict, List, Dictclass IssueState(TypedDict, total=False):    # Original user input    original_title: str    original_description: str    # Corrected version    corrected_title: str    corrected_description: str    # Professionally refined version    refined_title: str    refined_description: str    # Language errors detected    spelling_errors: List[str]    # Issues retrieved from vector database    candidate_issues: List[Dict]    # Duplicate analysis    duplicate_status: str    duplicate_issue_id: int | None    similarity_score: float | None    # Final application decision    final_decision: str    # Explanation    reason: str

This corresponds directly to the shared IssueState described in the problem statement. Pasted markdown


18. Step 15 – Create the Language Agent

Create:

agents/language_agent.py
from langchain_ollama import ChatOllamafrom config.settings import LLM_MODELdef create_llm():    return ChatOllama(        model=LLM_MODEL,        temperature=0    )def analyze_language(    title: str,    description: str):    llm = create_llm()    prompt = f"""You are a technical language correction agent.Analyze the following GitHub issue.Title:{title}Description:{description}Tasks:1. Detect spelling errors.2. Detect grammar problems.3. Correct the language.

Why?

The first agent is responsible only for language quality.

It should not make the duplicate decision.

This separation of responsibilities is what makes the workflow agentic.


19. Step 16 – Create Refinement Agent

Create:

agents/refinement_agent.py
from langchain_ollama import ChatOllamafrom config.settings import LLM_MODELdef refine_issue(    title: str,    description: str):    llm = ChatOllama(        model=LLM_MODEL,        temperature=0    )    prompt = f"""You are a GitHub technical issue refinement agent.Rewrite the following issue as a professionaltechnical issue report.Title:{title}Description:{description}Create:1. Clear technical title2. Description3. Expected Behavior4. Actual BehaviorRules:

The problem statement specifically requires that refinement must not invent technical facts. Pasted markdown


20. Step 17 – Create Duplicate Analysis Agent

This is the most important reasoning agent.

Create:

agents/duplicate_agent.py
from langchain_ollama import ChatOllamafrom config.settings import LLM_MODELdef analyze_duplicates(    refined_issue: str,    candidates: list):    llm = ChatOllama(        model=LLM_MODEL,        temperature=0    )    candidate_text = ""    for candidate, score in candidates:        candidate_text += f"""-----------------------------------Issue Number:{candidate.metadata.get("issue_number")}Similarity Score:{score}Issue:{candidate.page_content}URL:{candidate.metadata.get("url")}-----------------------------------"""    prompt = f"""

The important distinction is:

Embedding Model
      |
      v
Candidate Retrieval

LLM
      |
      v
Semantic Duplicate Reasoning

The source explicitly states that vector similarity alone should not determine duplicate status. Pasted markdown


21. Step 18 – Create LangGraph Nodes

Create:

workflow/nodes.py
from workflow.state import IssueStatefrom agents.language_agent import analyze_languagefrom agents.refinement_agent import refine_issuefrom rag.retriever import search_similar_issuesdef issue_input_node(    state: IssueState):    # Preserve the original user input.    print("\n[Issue Intake]")    return statedef language_check_node(    state: IssueState):    print("\n[Language Agent]")    result = analyze_language(        state["original_title"],        state["original_description"]    )    # For a production implementation, parse the    # structured LLM response instead of storing raw text.    state["corrected_title"] = state["original_title"]    state["corrected_description"] = result    return state

22. Step 19 – Create Duplicate Node

Add to workflow/nodes.py:

from agents.duplicate_agent import analyze_duplicatesdef duplicate_analysis_node(    state: IssueState):    print("\n[Duplicate Analysis Agent]")    # Convert our simplified candidate list back into    # information that can be supplied to the LLM.    candidates = []    for item in state["candidate_issues"]:        candidates.append(            (                item["title"],                item["score"]            )        )    refined_issue = (        state["refined_title"]        + "\n"        + state["refined_description"]    )    result = analyze_duplicates(        refined_issue,        candidates    )    # For demonstration, retain the LLM response.    state["reason"] = result

23. Step 20 – Create Decision Node

Add:

def decision_node(    state: IssueState):    print("\n[Decision Node]")    status = state.get(        "duplicate_status",        "NOT_DUPLICATE"    )    if status == "DUPLICATE":        state["final_decision"] = "DUPLICATE"    elif status == "POSSIBLE_DUPLICATE":        state["final_decision"] = "POSSIBLE_DUPLICATE"    else:        state["final_decision"] = "READY_TO_PUBLISH"    return state

The required final application decisions are:

DUPLICATE
POSSIBLE_DUPLICATE
READY_TO_PUBLISH

Pasted markdown


24. Step 21 – Build the LangGraph

Create:

workflow/graph.py
from langgraph.graph import StateGraph, START, ENDfrom workflow.state import IssueStatefrom workflow.nodes import (    issue_input_node,    language_check_node,    refinement_node,    rag_search_node,    duplicate_analysis_node,    decision_node)def build_graph():    # Create graph using our shared state.    graph = StateGraph(IssueState)    # Register nodes.    graph.add_node(        "issue_input",        issue_input_node    )    graph.add_node(        "language_check",        language_check_node    )    graph.add_node(        "refinement",        refinement_node    )    graph.add_node(

25. Step 22 – Run the Application

Create:

app/main.py
from workflow.graph import build_graphdef main():    print("=" * 60)    print("GitHub Intelligent Issue Refinement Agent")    print("=" * 60)    # Get user input.    title = input(        "\nEnter issue title: "    )    description = input(        "Enter issue description: "    )    # Create LangGraph application.    app = build_graph()    # Initial workflow state.    initial_state = {        "original_title": title,        "original_description": description,        "corrected_title": "",        "corrected_description": "",        "refined_title": "",        "refined_description": "",

Run:

python app/main.py

26. Example Input

Enter:

Title:
pod is not restrting after crash

Description:

when pod crash sometime its not coming back
i tried restart but same problem happening

The workflow should conceptually execute:

[Issue Intake]
      ↓
[Language Agent]
      ↓
[Correction]
      ↓
[Refinement Agent]
      ↓
[RAG Search]
      ↓
[Top 10 Candidates]
      ↓
[Duplicate Analysis Agent]
      ↓
[Decision]

27. Expected Refined Result

The LLM should produce something conceptually similar to:

Title:
Pod does not automatically restart after an unexpected crash

Description:

In certain situations, a pod that terminates unexpectedly
does not restart automatically.

The pod remains unavailable until it is manually restarted.

Expected Behavior:
The pod should automatically recover according to the
configured restart policy.

Actual Behavior:
The pod occasionally remains unavailable after the crash
and requires manual intervention.

This follows the refinement example from the problem statement. Pasted markdown


28. Example RAG Result

The vector database may return:

Top 10 Candidates

#9321     0.91
#15102    0.87
#20452    0.79
#41002    0.65
...

This means:

0.91 → very semantically similar
0.87 → highly similar
0.79 → reasonably similar
0.65 → less similar

But remember:

Similarity ≠ Duplicate

The LLM must examine the actual issue content.


29. Final Duplicate Analysis

The Duplicate Analysis Agent should compare:

New Issue
    |
    +-- Problem
    +-- Component
    +-- Symptoms
    +-- Trigger
    +-- Expected Behavior
    +-- Actual Behavior
    +-- Technical Context

against:

Candidate Issue #9321

Then produce:

DUPLICATE

or:

POSSIBLE_DUPLICATE

or:

NOT_DUPLICATE

The source specifically recommends these classifications for the analysis stage. Pasted markdown


30. Final Decision Logic

The application converts the analysis into:

                   Duplicate Analysis
                          |
             +------------+------------+
             |            |            |
             v            v            v
         DUPLICATE   POSSIBLE       NOT DUPLICATE
                     DUPLICATE           |
             |            |              |
             v            v              v
         DUPLICATE   POSSIBLE       READY TO
                     DUPLICATE       PUBLISH

31. Important Improvement – Use Structured Output

The above code demonstrates the architecture, but for a proper production-quality trainee solution, do not depend on parsing free-form LLM text.

Instead, define:

class DuplicateResult(BaseModel):    status: str    issue_number: int | None    confidence: float    reason: str

Then ask the LLM to return structured output.

Conceptually:

{
    "status": "DUPLICATE",
    "issue_number": 9321,
    "confidence": 0.91,
    "reason": "Both issues describe pods remaining unavailable after unexpected termination."
}

This directly follows the structured-output requirement in the problem statement. Pasted markdown


32. Important Improvement – Incremental Synchronization

The first version above demonstrates ingestion, but the complete project also requires incremental synchronization.

Create:

data/sync_state.json

Conceptually:

{
    "last_sync_time": "2026-10-06T08:00:00Z",

    "issues": {
        "9321": {
            "updated_at": "2026-10-05T10:20:00Z",
            "content_hash": "abc123"
        }
    }
}

During the next synchronization:

GitHub Issue
     |
     v
Existing?
   /   \
 No     Yes
 |       |
Insert   updated_at/hash changed?
         /        \
       No          Yes
       |            |
     Ignore       Re-index

This avoids unnecessary embedding generation and duplicate vector insertion. Pasted markdown


33. Complete End-to-End Flow

After all components are implemented, the complete system becomes:

                    GITHUB
                      |
                      v
              GitHub API / CLI
                      |
                      v
               Issue Collector
                      |
                      v
                 issues.json
                      |
                      v
                 Normalize
                      |
                      v
                Embeddings
                      |
                      v
                CHROMA DB
                      |
                      |
                      |
USER ----------------+
 |
 v
Issue Intake
 |
 v
Language Agent
 |
 +---- Errors ----> Correction
 |
 v
Refinement Agent
 |
 v
Query Embedding
 |
 v
Vector Search
 |
 v
Top 10 Candidates
 |
 v
Duplicate Analysis Agent
 |
 v
Decision Node
 |
 +--------------------+--------------------+
 |                    |                    |
 v                    v                    v
DUPLICATE       POSSIBLE_DUPLICATE    READY_TO_PUBLISH

This represents the offline and online data flow defined in the source problem statement. Pasted markdown


34. What, Why and How – Project Summary

ComponentWhat?Why?How?
GitHub APIGets historical issuesNeed knowledge baseREST API
issues.jsonStores normalized issuesLocal source datasetJSON
SynchronizerFinds changesAvoid reprocessingID + timestamp + hash
Embedding ModelText → vectorSemantic searchOllama
ChromaStores vectorsFast similarity retrievalVector DB
Language AgentChecks languageImprove input qualityQwen
Refinement AgentCreates technical reportStandardize issueQwen
RetrieverFinds candidatesReduce search spaceChroma
Duplicate AgentReasons about duplicatesSimilarity alone isn't enoughQwen
LangGraphControls workflowState + routing + agentsGraph
Decision NodeProduces final recommendationBusiness outcomeConditional logic

35. Most Important Viva Explanation

If asked:

"Why is this an Agentic AI project and not just an RAG chatbot?"

A good answer is:

This system combines an LLM, tools, RAG, persistent knowledge, shared state, multiple specialized agents and conditional workflow routing. The Language Agent handles language correction, the Refinement Agent creates a technical report, the RAG tool retrieves historical GitHub issues, and the Duplicate Analysis Agent reasons over those candidates before the Decision Node produces the final recommendation.

The source explicitly describes the project as demonstrating LLM + Tools + RAG + Persistent Knowledge + State + Conditional Routing + Agentic Workflow. Pasted markdown


36. One Critical Correction to Keep in the Final Implementation

The similarity score should not directly produce:

0.91 → DUPLICATE

Instead:

                    New Issue
                       |
                       v
                 Embedding
                       |
                       v
                 Vector Search
                       |
                       v
              Top 5–10 Candidates
                       |
                       v
            Duplicate Analysis Agent
                       |
             +---------+---------+
             |         |         |
             v         v         v
         DUPLICATE  POSSIBLE   NOT DUPLICATE
                       |
                       v
                Final Decision

That distinction is the core RAG + Agentic AI design principle of this assignment. Pasted markdown


Recommended implementation sequence for trainees

Do not try to build the whole project at once. Implement and demonstrate it in these stages:

Stage 1  → GitHub API + issues.json
Stage 2  → Incremental synchronization
Stage 3  → Embedding generation
Stage 4  → Chroma vector database
Stage 5  → Semantic search
Stage 6  → Language Agent
Stage 7  → Refinement Agent
Stage 8  → Duplicate Analysis Agent
Stage 9  → LangGraph state/workflow
Stage 10 → Final DUPLICATE / POSSIBLE_DUPLICATE / READY_TO_PUBLISH
Stage 11 → Automated tests
Stage 12 → Optional FastAPI/Streamlit UI

This staged approach makes it much easier for trainees to understand what each component does, why it is required, and how it contributes to the final Agentic AI system.

Thursday, October 1, 2026

FTP vs PSFTP

 

FTP vs PSFTP

These are two different things — one is a protocol, the other is a specific program — so the comparison works a bit like comparing "email" to "Outlook."

FTP (File Transfer Protocol)

  • A protocol (a set of rules) for transferring files between a client and a server over a network.
  • Sends data, usernames, and passwords in plain text — unencrypted. Anyone intercepting the traffic can read your credentials and file contents.
  • Uses two separate connections: one for commands, one for data.
  • Accessed via a client program — on Windows/Linux/Mac, often just the built-in ftp command, or graphical tools like FileZilla.
  • Still used in some legacy systems, but considered insecure for anything sensitive over the open internet.

PSFTP (PuTTY SFTP client)

  • Not a protocol — it's a specific program, part of the PuTTY suite of tools (alongside PuTTY itself, PSCP, Plink, etc.), built by Simon Tatham for Windows (and available on Unix-like systems too).
  • PSFTP implements SFTP (SSH File Transfer Protocol), which is a completely different protocol from FTP, despite the similar name.
  • SFTP runs over SSH (Secure Shell), so everything — commands, filenames, file contents, login credentials — is encrypted.
  • Uses a single secure connection (unlike FTP's two-connection setup).
  • Typically used to connect to Unix/Linux servers that accept SSH connections.

Quick comparison

FTPPSFTP (SFTP)
TypeProtocolProgram (implements the SFTP protocol)
SecurityUnencryptedEncrypted (via SSH)
Port21 (commands), 20 (data)22 (same as SSH)
Typical clientftp command, FileZillapsftp command (PuTTY suite)
RiskPasswords/data visible if interceptedProtected by SSH encryption

Why this matters for your lab

If your Unix server only accepts SSH connections (common for university lab servers), the plain ftp command from your earlier steps may simply fail to connect, because the server isn't running an FTP service at all — it's running SSH/SFTP instead. In that case, PSFTP (or an SFTP-capable client like WinSCP or FileZilla's SFTP mode) is the one that will actually work.

If ftp <server_address> connected successfully in your earlier task, the server does support plain FTP, so you're fine as-is. If it timed out or refused the connection, try psftp <server_address> instead — the commands inside (cd, ls, get, mget, bye) are almost identical to what you already used.

Monday, April 13, 2026

 

📘 Introduction to C#

✅ What is C#?

C# (C-Sharp) is a modern, object-oriented programming language developed by Microsoft.

👉 It is mainly used to build:

  • Desktop applications
  • Web applications
  • APIs
  • Enterprise software

✅ Why use C#?

  • ✔ Simple and easy to learn
  • ✔ Strongly typed (reduces errors)
  • ✔ Supports Object-Oriented Programming (OOP)
  • ✔ Works well with .NET ecosystem
  • ✔ Widely used in industry

❌ Why NOT use C#?

  • ❌ Not ideal for low-level system programming (like OS/kernel)
  • ❌ Requires .NET runtime
  • ❌ Less popular than JavaScript for frontend

✅ How C# Works (Basic Flow)

  1. Write code in .cs file
  2. Compile using .NET compiler
  3. Run → Output shown in console/app

📘 Core Concepts Explained


1️⃣ namespace

✅ What

A namespace is a container for classes.

✅ Why

  • Avoids naming conflicts
  • Organizes code

✅ Example

namespace MyApp
{
}

2️⃣ internal

✅ What

An access modifier.

✅ Why

  • Restricts access within the same project only

❌ Why not public?

  • public exposes it everywhere (less secure)

3️⃣ class

✅ What

A blueprint for creating objects.

✅ Why

  • Groups data and methods together

4️⃣ object

✅ What

Instance of a class.

✅ Why

  • Used to access class properties and methods

5️⃣ static

✅ What

Belongs to class, not object.

✅ Why

  • No need to create object to access it

6️⃣ void

✅ What

Method returns nothing.

✅ Why

  • Used when no return value is needed

7️⃣ string[]

✅ What

Array of strings.

✅ Why

  • Used to store multiple values
  • In Main, it stores command-line arguments

8️⃣ Console.WriteLine()

✅ What

Prints output to console.

✅ Why

  • Used for displaying messages

9️⃣ Console.ReadKey()

✅ What

Waits for a key press.

✅ Why

  • Prevents console from closing immediately

💡 Real-Time Example (Beginner Friendly)

👉 Scenario: Display employee details in console


✅ Full Program with Comments

// Namespace: groups related classes
namespace CompanyApp
{
// internal: accessible only within this project
internal class Employee
{
// Member variables
string _name;
int _age;

// Method to set values
public void SetDetails(string name, int age)
{
_name = name;
_age = age;
}

// Method to display values
public void Display()
{
Console.WriteLine("Employee Name: " + _name);
Console.WriteLine("Employee Age: " + _age);
}
}

internal class Program
{
// Entry point of program
static void Main(string[] args) // string[] stores command-line inputs
{
// Creating object of Employee class
Employee emp = new Employee();

// Setting values
emp.SetDetails("Rahul", 25);

// Displaying output
emp.Display();

// Static method call (no object needed)
Console.WriteLine("Press any key to exit...");

// Wait for user input
Console.ReadKey();
}
}
}

🔄 Flow of Above Program

  1. Program starts → Main()
  2. Object emp is created
  3. Data is assigned using method
  4. Data is displayed
  5. Message printed
  6. Program waits for key press

🎯 Key Takeaways

  • namespace → organizes code
  • internal → restricts access
  • class → blueprint
  • object → real instance
  • static → no object required
  • void → no return
  • string[] args → input arguments
  • Console.WriteLine() → output
  • Console.ReadKey() → pause

✅ One-Line Summary

👉 C# is an object-oriented language where programs are built using classes, objects, and methods, and executed starting from the Main() method.

Monday, March 9, 2026

PYTHON

 

PART 1: PYTHON FUNDAMENTALS

1. INTRODUCTION TO PYTHON

📖 What is Python?

Python is a high-level, interpreted programming language created by Guido van Rossum and first released in 1991 . It is designed with a philosophy that emphasizes code readability through significant whitespace and a straightforward syntax that resembles natural English.

python
# This is Python - clean and readable
print("Hello, World!")  # Simple, right?

🎯 Why Learn Python?

ReasonExplanation
Readable SyntaxCode looks almost like natural English, making it easier to learn and maintain 
Versatile ApplicationsWeb development, data science, automation, AI/ML, and more 
Rich EcosystemExtensive standard library and thousands of third-party packages 
Cross-platformRuns on Windows, macOS, Linux, and many other platforms 
Strong CommunityExcellent documentation, tutorials, and community support 
Rapid DevelopmentFaster to write and maintain than many other languages 

🛠️ How to Set Up Python

Windows Installation

bash
# 1. Download from python.org
# 2. Run installer - IMPORTANT: Check "Add Python to PATH"
# 3. Verify installation
python --version

macOS Installation

bash
# Using Homebrew (recommended)
brew install python

# Verify
python3 --version

Linux Installation (Ubuntu/Debian)

bash
sudo apt update
sudo apt install python3 python3-pip python3-venv
python3 --version

📝 Your First Python Program

Create a file called hello.py:

python
#!/usr/bin/env python3
"""
My First Python Program
This demonstrates basic Python syntax and structure
"""

# This is a comment - it's ignored by Python

# Get user input
name = input("What is your name? ")

# Create a greeting
greeting = f"Hello, {name}! Welcome to Python programming."

# Display the greeting
print(greeting)

# Show current year
year = 2026
print(f"The year is {year}")

Run it:

bash
python3 hello.py


PRACTICE QUESTIONS

To find the solution in Python