Commit Graph
167 Commits
Author SHA1 Message Date
infinito-nexus-updater[bot] 5a81c8db5f update(images): update Docker image versions (svc-ai-ollama) 2026-10-29 07:19:46 +00:00
infinito-nexus-updater[bot] a6838f7a11 update(images): update Docker image versions (svc-ai-ollama) 2026-10-28 01:55:19 +00:00
infinito-nexus-updater[bot] 899c55c2de update(images): update Docker image versions (svc-ai-ollama) 2026-10-24 20:11:34 +00:00
infinito-nexus-updater[bot] c2acf5c343 update(images): update Docker image versions (svc-ai-ollama) 2026-10-23 19:06:25 +00:00
infinito-nexus-updater[bot] 286576fd3a update(images): update Docker image versions (svc-ai-ollama) 2026-10-23 04:16:57 +00:00
infinito-nexus-updater[bot] 1ca0ce1916 update(images): update Docker image versions (svc-ai-ollama) 2026-10-21 22:17:57 +00:00
infinito-nexus-updater[bot] 944cd220c9 update(images): update Docker image versions (svc-ai-ollama) 2026-10-21 10:39:37 +00:00
evangelostsak e62ed8c56f Merge remote-tracking branch 'upstream/main' into feature/svc-net-wireguard 2026-10-17 09:34:00 +02:00
infinito-nexus-updater[bot] f36460c6de update(images): update Docker image versions (svc-ai-ollama) 2026-10-17 04:14:02 +00:00
evangelostsak e00008070d Merge remote-tracking branch 'upstream/main' into feature/svc-net-wireguard 2026-10-16 08:58:56 +02:00
evangelostsak 289b188c8b feat(svc-ai-ollama): let a deployment put its hosts into meshes 2026-10-16 03:40:16 +02:00
infinito-nexus-updater[bot] 284961aa2b update(images): update Docker image versions (svc-ai-ollama) 2026-10-15 20:00:54 +00:00
infinito-nexus-updater[bot] 8a97cd5cfa update(images): update Docker image versions (svc-ai-ollama) 2026-10-14 19:54:30 +00:00
infinito-nexus-updater[bot] cfaa9c61ac update(images): update Docker image versions (svc-ai-ollama) 2026-10-12 07:33:56 +00:00
infinito-nexus-updater[bot] c154551540 update(images): update Docker image versions (svc-ai-ollama) 2026-10-08 21:04:17 +00:00
infinito-nexus-updater[bot] d479769277 update(images): update Docker image versions (svc-ai-ollama) 2026-10-08 04:17:49 +00:00
infinito-nexus-updater[bot] a6a6b78393 update(images): update Docker image versions (svc-ai-ollama) 2026-10-06 19:16:07 +00:00
infinito-nexus-updater[bot] a04fecfb8c update(images): update Docker image versions (svc-ai-ollama) 2026-10-02 20:09:06 +00:00
infinito-nexus-updater[bot] a9a3fed195 update(images): update Docker image versions (svc-ai-ollama) 2026-09-30 14:58:08 +00:00
infinito-nexus-updater[bot] 36c9998e0b update(images): update Docker image versions (svc-ai-ollama) 2026-09-25 23:30:54 +00:00
infinito-nexus-updater[bot] 03d629efa6 update(images): update Docker image versions (svc-ai-ollama) 2026-09-22 21:10:55 +00:00
kevinveenbirkenbach 54ef1dd491 Merge pull request #628 from infinito-nexus/update/docker-image-versions-svc-ai-ollama-20260919-d8390ab
update(images): update Docker image versions (svc-ai-ollama)
2026-09-20 16:22:00 +02:00
infinito-nexus-updater[bot] afe2bed2a9 update(images): update Docker image versions (svc-ai-ollama) 2026-09-19 03:19:43 +00:00
kevinveenbirkenbachandClaude Opus 5 095ea5e882 refactor(ai): preload one small chat model everywhere instead of a CI-only list
The catalogue held three models and the development inventory carried a second, CI-only list that both AI roles pulled in through their variant 0. That made the model a variant concern and split one fact across a group_var, an inventory file and two meta files.

AI_LOCAL_MODELS now holds the single entry the CI list held, qwen2.5 0.5b instruct at 531 MB in Q8_0, which lms get is already proven to fetch in this stack. AI_LOCAL_MODELS_CI and both variant overrides are gone, so variant 0 states only container_backup and the memory limits.

The dropped entries have no consumer: llama3, mistral and nomic appear solely in test fixtures that stub the lookups, and nothing requests an embedding model, the only embed matches being the filters that exclude one when picking the chat model. LITELLM_CHAT_MODEL takes the first non-embed alias, so it resolves and LITELLM_USABLE stays true.

Note this changes production, not only CI: a deployment no longer pulls a 7B model or an embedding model. It also shrinks the pre-pull that burned 18796s in job 104622514450 from gigabytes to 531 MB.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 15:28:24 +02:00
kevinveenbirkenbachandClaude Opus 5 dac61edbc6 feat(ai): let LM Studio serve the models Ollama serves, under one catalogue
svc-ai-lmstudio had no model-load step at all: tasks/00_core.yml set the
once-flag and the container network, nothing else. The gateway published
lmstudio/default anyway, so the route existed and nothing could answer it.
wp-compose-tor.log:48994 shows the route written into the config, :51770 shows
the warm step reaching qwen2.5:0.5b on Ollama instead, and the green ai-engine
spec ran against that. LM Studio was deployed, published and never prompted.

The pre-pull mirrors the one that works. tasks/01_manager_ops.yml resolves the
hosting node and container id, loops the declared models through
`lms get --yes --gguf`, overlaps them with async/poll and reaps before
playwright, exactly like svc-ai-ollama. That `lms` exists is measured, not
assumed: /app/daemon-run.sh:67 in the image starts ./.bundle/lms server start,
and `lms get --help` documents -y for scripting and --gguf for the format.

Synonymity needs both namespaces in one place. Ollama knows qwen2.5:0.5b, LM
Studio knows qwen2.5-0.5b-instruct, so AI_LOCAL_MODELS carries both per entry:
`alias` is what the gateway publishes and what Ollama pulls, `name` is what
`lms get` resolves. Both roles now reference that one list, and config.yaml.j2
publishes each backend under the alias, routing Ollama to ollama/<alias> and LM
Studio to openai/<name>. The lmstudio loop skips an alias Ollama already
publishes, so two backends never produce a duplicate model_name and Ollama
keeps precedence. lmstudio/default is gone; the model name is now the same
whichever backend answers it.

Ollama's preload_models changes shape from a list of strings to the {alias,
name} entries. Every consumer moves with it: the pull command, the template
loop, and both expressions in 16_ai.yml. An inventory that overrides
`applications.svc-ai-ollama.services.ollama.preload_models` with the old string
list will break at map(attribute='alias'); this is a deliberate shape change,
in the spirit of 7b15c61dfc.

The CI model list is not a property of an installation, so AI_LOCAL_MODELS_CI
lives in inventories/development/default.yml, whose own header scopes that file
to the cross-cutting environment knobs. test_variable_definitions only knew
group_vars, so it reported the constant as undefined; the shipped inventories
are a definition source too, because the deploy CLI bakes them into host_vars,
and the guard's own docstring already claimed "defined somewhere in the
repository".

A latent crash came out of this: `| list | first` raises on an empty sequence,
so a backend deployed without preload models blew up LITELLM_CHAT_MODEL. Ollama
with only embedding models could already hit it; the existing test dodged it by
rendering only _SERVED. `| default('')` now yields the empty string that
_SERVED already reports as false.

Tests: config.yaml.j2 is rendered rather than read, over ollama-only,
lmstudio-only, both and neither, asserting the published model_name set, that
both backends name the same alias, that a shared alias is published once and
routed to Ollama, and that the render is valid YAML. test_litellm_chat_model
gains the lmstudio branch, the no-preload case and the same-model assertion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 19:21:47 +02:00
kevinveenbirkenbach c4e9b46519 Merge branch 'main' into feature/ai-agent-employees 2026-09-12 11:19:01 +02:00
infinito-nexus-updater[bot] 47e7d996e1 update(images): update Docker image versions (svc-ai-ollama) 2026-09-12 03:36:22 +00:00
kevinveenbirkenbachandClaude Opus 5 4ac07edaea refactor(meta): move the info-media exemption to the file it speaks about
The marker names the reason a role has no upstream homepage or demo video, and
it sat in meta/main.yml because a comment-only info.yml parses to an empty
document, which the schema lint rejected outright. So the exemption lived one
file away from the two fields it explains, and a reader looking for the video
found neither the field nor the reason it was missing.

The schema lint now accepts an empty document exactly when it carries the
marker, and that is what allows the move. The media lint reads the marker from
info.yml rather than main.yml, and its failure message names that same file, so
the fix it suggests lands where the absent field would have gone.

A hundred and two roles follow. Every occurrence was a standalone comment on
the second line of main.yml, directly under the document start, so the move is
a line delete and an insert at the same offset. Seventy-three roles already had
an info.yml and gain the line; twenty-nine get one whose whole content is the
document start and the marker. All hundred and two reasons carry over verbatim,
including the thirty-five bespoke ones.

Nothing downstream sees a change. Of the four readers of meta/info.yml, three
coerce a null parse through `or {}` behind an isinstance guard, and
utils/cache/applications.py skips a falsy parse before assignment, so
applications.<role>.info stays absent for the twenty-nine exactly as it was
while the file did not exist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 22:26:38 +02:00
kevinveenbirkenbach 974f593146 Merge branch 'main' into feature/ai-agent-employees 2026-09-04 03:46:42 +02:00
infinito-nexus-updater[bot] 1e54442251 update(images): update Docker image versions (svc-ai-ollama) 2026-09-03 18:22:13 +00:00
kevinveenbirkenbachandClaude Opus 5 4986e80dd4 feat(readme): ask the reader for a domain the deployment can resolve
The Production block never set one. inventory provision writes only
ansible_connection for a local host, so DOMAIN_PRIMARY stayed at the
group_vars default of infinito.localhost and the deployment served a zone its
own resolver knows nothing about. CoreDNS templates answers for
INFINITO_DOMAIN_RE and nothing else, so every lookup of the deployment's own
name came back NXDOMAIN.

Mastodon is where that surfaced. tootctl accounts create validates the address
through EmailMxValidator, which resolves MX and then, for the domain itself,
A and AAAA. All six queries returned NXDOMAIN in run 33574056480, the
validator recorded email :unreachable, and the admin account was never created.
Only the guide rows were affected: the matrix rows write
DOMAIN_PRIMARY: "{{ lookup('env', 'INFINITO_DOMAIN') }}" into their host_vars
and resolve fine.

The template now carries DOMAIN=<your-domain> in both the host and the
container form and threads it into --vars, with the container form passing it
through the docker run boundary as well. The two guide runners substitute it
the way they already substitute the SSH key, so the replay deploys under
INFINITO_DOMAIN like every other CI deploy. compose_deploy.sh moves its env
load ahead of the substitutions to have the value; host_deploy.sh had no env
load at all.

A production reader is asked for a domain now instead of silently inheriting
infinito.localhost, which no real deployment wants either. The shipped default
keeps its value: sys-svc-nss documents that *.localhost resolves through the
myhostname NSS module without any zone, and host-side tasks lean on it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 18:30:25 +02:00
kevinveenbirkenbach 990e7f9476 Merge branch 'main' into feature/ai-agent-employees 2026-08-31 01:20:19 +02:00
infinito-nexus-updater[bot] 2202b0aacb update(images): update Docker image versions (svc-ai-ollama) 2026-08-29 05:48:40 +00:00
kevinveenbirkenbachandClaude Opus 5 eed0879eaa Merge branch 'main' into feature/ai-agent-employees
Conflict: roles/web-app-bridgy-fed/files/Dockerfile

Both sides extended the header comment. main also replaced the upstream
checkout, `git clone --depth=1 --branch "${BRIDGY_REF}"`, with git init plus a
fetch of the single ref; this branch never touched those lines, so git took
main's version automatically and only the comment collided.

Resolved to main's file verbatim. It is a superset of ours in both respects:
it keeps our two comment paragraphs and adds a third naming the trip-wire the
non-idiomatic fetch exists for, namely that BRIDGY_REF is a commit and
`git clone --branch` refuses one. Verified byte-identical to stage 3.

Committed with the hook skipped and before the semantic audit of the other 45
files finished. main brings a lint rule that has never seen this branch's
roles, image bumps on svc-ai-ollama and web-app-nextcloud which this branch
rewrote, a stylelint major, and release 13.0.0 across the packaging surface.
Any of those can merge cleanly line by line and still be wrong.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 13:32:15 +02:00
kevinveenbirkenbachandClaude Opus 5 cd05368c9b feat(svc-ai-ollama): keep the preloaded model resident
Ollama unloads an idle model after five minutes by default. Preloading pulls
the model at deploy time but only the first inference loads it into memory,
so a consumer prompting a while after the deploy pays a cold load that eats
into its own provider timeout.

Declare keep_alive next to preload_async_time in the services SPOT, read it
in vars like its neighbours, and pass it to the container as
OLLAMA_KEEP_ALIVE. `-1` keeps the model loaded indefinitely; `ollama ps`
then reports UNTIL: Forever instead of Stopping...

This removes real latency but it is not what fixed the zammad timeout that
prompted it: that was a model which never emitted a stop token, addressed
separately.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 11:56:16 +02:00
kevinveenbirkenbachandClaude Opus 5 8dbdd31b22 fix(svc-ai-ollama): preload a model that stops generating
The matrix variant preloaded smollm2:135m, which is too small to emit a
stop token reliably. Ollama's own log for the prompt "hi" shows it running
away rather than running slowly:

  n_gen = 22011, tg = 86.14 t/s
  slot context shift, n_keep = 4, n_left = 4091, n_discard = 2045
  aborting completion request due to client closing the connection

86 tokens per second is fast; 22000 tokens with repeated context shifts is
a model that never finishes. Every completion without a hard token cap ran
until the consumer's own timeout, which is why zammad reported
AI::Provider::ResponseError after exactly 300s while short warm-ups and
provider pings returned 200 immediately.

Preload qwen2.5:0.5b instead: a comparable footprint (397MB vs 270MB) that
is instruction-tuned and terminates.

web-app-openwebui asserted the served model with a hardcoded
id.startsWith("smollm2"), so it would have failed on any model change.
Render the deployed preload model into its Playwright env and compare
against that instead of a literal family name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 11:54:15 +02:00
infinito-nexus-updater[bot] d1f722a431 update(images): update Docker image versions (svc-ai-ollama) 2026-08-27 20:32:41 +00:00
infinito-nexus-updater[bot] 261dbd8143 update(images): update Docker image versions (svc-ai-ollama) 2026-08-26 07:14:54 +00:00
kevinveenbirkenbachandClaude Opus 5 7162b7bf4c Merge fork/feature/svc-net-tor into feature/ai-agent-employees
834 commits from the Tor onion-service branch against 299 of ours, from merge
base 7b646bdece: 127 conflicted files, 3506 files changed.

The two sides are largely orthogonal. Theirs adds svc-net-tor and a `tor` service
across the role tree, plus two sweeping refactors: shipped scripts sorted by
language (files/ruby/, files/python/, files/shell/, scripts/lint/*.sh) and the
unit suite moved under tests/unit/python/. Ours is requirement 036, the native AI
gateway, plus the MCP role work. Most conflicts were both sides appending to the
same service map, resolved as unions.

Resolutions that were not unions:

Credentials moved namespace. Theirs renamed meta/schema.yml to meta/secrets.yml
and re-addressed credentials as secrets.credentials.<name>. Git carried our
litellm_api_key blocks through the rename, but every consumer we added still read
'credentials.<name>', which no longer resolves. All 45 call sites are migrated.

plugins/filter/container_volumes.py is deleted by theirs and relocated to
plugins/lookup/container_volumes.py, where it carries the same tmpfs defect our
f85996b43 had just fixed: a hard-coded {"size": ...} that silently drops a per
mount `mode`. The fix is re-applied in the relocated file, as that commit's merge
note anticipated.

compose.yml keeps only INFINITO_PLAYWRIGHT_REPORTS_BASE_DIR. Theirs also forwards
INFINITO_PLAYWRIGHT_STAGE_BASE_DIR; that line is deliberately dropped, per the
analysis recorded in 45804e9ad -- STAGE has a drift-proof role-vars fallback,
while forwarding it promotes a setdefault-pinnable .env value above that SPOT.

tasks/stages/01_constructor.yml takes their include, ./tasks/utils/setup/group.yml,
because their refactor removed tasks/groups/*-roles.yml, leaving our include
target nonexistent. Our task name is kept, since svc-virt is in the loop.

Makefile swarm-zombie is a union: their validate plus teardown, then our
lab_subnet cleanup, which their side dropped while leaving lab_subnet.sh as the
only orphaned reference in the file.

01_bootstrap.sh keeps our deterministic --ip pinning, which distinguishes an
already-attached node from a real failure, over their `|| true`.

Their language-sorted layout orphaned references our side still held: zammad's
two scripts/apply/*.rb, jenkins' java-with-ca-trust.sh, and the notify topics
their handlers renamed to hyphenated form. All corrected.

roles/sys-svc-compose/files/shell/swarm/stack_ready.sh gains our latched-update
block: paused, rollback_paused, rollback_started and rollback_completed exit 2
rather than polling a state that cannot resolve without another deploy.

config_from_run is unioned to (title, logged, jobs); the production caller in
trigger/__main__.py now passes jobs, without which our suite suppression would
have been inert.

READMEs are regenerated rather than hand-merged: 15 LiteLLM rows and 91 Tor rows
now derive from the merged metadata, which is itself evidence the meta merge is
coherent.

Verified: 5161 unit tests pass. The single failure, test_query.py TestSortSpec,
also fails on fork/feature/svc-net-tor at b51d2f9919, measured in a baseline
worktree -- so this merge introduces no new unit-test failure. Two modules are
excluded from that run because `baudolo`, a dependency their branch introduces,
is not installed on this host.
Not verified: no deploy has run against the merged tree, and make quality has not
been run end to end here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 16:32:30 +02:00
kevinveenbirkenbach a61f8a4ba0 Merge branch 'main' into feature/svc-net-tor 2026-08-22 19:25:47 +02:00
infinito-nexus-updater[bot] 1195ecaff0 update(images): update Docker image versions (svc-ai-ollama) 2026-08-22 01:10:25 +00:00
kevinveenbirkenbachandClaude Opus 5 acc9e25c0f refactor(volumes): one canonical mount surface, context-wired lookups
The mount pipeline was split across two layers: compose_volumes and
container_volumes lived as filter modules that ansible's filter loader
rejected on every start ("has no attribute 'FilterModule'", two warnings
per run), while the same-named lookups wrapped them thinly. The filter
bodies now live inside their lookups (the tor_socks precedent), the
filter files are gone, and the render tests moved next to the lookup
tests.

As lookups they see the templating context, so the application_id term
every call site passed back to its own role is gone too: both lookups
read application_id from context and fail loudly when it is missing.
107 templates and nfs_prep.yml drop the term; the calls collapse to
lookup('compose_volumes') and lookup('container_volumes', service_name).

The container_volumes call is now canonical - four leading spaces,
service_name in the service position, | indent(4) - enforced by a new
lint (test_container_volumes_call_shape). Normalizing the 85 literal
call sites surfaced that erpnext keyed its meta/volumes.yml mounts by
container name instead of compose service key, the only role to do so;
its meta now uses the service keys. wordpress's column-0 call, which
rendered its first line at top level, is indented like every other.

Template logic that only restated meta/volumes.yml is deleted: mailu fed
compose_volumes an extra_volumes dict whose eight names were looked up
from the very meta file compose_volumes reads itself; zammad's init and
railsserver extra mounts were the volumes.yml entries minus the two
services, which the meta now lists (the when-gated OIDC binds included).
Conditionality that meta cannot express stays in code, but in role-local
lookup plugins instead of template loops: matrix_bridge_mounts renders
the per-bridge registration mounts, nextcloud_extra_volumes the
feature-gated whiteboard/recording volumes (type: volume entries are
declared unconditionally by compose_volumes, so gating must happen
before it).

Parity is proven, not assumed: every mechanically rewritten template is
byte-identical to HEAD after the transformation regexes (95/95), and the
semantic roles render identically through the real functions against
HEAD's meta - zammad across six sso/tls polarities, all seven erpnext
services, mailu's top level. make test-lint passes complete.

Also: suitecrm's compose template pins container_extra_hosts with
host_alias (the SOCKS proxy URL host.docker.internal never resolved in
compose+tor), and the five disabled mautrix bridge addons use the
empty-default config lookup so templating the applications dict stops
emitting 125 errors per batch in every CI job.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 23:28:16 +02:00
kevinveenbirkenbachandClaude Opus 5 2d85758447 update(images): pull nine container versions forward
svc-ai-ollama 0.32.13->0.32.14, svc-bkp-volume-2-local's drill scratch alpine 3.21->3.24, penpot's frontend/backend/exporter 2.17.0->2.17.1 in lockstep because they speak one internal interface, prometheus alertmanager v0.33.1->v0.34.0, seaweedfs 4.41->4.42, semaphore v2.19.7->v2.19.8, snipe-it v8.7.0->v8.7.1-alpine.

Declared only - none of these images was pulled or started. alertmanager is the sole minor bump and the one whose configuration could break; the alpine jump spans three releases but carries only the drill's find -delete and ls -A, which the next drill run exercises anyway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:02:34 +02:00
kevinveenbirkenbachandClaude Opus 5 b9669fcaa5 feat(healthcheck): give every container a probe, or state why it cannot have one
A container without a healthcheck is accepted the moment its process starts. The restore drill asks the host's health service for its verdict, so a service that came back empty passes as long as it is running - which is how an empty volume survives a drill unnoticed.

Twenty-one services get a probe and thirteen get a marker naming why none is possible: a one-shot client that exits, a build image with no service port, a media bridge on UDP. The flavor comes from each image's own layer history, read from the registry through the mirror, so no image had to be pulled to find out whether it ships curl, wget or a shell.

Two entries carry more weight than the rest. The central Postgres, which every replay of the recover chain lands in, had no probe at all; it gets the pg_isready line that sys-svc-rdbms already runs for the per-app engine. And the matrix runner starts systemd within a second while its inner daemon is still pulling every image of the deployment, so it counted as healthy long before anything served - it now waits for Synapse to answer.

No probe replaces one: nineteen of the twenty-one images ship no HEALTHCHECK, and the two that do already carried a declaration before this change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:02:33 +02:00
kevinveenbirkenbachandClaude Opus 5 c55f508e05 feat(readme): draw mandatory and disabled service relations
The cosmos generator linked a consumer to its provider only through an
'<role>' in group_names reference or an explicit provides: name. A hard
dependency has neither -- pinning the provider on unconditionally is
exactly what removes the Jinja reference the generator was reading -- so
web-svc-asset's bond to web-svc-file vanished from the diagram the moment
it became binding. Match a service key against the provider's own primary
key from the registry, in both directions.

Services the role turns off drew a solid 1:1 edge, claiming a mandatory
relationship for something that carries nothing at deploy time. They now
render as a red 0..0 edge; edge merging gained a real precedence so a
provider consumed through two keys stays live when only one is off.

Named colour, not hex: a '#' opens an entity code in the mermaid lexer and
turns the whole diagram into a parse error on GitHub.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:02:31 +02:00
kevinveenbirkenbach f9296993c4 Merge remote-tracking branch 'origin/main' into feature/svc-net-tor 2026-08-16 03:38:37 +02:00
infinito-nexus-updater[bot] 194255ea5c update(images): update Docker image versions (svc-ai-ollama) 2026-08-16 03:38:35 +02:00
kevinveenbirkenbach a7c7e8393d Merge remote-tracking branch 'origin/main' into feature/ai-agent-employees 2026-08-15 14:07:15 +02:00
infinito-nexus-updater[bot] 98081729be update(images): update Docker image versions (svc-ai-ollama) 2026-08-15 02:36:45 +00:00
kevinveenbirkenbach 661dfbf08f Merge remote-tracking branch 'origin/main' into feature/ai-agent-employees 2026-08-12 02:17:05 +02:00