Open Ticket AI Runtime – Python Automation for OTOBO
Open Ticket AI Runtime
Section titled “Open Ticket AI Runtime”In this guide: What the OTAI Runtime is, how its pipe system works, and how it connects to OTOBO for custom automation — including non-AI workflows.
Related: Generic Agent · Web Services · REST API · OpenTicketAI product overview · OTOBO AI features
When built-in tools like the Generic Agent or Process Management reach their limits, you need a way to express richer logic: fetch tickets, evaluate conditions, call external APIs, update fields, and repeat — all under your control and on your infrastructure.
Open Ticket AI Runtime (OTAI Runtime) is an open-source, Python-based automation engine for exactly that. Despite the name, it is not limited to AI. You can use it for classical ticket routing, field updates, scheduled jobs, and integrations — and add AI classification or summarization only where it helps.
Source code: github.com/Softoft-Orga/open-ticket-ai (LGPL-2.1)
Table of Contents
Section titled “Table of Contents”- What OTAI Runtime does
- Pipes: if this, then do that
- How it connects to OTOBO
- Quick start
- Example: classify and route tickets
- Extend with Python plugins
- When to use OTAI vs built-in automation
- Further reading
What OTAI Runtime does
Section titled “What OTAI Runtime does”OTAI Runtime runs as a containerized Python service (Docker or pip install) between your helpdesk and any logic you define. For OTOBO, it typically:
- Ingests tickets — via the Generic Interface (Web Services) using a dedicated technical user.
- Runs a pipeline — a sequence of pipes that pass context from step to step.
- Executes actions — update queue, priority, dynamic fields, add notes, call external systems, or run ML models locally.
- Logs everything — each pipe result is traceable for auditing and debugging.
Because processing stays on-premise, ticket content does not need to leave your network — an important difference from cloud-only automation tools.
flowchart LR
OTOBO["OTOBO\n(Generic Interface)"]
RT["OTAI Runtime\n(Python pipelines)"]
AI["Optional:\nlocal ML / LLM"]
EXT["Optional:\nexternal APIs"]
OTOBO <-->|REST| RT
RT --> AI
RT --> EXT
RT -->|update tickets| OTOBO
Pipes: if this, then do that
Section titled “Pipes: if this, then do that”The core idea is pipes: small, composable processing units wired together in YAML. Each pipe receives a shared context (results from earlier steps), runs its task, and produces a PipeResult for the next step.
Think of it as if this, then do that, chained:
| Pattern | Pipe type | Behavior |
|---|---|---|
| When (trigger) | IntervalTrigger, ExpressionPipe | Run only every N seconds, or when a condition is true |
| If (guard) | ExpressionPipe with fail() | Stop the pipeline when a check fails |
| Then (action) | FetchTicketsPipe, UpdateTicketPipe, AddNotePipe | Read or change tickets in OTOBO |
| Else / skip | SimpleSequentialRunner | Run run only when on succeeded |
Simple pipes
Section titled “Simple pipes”Atomic steps with one job — for example fetch tickets from a queue:
- id: fetch_tickets use: base:FetchTicketsPipe injects: ticket_system: otobo_znuny params: ticket_search_criteria: queue: name: Incoming limit: 10Composite pipes (multi-step workflows)
Section titled “Composite pipes (multi-step workflows)”A CompositePipe runs child steps in order and merges their results — ideal for full workflows:
- id: ticket_workflow use: base:CompositePipe steps: - id: fetch use: base:FetchTicketsPipe injects: { ticket_system: otobo_znuny } params: ticket_search_criteria: queue: { name: Incoming } limit: 10
- id: guard use: base:ExpressionPipe params: expression: > {{ fail() if (get_pipe_result('fetch', 'fetched_tickets') | length) == 0 else 'ok' }}
- id: update use: base:UpdateTicketPipe injects: { ticket_system: otobo_znuny } params: ticket_id: "{{ get_pipe_result('fetch', 'fetched_tickets') | first | attr('id') }}" updated_ticket: queue: name: SupportConditional execution
Section titled “Conditional execution”SimpleSequentialRunner implements classic if-then logic: execute run only when on succeeds (for example, when an interval trigger fires):
- id: run-when-triggered use: base:SimpleSequentialRunner params: on: id: gate use: base:IntervalTrigger params: { interval: PT60S } run: id: do-something use: base:ExpressionPipe params: { expression: Triggered run }Pipes share data through Jinja2 templates. Use get_pipe_result('pipe_id', 'data_key') to read output from earlier steps and has_failed('pipe_id') to branch on errors.
For background polling (daemon-style loops), SimpleSequentialOrchestrator repeats its steps endlessly — useful for continuous ticket processing.
How it connects to OTOBO
Section titled “How it connects to OTOBO”OTAI Runtime talks to OTOBO through the Generic Interface, the same mechanism described in Web Services and the REST API reference.
Typical setup:
- Technical user — create an agent such as
open_ticket_aiwith only the permissions your pipeline needs (ro,move_into,priority,note, etc.). - Web service — import the bundled
OpenTicketAI.ymltemplate from the GitHub repository. It exposes restricted REST operations (ticket-search,ticket-get,ticket-update,ticket-create) and maps all requests to the technical user. - Runtime config — point OTAI at your OTOBO URL and credentials via environment variables and
config.yml.
The OTOBO-side steps mirror a standard Web Services integration; the runtime adds the Python pipeline layer on top.
Detailed setup: OTOBO / Znuny plugin setup (Open Ticket AI docs)
Quick start
Section titled “Quick start”Install via pip
Section titled “Install via pip”pip install open-ticket-ai
# OTOBO/Znuny connector and optional local ML pluginspip install open-ticket-ai otai-otobo-znuny otai-hf-localRun with Docker
Section titled “Run with Docker”docker pull openticketai/engine:latestservices: open-ticket-ai: image: openticketai/engine:latest ports: - "8080:8080" environment: OT_AI_CONFIG: /app/config.yml volumes: - ./config.yml:/app/config.yml:roClone the repository for development:
git clone https://github.com/Softoft-Orga/open-ticket-ai.gitcd open-ticket-aiuv syncuv run -m pytestExample: classify and route tickets
Section titled “Example: classify and route tickets”The same pipe model supports AI and non-AI steps. A classification pipe can sit between fetch and update:
- id: classify use: otai_hf_local:HFLocalTextClassificationPipe params: model: bert-base-german-cased text: "{{ get_pipe_result('fetch', 'fetched_tickets') | first | attr('subject') }}"
- id: update use: base:UpdateTicketPipe injects: { ticket_system: otobo_znuny } params: ticket_id: "{{ get_pipe_result('fetch', 'fetched_tickets') | first | attr('id') }}" updated_ticket: queue: name: "{{ get_pipe_result('classify', 'predicted_queue') }}"Replace the classification pipe with any other pipe — keyword matching, HTTP calls, database lookups — and the workflow structure stays the same.
Extend with Python plugins
Section titled “Extend with Python plugins”Every pipe is a Python class registered in the pipe registry (base:FetchTicketsPipe, base:UpdateTicketPipe, …). You can:
- Configure existing pipes in YAML (no code required for many automations).
- Install community plugins from the plugin marketplace.
- Write custom pipes in Python when you need proprietary business logic, then reference them with
use: your_plugin:YourPipe.
The runtime uses dependency injection, structured logging, and pytest-based testing — see the developer documentation on openticketai.com.
When to use OTAI vs built-in automation
Section titled “When to use OTAI vs built-in automation”| Need | Built-in OTOBO | OTAI Runtime |
|---|---|---|
| Simple rules (queue, priority, time) | Generic Agent | Usually overkill |
| Guided agent/customer flows | Process Management | Different purpose |
| REST integration with external systems | Web Services | OTAI uses this under the hood |
| Multi-step logic, Python, ML, custom APIs | Limited | OTAI Runtime |
| On-premise AI without cloud APIs | Not built in | OTAI Runtime + local model plugins |
| Fully custom automation without AI | Generic Agent or scripts | OTAI Runtime (pipes, no ML required) |
Further reading
Section titled “Further reading”- GitHub repository: github.com/Softoft-Orga/open-ticket-ai
- Official OTAI Runtime docs: openticketai.com/en/docs/otai-runtime/
- Pipe system reference: Pipe System
- First pipeline tutorial: First Pipeline
- Product / AI solutions: OpenTicketAI for OTOBO
License: LGPL-2.1-only — suitable for extending and integrating in enterprise environments while keeping custom pipe code under your control.