* feat: migrate file and live post-processing pipelines from Celery to Hatchet workflow engine
* fix: always force reprocessing
* fix: ci tests with live pipelines
* fix: ci tests with live pipelines
* fix: add auth guards to prevent anonymous access to write endpoints in non-public mode
* test: anon data accessible regardless of guards
* fix: celery test
* Increase max connections
* Classify hard and transient hatchet errors
* Fan out partial success
* Force reprocessing of error transcripts
* Stop retrying on 402 payment required
* Avoid httpx/hatchet timeout race
* Add retry wrapper to get_response for for transient errors
* Add retry backoff
* Return falsy results so get_response won't retry on empty string
* Skip error status in on_workflow_failure when transcript already ended
* Fix precommit issues
* Fail step on first fan-out failure instead of skipping
* fix: local processing instead of http server for cpu
* add fallback token if service worker doesnt work
* chore: rename processors to keep processor pattern up to date and allow other processors to be createed and used with env vars
* feat: enable daily co in selfhosted + only schedule tasks when necessary
* feat: refactor aws storage to be platform agnostic + add local pad tracking with slfhosted support
* Upgrade to nextjs 16
* Update sentry config
* Force dynamic for health route
* Upgrade eslint config
* Upgrade jest
* Move types to dev dependencies
* Remove pages from tailwind config
* Replace img with next image
* fix: switch structured output to tool-call with reflection retry
Replace the two-pass StructuredOutputWorkflow (TreeSummarize → acomplete)
with astructured_predict + reflection retry loop for structured LLM output.
- Enable function-calling mode (is_function_calling_model=True)
- Use astructured_predict with PromptTemplate for first attempt
- On ValidationError/parse failure, retry with reflection feedback
- Add min_length=10 to TopicResponse title/summary fields
- Remove dead StructuredOutputWorkflow class and its event types
- Rewrite tests to match new astructured_predict approach
* fix: include texts parameter in astructured_predict prompt
The switch to astructured_predict dropped the texts parameter entirely,
causing summary prompts (participants, subjects, action items) to be
sent without the transcript content. Combine texts with the prompt
before calling astructured_predict, mirroring what TreeSummarize did.
* fix: reduce TopicResponse min_length from 10 to 8 for title and summary
* ci: try fixing spawning job in github
* ci: fix for new arm64 builder
* fix: remove max_tokens cap to support thinking models (Kimi-K2.5)
Thinking/reasoning models like Kimi-K2.5 use output tokens for internal
chain-of-thought before generating the visible response. When max_tokens
was set (500 or 2048), the thinking budget consumed all available tokens,
leaving an empty response — causing TreeSummarize to return '' and
crashing the topic detection retry workflow.
Set max_tokens default to None so the model controls its own output
budget, allowing thinking models to complete both reasoning and response.
Also fix process.py CLI tool to import the Celery worker app before
dispatching tasks, ensuring the Redis broker config is used instead of
Celery's default AMQP transport.
* fix: remove max_tokens=200 cap from final title processor
Same thinking model issue — 200 tokens is especially tight and would be
entirely consumed by chain-of-thought reasoning, producing an empty title.
* Update server/reflector/tools/process.py
Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com>
* fix: remove max_tokens=500 cap from topic detector processor
Same thinking model fix — this is the original callsite that was failing
with Kimi-K2.5, producing empty TreeSummarize responses.
---------
Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com>
* feat: add change_seq to transcripts for ingestion support
Add a monotonically increasing change_seq column to the transcript table,
backed by a PostgreSQL sequence and BEFORE INSERT OR UPDATE trigger. Every
mutation gets a new sequence value, letting external ingesters checkpoint
and never miss an update.
* chore: regenerate frontend API types
* Standalone on ubuntu
* fix: use port 3043 for Caddy, disable rooms, remove dead Caddyfile
- Caddy mapped to host port 3043 instead of 80/443 to avoid conflicts
- FEATURE_ROOMS=false in standalone web service
- Removed scripts/standalone/Caddyfile (dead code on this branch)
- Updated all URLs, port checks, docs to reference :3043
---------
Co-authored-by: Igor Loskutov <igor.loskutoff@gmail.com>
* feat: remove network_mode host for standalone by fixing WebRTC port range and ICE candidates
aioice hardcodes bind(addr, 0) for ICE UDP sockets, making port mapping
impossible in Docker bridge networking. This adds two env-var-gated
mechanisms to replace network_mode: host:
1. WEBRTC_PORT_RANGE (e.g. "50000-50100"): monkey-patches aioice to bind
UDP sockets within a known range, so they can be mapped in Docker.
2. WEBRTC_HOST (e.g. "host.docker.internal"): rewrites container-internal
IPs in SDP answers with the Docker host's real IP, so LAN clients can
reach the ICE candidates.
Both default to None — no effect on existing deployments.
* fix: do not attempt sidecar to detect host ip, use the standalone script to figure out the external ip and use it
* style: reformat
---------
Co-authored-by: tito <tito@titos-Mac-Studio.local>
* feat: add Caddy reverse proxy with auto HTTPS for LAN access and auto-derive WebSocket URL
Add a Caddy service to docker-compose.standalone.yml that provides automatic
HTTPS with local certificates, enabling secure access to both the frontend
and API from the local network through a single entrypoint.
Backend changes:
- Add ROOT_PATH setting to FastAPI so the API can be served under /api prefix
- Route frontend and API (/server-api) through Caddy reverse proxy
Frontend changes:
- Support WEBSOCKET_URL=auto to derive the WebSocket URL from API_URL
automatically, using the page protocol (http→ws, https→wss) and host
- Make WEBSOCKET_URL env var optional instead of required
* style: pre-commit
* fix: make standalone compose self-contained (drop !reset dependency)
docker-compose.standalone.yml used !reset YAML tags to clear
network_mode and volumes from the base compose. !reset requires
Compose v2.24+ and breaks on Colima + brew-installed compose.
Rewrite as a fully self-contained file with all services defined
directly (server, worker, beat, redis, postgres, web, garage, cpu,
gpu-nvidia, ollama, ollama-cpu). No longer overlays docker-compose.yml.
Update setup-standalone.sh compose_cmd() to use only the standalone
file instead of both files.
* fix: update standalone docs to match self-contained compose usage
---------
Co-authored-by: Igor Loskutov <igor.loskutoff@gmail.com>
Without the plugin, `docker compose version` can still exit 0
by falling through to `docker version`. Grep for "Compose" in
the output to reliably detect the plugin.
Without the compose plugin, `docker compose -f ...` produces a
misleading "unknown shorthand flag: 'f'" error instead of telling
the user compose is missing.