-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy path.env.example
More file actions
195 lines (155 loc) · 8.19 KB
/
Copy path.env.example
File metadata and controls
195 lines (155 loc) · 8.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# Dotty — self-hosted StackChan robot assistant
# Copy to .env and fill in real values before deploying.
# --- xiaozhi-esp32-server (docker-compose.yml) ---
# Container timezone (IANA format).
TZ=Australia/Brisbane
# --- Kid Mode (child-safe guardrails) ---
# Set to "true" (default) to enable child-safe rules: age-appropriate
# vocabulary, topic blocklist, self-harm redirect, jailbreak resistance.
# Set to "false" for general-purpose assistant mode.
DOTTY_KID_MODE=true
# --- Admin API auth (X-Admin-Token) ---
# Shared secret protecting the /xiaozhi/admin/* routes (inject-text, say,
# set-state, play-asset, ...). `make setup` generates one into .env
# automatically if missing.
#
# Semantics: unset/empty = permissive mode — xiaozhi-server accepts admin
# calls with no auth (the pre-#149 behaviour). Set = xiaozhi-server
# requires a matching X-Admin-Token header on every admin call.
#
# Every caller reads this SAME variable: the bridge dashboard,
# dotty-behaviour's consumers, and the dotty-pi voice tools. When you set
# it, set the same value in each service's deploy-dir .env (bridge/,
# dotty-behaviour/, dotty-pi/) in the same restart window, or their admin
# calls will 401.
# DOTTY_ADMIN_TOKEN=
# --- bridge.py (admin dashboard) ---
# FastAPI listen port for the dashboard service (/ui, /admin/*, /health,
# /metrics). Post-#36 the bridge is dashboard-only; its former ZeroClaw
# voice path was retired (brain is now the dotty-pi container).
PORT=8081
# --- Perception: face greeter ---
# What the bridge says when a face is freshly detected. The firmware
# also fires WakeWordInvoke("face") on detection, which opens the mic
# regardless of this value. Trade-off:
#
# FACE_GREET_TEXT="Hi!" → popup chime + verbal "Hi!" + mic open
# (warmer; slightly noisy in everyday use)
# FACE_GREET_TEXT="" → popup chime + mic open, silent greeting
# (less chatty; mic still listens)
#
# Default is "Hi!". Set to "" to keep the mic-open behaviour without
# the verbal greeting.
# FACE_GREET_TEXT=Hi!
# Minimum seconds between consecutive face-detected greetings for the
# same device. Stops the robot re-greeting on every casual walk-by
# while still re-engaging after a real absence. The face state machine
# bounces in/out of the 2 s grace period during normal head movements,
# so any value below ~10 s will feel chatty. Default 30 s.
# FACE_GREET_MIN_INTERVAL_SEC=30
# Legacy alias for FACE_GREET_MIN_INTERVAL_SEC. Honoured for back-
# compat — set the new name on fresh deployments.
# FACE_GREET_COOLDOWN_SEC=30
# --- Purr-on-head-pet (Phase 1.7, Option B server-pushed) ---
# Path to the pre-rendered purr loop. Default points at the
# scaffolded location; drop a `purr.opus` file there to enable. See
# bridge/assets/README.md for spec (1-2 s loop, 24 kHz mono Opus).
# Until the file exists, the consumer logs a warning and no-ops.
# PURR_AUDIO_PATH=bridge/assets/purr.opus
# Per-device cooldown so a continuous head-pet doesn't re-trigger
# the clip on every event burst. Default 5 s.
# PURR_COOLDOWN_SEC=5
# Approximate playback duration. Used to extend `last_chat_t` while
# the purr plays so the sound localizer doesn't turn the head toward
# the speaker mid-purr. Match this to your purr.opus length.
# PURR_DURATION_SEC=2.0
# --- API keys (secrets — never commit real values) ---
# Required if using OpenAICompat LLM provider with a cloud endpoint.
# Get one at https://openrouter.ai/keys (OpenRouter) or https://platform.openai.com/api-keys (OpenAI).
# Not needed if running fully local via Ollama.
# OPENROUTER_API_KEY=sk-or-v1-...
# Required if using the vision feature (camera -> VLM description).
# Same key as above works if your provider supports vision models.
# VISION_API_KEY=sk-or-v1-...
# --- Google Calendar integration (optional) ---
# Comma-separated Google Calendar IDs for context injection.
# Requires a service account JSON at CALENDAR_SA_PATH.
# CALENDAR_ID=abc123@group.calendar.google.com
# CALENDAR_SA_PATH=/var/lib/dotty-bridge/secrets/google-calendar-sa.json
# Background poll cadence for the calendar cache refresher (seconds).
# Default 900 s = 15 min. Lower than CALENDAR_TTL_SEC so transient
# fetch failures don't leave a stale cache visible for the full TTL.
# CALENDAR_POLL_SEC=900
# Per-event person tag regex. Must define named groups `person` and
# `rest`. Default extracts `[Name] real summary` where Name is 1-32
# chars of [A-Za-z0-9_-] starting with a letter. Untagged events are
# bucketed under CALENDAR_HOUSEHOLD_BUCKET.
# CALENDAR_PERSON_PREFIX_RE=^\s*\[(?P<person>[A-Za-z][A-Za-z0-9_-]{0,31})\]\s*(?P<rest>.+)$
# Bucket name for events with no person tag. Leading underscore so it
# can't collide with a real first name typed into a calendar event.
# CALENDAR_HOUSEHOLD_BUCKET=_household
# --- Household registry ---
# Path to the YAML file that lists who lives here (display names,
# personalities, calendar prefixes, self-ID phrases, birthdates). The
# registry powers the speaker resolver, the proactive greeter, and the
# `[Speaking with]` block in voice prompts. Hot-reloaded on file change.
# Empty / missing file is fine — everyone resolves to `_household`.
# See `household.example.yaml` at the repo root for the schema.
# HOUSEHOLD_YAML_PATH=/var/lib/dotty-bridge/household.yaml
# --- Speaker resolver (Phase 1 identity) ---
# How long a self-ID phrase like "It's Brett" latches the channel onto
# that person. Default 600 s (10 min) — covers a typical conversation
# without dropping the user mid-thought. Anyone can override mid-session
# by saying another self-ID phrase ("It's Sam").
# SPEAKER_STICKY_SEC=600
# How wide a window (in minutes) calendar `[Person]` events still count
# as a prior. Defaults to 30 min — tight enough that "Hudson's library
# day at 10am" doesn't bias inputs at 5pm.
# SPEAKER_CALENDAR_WINDOW_MIN=30
# How recent a `face_recognized` perception event must be to vote.
# Default 30 s. Inert today (Layer 4 face-rec firmware not shipped);
# becomes the dominant signal once it lands.
# SPEAKER_PERCEPTION_WINDOW_SEC=30
# Below this confidence the resolver flags `ask_clarification=True` so
# the bridge can surface "Is that you, Hudson?" instead of guessing.
# SPEAKER_ASK_THRESHOLD=0.5
# --- Proactive Greetings (Layer 6) ---
# Server-initiated greetings when a recognised face walks into frame.
# See docs/proactive-greetings.md for the full architecture.
# Master kill switch.
# GREETER_ENABLED=true
# Subscribe to face_detected as a fallback while Layer 4 face
# recognition isn't fully wired. Treats every detection as
# identity=unknown — combine with GREETER_GREET_UNKNOWN to actually
# fire a greeting.
# GREETER_USE_FACE_DETECTED=false
# Greet unrecognised faces with a generic "Hello! I don't think we've met."
# GREETER_GREET_UNKNOWN=false
# Minimum hours between greetings for the same identity.
# GREETER_COOLDOWN_HOURS=4
# Hard cap on greetings per identity per day. Cooldown already prevents
# back-to-back firings; this is a ceiling, not a politeness lever.
# GREETER_PER_DAY_MAX=3
# Persistent greet log so a bridge restart doesn't re-greet everyone.
# GREETER_STATE_PATH=/var/lib/dotty-bridge/state/greeter_state.json
# Word cap fed to the LLM prompt.
# GREETER_GREETING_MAX_WORDS=15
# --- Blind mode (low-light camera handling) ---
# The OV-series camera produces unusable frames in the dark. When blind
# mode is active (civil dusk → civil dawn at the configured location):
# • the face-greeter ignores face_detected events (no 3 AM greets to
# noisy frames)
# • /api/vision/explain short-circuits with DOTTY_BLIND_PHOTO_REPLY
# instead of feeding a near-black JPEG to the VLM
# • [Context: ...] in the voice prompt notes "It's nighttime and Dotty
# can't see well right now" so unprompted "what do you see?" gets a
# sensible answer instead of a hallucination.
# Defaults match LOCAL_TZ (Brisbane). Set DOTTY_BLIND_MODE=false to
# disable all blind-mode gating (operator killswitch).
# DOTTY_BLIND_MODE=true
# DOTTY_BLIND_LAT=-27.47
# DOTTY_BLIND_LON=153.03
# DOTTY_BLIND_PHOTO_REPLY=It's too dark to see right now. Can you turn a light on?
# --- Debug flags ---
# (No bridge debug flags currently. The former ZEROCLAW_STREAM_DEBUG flag
# was retired with the ZeroClaw voice path in the #36 cutover.)