app

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: Apache-2.0 Imports: 66 Imported by: 0

Documentation

Overview

Package app contains the application-level wiring for the Thane server. It owns the full initialization sequence (databases, clients, tools, background loops) and the server lifecycle (start, graceful shutdown).

The primary entry point is New, which constructs an App from a validated config.Config. App.Serve then blocks until a shutdown signal is received and all in-flight requests drain.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	// contains filtered or unexported fields
}

App holds all long-lived application state for the Thane server. It is constructed by New and run by App.Serve. Fields map directly to the subsystems initialized during startup.

func New

func New(ctx context.Context, cfg *config.Config, logger *slog.Logger, stdout io.Writer, llmClient llm.Client, ollamaClients map[string]*modelproviders.OllamaClient, healthClients map[string]models.ResourceHealthClient, modelRuntime *models.Runtime) (*App, error)

New constructs and initializes a fully wired App from the provided configuration. The llmClient, resource health clients, and model registry/catalog are pre-constructed by the caller (cmd/thane) so that runAsk and runServe can share the same startup normalization path without importing internal/app.

New opens resources, wires dependencies, and registers background workers but does not start them. Call App.StartWorkers to launch all deferred goroutines and persistent loops, then App.Serve to start external servers and block until shutdown.

All resources that require cleanup are registered on the closer stack via [onClose] / [onCloseErr]. Workers register their stop functions during [StartWorkers]. The LIFO ordering guarantees workers stop before the resources they depend on are released. See [App.shutdown] for the two-phase teardown sequence.

Initialization is split into focused phases, each in its own file:

  • [initLogging] — logger, dataset writer, index DB, content writer
  • [initStores] — data stores, HA client, connwatch, router, scheduler
  • [initAgentLoop] — agent loop, path resolver, context injection
  • [initChannels] — tools, email, forge, MCP, Signal, facts, contacts
  • [initAwareness] — context providers, watchlist, person tracker, state watcher
  • [initDelegation] — delegate executor, notification routing, lenses, channel tags
  • [initServers] — API server, checkpointer, MQTT, dashboard, metacognitive
  • [finalizeCapabilityTags] — resolve capability tags from fully-assembled registry

Phase ordering rules for tool visibility (see #733):

  • Every global tool — including mqtt_wake_* registered in initServers and watchlist tools registered in initAwareness — must be in the registry before finalizeCapabilityTags runs so the snapshot reflects the complete catalog. The finalizer is deliberately last.
  • Subsystems whose backing runtime starts asynchronously (Signal) declare their tools up front via tools.Provider and return tools.ErrUnavailable from the handler until Bind is called. Those tools DO appear in the snapshot; they are not in s.deferredTools.
  • s.deferredTools is a narrow remaining escape hatch for tool families whose handler is still registered inside a deferWorker closure (today: macos_calendar_events). New subsystems should use Provider + declared-but-unavailable instead of adding entries here.
  • initDelegation no longer takes a capability-tag snapshot; it creates the delegate executor without tag state and leaves alwaysActiveTags / SetTagContextFunc to the finalizer.

func (*App) Close

func (a *App) Close()

Close releases all resources opened during New. It is safe to call multiple times and safe to call even if [StartWorkers] or [Serve] were never called — only non-nil resources are cleaned up. Callers should defer Close immediately after a successful New to guarantee cleanup on all exit paths.

func (*App) Logger

func (a *App) Logger() *slog.Logger

Logger returns the application's configured logger. Callers that construct the logger before calling New (e.g. cmd/thane/runServe) can call this after New returns to obtain the fully-configured logger (file handler, index handler, level, format) for subsequent log lines.

func (*App) Serve

func (a *App) Serve(ctx context.Context) error

Serve starts the API server(s), registers signal handlers for graceful shutdown, and blocks until the server stops. It returns nil on clean shutdown and a non-nil error only when the server fails unexpectedly.

Cleanup of all resources opened during New is handled by [App.shutdown], which Serve defers at entry.

func (*App) StartWorkers

func (a *App) StartWorkers(ctx context.Context) error

StartWorkers launches all background goroutines and persistent loops that were deferred during New. It is intended to be called once, after New returns and before App.Serve, as part of application startup.

Workers are started in the order they were registered (matching the original initialization order in New). If any worker returns a fatal error, StartWorkers returns immediately without starting remaining workers — the caller should treat this as a startup failure. Subsequent calls after all pending workers have been started do not start any additional workers and return nil.

type RelatedContact

type RelatedContact = agent.RelatedContact

RelatedContact mirrors agent.RelatedContact for the app package builder. We re-export the agent type alias here for clarity.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL