Skip to content

Cheat sheet

A one-page reference for building modules. Follow the links for the full explanation of each topic.

Module layout

my_module/
├── module.yaml          # the manifest (required)
├── __init__.py
├── models/              # your models (Python)
│   ├── __init__.py
│   └── ticket.py
├── views/               # list/form/kanban/search + actions + menus (XML)
│   └── helpdesk.xml
├── data/                # seed records (XML)
│   └── demo.xml
├── agents/              # agent declarations (Python)
├── skills/              # SKILL.md files
├── tools/               # @tool functions (Python)
├── workflows/           # workflow YAML
├── automations/         # automation YAML
└── triggers/            # trigger YAML

See Module structure & manifest.

module.yaml keys

Key Required Meaning
name Technical id of the module (snake_case).
version Module version, e.g. 1.0.0.
label Human-readable name (defaults to name).
author Author/vendor name.
requires Modules this one depends on, e.g. [base, contact].
models Python module(s)/package to import your models from, e.g. [models].
data Data/view XML files to load, in order, e.g. [views/helpdesk.xml, data/demo.xml].
agents Python module(s) declaring agents.
tools Python module(s) declaring @tool functions.
actions Python module(s) declaring server @action functions.
workflows Workflow YAML files.
automations Automation YAML files.
triggers Trigger YAML files.
skills Skill folders (each holding a SKILL.md).
installable false hides the module from installation (default true).
default_install true installs it automatically as part of the base set.
hooks Map of lifecycle hooks, e.g. { pre_init: "hooks:setup" }.

Field types

Import from victor.fields. Every field accepts label, and unless noted, required, default, and secret.

Field Required kwargs Notes
String Single-line text.
Text Multi-line text.
Integer Whole number.
Float Decimal number.
Boolean True/false.
Date Calendar date.
Datetime Date + time.
Selection options= Fixed choices: list of (value, label) pairs (a bare string is both).
CheckboxSet options= Multiple choices; value is a list of the enabled keys.
Reference target= Many-to-one link to another model (by its name).
Many2many target= Many-to-many link; optional relation= to name the join table.
One2many target=, inverse= Children on target, linked by the child's inverse Reference field.
Vector dim= Fixed-size embedding for similarity search (no required/default).
from victor import fields, models

class Ticket(models.Model):
    name = "ticket"                       # technical model name (snake_case, singular)
    label = "Ticket"                      # human name
    _description = "A support request."   # required — a module won't install without it

    display_name = fields.String(label="Subject", required=True)
    priority = fields.Selection(
        options=[("low", "Low"), ("normal", "Normal"), ("high", "High")],
        label="Priority", default="normal",
    )
    customer_id = fields.Reference(target="contact", label="Customer")

Common gotchas

  • _description is required on every model you define.
  • One2many needs inverse= (the name of the Reference field on the child that points back).
  • Vector needs dim=.
  • Don't name a field name — that attribute is the model's technical name. Use display_name for the record title.

See Models & fields.

View kinds

Kind Shows Notes
list A table of records The usual landing view.
kanban A card board Group with default_group_by.
card A card grid Compact record cards.
form A single record Opens when you click a record.
search The filter bar Declares <filter> chips; not listed in an action's views.
graph One record's node graph An interactive editor for step/flow records — not a chart.

List an action's screens in order with views="list,kanban,form". See Views.

Widgets

Set widget="…" on a <field> to override its default rendering.

Widget Renders as
email mailto: link + email input
url Clickable link + URL input
phone tel: link + phone input
tags Tag chips (for Many2many)
textarea Multi-line text box
monetary Number formatted as currency
toggle On/off switch
badge Pill/label
date Date picker
radio Radio buttons (for Selection)
checkbox-inline Inline checkboxes (for CheckboxSet)

Each field also renders sensibly with no widget set, based on its type.

View XML at a glance

<victor>
  <!-- a table + a form + a board -->
  <view id="view_list" model="ticket" type="list">
    <field name="display_name"/>
    <field name="priority"/>
  </view>

  <view id="view_form" model="ticket" type="form">
    <group string="Details">
      <field name="display_name"/>
      <field name="customer_id"/>
    </group>
    <notebook>
      <page string="Description"><field name="description" widget="textarea"/></page>
    </notebook>
  </view>

  <!-- the filter bar -->
  <view id="view_search" model="ticket" type="search">
    <search>
      <filter name="urgent" string="Urgent" domain='[["priority","=","high"]]'/>
      <filter name="by_stage" string="Stage" context="{'group_by': 'stage'}"/>
    </search>
  </view>

  <!-- make it reachable -->
  <action id="action_tickets" name="Tickets" model="ticket" views="list,form" path="tickets"/>
  <menu id="menu_helpdesk" parent="base.menu_root" label="Helpdesk"
        action="helpdesk.action_tickets" icon="LifeBuoy" sequence="20"/>
</victor>
Tag Purpose
<view type="list\|form\|kanban\|card\|search"> A screen for a model.
<field name="…" widget="…"> A column / input.
<group string="…"> A titled group of fields on a form.
<notebook> / <page string="…"> Tabbed sections on a form.
<filter name string domain\|context group> A search chip.
<action …> Binds a model to its views and gives it a URL.
<menu …> A navigation entry.
<extend view="mod.view_id"> Modify another module's view.
<seed model="…" id="…"> Create a record on install.

See Actions & menus, Extending other modules, and Seed & demo data.

Domains

A domain is a list of [field, operator, value] triples, e.g. [["priority", "=", "high"]]. Multiple separate filters combine with AND.

Operator Meaning
= != Equal / not equal
> >= < <= Comparisons
in not in Value is (not) in a list
like ilike Text match (ilike = case-insensitive)

Seed records

<victor>
  <seed model="contact" id="acme">
    <display_name>Acme Corp</display_name>
    <is_company>true</is_company>
  </seed>
  <seed model="ticket" id="t1">
    <display_name>Cannot log in</display_name>
    <customer_id>acme</customer_id>   <!-- resolves: "acme" is declared above in THIS file -->
  </seed>
</victor>

References in seeds

A Reference in a seed points at another seed by its id, declared earlier in the same file. Cross-file references are not resolved. See Seed & demo data.

Publish

  1. Put your module folder in your project's git repository.
  2. Push — Victor Cloud deploys it to your instance.
  3. Open the top-level Modules section and Install (or Upgrade) it.

See Publishing & installing.