Implement Stage 1: command generator, CLI, TTS and LLM clients
- lexicon.py: exact forms from docs/LEXICON.md (Polish diacritics preserved)
- generator.py: Clause/Command dataclasses, render(), random_command(level 1-3)
- llm.py: OpenAI-compatible client via urllib, JSON-only contract, fallback to random
- tts.py: Piper via subprocess, defensive (prints [TTS off: reason] on any failure)
- cli.py: argparse interface per SPEC §9
- tests/test_generator.py: 23 tests covering all genders, locations, level-3 joining,
capitalisation; all pass
DoD verified: pytest 23/23, python -m ipin_vr --level 3 --count 6 --no-audio OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:03:50 +02:00
|
|
|
import argparse
|
|
|
|
|
import random
|
Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4)
Python (ipin_vr/export.py):
- generate_bank(): levels 1–2 enumerated exhaustively (120/720 combos),
level 3 random with dedup; all deduplicated per-level
- run_export(): CLI --per-level / --out / --seed flags per ONDEVICE §4.1
- cli.py routes "export" subcommand before session args (backward-compat)
- 14 new tests: format, dedup for all 3 levels, space caps (L1=120, L2=720),
seed determinism, file output
Unity scaffold (ondevice/Scripts/):
- CommandBank.cs: loads commands.json from StreamingAssets (WebRequest on Android)
- TtsManager.cs: sherpa-onnx integration with [SHERPA] stubs, StreamingAssets→
persistentDataPath copy, defensive Speak() with onDone callback
- SessionController.cs: passthrough flow §6, level switching, busy guard on Next
- ondevice/README.md: full manual Editor steps §5 (Unity setup, Meta XR SDK,
sherpa-onnx install, scene wiring, font, build, metrics)
pytest: 37/37 passed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:11:53 +02:00
|
|
|
import sys
|
Implement Stage 1: command generator, CLI, TTS and LLM clients
- lexicon.py: exact forms from docs/LEXICON.md (Polish diacritics preserved)
- generator.py: Clause/Command dataclasses, render(), random_command(level 1-3)
- llm.py: OpenAI-compatible client via urllib, JSON-only contract, fallback to random
- tts.py: Piper via subprocess, defensive (prints [TTS off: reason] on any failure)
- cli.py: argparse interface per SPEC §9
- tests/test_generator.py: 23 tests covering all genders, locations, level-3 joining,
capitalisation; all pass
DoD verified: pytest 23/23, python -m ipin_vr --level 3 --count 6 --no-audio OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:03:50 +02:00
|
|
|
import time
|
|
|
|
|
|
Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4)
Python (ipin_vr/export.py):
- generate_bank(): levels 1–2 enumerated exhaustively (120/720 combos),
level 3 random with dedup; all deduplicated per-level
- run_export(): CLI --per-level / --out / --seed flags per ONDEVICE §4.1
- cli.py routes "export" subcommand before session args (backward-compat)
- 14 new tests: format, dedup for all 3 levels, space caps (L1=120, L2=720),
seed determinism, file output
Unity scaffold (ondevice/Scripts/):
- CommandBank.cs: loads commands.json from StreamingAssets (WebRequest on Android)
- TtsManager.cs: sherpa-onnx integration with [SHERPA] stubs, StreamingAssets→
persistentDataPath copy, defensive Speak() with onDone callback
- SessionController.cs: passthrough flow §6, level switching, busy guard on Next
- ondevice/README.md: full manual Editor steps §5 (Unity setup, Meta XR SDK,
sherpa-onnx install, scene wiring, font, build, metrics)
pytest: 37/37 passed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:11:53 +02:00
|
|
|
from .export import run_export
|
Implement Stage 1: command generator, CLI, TTS and LLM clients
- lexicon.py: exact forms from docs/LEXICON.md (Polish diacritics preserved)
- generator.py: Clause/Command dataclasses, render(), random_command(level 1-3)
- llm.py: OpenAI-compatible client via urllib, JSON-only contract, fallback to random
- tts.py: Piper via subprocess, defensive (prints [TTS off: reason] on any failure)
- cli.py: argparse interface per SPEC §9
- tests/test_generator.py: 23 tests covering all genders, locations, level-3 joining,
capitalisation; all pass
DoD verified: pytest 23/23, python -m ipin_vr --level 3 --count 6 --no-audio OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:03:50 +02:00
|
|
|
from .generator import random_command, render
|
|
|
|
|
from .llm import llm_command
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4)
Python (ipin_vr/export.py):
- generate_bank(): levels 1–2 enumerated exhaustively (120/720 combos),
level 3 random with dedup; all deduplicated per-level
- run_export(): CLI --per-level / --out / --seed flags per ONDEVICE §4.1
- cli.py routes "export" subcommand before session args (backward-compat)
- 14 new tests: format, dedup for all 3 levels, space caps (L1=120, L2=720),
seed determinism, file output
Unity scaffold (ondevice/Scripts/):
- CommandBank.cs: loads commands.json from StreamingAssets (WebRequest on Android)
- TtsManager.cs: sherpa-onnx integration with [SHERPA] stubs, StreamingAssets→
persistentDataPath copy, defensive Speak() with onDone callback
- SessionController.cs: passthrough flow §6, level switching, busy guard on Next
- ondevice/README.md: full manual Editor steps §5 (Unity setup, Meta XR SDK,
sherpa-onnx install, scene wiring, font, build, metrics)
pytest: 37/37 passed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:11:53 +02:00
|
|
|
raw = sys.argv[1:]
|
|
|
|
|
if raw and raw[0] == "export":
|
|
|
|
|
run_export(raw[1:])
|
|
|
|
|
return
|
|
|
|
|
_run_session()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _run_session() -> None:
|
Implement Stage 1: command generator, CLI, TTS and LLM clients
- lexicon.py: exact forms from docs/LEXICON.md (Polish diacritics preserved)
- generator.py: Clause/Command dataclasses, render(), random_command(level 1-3)
- llm.py: OpenAI-compatible client via urllib, JSON-only contract, fallback to random
- tts.py: Piper via subprocess, defensive (prints [TTS off: reason] on any failure)
- cli.py: argparse interface per SPEC §9
- tests/test_generator.py: 23 tests covering all genders, locations, level-3 joining,
capitalisation; all pass
DoD verified: pytest 23/23, python -m ipin_vr --level 3 --count 6 --no-audio OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:03:50 +02:00
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
|
description="ipin-vr: generator poleceń do terapii afazji"
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument("--level", type=int, choices=[1, 2, 3], default=1,
|
|
|
|
|
metavar="{1,2,3}", help="poziom trudności (domyślnie: 1)")
|
|
|
|
|
parser.add_argument("--count", type=int, default=5, metavar="N",
|
|
|
|
|
help="liczba poleceń (domyślnie: 5)")
|
|
|
|
|
parser.add_argument("--delay", type=float, default=4.0, metavar="S",
|
|
|
|
|
help="pauza między poleceniami w sekundach (domyślnie: 4.0)")
|
|
|
|
|
parser.add_argument("--voice", metavar="PATH",
|
|
|
|
|
help="ścieżka do modelu Piper .onnx")
|
|
|
|
|
parser.add_argument("--no-audio", action="store_true",
|
|
|
|
|
help="wyłącza TTS")
|
|
|
|
|
parser.add_argument("--llm", action="store_true",
|
|
|
|
|
help="użyj LLM do wyboru poleceń")
|
|
|
|
|
parser.add_argument("--llm-endpoint",
|
|
|
|
|
default="http://localhost:8080/v1/chat/completions",
|
|
|
|
|
metavar="URL", help="endpoint llama.cpp")
|
|
|
|
|
parser.add_argument("--llm-model", default="local", metavar="NAME",
|
|
|
|
|
help="nazwa modelu")
|
|
|
|
|
parser.add_argument("--seed", type=int, metavar="N",
|
|
|
|
|
help="deterministyczny generator losowy")
|
Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4)
Python (ipin_vr/export.py):
- generate_bank(): levels 1–2 enumerated exhaustively (120/720 combos),
level 3 random with dedup; all deduplicated per-level
- run_export(): CLI --per-level / --out / --seed flags per ONDEVICE §4.1
- cli.py routes "export" subcommand before session args (backward-compat)
- 14 new tests: format, dedup for all 3 levels, space caps (L1=120, L2=720),
seed determinism, file output
Unity scaffold (ondevice/Scripts/):
- CommandBank.cs: loads commands.json from StreamingAssets (WebRequest on Android)
- TtsManager.cs: sherpa-onnx integration with [SHERPA] stubs, StreamingAssets→
persistentDataPath copy, defensive Speak() with onDone callback
- SessionController.cs: passthrough flow §6, level switching, busy guard on Next
- ondevice/README.md: full manual Editor steps §5 (Unity setup, Meta XR SDK,
sherpa-onnx install, scene wiring, font, build, metrics)
pytest: 37/37 passed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:11:53 +02:00
|
|
|
args = parser.parse_args(sys.argv[1:])
|
Implement Stage 1: command generator, CLI, TTS and LLM clients
- lexicon.py: exact forms from docs/LEXICON.md (Polish diacritics preserved)
- generator.py: Clause/Command dataclasses, render(), random_command(level 1-3)
- llm.py: OpenAI-compatible client via urllib, JSON-only contract, fallback to random
- tts.py: Piper via subprocess, defensive (prints [TTS off: reason] on any failure)
- cli.py: argparse interface per SPEC §9
- tests/test_generator.py: 23 tests covering all genders, locations, level-3 joining,
capitalisation; all pass
DoD verified: pytest 23/23, python -m ipin_vr --level 3 --count 6 --no-audio OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:03:50 +02:00
|
|
|
|
|
|
|
|
if args.seed is not None:
|
|
|
|
|
random.seed(args.seed)
|
|
|
|
|
|
|
|
|
|
use_audio = (not args.no_audio) and (args.voice is not None)
|
|
|
|
|
|
|
|
|
|
for i in range(1, args.count + 1):
|
|
|
|
|
if args.llm:
|
|
|
|
|
cmd = llm_command(args.level, args.llm_endpoint, args.llm_model)
|
|
|
|
|
else:
|
|
|
|
|
cmd = random_command(args.level)
|
|
|
|
|
|
|
|
|
|
text = render(cmd)
|
|
|
|
|
print(f"{i}. {text}")
|
|
|
|
|
|
|
|
|
|
if use_audio:
|
|
|
|
|
from .tts import speak
|
|
|
|
|
speak(text, args.voice)
|
|
|
|
|
|
|
|
|
|
if i < args.count:
|
|
|
|
|
time.sleep(args.delay)
|