Apps Guide

Apps are reusable, versioned computational units written in Cogniscript that can be compiled, stored, and executed with input parameters. They are first-class citizens in Maitento alongside Agents, Capsules, and Interactions.

Table of Contents

  1. Key Concepts
  2. App Structure
  3. App Versions
  4. Build Process
  5. Execution Flow
  6. Inputs and Outputs
  7. Process Status
  8. API Reference
  9. SDK Usage
  10. Shell Commands
  11. Cogniscript Syscalls
  12. Best Practices

Key Concepts

  • Apps represent compiled Cogniscript programs that define automation logic
  • AppVersions are immutable snapshots of an app’s code at a point in time
  • AppProcesses are running instances of an app version

Apps are written in Cogniscript, a purpose-built programming language for the Maitento ecosystem. Cogniscript provides a C-like syntax with 80+ built-in functions and 109 Maitento-specific syscalls. See the Cogniscript Language Guide for complete language documentation.


App Structure

Each App contains:

PropertyDescription
IdUnique identifier for the app
NameHuman-readable name (unique within namespace)
NamespaceIdNamespace scope for the app
VersionsList of app versions
UserCreatedByIdCreator of the app
DateCreated / DateUpdatedTimestamps

App Versions

Each version includes:

PropertyDescription
VersionInteger version number (starts at 1)
InputsArray of input parameter definitions
FileChecksumMD5 checksum of compiled binary
ExecutionTimeLimitOptional timeout for execution
IsDisabledWhether this version can be executed
ExternalOperationsMCP/OpenAPI bindings

Versions are immutable once created. To update app logic, create a new version rather than modifying existing ones. This ensures traceability and allows rollback to previous versions if needed.


Build Process

Apps go through a three-phase build process:

  1. Compile Phase: Cogniscript source code is compiled into operations
  2. Reference Resolution: External bindings (MCP, OpenAPI) are validated
  3. Create & Deploy: Binary is persisted to storage ({tenantId}/apps/{appId}/{version}.mtb)

The compilation pipeline transforms your Cogniscript source through tokenization, parsing, assembly generation, and finally produces executable bytecode that runs on the Cogniscript Virtual Machine.


Execution Flow

  1. AppService.Start() creates an AppProcess with status New
  2. AppProcessRunner.Run() loads the compiled app, validates checksum, and maps inputs
  3. AppExecutor.ExecuteApp() runs the VM in a dedicated thread
  4. Process status updates to Running, then Finished, Error, or Killed

Inputs and Outputs

Supported Data Types

Apps support the following data types for inputs and outputs:

TypeDescription
StringText value
IntegerWhole number
DecimalFloating-point number
GuidUUID identifier
BoolBoolean true/false
DateDate/time value
JsonObjectJSON object
JsonArrayJSON array

Reading Inputs in Cogniscript

// Read inputs
var value = appState.getInput("paramName")

// Set outputs
appState.setOutputString("result", "value")
appState.setOutputInteger("count", 42)

// Chain apps
var processId = app.start("appName@namespace", { "input": "value" })

// Query apps
var appInfo = app.get("appName@namespace")
var apps = app.list("namespace")

Process Status

Status Values

StatusDescription
NewProcess created but not yet started
RunningProcess is actively executing
HumanInteractionRequiredWaiting for user input
WaitingToResumeQueued to resume after pause
PausedExecution is paused
FinishedCompleted successfully
ErrorTerminated due to error
KilledManually terminated

Pause Types

TypeDescription
NoneNot paused
AppPaused by app logic (e.g., waiting for another app)
InteractionPaused for human interaction
CodeGenerationPaused during AI code generation

API Reference

Endpoints

EndpointMethodDescription
/appsGETList all apps
/namespaces/{ns}/appsGETList apps in namespace
/namespaces/{ns}/appsPOSTCreate app
/apps/by-id/{id}GETGet app by ID
/namespaces/{ns}/apps/by-name/{name}GETGet app by name
/apps/by-id/{id}/versions/{v}/startPUTStart app by ID/version
/namespaces/{ns}/apps/by-name/{name}/versions/latest/startPUTStart latest version
/apps/processes/by-id/{id}GETGet process by ID
/apps/processes/by-id/{id}/inputsPUTUpdate process inputs
/namespaces/{ns}/apps/processesGETList active processes

Authentication

All endpoints require authentication:

MethodHeaderDescription
Bearer TokenAuthorization: Bearer <token>JWT token
API KeyX-Api-Key: <api-key>API key

Required Roles: Tenant.Admin or Tenant.User


SDK Usage

Working with Apps

// Create client
var client = MaitentoClient.Create("your-api-key");

// List all apps
App[] allApps = await client.Apps.GetAllAsync();

// Get app by name
App? app = await client.Apps.GetByNameAsync("production", "data-processor");

// Start an app with inputs
NameValuePair[] inputs = new[]
{
    new NameValuePair("reportType", "monthly"),
    new NameValuePair("outputFormat", "pdf")
};

AppProcess process = await client.Apps.StartAsync(
    "production",
    "report-generator",
    inputs
);

Console.WriteLine($"Started process: {process.Id}");

// Poll for completion
while (process.Status == AppProcessStatus.Running ||
       process.Status == AppProcessStatus.New)
{
    await Task.Delay(1000);
    process = await client.Apps.GetProcessAsync(process.Id) ?? process;
}

Console.WriteLine($"Final Status: {process.Status}");
Console.WriteLine($"Return Value: {process.ReturnValue}");

// Handle human interaction
if (process.Status == AppProcessStatus.HumanInteractionRequired)
{
    NameValuePair[] additionalInputs = new[]
    {
        new NameValuePair("approvalDecision", "approved")
    };

    process = await client.Apps.ProcessPatchInputs(process.Id, additionalInputs);
}

Exception Handling

try
{
    var process = await client.Apps.StartAsync(...);
}
catch (MaitentoValidationException ex)
{
    Console.WriteLine("Validation errors:");
    foreach (var error in ex.ValidationErrors)
    {
        Console.WriteLine($"  {error.Key}: {string.Join(", ", error.Value)}");
    }
}
catch (MaitentoApiException ex)
{
    Console.WriteLine($"API error ({ex.StatusCode}): {ex.ResponseBody}");
}
catch (MaitentoApiAuthenticationException ex)
{
    Console.WriteLine("Authentication failed - check your API key");
}

Shell Commands

Listing Apps

# List all apps in default namespace
app-list

# List apps in specific namespace
app-list --namespace production

Getting App Details

# Get app details
app-get data-processor --namespace production

Starting Apps

# Start an app (fire and forget)
app-start report-generator --namespace production

# Start with inputs
app-start data-processor --input-file-path "/data/input.csv" --input-batch-size 100

# Run and wait for completion
app-run simple-task --namespace production

Monitoring Apps

# List running processes
app-ps --namespace production

# Attach to a running process
app-attach a1b2c3d4-e5f6-7890-abcd-ef1234567890

Cogniscript Syscalls

The following syscalls are available for working with Apps from within Cogniscript code:

SyscallDescriptionParametersReturns
AppListList all appsnamespaceNameApp[] JSON
AppGetGet app by namename*App JSON
AppStartStart app processname*, inputs (JsonObject)ProcessId
AppProcessGetGet process detailsprocessId*AppProcess JSON
AppStateGetInputGet input valuename*String or null
AppStateSetInputSet input valuename*, value*void
AppStateSetOutputStringSet string outputname*, valuevoid
AppStateSetOutputIntegerSet integer outputname*, valuevoid
AppStateSetOutputBoolSet boolean outputname*, valuevoid
AppStateSetOutputDecimalSet decimal outputname*, valuevoid
AppStateSetOutputGuidSet GUID outputname*, valuevoid
AppStateSetOutputDateSet date outputname*, valuevoid
AppStateSetOutputJsonObjectSet JSON object outputname*, valuevoid
AppStateSetOutputJsonArraySet JSON array outputname*, valuevoid

Example: Maitento Integration

void main() {
    // Create a VFS file
    VfsWriteText("data", "default", "/logs/output.txt", "Processing started...");

    // Start an app process
    jsonObject inputs = JsonObjectCreate();
    inputs = JsonObjectSetString(inputs, "task", "analyze");

    string processId = AppStart("data-processor", inputs);
    PrintLine("Started process: " + processId);

    // Wait for completion
    string process = AppProcessGet(processId);
    PrintLine("Process status: " + process);
}

Best Practices

  1. Versioning: Create new versions rather than modifying existing ones for traceability
  2. Inputs: Define clear input types and validate early in your Cogniscript code
  3. Timeouts: Set appropriate ExecutionTimeLimit to prevent runaway processes
  4. Composition: Use app.start() to chain apps for complex workflows
  5. Error Handling: Always check process status and handle errors appropriately
  6. Outputs: Use typed output methods (setOutputString, setOutputInteger, etc.) for type safety