AIGEN
The AIGEN I/O Server exposes HSYCO's generative AI subsystem as a set of datapoints, so that any EVENTS or JavaScript automation can send a prompt to a Large Language Model and read back its answer.
See Assistant for the Manager and Client chat surfaces. AIGEN uses the same provider and tool infrastructure, but it is a datapoint-driven automation interface.
Each I/O Server instance is bound to an AI profile, one of the entries defined in config/aigen_profiles.ini, which selects the provider (Anthropic, OpenAI, OpenAI-compatible, Google Gemini or Ollama), its credentials or base URL, and the tool bundles the model is allowed to call. The driver adds conversation sessions on top of it: multiple independent chats, each with its own history, its own attachments and its own set of datapoints.
An AIGEN I/O Server can use the tools selected in its profile, except Project Editor, Code Editor, Client Page, and Session Files. See Assistant Tools for the available bundles.
Prompts and attachments are not limited to plain text: a prompt can reference a camera with a cam: token, or a file with a file: token, and the driver resolves them into real image or document attachments before calling the model (see Prompt Tokens).
Requirements
In Manager Settings, turn on Enabled for AIGEN I/O Server for the profile you want to use. If you edit config/aigen_profiles.ini directly, set <profile>.ioserver = true. Existing profiles that were enabled only for Manager need this setting too. The profile also needs valid provider credentials or, for Ollama, a reachable server with a model installed. If no tool bundles are selected, the I/O Server can use all of its available tools.
HSYCO Configuration
Add an AIGEN I/O Server in the I/O Servers section of the Settings and set its parameters. No IP address or port is required: the driver connects to the provider defined by the profile.
Options
| ID | Default | Values | Description |
|---|---|---|---|
| profile | <id> | mandatory; ID of a profile enabled for AIGEN I/O Server. The server cannot start if the profile is missing or disabled | |
| model | base | base | uses the provider's current base chat model |
| advanced | uses the provider's current advanced chat model; providers without an advanced mapping use their default chat model | ||
| maxoutputtokens | 1024 | >= 1 | maximum number of tokens the model is allowed to generate in a single answer |
| system | <text> | system prompt, prepended to every conversation of every session | |
| tools.parallel | true | true | the model is allowed to request multiple tool calls in the same round |
| false | tool calls are executed one at a time | ||
| tools.maxrounds | 8 | >= 1 | maximum rounds of tool use before the server returns an answer |
| session.timeout | 0 | >= 0 | idle time in minutes after which a session is automatically closed and its conversation discarded. 0 means sessions never expire |
| session.persist | false | true | conversations are stored on disk, under state/drivers/aigen/<ioserver_name>/sessions, and survive an HSYCO restart |
| false | conversations are kept in memory only | ||
| history | true | true | each session keeps the conversation history, so that the model sees the previous turns |
| false | every message is sent as a new, stateless conversation | ||
| history.maxsize | 8 | >= 0 | maximum number of messages retained in a session's history. 0 means unlimited |
Ollama and OpenAI-compatible models
These providers discover model IDs from their configured endpoint, but HSYCO cannot infer which discovered model is base or advanced. Map the installed models in Manager Settings or directly in config/aigen_profiles.ini:
local.provider = ollama
local.base_url = http://localhost:11434
local.mini_model = llama-mini
local.base_model = llama-small
local.advanced_model = llama-large
local.compaction_model = llama-summary
local.base_reasoning = medium
local.base_context_window = 131072
local.base_max_output_tokens = 16384
These settings are optional. Mini defaults to Base, while Compaction defaults to Advanced. If any selected mapping is absent or names an unavailable model, HSYCO uses the first model returned by the endpoint. In Manager Settings, the Models action discovers endpoint models and exposes model, reasoning, context-window, and output-limit settings for each assignment. For curated providers, the same action displays the catalog assignments and capabilities as read-only labels.
Sessions
A session is an independent conversation, identified by an ID. Sessions are created on demand: writing to session.new, or to any session.<id>.* datapoint of an unknown ID, creates the session and its datapoints.
If session.new is written with an empty value, HSYCO generates a random 8-character hexadecimal ID and publishes it in session.list.
Each send runs asynchronously on its own thread: the status datapoint moves to thinking and back to idle when the answer is written to response. While a session is busy, further messages sent to that session are ignored and logged as an error; other sessions are unaffected and can run in parallel.
Sessions are closed explicitly by writing to session.<id>.close, or automatically when they stay idle for longer than session.timeout.
Prompt Tokens
Before a message is sent to the model, the driver scans it for cam: and file: tokens. Each token is removed from the text and replaced by an attachment, and possibly by a short note that tells the model what the attachment is. All the remaining fragments of text are joined with a single space and become the prompt.
Token resolution never aborts a send: if a camera is unknown or a file is missing, the driver writes an error to the log, replaces the token with a note explaining the failure, and sends the message anyway.
Camera Tokens
| Token | Frame |
|---|---|
cam:<name> | the camera's live frame; if the camera has no live image, the newest recorded frame is used |
cam:<name>:<seconds> | the recorded frame nearest to <seconds> ago, e.g. cam:garage:120 for two minutes ago |
cam:<name>:<yyyy-MM-ddTHH:mm:ss> | the recorded frame nearest to that instant, e.g. cam:garage:2026-07-14T09:30:00 |
<name> is the camera name as defined in HSYCO's cameras configuration. It can contain letters, digits, underscores, hyphens and internal dots (front-door.2), but it cannot end with a dot or a hyphen, so a token that closes a sentence, like what do you see in cam:hall., does not swallow the final period into the camera name. A token is only recognized when cam: is not preceded by a word character, a dot or a hyphen, so words like webcam:hall are left alone.
The frame is downscaled, attached to the message as an image, and the token is replaced in the prompt by a caption that carries its provenance:
[camera hall, latest 2026-07-14 09:31:12]
[camera garage, recorded 2026-07-14 09:29:58]
where latest means the live frame and recorded means a frame read from the recordings archive. When the frame cannot be obtained, the token is replaced by:
[camera frame unavailable: hall - unknown camera: hall]
File Tokens
file:<name> attaches a file to the message. The file name may contain letters, digits, underscores, dots and hyphens; it must not contain path separators, and it is resolved relative to the HSYCO installation directory. A file in a subdirectory, or referenced with an absolute path, has to be attached with the attach datapoint instead, which accepts any path.
The token is removed from the prompt and the file is uploaded as an attachment. If the file does not exist, is not readable, or exceeds the size limits, the token is replaced by:
[file not found: notes.txt]
Attachments are classified from their MIME type and extension as image, audio, text or document, and are subject to these limits: 12 MB per file; images larger than 150 KB are downscaled before being sent; text files are truncated at 256 KB or 12,000 characters.
Staged Attachments
The session.<id>.attach datapoint stages one or more attachments for the next message of that session. Its value is a comma-separated list, where each item is either a cam: token, with the same syntax described above, or the path of a file, with no file: prefix and no restriction on directories:
IO aigen.session.kitchen.attach = cam:hall, cam:garage:300, /opt/hsyco/logs/report.csv
Staged attachments are consumed by the next send: they are attached to that message, the captions of the staged cameras are appended at the end of the prompt text, and the staging list is emptied. Writing to session.<id>.attach.clear discards the staged attachments without sending anything.
Datapoints
Basic Info
| ID | Value | R/W | Description |
|---|---|---|---|
| connection | online | R | the provider is reachable and correctly configured |
| offline | R | the provider is unreachable, or the profile cannot be resolved. Reachability is re-checked every 15 seconds |
Session Management
| ID | Value | R/W | Description |
|---|---|---|---|
| session.new | <id> | W | create a session with the given ID. |
| session.new | W | create a session with a randomly generated ID | |
| session.list | <id>, <id>, ... | R | comma-separated list of the currently open sessions |
Session
| ID | Value | R/W | Description |
|---|---|---|---|
| session.<id>.send | String | W | send a message to the model. cam: and file: tokens in the text are expanded before sending. Ignored if the session is already processing a message |
| session.<id>.attach | String | W | comma-separated list of cam: tokens and file paths to attach to the next message |
| session.<id>.attach.clear | W | discard the attachments staged for the session | |
| session.<id>.reset | W | clear the session's staged attachments, response, error and token counters, and set its status back to idle | |
| session.<id>.close | W | close the session, discard its conversation and remove it from session.list | |
| session.<id>.status | idle | R | the session is ready to accept a message |
| thinking | R | the model is generating an answer | |
| error | R | the last message failed. The reason is in the error datapoint | |
| closed | R | the session has been closed, explicitly or by timeout | |
| session.<id>.response | String | R | the model's answer to the last message |
| session.<id>.error | String | R | the reason of the last failure, empty when the last message succeeded |
| session.<id>.tokens.input | <value> | R | input tokens consumed by the last message |
| session.<id>.tokens.output | <value> | R | output tokens generated by the last message |
| session.<id>.tokens.input.total | <value> | R | input tokens consumed by the session since it was created or reset |
| session.<id>.tokens.output.total | <value> | R | output tokens generated by the session since it was created or reset |
| session.<id>.started | ISO-8601 | R | creation time of the session, in UTC |
| session.<id>.expires | <value> | R | seconds remaining before the session expires, updated every 15 seconds. Empty when session.timeout is 0 |
Examples
Asking a question
init : IO aigen.session.new = kitchen
aigen.session.kitchen.status = idle : IO aigen.session.kitchen.send = "how many lights are on right now?"
The answer is written to aigen.session.kitchen.response as soon as the model replies, and can be used in any other rule.
Describing a camera scene
INIT : {
ioSet("aigen.session.gate.send", "someone rang the bell: describe the person you see in cam:entrance");
}
The cam:entrance token is replaced with the camera's live frame plus its caption, so the model receives the image together with the question.
Comparing two moments in time
init : IO aigen.session.gate.send = "compare cam:parking with cam:parking:600 and tell me which cars have left in the last ten minutes"
The first token resolves to the live frame, the second one to the recorded frame of ten minutes earlier.
Attaching a file and a camera frame
INIT : {
ioSet("aigen.session.report.attach", "cam:boiler, /opt/hsyco/logs/energy.csv");
ioSet("aigen.session.report.send", "the picture is the boiler display, the file is today's consumption: is anything anomalous?");
}
Release Notes
4.2.0
- initial release