Repository navigation
fix(yeti): set the agents variables Yeti actually reads - #279
Conversation
YETI_AGENTS_ENDPOINT is not a setting Yeti has. Its config layer maps YETI_<SECTION>_<KEY>, and the agents integration reads enabled, http_root and websocket_root (core/web/apiv2/agents.py). The variable was therefore ignored, and because the image ships a yeti.conf, the API fell back to its Compose defaults: enabled=True with http_root=http://agents:8888, a name that does not resolve in Kubernetes. The feature appeared in the UI and failed for every user. The disabled path had the same cause and needed saying explicitly: with no variable set at all, that same config file left the feature advertised with no backend deployed. Deploying agents also now requires global.yeti.apiKeySecret. The agents reach Yeti over its API, so without those credentials the workload starts but every tool call fails -- the tools being the reason it is connected to Yeti at all. The condition moves into a yeti.agentsEnabled helper because the same answer decides three things, the StatefulSet, its Service and what the API is told, and those must not be able to disagree.
Enabling agents without credentials used to render nothing, so asking for the service and not getting it looked the same as not asking. It now stops the install and names the secret that is missing, with the command to create it: the pod would otherwise start and be unable to answer, which is harder to work out after the fact than a message at the point of the mistake. agents.enabled therefore defaults to false. It cannot default to true while this is fatal, because chart-testing installs with the chart's own defaults and has no secrets to give it. ChromaDB is enabled by default instead, which needs no credentials and which Yeti otherwise falls back to an embedded index for -- one per process, so the API and the task workers stop seeing the same data as soon as they are scheduled apart. Also adds a readiness probe on the agents /health endpoint, verified present in yetiplatform/yeti-agents:dev. Readiness only: a configuration problem is not fixed by restarting, and a liveness probe on the same endpoint would replace a pod that can still be asked what is wrong with one that keeps dying.
|
Pushed two follow-ups after yeti-platform/yeti-agents#7 merged. ChromaDB is now enabled by defaultIt needs no credentials, and without it Yeti falls back to an embedded index. That index is per-process, so the API and the task workers stop seeing the same data the moment they are scheduled onto different nodes — writes land in one and reads come back empty from the other, with no error on either side. Sharing a volume is not an alternative: the embedded backend is SQLite, whose locking is unreliable on network filesystems. Asking for agents without credentials now fails the installPreviously Missing
Readiness probe on the agents serviceyeti-agents#7 added Readiness only, no liveness probe: a configuration problem is not fixed by restarting, and a liveness probe on the same endpoint would replace a pod that can still be asked what is wrong with one that keeps dying. Verified
Chart versions bumped to |
Follow-up to #277 and #278. The ChromaDB wiring in those is correct — I verified
YETI_CHROMADB_HTTP_ROOT,/api/v2/heartbeatandmountPath: /dataagainstchromadb/chroma:1.5.7andyetiplatform/yeti:2.9.0. This fixes the equivalent problem on the agents side.1.
YETI_AGENTS_ENDPOINTis not a setting Yeti hasYeti's config layer maps environment variables as
YETI_<SECTION>_<KEY>, and the agents integration readsenabled,http_rootandwebsocket_root(core/web/apiv2/agents.py:24-25). There is noendpointkey, so the variable was ignored.It failed loudly rather than silently, because the image ships
/app/yeti.conf. Runningyetiplatform/yeti:2.9.0with only the chart's variable set:Those are the Docker Compose service names. In Kubernetes they do not resolve — and since
enabledalso falls back toTrue, the UI advertised the agents feature and it failed for every user.2. Disabling agents did not disable them either
Same root cause, opposite direction. With agents off the guard set no variable at all, so that same
yeti.confleftenabled = True— the UI offered a feature with no backend deployed. The{{- else }}branch is as load-bearing as theif:3. Agents required
googleApiKeySecretbut notglobal.yeti.apiKeySecretapiKeySecretdefaults to"", so with only a Google secret configured the workload deployed withoutYETI_API_KEY:The agents start, but
semantic_searchfails on every call — the tool being the entire reason they are wired to Yeti. Both credentials are now required before the workload renders.The condition moves into a
yeti.agentsEnabledhelper rather than being repeated: the same answer decides the StatefulSet, its Service, and what the API is told about the feature, and those must not be able to disagree.Verified
helm lintpasses. All four configurations render as intended:YETI_AGENTS_ENABLED"False"googleApiKeySecretonly"False"llmProvider=ollama+apiKeySecret"True""True"With everything enabled, all five StatefulSets render (
api…agents,arangodb,bloomcheck,chromadb,tasks) and the URLs are correct:Deliberately not included
A
readinessProbeon the agents workload. yeti-platform/yeti-agents#7 adds a/healthendpoint reporting configuration state, which is the right probe target — but it is not merged, soyetiplatform/yeti-agents:devdoes not serve it yet and a probe would fail every pod. Worth a follow-up once that image ships.The
yeti.envsscope. The agents pod receivesYETI_ARANGODB_PASSWORD,YETI_AUTH_SECRET_KEYandYETI_USER_PASSWORDthrough the shared include and needs none of them. Out of scope here; better handled when that helper is split.Suggestion
This is the second variable-name mismatch of this kind (
YETI_CHROMA_HOSTin #277 review,YETI_AGENTS_ENDPOINThere), andhelm lintcannot catch either — they are semantically wrong, not malformed. A render-and-assert over the handful of variables Yeti actually reads would stop the next one: