-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
136 lines (136 loc) · 6.93 KB
/
Copy path.env.example
File metadata and controls
136 lines (136 loc) · 6.93 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
HOST=127.0.0.1
PORT=3996
PUBLIC_BASE_URL=http://127.0.0.1:3996
# `cloud` hides self-hosted tunnel controls and presents connector-first operations in the console.
DEPLOYMENT_MODE=self-hosted
# `npm run setup:tunnel -- --mode serve --write-env` replaces PUBLIC_BASE_URL with
# the Tailscale HTTPS origin and appends it to CLERK_AUTHORIZED_PARTIES.
DATA_FILE=.data/agent-controller.json
STORAGE_PROVIDER=convex
CONVEX_URL=https://your-deployment.convex.cloud
CONVEX_DEPLOYMENT=dev:your-deployment
GATEWAY_CONVEX_SECRET=replace-with-shared-gateway-convex-secret
T3_TOKEN_ENCRYPTION_KEY=replace-with-32-byte-or-longer-token-encryption-secret
MEDIA_DIR=.data/media
MAX_MEDIA_BYTES=2097152
MEDIA_UPLOAD_SESSION_TTL_MS=900000
DEFAULT_MEDIA_RETENTION_DAYS=30
ENVIRONMENT_RETENTION_DAYS=30
# Signs the short-lived media URLs handed to T3 as attachments.
# Falls back to T3_TOKEN_ENCRYPTION_KEY, then GATEWAY_CONVEX_SECRET.
MEDIA_SIGNING_KEY=replace-with-media-url-signing-secret
MEDIA_LINK_TTL_SECONDS=900
# Media at or under this size is also inlined into the dispatch payload so an
# environment that cannot call back to the gateway still receives the bytes.
MEDIA_INLINE_MAX_BYTES=262144
# TRANSCRIPTION_PROVIDER: disabled | mock | openai | parakeet
#
# Leaving this unset is the same as "disabled", and a disabled provider fails every job
# terminally with "No transcription provider is configured." — the voice pipeline is dead
# end to end until this names a real one. "mock" returns a fabricated transcript and must
# never reach a deployment that dispatches to an agent.
#
# "parakeet" is the intended local path: nvidia/parakeet-tdt-0.6b-v2 running in the sidecar
# at scripts/parakeet-sidecar.py, which the gateway only ever talks HTTP to.
#
# npm run parakeet:fetch # ~630 MB of ONNX weights into PARAKEET_MODEL_DIR
# npm run parakeet:sidecar # loads them and listens on 127.0.0.1:8977
TRANSCRIPTION_PROVIDER=parakeet
# TRANSCRIPTION_URL=https://api.openai.com/v1/audio/transcriptions
# TRANSCRIPTION_API_KEY=sk-replace
# TRANSCRIPTION_MODEL=whisper-1
# TRANSCRIPTION_TIMEOUT_MS=30000
# Where the sidecar listens. Must match the --port/--route it was started with.
# PARAKEET_URL=http://127.0.0.1:8977/v1/transcribe
# Where `npm run parakeet:fetch` writes the weights and the sidecar reads them from.
# Under .data/ so it is already gitignored; never commit the weights.
# PARAKEET_MODEL_DIR=.data/models/parakeet-tdt-0.6b-v2-onnx
# int8 (~630 MB, the default) or fp32 (~2.5 GB, slower on CPU for a marginal gain).
# PARAKEET_MODEL_PRECISION=int8
# The checkpoint the gateway believes is loaded; the sidecar refuses a mismatch.
# PARAKEET_MODEL=nvidia/parakeet-tdt-0.6b-v2
# v2 is ENGLISH ONLY. Another language is a terminal configuration error, not a degraded
# transcript — the model would return confident English-shaped nonsense and the gateway
# would dispatch it. Use a multilingual checkpoint instead of changing this.
# PARAKEET_LANGUAGE=en
# CPU inference is minutes, not seconds, on a long clip.
# PARAKEET_TIMEOUT_MS=120000
# A WAV whose own header exceeds this is refused before any inference is spent.
# PARAKEET_MAX_CLIP_SECONDS=120
# One model in memory on a CPU is one clip at a time; raise it only on a GPU box.
# PARAKEET_CONCURRENCY=1
# PARAKEET_ACCEPTED_CONTENT_TYPES=audio/wav,audio/webm,audio/ogg,audio/mp4
# Only needed when the sidecar sits behind an authenticated hop.
# PARAKEET_API_KEY=replace
# VISION_PROVIDER: disabled | mock | openai. Powers POST /v1/media/:id/describe, whose
# description is attached to the prompt so the agent gets the image content even when it
# cannot fetch or see the image itself.
VISION_PROVIDER=disabled
# VISION_URL=https://api.openai.com/v1/chat/completions
# VISION_API_KEY=sk-replace
# VISION_MODEL=gpt-4o-mini
# VISION_TIMEOUT_MS=30000
# Media object storage. "disk" keeps files under MEDIA_DIR; "s3" uses any S3-compatible bucket.
MEDIA_STORAGE_PROVIDER=disk
# S3_ENDPOINT=http://127.0.0.1:9000
# S3_REGION=us-east-1
# S3_BUCKET=agent-controller-media
# S3_ACCESS_KEY_ID=replace
# S3_SECRET_ACCESS_KEY=replace
# Leave S3_FORCE_PATH_STYLE unset to auto-detect: MinIO/R2 need path style, AWS does not.
# S3_FORCE_PATH_STYLE=1
# Durable firmware artifacts. Use a private S3/R2 bucket in production; downloads remain behind
# device authentication and storage credentials are never returned by the API.
# FIRMWARE_STORAGE_PROVIDER=s3
# FIRMWARE_S3_BUCKET=agent-controller-firmware
# FIRMWARE_S3_PREFIX=firmware
# FIRMWARE_DIR=.data/firmware
# MAX_FIRMWARE_BYTES=16777216
# Optional dedicated HMAC key for short-lived legacy OTA download capabilities. If omitted,
# OTA_SIGNING_KEY is used. Keep this server-side; it is never returned to a controller.
# FIRMWARE_DOWNLOAD_SIGNING_KEY=replace-with-random-server-secret
# FIRMWARE_DOWNLOAD_TTL_SECONDS=600
# Alert thresholds default to the roadmap's beta success criteria.
# ALERT_ACK_MEDIAN_MS=2000
# ALERT_DISPATCH_MEDIAN_MS=10000
# ALERT_COMMAND_FAILURE_RATIO=0.1
# Phase 4 "TLS only": refuse to issue or accept device credentials over plaintext.
# Loopback stays exempt for local development. See docs/production-security.md.
REQUIRE_TLS=0
# Issuing roots embedded into generated factory controller_config.h files. Keep the current and next
# roots during CA rotation; production firmware refuses HTTPS when the current root is empty.
# GATEWAY_TLS_ROOT_CA_PEM=-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----
# GATEWAY_TLS_NEXT_ROOT_CA_PEM=-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----
AUTH_PROVIDER=clerk
CLERK_SECRET_KEY=sk_test_replace
VITE_CLERK_PUBLISHABLE_KEY=pk_test_replace
CLERK_AUTHORIZED_PARTIES=http://127.0.0.1:3996,https://gateway.example.com
CLERK_JWT_ISSUER_DOMAIN=https://your-clerk-issuer.clerk.accounts.dev
# FACTORY_TOKEN=replace-with-factory-secret
# OTA_SIGNING_KEY=replace-with-firmware-manifest-signing-key
DEFAULT_HARDWARE_MODEL=e213-esp32-s3r8
# Policy: comma-separated trusted origins (CIDR, exact IP, or the literal "loopback").
# Leave unset to disable network-location policy entirely. When set, requests from outside
# these ranges escalate shell input to an approval gate.
# TRUSTED_NETWORKS=loopback,10.0.0.0/8
# Policy: global allowed-hours window, "START-END" in local time, or a JSON window object.
# POLICY_ALLOWED_HOURS=9-18
# Background T3 snapshot polling for users with a live stream or a recent device heartbeat.
SNAPSHOT_POLL_ENABLED=1
SNAPSHOT_POLL_INTERVAL_MS=5000
# Share one rate-limit window across processes. Unset means per-process limits, so N instances
# allow N times the configured limit.
# RATE_LIMIT_REDIS_URL=redis://127.0.0.1:6379
# Billing. Plan limits and tier-based policy stay inert until BILLING_ENFORCED=1, because the
# default free tier grants 0 devices and no shell access.
BILLING_ENFORCED=0
# BILLING_WEBHOOK_SECRET=replace-with-provider-webhook-secret
RATE_LIMIT_WINDOW_MS=60000
AUTH_RATE_LIMIT=30
FACTORY_WRITE_RATE_LIMIT=30
USER_READ_RATE_LIMIT=240
USER_WRITE_RATE_LIMIT=60
DEVICE_HEARTBEAT_RATE_LIMIT=120
DEVICE_READ_RATE_LIMIT=120
DEVICE_WRITE_RATE_LIMIT=30
DEMO_MODE=0