textflowkit 0.1.10__tar.gz → 0.1.12__tar.gz
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.
- {textflowkit-0.1.10 → textflowkit-0.1.12}/CHANGELOG.md +95 -1
- {textflowkit-0.1.10 → textflowkit-0.1.12}/CONTRIBUTING.md +7 -1
- {textflowkit-0.1.10 → textflowkit-0.1.12}/PKG-INFO +184 -25
- {textflowkit-0.1.10 → textflowkit-0.1.12}/README.md +177 -24
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/adapters.md +111 -3
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/architecture.md +89 -1
- textflowkit-0.1.12/docs/assets/live-streaming-flow.svg +50 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/index.html +73 -8
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/install.md +74 -2
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/release-checklist.md +31 -1
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/roadmap.md +25 -1
- textflowkit-0.1.12/docs/streaming.md +514 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/user-manual.md +183 -8
- textflowkit-0.1.12/packaging/windows/README.md +71 -0
- textflowkit-0.1.12/packaging/windows/THIRD-PARTY-NOTICES.txt +34 -0
- textflowkit-0.1.12/packaging/windows/assets.lock.json +56 -0
- textflowkit-0.1.12/packaging/windows/launch.py +140 -0
- textflowkit-0.1.12/packaging/windows/source-materials.json +20 -0
- textflowkit-0.1.12/packaging/windows/textflowkit.iss +77 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/pyproject.toml +9 -2
- textflowkit-0.1.12/scripts/build_windows_installer.py +160 -0
- textflowkit-0.1.12/scripts/prepare_windows_payload.py +992 -0
- textflowkit-0.1.12/src/textflowkit/__init__.py +41 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/adapters/http_server.py +258 -2
- textflowkit-0.1.12/src/textflowkit/adapters/streaming_ws.py +1276 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/service.py +3 -0
- textflowkit-0.1.12/src/textflowkit/core/stream_worker.py +227 -0
- textflowkit-0.1.12/src/textflowkit/core/streaming.py +1198 -0
- textflowkit-0.1.12/src/textflowkit/core/streaming_assets.py +542 -0
- textflowkit-0.1.12/src/textflowkit/core/streaming_events.py +330 -0
- textflowkit-0.1.12/src/textflowkit/core/streaming_process.py +521 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/whistle.py +3 -0
- textflowkit-0.1.12/src/textflowkit/core/windows_process.py +24 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/sources/acquire.py +4 -1
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/app.py +235 -2
- textflowkit-0.1.12/src/textflowkit/ui/cleanup.py +306 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/launcher.py +28 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/static/app.css +7 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/static/app.js +6 -0
- textflowkit-0.1.12/src/textflowkit/ui/static/cleanup.js +151 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/static/index.html +23 -0
- textflowkit-0.1.12/src/textflowkit/ui/static/streaming-capture-worklet.js +156 -0
- textflowkit-0.1.12/src/textflowkit/ui/static/streaming-example.html +699 -0
- textflowkit-0.1.12/tests/test_streaming_assets.py +320 -0
- textflowkit-0.1.12/tests/test_streaming_browser_lifecycle.py +1347 -0
- textflowkit-0.1.12/tests/test_streaming_core.py +654 -0
- textflowkit-0.1.12/tests/test_streaming_example.py +371 -0
- textflowkit-0.1.12/tests/test_streaming_repairs.py +950 -0
- textflowkit-0.1.12/tests/test_streaming_transport.py +837 -0
- textflowkit-0.1.12/tests/test_streaming_u5_repairs.py +917 -0
- textflowkit-0.1.12/tests/test_streaming_ui_integration.py +190 -0
- textflowkit-0.1.12/tests/test_ui_cleanup.py +452 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_packaging.py +18 -4
- textflowkit-0.1.12/tests/test_windows_installer.py +512 -0
- textflowkit-0.1.12/tests/test_windows_payload.py +413 -0
- textflowkit-0.1.10/src/textflowkit/__init__.py +0 -8
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.dockerignore +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.env.example +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.gitattributes +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.github/dependabot.yml +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.github/workflows/ci.yml +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.github/workflows/publish-pypi.yml +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.gitignore +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/.pre-commit-config.yaml +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/Dockerfile +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/LEGAL.md +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/LICENSE +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/SECURITY.md +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/compose.yaml +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/.nojekyll +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/404.html +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/assets/architecture-overview.svg +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/assets/local-ui-flow.svg +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/assets/whistle-resume.svg +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/site-deployment.md +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/docs/sources.md +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/fetch_published_fonts.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/smoke_installed_wheel.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/smoke_live_youtube.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/verify_readme_release.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/verify_release_ci.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/verify_release_versions.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/scripts/write_release_manifest.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/adapters/__init__.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/adapters/mcp_server.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/assets/README.md +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/assets/selftest-speech.wav +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/cli.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/__init__.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/batch.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/bind.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/cancel.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/checkpoint.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/diarize.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/engine.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/executor.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/jobs.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/model.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/paths.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/pipeline.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/retrieval.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/runner.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/sqlite_store.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/startup.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/submission.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/timeutil.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/translate.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/core/whistle_assets.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/__init__.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/_cue_layout.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/_cue_text.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/_rename_excl.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/_rename_noreplace.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/docx.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/markdown.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/pdf.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/srt.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/txt.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/render/vtt.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/sources/__init__.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/sources/detect.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/sources/scratch.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/__init__.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/capabilities.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/ownership.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/paths.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/security.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/src/textflowkit/ui/uploads.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/__init__.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/ollama_stub.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_acquire.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_adapters.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_admission_ownership.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_atomic_resume.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_atomic_resume_aba.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_batch.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_batch_item_boundary.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_batch_resume_shared.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_bind.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cancellation_finalization.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_checkpoint.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_checkpoint_single_copy.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cli.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cli_batch_feedback.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cli_owning_recovery.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cli_resume_batch.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cli_stage_feedback.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cli_stdout_format.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_confined_decoder_boundary.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_confined_indirect_media.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_confined_resume_boundary.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_container_example.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_cue_layout.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_diarize.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_diarize_example_flags.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_diarize_token_docs.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_docx_publication_identity.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_done_output_integrity.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_empty_formats_resume.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_engine_adapters.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_engine_cache.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_engine_faster.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_engine_quiet.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_executor.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_executor_store_failure.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_export.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_export_file_mode.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_export_preflight.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_faster_whisper_docs.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_fetch_published_fonts.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_font_notices.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_http_host_boundary.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_http_trusted_proxy.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_job_progress.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_jobs.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_landing_commands.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_landing_page.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_legal_summary.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_linux_no_hardlink.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_live_smoke_script.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_macos_no_hardlink.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_mcp_batch_cookie_docs.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_mcp_http_boundary.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_mcp_protocol_cleanliness.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_mcp_terminal_guidance.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_mcp_tool_descriptions.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_mcp_work_root.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_model.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_partial_output_resume.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_partial_pdf_resume.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_paths.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_pipeline_integrity.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_pipeline_resume_setup.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_production_browser_cookies.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_publish_ci_gate.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_publish_fonts_wiring.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_publish_manifest_wiring.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_publish_workflow_gate.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_readme_layout.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_readme_release_guard.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_release_boundaries.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_release_manifest.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_release_surfaces.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_render.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_retrieval.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_sdist_allowlist.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_service_profile.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_site_not_found.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_sources.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_stage_reuse_resume.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_startup_recovery.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_stdio_protocol.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_submission.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_submission_validation.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_translate.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_translate_completeness.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_assets_and_capabilities.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_consoleless_logging.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_existing_routes_unchanged.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_launcher.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_ownership_and_shutdown.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_real_serve.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_security.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_submission_and_download.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_ui_uploads.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_verify_release_versions.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_whistle_assets.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_whistle_defaults.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_whistle_engine.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_whistle_job_resume.py +0 -0
- {textflowkit-0.1.10 → textflowkit-0.1.12}/tests/test_windows_no_hardlink.py +0 -0
|
@@ -1,5 +1,99 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.1.12 — 2026-10-17
|
|
4
|
+
|
|
5
|
+
Core: 0.1.12; unchanged optional fonts: 0.1.6. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available.
|
|
6
|
+
|
|
7
|
+
### Optional local UI proofreading (v0.1.12)
|
|
8
|
+
|
|
9
|
+
- Add explicit post-transcription local Ollama proofreading with an installed-tag
|
|
10
|
+
picker; prefer `qwen3.5:9b` only when installed (size/performance fit unverified),
|
|
11
|
+
otherwise require selection.
|
|
12
|
+
No model downloads, cloud tags, paid provider, telemetry or new package dependency.
|
|
13
|
+
- Preserve original jobs and exports; persist a separate original-hash-bound AI
|
|
14
|
+
variant with provider/model/time provenance, source segment IDs/timestamps, no
|
|
15
|
+
inherited word alignment, comparison/original-only views and corrected TXT/copy.
|
|
16
|
+
- Bound background work and validate complete JSON/segment coverage atomically.
|
|
17
|
+
One cleanup at a time; fail without partial output. Normal shutdown drains work;
|
|
18
|
+
interrupted leases expire. AI corrections require human review.
|
|
19
|
+
|
|
20
|
+
- Validation history: the first cold full-UI attempt ended in a generic error; a
|
|
21
|
+
later hot 39-segment run returned zero edits despite clear spelling errors.
|
|
22
|
+
Final cold run (model explicitly unloaded first) completed all 39 segments in
|
|
23
|
+
three chunks with four changed segments at 2026-10-16 17:39:52 UTC. The original
|
|
24
|
+
SQLite JSON/source and IDs/timestamps matched; visible side-by-side review and
|
|
25
|
+
corrected TXT save were verified, with the saved file hash matching the variant.
|
|
26
|
+
This proves workflow completion for one run, not accuracy; “fundamental” and
|
|
27
|
+
“victims” were plausible guesses not verified against audio. Review against audio.
|
|
28
|
+
|
|
29
|
+
### Native Windows installer
|
|
30
|
+
|
|
31
|
+
- Package the existing local browser UI in a native per-user installer for core
|
|
32
|
+
v0.1.12. Built and tested locally; public EXE publication remains gated on
|
|
33
|
+
corresponding-source compliance review. No public installer link is available.
|
|
34
|
+
- Bundle: private embeddable CPython, the UI and HTTP, export, and
|
|
35
|
+
streaming dependencies, the pinned Whistle model and runtime, and ffmpeg,
|
|
36
|
+
ffprobe, and Node. The installer is designed to need no separate Python, WSL,
|
|
37
|
+
or Docker installation.
|
|
38
|
+
- Prebundled Whistle assets and media binaries mean local file jobs need no
|
|
39
|
+
first-use asset download. URL media still needs network access. The default
|
|
40
|
+
Whistle engine supports only these seven advertised languages: `en`, `de`,
|
|
41
|
+
`fr`, `es`, `it`, `nl`, and `pl`.
|
|
42
|
+
- Per-user setup with a Start Menu entry and optional desktop shortcut; launch
|
|
43
|
+
starts the loopback server and opens the existing UI in the browser. It normally
|
|
44
|
+
needs no administrator rights, changes no global `PATH`, and has no automatic
|
|
45
|
+
updates.
|
|
46
|
+
- Keep UI data outside the app install directory and preserve it on upgrade and
|
|
47
|
+
uninstall. Stop server and wait before upgrade or uninstall; the candidate will
|
|
48
|
+
block while it is running rather than force-kill active jobs. Stop server drains
|
|
49
|
+
jobs, so cancel one first if it should not finish.
|
|
50
|
+
- Do not bundle optional `openai-whisper` or diarization dependencies; their
|
|
51
|
+
documented optional paths remain available through the Python package. Bundled
|
|
52
|
+
streaming dependencies do not change the opt-in default; physical browser
|
|
53
|
+
microphone capture remains unverified.
|
|
54
|
+
- The installer bundle includes third-party license and notice files,
|
|
55
|
+
including FFmpeg LGPL notices and corresponding-source information. Verify
|
|
56
|
+
exact notices and source-distribution details against final binaries before
|
|
57
|
+
publication.
|
|
58
|
+
- The candidate is unsigned, so Windows may show a SmartScreen warning.
|
|
59
|
+
|
|
60
|
+
## v0.1.11 — 2026-10-06
|
|
61
|
+
|
|
62
|
+
Optional native live streaming supports **Windows x86_64 only**. Core version:
|
|
63
|
+
0.1.11; unchanged optional fonts: 0.1.6. Existing standalone Whistle defaults,
|
|
64
|
+
file/URL jobs, CLI, and MCP behavior are unchanged. The public site remains static
|
|
65
|
+
documentation and serves no streams. Local source validation does not establish
|
|
66
|
+
published-package verification or cross-platform live support.
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- **Public `StreamingSession` API.** Bounded PCM feed, typed incremental events,
|
|
72
|
+
flush/finish, cancellation, canonical final `Transcript`, and context-manager
|
|
73
|
+
cleanup. One owned native child per session binds directly to the separately
|
|
74
|
+
pinned `libneedle3.dll`; no upstream Python SDK or telemetry module is loaded.
|
|
75
|
+
Live sessions are ephemeral, with no replay or durable resume.
|
|
76
|
+
- **Live microphone streaming (opt-in, loopback-only).** When
|
|
77
|
+
`TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
|
|
78
|
+
WebSocket and the local UI serves `/api/stream`, both transcribing audio as it
|
|
79
|
+
arrives. A runnable, self-hosted browser example is at `/streaming-example`
|
|
80
|
+
(and `/api/streaming-example` under the UI); its `AudioWorklet` resamples any
|
|
81
|
+
device rate to 16 kHz mono with continuous phase. Off by default: with the
|
|
82
|
+
switch unset the endpoint does not exist. The standalone `textflowkit` CLI is
|
|
83
|
+
unaffected — it does not open a microphone or a streaming socket. Requires the
|
|
84
|
+
new `streaming` extra (`pip install "textflowkit[streaming]"`), which adds the
|
|
85
|
+
`websockets` dependency. Auth is fail-closed: the UI accepts only its own origin
|
|
86
|
+
and capability, the standalone API requires the API token (even in developer
|
|
87
|
+
mode), and a separate origin may stream only if the operator lists it in
|
|
88
|
+
`TEXTFLOWKIT_STREAMING_ORIGINS` (a browser needs its own origin listed, including
|
|
89
|
+
the standalone example's). See [docs/streaming.md](docs/streaming.md).
|
|
90
|
+
**Bounded live runs verified on this machine's native engine** — 65 s and 300 s
|
|
91
|
+
through the product core on Windows x86_64. A separate assembled UI WebSocket
|
|
92
|
+
run fed prerecorded PCM at real time for 12 s. Browser lifecycle and resampling
|
|
93
|
+
checks used fake audio; **physical microphone capture was not verified**. Only
|
|
94
|
+
English was measured natively; the other six accepted languages and live
|
|
95
|
+
Linux/macOS were not exercised. No public remote streaming is provided.
|
|
96
|
+
|
|
3
97
|
## v0.1.10 — 2026-10-06
|
|
4
98
|
|
|
5
99
|
**The local browser interface ships.** The loopback-only browser workspace
|
|
@@ -51,7 +145,7 @@ security boundaries. A **native Windows** machine, in a real browser, proved the
|
|
|
51
145
|
workspace end to end (drop a file, submit, download, stop). That is one platform's
|
|
52
146
|
browser proof, **not** a live Linux or macOS UI run — those platforms are covered
|
|
53
147
|
by automated tests only, and cross-platform CI (Windows/Linux/macOS) is a separate
|
|
54
|
-
|
|
148
|
+
release gate. **No live optional-backend (translation or
|
|
55
149
|
diarization) run through the UI is claimed.** The engine and packaging changes of
|
|
56
150
|
v0.1.9 are unchanged by this release.
|
|
57
151
|
|
|
@@ -14,9 +14,15 @@ python -m venv .venv
|
|
|
14
14
|
# Windows: .venv\Scripts\activate
|
|
15
15
|
# POSIX: source .venv/bin/activate
|
|
16
16
|
pip install ./packages/textflowkit-fonts # local optional PDF font companion
|
|
17
|
-
pip install -e ".[dev,mcp,http,export]"
|
|
17
|
+
pip install -e ".[dev,mcp,http,streaming,export,whisper]"
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
The full suite needs both `streaming` (WebSocket transport) and `whisper`
|
|
21
|
+
(optional standalone engine) dependencies. Use a development environment; for
|
|
22
|
+
an existing AMD ROCm torch stack, follow [the install guide](docs/install.md)
|
|
23
|
+
to preserve that stack. Native live streaming supports Windows x86_64 only;
|
|
24
|
+
ordinary standalone platform support and defaults remain unchanged.
|
|
25
|
+
|
|
20
26
|
## Test and lint — the commands CI runs
|
|
21
27
|
|
|
22
28
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: textflowkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: Cross-platform media transcription toolkit: URL or file in, timestamped transcripts and subtitle files out.
|
|
5
5
|
Project-URL: Homepage, https://www.textflowkit.org/
|
|
6
6
|
Project-URL: Issues, https://github.com/scottconverse/textflowkit/issues
|
|
@@ -32,6 +32,7 @@ Requires-Dist: python-docx>=1.1; extra == 'all'
|
|
|
32
32
|
Requires-Dist: reportlab>=4.0; extra == 'all'
|
|
33
33
|
Requires-Dist: textflowkit-fonts<0.2,>=0.1.5; extra == 'all'
|
|
34
34
|
Requires-Dist: uvicorn>=0.30; extra == 'all'
|
|
35
|
+
Requires-Dist: websockets<16,>=15; extra == 'all'
|
|
35
36
|
Provides-Extra: dev
|
|
36
37
|
Requires-Dist: build>=1.2; extra == 'dev'
|
|
37
38
|
Requires-Dist: hatchling>=1.25; extra == 'dev'
|
|
@@ -53,6 +54,11 @@ Requires-Dist: pydantic>=2.7; extra == 'http'
|
|
|
53
54
|
Requires-Dist: uvicorn>=0.30; extra == 'http'
|
|
54
55
|
Provides-Extra: mcp
|
|
55
56
|
Requires-Dist: mcp>=2.0; extra == 'mcp'
|
|
57
|
+
Provides-Extra: streaming
|
|
58
|
+
Requires-Dist: fastapi>=0.115; extra == 'streaming'
|
|
59
|
+
Requires-Dist: pydantic>=2.7; extra == 'streaming'
|
|
60
|
+
Requires-Dist: uvicorn>=0.30; extra == 'streaming'
|
|
61
|
+
Requires-Dist: websockets<16,>=15; extra == 'streaming'
|
|
56
62
|
Provides-Extra: whisper
|
|
57
63
|
Requires-Dist: openai-whisper>=20240930; extra == 'whisper'
|
|
58
64
|
Description-Content-Type: text/markdown
|
|
@@ -67,7 +73,7 @@ Cross-platform media transcription toolkit. **One core, one CLI, thin adapters.*
|
|
|
67
73
|
[User manual](https://github.com/scottconverse/textflowkit/blob/main/docs/user-manual.md) ·
|
|
68
74
|
[Developer and integration manual](https://github.com/scottconverse/textflowkit/blob/main/docs/adapters.md)
|
|
69
75
|
|
|
70
|
-
**Current release: [v0.1.
|
|
76
|
+
**Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).**
|
|
71
77
|
|
|
72
78
|
The [static site deployment](https://github.com/scottconverse/textflowkit/blob/main/docs/site-deployment.md) is hosted on Cloudflare
|
|
73
79
|
Pages. GitHub remains the source and CI host; the website does not run the
|
|
@@ -128,7 +134,7 @@ DOCX and PDF are available through the optional `export` extra.
|
|
|
128
134
|
|
|
129
135
|
## Architecture
|
|
130
136
|
|
|
131
|
-
 sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/architecture-overview.svg)
|
|
132
138
|
|
|
133
139
|
The design principle is **one shared core, thin doors**. Everything of substance
|
|
134
140
|
lives in the core; the interfaces are thin — the local browser UI is a fifth door
|
|
@@ -150,6 +156,32 @@ means writing one source adapter, not another tool.
|
|
|
150
156
|
For the job lifecycle, process ownership, checkpoints, and output publication,
|
|
151
157
|
see [docs/architecture.md](https://github.com/scottconverse/textflowkit/blob/main/docs/architecture.md).
|
|
152
158
|
|
|
159
|
+
## Live microphone streaming (opt-in)
|
|
160
|
+
|
|
161
|
+
In v0.1.12, live streaming supports **Windows x86_64 only**. When
|
|
162
|
+
`TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
|
|
163
|
+
WebSocket and the local UI serves `/api/stream`, both transcribing a live microphone
|
|
164
|
+
as you speak. A **runnable, self-hosted browser example** ships at
|
|
165
|
+
`/streaming-example` (and `/api/streaming-example` under the UI): it captures with an
|
|
166
|
+
`AudioWorklet`, resamples any device rate to 16 kHz mono, and shows the transcript.
|
|
167
|
+
No CDN, no analytics, no external fetch. Requires the `streaming` extra:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
python -m pip install "textflowkit[streaming]==0.1.12"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
It is **off by default** — with the switch unset the endpoint does not exist — and
|
|
174
|
+
**loopback-only**: auth is fail-closed, so the UI accepts only its own origin and
|
|
175
|
+
capability, the standalone API requires `TEXTFLOWKIT_API_TOKEN` (even in developer
|
|
176
|
+
mode), and a separate origin — including the standalone browser example's own origin —
|
|
177
|
+
may stream only if listed in `TEXTFLOWKIT_STREAMING_ORIGINS`. The standalone
|
|
178
|
+
`textflowkit` CLI is unaffected: it does not open a microphone or a streaming socket.
|
|
179
|
+
**Bounded live runs are verified on the native engine here** — 65 s and 300 s
|
|
180
|
+
end-to-end on Windows x86_64; the transport and the browser resampler are covered by
|
|
181
|
+
tests, and a physical browser microphone has not yet been captured (the browser proof
|
|
182
|
+
drives the page against a fake audio device). See
|
|
183
|
+
[docs/streaming.md](https://github.com/scottconverse/textflowkit/blob/main/docs/streaming.md).
|
|
184
|
+
|
|
153
185
|
## Recognized sources
|
|
154
186
|
|
|
155
187
|
YouTube · TikTok · Facebook · Instagram · Vimeo · Twitch · Bilibili · Rumble ·
|
|
@@ -201,6 +233,38 @@ installs `textflowkit-fonts` for offline multilingual PDF rendering:
|
|
|
201
233
|
python -m pip install 'textflowkit[export]'
|
|
202
234
|
```
|
|
203
235
|
|
|
236
|
+
## Windows desktop installer (v0.1.12; public EXE pending)
|
|
237
|
+
|
|
238
|
+
An installer for the existing local browser workspace accompanies core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. The Python package remains supported for developers and integrations.
|
|
239
|
+
|
|
240
|
+
The candidate is designed to run without a separately installed Python, WSL, or
|
|
241
|
+
Docker. Its bundle includes a private embeddable CPython runtime, the
|
|
242
|
+
browser UI and HTTP, export, and streaming dependencies, the pinned Whistle model
|
|
243
|
+
and runtime, and ffmpeg, ffprobe, and Node. The setup installs per user,
|
|
244
|
+
creates a Start Menu shortcut, and offers an optional desktop shortcut. Opening
|
|
245
|
+
the shortcut will start the local server and open the existing browser UI at
|
|
246
|
+
localhost. It is designed to need no administrator rights in normal use, change
|
|
247
|
+
no global `PATH`, and avoid automatic updates.
|
|
248
|
+
|
|
249
|
+
The pinned Whistle assets and media binaries are prebundled, so local file jobs
|
|
250
|
+
need no first-use asset download. URL sources still need their normal network
|
|
251
|
+
access. The default Whistle engine supports only these seven advertised languages:
|
|
252
|
+
`en`, `de`, `fr`, `es`, `it`, `nl`, and `pl`. Optional `openai-whisper` and diarization dependencies are not
|
|
253
|
+
bundled; those features remain documented for the Python package when separately
|
|
254
|
+
installed and configured. Streaming dependencies are bundled, but live streaming
|
|
255
|
+
remains opt-in and physical browser microphone capture has not been verified.
|
|
256
|
+
|
|
257
|
+
The candidate is designed to keep UI data outside the application install
|
|
258
|
+
directory and preserve it on upgrades and uninstall. Stop the UI server with
|
|
259
|
+
**Stop server** and wait for it to exit before upgrading or uninstalling; the
|
|
260
|
+
installer will block while it is running rather than force-killing active jobs.
|
|
261
|
+
Cancel a job first if it should not drain to completion. The bundle also
|
|
262
|
+
includes third-party license and notice files, including FFmpeg's LGPL notices
|
|
263
|
+
and corresponding-source information. Check exact notices and source-distribution
|
|
264
|
+
details against the final bundled binaries before publication. The candidate is
|
|
265
|
+
unsigned, so Windows may show a SmartScreen warning. See the [installer candidate
|
|
266
|
+
notes](docs/install.md#windows-desktop-installer-v0112-public-exe-pending).
|
|
267
|
+
|
|
204
268
|
## Python API
|
|
205
269
|
|
|
206
270
|
The same pipeline used by the CLI and adapters is available to Python callers:
|
|
@@ -296,7 +360,7 @@ textflowkit export ./transcript.json --format vtt
|
|
|
296
360
|
needs no PyTorch, so a fresh `pip install textflowkit` stays small and pulls no
|
|
297
361
|
torch; `openai-whisper` is an explicitly selectable opt-in engine.
|
|
298
362
|
|
|
299
|
-
, each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/whistle-resume.svg)
|
|
300
364
|
|
|
301
365
|
- **CPU only, no torch.** It runs a pinned native binary and downloads one pinned
|
|
302
366
|
model on first use. Naming a GPU device is refused rather than silently
|
|
@@ -313,7 +377,7 @@ torch; `openai-whisper` is an explicitly selectable opt-in engine.
|
|
|
313
377
|
of context on each side, so every standalone clip is ≤ 30 seconds (the native
|
|
314
378
|
CLI's limit). Overlap words are selected by core midpoint rather than text
|
|
315
379
|
deduplication, so repeated spoken phrases are preserved.
|
|
316
|
-
- **
|
|
380
|
+
- **Standalone streaming is not used.** The native `--audio-stream` mode failed its
|
|
317
381
|
coverage and is never passed; only the committed standalone output is parsed.
|
|
318
382
|
- **Durable block resume.** With `TEXTFLOWKIT_DB` set, a long run writes partial
|
|
319
383
|
per-block checkpoints; a resume checks the source and decoded-WAV hashes and the
|
|
@@ -407,7 +471,7 @@ its own beyond the `http` extra. It ships with the core package as of v0.1.10:
|
|
|
407
471
|
a regular install of the current release carries it.
|
|
408
472
|
|
|
409
473
|
```bash
|
|
410
|
-
python -m pip install 'textflowkit[http,export]==0.1.
|
|
474
|
+
python -m pip install 'textflowkit[http,export]==0.1.12'
|
|
411
475
|
textflowkit-ui
|
|
412
476
|
```
|
|
413
477
|
|
|
@@ -478,29 +542,37 @@ browser interface share the job contract without blocking a request.
|
|
|
478
542
|
|
|
479
543
|
## Status
|
|
480
544
|
|
|
481
|
-
**v0.1.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
545
|
+
**v0.1.12 release.** Adds optional UI-only local Ollama proofreading and native
|
|
546
|
+
Windows installer packaging; public EXE distribution remains gated on unresolved
|
|
547
|
+
corresponding-source compliance review, with no public installer download link.
|
|
548
|
+
Existing optional live streaming provides a transport-neutral
|
|
549
|
+
`StreamingSession` Python API, incremental transcript events, and authenticated
|
|
550
|
+
loopback WebSockets (`/stream` on the developer HTTP API and `/api/stream` on the
|
|
551
|
+
local UI), with a packaged browser microphone example. The native live capability
|
|
552
|
+
supports **Windows x86_64 only** and uses one owned child with a separately pinned
|
|
553
|
+
`libneedle3.dll`. The `streaming` extra supplies the WebSocket dependency;
|
|
554
|
+
`TEXTFLOWKIT_STREAMING=1` enables the server routes. Streaming is off by default.
|
|
555
|
+
|
|
556
|
+
Existing file and URL transcription, CLI, MCP, durable jobs, and local browser
|
|
557
|
+
workspace defaults remain unchanged. Whistle stays the CPU-only standalone default;
|
|
558
|
+
`openai-whisper` remains an explicit opt-in engine. The local browser workspace
|
|
559
|
+
introduced in v0.1.10 still needs only the `http` extra for its ordinary job flow.
|
|
560
|
+
Fonts remain 0.1.6. Live sessions are ephemeral and have no durable resume.
|
|
561
|
+
|
|
562
|
+
**Streaming evidence.** Local English PCM runs exercised the native core for 65 s
|
|
563
|
+
and 300 s; a separate assembled UI WebSocket run fed prerecorded PCM at real time
|
|
564
|
+
for 12 s and returned incremental events and a final transcript. Browser lifecycle
|
|
565
|
+
and resampling checks used fake audio. Physical browser microphone capture, live
|
|
566
|
+
Linux/macOS, and the six other accepted languages were not verified. The public
|
|
567
|
+
website remains static documentation and serves no streaming endpoint. Local source
|
|
568
|
+
validation does not establish published-package or exact-commit CI results.
|
|
497
569
|
|
|
498
570
|
**Verification limit.** The local browser interface is covered by an automated
|
|
499
571
|
suite, and the UI's behavior was proved on a **native Windows** machine in a real
|
|
500
572
|
browser. No live optional-backend (translation/diarization) run through the UI is
|
|
501
573
|
claimed, and **no live Linux or macOS UI run was performed here** — those
|
|
502
574
|
platforms are covered by automated tests only, and CI across Windows, Linux, and
|
|
503
|
-
macOS is
|
|
575
|
+
macOS is a separate release gate. Release publication uses the tag
|
|
504
576
|
workflow, which requires successful exact-commit main CI before PyPI uploads and
|
|
505
577
|
creates the public GitHub release only afterward. Check the linked release for
|
|
506
578
|
artifacts and workflow status; local source verification is not a fresh
|
|
@@ -517,7 +589,7 @@ MCP speech, seven-format exports and completed resume; the v0.1.8 runtime fixes
|
|
|
517
589
|
were independently checked through fresh-process CLI restart probes, real SQLite
|
|
518
590
|
setup-failure tests, and the full Windows test suite. Those checks are not new
|
|
519
591
|
individual-harness receipts. That is the previous releases' record, not evidence
|
|
520
|
-
for v0.1.
|
|
592
|
+
for v0.1.12.
|
|
521
593
|
|
|
522
594
|
The v0.1.6 release was the post-v0.1.5 review repair set: security hardening
|
|
523
595
|
for media acquisition and the HTTP and MCP adapters, safer subtitle wrapping and
|
|
@@ -536,7 +608,7 @@ and both [core](https://pypi.org/project/textflowkit/0.1.6/) and
|
|
|
536
608
|
[fonts](https://pypi.org/project/textflowkit-fonts/0.1.6/) PyPI projects are
|
|
537
609
|
live — that is the v0.1.6 release's evidence, not a receipt for a later release.
|
|
538
610
|
Everything from here to the end of this section is the v0.1.6 release's
|
|
539
|
-
historical record as published: it is not re-verified for v0.1.
|
|
611
|
+
historical record as published: it is not re-verified for v0.1.12, whose separate release evidence is not supplied by these historical paragraphs.
|
|
540
612
|
Merged-main CI passed 16/16 on the tagged commit; the published wheel and
|
|
541
613
|
sdist digests match the GitHub release assets and their SHA-256 list; and a fresh
|
|
542
614
|
Windows Python 3.12 install of `textflowkit[export,mcp,http]==0.1.6` from PyPI
|
|
@@ -573,3 +645,90 @@ limitation of liability.
|
|
|
573
645
|
|
|
574
646
|
Issues and PRs welcome. Please read [LEGAL.md](https://github.com/scottconverse/textflowkit/blob/main/LEGAL.md) before adding a source
|
|
575
647
|
adapter.
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
## Optional local AI transcript cleanup (v0.1.12)
|
|
651
|
+
|
|
652
|
+
v0.1.12 adds **opt-in proofreading in the local browser UI only**. After a transcription finishes, choose an
|
|
653
|
+
installed local Ollama model and click **Proofread with local AI**. Cleanup never
|
|
654
|
+
runs automatically. Ollama and cleanup models are not bundled in the installer.
|
|
655
|
+
The optional default preference is `qwen3.5:9b` only if already installed; its
|
|
656
|
+
size/performance fit has not been verified. Otherwise choose an installed local
|
|
657
|
+
model explicitly, such as `qwen3.8:27b-q4_K_M`. Larger models are never silently
|
|
658
|
+
selected. Install a model yourself through Ollama when needed; TextFlowKit does
|
|
659
|
+
not pull models, enable cloud tags, or use a paid provider.
|
|
660
|
+
|
|
661
|
+
The original transcript, job JSON, original copy button, search, and all existing
|
|
662
|
+
exports remain unchanged. Choose **Original only** or compare **source original
|
|
663
|
+
(left) / AI corrected (right)** in timestamp-anchored rows. Use **Copy corrected
|
|
664
|
+
text** or **Save corrected TXT** for the separate AI variant. The comparison
|
|
665
|
+
proofreads original source speech, not an optional translation. AI can make
|
|
666
|
+
plausible but wrong corrections, including names and facts: review against the
|
|
667
|
+
original and audio before using it. Prompt instructions reduce errors but do not
|
|
668
|
+
guarantee accuracy or resistance to instructions embedded in speech.
|
|
669
|
+
|
|
670
|
+
Corrected segments retain source start/end timestamps and stable zero-based
|
|
671
|
+
original segment indices. They have no inherited word alignment or translation;
|
|
672
|
+
**corrected word timing is not verified**. A separate persisted variant records
|
|
673
|
+
local provider, requested/returned model, UTC completion time, endpoint, successful
|
|
674
|
+
`done_reason=stop`, policy version and original SHA-256. If original job JSON
|
|
675
|
+
changes, its correction is invalidated. No partial replacement is published: bad,
|
|
676
|
+
truncated, missing, duplicated, reordered or extra segments fail the entire attempt.
|
|
677
|
+
A failed retry retains an earlier fully validated variant only if its original
|
|
678
|
+
hash still matches.
|
|
679
|
+
|
|
680
|
+
Cleanup uses a separate SQLite file named `<job database filename>.cleanup.sqlite3`
|
|
681
|
+
beside `TEXTFLOWKIT_DB` (or the UI default database). Include it when backing up UI
|
|
682
|
+
data; it contains transcript text and provenance. The canonical job store is never
|
|
683
|
+
updated by cleanup. Reloading/reopening a completed job retrieves its saved variant,
|
|
684
|
+
even if Ollama is offline. Model selection is per attempt; it is not a global
|
|
685
|
+
transcription/translation model setting.
|
|
686
|
+
|
|
687
|
+
Configuration is process-local environment, consistent with the existing UI:
|
|
688
|
+
|
|
689
|
+
- `TEXTFLOWKIT_CLEANUP_OLLAMA_URL`: default `http://127.0.0.1:11434`; only HTTP on
|
|
690
|
+
a literal loopback IP and explicit port is accepted (IPv6 `[::1]` also works).
|
|
691
|
+
DNS names, credentials, other paths, remote hosts and redirects are refused;
|
|
692
|
+
proxy environment variables are ignored by the cleanup client.
|
|
693
|
+
- `TEXTFLOWKIT_CLEANUP_MODEL`: optional preferred installed local tag; defaults
|
|
694
|
+
to `qwen3.5:9b`. If absent from installed tags, explicit selection is required.
|
|
695
|
+
Cloud tags and Ollama remote-model metadata are refused.
|
|
696
|
+
|
|
697
|
+
One cleanup runs at a time; the browser polls a background worker and remains
|
|
698
|
+
usable. Limits: 2,000 segments, 120,000 source characters, 60 chunks, at most
|
|
699
|
+
1,000 UTF-8 encoded bytes per chunk and 40 segments per chunk. A small read-only
|
|
700
|
+
neighboring context helps with sentences spanning segments without merging them.
|
|
701
|
+
Generation requests use temperature 0, thinking disabled, context 8,192 and at
|
|
702
|
+
most 4,096 generated tokens per chunk. Requests have a 180-second socket timeout,
|
|
703
|
+
bounded response reads (1 MiB), and strict 64 KiB model JSON limits. The overall
|
|
704
|
+
work budget remains 600 seconds, checked between requests and reads; a blocking
|
|
705
|
+
socket operation can take up to its remaining request timeout before failure is
|
|
706
|
+
observed. Oversize or timeout failures leave the original available.
|
|
707
|
+
|
|
708
|
+
Normal UI shutdown drains an active cleanup (it can take several minutes); there
|
|
709
|
+
is no cleanup cancellation button. Abrupt process exit leaves no partial variant;
|
|
710
|
+
an interrupted running lease becomes retryable after at most 785 seconds from its
|
|
711
|
+
start. Cleanup does not restart Ollama or stop/unload other models. Model text is
|
|
712
|
+
rendered with DOM text nodes, never HTML. Cleanup adds no Python dependency,
|
|
713
|
+
telemetry, cloud provider or network destination beyond the configured local
|
|
714
|
+
Ollama service. Existing media acquisition/translation network behavior is separate.
|
|
715
|
+
|
|
716
|
+
### Candidate validation status
|
|
717
|
+
|
|
718
|
+
The first cold full-UI attempt ended with a generic error and produced no variant;
|
|
719
|
+
the original remained intact. A subsequent hot 39-segment run returned zero text
|
|
720
|
+
edits despite clear source spelling errors, so it was not useful cleanup-quality
|
|
721
|
+
evidence. The final cold run began with the model explicitly unloaded and
|
|
722
|
+
completed all 39 segments in three chunks at
|
|
723
|
+
2026-10-16 17:39:52 UTC. It used matching requested/returned
|
|
724
|
+
`qwen3.8:27b-q4_K_M` and changed four segments. The original SQLite JSON matched
|
|
725
|
+
the source file, with segment IDs and timestamps preserved. The in-app-browser
|
|
726
|
+
side-by-side comparison was visible, and **Save corrected TXT** produced a
|
|
727
|
+
2,516-byte file whose SHA-256 matched the validated variant.
|
|
728
|
+
|
|
729
|
+
Observed edits included “guardrails,” “precludes,” and punctuation. “Fundamental”
|
|
730
|
+
and “victims” were plausible guesses, not verified against the audio. This is
|
|
731
|
+
measured evidence that the local full workflow completed and saved its separate
|
|
732
|
+
variant for this run; it does not establish transcription accuracy or general
|
|
733
|
+
cleanup quality. Review every correction against the audio. This is local workflow evidence,
|
|
734
|
+
not an audio-accuracy certification.
|