{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9f97dd1e",
   "metadata": {},
   "source": [
    "# Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "9e974df6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import TypedDict, List, Annotated\n",
    "from IPython.display import Image, display\n",
    "\n",
    "from langchain_core.documents import Document\n",
    "from langchain_core.messages import SystemMessage\n",
    "from langgraph.graph.message import add_messages\n",
    "from langchain_elasticsearch import ElasticsearchStore\n",
    "from langgraph.graph import StateGraph, END\n",
    "\n",
    "from src.utils.llm_factory import create_chat_model\n",
    "from src.utils.emb_factory import create_embedding_model\n",
    "from src.config import (\n",
    "    ELASTICSEARCH_LOCAL_URL,\n",
    "    ELASTICSEARCH_INDEX,\n",
    "    OLLAMA_LOCAL_URL,\n",
    "    OLLAMA_MODEL_NAME,\n",
    "    OLLAMA_EMB_MODEL_NAME\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8eb6506",
   "metadata": {},
   "source": [
    "### Create instances"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "30edcecc",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = create_chat_model(\n",
    "    provider=\"ollama\",\n",
    "    model=OLLAMA_MODEL_NAME,\n",
    "    base_url=OLLAMA_LOCAL_URL,\n",
    "    temperature=0,\n",
    "    validate_model_on_init=True,\n",
    ")\n",
    "embeddings = create_embedding_model(\n",
    "    provider=\"ollama\",\n",
    "    model=OLLAMA_EMB_MODEL_NAME,\n",
    "    base_url=OLLAMA_LOCAL_URL,\n",
    ")\n",
    "vector_store = ElasticsearchStore(\n",
    "    es_url=ELASTICSEARCH_LOCAL_URL,\n",
    "    index_name=ELASTICSEARCH_INDEX,\n",
    "    embedding=embeddings,\n",
    "    query_field=\"text\",\n",
    "    vector_query_field=\"vector\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "50b71d45",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LLM:  qwen2.5:1.5b\n",
      "Embeddings:  qwen3-0.6B-emb:latest\n"
     ]
    }
   ],
   "source": [
    "print(\"LLM: \", llm.model)\n",
    "print(\"Embeddings: \", embeddings.model)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "873ea2f6",
   "metadata": {},
   "source": [
    "### State"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5f8c88cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "class AgentState(TypedDict):\n",
    "    messages: Annotated[list, add_messages]\n",
    "    reformulated_query: str\n",
    "    context: str"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "395966e2",
   "metadata": {},
   "source": [
    "### Prompts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "66ae23f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "REFORMULATE_PROMPT = SystemMessage(\n",
    "    content=(\n",
    "        \"You are a deterministic lexical query rewriter used for vector retrieval.\\n\"\n",
    "        \"Your task is to rewrite user questions into optimized keyword search queries.\\n\\n\"\n",
    "\n",
    "        \"CRITICAL RULES (ABSOLUTE):\\n\"\n",
    "        \"1. NEVER answer the question.\\n\"\n",
    "        \"2. NEVER expand acronyms.\\n\"\n",
    "        \"3. NEVER introduce new terms not present in the original query.\\n\"\n",
    "        \"4. NEVER infer missing information.\\n\"\n",
    "        \"5. NEVER add explanations, definitions, or interpretations.\\n\"\n",
    "        \"6. Preserve all technical tokens exactly as written.\\n\"\n",
    "        \"7. Only remove filler words (e.g., what, does, is, explain, tell me, please).\\n\"\n",
    "        \"8. You may reorder terms for better retrieval.\\n\"\n",
    "        \"9. Output must be a single-line plain keyword query.\\n\"\n",
    "        \"10. If the query is already optimal, return it unchanged.\\n\\n\"\n",
    "        \"11. If you receive something that looks like code, do NOT attempt to rewrite it. Return it verbatim.\\n\\n\"\n",
    "\n",
    "        \"ALLOWED OPERATIONS:\\n\"\n",
    "        \"- Remove interrogative phrasing.\\n\"\n",
    "        \"- Remove stopwords.\\n\"\n",
    "        \"- Reorder words.\\n\"\n",
    "        \"- Convert to noun phrase form.\\n\\n\"\n",
    "\n",
    "        \"FORBIDDEN OPERATIONS:\\n\"\n",
    "        \"- Expanding abbreviations.\\n\"\n",
    "        \"- Paraphrasing into unseen vocabulary.\\n\"\n",
    "        \"- Adding definitions.\\n\"\n",
    "        \"- Answering implicitly.\\n\\n\"\n",
    "\n",
    "        \"Examples:\\n\"\n",
    "        \"Input: What does AVAP stand for?\\n\"\n",
    "        \"Output: AVAP stand for\\n\"\n",
    "\n",
    "        \"Input: Hey, I'm trying to understand how AVAP handels a ZeroDivisionError when doing divison or modulus operatoins. Can you explane what situatoins cause a ZeroDivisionError to be raised and how I can catch it in my AVAP scripts?\\n\"\n",
    "        \"Output: AVAP ZeroDivisionError division / modulus % catch try except\\n\"\n",
    "        \n",
    "        \"Input: What does AVAP stand for?\\n\"\n",
    "        \"Output: AVAP stand for\\n\"\n",
    "\n",
    "        \"Input: Please explain how the import statement works in AVAP scripts.\\n\"\n",
    "        \"Output: AVAP import statement syntax behavior\\n\\n\"\n",
    "\n",
    "        \"Return only the rewritten query.\"\n",
    "    )\n",
    ")\n",
    "\n",
    "GENERATE_PROMPT = SystemMessage(\n",
    "    content=(\n",
    "        \"\"\"You are a retrieval-grounded assistant.\n",
    "\n",
    "        CRITICAL SCOPE RULES\n",
    "        - AVAP (Advanced Virtual API Programming) is a new/unknown programming language.\n",
    "        - If the user message is AVAP-related (explicitly mentions \"AVAP\" case-insensitive OR the provided context is AVAP code/docs), you MUST answer using ONLY <CONTEXT>.\n",
    "        - You MUST NOT use general programming knowledge to interpret AVAP.\n",
    "        - You MUST NOT assume AVAP behaves like any other language even if syntax looks similar.\n",
    "        - You MUST NOT infer missing details. Only state what is explicitly present in <CONTEXT>.\n",
    "\n",
    "        GROUNDING REQUIREMENTS (AVAP-RELATED)\n",
    "        1) Every non-trivial factual claim MUST be directly supported by an EXACT QUOTE from <CONTEXT>.\n",
    "        2) If a claim is not supported by a quote, DO NOT include it.\n",
    "        3) If <CONTEXT> does not contain enough information to answer, reply with EXACTLY:\n",
    "        \"I don't have enough information in the provided context to answer that.\"\n",
    "\n",
    "        WORKFLOW (AVAP-RELATED) — FOLLOW IN ORDER\n",
    "        A) Identify the specific question(s) being asked.\n",
    "        B) Extract the minimum necessary quotes from <CONTEXT> that answer those question(s).\n",
    "        C) Write the answer using ONLY those quotes (paraphrase is allowed, but every statement must be backed by at least one quote).\n",
    "        D) Verify: for EACH sentence in your answer, confirm there is a supporting quote. If any sentence lacks a quote, delete it or refuse.\n",
    "\n",
    "        OUTPUT FORMAT (AVAP-RELATED ONLY)\n",
    "        Answer:\n",
    "        <short, direct answer; no extra speculation; no unrelated tips>\n",
    "\n",
    "        Evidence:\n",
    "        - \"<exact quote 1>\"\n",
    "        - \"<exact quote 2>\"\n",
    "        (Include only quotes you actually used. Prefer the smallest quotes that fully support the statements.)\n",
    "\n",
    "        NON-AVAP QUESTIONS\n",
    "        - If the question is clearly not AVAP-related, answer normally using general knowledge.\n",
    "\n",
    "        <CONTEXT>\n",
    "        {context}\n",
    "        </CONTEXT>\"\"\"\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15780588",
   "metadata": {},
   "source": [
    "### Build graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "100246d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "retrieve_kwargs = {\n",
    "    \"k\": 3\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "36d0f54e",
   "metadata": {},
   "outputs": [],
   "source": [
    "def format_context(docs: List[Document]) -> str:\n",
    "    chunks: List[str] = []\n",
    "    for i, doc in enumerate(docs, 1):\n",
    "        source = (doc.metadata or {}).get(\"source\", \"Untitled\")\n",
    "        source_id = (doc.metadata or {}).get(\"id\", f\"chunk-{i}\")\n",
    "        text = doc.page_content or \"\"\n",
    "        chunks.append(f\"[{i}] id={source_id} source={source}\\n{text}\")\n",
    "    return \"\\n\\n\".join(chunks)\n",
    "\n",
    "def reformulate(state: AgentState) -> AgentState:\n",
    "    \"\"\"Use the LLM to rewrite the user query for better retrieval.\"\"\"\n",
    "    user_msg = state[\"messages\"][-1]\n",
    "    resp = llm.invoke([REFORMULATE_PROMPT, user_msg])\n",
    "    reformulated = resp.content.strip()\n",
    "    print(f\"[reformulate] '{user_msg.content}' → '{reformulated}'\")\n",
    "    return {\"reformulated_query\": reformulated}\n",
    "\n",
    "\n",
    "def retrieve(state: AgentState) -> AgentState:\n",
    "    \"\"\"Retrieve context using the reformulated query.\"\"\"\n",
    "    query = state[\"reformulated_query\"]\n",
    "    docs = vector_store.as_retriever(\n",
    "        search_type=\"similarity\",\n",
    "        search_kwargs=retrieve_kwargs,\n",
    "    ).invoke(query)\n",
    "    context = format_context(docs)\n",
    "    print(f\"[retrieve] {len(docs)} docs fetched\")\n",
    "    print(context)\n",
    "    return {\"context\": context}\n",
    "\n",
    "\n",
    "def generate(state: AgentState) -> AgentState:\n",
    "    \"\"\"Generate the final answer using retrieved context.\"\"\"\n",
    "    prompt = SystemMessage(\n",
    "        content=GENERATE_PROMPT.content.format(context=state[\"context\"])\n",
    "    )\n",
    "    resp = llm.invoke([prompt] + state[\"messages\"])\n",
    "    return {\"messages\": [resp]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fae46a58",
   "metadata": {},
   "outputs": [],
   "source": [
    "graph_builder = StateGraph(AgentState)\n",
    "\n",
    "graph_builder.add_node(\"reformulate\", reformulate)\n",
    "graph_builder.add_node(\"retrieve\", retrieve)\n",
    "graph_builder.add_node(\"generate\", generate)\n",
    "\n",
    "graph_builder.set_entry_point(\"reformulate\")\n",
    "graph_builder.add_edge(\"reformulate\", \"retrieve\")\n",
    "graph_builder.add_edge(\"retrieve\", \"generate\")\n",
    "graph_builder.add_edge(\"generate\", END)\n",
    "\n",
    "graph = graph_builder.compile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7f57b543",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14976 characters]",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "try:\n",
    "    display(Image(graph.get_graph().draw_mermaid_png()))\n",
    "except Exception:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e9aff05",
   "metadata": {},
   "source": [
    "### Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8569cf39",
   "metadata": {},
   "outputs": [],
   "source": [
    "def stream_graph_updates(user_input: str, graph: StateGraph):\n",
    "    for event in graph.stream(\n",
    "        {\"messages\": [{\"role\": \"user\", \"content\": user_input}]},\n",
    "        stream_mode=\"values\",\n",
    "    ):\n",
    "        event[\"messages\"][-1].pretty_print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a1a1f3cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "user_input = \"\"\"Whats AVAP?\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "53b89690",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "Whats AVAP?\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[reformulate] 'Whats AVAP?' → 'AVAP is an acronym.'\n",
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "Whats AVAP?\n",
      "[retrieve] 3 docs fetched\n",
      "[1] id=chunk-1 source=1_Introduction.txt\n",
      "Introduction Discovering a New Programming Language Welcome to the AVAP book, where you will delve into the fascinating world of an innovative and powerful programming language: AVAP™. In these pages, we will explore together the fundamental concepts, syntax, and unique features of AVAP™, and prepare you to master this new language and harness its full potential in your software development projects. Discovering AVAP AVAP™ is much more than just a programming language; it is a versatile tool designed to enhance creativity and efficiency in software development. With its clear and expressive syntax, AVAP™ allows developers to write code more quickly and concisely, without sacrificing the power and flexibility needed to create robust and scalable applications. What Makes AVAP Special? AVAP™ stands out due to several distinctive features that make it unique in the programming world: Integrated Virtualization: AVAP™ is designed from the ground up with the concept of virtualization in mind. Every aspect of the language is optimized to work in virtual environments, allowing developers to create immersive and scalable experiences. Powerful APIs: AVAP™ provides a comprehensive set of tools for interacting with external APIs and web services, making it easier to integrate advanced functionalities into your applications. Enhanced Productivity: With an intuitive syntax and advanced abstraction features, AVAP™ allows you to write less code to achieve more, thereby increasing your productivity and accelerating development time. What Will You Find in This Book? In this book, we will guide you through the basic and advanced concepts of AVAP™, providing practical examples, useful tips, and challenging exercises to help you master the language and become an expert AVAP™ developer. From installing and configuring the development environment to creating complete applications, this book will accompany you every step of the way towards mastering AVAP™. Are You Ready to Get Started? Then let’s not wait any longer! Dive into the pages of this book and get ready to embark on an exciting journey towards mastering AVAP™. Whether you are an experienced programmer looking for new tools or a curious beginner in the world of programming, this book has something for you. Let’s explore the fascinating world of AVAP™ together! The Virtuality Attribute in AVAP™ AVAP™ (Advance Virtual API Programming) is a dynamic programming language distinguished by its virtuality attribute, which enables the development of virtual APIs in a dynamic and flexible manner. This attribute is based on the fact that the language specifications do not reside in the language interpreter, allowing the final code to be constructed in real-time by the language server. 1.1 Virtuality Principle in AVAP The principle of virtuality in AVAP™ is based on several key aspects: 1.1.1 Language Specifications Decoupled from the Interpreter In AVAP™, language specifications are not compiled into the core of the language nor do they reside in the interpreter. This means that the interpreter is not tied to a specific implementation of the language, providing great flexibility and adaptability in code interpretation. 1.1.2 Dynamic Code Construction in Real-Time Thanks to the virtuality attribute, AVAP™ allows for dynamic code construction in real-time. This means that the final code to be interpreted by the language server can vary and mutate according to current needs, without the need for recompilation or redistribution. 1.1.3 Development of Dynamic Virtual APIs The virtuality attribute in AVAP™ enables the development of virtual APIs in a dynamic manner. This allows APIs to evolve, improve, and adapt to new security or functional needs in real-time, without affecting the clients utilizing the API endpoint. 1.2 Benefits of the Virtuality Attribute Flexibility: The ability to construct code in real-time provides significant flexibility in API development and management. Agility: The capacity to adapt and evolve without the need for precompilation or distributed updates allows for greater agility in software development. Simplified Maintenance: The development of dynamic virtual APIs simplifies the maintenance process, as changes do not need to be made to clients consuming those APIs. 1.3 Interaction with Artificial Intelligence One of the most innovative features of this language is its integration with artificial intelligence through OpenAI. This integration allows the language to automatically generate the necessary results through an interface with OpenAI once the programmer has a clear solution to a problem. This functionality not only speeds up development but also reduces the margin of error and improves efficiency. 1.4 Access to Databases The language also includes the capability to interact with databases using natural language, supported by artificial intelligence, currently version XXXXX through OpenAI. This feature allows for complex queries and data manipulation without deep knowledge of SQL, simplifying development and improving accessibility for programmers of all levels. With this guide, we hope to provide you with all the necessary information to make the most of this dynamic language's capabilities. From variable management to automated result generation and simplified database access, this language is designed to transform the way you develop APIs. 1.5 Conclusions The virtuality attribute in AVAP™ represents an innovative approach to virtual API development, allowing for greater flexibility, agility, and simplification in the software development and maintenance process. By decoupling language specifications from the interpreter and enabling dynamic code construction in real-time, AVAP™ offers a new paradigm in API design and management.\n",
      "\n",
      "[2] id=chunk-2 source=3_Notation.txt\n",
      "Chapter 2: Notation in AVAP™ Introduction Notation in AVAP™ refers to the conventions and rules used to write and format code in the AVAP™ programming language. Notation is essential to ensure code readability and comprehension, as well as to establish a coherent and consistent syntax across all projects. General Conventions In AVAP™, several general notation conventions are followed, similar to those used in other programming languages like Python. Some of these conventions include: Indentation: Code is structured through indentation, using white spaces or tabs to indicate the hierarchy and structure of the code. It is recommended to use four spaces for each level of indentation. Case Sensitivity: AVAP™ is case-sensitive, meaning that identifiers, variable names, and keywords must be consistently written using the same capitalization format throughout the code. Comments: Comments are used to document the code and explain its functionality. Single-line comments begin with the // symbol, while multi-line comments start with /* and end with */. Specific Notation Rules In addition to general conventions, AVAP™ follows specific notation rules for different elements of the language, including: Variables: Variable names should be descriptive and meaningful, using lowercase letters and underscores to separate words if necessary for readability (e.g., variable_name). Functions: Function names should follow the same conventions as variables, with the addition of parentheses to indicate function parameters (e.g., function_name(parameter1, parameter2)). Constants: Constants are typically written in uppercase letters with underscores separating words (e.g., EXAMPLE_CONSTANT). The descriptions of lexical analysis and syntax use a modified Backus–Naur form (BNF) grammar notation. This uses the following style of definition: <program> ::= <statement_list> <statement_list> ::= <statement> | <statement> <statement_list> <statement> ::= <global_assignment> | <local_assignment> | <command> <global_assignment> ::= \"addVar(\" <string_value> \",\" <variable_name> \")\" <local_assignment> ::= <variable_name> \"=\" <value> <string_value> ::= \"\"\" <string_content> \"\"\" <string_content> ::= <string_part> | <string_part> <string_content> <string_part> ::= <text> | <variable_reference> <text> ::= <character> | <character> <text> <variable_reference> ::= \" <variable_name> \" <variable_name> ::= <letter> | <letter> <variable_name> <value> ::= <string_value> | <number> | <expression> <number> ::= <digit> | <digit> <number> <expression> ::= <value> | <value> <operator> <value> <operator> ::= \"+\" | \"-\" | \"*\" | \"/\" <command> ::= <any_valid_command_syntax> <character> ::= any character except `\" ` and `\\` <letter> ::= \"a\" | \"b\" | \"c\" | \"d\" | \"e\" | \"f\" | \"g\" | \"h\" | \"i\" | \"j\" | \"k\" | \"l\" | \"m\" | \"n\" | \"o\" | \"p\" | \"q\" | \"r\" | \"s\" | \"t\" | \"u\" | \"v\" | \"w\" | \"x\" | \"y\" | \"z\" | \"A\" | \"B\" | \"C\" | \"D\" | \"E\" | \"F\" | \"G\" | \"H\" | \"I\" | \"J\" | \"K\" | \"L\" | \"M\" | \"N\" | \"O\" | \"P\" | \"Q\" | \"R\" | \"S\" | \"T\" | \"U\" | \"V\" | \"W\" | \"X\" | \"Y\" | \"Z\" | \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\" | \"_\" <digit> ::= \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\" Explanation: <program>: A program is a list of statements. <statement_list>: A list of statements can be a single statement or a statement followed by another list of statements. <statement>: A statement can be a global assignment, a local assignment, or a command. <global_assignment>: A global assignment follows the format addVar('value', variable_name). <local_assignment>: A local assignment follows the Python syntax variable_name = value. <string_value>: A string value is enclosed in double quotes and contains string content. <string_content>: The content of a string can be a string part or a string part followed by more string content. <string_part>: A string part can be literal text or a variable reference. <text>: Text is a series of characters. <variable_reference>: A variable reference follows the format $ variable . <variable_name>: A variable name can be a letter or a combination of letters. <value>: A value can be a string value, a number, or an expression. <number>: A number can be a digit or a series of digits. <expression>: An expression can be a value or a combination of two values with an operator. <operator>: An operator can be +, -, *, or /. <command>: A command can be any valid command syntax. <character>: A character can be any character except double quotes and the backslash. <letter>: A letter can be an alphabetical character, a digit, or an underscore. <digit>: A digit is a number from 0 to 9. This BNF notation covers the assignment of global and local variables, as well as variable substitution in strings. Practical Example // Definition of a variable example_variable = 10 // Definition of a function example_function(parameter): // Function body result = parameter * 2 return result // Function call result = example_function(example_variable) In this example, notation conventions are used to define a variable, a function, and to call the function with a parameter. Conclusions Notation in AVAP™ is a fundamental part of software development in the language. By following clear and consistent notation conventions, developers can write and maintain code more effectively, contributing to the readability, understanding, and maintainability of the code in projects of any size and complexity. With this understanding of notation in AVAP™, developers can write clean and structured code that is easy to understand and maintain over time.\n",
      "\n",
      "[3] id=chunk-3 source=10.1_Expressions.txt\n",
      "6. Expressions in AVAP This chapter explains the meaning of expression elements in AVAP. 6.1. Arithmetic Conversions When describing an arithmetic operator in AVAP and using the phrase \"numeric arguments are converted to a common type,\" it means that the operator's implementation for built-in types works as follows: If either of the arguments is a complex number, the other is converted to complex. Otherwise, if either of the arguments is a floating-point number, the other is converted to floating-point. Otherwise, both must be integers, and no conversion is needed. Additional rules may apply for certain operators. 6.2. Atoms Atoms are the most basic elements of expressions in AVAP. The simplest atoms are identifiers or literals. Forms enclosed in parentheses, brackets, or braces are also syntactically categorized as atoms. The syntax for atoms is: atom ::= identifier | literal | enclosure enclosure ::= parenth_form | list_display | dict_display | set_display | generator_expression 6.2.1. Identifiers (Names) An identifier that appears as an atom is a name. When the name is bound to an object, evaluating the atom yields that object. When a name is not bound, an attempt to evaluate it raises a NameError exception. Private Name Mangling When an identifier that occurs literally in a class definition begins with two or more underscores and does not end with two or more underscores, it is considered a private name of that class. Private names are transformed into a longer form before code is generated for them. The transformation inserts the class name, with the initial underscores removed and a single underscore inserted, in front of the name. 6.2.2. Literals AVAP supports string and bytes literals, as well as various numeric literals: literal ::= stringliteral | bytesliteral | integer | floatnumber | imagnumber Evaluating a literal produces an object of the given type (string, bytes, integer, floating-point number, complex number) with the given value. All literals correspond to immutable data types. 6.2.3. Parenthesized Forms A parenthesized form is an optional list of expressions enclosed in parentheses: parenth_form ::= \"(\" [starred_expression] \")\" A parenthesized expression produces whatever the expression list produces: if the list contains at least one comma, it produces a tuple; otherwise, it produces the single expression that makes up the list of expressions. 6.2.4. Comprehensions for Lists, Sets and Dictionaries To construct a list, set, or dictionary, AVAP provides special syntax called \"comprehension,\" each in two flavors: The contents of the container are listed explicitly. They are computed using a set of loop and filtering instructions, called a \"comprehension.\" Common syntax elements for comprehensions are: comprehension ::= assignment_expression comp_for comp_for ::= \"for\" target_list \"in\" or_test [comp_iter] comp_iter ::= comp_for | comp_if comp_if ::= \"if\" or_test [comp_iter] A comprehension consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new container are those produced by considering each for or if clause as a block, nested from left to right, and evaluating the expression to produce an element each time the innermost block is reached. 6.2.5. List Displays In AVAP, lists are generated and handled differently. To construct a list, the command variableToList(variable, list) is used, and an item from the list is retrieved with itemFromList(list, index, variable_to_store_item). To get the number of elements in the list, getListLen(list, var_to_store_list_length) is used. The syntax for list displays is: list_display ::= \"[\" [starred_list | comprehension] \"]\" A list display produces a new list object, whose content is specified by a list of expressions or a comprehension. When a list of expressions is provided, its elements are evaluated from left to right and placed in the list object in that order. 6.2.6. Set Displays A set display is denoted by curly braces and is distinguished from dictionary displays by the absence of colon characters separating keys and values: set_display ::= \"{\" (starred_list | comprehension) \"}\" A set display produces a new mutable set object, whose content is specified by a sequence of expressions or a comprehension. 6.2.7. Dictionary Displays In AVAP, objects are created and managed using specific commands. An object is created with AddvariableToJSON(key, value, object_variable), and a key from the object is retrieved with variableFromJSON(object_variable, key, var_to_store_key_value). The syntax for dictionary displays is: dict_display ::= \"{\" [dict_item_list | dict_comprehension] \"}\" dict_item_list ::= dict_item (\",\" dict_item)* [\",\"] dict_item ::= expression \":\" expression | \"**\" or_expr dict_comprehension ::= expression \":\" expression comp_for A dictionary display produces a new dictionary object. If a comma-separated sequence of dictionary items is provided, they are evaluated from left to right to define the dictionary entries. Slices A slice selects a range of elements in a sequence object (e.g., a string, tuple, or list). Slices can be used as expressions or as targets in assignments or statements. The syntax for a slice is as follows: slicing ::= primary \"[\" slice_list \"]\" slice_list ::= slice_item (\",\" slice_item)* [\",\"] slice_item ::= expression | proper_slice proper_slice ::= [lower_bound] \":\" [upper_bound] [ \":\" [stride] ] lower_bound ::= expression upper_bound ::= expression stride ::= expression There is ambiguity in the formal syntax here: anything that looks like a list expression also looks like a list slice, so any subscription might be interpreted as a slice. Instead of complicating the syntax further, this is disambiguated by defining that in this case, the interpretation as a subscription takes precedence over the interpretation as a slice (this is the case if the list slice does not contain a proper slice). The semantics for a slice are as follows. The primary is indexed (using the same __getitem__() method as in a normal subscription) with a key constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple that contains the conversion of the slice elements; otherwise, the conversion of the single slice element is the key. The conversion of a slice element that is an expression is that expression. The conversion of a proper slice is a slice object whose start, stop, and step attributes are the values of the expressions given as the lower bound, upper bound, and step, respectively, substituting None for missing expressions. Calls A call invokes a callable object (e.g., a function) with a possibly empty series of arguments: call ::= primary \"(\" [argument_list [\",\"] | comprehension] \")\" argument_list ::= positional_arguments [\",\" starred_and_keywords] [\",\" keywords_arguments] | starred_and_keywords [\",\" keywords_arguments] | keywords_arguments positional_arguments ::= positional_item (\",\" positional_item)* positional_item ::= assignment_expression | \"*\" expression starred_and_keywords ::= (\"*\" expression | keyword_item) (\",\" \"*\" expression | \",\" keyword_item)* keywords_arguments ::= (keyword_item | \"**\" expression) (\",\" keyword_item | \",\" \"**\" expression)* keyword_item ::= identifier \"=\" expression An optional trailing comma may be present after positional and keyword arguments but does not affect the semantics. The primary must evaluate to a callable object (user-defined functions, built-in functions, built-in object methods, class objects, class instance methods, and any object with a __call__() method are callable). All argument expressions are evaluated before attempting the call. Please refer to the Function Definitions section for the syntax of formal parameter lists. If keyword arguments are present, they are first converted into positional arguments as follows. First, a list of unfilled slots is created for the formal parameters. If there are N positional arguments, they are placed in the first N slots. Then, for each keyword argument, the identifier is used to determine the corresponding slot. If the slot is already filled, a TypeError exception is raised. Otherwise, the argument is placed in the slot, filling it (even if the expression is None, it fills the slot). When all arguments have been processed, any slots that are still empty are filled with the default value from the function definition. If there are unfilled slots for which no default value is specified, a TypeError exception is raised. Otherwise, the list of filled slots is used as the argument list for the call. Implementation Details in AVAP In AVAP, variables are stored as strings, and lists and objects are managed using specific commands: Lists: To generate a list, use variableToList(variable, list). To retrieve an item from the list, use itemFromList(list, index, variable_to_store_item). To get the number of items in the list, use getListLen(list, var_to_store_list_length). Objects (dictionaries): An object is created with AddvariableToJSON(key, value, object_variable). To retrieve a key from the object, use variableFromJSON(object_variable, key, var_to_store_key_value). Usage Example Creation and management of lists: // Creating a list variableToList(\"item1\", \"myList\") variableToList(\"item2\", \"myList\") variableToList(\"item3\", \"myList\") // Retrieving an item from the list itemFromList(\"myList\", 1, \"myVariable\") // Getting the length of the list getListLen(\"myList\", \"listLength\") Creation and management of objects (dictionaries): // Creating an object AddvariableToJSON(\"key1\", \"value1\", \"myObject\") AddvariableToJSON(\"key2\", \"value2\", \"myObject\") // Retrieving a value by key from the object variableFromJSON(\"myObject\", \"key1\", \"myVariable\") In this way, lists and objects in AVAP can be manipulated using the specific functions provided for working with variables stored as strings.\n",
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "Whats AVAP?\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "AVAP is a programming language designed by Microsoft Research. It was created to address some of the limitations of existing languages like Python, JavaScript, and C#. The goal was to create a language that could be used for both web development and desktop applications.\n",
      "\n",
      "Key features of AVAP include:\n",
      "\n",
      "1. **Type System**: It has a more complex type system compared to simpler languages like Python or JavaScript.\n",
      "2. **Built-in Functions**: It includes built-in functions that can perform operations on data structures, similar to how they are done in other programming languages.\n",
      "3. **Syntax and Semantics**: The syntax is designed to be intuitive for developers familiar with C# but also allows for some flexibility.\n",
      "\n",
      "AVAP was intended as a language that could bridge the gap between web development (JavaScript) and desktop applications (C#), providing a more powerful and flexible environment than either alone. However, it never gained widespread adoption due to various reasons including its complexity and lack of community support compared to simpler languages like JavaScript or C#.\n"
     ]
    }
   ],
   "source": [
    "stream_graph_updates(user_input, graph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3dda5f99",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "assistance-engine",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
