Add BEIR analysis notebooks and evaluation pipeline for embedding models

- Created `n00 Beir Analysis_cosqa.ipynb` for analyzing CoSQA dataset with BEIR.
- Created `n00 first Analysis.ipynb` for initial analysis with embeddings.
- Implemented `evaluate_embeddings_pipeline.py` to evaluate embedding models across CodexGlue, CoSQA, and SciFact benchmarks.
- Added adapters for Ollama and HuggingFace embeddings to ensure compatibility with BEIR.
- Enhanced error handling and data normalization in embedding processes.
- Included functionality to load datasets from local cache or download if not present.
This commit is contained in:
pseco 2026-03-26 09:37:37 +01:00
parent 0d2cdd2190
commit 1ee5f21c7c
12 changed files with 1837 additions and 85 deletions

View File

@ -0,0 +1,832 @@
[
{
"id": "avap_q1",
"question": "What type of language is AVAP and what is it primarily designed for?",
"ground_truth": "AVAP is a Turing Complete Domain-Specific Language (DSL) designed for the secure, concurrent, and deterministic orchestration of microservices and I/O. It is not a general-purpose language; its hybrid engine and strict grammar are optimized for fast HTTP transaction processing, in-memory data manipulation, and persistence."
},
{
"id": "avap_q2",
"question": "¿Por qué AVAP es considerado un lenguaje orientado a líneas?",
"ground_truth": "AVAP es estrictamente orientado a líneas porque cada instrucción lógica debe completarse en una única línea física de texto. El motor reconoce el salto de línea o retorno de carro como el terminador absoluto de la instrucción, y no se admite la partición de una instrucción en múltiples líneas."
},
{
"id": "avap_q3",
"question": "What happens when an HTTP request uses a method not specified in registerEndpoint?",
"ground_truth": "The AVAP server will automatically reject the request with an HTTP Error 405 if the request method does not match the method specified in the registerEndpoint command."
},
{
"id": "avap_q4",
"question": "¿Qué hace el operador de desreferenciación $ en AVAP?",
"ground_truth": "El prefijo $ indica al motor que debe buscar en la tabla de símbolos la variable cuyo nombre sigue al símbolo y extraer su valor. Por ejemplo, en addVar(copia, $original), el motor busca la variable llamada 'original' y extrae su valor para asignarlo a 'copia'."
},
{
"id": "avap_q5",
"question": "What are the semantic restrictions of the addVar command in AVAP?",
"ground_truth": "The addVar command accepts either addVar(value, variable) or addVar(variable, value). If both arguments are identifiers, the value of the second is assigned to the first. It is not permitted to use two literals as arguments; at least one argument must be an identifier."
},
{
"id": "avap_q6",
"question": "¿En qué orden busca addParam los parámetros de una petición HTTP?",
"ground_truth": "El comando addParam inspecciona la petición HTTP en un orden jerárquico estricto: primero en la URL (Query arguments), luego en el JSON Body, y finalmente en el Form Data. Si el parámetro no existe en ninguno de estos lugares, la variable de destino se inicializa como None."
},
{
"id": "avap_q7",
"question": "What does getQueryParamList do when a URL parameter appears multiple times?",
"ground_truth": "The getQueryParamList command automatically packages multiple occurrences of the same URL parameter (for example, ?filter=A&filter=B) into a single list structure, making it easy to handle repeated query parameters."
},
{
"id": "avap_q8",
"question": "¿Cómo se define el código de estado HTTP de respuesta en AVAP?",
"ground_truth": "La variable de sistema _status permite definir explícitamente el código HTTP de salida. Puede asignarse mediante asignación directa (por ejemplo, _status = 404) o mediante el comando addVar (por ejemplo, addVar(_status, 401)). Es accesible y asignable desde cualquier scope."
},
{
"id": "avap_q9",
"question": "What is the purpose of the addResult command in AVAP?",
"ground_truth": "The addResult command registers which variables will form part of the final JSON response body. It is the mechanism through which AVAP sends data back to the HTTP client, since AVAP has no internal print commands."
},
{
"id": "avap_q10",
"question": "¿Cuáles son los dos modos de invocación del comando if() en AVAP?",
"ground_truth": "El comando if() tiene dos modos: el Modo 1 (comparación estructurada) con sintaxis if(átomo_1, átomo_2, 'operador'), usado para comparaciones directas entre dos valores simples; y el Modo 2 (expresión libre) con sintaxis if(None, None, `expresión_compleja`), usado para evaluar expresiones lógicas complejas encapsuladas entre acentos graves."
},
{
"id": "avap_q11",
"question": "In AVAP's structured if mode, what types of values are allowed as the first two arguments?",
"ground_truth": "In Mode 1 (structured comparison), the first two arguments must be simple identifiers (variables) or literals (strings or numbers). The use of None is not permitted in this mode, and expressions involving property access such as data.user or list[0] are also not allowed."
},
{
"id": "avap_q12",
"question": "¿Qué delimitador debe usarse para el tercer argumento en el Modo 2 del comando if()?",
"ground_truth": "En el Modo 2 (expresión libre), el tercer argumento debe estar encapsulado entre acentos graves (backticks). No se permite usar comillas dobles o simples para este argumento. Los primeros dos argumentos deben ser literalmente la palabra None sin comillas."
},
{
"id": "avap_q13",
"question": "What is wrong with the expression if(username, None, '==') in AVAP?",
"ground_truth": "This expression is invalid because Mode 1 of the if command prohibits the use of None as an argument. If None needs to be used, Mode 2 must be used instead, with the syntax if(None, None, `expression`)."
},
{
"id": "avap_q14",
"question": "¿Cómo se cierra un bloque condicional if en AVAP?",
"ground_truth": "Todo bloque condicional if en AVAP requiere un cierre explícito utilizando el comando end(). El bloque opcional else se introduce con else() y también queda delimitado por el end() final."
},
{
"id": "avap_q15",
"question": "How do you exit a startLoop early in AVAP?",
"ground_truth": "The way to exit a startLoop early in AVAP is by invoking the global return() command. The loop itself only iterates based on finite numeric indices and must be closed with endLoop()."
},
{
"id": "avap_q16",
"question": "¿Qué ocurre cuando se produce un fallo dentro de un bloque try() en AVAP?",
"ground_truth": "Si ocurre un fallo del sistema dentro del bloque try, el flujo de ejecución salta al bloque exception(variable_error), donde la variable especificada se puebla con la traza del error para facilitar la recuperación del script."
},
{
"id": "avap_q17",
"question": "What is the syntax for launching an asynchronous goroutine in AVAP?",
"ground_truth": "The syntax for launching a goroutine is: identifier = go function_name(parameters). This creates a new isolated execution context and returns a unique identifier that must be saved to interact with the thread later."
},
{
"id": "avap_q18",
"question": "¿Qué devuelve gather() si se supera el timeout especificado?",
"ground_truth": "Si se supera el timeout especificado en gather(identificador, timeout), el comando cancela la espera y devuelve None como resultado."
},
{
"id": "avap_q19",
"question": "What is avapConnector and how is it used in AVAP?",
"ground_truth": "avapConnector is the mechanism for integrating with third-party services configured on the AVAP platform. A connector is registered in advance with a unique UUID. When instantiated, the variable becomes a proxy object that encapsulates credentials and context, exposing dynamic methods via dot notation."
},
{
"id": "avap_q20",
"question": "¿Qué parámetro es obligatorio en RequestPost y RequestGet para evitar hilos bloqueados?",
"ground_truth": "Tanto RequestPost como RequestGet exigen un parámetro de timeout expresado en milisegundos. Si se supera este tiempo, la variable destino recibe None. Este parámetro es obligatorio para evitar que los hilos queden bloqueados por latencia de red."
},
{
"id": "avap_q21",
"question": "What is the difference between RequestPost and RequestGet in AVAP?",
"ground_truth": "RequestPost executes an HTTP POST request and includes a body parameter, with the signature RequestPost(url, querystring, headers, body, destination, timeout). RequestGet executes an HTTP GET request and omits the body, with the signature RequestGet(url, querystring, headers, destination, timeout)."
},
{
"id": "avap_q22",
"question": "¿Qué hace ormAccessSelect cuando el selector está vacío?",
"ground_truth": "El comando ormAccessSelect recupera registros de una tabla. El selector es la cláusula WHERE y puede estar vacío, lo que implica que se recuperarán todos los registros de la tabla. El resultado se devuelve como una lista de diccionarios."
},
{
"id": "avap_q23",
"question": "When is ormDirect used instead of other ORM commands in AVAP?",
"ground_truth": "ormDirect is used for executing raw SQL statements, making it suitable for complex analytical queries that cannot be expressed through the structured ORM commands like ormAccessSelect or ormAccessUpdate."
},
{
"id": "avap_q24",
"question": "¿Es obligatorio el selector en ormAccessUpdate? ¿Por qué?",
"ground_truth": "Sí, el selector es obligatorio en ormAccessUpdate. Su propósito es delimitar el alcance del cambio en la tabla, es decir, especificar qué registros deben ser modificados. Sin él, la operación podría afectar a todos los registros de la tabla."
},
{
"id": "avap_q25",
"question": "How does AVAP distinguish between a third-party connector and a database ORM connector at runtime?",
"ground_truth": "The grammar treats both connector types identically using avapConnector('TOKEN'). The distinction is made at runtime by the execution engine, which selects the appropriate adapter based on the UUID passed as argument, determining whether it resolves to a database ORM or a third-party proxy."
},
{
"id": "avap_q26",
"question": "¿Cómo se construye una lista en AVAP si no se pueden usar literales de array?",
"ground_truth": "En AVAP, las listas no se instancian con literales de array. Se construyen y recorren a través de un conjunto cerrado de comandos especializados como variableToList (para crear una lista desde un valor escalar), itemFromList (para acceder a elementos por índice) y getListLen (para obtener la longitud)."
},
{
"id": "avap_q27",
"question": "What does variableToList do in AVAP?",
"ground_truth": "variableToList forces a scalar variable to be converted into an iterable list structure containing a single element. It is the canonical entry point for building a list from scratch starting from an existing value."
},
{
"id": "avap_q28",
"question": "¿Por qué se recomienda llamar a getListLen antes de itemFromList?",
"ground_truth": "Se recomienda llamar siempre a getListLen antes de itemFromList para evitar accesos fuera de rango. getListLen calcula el número total de elementos en la lista, lo que permite construir bucles de recorrido seguro y validar que el índice al que se quiere acceder existe."
},
{
"id": "avap_q29",
"question": "What happens when AddVariableToJSON is called with a key that already exists in the JSON object?",
"ground_truth": "When AddVariableToJSON is called with a key that already exists in the JSON object, the existing value for that key is overwritten with the new value provided."
},
{
"id": "avap_q30",
"question": "¿Cuál es la diferencia entre encodeSHA256 y encodeMD5 en AVAP?",
"ground_truth": "Ambas son funciones criptográficas que encriptan texto de forma irreversible. SHA-256 produce un digest de 64 caracteres hexadecimales y ofrece mayor resistencia criptográfica, mientras que MD5 produce un digest de 32 caracteres. Se recomienda SHA-256 para nuevos desarrollos."
},
{
"id": "avap_q31",
"question": "What regex syntax does getRegex use in AVAP?",
"ground_truth": "The getRegex command uses standard regex syntax compatible with Python's re module. It applies the pattern to the source variable and extracts the first exact match found."
},
{
"id": "avap_q32",
"question": "¿Qué hace getDateTime en AVAP y qué parámetros acepta?",
"ground_truth": "getDateTime captura la fecha y hora actuales del sistema, aplica el ajuste timedelta especificado y las convierte a la zona horaria indicada antes de almacenar el resultado en la variable destino. Acepta cualquier zona horaria reconocida por la librería pytz de Python. Sus parámetros son: formato, timedelta, zona_horaria y destino."
},
{
"id": "avap_q33",
"question": "What is the difference between getTimeStamp and stampToDatetime in AVAP?",
"ground_truth": "getTimeStamp converts a readable date string to its Unix Epoch integer value, while stampToDatetime does the reverse, converting an Epoch integer value to a formatted date string. Both support strftime format notation and timedelta adjustments in seconds."
},
{
"id": "avap_q34",
"question": "¿Cómo se expresa un timedelta negativo en los comandos de fecha de AVAP?",
"ground_truth": "Los comandos de fecha de AVAP expresan el timedelta en segundos. Un valor positivo suma tiempo y un valor negativo resta tiempo. Por ejemplo, para restar una hora se usaría -3600 como valor de timedelta."
},
{
"id": "avap_q35",
"question": "What does randomString do in AVAP and what parameters does it take?",
"ground_truth": "randomString generates a random string of a specified length whose characters are restricted to the set defined by a pattern (a character regular expression). It takes three parameters: pattern, length, and destination. It is useful for generating session tokens, temporary passwords, or unique identifiers."
},
{
"id": "avap_q36",
"question": "¿Qué hace el comando replace en AVAP?",
"ground_truth": "El comando replace localiza todas las ocurrencias de un patrón de búsqueda dentro de la variable de origen y las sustituye por el valor de reemplazo, almacenando el resultado en la variable destino. Sus parámetros son: origen, patron_busqueda, reemplazo y destino."
},
{
"id": "avap_q37",
"question": "How are function blocks delimited in AVAP, and how does this differ from control structures?",
"ground_truth": "Functions use curly braces {} as block delimiters, which is an explicit architectural decision. This differs from control structures like if, loop, and try, which use keyword closers such as end(), endLoop(), and end() respectively. The parser distinguishes between them by the opening token."
},
{
"id": "avap_q38",
"question": "¿Qué hace return() cuando se usa dentro de un startLoop en AVAP?",
"ground_truth": "Cuando return() se usa dentro de un startLoop, actúa como interruptor de flujo que rompe la iteración anticipadamente, además de inyectar el valor calculado al llamador y liberar la memoria local de la función."
},
{
"id": "avap_q39",
"question": "What is the difference between include and import in AVAP?",
"ground_truth": "include is a preprocessor directive that pastes the content of a physical file at the current line (static inclusion). import loads collections of functions: angle brackets (import <math>) are used for native libraries, while quotes (import 'my_utils') are used for local libraries."
},
{
"id": "avap_q40",
"question": "¿Cómo se importa una librería nativa en AVAP?",
"ground_truth": "Para importar una librería nativa en AVAP se usan corchetes angulares, con la sintaxis import <nombre_libreria>. Para librerías locales se usan comillas, con la sintaxis import 'nombre_libreria'."
},
{
"id": "avap_q41",
"question": "What type casting functions are available in AVAP expressions?",
"ground_truth": "AVAP supports explicit type casting using standard constructor functions: int(var) to convert to integer, float(var) to convert to float, and str(var) to convert to string. These can be used in any evaluation."
},
{
"id": "avap_q42",
"question": "¿Cómo funciona el slicing en AVAP?",
"ground_truth": "En AVAP se pueden extraer fragmentos de listas o strings usando la notación de dos puntos. Por ejemplo, mi_lista[1:4] extrae los elementos desde el índice 1 hasta el índice 3 (el índice final es exclusivo). Esta notación también soporta un tercer parámetro opcional para el paso."
},
{
"id": "avap_q43",
"question": "What are list comprehensions in AVAP and how are they written?",
"ground_truth": "AVAP supports list comprehensions for quickly building lists using iterators in a single line, allowing filtering and mapping of entire collections. The syntax is [expression for identifier in expression] with an optional if clause, for example [x * 2 for x in values if x > 0]."
},
{
"id": "avap_q44",
"question": "¿Cuáles son los tres tipos de comentarios en AVAP y cómo se diferencian?",
"ground_truth": "AVAP tiene tres tipos de comentarios: comentarios de línea (//) que ignoran el texto hasta el salto de línea; comentarios de bloque (/* ... */) para aislar bloques multilínea; y comentarios de documentación (///) utilizados por analizadores de código o IDEs para generar documentación técnica automática (Docstrings)."
},
{
"id": "avap_q45",
"question": "Why must the lexer evaluate /// before // in AVAP?",
"ground_truth": "The lexer must evaluate /// before // because it applies the longest-match principle. Since /// starts with //, if // were evaluated first, the documentation comment marker would be incorrectly tokenized as a line comment followed by a slash."
},
{
"id": "avap_q46",
"question": "¿Cuál es la jerarquía de precedencia de operadores en AVAP, de menor a mayor?",
"ground_truth": "La jerarquía de precedencia en AVAP de menor a mayor es: or lógico, and lógico, not lógico, comparaciones (==, !=, <, >, <=, >=, in, is), suma y resta aritméticas, multiplicación/división/módulo, factor (unario), y potencia (**)."
},
{
"id": "avap_q47",
"question": "What are the three memory scope types in AVAP?",
"ground_truth": "AVAP uses a memory model based on three types of scopes: Global Scope (accessible from anywhere in the program), Main Local Scope (the main execution flow outside any function), and Function Scope (created independently for each function invocation)."
},
{
"id": "avap_q48",
"question": "¿Pueden las funciones en AVAP acceder a las variables del flujo principal?",
"ground_truth": "No. Las variables del Main Local Scope no son accesibles desde las funciones. Las funciones solo pueden acceder a su propio Function Scope y al Global Scope. Esto evita dependencias implícitas entre funciones y el flujo principal."
},
{
"id": "avap_q49",
"question": "What happens to Function Scope variables when a function finishes executing?",
"ground_truth": "When a function finishes executing, its Function Scope is destroyed. All variables created within the function, including parameters and intermediate results, cease to exist and are not visible from outside the function."
},
{
"id": "avap_q50",
"question": "¿Pueden las goroutines acceder al Main Local Scope en AVAP?",
"ground_truth": "No. Las goroutines siguen las mismas reglas de scope que una función normal. Por lo tanto, pueden acceder al Global Scope y a su propio Function Scope, pero no pueden acceder al Main Local Scope."
},
{
"id": "avap_q51",
"question": "What is the variable resolution order inside a function in AVAP?",
"ground_truth": "Inside a function, variable resolution follows this hierarchical order: first the Function Scope is checked, then the Global Scope. The Main Local Scope is not visible inside functions. If a variable does not exist in any visible scope, the engine produces a runtime error."
},
{
"id": "avap_q52",
"question": "¿Cuánto tiempo existe el Global Scope en AVAP?",
"ground_truth": "El Global Scope existe durante toda la vida del proceso del intérprete. Las variables globales actúan como estado compartido del programa y son visibles desde el flujo principal, desde todas las funciones y desde las goroutines."
},
{
"id": "avap_q53",
"question": "What token does the AVAP lexer produce for the end of a line?",
"ground_truth": "The AVAP lexer produces the EOL token for the end of a line. This token acts as a statement terminator and is generated by carriage return or line feed characters (\\r\\n, \\n, or \\r)."
},
{
"id": "avap_q54",
"question": "¿Qué elementos descarta el lexer de AVAP y no envía al parser?",
"ground_truth": "El lexer de AVAP descarta y no envía al parser los siguientes elementos: WHITESPACE (espacios y tabulaciones), LINE_COMMENT (comentarios de línea //), DOC_COMMENT (comentarios de documentación ///) y BLOCK_COMMENT (comentarios de bloque /* */)."
},
{
"id": "avap_q55",
"question": "What is the DEREF token in AVAP and when is it used?",
"ground_truth": "The DEREF token is the dollar sign ($) prefix used to dereference a variable, meaning it instructs the engine to look up the variable's value in the symbol table. For example, addVar(copy, $original) uses DEREF to access the value of the variable named 'original'."
},
{
"id": "avap_q56",
"question": "¿Cuál es el orden de precedencia léxica que debe seguir el lexer de AVAP?",
"ground_truth": "El lexer de AVAP debe aplicar el principio de máxima coincidencia en este orden: primero comentarios (/// antes que //, luego /* */), luego whitespace, palabras reservadas, identificadores, números flotantes, enteros, strings, operadores compuestos (**,==,<=,>=,!=), operadores simples y finalmente delimitadores."
},
{
"id": "avap_q57",
"question": "Why must ** be evaluated before * in the AVAP lexer?",
"ground_truth": "The ** operator must be evaluated before * because the lexer applies the longest-match principle. If * were evaluated first, the power operator ** would be incorrectly tokenized as two separate multiplication operators."
},
{
"id": "avap_q58",
"question": "¿Qué secuencias de escape soporta AVAP en los literales de cadena?",
"ground_truth": "AVAP soporta las siguientes secuencias de escape en literales de cadena: \\\" (comilla doble), \\' (comilla simple), \\\\ (barra invertida), \\n (salto de línea), \\t (tabulación), \\r (retorno de carro) y \\0 (carácter nulo)."
},
{
"id": "avap_q59",
"question": "Does a \\n inside a string literal act as a statement terminator in AVAP?",
"ground_truth": "No. A \\n inside a string literal is a data character, not a statement terminator. The physical EOL (end of line) is the only statement terminator in AVAP."
},
{
"id": "avap_q60",
"question": "¿Qué palabras están reservadas en AVAP y no pueden usarse como identificadores?",
"ground_truth": "Las palabras reservadas en AVAP incluyen: palabras de control de flujo (if, else, end, startLoop, endLoop, try, exception, return), declaración de funciones (function), concurrencia (go, gather), modularidad (include, import), operadores lógicos (and, or, not, in, is) y literales (True, False, None)."
},
{
"id": "avap_q61",
"question": "What is the BNF rule for a valid AVAP identifier?",
"ground_truth": "A valid AVAP identifier must start with a letter (a-z or A-Z) or an underscore, followed by zero or more letters, digits (0-9), or underscores. The formal rule is: [a-zA-Z_][a-zA-Z0-9_]*"
},
{
"id": "avap_q62",
"question": "¿Cómo se define un número flotante en la gramática léxica de AVAP?",
"ground_truth": "Un número flotante en AVAP se define como uno o más dígitos seguidos de un punto y cero o más dígitos, o como un punto seguido de uno o más dígitos. La regla formal es: [0-9]+\\.[0-9]* | \\.[0-9]+. Ejemplos válidos son 1.0, 3.14 y .5."
},
{
"id": "avap_q63",
"question": "What is the purpose of registerEndpoint's middleware list parameter?",
"ground_truth": "The middleware list parameter in registerEndpoint allows injecting a list of functions that execute before the main handler. These middleware functions are used to validate tokens and perform pre-processing before the main block executes."
},
{
"id": "avap_q64",
"question": "¿Qué diferencia hay entre una llamada a función global y una llamada a método en AVAP?",
"ground_truth": "Una llamada a función global (function_call_stmt) no tiene receptor de objeto y usa la sintaxis identificador(argumentos). Una llamada a método (method_call_stmt) se realiza sobre un objeto conector usando notación de punto, con la sintaxis identificador = identificador.identificador(argumentos)."
},
{
"id": "avap_q65",
"question": "What does ormCreateTable do in AVAP and what parameters does it require?",
"ground_truth": "ormCreateTable is a DDL command for creating tables in the connected database. It requires four parameters: fields (the field names), fieldsType (the data types of the fields), tableName (the name of the table to create), and varTarget (the variable to store the result)."
},
{
"id": "avap_q66",
"question": "¿Qué devuelve ormAccessSelect en AVAP?",
"ground_truth": "ormAccessSelect devuelve una lista de diccionarios, donde cada diccionario representa un registro recuperado de la tabla. El campo fields acepta * para recuperar todos los campos o una lista de campos específicos, y el selector es la cláusula WHERE que puede estar vacía."
},
{
"id": "avap_q67",
"question": "How does AVAP handle output if it has no print command?",
"ground_truth": "Since AVAP has no internal print commands, all data output is performed through the HTTP interface. The addResult command registers which variables will form part of the final JSON response body sent back to the HTTP client."
},
{
"id": "avap_q68",
"question": "¿Qué es el Main Local Scope en AVAP y cuándo desaparece?",
"ground_truth": "El Main Local Scope corresponde al flujo de ejecución principal del script, fuera de cualquier función. Las variables declaradas en este ámbito son locales del flujo principal, no son accesibles desde funciones ni goroutines, y desaparecen cuando finaliza la ejecución del script."
},
{
"id": "avap_q69",
"question": "What is the BNF structure of a try/exception block in AVAP?",
"ground_truth": "A try/exception block in AVAP has the structure: try() followed by a block, then exception(identifier) followed by another block, and finally end(). The identifier in the exception clause receives the error trace when a system failure occurs inside the try block."
},
{
"id": "avap_q70",
"question": "¿Puede una sentencia AVAP ocupar más de una línea física?",
"ground_truth": "No. AVAP es estrictamente orientado a líneas y no admite la partición de una instrucción en múltiples líneas. Cada instrucción lógica debe completarse en una única línea física de texto, y el EOL es el terminador absoluto de la instrucción."
},
{
"id": "avap_q71",
"question": "What is the syntax for declaring a function in AVAP?",
"ground_truth": "A function in AVAP is declared using the keyword 'function' followed by the function name, parentheses with an optional parameter list, and then the function body enclosed in curly braces {}. The formal syntax is: function identifier([param_list]) { block }."
},
{
"id": "avap_q72",
"question": "¿Qué hace variableFromJSON en AVAP?",
"ground_truth": "variableFromJSON parsea un objeto JSON en memoria y extrae el valor correspondiente a la clave especificada, almacenándolo en la variable destino. El acceso es directo por nombre de propiedad."
},
{
"id": "avap_q73",
"question": "What is the index base used by itemFromList in AVAP?",
"ground_truth": "itemFromList uses zero-based indexing (base 0) to access elements in a list. It safely extracts the element at the specified index position from the source list and stores it in the destination variable."
},
{
"id": "avap_q74",
"question": "¿Cuál es la diferencia entre el nivel léxico y el nivel sintáctico en AVAP?",
"ground_truth": "El nivel léxico (cubierto por el Apéndice X) produce tokens como IDENTIFIER, INTEGER, FLOAT, STRING, operadores, delimitadores, EOL y palabras reservadas. El nivel sintáctico consume esos tokens para construir el AST (árbol de sintaxis abstracta) según las reglas BNF de las Secciones I-IX."
},
{
"id": "avap_q75",
"question": "What comparison operators are supported in AVAP's structured if mode?",
"ground_truth": "In AVAP's structured if mode (Mode 1), the supported comparison operators are: == (equal), != (not equal), > (greater than), < (less than), >= (greater than or equal), and <= (less than or equal). The operator must be passed as a string enclosed in double quotes."
},
{
"id": "avap_q76",
"question": "¿Qué es un motor de evaluación híbrida en el contexto de AVAP?",
"ground_truth": "El motor de evaluación híbrida de AVAP permite combinar comandos declarativos con expresiones dinámicas. Cuando el intérprete lee una asignación como variable = expresión, resuelve cualquier operación matemática o lógica en tiempo real utilizando este motor subyacente."
},
{
"id": "avap_q77",
"question": "What tokens are produced by the AVAP lexer for comparison operators?",
"ground_truth": "The AVAP lexer produces the following tokens for comparison operators: EQ for ==, NEQ for !=, LT for <, GT for >, LTE for <=, and GTE for >=."
},
{
"id": "avap_q78",
"question": "¿Qué es un objeto proxy en el contexto de avapConnector?",
"ground_truth": "Cuando se instancia un avapConnector, la variable se convierte en un objeto proxy que encapsula las credenciales y el contexto del servicio de terceros. Este objeto expone métodos dinámicos mediante notación de punto, que son resueltos en tiempo de ejecución (runtime)."
},
{
"id": "avap_q79",
"question": "How does AVAP's gather command work when waiting for a goroutine result?",
"ground_truth": "The gather command pauses the main thread waiting for the result of a goroutine identified by the given identifier. If the specified timeout is exceeded, it cancels the wait and returns None. The syntax is: result = gather(identifier, timeout)."
},
{
"id": "avap_q80",
"question": "¿Qué ocurre si se intenta usar if(user.id, 10, '==') en AVAP?",
"ground_truth": "Esta expresión es inválida porque el Modo 1 del comando if no permite expresiones de acceso con punto (como user.id). Para comparar un valor extraído de una estructura, primero debe asignarse a una variable simple y luego usar esa variable en el if."
},
{
"id": "avap_q81",
"question": "What is the purpose of the _status system variable in AVAP?",
"ground_truth": "_status is a reserved system variable that allows explicitly defining the HTTP response status code. It is accessible and assignable from any scope, and can be set either through direct assignment (_status = 404) or through the addVar command (addVar(_status, 401))."
},
{
"id": "avap_q82",
"question": "¿Cómo se accede a los métodos de un objeto conector en AVAP?",
"ground_truth": "Los métodos de un objeto conector se acceden mediante notación de punto. Primero se instancia el conector con avapConnector('UUID'), y luego se invocan sus métodos dinámicos con la sintaxis objeto.metodo(argumentos). Los métodos son resueltos en tiempo de ejecución."
},
{
"id": "avap_q83",
"question": "What does the BNF rule for startLoop look like in AVAP?",
"ground_truth": "The BNF rule for startLoop is: startLoop(identifier, expression, expression) followed by a block and closed with endLoop(). The identifier is the counter variable, and the two expressions define the start and end of the iteration range."
},
{
"id": "avap_q84",
"question": "¿Qué tipo de datos devuelve getListLen en AVAP?",
"ground_truth": "getListLen calcula el número total de elementos contenidos en una lista y almacena el resultado como un entero en la variable destino. Este valor entero puede usarse para construir bucles de recorrido seguro."
},
{
"id": "avap_q85",
"question": "Can AVAP functions access variables declared in the main execution flow?",
"ground_truth": "No. AVAP functions cannot access variables from the Main Local Scope. Functions can only access their own Function Scope and the Global Scope. This design prevents implicit dependencies between functions and the main flow."
},
{
"id": "avap_q86",
"question": "¿Qué formato de zona horaria acepta getDateTime en AVAP?",
"ground_truth": "getDateTime acepta cualquier zona horaria reconocida por la librería pytz de Python. El parámetro zona_horaria debe ser un string con el nombre de la zona horaria en el formato estándar de pytz."
},
{
"id": "avap_q87",
"question": "What is the BNF production rule for an AVAP assignment statement?",
"ground_truth": "The BNF production rule for an assignment in AVAP is: assignment ::= identifier '=' expression. This means an assignment consists of an identifier on the left side, the equals sign, and an expression on the right side."
},
{
"id": "avap_q88",
"question": "¿Qué hace el comando ormCheckTable en AVAP?",
"ground_truth": "ormCheckTable verifica la existencia de una tabla en la base de datos conectada. Recibe el nombre de la tabla (tableName) y una variable destino (varTarget) donde almacena el resultado de la verificación."
},
{
"id": "avap_q89",
"question": "How does AVAP support dictionary literals in expressions?",
"ground_truth": "AVAP supports dictionary literals through the dict_display rule in the grammar, which uses curly braces containing key-datum pairs separated by commas. Each key-datum pair consists of an expression, a colon, and another expression."
},
{
"id": "avap_q90",
"question": "¿Cuál es la sintaxis BNF de la declaración return en AVAP?",
"ground_truth": "La sintaxis BNF de return en AVAP es: return_stmt ::= 'return(' [expression] ')'. La expresión es opcional, lo que permite usar return() sin valor para simplemente interrumpir el flujo de ejecución."
},
{
"id": "avap_q91",
"question": "What is the difference between a line comment and a documentation comment in AVAP?",
"ground_truth": "A line comment (//) simply ignores text until the end of the line and is discarded by the lexer. A documentation comment (///) is also discarded by the lexer but is intended to be used by code analyzers or IDEs to automatically generate technical documentation (Docstrings) from the source code."
},
{
"id": "avap_q92",
"question": "¿Qué operadores lógicos soporta AVAP en las expresiones?",
"ground_truth": "AVAP soporta los operadores lógicos and, or y not en las expresiones. Además, soporta los operadores in e is como operadores de comparación. En la jerarquía de precedencia, not tiene mayor precedencia que and, y and tiene mayor precedencia que or."
},
{
"id": "avap_q93",
"question": "What is the BNF rule for the addParam command in AVAP?",
"ground_truth": "The BNF rule for addParam is: addparam_cmd ::= 'addParam(' stringliteral ',' identifier ')'. The first argument is a string literal with the parameter name to look up in the HTTP request, and the second is the identifier (variable) where the value will be stored."
},
{
"id": "avap_q94",
"question": "¿Cómo se define un bloque de comentario multilínea en AVAP?",
"ground_truth": "Un bloque de comentario multilínea en AVAP se define usando /* para abrir y */ para cerrar. Puede abarcar múltiples líneas y todo su contenido es ignorado por el lexer. La regla léxica es: BLOCK_COMMENT ::= '/*' .*? '*/'."
},
{
"id": "avap_q95",
"question": "What is the purpose of the go command in AVAP's concurrency model?",
"ground_truth": "The go command creates a new isolated execution context (goroutine) for a function, allowing the server to process long I/O operations without blocking the main thread. It returns a unique identifier that must be saved to interact with the thread later, typically using the gather command."
},
{
"id": "avap_q96",
"question": "¿Qué restricción tiene el Modo 1 del if() respecto a expresiones de acceso?",
"ground_truth": "El Modo 1 del if() no permite el uso de expresiones de acceso como data.user o list[0] como argumentos. Si se necesita comparar un valor extraído de una estructura de datos, primero debe asignarse a una variable simple y luego usar esa variable en el if."
},
{
"id": "avap_q97",
"question": "What does the AVAP documentation say about the relationship between the lexer and the parser?",
"ground_truth": "The lexer (Appendix X) operates at the lexical level, transforming source code into a sequence of tokens such as IDENTIFIER, INTEGER, FLOAT, STRING, operators, delimiters, EOL, and reserved words. The parser (Sections I-IX) operates at the syntactic level, consuming those tokens to build the AST according to the BNF grammar rules."
},
{
"id": "avap_q98",
"question": "¿Qué ocurre si una variable no existe en ningún scope visible dentro de una función en AVAP?",
"ground_truth": "Si una variable no existe en los scopes visibles (Function Scope y Global Scope) dentro de una función, el motor de ejecución produce un error de ejecución (runtime error)."
},
{
"id": "avap_q99",
"question": "What is the BNF rule for the gather command in AVAP?",
"ground_truth": "The BNF rule for gather is: gather_stmt ::= identifier '=' 'gather(' identifier [',' expression] ')'. The first identifier stores the result, the second identifier is the goroutine handle, and the optional expression is the timeout value."
},
{
"id": "avap_q100",
"question": "¿Cuál es la diferencia entre ormAccessInsert y ormAccessUpdate en AVAP?",
"ground_truth": "ormAccessInsert realiza la inserción parametrizada de nuevos registros en una tabla y tiene la firma ormAccessInsert(fieldsValues, tableName, varTarget). ormAccessUpdate modifica registros existentes y tiene la firma ormAccessUpdate(fields, fieldsValues, tableName, selector, varTarget), donde el selector es obligatorio para delimitar qué registros se modifican."
},
{
"id": "asignacion_booleana_q1",
"question": "How do you evaluate a numeric condition and return a boolean result in AVAP?",
"ground_truth": "nivel = 5\nes_admin = nivel >= 10\naddResult(es_admin)"
},
{
"id": "asignacion_booleana_q2",
"question": "¿Cómo se asigna el resultado de una comparación a una variable y se devuelve como respuesta?",
"ground_truth": "es_admin = nivel >= 10\naddResult(es_admin)"
},
{
"id": "asignacion_matematica_q1",
"question": "How do you calculate a subtotal with tax and return the total in AVAP?",
"ground_truth": "subtotal = 150.50\niva = subtotal * 0.21\ntotal = subtotal + iva\naddResult(total)"
},
{
"id": "asignacion_matematica_q2",
"question": "¿Cómo se encadenan operaciones aritméticas sobre variables numéricas en AVAP?",
"ground_truth": "subtotal = 150.50\niva = subtotal * 0.21\ntotal = subtotal + iva\naddResult(total)"
},
{
"id": "bucle_1_10_q1",
"question": "How do you build a JSON object dynamically inside a loop in AVAP?",
"ground_truth": "startLoop(i,1,10)\n item = \"item_%s\" % i\n AddvariableToJSON(item,'valor_generado',mi_json)\nendLoop()\naddResult(mi_json)"
},
{
"id": "bucle_1_10_q2",
"question": "¿Cómo se itera un número fijo de veces y se agrega una propiedad a un objeto JSON en cada iteración?",
"ground_truth": "startLoop(i,1,10)\n item = \"item_%s\" % i\n AddvariableToJSON(item,'valor_generado',mi_json)\nendLoop()\naddResult(mi_json)"
},
{
"id": "bucle_longitud_de_datos_q1",
"question": "How do you iterate over a list using its length as the loop bound in AVAP?",
"ground_truth": "registros = ['1','2','3']\ngetListLen(registros, total)\ncontador = 0\nstartLoop(idx, 0, 2)\n actual = registros[int(idx)]\nendLoop()\naddResult(actual)"
},
{
"id": "bucle_longitud_de_datos_q2",
"question": "¿Cómo se accede a elementos de una lista por índice dentro de un bucle en AVAP?",
"ground_truth": "startLoop(idx, 0, 2)\n actual = registros[int(idx)]\nendLoop()\naddResult(actual)"
},
{
"id": "calculo_de_expiracion_q1",
"question": "How do you calculate a future date by adding seconds to the current time in AVAP?",
"ground_truth": "getDateTime(\"\", 86400, \"UTC\", expira)\naddResult(expira)"
},
{
"id": "calculo_de_expiracion_q2",
"question": "¿Cómo se obtiene la fecha de expiración sumando un día a la hora actual en UTC?",
"ground_truth": "getDateTime(\"\", 86400, \"UTC\", expira)\naddResult(expira)"
},
{
"id": "captura_de_id_q1",
"question": "How do you capture a query parameter and return it directly as a response in AVAP?",
"ground_truth": "addParam(\"client_id\", id_interno)\naddResult(id_interno)"
},
{
"id": "captura_de_id_q2",
"question": "¿Cómo se lee un parámetro de entrada llamado client_id y se incluye en la respuesta?",
"ground_truth": "addParam(\"client_id\", id_interno)\naddResult(id_interno)"
},
{
"id": "captura_de_listas_multiples_q1",
"question": "How do you capture multiple occurrences of a URL parameter as a list in AVAP?",
"ground_truth": "getQueryParamList(\"lista_correos\", lista_correos)\naddResult(lista_correos)"
},
{
"id": "captura_de_listas_multiples_q2",
"question": "¿Cómo se capturan varios valores del mismo parámetro de URL y se devuelven como lista?",
"ground_truth": "addParam(\"emails\", emails)\ngetQueryParamList(\"lista_correos\", lista_correos)\naddResult(lista_correos)"
},
{
"id": "comparacion_simple_q1",
"question": "How do you read a parameter and conditionally assign a message based on its value in AVAP?",
"ground_truth": "addParam(\"lang\", l)\nif(l, \"es\", \"=\")\n addVar(msg, \"Hola\")\nend()\naddResult(msg)"
},
{
"id": "comparacion_simple_q2",
"question": "¿Cómo se usa if() en Modo 1 para comparar un parámetro con un string literal?",
"ground_truth": "if(l, \"es\", \"=\")\n addVar(msg, \"Hola\")\nend()\naddResult(msg)"
},
{
"id": "concatenacion_dinamica_q1",
"question": "How do you build a dynamic log message by interpolating a variable into a string in AVAP?",
"ground_truth": "nombre = \"Sistema\"\nlog = \"Evento registrado por: %s\" % nombre\naddResult(log)"
},
{
"id": "concatenacion_dinamica_q2",
"question": "¿Cómo se construye un string dinámico usando el operador % con una variable en AVAP?",
"ground_truth": "log = \"Evento registrado por: %s\" % nombre\naddResult(log)"
},
{
"id": "construccion_dinamica_de_objeto_q1",
"question": "How do you inject a variable key-value pair into a JSON object dynamically in AVAP?",
"ground_truth": "datos_cliente = \"datos\"\naddVar(clave, \"cliente_vip\")\nAddvariableToJSON(clave, datos_cliente, mi_json_final)\naddResult(mi_json_final)"
},
{
"id": "construccion_dinamica_de_objeto_q2",
"question": "¿Cómo se usa AddvariableToJSON con una clave almacenada en variable para construir un objeto JSON?",
"ground_truth": "addVar(clave, \"cliente_vip\")\nAddvariableToJSON(clave, datos_cliente, mi_json_final)\naddResult(mi_json_final)"
},
{
"id": "contador_de_parametros_q1",
"question": "How do you count the number of elements in a list received as a parameter in AVAP?",
"ground_truth": "addParam(\"data_list\", mi_lista)\ngetListLen(mi_lista, cantidad)\naddResult(cantidad)"
},
{
"id": "contador_de_parametros_q2",
"question": "¿Cómo se obtiene la longitud de una lista capturada desde la petición HTTP?",
"ground_truth": "addParam(\"data_list\", mi_lista)\ngetListLen(mi_lista, cantidad)\naddResult(cantidad)"
},
{
"id": "conversion_timestamp_legible_q1",
"question": "How do you convert a Unix epoch timestamp to a human-readable date string in AVAP?",
"ground_truth": "stampToDatetime(1708726162, \"%d/%m/%Y\", 0, fecha_human)\naddResult(fecha_human)"
},
{
"id": "conversion_timestamp_legible_q2",
"question": "¿Cómo se transforma un valor epoch en una fecha con formato día/mes/año en AVAP?",
"ground_truth": "stampToDatetime(1708726162, \"%d/%m/%Y\", 0, fecha_human)\naddResult(fecha_human)"
},
{
"id": "else_estandar_q1",
"question": "How do you use an if-else block to set a boolean variable based on a numeric condition in AVAP?",
"ground_truth": "addParam(\"sal_par\",saldo)\nif(saldo, 0, \">\")\n permitir = True\nelse()\n permitir = False\nend()\naddResult(permitir)"
},
{
"id": "else_estandar_q2",
"question": "¿Cómo se implementa una rama else() para asignar False cuando una condición no se cumple?",
"ground_truth": "if(saldo, 0, \">\")\n permitir = True\nelse()\n permitir = False\nend()\naddResult(permitir)"
},
{
"id": "expresion_compleja_q1",
"question": "How do you evaluate a complex multi-condition expression using if() Mode 2 in AVAP?",
"ground_truth": "if(None, None, \" user_type == 'VIP' or compras > 100\")\n addVar(descuento, 0.20)\nend()\naddResult(descuento)"
},
{
"id": "expresion_compleja_q2",
"question": "¿Cómo se capturan dos parámetros y se evalúan juntos en una expresión libre con if(None, None, ...)?",
"ground_truth": "addParam(\"userrype\", user_type)\naddParam(\"sells\", compras)\nif(None, None, \" user_type == 'VIP' or compras > 100\")\n addVar(descuento, 0.20)\nend()\naddResult(descuento)"
},
{
"id": "fecha_para_base_de_datos_q1",
"question": "How do you get the current datetime formatted for SQL storage in a specific timezone in AVAP?",
"ground_truth": "getDateTime(\"%Y-%m-%d %H:%M:%S\", 0, \"Europe/Madrid\", sql_date)\naddResult(sql_date)"
},
{
"id": "fecha_para_base_de_datos_q2",
"question": "¿Cómo se obtiene la fecha y hora actual en formato ISO para insertar en base de datos con zona horaria de Madrid?",
"ground_truth": "getDateTime(\"%Y-%m-%d %H:%M:%S\", 0, \"Europe/Madrid\", sql_date)\naddResult(sql_date)"
},
{
"id": "funcion_de_suma_q1",
"question": "How do you define and call a function that adds two numbers and returns the result in AVAP?",
"ground_truth": "function suma(a, b){\n total = a + b\n return(total)\n }\nresultado = suma(10, 20)\naddResult(resultado)"
},
{
"id": "funcion_de_suma_q2",
"question": "¿Cómo se declara una función con parámetros, se realiza un cálculo interno y se retorna el valor?",
"ground_truth": "function suma(a, b){\n total = a + b\n return(total)\n }"
},
{
"id": "funcion_validacion_acceso_q1",
"question": "How do you write a function that validates a token and returns a boolean access result in AVAP?",
"ground_truth": " function es_valido(token){\n response = False\n if(token, \"SECRET\", \"=\")\n response = True\n end()\n return(response)\n }\nautorizado = es_valido(\"SECRET\")\naddResult(autorizado)"
},
{
"id": "funcion_validacion_acceso_q2",
"question": "¿Cómo se usa un condicional dentro de una función para cambiar el valor de retorno según el parámetro recibido?",
"ground_truth": " function es_valido(token){\n response = False\n if(token, \"SECRET\", \"=\")\n response = True\n end()\n return(response)\n }"
},
{
"id": "generador_de_tokens_aleatorios_q1",
"question": "How do you generate a random alphanumeric token of a fixed length in AVAP?",
"ground_truth": "randomString(\"[A-Z]\\d\", 32, token_seguridad)\naddResult(token_seguridad)"
},
{
"id": "generador_de_tokens_aleatorios_q2",
"question": "¿Cómo se genera una cadena aleatoria de 32 caracteres con un patrón específico para usar como token de seguridad?",
"ground_truth": "randomString(\"[A-Z]\\d\", 32, token_seguridad)\naddResult(token_seguridad)"
},
{
"id": "hash_SHA256_para_integridad_q1",
"question": "How do you compute a SHA-256 hash of a string and return it as a checksum in AVAP?",
"ground_truth": "encodeSHA256(\"payload_data\", checksum)\naddResult(checksum)"
},
{
"id": "hash_SHA256_para_integridad_q2",
"question": "¿Cómo se genera un hash irreversible de un dato para verificar integridad en AVAP?",
"ground_truth": "encodeSHA256(\"payload_data\", checksum)\naddResult(checksum)"
},
{
"id": "hello_world_q1",
"question": "How do you register a GET endpoint and return a greeting message in AVAP?",
"ground_truth": "registerEndpoint(\"/hello_world\",\"GET\",[],\"HELLO_WORLD\",main,result)\naddVar(name,\"Alberto\")\nresult = \"Hello,\" + name \naddResult(result)"
},
{
"id": "hello_world_q2",
"question": "¿Cómo se registra un endpoint HTTP y se construye una respuesta concatenando un nombre fijo?",
"ground_truth": "registerEndpoint(\"/hello_world\",\"GET\",[],\"HELLO_WORLD\",main,result)\naddVar(name,\"Alberto\")\nresult = \"Hello,\" + name \naddResult(result)"
},
{
"id": "hola_mundo_q1",
"question": "How do you assign a string literal to a variable and return it as the API response in AVAP?",
"ground_truth": "addVar(mensaje, \"Hola mundo desde AVAP\")\naddResult(mensaje)"
},
{
"id": "hola_mundo_q2",
"question": "¿Cuál es la forma mínima de devolver un mensaje de texto fijo como respuesta en AVAP?",
"ground_truth": "addVar(mensaje, \"Hola mundo desde AVAP\")\naddResult(mensaje)"
},
{
"id": "if_desigualdad_q1",
"question": "How do you compare a captured parameter against an existing variable using the inequality operator in AVAP?",
"ground_truth": "addParam(\"password\",pass_nueva)\npass_antigua = \"password\"\nif(pass_nueva, pass_antigua, \"!=\")\n addVar(cambio, \"Contraseña actualizada\")\nend()\naddResult(cambio)"
},
{
"id": "if_desigualdad_q2",
"question": "¿Cómo se detecta que una contraseña nueva es diferente a la antigua y se registra el cambio?",
"ground_truth": "if(pass_nueva, pass_antigua, \"!=\")\n addVar(cambio, \"Contraseña actualizada\")\nend()\naddResult(cambio)"
},
{
"id": "limpieza_de_strings_q1",
"question": "How do you replace a substring within a string variable and return the cleaned result in AVAP?",
"ground_truth": "replace(\"REF_1234_OLD\",\"OLD\", \"NEW\", ref_actualizada)\naddResult(ref_actualizada)"
},
{
"id": "limpieza_de_strings_q2",
"question": "¿Cómo se normaliza una referencia reemplazando una parte del texto con un nuevo valor en AVAP?",
"ground_truth": "replace(\"REF_1234_OLD\",\"OLD\", \"NEW\", ref_actualizada)\naddResult(ref_actualizada)"
},
{
"id": "manejo_error_sql_critico_q1",
"question": "How do you catch a database error and return a 500 status with an error message in AVAP?",
"ground_truth": "try()\n ormDirect(\"UPDATE table_inexistente SET a=1\", res)\nexception(e)\n addVar(_status, 500)\n addVar(error_msg, \"Error de base de datos\")\n addResult(error_msg)\nend()"
},
{
"id": "manejo_error_sql_critico_q2",
"question": "¿Cómo se usa try/exception para manejar un fallo en una sentencia SQL directa y responder con código 500?",
"ground_truth": "try()\n ormDirect(\"UPDATE table_inexistente SET a=1\", res)\nexception(e)\n addVar(_status, 500)\n addVar(error_msg, \"Error de base de datos\")\n addResult(error_msg)\nend()"
},
{
"id": "obtencion_timestamp_q1",
"question": "How do you get the current UTC timestamp and return it as the API response in AVAP?",
"ground_truth": "getDateTime(\"\", 0, \"UTC\", ahora)\naddResult(ahora)"
},
{
"id": "obtencion_timestamp_q2",
"question": "¿Cómo se obtiene la fecha y hora actual sin modificar el offset y se devuelve en la respuesta?",
"ground_truth": "getDateTime(\"\", 0, \"UTC\", ahora)\naddResult(ahora)"
},
{
"id": "ormAccessCreate_q1",
"question": "How do you check if a table exists and create it only if it does not in AVAP?",
"ground_truth": "ormCheckTable(tabla_pruebas,resultado_comprobacion)\nif(resultado_comprobacion,False,'==')\n ormCreateTable(\"username,age\",'VARCHAR,INTEGER',tabla_pruebas,resultado_creacion)\nend()\naddResult(resultado_comprobacion)\naddResult(resultado_creacion)"
},
{
"id": "ormAccessCreate_q2",
"question": "¿Cómo se usa ormCheckTable junto con un condicional para crear una tabla solo cuando no existe?",
"ground_truth": "ormCheckTable(tabla_pruebas,resultado_comprobacion)\nif(resultado_comprobacion,False,'==')\n ormCreateTable(\"username,age\",'VARCHAR,INTEGER',tabla_pruebas,resultado_creacion)\nend()"
},
{
"id": "paginacion_dinamica_recursos_q1",
"question": "How do you implement dynamic pagination by reading page and size parameters and slicing a list in AVAP?",
"ground_truth": "addParam(\"page\", p)\naddParam(\"size\", s)\nregistros = [\"u1\", \"u2\", \"u3\", \"u4\", \"u5\", \"u6\"]\noffset = int(p) * int(s)\nlimite = offset + int(s)\ncontador = 0\naddResult(offset)\naddResult(limite)\nstartLoop(i, 2, limite)\n actual = registros[int(i)]\n titulo = \"reg_%s\" % i\n AddvariableToJSON(titulo, actual, pagina_json)\nendLoop()\naddResult(pagina_json)"
},
{
"id": "paginacion_dinamica_recursos_q2",
"question": "¿Cómo se calculan el offset y el límite de paginación a partir de parámetros de entrada y se construye un JSON con los resultados?",
"ground_truth": "offset = int(p) * int(s)\nlimite = offset + int(s)\nstartLoop(i, 2, limite)\n actual = registros[int(i)]\n titulo = \"reg_%s\" % i\n AddvariableToJSON(titulo, actual, pagina_json)\nendLoop()\naddResult(pagina_json)"
},
{
"id": "referencia_por_valor_q1",
"question": "How do you copy the value of one variable into another using the dereference operator in AVAP?",
"ground_truth": "addVar(base, 1000)\naddVar(copia, $base)\naddResult(copia)"
},
{
"id": "referencia_por_valor_q2",
"question": "¿Cómo se usa el operador $ para pasar el valor de una variable como argumento a addVar?",
"ground_truth": "addVar(copia, $base)\naddResult(copia)"
},
{
"id": "respuesta_multiple_q1",
"question": "How do you include multiple variables in the JSON response body in AVAP?",
"ground_truth": "addVar(code, 200)\naddVar(status, \"Success\")\naddResult(code)\naddResult(status)"
},
{
"id": "respuesta_multiple_q2",
"question": "¿Cómo se agregan varios campos a la respuesta HTTP usando addResult múltiples veces?",
"ground_truth": "addResult(code)\naddResult(status)"
},
{
"id": "salida_bucle_correcta_q1",
"question": "How do you exit a loop early when a specific value is found during iteration in AVAP?",
"ground_truth": "encontrado = False\nstartLoop(i, 1, 10)\n if(i, 5, \"==\")\n encontrado = True\n i = 11 \n end()\nendLoop()\naddResult(encontrado)"
},
{
"id": "salida_bucle_correcta_q2",
"question": "¿Cómo se usa un condicional dentro de un startLoop para detectar un valor y detener la iteración?",
"ground_truth": "startLoop(i, 1, 10)\n if(i, 5, \"==\")\n encontrado = True\n i = 11 \n end()\nendLoop()"
},
{
"id": "try_catch_request_q1",
"question": "How do you wrap an external HTTP GET request in a try-exception block to handle network errors in AVAP?",
"ground_truth": "try()\n RequestGet(\"https://api.test.com/data\", 0, 0, respuesta, None)\nexception(e)\n addVar(error_trace, e)\n addResult(error_trace)\nend()"
},
{
"id": "try_catch_request_q2",
"question": "¿Cómo se captura la traza de error de una petición GET fallida y se devuelve en la respuesta?",
"ground_truth": "exception(e)\n addVar(error_trace, e)\n addResult(error_trace)\nend()"
},
{
"id": "validacion_de_nulo_q1",
"question": "How do you return a 403 error when a required API key parameter is missing in AVAP?",
"ground_truth": "addParam(\"api_key\", key)\nif(key, None, \"==\")\n addVar(_status, 403)\n addVar(error, \"Acceso denegado: falta API KEY\")\n addResult(error)\nend()"
},
{
"id": "validacion_de_nulo_q2",
"question": "¿Cómo se verifica que un parámetro no sea nulo y se responde con un código de estado HTTP de error si falta?",
"ground_truth": "if(key, None, \"==\")\n addVar(_status, 403)\n addVar(error, \"Acceso denegado: falta API KEY\")\n addResult(error)\nend()"
},
{
"id": "validacion_in_pertenece_a_lista_q1",
"question": "How do you check if a role parameter belongs to a set of allowed values using a free expression in AVAP?",
"ground_truth": "addParam(\"rol\", r)\nacceso = False\n\nif(None, None, \"r == 'admin' or r == 'editor' or r == 'root'\")\n acceso = True\nend()\n\naddResult(acceso)"
},
{
"id": "validacion_in_pertenece_a_lista_q2",
"question": "¿Cómo se usa if() en Modo 2 para evaluar si una variable pertenece a un conjunto de valores permitidos?",
"ground_truth": "if(None, None, \"r == 'admin' or r == 'editor' or r == 'root'\")\n acceso = True\nend()\n\naddResult(acceso)"
}
]

View File

@ -14,6 +14,11 @@ class OpenAIChatFactory(BaseProviderFactory):
return ChatOpenAI(model=model, **kwargs)
class AnthropicChatFactory(BaseProviderFactory):
def create(self, model: str, **kwargs: Any):
from langchain_anthropic import ChatAnthropic
return ChatAnthropic(model=model, **kwargs)
class OllamaChatFactory(BaseProviderFactory):
def create(self, model: str, **kwargs: Any):
@ -46,6 +51,7 @@ CHAT_FACTORIES: Dict[str, BaseProviderFactory] = {
"ollama": OllamaChatFactory(),
"bedrock": BedrockChatFactory(),
"huggingface": HuggingFaceChatFactory(),
"anthropic": AnthropicChatFactory(),
}

View File

@ -9,6 +9,7 @@ dependencies = [
"grpcio-reflection>=1.78.0",
"grpcio-tools>=1.78.0",
"langchain>=1.2.10",
"langchain-anthropic>=1.4.0",
"langchain-aws>=1.3.1",
"langchain-community>=0.4.1",
"langchain-elasticsearch>=1.0.0",

View File

@ -14,6 +14,11 @@ class OpenAIChatFactory(BaseProviderFactory):
return ChatOpenAI(model=model, **kwargs)
class AnthropicChatFactory(BaseProviderFactory):
def create(self, model: str, **kwargs: Any):
from langchain_anthropic import ChatAnthropic
return ChatAnthropic(model=model, **kwargs)
class OllamaChatFactory(BaseProviderFactory):
def create(self, model: str, **kwargs: Any):
@ -46,6 +51,7 @@ CHAT_FACTORIES: Dict[str, BaseProviderFactory] = {
"ollama": OllamaChatFactory(),
"bedrock": BedrockChatFactory(),
"huggingface": HuggingFaceChatFactory(),
"anthropic": AnthropicChatFactory(),
}
@ -54,7 +60,7 @@ def create_chat_model(provider: str, model: str, **kwargs: Any):
Create a chat model instance for the given provider.
Args:
provider: The provider name (openai, ollama, bedrock, huggingface).
provider: The provider name (openai, ollama, bedrock, huggingface, anthropic).
model: The model identifier.
**kwargs: Additional keyword arguments passed to the model constructor.

43
uv.lock
View File

@ -1,5 +1,5 @@
version = 1
revision = 3
revision = 2
requires-python = ">=3.11"
resolution-markers = [
"python_full_version >= '3.14' and sys_platform == 'win32'",
@ -167,6 +167,25 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
]
[[package]]
name = "anthropic"
version = "0.86.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "distro" },
{ name = "docstring-parser" },
{ name = "httpx" },
{ name = "jiter" },
{ name = "pydantic" },
{ name = "sniffio" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/37/7a/8b390dc47945d3169875d342847431e5f7d5fa716b2e37494d57cfc1db10/anthropic-0.86.0.tar.gz", hash = "sha256:60023a7e879aa4fbb1fed99d487fe407b2ebf6569603e5047cfe304cebdaa0e5", size = 583820, upload-time = "2026-03-18T18:43:08.017Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/63/5f/67db29c6e5d16c8c9c4652d3efb934d89cb750cad201539141781d8eae14/anthropic-0.86.0-py3-none-any.whl", hash = "sha256:9d2bbd339446acce98858c5627d33056efe01f70435b22b63546fe7edae0cd57", size = 469400, upload-time = "2026-03-18T18:43:06.526Z" },
]
[[package]]
name = "anyio"
version = "4.12.1"
@ -263,6 +282,7 @@ dependencies = [
{ name = "grpcio-reflection" },
{ name = "grpcio-tools" },
{ name = "langchain" },
{ name = "langchain-anthropic" },
{ name = "langchain-aws" },
{ name = "langchain-community" },
{ name = "langchain-elasticsearch" },
@ -305,6 +325,7 @@ requires-dist = [
{ name = "grpcio-reflection", specifier = ">=1.78.0" },
{ name = "grpcio-tools", specifier = ">=1.78.0" },
{ name = "langchain", specifier = ">=1.2.10" },
{ name = "langchain-anthropic", specifier = ">=1.4.0" },
{ name = "langchain-aws", specifier = ">=1.3.1" },
{ name = "langchain-community", specifier = ">=0.4.1" },
{ name = "langchain-elasticsearch", specifier = ">=1.0.0" },
@ -2140,6 +2161,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7c/06/c3394327f815fade875724c0f6cff529777c96a1e17fea066deb997f8cf5/langchain-1.2.10-py3-none-any.whl", hash = "sha256:e07a377204451fffaed88276b8193e894893b1003e25c5bca6539288ccca3698", size = 111738, upload-time = "2026-02-10T14:56:47.985Z" },
]
[[package]]
name = "langchain-anthropic"
version = "1.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anthropic" },
{ name = "langchain-core" },
{ name = "pydantic" },
]
sdist = { url = "https://files.pythonhosted.org/packages/98/c7/259d4d805c6ac90c8695714fc15498a4557bb515eb24f692fd611966e383/langchain_anthropic-1.4.0.tar.gz", hash = "sha256:bbf64e99f9149a34ba67813e9582b2160a0968de9e9f54f7ba8d1658f253c2e5", size = 674360, upload-time = "2026-03-17T18:42:20.751Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2e/c0/77f99373276d4f06c38a887ef6023f101cfc7ba3b2bf9af37064cdbadde5/langchain_anthropic-1.4.0-py3-none-any.whl", hash = "sha256:c84f55722336935f7574d5771598e674f3959fdca0b51de14c9788dbf52761be", size = 48463, upload-time = "2026-03-17T18:42:19.742Z" },
]
[[package]]
name = "langchain-aws"
version = "1.3.1"
@ -2198,7 +2233,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.2.15"
version = "1.2.22"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jsonpatch" },
@ -2210,9 +2245,9 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "uuid-utils" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cc/db/693d81b6c229aceb7c6e6809939c6ab1b023554227a25de438f00c0389c6/langchain_core-1.2.15.tar.gz", hash = "sha256:7d5f5d2daa8ddbe4054a96101dc5d509926f831b9914808c24640987d499758c", size = 835280, upload-time = "2026-02-23T15:04:49.185Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/48/e0/a6a83dde94400b43d9b091ecbb41a50d6f86c4fecacb81b13d8452a7712b/langchain_core-1.2.15-py3-none-any.whl", hash = "sha256:8d920d8a31d8c223966a3993d8c79fd6093b9665f2222fc878812f3a52072ab7", size = 502213, upload-time = "2026-02-23T15:04:47.967Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" },
]
[[package]]