create-spatius-app 0.1.3-beta.1 → 0.1.3
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 +12 -10
- package/dist/cli.js +199 -207
- package/dist/templates.js +183 -199
- package/package.json +3 -3
- package/templates/cloudflare-livekit/AGENTS.md +2 -0
- package/templates/cloudflare-livekit/README.md +10 -0
- package/templates/cloudflare-livekit/agent/Dockerfile.pip +8 -0
- package/templates/cloudflare-livekit/agent/Dockerfile.uv +8 -0
- package/templates/cloudflare-livekit/agent/README.md +16 -1
- package/templates/cloudflare-livekit/agent/pyproject.toml +1 -1
- package/templates/cloudflare-livekit/agent/src/agent.py +2 -1
- package/templates/cloudflare-livekit/agent/tests/test_agent_startup.py +49 -0
- package/templates/cloudflare-livekit/agent/uv.lock +14 -14
- package/templates/cloudflare-livekit/gitignore +1 -0
- package/templates/cloudflare-livekit/package-lock.json +511 -411
- package/templates/cloudflare-livekit/package.json +17 -16
- package/templates/cloudflare-livekit/pnpm-lock.yaml +572 -480
- package/templates/cloudflare-livekit/tests/dev-fixtures.mjs +7 -2
- package/templates/cloudflare-livekit/tests/dev-supervision.test.mjs +82 -20
- package/templates/layers/agora/AGENTS.md +9 -4
- package/templates/layers/agora/README.md +14 -8
- package/templates/layers/agora/package-lock.json +6307 -4129
- package/templates/layers/agora/package.json +24 -18
- package/templates/layers/agora/pnpm-lock.yaml +1765 -563
- package/templates/layers/agora/pnpm-workspace.yaml +8 -0
- package/templates/layers/agora/scripts/check-worker.mjs +98 -0
- package/templates/layers/agora/tsconfig.worker.json +23 -0
- package/templates/layers/agora/worker/agora.test.ts +2 -0
- package/templates/layers/agora/worker/agora.ts +1 -10
- package/templates/layers/agora/worker/index.test.ts +66 -0
- package/templates/layers/agora/worker/index.ts +4 -0
- package/templates/layers/agora/wrangler.jsonc +24 -0
- package/templates/cloudflare-livekit/worker-configuration.d.ts +0 -17184
- package/templates/layers/agora/tsconfig.json +0 -16
- package/templates/layers/node/Dockerfile +0 -12
- package/templates/layers/node/dockerignore +0 -10
- package/templates/layers/node/package-lock.json +0 -5569
- package/templates/layers/node/pnpm-lock.yaml +0 -3470
- package/templates/layers/node/railway.json +0 -8
- package/templates/layers/node/scripts/dev-service.mjs +0 -14
- package/templates/layers/node/scripts/dev-web.mjs +0 -22
- package/templates/layers/node/server/index.ts +0 -92
- package/templates/layers/node/vite.config.ts +0 -17
- package/templates/layers/railway-agent/agent/railway.json +0 -5
- /package/templates/layers/agora/{env.example → dev.vars.example} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-spatius-app",
|
|
3
|
-
"version": "0.1.3
|
|
4
|
-
"description": "Create a Spatius voice-avatar app with LiveKit or Agora
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Create a Spatius voice-avatar app with LiveKit or Agora Conversational AI on Cloudflare Workers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-spatius-app": "./dist/cli.js"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=22"
|
|
36
36
|
},
|
|
37
|
-
"packageManager": "pnpm@12.
|
|
37
|
+
"packageManager": "pnpm@12.4.1",
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public",
|
|
40
40
|
"provenance": true
|
|
@@ -22,6 +22,8 @@ Run from the project root:
|
|
|
22
22
|
|
|
23
23
|
All checks can run after dependency installation, before credential setup.
|
|
24
24
|
Browser tests require Chromium; see README.md for the installation command.
|
|
25
|
+
Wrangler generates the ignored `worker-configuration.d.ts` during installation
|
|
26
|
+
and before lint, type checking, and builds. Update `wrangler.jsonc` to change bindings.
|
|
25
27
|
|
|
26
28
|
## Working guidelines
|
|
27
29
|
|
|
@@ -54,6 +54,16 @@ This starts the Python agent first, then starts the frontend and Cloudflare
|
|
|
54
54
|
Worker once the agent has registered with LiveKit. If registration takes more
|
|
55
55
|
than 60 seconds, startup stops with an error.
|
|
56
56
|
|
|
57
|
+
Press Ctrl+C once to stop both services. If shutdown logs cover the shell prompt
|
|
58
|
+
and it looks as though another Ctrl+C is required, use pnpm 12.4.1 or later for
|
|
59
|
+
both the executable on your PATH and the `packageManager` pin in `package.json`.
|
|
60
|
+
An older launcher or project pin can return to the shell before the services
|
|
61
|
+
finish shutting down; [pnpm 12.4.1 fixes signal forwarding and waiting](https://github.com/pnpm/pnpm/releases/tag/v12.4.1).
|
|
62
|
+
For a Homebrew installation, run `brew update` followed by `brew upgrade pnpm`.
|
|
63
|
+
Set `packageManager` to `pnpm@12.4.1`, then run `pnpm install` to refresh the
|
|
64
|
+
package-manager lock entry. Changing only the project pin leaves an older
|
|
65
|
+
launcher in use; upgrading only the launcher leaves an older project pin active.
|
|
66
|
+
|
|
57
67
|
## Validate without credentials
|
|
58
68
|
|
|
59
69
|
After installing both dependency sets, you can run these checks before account
|
|
@@ -21,6 +21,11 @@ ENV PATH="/app/.venv/bin:$PATH" \
|
|
|
21
21
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
22
22
|
PYTHONUNBUFFERED=1
|
|
23
23
|
|
|
24
|
+
# Spatius encodes outgoing avatar audio with the native Opus library.
|
|
25
|
+
RUN apt-get update \
|
|
26
|
+
&& apt-get install -y --no-install-recommends libopus0 \
|
|
27
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
28
|
+
|
|
24
29
|
RUN useradd --create-home --uid 10001 appuser
|
|
25
30
|
WORKDIR /app
|
|
26
31
|
|
|
@@ -28,4 +33,7 @@ COPY --from=builder --chown=appuser:appuser /app /app
|
|
|
28
33
|
|
|
29
34
|
USER appuser
|
|
30
35
|
|
|
36
|
+
# Fail the build if the runtime cannot load the native audio encoder.
|
|
37
|
+
RUN python -c "import opuslib_next"
|
|
38
|
+
|
|
31
39
|
CMD ["python", "-m", "src.agent", "start"]
|
|
@@ -19,6 +19,11 @@ FROM python:${PYTHON_VERSION}-slim-bookworm
|
|
|
19
19
|
ENV PATH="/app/.venv/bin:$PATH" \
|
|
20
20
|
PYTHONUNBUFFERED=1
|
|
21
21
|
|
|
22
|
+
# Spatius encodes outgoing avatar audio with the native Opus library.
|
|
23
|
+
RUN apt-get update \
|
|
24
|
+
&& apt-get install -y --no-install-recommends libopus0 \
|
|
25
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
26
|
+
|
|
22
27
|
RUN useradd --create-home --uid 10001 appuser
|
|
23
28
|
WORKDIR /app
|
|
24
29
|
|
|
@@ -26,4 +31,7 @@ COPY --from=builder --chown=appuser:appuser /app /app
|
|
|
26
31
|
|
|
27
32
|
USER appuser
|
|
28
33
|
|
|
34
|
+
# Fail the build if the runtime cannot load the native audio encoder.
|
|
35
|
+
RUN python -c "import opuslib_next"
|
|
36
|
+
|
|
29
37
|
CMD ["python", "-m", "src.agent", "start"]
|
|
@@ -6,6 +6,19 @@ and turn detection. The Spatius plugin sends the generated speech through the
|
|
|
6
6
|
Spatius motion service and publishes synchronized avatar data into the same
|
|
7
7
|
LiveKit room as the browser.
|
|
8
8
|
|
|
9
|
+
## Session startup
|
|
10
|
+
|
|
11
|
+
The worker runs `spatius.prewarm` through `AgentServer`'s `setup_fnc` when each
|
|
12
|
+
job process initializes. It prepares automatic region selection, TLS connections,
|
|
13
|
+
and a session token using the same Spatius environment variables as the avatar
|
|
14
|
+
session, so a warm process can skip that setup when a room is dispatched.
|
|
15
|
+
The avatar ID still comes from the job's dispatch metadata.
|
|
16
|
+
|
|
17
|
+
Warm-up is best effort: missing configuration or a failed warm-up leaves normal
|
|
18
|
+
session startup responsible for resolving the region and fetching a token.
|
|
19
|
+
LiveKit keeps idle processes ready in production; development mode initializes
|
|
20
|
+
processes on demand, so its first session still pays the warm-up cost.
|
|
21
|
+
|
|
9
22
|
## Voice configuration
|
|
10
23
|
|
|
11
24
|
- TTS uses `cartesia/sonic-3.6` through LiveKit Inference. Setup offers
|
|
@@ -77,4 +90,6 @@ Use `lk agent deploy` for later releases. Keep `livekit.toml` local until you
|
|
|
77
90
|
have reviewed the project-specific values it contains.
|
|
78
91
|
|
|
79
92
|
The Docker image runs as a non-root user and downloads model support files at
|
|
80
|
-
build time so startup does not need to fetch them.
|
|
93
|
+
build time so startup does not need to fetch them. It also installs the native
|
|
94
|
+
Opus library required for Spatius audio forwarding and checks that the Python
|
|
95
|
+
binding can load it during the build.
|
|
@@ -5,7 +5,7 @@ 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.8.
|
|
8
|
+
"livekit-agents[spatius]~=1.8.1",
|
|
9
9
|
"livekit-plugins-noise-cancellation~=0.3.0",
|
|
10
10
|
"python-dotenv>=1.2.1,<2",
|
|
11
11
|
]
|
|
@@ -11,6 +11,55 @@ with patch("dotenv.load_dotenv"):
|
|
|
11
11
|
from src import agent as agent_module
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
class ProcessPrewarmTests(unittest.TestCase):
|
|
15
|
+
def setUp(self) -> None:
|
|
16
|
+
self.enterContext(
|
|
17
|
+
patch.dict(
|
|
18
|
+
"os.environ",
|
|
19
|
+
{"SPATIUS_APP_ID": "app-test", "SPATIUS_API_KEY": "key-test"},
|
|
20
|
+
clear=True,
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
# Exercise the registered hook and installed plugin without provider calls.
|
|
24
|
+
self.sdk_prewarm = self.enterContext(
|
|
25
|
+
patch(
|
|
26
|
+
"spatius.prewarm",
|
|
27
|
+
new_callable=AsyncMock,
|
|
28
|
+
return_value=SimpleNamespace(
|
|
29
|
+
region="test-region",
|
|
30
|
+
tls_warmed=True,
|
|
31
|
+
session_token_prefetched=True,
|
|
32
|
+
),
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def test_process_setup_warms_connection_state_without_an_avatar(self) -> None:
|
|
37
|
+
with patch.object(agent_module.spatius, "AvatarSession") as avatar:
|
|
38
|
+
agent_module.server.setup_fnc(SimpleNamespace())
|
|
39
|
+
|
|
40
|
+
self.sdk_prewarm.assert_awaited_once()
|
|
41
|
+
options = self.sdk_prewarm.call_args.kwargs
|
|
42
|
+
self.assertEqual(options["app_id"], "app-test")
|
|
43
|
+
self.assertEqual(options["api_key"], "key-test")
|
|
44
|
+
self.assertEqual(options["region"], "auto")
|
|
45
|
+
self.assertTrue(options["prefetch_session_token"])
|
|
46
|
+
avatar.assert_not_called()
|
|
47
|
+
|
|
48
|
+
def test_warmup_failure_does_not_fail_process_setup(self) -> None:
|
|
49
|
+
self.sdk_prewarm.side_effect = ConnectionError("warm-up unavailable")
|
|
50
|
+
|
|
51
|
+
with self.assertLogs("livekit.plugins.spatius", level="WARNING"):
|
|
52
|
+
agent_module.server.setup_fnc(SimpleNamespace())
|
|
53
|
+
|
|
54
|
+
self.sdk_prewarm.assert_awaited_once()
|
|
55
|
+
|
|
56
|
+
def test_process_setup_without_configuration_skips_warmup(self) -> None:
|
|
57
|
+
with patch.dict("os.environ", {}, clear=True):
|
|
58
|
+
agent_module.server.setup_fnc(SimpleNamespace())
|
|
59
|
+
|
|
60
|
+
self.sdk_prewarm.assert_not_awaited()
|
|
61
|
+
|
|
62
|
+
|
|
14
63
|
class AgentStartupTests(unittest.IsolatedAsyncioTestCase):
|
|
15
64
|
def setUp(self) -> None:
|
|
16
65
|
self.events: list[str] = []
|
|
@@ -777,7 +777,7 @@ wheels = [
|
|
|
777
777
|
|
|
778
778
|
[[package]]
|
|
779
779
|
name = "livekit"
|
|
780
|
-
version = "1.1.
|
|
780
|
+
version = "1.1.18"
|
|
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/43/06/ed2cda99ce0c7f10f6599588b296d2bde08ec1235a97416e9986629ce131/livekit-1.1.18.tar.gz", hash = "sha256:1097b8613fa4625e3fb0bd4fe5b09a3b04b39151c08b78498831dfc57235d1d1", size = 386573, upload-time = "2026-09-08T01:50:55.05Z" }
|
|
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/d3/b1/be04d760136480aa2d27f8247adc6d0a1e25395b146f04267fb8e716fe6a/livekit-1.1.18-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:8337e956e9816814572c964e7553d66e4845bc3299cb5aeab8a0d671e293ed32", size = 10471856, upload-time = "2026-09-08T01:50:41.85Z" },
|
|
792
|
+
{ url = "https://files.pythonhosted.org/packages/d3/60/a0bf23774eecfc012b60bae84f329537053a0e0952d6f43dc6154d01ac5b/livekit-1.1.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8557d6438da4b8968263b44920e7ab606a9ea34bc49fb8fd89054eb3e5cc162d", size = 9292804, upload-time = "2026-09-08T01:50:44.968Z" },
|
|
793
|
+
{ url = "https://files.pythonhosted.org/packages/f1/68/4b5e996660185f2db937a356c9e72981eab42c846f24ba992b997fa9f973/livekit-1.1.18-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:e9305aa097fe75f533db3205ab15868730e467130ffdda7d4adc3840f30b282a", size = 10584633, upload-time = "2026-09-08T01:50:47.735Z" },
|
|
794
|
+
{ url = "https://files.pythonhosted.org/packages/e0/5e/a0220ddf5e53bb3ee4f4969e9ca5e3a3e9567c584b66cd71355a45c069a8/livekit-1.1.18-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:dc2461b668ffa66ca504d05c88af7ea640372f53672ae367145412e374d6aff0", size = 11809468, upload-time = "2026-09-08T01:50:50.332Z" },
|
|
795
|
+
{ url = "https://files.pythonhosted.org/packages/f6/47/22455e01c76b271f7d9399546c2becabe4bf0f58a43e79859bb0ca4fc426/livekit-1.1.18-py3-none-win_amd64.whl", hash = "sha256:a61d4fd39392e7d28a7dbbe3b68be7b600115ed32501f5b016579846de945913", size = 10972019, upload-time = "2026-09-08T01:50:52.912Z" },
|
|
796
796
|
]
|
|
797
797
|
|
|
798
798
|
[[package]]
|
|
799
799
|
name = "livekit-agents"
|
|
800
|
-
version = "1.8.
|
|
800
|
+
version = "1.8.1"
|
|
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/5c/f1/cc1fcbc24da6f90cf38809c5ceafff1a1d1c1527a32431ce9b00e64deb95/livekit_agents-1.8.1.tar.gz", hash = "sha256:9319b4a7cf3891db4c1de9edd98fad4918919beadb2ceff5b3fbd34ae67384b5", size = 2712687, upload-time = "2026-09-10T18:59:30.729Z" }
|
|
837
837
|
wheels = [
|
|
838
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
838
|
+
{ url = "https://files.pythonhosted.org/packages/0e/2c/29419a913c57b863eba93cbb41df2f3e58b57c3d8f790c6f97be81203ef7/livekit_agents-1.8.1-py3-none-any.whl", hash = "sha256:3e9e4e732ecebcf0512d5eec25621a365c3572289d1f136396d8a1c5ea78e2ac", size = 2832498, upload-time = "2026-09-10T18:59:28.67Z" },
|
|
839
839
|
]
|
|
840
840
|
|
|
841
841
|
[package.optional-dependencies]
|
|
@@ -935,15 +935,15 @@ wheels = [
|
|
|
935
935
|
|
|
936
936
|
[[package]]
|
|
937
937
|
name = "livekit-plugins-spatius"
|
|
938
|
-
version = "1.8.
|
|
938
|
+
version = "1.8.1"
|
|
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/3f/a7/96d690fa9177fb29ae162fdd3957eee2c87ff3c0b9c4e85956532f94a779/livekit_plugins_spatius-1.8.1.tar.gz", hash = "sha256:d71b74eea79a58861c5893d67d4196d4a3deb2836c23cf4316759aae368b4b9d", size = 10093, upload-time = "2026-09-10T19:01:10.334Z" }
|
|
945
945
|
wheels = [
|
|
946
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
946
|
+
{ url = "https://files.pythonhosted.org/packages/f7/93/b562e8e3ff22b19f69575302b41649bcde379497b73b2fc003f76553a8c4/livekit_plugins_spatius-1.8.1-py3-none-any.whl", hash = "sha256:234d2d0817e43a0aa736c2bfc698b364f6ad64c2ba55c469bab35169099f928e", size = 11330, upload-time = "2026-09-10T19:01:09.016Z" },
|
|
947
947
|
]
|
|
948
948
|
|
|
949
949
|
[[package]]
|
|
@@ -1891,7 +1891,7 @@ dev = [
|
|
|
1891
1891
|
|
|
1892
1892
|
[package.metadata]
|
|
1893
1893
|
requires-dist = [
|
|
1894
|
-
{ name = "livekit-agents", extras = ["spatius"], specifier = "~=1.8.
|
|
1894
|
+
{ name = "livekit-agents", extras = ["spatius"], specifier = "~=1.8.1" },
|
|
1895
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" },
|