426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
341 lines
12 KiB
Python
341 lines
12 KiB
Python
"""Tests for `scripts/lib/local_path_source.py` and the nightly-export bridge.
|
|
|
|
Exercises the `source: { type: local_path }` resolver, the
|
|
`stage_local_path_source` symlink step, and the `eliza_native_passthrough`
|
|
adapter end-to-end against a synthetic export tree.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
sys.path.insert(0, str(HERE))
|
|
|
|
from lib.adapters import REGISTRY # noqa: E402
|
|
from lib.expected_response import make_expected_response_encoder # noqa: E402
|
|
from lib.local_path_source import LocalPathSource, expand_env # noqa: E402
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# expand_env
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_expand_env_uses_default_when_var_unset(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.delenv("ELIZA_TEST_ROOT", raising=False)
|
|
assert expand_env("${ELIZA_TEST_ROOT:-/tmp/default}") == "/tmp/default"
|
|
|
|
|
|
def test_expand_env_uses_env_when_set(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setenv("ELIZA_TEST_ROOT", "/var/data/eliza")
|
|
assert (
|
|
expand_env("${ELIZA_TEST_ROOT:-/tmp/default}/training/datasets")
|
|
== "/var/data/eliza/training/datasets"
|
|
)
|
|
|
|
|
|
def test_expand_env_handles_no_var() -> None:
|
|
assert expand_env("/already/absolute/path") == "/already/absolute/path"
|
|
|
|
|
|
def test_expand_env_expands_tilde() -> None:
|
|
expanded = expand_env("~/example")
|
|
assert expanded.startswith(os.path.expanduser("~"))
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# LocalPathSource.from_entry
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_from_entry_returns_none_when_not_local_path() -> None:
|
|
assert LocalPathSource.from_entry({"slug": "x", "repo_id": "foo/bar"}) is None
|
|
assert (
|
|
LocalPathSource.from_entry(
|
|
{"slug": "x", "source": {"type": "hf_repo", "repo_id": "foo/bar"}}
|
|
)
|
|
is None
|
|
)
|
|
|
|
|
|
def test_from_entry_requires_root_and_glob() -> None:
|
|
with pytest.raises(ValueError):
|
|
LocalPathSource.from_entry({"slug": "x", "source": {"type": "local_path"}})
|
|
with pytest.raises(ValueError):
|
|
LocalPathSource.from_entry(
|
|
{"slug": "x", "source": {"type": "local_path", "root": "/tmp"}}
|
|
)
|
|
|
|
|
|
def test_from_entry_parses_full_block(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setenv("ELIZA_TEST_ROOT", "/tmp/eliza-state")
|
|
parsed = LocalPathSource.from_entry(
|
|
{
|
|
"slug": "eliza-nightly-action-planner",
|
|
"source": {
|
|
"type": "local_path",
|
|
"root": "${ELIZA_TEST_ROOT:-~/.eliza}/training/datasets",
|
|
"glob": "*/action_planner_trajectories.jsonl",
|
|
"task": "action_planner",
|
|
},
|
|
}
|
|
)
|
|
assert parsed is not None
|
|
assert parsed.root == Path("/tmp/eliza-state/training/datasets")
|
|
assert parsed.glob == "*/action_planner_trajectories.jsonl"
|
|
assert parsed.task == "action_planner"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# resolve_files
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_resolve_files_returns_empty_when_root_missing(tmp_path: Path) -> None:
|
|
parsed = LocalPathSource(
|
|
root=tmp_path / "does" / "not" / "exist",
|
|
glob="*/file.jsonl",
|
|
task=None,
|
|
)
|
|
assert parsed.resolve_files() == []
|
|
|
|
|
|
def test_resolve_files_globs_dated_subdirs(tmp_path: Path) -> None:
|
|
(tmp_path / "2026-05-11").mkdir()
|
|
(tmp_path / "2026-05-12").mkdir()
|
|
(tmp_path / "2026-05-11" / "action_planner_trajectories.jsonl").write_text("")
|
|
(tmp_path / "2026-05-12" / "action_planner_trajectories.jsonl").write_text("")
|
|
(tmp_path / "2026-05-11" / "should_respond_trajectories.jsonl").write_text("")
|
|
|
|
parsed = LocalPathSource(
|
|
root=tmp_path,
|
|
glob="*/action_planner_trajectories.jsonl",
|
|
task="action_planner",
|
|
)
|
|
files = parsed.resolve_files()
|
|
assert len(files) == 2
|
|
assert all(p.name == "action_planner_trajectories.jsonl" for p in files)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# stage_local_path_source (download_datasets.py)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_stage_local_path_source_symlinks_files(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
import download_datasets
|
|
|
|
export_root = tmp_path / "export"
|
|
raw_root = tmp_path / "raw"
|
|
(export_root / "2026-05-11").mkdir(parents=True)
|
|
src = export_root / "2026-05-11" / "action_planner_trajectories.jsonl"
|
|
src.write_text("{}\n")
|
|
|
|
monkeypatch.setattr(download_datasets, "RAW_DIR", raw_root)
|
|
monkeypatch.setenv("ELIZA_TEST_ROOT", str(export_root))
|
|
|
|
entry = {
|
|
"slug": "eliza-nightly-action-planner",
|
|
"source": {
|
|
"type": "local_path",
|
|
"root": "${ELIZA_TEST_ROOT}",
|
|
"glob": "*/action_planner_trajectories.jsonl",
|
|
"task": "action_planner",
|
|
},
|
|
}
|
|
slug, status, _size = download_datasets.stage_local_path_source(entry)
|
|
assert (slug, status) == ("eliza-nightly-action-planner", "ok")
|
|
staged = raw_root / "eliza-nightly-action-planner" / "2026-05-11__action_planner_trajectories.jsonl"
|
|
assert staged.is_symlink()
|
|
assert staged.resolve() == src.resolve()
|
|
assert (raw_root / "eliza-nightly-action-planner" / ".done").is_file()
|
|
|
|
|
|
def test_stage_local_path_source_empty_export_is_noop(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
import download_datasets
|
|
|
|
raw_root = tmp_path / "raw"
|
|
empty_root = tmp_path / "does-not-exist"
|
|
monkeypatch.setattr(download_datasets, "RAW_DIR", raw_root)
|
|
|
|
entry = {
|
|
"slug": "eliza-nightly-action-planner",
|
|
"source": {
|
|
"type": "local_path",
|
|
"root": str(empty_root),
|
|
"glob": "*/action_planner_trajectories.jsonl",
|
|
},
|
|
}
|
|
slug, status, _size = download_datasets.stage_local_path_source(entry)
|
|
assert (slug, status) == ("eliza-nightly-action-planner", "ok")
|
|
assert (raw_root / "eliza-nightly-action-planner" / ".done").is_file()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# eliza_native_passthrough adapter (lib.adapters)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def _native_row(*, task_type: str = "action_planner") -> dict:
|
|
return {
|
|
"format": "eliza_native_v1",
|
|
"schemaVersion": 1,
|
|
"boundary": "vercel_ai_sdk.generateText",
|
|
"request": {
|
|
"messages": [
|
|
{"role": "system", "content": "you are eliza"},
|
|
{"role": "user", "content": "hello"},
|
|
],
|
|
"settings": {"temperature": 0.0, "topP": 1.0},
|
|
},
|
|
"response": {
|
|
"text": '{"thought":"reply","toolCalls":[]}',
|
|
"finishReason": "stop",
|
|
},
|
|
"metadata": {
|
|
"task_type": task_type,
|
|
"trajectory_id": "traj-1",
|
|
"call_id": "call-1",
|
|
"agent_id": "agent-7",
|
|
},
|
|
}
|
|
|
|
|
|
def test_eliza_native_passthrough_emits_valid_records() -> None:
|
|
adapter = REGISTRY["eliza_native_passthrough"]
|
|
encoder = make_expected_response_encoder("json")
|
|
try:
|
|
rows = [_native_row()]
|
|
out = list(
|
|
adapter(
|
|
rows,
|
|
slug="eliza-nightly-action-planner",
|
|
license="proprietary",
|
|
split="train",
|
|
encoder=encoder,
|
|
)
|
|
)
|
|
assert len(out) == 1
|
|
rec = out[0]
|
|
ok, _ = rec.is_valid()
|
|
assert ok, rec.to_dict()
|
|
md = rec.metadata
|
|
assert md["task_type"] == "action_planner"
|
|
assert md["source_dataset"] == "eliza-nightly-action-planner"
|
|
assert md["trajectory_id"] == "traj-1"
|
|
assert md["call_id"] == "call-1"
|
|
assert rec.currentMessage["content"] == "hello"
|
|
# System turns surface in metadata, not as a memory entry.
|
|
assert "you are eliza" in md["system_prompt"]
|
|
assert rec.expectedResponse.startswith("{")
|
|
finally:
|
|
encoder.close()
|
|
|
|
|
|
def test_eliza_native_passthrough_skips_malformed_rows() -> None:
|
|
adapter = REGISTRY["eliza_native_passthrough"]
|
|
encoder = make_expected_response_encoder("json")
|
|
try:
|
|
rows = [{"not": "a native row"}]
|
|
out = list(
|
|
adapter(
|
|
rows,
|
|
slug="x",
|
|
license="proprietary",
|
|
split="train",
|
|
encoder=encoder,
|
|
)
|
|
)
|
|
# Malformed rows emit an ElizaRecord that fails is_valid() — the
|
|
# normalize.py harness routes those to errors.jsonl. The shape
|
|
# under test is just that no exception is raised and the failure
|
|
# is observable via is_valid().
|
|
assert len(out) == 1
|
|
ok, _ = out[0].is_valid()
|
|
assert not ok
|
|
finally:
|
|
encoder.close()
|
|
|
|
|
|
def test_eliza_native_passthrough_carries_task_from_metadata() -> None:
|
|
adapter = REGISTRY["eliza_native_passthrough"]
|
|
encoder = make_expected_response_encoder("json")
|
|
try:
|
|
rows = [_native_row(task_type="should_respond")]
|
|
out = list(
|
|
adapter(
|
|
rows,
|
|
slug="eliza-nightly-should-respond",
|
|
license="proprietary",
|
|
split="train",
|
|
encoder=encoder,
|
|
)
|
|
)
|
|
assert out[0].metadata["task_type"] == "should_respond"
|
|
finally:
|
|
encoder.close()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Manual end-to-end: drop a JSONL, stage, normalize.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_end_to_end_stage_then_normalize(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
import download_datasets
|
|
import normalize
|
|
|
|
export_root = tmp_path / "export"
|
|
raw_root = tmp_path / "raw"
|
|
normalized_root = tmp_path / "normalized"
|
|
(export_root / "2026-05-11").mkdir(parents=True)
|
|
src = export_root / "2026-05-11" / "action_planner_trajectories.jsonl"
|
|
src.write_text(json.dumps(_native_row()) + "\n")
|
|
|
|
monkeypatch.setattr(download_datasets, "RAW_DIR", raw_root)
|
|
monkeypatch.setattr(normalize, "RAW_DIR", raw_root)
|
|
monkeypatch.setattr(normalize, "OUT_DIR", normalized_root)
|
|
monkeypatch.setenv("ELIZA_TEST_ROOT", str(export_root))
|
|
|
|
entry = {
|
|
"slug": "eliza-nightly-action-planner",
|
|
"source": {
|
|
"type": "local_path",
|
|
"root": "${ELIZA_TEST_ROOT}",
|
|
"glob": "*/action_planner_trajectories.jsonl",
|
|
"task": "action_planner",
|
|
},
|
|
"normalizer": "eliza_native_passthrough",
|
|
"license": "proprietary",
|
|
"weight": 1.0,
|
|
}
|
|
download_datasets.stage_local_path_source(entry)
|
|
|
|
encoder = make_expected_response_encoder("json")
|
|
try:
|
|
n_in, n_out, n_err = normalize.normalize_dataset(
|
|
entry, max_records=None, encoder=encoder
|
|
)
|
|
finally:
|
|
encoder.close()
|
|
assert (n_in, n_out, n_err) == (1, 1, 0)
|
|
out_jsonl = normalized_root / "eliza-nightly-action-planner.jsonl"
|
|
assert out_jsonl.is_file()
|
|
lines = out_jsonl.read_text().splitlines()
|
|
assert len(lines) == 1
|
|
rec = json.loads(lines[0])
|
|
assert rec["metadata"]["task_type"] == "action_planner"
|
|
assert rec["metadata"]["source_dataset"] == "eliza-nightly-action-planner"
|