create-spatius-app 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -4
- package/dist/cli.js +7547 -23
- package/dist/cli.js.map +1 -1
- package/dist/templates.js +7655 -103
- package/dist/templates.js.map +1 -1
- package/package.json +2 -2
- package/schemas/result-v3.schema.json +170 -0
- package/templates/cloudflare-livekit/AGENTS.md +4 -0
- package/templates/cloudflare-livekit/README.md +44 -1
- package/templates/cloudflare-livekit/agent/README.md +0 -4
- package/templates/cloudflare-livekit/agent/pyproject.toml +2 -2
- package/templates/cloudflare-livekit/agent/src/agent.py +10 -0
- package/templates/cloudflare-livekit/agent/tests/test_agent_startup.py +21 -0
- package/templates/cloudflare-livekit/agent/uv.lock +21 -21
- package/templates/cloudflare-livekit/npmrc +0 -3
- package/templates/cloudflare-livekit/package.json +2 -2
- package/templates/cloudflare-livekit/pnpm-lock.yaml +101 -0
- package/templates/cloudflare-livekit/scripts/dev-web.mjs +12 -0
- package/templates/cloudflare-livekit/scripts/dev.mjs +29 -0
- package/templates/cloudflare-livekit/scripts/wait-for-agent.mjs +20 -0
- package/templates/cloudflare-livekit/tests/dev-fixtures.mjs +12 -1
- package/templates/cloudflare-livekit/tests/dev-supervision.test.mjs +108 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-spatius-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Create a Spatius app with a web frontend, Cloudflare Worker, and LiveKit agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=22"
|
|
36
36
|
},
|
|
37
|
-
"packageManager": "pnpm@
|
|
37
|
+
"packageManager": "pnpm@12.3.4",
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public",
|
|
40
40
|
"provenance": true
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "create-spatius-app result v3",
|
|
4
|
+
"oneOf": [
|
|
5
|
+
{
|
|
6
|
+
"$ref": "#/$defs/success"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"$ref": "#/$defs/failure"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"$defs": {
|
|
13
|
+
"success": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"required": [
|
|
17
|
+
"schemaVersion",
|
|
18
|
+
"ok",
|
|
19
|
+
"command",
|
|
20
|
+
"dryRun",
|
|
21
|
+
"generatorVersion",
|
|
22
|
+
"projectDirectory",
|
|
23
|
+
"template",
|
|
24
|
+
"created",
|
|
25
|
+
"wouldCreate",
|
|
26
|
+
"actions",
|
|
27
|
+
"packageManagers",
|
|
28
|
+
"nextSteps",
|
|
29
|
+
"humanSteps"
|
|
30
|
+
],
|
|
31
|
+
"properties": {
|
|
32
|
+
"schemaVersion": {
|
|
33
|
+
"const": 3
|
|
34
|
+
},
|
|
35
|
+
"ok": {
|
|
36
|
+
"const": true
|
|
37
|
+
},
|
|
38
|
+
"command": {
|
|
39
|
+
"const": "create"
|
|
40
|
+
},
|
|
41
|
+
"dryRun": {
|
|
42
|
+
"type": "boolean"
|
|
43
|
+
},
|
|
44
|
+
"generatorVersion": {
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
"projectDirectory": {
|
|
48
|
+
"type": "string"
|
|
49
|
+
},
|
|
50
|
+
"template": {
|
|
51
|
+
"const": "default"
|
|
52
|
+
},
|
|
53
|
+
"created": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "string"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"wouldCreate": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"items": {
|
|
62
|
+
"type": "string"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"actions": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"additionalProperties": false,
|
|
68
|
+
"required": ["dependenciesInstalled", "gitInitialized", "deployed"],
|
|
69
|
+
"properties": {
|
|
70
|
+
"dependenciesInstalled": {
|
|
71
|
+
"type": "boolean"
|
|
72
|
+
},
|
|
73
|
+
"gitInitialized": {
|
|
74
|
+
"const": false
|
|
75
|
+
},
|
|
76
|
+
"deployed": {
|
|
77
|
+
"const": false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"packageManagers": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"additionalProperties": false,
|
|
84
|
+
"required": ["javascript", "python"],
|
|
85
|
+
"properties": {
|
|
86
|
+
"javascript": {
|
|
87
|
+
"enum": ["npm", "pnpm", "bun"]
|
|
88
|
+
},
|
|
89
|
+
"python": {
|
|
90
|
+
"enum": ["pip", "uv"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"nextSteps": {
|
|
95
|
+
"type": "array",
|
|
96
|
+
"items": {
|
|
97
|
+
"type": "string"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"humanSteps": {
|
|
101
|
+
"type": "array",
|
|
102
|
+
"description": "Human prerequisites before running the app. Commands run from projectDirectory. On dry runs these are planned steps after creation, not actions already performed.",
|
|
103
|
+
"items": {
|
|
104
|
+
"type": "object",
|
|
105
|
+
"additionalProperties": false,
|
|
106
|
+
"required": ["command", "reason", "requiresHuman", "requiresTty"],
|
|
107
|
+
"properties": {
|
|
108
|
+
"command": {
|
|
109
|
+
"type": "string"
|
|
110
|
+
},
|
|
111
|
+
"reason": {
|
|
112
|
+
"type": "string"
|
|
113
|
+
},
|
|
114
|
+
"requiresHuman": {
|
|
115
|
+
"const": true
|
|
116
|
+
},
|
|
117
|
+
"requiresTty": {
|
|
118
|
+
"const": true
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"failure": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"additionalProperties": false,
|
|
128
|
+
"required": ["schemaVersion", "ok", "error"],
|
|
129
|
+
"properties": {
|
|
130
|
+
"schemaVersion": {
|
|
131
|
+
"const": 3
|
|
132
|
+
},
|
|
133
|
+
"ok": {
|
|
134
|
+
"const": false
|
|
135
|
+
},
|
|
136
|
+
"error": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"additionalProperties": false,
|
|
139
|
+
"required": ["code", "message"],
|
|
140
|
+
"properties": {
|
|
141
|
+
"code": {
|
|
142
|
+
"enum": [
|
|
143
|
+
"CANCELLED",
|
|
144
|
+
"FILESYSTEM_ERROR",
|
|
145
|
+
"INSTALL_FAILED",
|
|
146
|
+
"INVALID_ARGUMENT",
|
|
147
|
+
"PACKAGE_MANAGER_NOT_FOUND",
|
|
148
|
+
"PACKAGE_MANAGER_UNAVAILABLE",
|
|
149
|
+
"TARGET_NOT_DIRECTORY",
|
|
150
|
+
"TARGET_NOT_EMPTY",
|
|
151
|
+
"TEMPLATE_NOT_FOUND",
|
|
152
|
+
"UNSAFE_TARGET",
|
|
153
|
+
"UNKNOWN_ERROR"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"message": {
|
|
157
|
+
"type": "string"
|
|
158
|
+
},
|
|
159
|
+
"path": {
|
|
160
|
+
"type": "string"
|
|
161
|
+
},
|
|
162
|
+
"recovery": {
|
|
163
|
+
"type": "string"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -18,6 +18,10 @@ Run from the project root:
|
|
|
18
18
|
- Start only the Python agent: `__SPATIUS_AGENT_DEV_COMMAND__`
|
|
19
19
|
- Check frontend/Worker: `__SPATIUS_CHECK_COMMAND__`
|
|
20
20
|
- Check Python: `__SPATIUS_AGENT_CHECK_COMMAND__`
|
|
21
|
+
- Check browser flows with mocks: `__SPATIUS_E2E_COMMAND__`
|
|
22
|
+
|
|
23
|
+
All checks can run after dependency installation, before credential setup.
|
|
24
|
+
Browser tests require Chromium; see README.md for the installation command.
|
|
21
25
|
|
|
22
26
|
## Working guidelines
|
|
23
27
|
|
|
@@ -28,10 +28,53 @@ npx create-spatius-app setup . --interactive
|
|
|
28
28
|
Follow the prompts to connect LiveKit and Spatius, select an avatar, and choose
|
|
29
29
|
a matching voice. This configures local development only, not deployment.
|
|
30
30
|
|
|
31
|
+
#### Manual credential setup
|
|
32
|
+
|
|
33
|
+
Alternatively, copy `.dev.vars.example` to `.dev.vars` and
|
|
34
|
+
`agent/.env.example` to `agent/.env.local`, then edit the copies locally:
|
|
35
|
+
|
|
36
|
+
- Use the same LiveKit Cloud project’s `LIVEKIT_URL`, `LIVEKIT_API_KEY`, and
|
|
37
|
+
`LIVEKIT_API_SECRET` in both files.
|
|
38
|
+
- Set the same `SPATIUS_APP_ID` in both files and set `SPATIUS_API_KEY` in
|
|
39
|
+
`agent/.env.local` to a key for that app.
|
|
40
|
+
- In `.dev.vars`, set `SPATIUS_AVATAR_ID` to your chosen avatar.
|
|
41
|
+
`SPATIUS_AVATAR_BACKGROUND_URL` is optional and can stay empty. Keep the
|
|
42
|
+
example `CARTESIA_VOICE_ID` to use the default voice.
|
|
43
|
+
|
|
44
|
+
Keep the example `LIVEKIT_AGENT_NAME` so the Worker dispatches the bundled
|
|
45
|
+
agent. Both credential files are ignored by Git; keep their values local.
|
|
46
|
+
|
|
31
47
|
### 3. Start the app
|
|
32
48
|
|
|
33
49
|
```sh
|
|
34
50
|
__SPATIUS_DEV_COMMAND__
|
|
35
51
|
```
|
|
36
52
|
|
|
37
|
-
This starts the
|
|
53
|
+
This starts the Python agent first, then starts the frontend and Cloudflare
|
|
54
|
+
Worker once the agent has registered with LiveKit. If registration takes more
|
|
55
|
+
than 60 seconds, startup stops with an error.
|
|
56
|
+
|
|
57
|
+
## Validate without credentials
|
|
58
|
+
|
|
59
|
+
After installing both dependency sets, you can run these checks before account
|
|
60
|
+
setup. Run them from the project root:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
__SPATIUS_CHECK_COMMAND__
|
|
64
|
+
__SPATIUS_AGENT_CHECK_COMMAND__
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
These check formatting, lint, types, unit tests, development-process behavior,
|
|
68
|
+
and the production build. They do not require LiveKit or Spatius credentials.
|
|
69
|
+
|
|
70
|
+
Browser tests use mocked services and also run without credentials:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
npx playwright install chromium
|
|
74
|
+
__SPATIUS_E2E_COMMAND__
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The first command downloads Chromium if needed. On Linux, use
|
|
78
|
+
`npx playwright install --with-deps chromium` to also install required system
|
|
79
|
+
libraries. These tests verify the local UI flow; a real voice-avatar
|
|
80
|
+
conversation still requires account setup and starting the app.
|
|
@@ -22,10 +22,6 @@ LiveKit room as the browser.
|
|
|
22
22
|
enhanced noise-cancellation model in the browser; standard browser echo
|
|
23
23
|
cancellation can stay enabled.
|
|
24
24
|
|
|
25
|
-
The noise-cancellation dependency stays on the BVC-compatible `0.2.x` series.
|
|
26
|
-
LiveKit's newer voice-isolation recommendation is Krisp VIVA; switching to that
|
|
27
|
-
is a separate choice, not an implicit dependency upgrade.
|
|
28
|
-
|
|
29
25
|
See [Cartesia TTS](https://docs.livekit.io/agents/models/tts/cartesia/),
|
|
30
26
|
[expressive mode](https://docs.livekit.io/agents/models/tts/expressive/), and
|
|
31
27
|
[noise cancellation](https://docs.livekit.io/transport/media/noise-cancellation/).
|
|
@@ -5,8 +5,8 @@ description = "A LiveKit voice agent with a Spatius avatar"
|
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11,<3.15"
|
|
7
7
|
dependencies = [
|
|
8
|
-
"livekit-agents[spatius]~=1.
|
|
9
|
-
"livekit-plugins-noise-cancellation~=0.
|
|
8
|
+
"livekit-agents[spatius]~=1.8.0",
|
|
9
|
+
"livekit-plugins-noise-cancellation~=0.3.0",
|
|
10
10
|
"python-dotenv>=1.2.1,<2",
|
|
11
11
|
]
|
|
12
12
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import os
|
|
2
3
|
import textwrap
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
|
|
4
6
|
from dotenv import load_dotenv
|
|
5
7
|
from livekit import rtc
|
|
@@ -43,6 +45,14 @@ class Assistant(Agent):
|
|
|
43
45
|
server = AgentServer()
|
|
44
46
|
|
|
45
47
|
|
|
48
|
+
@server.on("worker_registered")
|
|
49
|
+
def report_dev_ready(_worker_id: str, _server_info: object) -> None:
|
|
50
|
+
# Only the root dev supervisor supplies this per-run path. Registration,
|
|
51
|
+
# not process launch or the local health endpoint, releases web startup.
|
|
52
|
+
if ready_file := os.environ.get("SPATIUS_DEV_READY_FILE"):
|
|
53
|
+
Path(ready_file).touch()
|
|
54
|
+
|
|
55
|
+
|
|
46
56
|
@server.rtc_session(agent_name="spatius-agent")
|
|
47
57
|
async def spatius_agent(ctx: JobContext) -> None:
|
|
48
58
|
ctx.log_context_fields = {"room": ctx.room.name}
|
|
@@ -207,5 +207,26 @@ class AgentStartupTests(unittest.IsolatedAsyncioTestCase):
|
|
|
207
207
|
)
|
|
208
208
|
|
|
209
209
|
|
|
210
|
+
class DevReadinessTests(unittest.TestCase):
|
|
211
|
+
def test_registration_writes_only_the_supervisors_ready_file(self) -> None:
|
|
212
|
+
with (
|
|
213
|
+
patch.dict(
|
|
214
|
+
"os.environ", {"SPATIUS_DEV_READY_FILE": "/tmp/test-agent-ready"}
|
|
215
|
+
),
|
|
216
|
+
patch.object(agent_module, "Path") as path,
|
|
217
|
+
):
|
|
218
|
+
agent_module.server.emit("worker_registered", "worker-test", object())
|
|
219
|
+
path.assert_called_once_with("/tmp/test-agent-ready")
|
|
220
|
+
path.return_value.touch.assert_called_once_with()
|
|
221
|
+
|
|
222
|
+
def test_standalone_agent_does_not_write_a_ready_file(self) -> None:
|
|
223
|
+
with (
|
|
224
|
+
patch.dict("os.environ", {}, clear=True),
|
|
225
|
+
patch.object(agent_module, "Path") as path,
|
|
226
|
+
):
|
|
227
|
+
agent_module.server.emit("worker_registered", "worker-test", object())
|
|
228
|
+
path.assert_not_called()
|
|
229
|
+
|
|
230
|
+
|
|
210
231
|
if __name__ == "__main__":
|
|
211
232
|
unittest.main()
|
|
@@ -777,7 +777,7 @@ wheels = [
|
|
|
777
777
|
|
|
778
778
|
[[package]]
|
|
779
779
|
name = "livekit"
|
|
780
|
-
version = "1.1.
|
|
780
|
+
version = "1.1.17"
|
|
781
781
|
source = { registry = "https://pypi.org/simple" }
|
|
782
782
|
dependencies = [
|
|
783
783
|
{ name = "aiofiles" },
|
|
@@ -786,18 +786,18 @@ dependencies = [
|
|
|
786
786
|
{ name = "protobuf" },
|
|
787
787
|
{ name = "types-protobuf" },
|
|
788
788
|
]
|
|
789
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
789
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/e20f97969cf21959061cdc6e1c89e3ad88e23693030398df283c236430fc/livekit-1.1.17.tar.gz", hash = "sha256:0553bfc9041dc8430029597a2278b43e4bb75594a72cb9dcc42bf3ee8e1689a0", size = 378467, upload-time = "2026-09-01T05:03:19.976Z" }
|
|
790
790
|
wheels = [
|
|
791
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
792
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
793
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
794
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
795
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
791
|
+
{ url = "https://files.pythonhosted.org/packages/fd/74/d93c5dd19ff2139c070eacb634e075cd2aff239a9cf692002afaa529a630/livekit-1.1.17-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:39188ac6c805643c8ef952cccb96b2e81e430600e626dea9c6aa1faca7013fdb", size = 10468167, upload-time = "2026-09-01T05:03:06.001Z" },
|
|
792
|
+
{ url = "https://files.pythonhosted.org/packages/d6/3a/9f4f5e3f0c325d0d5d19c5dc1ae345f4bf1353369db3b42e265a1ee4dbc5/livekit-1.1.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:078d249974aed5e845b60f840802e36dc9d2c9c1dd606341fb95ee018749169e", size = 9289118, upload-time = "2026-09-01T05:03:09.011Z" },
|
|
793
|
+
{ url = "https://files.pythonhosted.org/packages/1a/d5/89293b55b7a719c7f7b7929d995c009bee7ce9f4d29876c77ee878fd9bf9/livekit-1.1.17-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:984c7c0efa3e1f917e973ce412a141ff8244baf98ff24587aa82c206b621054f", size = 10580945, upload-time = "2026-09-01T05:03:11.743Z" },
|
|
794
|
+
{ url = "https://files.pythonhosted.org/packages/c9/4e/aad025688f8aceeecb4ec97aaae3541d64302e03454c84dc57e02bbaf5b9/livekit-1.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:100f2ddd8e433ea906ecf45f1d37063e43e72c7c2cff0b65ddddc11181bc8dd7", size = 11805780, upload-time = "2026-09-01T05:03:14.614Z" },
|
|
795
|
+
{ url = "https://files.pythonhosted.org/packages/97/7a/5447238155494f2a2fd55ff0f7705b9769fe67e787b52150a5d269eeaa61/livekit-1.1.17-py3-none-win_amd64.whl", hash = "sha256:7a7b1bdb646775d8042ec97baec6c6b615c5828d6f9b6dd2adaa167841d6f6c2", size = 10968316, upload-time = "2026-09-01T05:03:17.671Z" },
|
|
796
796
|
]
|
|
797
797
|
|
|
798
798
|
[[package]]
|
|
799
799
|
name = "livekit-agents"
|
|
800
|
-
version = "1.
|
|
800
|
+
version = "1.8.0"
|
|
801
801
|
source = { registry = "https://pypi.org/simple" }
|
|
802
802
|
dependencies = [
|
|
803
803
|
{ name = "aiofiles" },
|
|
@@ -833,9 +833,9 @@ dependencies = [
|
|
|
833
833
|
{ name = "typing-extensions" },
|
|
834
834
|
{ name = "watchfiles" },
|
|
835
835
|
]
|
|
836
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
836
|
+
sdist = { url = "https://files.pythonhosted.org/packages/99/88/ace06ebd95b8cc45e25430a2a10ec7ccfb6b386b67907192ad421493858f/livekit_agents-1.8.0.tar.gz", hash = "sha256:132029af152a585770b58623a1a2ac7c8b1b9241b045e8cd220b30415fbcf2ad", size = 2688509, upload-time = "2026-09-05T00:10:03.294Z" }
|
|
837
837
|
wheels = [
|
|
838
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
838
|
+
{ url = "https://files.pythonhosted.org/packages/f4/79/a1dce13ad49ab5b3248727b808ef265b2a535928c53161440d049a0b747d/livekit_agents-1.8.0-py3-none-any.whl", hash = "sha256:0da6c79c71eb7620af14d5c18adba1da796d6743338630813c341e9ce72f45c8", size = 2806075, upload-time = "2026-09-05T00:10:01.23Z" },
|
|
839
839
|
]
|
|
840
840
|
|
|
841
841
|
[package.optional-dependencies]
|
|
@@ -920,30 +920,30 @@ wheels = [
|
|
|
920
920
|
|
|
921
921
|
[[package]]
|
|
922
922
|
name = "livekit-plugins-noise-cancellation"
|
|
923
|
-
version = "0.
|
|
923
|
+
version = "0.3.0"
|
|
924
924
|
source = { registry = "https://pypi.org/simple" }
|
|
925
925
|
dependencies = [
|
|
926
926
|
{ name = "livekit" },
|
|
927
927
|
]
|
|
928
928
|
wheels = [
|
|
929
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
930
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
931
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
932
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
933
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
929
|
+
{ url = "https://files.pythonhosted.org/packages/d8/ad/e049eeca9c5175cc70c036c6dc5ce048215949b5d7ea83dbea6e2e06260c/livekit_plugins_noise_cancellation-0.3.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:6c877ca3f31278ce3b6ba7a3adc0eaaf813a53ba5a900445616be69ce7e4b3a8", size = 66079924, upload-time = "2026-07-17T10:35:02.671Z" },
|
|
930
|
+
{ url = "https://files.pythonhosted.org/packages/07/61/7a860386cf0c9d27f4d3fdcfeee411153e1618552d6a15ad46d32df64ac5/livekit_plugins_noise_cancellation-0.3.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1d100f249d25556696d8fe358b7c22d81017df67f256ee3b5c9c36830409621f", size = 64625049, upload-time = "2026-07-17T10:35:06.186Z" },
|
|
931
|
+
{ url = "https://files.pythonhosted.org/packages/2d/0d/df886e71b463911a9190cea948100f89c1e0546cff7e84dd93862b73e2d9/livekit_plugins_noise_cancellation-0.3.0-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:4b48de9ffdb8af47820ecd5e44ef0dbb910dfd05f17f6fadcbfd64deceb7a09a", size = 70250046, upload-time = "2026-07-17T10:35:09.376Z" },
|
|
932
|
+
{ url = "https://files.pythonhosted.org/packages/d1/43/701df4746e4e8b660f1399ec0a3da80de211f1624725a7496d28f7443b4a/livekit_plugins_noise_cancellation-0.3.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:1703099d634d26171e2f0402c81fc84f13bf0bc92a7f9ba16f9af1d0eefee980", size = 73004876, upload-time = "2026-07-17T10:35:12.775Z" },
|
|
933
|
+
{ url = "https://files.pythonhosted.org/packages/6f/b4/3ed7bac7aabec196c1e8969b407b71f69bdb0c942b1b3cd2aed07ae276cf/livekit_plugins_noise_cancellation-0.3.0-py3-none-win_amd64.whl", hash = "sha256:7f6001d0dd3b00c7748949b7a8349de002118fc03faa2d38411ad0d05180ccab", size = 65788455, upload-time = "2026-07-17T10:35:15.759Z" },
|
|
934
934
|
]
|
|
935
935
|
|
|
936
936
|
[[package]]
|
|
937
937
|
name = "livekit-plugins-spatius"
|
|
938
|
-
version = "1.
|
|
938
|
+
version = "1.8.0"
|
|
939
939
|
source = { registry = "https://pypi.org/simple" }
|
|
940
940
|
dependencies = [
|
|
941
941
|
{ name = "livekit-agents" },
|
|
942
942
|
{ name = "spatius", extra = ["opus"] },
|
|
943
943
|
]
|
|
944
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
944
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c0/40/ce00a90cdfd3fd0840ef452e8706e88ae5da9ab2c2cc900a615bfae7abcf/livekit_plugins_spatius-1.8.0.tar.gz", hash = "sha256:76d80c79db4673da4c1ce84f51fbec986a0bd7b888226d8fced68992c7d798e8", size = 8601, upload-time = "2026-09-05T00:12:14.914Z" }
|
|
945
945
|
wheels = [
|
|
946
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
946
|
+
{ url = "https://files.pythonhosted.org/packages/4d/34/bd44feacb043d16e18396bb7bb9ccb8f100348efce5090d853f8a6bfff1d/livekit_plugins_spatius-1.8.0-py3-none-any.whl", hash = "sha256:c852c7c1ec26b094cc207fa127de1f65e305c6def43d626ee65a250339a1bb69", size = 8712, upload-time = "2026-09-05T00:12:13.838Z" },
|
|
947
947
|
]
|
|
948
948
|
|
|
949
949
|
[[package]]
|
|
@@ -1891,8 +1891,8 @@ dev = [
|
|
|
1891
1891
|
|
|
1892
1892
|
[package.metadata]
|
|
1893
1893
|
requires-dist = [
|
|
1894
|
-
{ name = "livekit-agents", extras = ["spatius"], specifier = "~=1.
|
|
1895
|
-
{ name = "livekit-plugins-noise-cancellation", specifier = "~=0.
|
|
1894
|
+
{ name = "livekit-agents", extras = ["spatius"], specifier = "~=1.8.0" },
|
|
1895
|
+
{ name = "livekit-plugins-noise-cancellation", specifier = "~=0.3.0" },
|
|
1896
1896
|
{ name = "python-dotenv", specifier = ">=1.2.1,<2" },
|
|
1897
1897
|
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15,<1" },
|
|
1898
1898
|
]
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"cf-typegen": "wrangler types --env-interface CloudflareBindings",
|
|
11
11
|
"check": "pnpm format:check && pnpm lint && pnpm typecheck && pnpm test && pnpm test:dev && pnpm build",
|
|
12
12
|
"deploy": "pnpm build && wrangler deploy",
|
|
13
|
-
"dev": "
|
|
13
|
+
"dev": "node scripts/dev.mjs \"pnpm run dev:web\" \"pnpm run agent:dev\"",
|
|
14
14
|
"dev:web": "node scripts/dev-web.mjs",
|
|
15
15
|
"format": "prettier --write .",
|
|
16
16
|
"format:check": "prettier --check .",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=22.12"
|
|
27
27
|
},
|
|
28
|
-
"packageManager": "pnpm@
|
|
28
|
+
"packageManager": "pnpm@12.3.4",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@livekit/components-react": "2.9.24",
|
|
31
31
|
"@spatius/avatarkit": "1.3.8",
|
|
@@ -1,3 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
lockfileVersion: '9.0'
|
|
3
|
+
|
|
4
|
+
importers:
|
|
5
|
+
|
|
6
|
+
.:
|
|
7
|
+
configDependencies: {}
|
|
8
|
+
packageManagerDependencies:
|
|
9
|
+
pnpm:
|
|
10
|
+
specifier: 12.3.4
|
|
11
|
+
version: 12.3.4
|
|
12
|
+
|
|
13
|
+
packages:
|
|
14
|
+
|
|
15
|
+
'@pnpm/exe.darwin-arm64@12.3.4':
|
|
16
|
+
resolution: {integrity: sha512-PAyUol8T1+/+ViOiXAt51ECA+QnfXCqz6foL4bW+LsoX0NcVd5XVEM2mRQu+LV4oc7uRz9zf9U0P+XFfuQeDAw==}
|
|
17
|
+
cpu: [arm64]
|
|
18
|
+
os: [darwin]
|
|
19
|
+
|
|
20
|
+
'@pnpm/exe.darwin-x64@12.3.4':
|
|
21
|
+
resolution: {integrity: sha512-fxP9JCk0Cdye+ePuj+GJJLMUMTqHGWRdb1dtv4How876uQ2ehxvenpgiYAir/ceO9PsYUZkFTtyZdx+rRu5QOA==}
|
|
22
|
+
cpu: [x64]
|
|
23
|
+
os: [darwin]
|
|
24
|
+
|
|
25
|
+
'@pnpm/exe.linux-arm64-musl@12.3.4':
|
|
26
|
+
resolution: {integrity: sha512-FBOt0/7ye6O6q4AllVV5QMviB6qE6fqkeczV/+MDWQsmo+QJrlfsh6X7CpH/tClVpBZEyIbjpUoT8bNhCYBxEg==}
|
|
27
|
+
cpu: [arm64]
|
|
28
|
+
os: [linux]
|
|
29
|
+
libc: [musl]
|
|
30
|
+
|
|
31
|
+
'@pnpm/exe.linux-arm64@12.3.4':
|
|
32
|
+
resolution: {integrity: sha512-t71AVA7LRqiKTyZ5xMYaZc2n5DfdpMbfokZuiIOXHBOM03ECnF0t4iYwaBDqJgVjlKYUOwaF/bRQajGNA4cJ4w==}
|
|
33
|
+
cpu: [arm64]
|
|
34
|
+
os: [linux]
|
|
35
|
+
libc: [glibc]
|
|
36
|
+
|
|
37
|
+
'@pnpm/exe.linux-x64-musl@12.3.4':
|
|
38
|
+
resolution: {integrity: sha512-RPmk7Jb/aYaFvL2iyDN/AtMY+hUEsue732WmXpcuQ9tBpMnGyA5py7Z3+e+qmQaJ0zY/4ni9jJiyPBQHujmv6w==}
|
|
39
|
+
cpu: [x64]
|
|
40
|
+
os: [linux]
|
|
41
|
+
libc: [musl]
|
|
42
|
+
|
|
43
|
+
'@pnpm/exe.linux-x64@12.3.4':
|
|
44
|
+
resolution: {integrity: sha512-2ZqOlSPkfwX1h5cR+FPiWf8+F+2hZT/3TvhUK5sigHqwaQCIiq8R7CGxhndKs63JtcLi2a1Qpo+wX/EoyfjyJQ==}
|
|
45
|
+
cpu: [x64]
|
|
46
|
+
os: [linux]
|
|
47
|
+
libc: [glibc]
|
|
48
|
+
|
|
49
|
+
'@pnpm/exe.win32-arm64@12.3.4':
|
|
50
|
+
resolution: {integrity: sha512-ANyrHqyqco6SXBysUTRF74itDyyraea7IbFsKFdNXTjcFnfycTDx37EwuhdpPYFNSIh2JhUG4fByclsRfiHX7w==}
|
|
51
|
+
cpu: [arm64]
|
|
52
|
+
os: [win32]
|
|
53
|
+
|
|
54
|
+
'@pnpm/exe.win32-x64@12.3.4':
|
|
55
|
+
resolution: {integrity: sha512-WH/KqBPY/hq2Tb7SgQltEZytimcjgKRaCRL/aM9CI0c67iKc5TVmHUhIiL3Ux9FB4bWn36i6XewUcScQI+zG8w==}
|
|
56
|
+
cpu: [x64]
|
|
57
|
+
os: [win32]
|
|
58
|
+
|
|
59
|
+
pnpm@12.3.4:
|
|
60
|
+
resolution: {integrity: sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==}
|
|
61
|
+
engines: {node: '>=18.*'}
|
|
62
|
+
hasBin: true
|
|
63
|
+
|
|
64
|
+
snapshots:
|
|
65
|
+
|
|
66
|
+
'@pnpm/exe.darwin-arm64@12.3.4':
|
|
67
|
+
optional: true
|
|
68
|
+
|
|
69
|
+
'@pnpm/exe.darwin-x64@12.3.4':
|
|
70
|
+
optional: true
|
|
71
|
+
|
|
72
|
+
'@pnpm/exe.linux-arm64-musl@12.3.4':
|
|
73
|
+
optional: true
|
|
74
|
+
|
|
75
|
+
'@pnpm/exe.linux-arm64@12.3.4':
|
|
76
|
+
optional: true
|
|
77
|
+
|
|
78
|
+
'@pnpm/exe.linux-x64-musl@12.3.4':
|
|
79
|
+
optional: true
|
|
80
|
+
|
|
81
|
+
'@pnpm/exe.linux-x64@12.3.4':
|
|
82
|
+
optional: true
|
|
83
|
+
|
|
84
|
+
'@pnpm/exe.win32-arm64@12.3.4':
|
|
85
|
+
optional: true
|
|
86
|
+
|
|
87
|
+
'@pnpm/exe.win32-x64@12.3.4':
|
|
88
|
+
optional: true
|
|
89
|
+
|
|
90
|
+
pnpm@12.3.4:
|
|
91
|
+
optionalDependencies:
|
|
92
|
+
'@pnpm/exe.darwin-arm64': 12.3.4
|
|
93
|
+
'@pnpm/exe.darwin-x64': 12.3.4
|
|
94
|
+
'@pnpm/exe.linux-arm64': 12.3.4
|
|
95
|
+
'@pnpm/exe.linux-arm64-musl': 12.3.4
|
|
96
|
+
'@pnpm/exe.linux-x64': 12.3.4
|
|
97
|
+
'@pnpm/exe.linux-x64-musl': 12.3.4
|
|
98
|
+
'@pnpm/exe.win32-arm64': 12.3.4
|
|
99
|
+
'@pnpm/exe.win32-x64': 12.3.4
|
|
100
|
+
|
|
101
|
+
---
|
|
1
102
|
lockfileVersion: '9.0'
|
|
2
103
|
|
|
3
104
|
settings:
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { projectDirectory } from './agent-runtime.mjs';
|
|
3
|
+
import { waitForAgent } from './wait-for-agent.mjs';
|
|
3
4
|
import { runProcess } from './managed-process.mjs';
|
|
4
5
|
|
|
6
|
+
try {
|
|
7
|
+
if (process.env.SPATIUS_DEV_READY_FILE) {
|
|
8
|
+
console.log('Waiting for the LiveKit agent to register…');
|
|
9
|
+
await waitForAgent(process.env.SPATIUS_DEV_READY_FILE);
|
|
10
|
+
console.log('LiveKit agent registered. Starting frontend and Worker…');
|
|
11
|
+
}
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.error(error.message);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
const result = await runProcess(
|
|
6
18
|
process.execPath,
|
|
7
19
|
[
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { projectDirectory } from './agent-runtime.mjs';
|
|
5
|
+
import { runProcess } from './managed-process.mjs';
|
|
6
|
+
|
|
7
|
+
// A fresh directory prevents a previous run or another project from releasing
|
|
8
|
+
// this run's startup gate. Keep it outside the agent's auto-reload watch tree.
|
|
9
|
+
const directory = await mkdtemp(join(tmpdir(), 'spatius-dev-'));
|
|
10
|
+
try {
|
|
11
|
+
const result = await runProcess(
|
|
12
|
+
'concurrently',
|
|
13
|
+
['--kill-others', '--names', 'web,agent', ...process.argv.slice(2)],
|
|
14
|
+
{
|
|
15
|
+
cwd: projectDirectory,
|
|
16
|
+
env: {
|
|
17
|
+
...process.env,
|
|
18
|
+
SPATIUS_DEV_READY_FILE: join(directory, 'agent-ready'),
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
if (result.failed)
|
|
23
|
+
console.error(
|
|
24
|
+
'Could not start development services. Install JavaScript dependencies and try again.',
|
|
25
|
+
);
|
|
26
|
+
process.exitCode = result.code;
|
|
27
|
+
} finally {
|
|
28
|
+
await rm(directory, { recursive: true, force: true });
|
|
29
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
import { performance } from 'node:perf_hooks';
|
|
3
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
4
|
+
|
|
5
|
+
export async function waitForAgent(path, timeout = 60_000) {
|
|
6
|
+
const deadline = performance.now() + timeout;
|
|
7
|
+
while (true) {
|
|
8
|
+
try {
|
|
9
|
+
await access(path);
|
|
10
|
+
return;
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (error.code !== 'ENOENT') throw error;
|
|
13
|
+
}
|
|
14
|
+
if (performance.now() >= deadline)
|
|
15
|
+
throw new Error(
|
|
16
|
+
'LiveKit agent did not register within 60 seconds. Check the agent logs, credentials, and network connection, then run dev again.',
|
|
17
|
+
);
|
|
18
|
+
await delay(Math.min(100, Math.max(0, deadline - performance.now())));
|
|
19
|
+
}
|
|
20
|
+
}
|