assistance-engine/docs/AVAP Language: Core Command.../AVAP.md

26 KiB

SECTION I: Architecture, Memory, and Fundamentals

This section sets the foundations of how AVAP manages service logic and data manipulation in memory. Unlike conventional interpreted languages, AVAP uses a hybrid evaluation engine that allows combining declarative commands with dynamic expressions.


1.1 Endpoint Registration (registerEndpoint)

The registerEndpoint command is the atomic unit of configuration. It acts as the bridge between the network (HTTP) and the code.

Interface

registerEndpoint(path, method, middleware, description, handler, output)

Parameter Specification

  • path (String): Defines the URL path. It supports static routes and is prepared for future implementations of path parameters (variable segments).

  • method (String): Specifies the allowed HTTP verb (GET, POST, PUT, DELETE). The server will automatically reject any request that does not match this method (Error 405).

  • middleware (List): A list of functions that are executed sequentially before the handler. Ideal for JWT token validations or maintenance checks. If a middleware function fails, the flow stops before reaching the main code.

  • description (String): Metadata for automatic documentation (Swagger/OpenAPI). It does not affect execution but is vital for the development lifecycle.

  • handler (Function): The logical Entry Point. It is the name of the main function where the business logic resides.

  • output (Variable): Defines the "master" variable that the engine will automatically return upon completion, unless additional results are specified via addResult.


1.2 Variable Assignment Engine (Dynamic Assignment)

AVAP allows a direct assignment syntax using the = symbol, which grants flexibility similar to languages like Python, but under strict context control.

Internal Mechanics: The eval Process

When the interpreter finds an instruction of the type variable = expression, it activates a three-step process:

  1. Cleaning and Tokenization: The engine identifies if the expression contains references to existing variables (using $), method calls, or literals.

  2. Expression Evaluation: Operations are resolved in real-time. This allows:

    • Boolean Logic: is_valid = (age > 18 and has_permission == True).

    • Arithmetic: tax = subtotal * 0.21.

    • String Formatting: query = "SELECT * FROM users WHERE id = %s" % recovered_id.

  3. Object and Property Resolution: Allows deep access to complex structures returned by database connectors or APIs: client_email = user_list[0].profile.email.

Effect on Memory

Unlike addVar, dynamic assignment is capable of transforming the variable type on the fly (Mutable Type System). If a variable contained a number and is assigned a string after evaluation, the engine updates the variable metadata automatically.


1.3 State Initialization and References (addVar)

addVar is the fundamental command to define the global state of the script.

Interface

addVar(targetVarName, varValue)

Advanced Behavior

  • Intelligent Automatic Typing: The engine inspects varValue. If it detects a numerical format (even if it comes as a string from configuration), it will internally convert it to int or float. It supports the use of commas and periods interchangeably, normalizing the value for mathematical operations.

  • The Reference Prefix $: This is the dereferencing operator.

    • addVar(copy, $original): Indicates to the engine that it should not assign the string "$original", but look in the symbol table for the current value of the variable original and copy it.
  • Scope: Variables created with addVar in the main body of the script are considered Request Session Variables, meaning they live during the entire execution lifecycle of that specific API call, but are isolated from other concurrent requests to guarantee data security (Thread-Safety).

Syntax Usage Description
name = "Juan" Direct Assignment Creates a simple text string.
total = $price * 1.10 Dynamic Evaluation Uses the value of price for a calculation and saves the result.
addVar(status, 200) Initialization Explicit method to ensure creation in the global context.
data = res[0].info Object Access Extracts a specific property from a JSON object or DB result.

SECTION II: Input and Output (I/O) Management

This section describes the mechanisms that AVAP uses for external data ingestion, parameter integrity validation, and constructing the response package that will be delivered to the final client.


2.1 Intelligent Parameter Capture (addParam)

The addParam command is the component in charge of extracting information from the incoming HTTP request. Its design is source-agnostic, which simplifies development by not requiring the programmer to specify where the data comes from.

Interface

addParam(param_name, target_variable)

When addParam is invoked, the AVAP engine inspects the request in the following hierarchical order:

  1. Query Arguments: Parameters present in the URL (e.g., ?id=123).

  2. JSON Body: If the request has a Content-Type: application/json, it looks for the key inside the JSON object.

  3. Form Data / Body Arguments: Data sent via standard forms (x-www-form-urlencoded).

Technical Behavior

  • Automatic Decoding: The engine attempts to decode values to ASCII/UTF-8 format, eliminating encoding inconsistencies.

  • Null Treatment: If the requested parameter does not exist in any of the sources, the target variable (target_variable) is initialized as None. This allows performing subsequent security checks via if blocks.


2.2 Validation and Collection Counting (getListLen)

To guarantee that an API is robust, it is necessary to validate how much information has been received. getListLen acts as AVAP's volume inspector.

Interface

getListLen(source_variable, target_variable)

I/O Applications

  • Parameter Validation: Allows counting how many elements a variable contains that has been populated by addParam or getQueryParamList.

  • Loop Security: Before starting a startLoop, it is recommended to use getListLen to define the upper limit of the cycle, avoiding overflow errors.

  • Database Results: After a query, it determines if records were obtained (length > 0) or if the query resulted empty.


2.3 Multiple List Capture (getQueryParamList)

Scenarios exist where the same parameter is sent several times (e.g., search filters like ?color=red&color=blue). AVAP manages this through a specialized capture in lists.

Interface

getQueryParamList(param_name, target_list_variable)

Effect

Transforms all occurrences of param_name into a structured list inside target_list_variable. If there is only one value, it creates a single-element list. This ensures that subsequent logic can always treat the data as a collection, avoiding type errors.


2.4 Construction of the Response (addResult)

The addResult command is in charge of registering which variables will be part of the response body. AVAP dynamically constructs a JSON output object based on calls to this command.

Interface

addResult(source_variable)

Advanced Features

  • Promise Management: If the variable passed to addResult is the result of an operation initiated with go_async, the engine will automatically mark that field as "promised" in the response, or return the thread ID if synchronization has not completed.

  • String Cleaning: The engine detects if the content of the variable has redundant quotes (product of previous evaluations) and normalizes them to ensure that the resulting JSON is valid and clean.

  • Multi-Registration: Multiple calls to addResult can be made. Each call adds a new key to the output JSON object. By default, the key in the JSON will be the variable name, unless a custom key is used in the engine.


2.5 HTTP Status Control (_status)

AVAP uses a reserved system variable to communicate with the underlying web server and define the success or error code of the transaction.

Use of _status

When assigning a numerical value to the _status variable (using addVar or direct assignment), the programmer defines the HTTP code of the response.

Code Common Use in AVAP
200 Successful operation (Default value).
201 Resource successfully created.
400 Parameter validation error (Bad Request).
401 Authentication failure.
500 Internal error captured in an exception block.

Section II Integrated Example

// We capture input
addParam("user_id", id)

// We validate presence
if(id, None, '==')
    addVar(_status, 400)
    addVar(error, "The user ID is mandatory")
    addResult(error)
    return()
end()

// If we reach here, we respond with success
addVar(_status, 200)
addResult(id)

SECTION III: Control Logic and Decision Structures

This section details how AVAP manages execution flow. The language uses closed block structures that allow for a clear sequential reading, facilitating the debugging of complex APIs.


3.1 The Conditional Block (if / else / end)

The if structure in AVAP is a versatile tool that allows for atomic comparisons or the evaluation of complex logical expressions processed by the dynamic evaluation engine.

Standard Interface

if(variable_A, valor_B, operador)

Available Operators

Operator Description Example
= Strict equality (or numerical equivalence). if(rol, "admin", "=")
!= Inequality. if(status, 200, "!=")
> / < Numerical magnitude comparison. if(edad, 18, ">")
in Checks if an element belongs to a list or string. if(user, lista_negra, "in")

Evaluation of Complex Expressions

AVAP allows omitting comparison parameters to evaluate a complete logical expression directly in the third parameter.

  • Example: if(None, None, "age >= 18 and balance > 100").

Closing Structure

Every if block can include an optional else() block and must end with the end() command.


3.2 Iterations and Loops (startLoop / endLoop)

For the processing of collections (like database rows or parameter lists), AVAP implements a repetition cycle controlled by indices.

Interface

startLoop(contador, inicio, fin)

Execution Mechanics

  1. Initialization: The engine creates the contador variable with the value of inicio.

  2. Increment: In each turn, the counter increases automatically by 1 unit.

  3. Exit Condition: The loop stops when the contador exceeds the value of fin.

Practical Example: List Processing

// We obtain the length of a list captured in Section II
getListLen(items_received, total)

startLoop(i, 0, total)
    current_item = items_received[i]
    // Processing logic for each item...
endLoop()

3.3 Error Management and Robustness (try / exception)

AVAP is a language designed for production environments where external failures (database timeout, down third-party APIs) are a reality. The try block allows capturing these events without stopping the server.

Interface

try ... exception(error_variable) ... end()

Technical Operation

  • try Block: The engine attempts to execute the instructions contained within. If a critical failure occurs, it stops execution of that block immediately.

  • exception Block: If an error is detected, control passes to this block. The error_variable is automatically populated with a string describing the failure (simplified Stack trace).

  • end() Block: Closes the structure and allows the script to continue its normal execution after the error handling.

Example of Security in Connectors

try
    // We attempt a query to an external connector (Section V)
    resultado = db.query("SELECT * FROM pagos")
exception(failure_detail)
    // If it fails, we log the error and notify
    addVar(_status, 500)
    addVar(message, "Persistence error: %s" % failure_detail)
    addResult(message)
end()

3.4 Premature Exit Control (return)

The return() command is a control instruction that immediately terminates the execution of the current context (be it a function or the main script).

  • If used within a function, it returns control (and optionally a value) to the caller.

  • If used in the main flow, it ends execution of the API and triggers the automatic sending of the JSON response built up to that moment.


Summary of Section III: With these structures, the AVAP programmer has total control over the dynamic behavior of the code. The combination of Dynamic Evaluation (Section I), Data Validation (Section II) and Control Structures (Section III) allows for building extremely complex and secure microservices.

SECTION IV: Concurrency and Asynchrony

AVAP implements a concurrency model based on threads that allows for "fire-and-forget" or parallel execution with subsequent synchronization. This is fundamental for tasks like sending emails, processing logs or querying multiple external APIs simultaneously.


4.1 Launching Background Processes (go_async)

The command go_async extracts a block of code from the main sequential flow and places it in a parallel execution queue.

Interface

go_async(thread_id)

Execution Mechanics

  1. Identification: The programmer assigns a thread_id (a string or variable) to be able to reference that process later.

  2. Bifurcation (Forking): As soon as it is invoked, the AVAP engine creates a new native thread. The main flow immediately continues to the next instruction after the go_async block.

  3. Context Isolation: The asynchronous thread inherits a copy of the state of the variables at the moment of firing, allowing it to work safely without interfering with the main thread.

Example: Immediate Response with Long Process

addParam("email", destination)

go_async("email_delivery")
    // This block takes 5 seconds, but the API does not wait
    email_service.send(destination, "Welcome to AVAP")
end()

addVar(msg, "Your email is being processed in the background")
addResult(msg)
// The client receives the response in milliseconds

4.2 Result Synchronization (gather)

When the main flow needs data generated by an asynchronous thread to continue, the gather synchronization mechanism is used.

Interface

gather(thread_id, timeout)

Specifications

  • thread_id: The identifier used in the go_async command.

  • timeout (Seconds): Maximum time that the main thread will wait. If the thread does not finish in this time, AVAP launches an exception that can be captured (Section III).

Technical Behavior

  • Controlled Blocking: The main thread stops (suspends) until the thread_id thread finishes.

  • State Recovery: Once synchronized, any variable modified inside the asynchronous thread is fused with the context of the main thread.


4.3 Optimized Parallel Execution (Fan-Out Pattern)

AVAP allows launching multiple threads and then waiting for all of them, reducing total execution time to the time of the slowest thread, instead of the sum of all.

Example: Querying multiple databases

go_async("db_north")
    data_north = connector_north.query("SELECT...")
end()

go_async("db_south")
    data_south = connector_south.query("SELECT...")
end()

// We wait for both (Maximum 10 seconds)
gather("db_north", 10)
gather("db_south", 10)

// We combine results using Section I
total_result = data_north + data_south
addResult(total_result)

4.4 Status of Promises in the Output

As mentioned in Section II, if a variable that is still being processed in an asynchronous thread is sent to addResult, AVAP manages the response intelligently:

  • If the thread still runs: The output JSON will show "variable": "promised" or the thread ID.

  • If the thread failed: The error will be registered in the internal log and the variable will be None.

  • If gather was used before addResult: The real processed value will be sent.

SECTION V: Persistence, Connectors and Native ORM

AVAP is designed to be database agnostic. It allows data manipulation through three layers: the universal connector, simplified ORM commands and direct SQL execution.


5.1 The Universal Connector (avapConnector)

The avapConnector command is the starting point for any external integration. It uses a system of Connection Tokens (Base64) that encapsulate the configuration (host, port, credentials, driver) to keep the code clean and safe.

Interface

connector_variable = avapConnector("BASE64_TOKEN")

Characteristics of Connector Objects

Once the variable is instantiated, it behaves as an object with dynamic methods:

  • DB Connectors: Expose the .query(sql_string) method, which returns objects or lists according to the result.

  • API Connectors (Twilio, Slack, etc.): Expose native methods of the service (e.g., .send_sms()).

Example: Use of Dynamic Assignment with Connectors

// We instantiate the connection
db = avapConnector("REJfQ09OTkVDVE9SR...")

// We execute and use Section I to filter on the fly
users = db.query("SELECT * FROM users")
first_admin = users[0].name if users[0].role == 'admin' else 'N/A'

addResult(first_admin)

5.2 Native ORM Layer (ormCheckTable / ormDirect)

For quick operations on the local or default database cluster, AVAP offers system-level commands that do not require prior instantiation.

5.2.1 ormCheckTable

Verifies the existence of a structure in the database. It is vital for installation scripts or automatic migrations.

  • Interface: ormCheckTable(table_name, target_var)

  • Response: The target_var will receive the string values "True" or "False".

5.2.2 ormDirect

Executes SQL commands directly. It differs from .query() in that it is optimized for statements that do not necessarily return rows (like INSERT, UPDATE or CREATE TABLE).

  • Interface: ormDirect(statement, target_var)

  • Use of Interpolation: ormDirect("UPDATE users SET login = '%s' WHERE id = %s" % (now, id), result)


5.3 Data Access Abstraction (Implicit Commands)

AVAP includes specialized commands for the most common CRUD operations, reducing the need to write manual SQL and mitigating injection risks.

ormAccessSelect

Performs filtered queries returning a structure of object lists.

  • Syntax: ormAccessSelect(table, filters, target)

ormAccessInsert / ormAccessUpdate

Manages data persistence. If used on an object that already has an ID, Update synchronizes changes; otherwise, Insert creates the record.


5.4 Dynamic Query Formatting (Anti-Injection)

As detailed in Section I, the AVAP engine processes SQL strings before sending them to the database engine. The official recommendation is to always use interpolation using the % operator to ensure that data types (Strings vs Integers) are correctly treated by the driver.

// Safe and Recommended Way
sql = "SELECT * FROM %s WHERE status = '%s'" % (table_name, status_recovered)
res = db.query(sql)

5.5 Cryptographic Security Integration (encodeSHA256)

In the persistence flow, AVAP provides native tools to secure sensitive data before it touches the disk.

Interface

encodeSHA256(source_text, target_variable)

Full Registration Flow (Final Example)

This example joins Sections I, II, III and V:

// II: Capture
addParam("pass", p)
addParam("user", u)

// I and V: Processing and Security
encodeSHA256(p, secure_pass)

// V: Insertion
sql = "INSERT INTO users (username, password) VALUES ('%s', '%s')" % (u, secure_pass)
ormDirect(sql, db_result)

// III and II: Response
if(db_result, "Success", "=")
    addVar(msg, "User created")
    addResult(msg)
end()

SECTION VI: System Utilities and Transformation

This section documents the native commands for advanced string manipulation, precise time handling and generation of dynamic data.


6.1 Time and Date Management (getDateTime / stampToDatetime)

AVAP handles time in two ways: as Epoch/Timestamp (numerical, ideal for calculations) and as Datetime (formatted text, ideal for humans and databases).

6.1.1 getDateTime

Generates current time with high precision.

  • Interface: getDateTime(format, timeDelta, timeZone, targetVar)

  • Parameters:

    • format: Ej: "%Y-%m-%d %H:%M:%S". If left empty, returns the current Epoch.

    • timeDelta: Seconds to add (positive) or subtract (negative). Very useful for calculating token expiration.

    • timeZone: Time zone region (ej: "Europe/Madrid").

6.1.2 stampToDatetime

Converts a numerical value (Unix Timestamp) into a legible text string.

  • Interface: stampToDatetime(timestamp, format, offset, targetVar)

  • Common use: Formatting dates recovered from the database (Section V) before sending them to the client (Section II).


6.2 Advanced String Manipulation (replace / randomString)

6.2.1 replace

Allows for cleaning and transformation of texts. It is fundamental when data is received from the client that requires sanitization.

  • Interface: replace(sourceText, oldText, newText, targetVar)

  • Example: Cleaning spaces or unwanted characters in a username before a SQL query.

6.2.2 randomString

Generates secure random alphanumeric strings.

  • Interface: randomString(length, targetVar)

  • Applications: Generation of temporary passwords, session IDs or unique file names.


6.3 Security and Hash Operations (encodeSHA256)

Although mentioned in persistence, its use is a data transformation utility.

  • Mechanics: It is a deterministic one-way function.

  • Important: AVAP uses an optimized implementation that guarantees that the same text always produces the same hash, allowing secure "login" comparisons without knowing the real password.


6.4 The Value Return Command (return)

In the context of functions and flows, return not only stops execution, but can "inject" the result of a sub-routine into the main flow.

Example of complete utility flow:

// 1. We generate a temporary token
randomString(16, token_raw)

// 2. We calculate expiration (within 1 hour = 3600 seg)
getDateTime("%Y-%m-%d %H:%M:%S", 3600, "UTC", expiration_date)

// 3. We format a system message using Section I
message = "Your token %s expires on %s" % (token_raw, expiration_date)

// 4. We send to the client (Section II)
addResult(message)

6.5 Table of Common Formats (Cheat Sheet)

Token Description Example
%Y Full year 2026
%m Month (01-12) 02
%d Day (01-31) 23
%H Hour (00-23) 21
%M Minute (00-59) 45

SECTION VII: Function Architecture and Scopes

This section details how to encapsulate reusable logic and how AVAP manages isolated memory to avoid side effects between different parts of the program.


7.1 Definition and Declaration (function)

A function in AVAP is an independent block of code that is registered in the engine to be invoked at any moment.

Interface

function function_name(argument1, argument2, ...){ ... }

Technical Characteristics:

  • Local Scope (function_local_vars): Upon entering a function, AVAP creates a new dictionary of local variables. Variables created within (ej. temp = 10) do not exist outside the function, protecting global state.

  • Context Inheritance: Functions can read global variables using the $ prefix, but any new assignment (=) will remain in local scope unless a global persistence command is used.


7.2 The Exit Command (return)

It is the mechanism to finalize function execution and, optionally, send a value back to the caller.

Interface

return(variable_or_value)

Behavior:

  1. Finalization: Immediately stops processing of the function.

  2. Data Transfer: The value passed to the return is injected into the variable that performed the call in the main flow.

  3. Cleaning: Once return is executed, the dictionary of local variables of that function is destroyed to free memory.


7.3 Invocation and Parameter Passing

Functions are called by their name followed by the values or variables they require.

Example of Professional Implementation:

// Function Definition (Local Scope)
function calculate_discount(base_price, percentage){
    factor = percentage / 100
    discount = base_price * factor
    total = base_price - discount
    return(total)
}

// Main Flow (Global Scope)
addVar(pvp, 150)
// Call to the function passing a reference $ and a literal value
final_price = calculate_discount($pvp, 20)

addResult(final_price) // Result: 120

7.4 Functions as Middlewares

In the registerEndpoint command (Section I), the middleware parameter accepts a list of functions. These functions have special behavior:

  • If a middleware executes a return() without a value or with an error value, AVAP can be configured to abort the request before reaching the main handler.

  • They are ideal for Guard tasks:

    • API Key verification.

    • Data schema validation.

    • Initial audit registration (logs).


7.5 Recursivity and Limits

AVAP allows recursivity (a function calling itself), but caution is recommended regarding stack depth for asynchronous processes (Section IV). To process large data volumes, the use of startLoop (Section III) is always preferable.