Operate
Deployment and maintenance
Keep the runtime host, persistent services, and the hosted call service separate.
Choose the runtime host
The runtime host needs the workspace, the agent installation, credentials, and network access to the selected providers. A call link connects a device to that host; it does not host your agent for you.
Start with a foreground call. Verify the workspace and permissions before adding unattended operation. A sleeping or offline laptop cannot provide a continuously available agent.
For a VPS, choose how browser calls reach you:
| Delivery | Needs | Limit |
|---|---|---|
| Your tailnet | Tailscale on the VPS and on your phone or laptop, with HTTPS certificates enabled | None |
| Hosted relay | Nothing extra | 30 minutes per call, plus daily budgets |
See calls over your tailnet. A Discord bot needs neither; it only needs outbound access to Discord.
OS services
The service commands generate user-level launchd or systemd definitions. Set agent.workspace_dir explicitly in the profile, then check preflight:
sleeptalk service preflight workspace-voice --config /path/to/profile.toml
sleeptalk service install workspace-voice --config /path/to/profile.toml
sleeptalk service status workspace-voiceservice install prints a preflight report and the definition, then asks before writing it. --yes skips the question. It never enables or starts the job; start it with your OS service manager. A ready preflight means a definition can be written. It does not prove the service can reach credentials, the agent login, or the workspace.
Generated definitions pin the Python executable, profile, and working directory. They do not embed provider keys. Moving an installation means regenerating and reviewing the definition. Terminal audio needs an attached person and is not a service path. A Discord bot is the usual thing to run as a service; see Discord setup.
Stop and unload a running job through the OS manager before service uninstall. Uninstall removes the definition and keeps profiles, logs, credentials, and installed runtimes. The exact OS commands are in the deployment guide. Reboot, sleep, and login behavior are still yours to check.
Containers
The repository includes a Dockerfile and a Compose example. The image includes ffmpeg, libopus, and the default pi agent CLI. Sleeptalk and the agents it starts run as an unprivileged user, never root. Build from the repository; the image name in the guide is a placeholder, not a published image.
The Compose volume covers SLEEPTALK_HOME. Private credentials and isolated runtimes live in separate locations, so that one mount is not a complete persistence plan. Map the workspace and private state deliberately, and check the container user's access before treating a recreated container as recoverable.
Updates
For a PyPI install, stop the affected call or service, activate the same environment, and update:
. ~/.venvs/sleeptalk/bin/activate
python -m pip install --upgrade sleeptalkInclude the extras you use, for example python -m pip install --upgrade 'sleeptalk[claude,terminal]'. Check the installed version with sleeptalk --version, read the release notes, and verify a call before restarting unattended operation. Keep the previous version and configuration available for rollback. See support and release status.
For a reviewed release wheel, sleeptalk host bootstrap --artifact <wheel> --sha256 <hash> --surface <surface> --agent <agent> verifies the hash and installs into a new, separate environment. It does not replace the environment an existing call is using. Use the executable named in its receipt, and test the new installation before switching a service to it.
Main-branch wheels built by CI carry an increasing version, so a newer build installs over an older one.
Exit codes
| Code | Runtime result | Supervisor action |
|---|---|---|
| 0 | Clean shutdown | Intended stop. Not a failure. |
| 1 | Runtime crash, after a FATAL log line | Safe to restart |
| 2 | Configuration or startup error | Do not restart. Fix the configuration. |
For systemd, pair Restart=on-failure with RestartPreventExitStatus=2 so a configuration error does not loop. Other commands have their own exit contracts. Each run also appends to logs/<slug>.log in the state directory.
Self-host browser signaling
Use --rendezvous on sleeptalk link or sleeptalk host start-voice to point at a compatible signaling origin you operate. The flag selects a service; it does not deploy one. Plain http origins work only on loopback.
Operators need HTTPS signaling, installation grants, TURN configuration, budgets, rate limits, revocation, monitoring, and a rollback procedure. A STUN-only development deployment does not give reliable public connectivity.
Operating the hosted call service
The hosted service is a Cloudflare Worker in the repository's rendezvous/ folder. Production serves call.sleep.talk from the sleeptalk-call-production Worker (wrangler.production.jsonc). Staging serves call-staging.sleep.talk from sleeptalk-call-staging (wrangler.jsonc). Use the host names, not the Worker names, in user-facing text.
The Worker serves the call page and the settings page for phones (/settings). One build writes the page to sleeptalk/_web, which both the wheel and the Worker read. The built files are committed, so local and tailnet calls get a page change with the next package; hosted calls get it only after a Worker deploy:
npm test
npm run check
npm run deploy:staging
npm run deploy:productionDeploy and prove staging before production. Relay budgets, rate limits, halt, credential rotation, and rollback are in browser service operations. A halt blocks new links and new TURN credentials; it does not stop credentials already issued.