Documentation
¶
Overview ¶
Package otel discovers the local `ycode serve` observability stack (Prometheus + Alertmanager + VictoriaLogs + Jaeger + Perses, all reverse-proxied under one bearer-authed HTTP server) and lets outpost expose each surface through the matrix tunnel as a built-in app.
The data plane stays on the outpost: cloudbox federates by fanning out queries to each paired host's /app/otel-* surface; nothing is shipped or stored centrally. Symmetric with the LLM-pool and k3s- agent legs, where cloudbox owns the control plane and outposts own the data.
Discovery mirrors internal/agent/ycode/: a running `ycode serve` publishes $HOME/.agents/ycode/manifest.json. The manifest carries the proxy base URL (endpoints.proxy) and the path to the bearer token file (auth.tokenFile). One ycode-serve per OS user — no scanning, no probing beyond a single file read.
Index ¶
Constants ¶
const ( SurfacePrometheus = "otel-prometheus" // PromQL + remote_read + /federate SurfaceAlerts = "otel-alerts" // Alertmanager API v2 + UI SurfaceLogs = "otel-logs" // VictoriaLogs select/insert SurfaceTraces = "otel-traces" // Jaeger query SurfaceDashboard = "otel-dashboard" // Perses dashboards )
Surface names for the ycode observability stack. Each becomes a built-in app: /app/<name> on the matrix tunnel proxies to <ycode-proxy>/<sub-path>/. Cloudbox discovers these by scanning the /apps response for capability Type="otel".
Variables ¶
This section is empty.
Functions ¶
func BearerInjector ¶
BearerInjector returns proxy-wrap middleware that stamps Authorization: Bearer <token> on every forwarded request. The ycode proxy enforces bearer auth on every sub-path including /prometheus/ — without this header upstream returns 401 and the federated query path looks broken from cloudbox's side.
We set unconditionally (overwriting any inbound Authorization) because cloudbox's matrix-tunnel hop carries its own bearer in the reverse direction; the inbound value is irrelevant to ycode and would make this surface inadvertently accept cloudbox-tier tokens. Empty token returns a pass-through wrapper — handy for tests and for ycode builds with auth disabled.
func SubPath ¶
SubPath returns the ycode-proxy sub-path each surface lives at. Empty for unknown surfaces.
func Surfaces ¶
func Surfaces() []string
Surfaces returns the ordered list of ycode observability surfaces outpost exposes when OtelOn() is true. Order is significant only for log output (prometheus first because it's the most-queried) — every caller iterates the slice and treats each independently.
func YcodeSurfaceEnabled ¶ added in v0.1.1
YcodeSurfaceEnabled folds the catalog's DefaultOn with the per-surface overlay map. Returns true when the operator opted in, or when the surface is in the default-on set and the operator hasn't overridden. Reads safely from a nil map.
Types ¶
type Target ¶
type Target struct {
ProxyURL string
Token string
Available bool
// ManifestPath is the file we read (or tried to read). Exposed for
// admin-UI grey-out text ("tried <path>").
ManifestPath string
}
Target describes a discovered ycode observability proxy. ProxyURL is the base URL with no trailing slash (e.g. "http://127.0.0.1:31415"); callers append the per-surface sub-path (e.g. "/prometheus/"). Token is the raw bearer string read from auth.tokenFile, or "" when the manifest didn't advertise one (auth disabled).
Available reports whether a probe of ProxyURL returned any HTTP response. False means either no manifest, no ycode process, or a dead process (stale manifest); the caller skips registration.
type YcodeSurface ¶ added in v0.1.1
type YcodeSurface struct {
// Name is both the AppRegistry slot and the cloudbox tile name.
// Convention: `ycode` for the canonical chat (cloudbox's
// DefaultApps lists it), `ycode-<kind>` for everything else.
Name string
// Path is the sub-path on ycode's bearer-authed proxy at
// 127.0.0.1:31415. Trailing slash kept so reverse-proxy joins
// cleanly against an empty request path.
Path string
// Label is what the SPA toggle row says — human-readable.
Label string
// DefaultOn means the surface is enabled when YcodeShareSurfaces
// in FileConfig is nil OR has no entry for this Name. Only `ycode`
// (the chat) is default-on — turning ycode_share on without any
// other config should land the operator on a useful surface.
DefaultOn bool
}
YcodeSurface describes one ycode-backed UI surface outpost can expose through the matrix tunnel as a per-surface built-in app. Each entry becomes /h/<host>/app/<Name>/ on cloudbox; outpost reverse-proxies to <ycode-proxy>/<Path>/ with the ycode bearer auto-injected.
func YcodeSurfaces ¶ added in v0.1.1
func YcodeSurfaces() []YcodeSurface
YcodeSurfaces returns the catalog of ycode-backed UI surfaces in stable order. main.go iterates and registers each one whose EnabledIn(fc) returns true; the SPA renders one toggle row per entry.
Phase-scoped to chat-style entry points for now:
- ycode → /chat/ the polished chat ycode itself advertises as the canonical entry (default-on)
- ycode-canvas → /ycode/canvas/ canvas/a2ui interaction surface
- ycode-classic → /ycode/ the minimal chat at the legacy /ycode/ path
Non-chat surfaces (ollama UI, git, memos, graph) live in ycode's componentPathMap and are still reachable via outpost-add custom apps; they were briefly included in this catalog and pulled back out so operators get a focused list of "ways to chat with ycode." Re-introduce here once we have UI affordances to keep them visually grouped separately from chats.
Forward direction: canvas + chat are converging toward the unified agentic interaction surface, with the other paths potentially subsumed in a future ycode release. Keeping this list small now matches the trajectory and avoids surfacing options that will disappear later.