textflowkit 0.1.11__tar.gz → 0.1.13__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.11 → textflowkit-0.1.13}/.github/workflows/ci.yml +13 -2
- textflowkit-0.1.13/AGENTS.md +19 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/CHANGELOG.md +92 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/PKG-INFO +172 -15
- {textflowkit-0.1.11 → textflowkit-0.1.13}/README.md +171 -14
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/adapters.md +72 -4
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/architecture.md +79 -2
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/assets/architecture-overview.svg +1 -1
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/assets/whistle-resume.svg +5 -5
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/index.html +73 -12
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/install.md +59 -4
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/release-checklist.md +54 -5
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/roadmap.md +22 -1
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/streaming.md +4 -4
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/user-manual.md +175 -16
- textflowkit-0.1.13/docs/verification/whistle-coverage-20261019.md +77 -0
- textflowkit-0.1.13/docs/verification/windows-sources-20261019.md +51 -0
- textflowkit-0.1.13/packaging/windows/README.md +78 -0
- textflowkit-0.1.13/packaging/windows/THIRD-PARTY-NOTICES.txt +46 -0
- textflowkit-0.1.13/packaging/windows/assets.lock.json +56 -0
- textflowkit-0.1.13/packaging/windows/launch.py +140 -0
- textflowkit-0.1.13/packaging/windows/source-materials.json +39 -0
- textflowkit-0.1.13/packaging/windows/textflowkit.iss +77 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/pyproject.toml +6 -1
- textflowkit-0.1.13/scripts/build_windows_installer.py +160 -0
- textflowkit-0.1.13/scripts/prepare_windows_payload.py +1010 -0
- textflowkit-0.1.13/scripts/run_deepseek_worker.py +110 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/__init__.py +1 -1
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/checkpoint.py +1 -1
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/service.py +3 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/streaming_process.py +4 -3
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/whistle.py +223 -21
- textflowkit-0.1.13/src/textflowkit/core/windows_process.py +24 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/sources/acquire.py +4 -1
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/app.py +101 -0
- textflowkit-0.1.13/src/textflowkit/ui/cleanup.py +306 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/launcher.py +3 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/static/app.css +7 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/static/app.js +6 -0
- textflowkit-0.1.13/src/textflowkit/ui/static/cleanup.js +151 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/static/index.html +23 -0
- textflowkit-0.1.13/tests/fixtures/whistle_seam_regressions.json +3767 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_sdist_allowlist.py +4 -0
- textflowkit-0.1.13/tests/test_ui_cleanup.py +452 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_packaging.py +5 -2
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_whistle_engine.py +13 -13
- textflowkit-0.1.13/tests/test_whistle_seams.py +187 -0
- textflowkit-0.1.13/tests/test_windows_installer.py +512 -0
- textflowkit-0.1.13/tests/test_windows_payload.py +483 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.dockerignore +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.env.example +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.gitattributes +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.github/dependabot.yml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.github/workflows/publish-pypi.yml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.gitignore +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/.pre-commit-config.yaml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/CONTRIBUTING.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/Dockerfile +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/LEGAL.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/LICENSE +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/SECURITY.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/compose.yaml +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/.nojekyll +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/404.html +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/assets/live-streaming-flow.svg +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/assets/local-ui-flow.svg +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/site-deployment.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/docs/sources.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/fetch_published_fonts.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/smoke_installed_wheel.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/smoke_live_youtube.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/verify_readme_release.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/verify_release_ci.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/verify_release_versions.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/scripts/write_release_manifest.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/adapters/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/adapters/http_server.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/adapters/mcp_server.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/adapters/streaming_ws.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/assets/README.md +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/assets/selftest-speech.wav +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/cli.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/batch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/bind.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/cancel.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/diarize.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/engine.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/executor.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/jobs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/model.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/paths.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/pipeline.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/retrieval.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/runner.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/sqlite_store.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/startup.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/stream_worker.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/streaming.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/streaming_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/streaming_events.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/submission.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/timeutil.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/translate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/core/whistle_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/_cue_layout.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/_cue_text.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/_rename_excl.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/_rename_noreplace.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/docx.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/markdown.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/pdf.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/srt.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/txt.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/render/vtt.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/sources/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/sources/detect.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/sources/scratch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/capabilities.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/ownership.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/paths.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/security.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/static/streaming-capture-worklet.js +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/static/streaming-example.html +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/src/textflowkit/ui/uploads.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/__init__.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/ollama_stub.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_acquire.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_adapters.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_admission_ownership.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_atomic_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_atomic_resume_aba.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_batch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_batch_item_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_batch_resume_shared.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_bind.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cancellation_finalization.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_checkpoint.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_checkpoint_single_copy.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cli.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cli_batch_feedback.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cli_owning_recovery.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cli_resume_batch.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cli_stage_feedback.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cli_stdout_format.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_confined_decoder_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_confined_indirect_media.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_confined_resume_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_container_example.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_cue_layout.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_diarize.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_diarize_example_flags.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_diarize_token_docs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_docx_publication_identity.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_done_output_integrity.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_empty_formats_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_engine_adapters.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_engine_cache.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_engine_faster.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_engine_quiet.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_executor.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_executor_store_failure.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_export.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_export_file_mode.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_export_preflight.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_faster_whisper_docs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_fetch_published_fonts.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_font_notices.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_http_host_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_http_trusted_proxy.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_job_progress.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_jobs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_landing_commands.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_landing_page.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_legal_summary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_linux_no_hardlink.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_live_smoke_script.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_macos_no_hardlink.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_mcp_batch_cookie_docs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_mcp_http_boundary.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_mcp_protocol_cleanliness.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_mcp_terminal_guidance.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_mcp_tool_descriptions.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_mcp_work_root.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_model.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_partial_output_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_partial_pdf_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_paths.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_pipeline_integrity.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_pipeline_resume_setup.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_production_browser_cookies.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_publish_ci_gate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_publish_fonts_wiring.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_publish_manifest_wiring.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_publish_workflow_gate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_readme_layout.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_readme_release_guard.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_release_boundaries.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_release_manifest.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_release_surfaces.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_render.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_retrieval.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_service_profile.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_site_not_found.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_sources.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_stage_reuse_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_startup_recovery.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_stdio_protocol.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_browser_lifecycle.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_core.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_example.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_repairs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_transport.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_u5_repairs.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_streaming_ui_integration.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_submission.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_submission_validation.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_translate.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_translate_completeness.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_assets_and_capabilities.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_consoleless_logging.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_existing_routes_unchanged.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_launcher.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_ownership_and_shutdown.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_real_serve.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_security.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_submission_and_download.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_ui_uploads.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_verify_release_versions.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_whistle_assets.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_whistle_defaults.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_whistle_job_resume.py +0 -0
- {textflowkit-0.1.11 → textflowkit-0.1.13}/tests/test_windows_no_hardlink.py +0 -0
|
@@ -45,9 +45,20 @@ jobs:
|
|
|
45
45
|
if: runner.os == 'Linux'
|
|
46
46
|
run: sudo apt-get update && sudo apt-get install -y ffmpeg
|
|
47
47
|
|
|
48
|
-
- name: Install ffmpeg (Windows)
|
|
48
|
+
- name: Install pinned ffmpeg (Windows)
|
|
49
49
|
if: runner.os == 'Windows'
|
|
50
|
-
|
|
50
|
+
shell: python
|
|
51
|
+
run: |
|
|
52
|
+
import os, runpy
|
|
53
|
+
from pathlib import Path
|
|
54
|
+
ns = runpy.run_path('scripts/prepare_windows_payload.py')
|
|
55
|
+
spec = ns['load_asset_lock'](Path('packaging/windows/assets.lock.json'))['assets']['ffmpeg']
|
|
56
|
+
cache = Path(os.environ['RUNNER_TEMP']) / 'textflowkit-ci-ffmpeg'
|
|
57
|
+
archive = ns['_download_locked_asset'](cache, spec)
|
|
58
|
+
destination = cache / 'payload'
|
|
59
|
+
ns['prepare_ffmpeg_archive'](archive, destination)
|
|
60
|
+
with open(os.environ['GITHUB_PATH'], 'a', encoding='utf-8') as f:
|
|
61
|
+
f.write(str(destination / 'bin') + '\n')
|
|
51
62
|
|
|
52
63
|
- name: Install ffmpeg (macOS)
|
|
53
64
|
if: runner.os == 'macOS'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# TextFlowKit agent instructions
|
|
2
|
+
|
|
3
|
+
Scott's current bounded completion contract governs this work. Follow the active task and repository-required CI; preserve unrelated work and credentials. Keep one concise execution record, reuse unaffected evidence, and distinguish prepared, executed, verified and delivered work. A documented blocker remains incomplete. Do not invent adjacent features or weaken checks.
|
|
4
|
+
|
|
5
|
+
## Roles and delegation
|
|
6
|
+
|
|
7
|
+
The main assistant coordinates, plans and oversees. A worker invoked for an implementation unit performs that assigned unit directly; it is not another coordinator. Do not launch nested workers or automatic review/fan-out unless the owner or assignment explicitly authorizes it. Default to serial execution and one release candidate.
|
|
8
|
+
|
|
9
|
+
## Model selection
|
|
10
|
+
|
|
11
|
+
Follow Scott's active task selection; do not impose a project-wide Ollama default. His normal substantial-work/coordination preference is gpt-6.1-sol at medium, with gpt-6-luna at xhigh for small bounded work when available. Do not spawn a worker merely to switch models or add providers without authorization.
|
|
12
|
+
|
|
13
|
+
For the explicitly authorized current Whistle release and issue #31 source-recovery work, Scott requested Ollama `deepseek-v4.1-flash:1017-cloud`, reasoning OFF. `scripts/run_deepseek_worker.py` is an explicit opt-in runner for those assigned DeepSeek units: it sends `think: false`, allows no model fallback, and records the actual response model. Ollama currently returns canonical ID `deepseek-v4.1-flash:1017` without the `-cloud` transport suffix. Do not confuse a worker's self-description with the transport receipts. Preserve existing DeepSeek integrations with reasoning off, but do not turn this task-specific instruction into the default for unrelated future work.
|
|
14
|
+
|
|
15
|
+
This does not change the application's transcription or AI-cleanup defaults. Whistle remains the default transcription engine.
|
|
16
|
+
|
|
17
|
+
## Scope and delivery safeguards
|
|
18
|
+
|
|
19
|
+
Preserve unfinished work. Workers must not push, merge, tag, publish, release, stop unrelated processes, or change global configuration unless that unit is explicitly authorized to do so. The coordinating release task has Scott's push/merge/tag/publication authorization and separately his authorization to complete issue #31. Keep scratch, caches and build outputs outside the checkout. Verify process identity before acting on a PID; record ownership and terminal result for background jobs. Follow enforced controls rather than disguising a rejected action.
|
|
@@ -1,5 +1,97 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.1.13 — 2026-10-19
|
|
4
|
+
|
|
5
|
+
Core: 0.1.13; unchanged optional fonts: 0.1.6. Whistle missing-speech fixes and a
|
|
6
|
+
native Windows installer distributed with matching FFmpeg sources and notices.
|
|
7
|
+
|
|
8
|
+
- Bound native Whistle decode inputs to 15 seconds with 11-second owned cores
|
|
9
|
+
and up to two seconds of context per side. The former 30-second inputs
|
|
10
|
+
reproducibly omitted passages recovered by shorter inputs. Window policy is
|
|
11
|
+
part of resume identity; partial progress from the old plan requires a fresh
|
|
12
|
+
run. The engine and pinned model remain Whistle.
|
|
13
|
+
- Check short gaps with a bounded, differently framed native decode. Add words
|
|
14
|
+
only between two matching timed anchors; retain original words/repetitions,
|
|
15
|
+
skip long pauses, and cap extra calls per core. Record recovery counts.
|
|
16
|
+
- Correct Whistle shared-context assembly when independently estimated word
|
|
17
|
+
timestamps cause both neighboring cores to keep or discard the same occurrence.
|
|
18
|
+
Match occurrences one-to-one; preserve real repeated speech and leave ambiguous
|
|
19
|
+
collapsed repetitions untouched rather than using global text deduplication.
|
|
20
|
+
- Persist raw boundary context in Whistle progress schema 2 so resumed assembly
|
|
21
|
+
matches uninterrupted output. Old schema-1 partial runs require a fresh start;
|
|
22
|
+
completed jobs remain unchanged. Default engine remains Whistle.
|
|
23
|
+
- The native 30-second omission cases remain reproducible upstream; shorter
|
|
24
|
+
input windows and anchored gap checks mitigate them in TextFlowKit without
|
|
25
|
+
changing the engine or model weights.
|
|
26
|
+
- Verification on one four-hour public meeting (1310 native cores, 18 min 34 s
|
|
27
|
+
native decode, 34,723 final words): the two long missing passages were
|
|
28
|
+
restored (2 to 50 and 0 to 47 words), 62 short-gap checks accepted 7 for 53
|
|
29
|
+
added words, resume after cores 350 and 700 reproduced exact word text and
|
|
30
|
+
timings, and no invalid bounds or backwards starts remained. Focused suite:
|
|
31
|
+
113 passed. Full suite: 2,097 passed, 18 skipped; skips are not passes. This is
|
|
32
|
+
coverage evidence for one recording, not human WER or perfect accuracy; normal
|
|
33
|
+
spelling errors remain. See
|
|
34
|
+
[the verification note](docs/verification/whistle-coverage-20261019.md).
|
|
35
|
+
|
|
36
|
+
- Package matching FFmpeg sources, pinned build recipes, dependency archives and full notices alongside the Windows installer; record source hashes and preserve compatible DLL replacement. See [source verification](docs/verification/windows-sources-20261019.md).
|
|
37
|
+
|
|
38
|
+
## v0.1.12 — 2026-10-17
|
|
39
|
+
|
|
40
|
+
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.
|
|
41
|
+
|
|
42
|
+
### Optional local UI proofreading (v0.1.12)
|
|
43
|
+
|
|
44
|
+
- Add explicit post-transcription local Ollama proofreading with an installed-tag
|
|
45
|
+
picker; prefer `qwen3.5:9b` only when installed (size/performance fit unverified),
|
|
46
|
+
otherwise require selection.
|
|
47
|
+
No model downloads, cloud tags, paid provider, telemetry or new package dependency.
|
|
48
|
+
- Preserve original jobs and exports; persist a separate original-hash-bound AI
|
|
49
|
+
variant with provider/model/time provenance, source segment IDs/timestamps, no
|
|
50
|
+
inherited word alignment, comparison/original-only views and corrected TXT/copy.
|
|
51
|
+
- Bound background work and validate complete JSON/segment coverage atomically.
|
|
52
|
+
One cleanup at a time; fail without partial output. Normal shutdown drains work;
|
|
53
|
+
interrupted leases expire. AI corrections require human review.
|
|
54
|
+
|
|
55
|
+
- Validation history: the first cold full-UI attempt ended in a generic error; a
|
|
56
|
+
later hot 39-segment run returned zero edits despite clear spelling errors.
|
|
57
|
+
Final cold run (model explicitly unloaded first) completed all 39 segments in
|
|
58
|
+
three chunks with four changed segments at 2026-10-16 17:39:52 UTC. The original
|
|
59
|
+
SQLite JSON/source and IDs/timestamps matched; visible side-by-side review and
|
|
60
|
+
corrected TXT save were verified, with the saved file hash matching the variant.
|
|
61
|
+
This proves workflow completion for one run, not accuracy; “fundamental” and
|
|
62
|
+
“victims” were plausible guesses not verified against audio. Review against audio.
|
|
63
|
+
|
|
64
|
+
### Native Windows installer
|
|
65
|
+
|
|
66
|
+
- Package the existing local browser UI in a native per-user installer for core
|
|
67
|
+
v0.1.12. Built and tested locally; public EXE publication remains gated on
|
|
68
|
+
corresponding-source compliance review. No public installer link is available.
|
|
69
|
+
- Bundle: private embeddable CPython, the UI and HTTP, export, and
|
|
70
|
+
streaming dependencies, the pinned Whistle model and runtime, and ffmpeg,
|
|
71
|
+
ffprobe, and Node. The installer is designed to need no separate Python, WSL,
|
|
72
|
+
or Docker installation.
|
|
73
|
+
- Prebundled Whistle assets and media binaries mean local file jobs need no
|
|
74
|
+
first-use asset download. URL media still needs network access. The default
|
|
75
|
+
Whistle engine supports only these seven advertised languages: `en`, `de`,
|
|
76
|
+
`fr`, `es`, `it`, `nl`, and `pl`.
|
|
77
|
+
- Per-user setup with a Start Menu entry and optional desktop shortcut; launch
|
|
78
|
+
starts the loopback server and opens the existing UI in the browser. It normally
|
|
79
|
+
needs no administrator rights, changes no global `PATH`, and has no automatic
|
|
80
|
+
updates.
|
|
81
|
+
- Keep UI data outside the app install directory and preserve it on upgrade and
|
|
82
|
+
uninstall. Stop server and wait before upgrade or uninstall; the candidate will
|
|
83
|
+
block while it is running rather than force-kill active jobs. Stop server drains
|
|
84
|
+
jobs, so cancel one first if it should not finish.
|
|
85
|
+
- Do not bundle optional `openai-whisper` or diarization dependencies; their
|
|
86
|
+
documented optional paths remain available through the Python package. Bundled
|
|
87
|
+
streaming dependencies do not change the opt-in default; physical browser
|
|
88
|
+
microphone capture remains unverified.
|
|
89
|
+
- The installer bundle includes third-party license and notice files,
|
|
90
|
+
including FFmpeg LGPL notices and corresponding-source information. Verify
|
|
91
|
+
exact notices and source-distribution details against final binaries before
|
|
92
|
+
publication.
|
|
93
|
+
- The candidate is unsigned, so Windows may show a SmartScreen warning.
|
|
94
|
+
|
|
3
95
|
## v0.1.11 — 2026-10-06
|
|
4
96
|
|
|
5
97
|
Optional native live streaming supports **Windows x86_64 only**. Core version:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: textflowkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
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
|
|
@@ -73,7 +73,7 @@ Cross-platform media transcription toolkit. **One core, one CLI, thin adapters.*
|
|
|
73
73
|
[User manual](https://github.com/scottconverse/textflowkit/blob/main/docs/user-manual.md) ·
|
|
74
74
|
[Developer and integration manual](https://github.com/scottconverse/textflowkit/blob/main/docs/adapters.md)
|
|
75
75
|
|
|
76
|
-
**Current release: [v0.1.
|
|
76
|
+
**Current release: [v0.1.13](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13).**
|
|
77
77
|
|
|
78
78
|
The [static site deployment](https://github.com/scottconverse/textflowkit/blob/main/docs/site-deployment.md) is hosted on Cloudflare
|
|
79
79
|
Pages. GitHub remains the source and CI host; the website does not run the
|
|
@@ -134,7 +134,7 @@ DOCX and PDF are available through the optional `export` extra.
|
|
|
134
134
|
|
|
135
135
|
## Architecture
|
|
136
136
|
|
|
137
|
-
 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.13/docs/assets/architecture-overview.svg)
|
|
138
138
|
|
|
139
139
|
The design principle is **one shared core, thin doors**. Everything of substance
|
|
140
140
|
lives in the core; the interfaces are thin — the local browser UI is a fifth door
|
|
@@ -158,7 +158,7 @@ see [docs/architecture.md](https://github.com/scottconverse/textflowkit/blob/mai
|
|
|
158
158
|
|
|
159
159
|
## Live microphone streaming (opt-in)
|
|
160
160
|
|
|
161
|
-
In v0.1.
|
|
161
|
+
In v0.1.13, live streaming supports **Windows x86_64 only**. When
|
|
162
162
|
`TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
|
|
163
163
|
WebSocket and the local UI serves `/api/stream`, both transcribing a live microphone
|
|
164
164
|
as you speak. A **runnable, self-hosted browser example** ships at
|
|
@@ -167,7 +167,7 @@ as you speak. A **runnable, self-hosted browser example** ships at
|
|
|
167
167
|
No CDN, no analytics, no external fetch. Requires the `streaming` extra:
|
|
168
168
|
|
|
169
169
|
```bash
|
|
170
|
-
python -m pip install "textflowkit[streaming]==0.1.
|
|
170
|
+
python -m pip install "textflowkit[streaming]==0.1.13"
|
|
171
171
|
```
|
|
172
172
|
|
|
173
173
|
It is **off by default** — with the switch unset the endpoint does not exist — and
|
|
@@ -233,6 +233,40 @@ installs `textflowkit-fonts` for offline multilingual PDF rendering:
|
|
|
233
233
|
python -m pip install 'textflowkit[export]'
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
+
## Windows desktop installer (v0.1.13)
|
|
237
|
+
|
|
238
|
+
[Download Windows x64 setup](https://github.com/scottconverse/textflowkit/releases/download/v0.1.13/TextFlowKit-0.1.13-windows-x64-setup.exe) · [Matching sources and notices](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13)
|
|
239
|
+
|
|
240
|
+
An installer for the existing local browser workspace accompanies core v0.1.13. The Windows installer and its matching FFmpeg source and notice bundles are distributed together through the [v0.1.13 release](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13). The Python package remains supported for developers and integrations.
|
|
241
|
+
|
|
242
|
+
The installer is designed to run without a separately installed Python, WSL, or
|
|
243
|
+
Docker. Its bundle includes a private embeddable CPython runtime, the
|
|
244
|
+
browser UI and HTTP, export, and streaming dependencies, the pinned Whistle model
|
|
245
|
+
and runtime, and ffmpeg, ffprobe, and Node. The setup installs per user,
|
|
246
|
+
creates a Start Menu shortcut, and offers an optional desktop shortcut. Opening
|
|
247
|
+
the shortcut will start the local server and open the existing browser UI at
|
|
248
|
+
localhost. It is designed to need no administrator rights in normal use, change
|
|
249
|
+
no global `PATH`, and avoid automatic updates.
|
|
250
|
+
|
|
251
|
+
The pinned Whistle assets and media binaries are prebundled, so local file jobs
|
|
252
|
+
need no first-use asset download. URL sources still need their normal network
|
|
253
|
+
access. The default Whistle engine supports only these seven advertised languages:
|
|
254
|
+
`en`, `de`, `fr`, `es`, `it`, `nl`, and `pl`. Optional `openai-whisper` and diarization dependencies are not
|
|
255
|
+
bundled; those features remain documented for the Python package when separately
|
|
256
|
+
installed and configured. Streaming dependencies are bundled, but live streaming
|
|
257
|
+
remains opt-in and physical browser microphone capture has not been verified.
|
|
258
|
+
|
|
259
|
+
The installer is designed to keep UI data outside the application install
|
|
260
|
+
directory and preserve it on upgrades and uninstall. Stop the UI server with
|
|
261
|
+
**Stop server** and wait for it to exit before upgrading or uninstalling; the
|
|
262
|
+
installer will block while it is running rather than force-killing active jobs.
|
|
263
|
+
Cancel a job first if it should not drain to completion. The bundle also
|
|
264
|
+
includes third-party license and notice files, including FFmpeg's LGPL notices
|
|
265
|
+
and corresponding-source information. Check exact notices and source-distribution
|
|
266
|
+
details in the matching source bundles distributed with this release. The installer is
|
|
267
|
+
unsigned, so Windows may show a SmartScreen warning. See the [installer candidate
|
|
268
|
+
notes](https://github.com/scottconverse/textflowkit/blob/main/docs/install.md#windows-desktop-installer-v0113).
|
|
269
|
+
|
|
236
270
|
## Python API
|
|
237
271
|
|
|
238
272
|
The same pipeline used by the CLI and adapters is available to Python callers:
|
|
@@ -328,7 +362,7 @@ textflowkit export ./transcript.json --format vtt
|
|
|
328
362
|
needs no PyTorch, so a fresh `pip install textflowkit` stays small and pulls no
|
|
329
363
|
torch; `openai-whisper` is an explicitly selectable opt-in engine.
|
|
330
364
|
|
|
331
|
-

|
|
332
366
|
|
|
333
367
|
- **CPU only, no torch.** It runs a pinned native binary and downloads one pinned
|
|
334
368
|
model on first use. Naming a GPU device is refused rather than silently
|
|
@@ -341,16 +375,26 @@ torch; `openai-whisper` is an explicitly selectable opt-in engine.
|
|
|
341
375
|
Apple Silicon. **Intel Macs are not supported**; a request there is refused
|
|
342
376
|
with a message that names the explicit `whisper` engine instead. No WSL layer
|
|
343
377
|
is involved.
|
|
344
|
-
- **How it works:** long audio is split into
|
|
345
|
-
of context on each side, so every standalone clip is ≤
|
|
346
|
-
|
|
347
|
-
|
|
378
|
+
- **How it works:** long audio is split into 11-second cores with up to 2 seconds
|
|
379
|
+
of context on each side, so every standalone clip is ≤ 15 seconds. This conservative
|
|
380
|
+
ceiling avoids reproduced omissions on 30-second inputs. Midpoints provide initial ownership; shared-context matching
|
|
381
|
+
reconciles duplicate or dropped occurrences when neighboring timestamps
|
|
382
|
+
disagree. This is not global text deduplication: real repetitions and ambiguous
|
|
383
|
+
recognition are preserved. The 15-second ceiling and this assembly behavior ship
|
|
384
|
+
in v0.1.13; neither recovers speech the native recognizer never emits.
|
|
385
|
+
- **Speech-gap check (v0.1.13).** Short gaps between recognized words receive a
|
|
386
|
+
bounded second listen with different clip boundaries. Extra words are accepted
|
|
387
|
+
only between matching words on both sides at nearby times. Existing words and
|
|
388
|
+
repetitions stay intact; long pauses do not trigger this check. The model is
|
|
389
|
+
still Whistle, with the same pinned weights and telemetry settings.
|
|
348
390
|
- **Standalone streaming is not used.** The native `--audio-stream` mode failed its
|
|
349
391
|
coverage and is never passed; only the committed standalone output is parsed.
|
|
350
392
|
- **Durable block resume.** With `TEXTFLOWKIT_DB` set, a long run writes partial
|
|
351
393
|
per-block checkpoints; a resume checks the source and decoded-WAV hashes and the
|
|
352
394
|
config, then re-runs only the blocks that were not finished. The durable store
|
|
353
|
-
still assumes one owning process.
|
|
395
|
+
still assumes one owning process. The v0.1.13 assembly policy saves raw
|
|
396
|
+
boundary context with schema 2; old schema-1 partial runs must be restarted,
|
|
397
|
+
not resumed under the new assembly policy. Existing completed jobs are unchanged.
|
|
354
398
|
- **Cancellation.** A running Whistle run terminates its exact owned child
|
|
355
399
|
process bounded by a per-clip timeout. A single long `openai-whisper` model call
|
|
356
400
|
is still only cancellable at its next stage boundary, as documented for the
|
|
@@ -439,7 +483,7 @@ its own beyond the `http` extra. It ships with the core package as of v0.1.10:
|
|
|
439
483
|
a regular install of the current release carries it.
|
|
440
484
|
|
|
441
485
|
```bash
|
|
442
|
-
python -m pip install 'textflowkit[http,export]==0.1.
|
|
486
|
+
python -m pip install 'textflowkit[http,export]==0.1.13'
|
|
443
487
|
textflowkit-ui
|
|
444
488
|
```
|
|
445
489
|
|
|
@@ -510,7 +554,17 @@ browser interface share the job contract without blocking a request.
|
|
|
510
554
|
|
|
511
555
|
## Status
|
|
512
556
|
|
|
513
|
-
**v0.1.
|
|
557
|
+
**v0.1.13 release.** Fixes reproduced Whistle speech omissions. Native decode
|
|
558
|
+
inputs are now bounded to 15 seconds (11-second owned cores with up to 2 seconds
|
|
559
|
+
of context per side), short interior speech gaps get a bounded second listen that
|
|
560
|
+
accepts words only between matching timed anchors, and shared-context words are
|
|
561
|
+
reconciled one-to-one before durable resume. Whistle remains the default engine
|
|
562
|
+
with the same pinned model and runtime; fonts remain 0.1.6. Progress schema 2
|
|
563
|
+
stores raw boundary context, so an unfinished partial job from the previous
|
|
564
|
+
26-second-core plan (schema 1) must be restarted instead of resumed; completed
|
|
565
|
+
records are unchanged. The native Windows installer is rebuilt at v0.1.13 and
|
|
566
|
+
distributed with matching FFmpeg sources, notices, hashes and build instructions.
|
|
567
|
+
Existing optional live streaming provides a transport-neutral
|
|
514
568
|
`StreamingSession` Python API, incremental transcript events, and authenticated
|
|
515
569
|
loopback WebSockets (`/stream` on the developer HTTP API and `/api/stream` on the
|
|
516
570
|
local UI), with a packaged browser microphone example. The native live capability
|
|
@@ -532,6 +586,22 @@ Linux/macOS, and the six other accepted languages were not verified. The public
|
|
|
532
586
|
website remains static documentation and serves no streaming endpoint. Local source
|
|
533
587
|
validation does not establish published-package or exact-commit CI results.
|
|
534
588
|
|
|
589
|
+
**v0.1.12 cleanup (historical).** The opt-in local Ollama proofreading path remains
|
|
590
|
+
as introduced in v0.1.12, covering the local browser UI only; it was not changed by
|
|
591
|
+
v0.1.13. It keeps the published 39-segment cleanup proof from v0.1.12 with no
|
|
592
|
+
audio-accuracy claim: that proof records segment/format handling, not recognition
|
|
593
|
+
accuracy.
|
|
594
|
+
|
|
595
|
+
**v0.1.13 Whistle coverage, omission, and resume.** The 15-second bound (11-second
|
|
596
|
+
cores plus up to 2 s context per side) fixes reproduced speech omissions on
|
|
597
|
+
30-second inputs; the interior speech-gap second listen accepts extra words only
|
|
598
|
+
between matching timed anchors; shared-context words are reconciled one-to-one
|
|
599
|
+
before durable resume so a partial run rejoins without double ownership. Recognized
|
|
600
|
+
language coverage remains the same accepted set, and nothing here recovers speech
|
|
601
|
+
the native recognizer never emits. See
|
|
602
|
+
[docs/verification/whistle-coverage-20261019.md](https://github.com/scottconverse/textflowkit/blob/main/docs/verification/whistle-coverage-20261019.md)
|
|
603
|
+
for the run-by-run coverage, omission, and resume evidence.
|
|
604
|
+
|
|
535
605
|
**Verification limit.** The local browser interface is covered by an automated
|
|
536
606
|
suite, and the UI's behavior was proved on a **native Windows** machine in a real
|
|
537
607
|
browser. No live optional-backend (translation/diarization) run through the UI is
|
|
@@ -554,7 +624,7 @@ MCP speech, seven-format exports and completed resume; the v0.1.8 runtime fixes
|
|
|
554
624
|
were independently checked through fresh-process CLI restart probes, real SQLite
|
|
555
625
|
setup-failure tests, and the full Windows test suite. Those checks are not new
|
|
556
626
|
individual-harness receipts. That is the previous releases' record, not evidence
|
|
557
|
-
for v0.1.
|
|
627
|
+
for v0.1.13.
|
|
558
628
|
|
|
559
629
|
The v0.1.6 release was the post-v0.1.5 review repair set: security hardening
|
|
560
630
|
for media acquisition and the HTTP and MCP adapters, safer subtitle wrapping and
|
|
@@ -573,7 +643,7 @@ and both [core](https://pypi.org/project/textflowkit/0.1.6/) and
|
|
|
573
643
|
[fonts](https://pypi.org/project/textflowkit-fonts/0.1.6/) PyPI projects are
|
|
574
644
|
live — that is the v0.1.6 release's evidence, not a receipt for a later release.
|
|
575
645
|
Everything from here to the end of this section is the v0.1.6 release's
|
|
576
|
-
historical record as published: it is not re-verified for v0.1.
|
|
646
|
+
historical record as published: it is not re-verified for v0.1.13, whose separate release evidence is not supplied by these historical paragraphs.
|
|
577
647
|
Merged-main CI passed 16/16 on the tagged commit; the published wheel and
|
|
578
648
|
sdist digests match the GitHub release assets and their SHA-256 list; and a fresh
|
|
579
649
|
Windows Python 3.12 install of `textflowkit[export,mcp,http]==0.1.6` from PyPI
|
|
@@ -610,3 +680,90 @@ limitation of liability.
|
|
|
610
680
|
|
|
611
681
|
Issues and PRs welcome. Please read [LEGAL.md](https://github.com/scottconverse/textflowkit/blob/main/LEGAL.md) before adding a source
|
|
612
682
|
adapter.
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
## Optional local AI transcript cleanup (introduced in v0.1.12)
|
|
686
|
+
|
|
687
|
+
v0.1.12 adds **opt-in proofreading in the local browser UI only** (introduced in v0.1.12; unchanged in v0.1.13). After a transcription finishes, choose an
|
|
688
|
+
installed local Ollama model and click **Proofread with local AI**. Cleanup never
|
|
689
|
+
runs automatically. Ollama and cleanup models are not bundled in the installer.
|
|
690
|
+
The optional default preference is `qwen3.5:9b` only if already installed; its
|
|
691
|
+
size/performance fit has not been verified. Otherwise choose an installed local
|
|
692
|
+
model explicitly, such as `qwen3.8:27b-q4_K_M`. Larger models are never silently
|
|
693
|
+
selected. Install a model yourself through Ollama when needed; TextFlowKit does
|
|
694
|
+
not pull models, enable cloud tags, or use a paid provider.
|
|
695
|
+
|
|
696
|
+
The original transcript, job JSON, original copy button, search, and all existing
|
|
697
|
+
exports remain unchanged. Choose **Original only** or compare **source original
|
|
698
|
+
(left) / AI corrected (right)** in timestamp-anchored rows. Use **Copy corrected
|
|
699
|
+
text** or **Save corrected TXT** for the separate AI variant. The comparison
|
|
700
|
+
proofreads original source speech, not an optional translation. AI can make
|
|
701
|
+
plausible but wrong corrections, including names and facts: review against the
|
|
702
|
+
original and audio before using it. Prompt instructions reduce errors but do not
|
|
703
|
+
guarantee accuracy or resistance to instructions embedded in speech.
|
|
704
|
+
|
|
705
|
+
Corrected segments retain source start/end timestamps and stable zero-based
|
|
706
|
+
original segment indices. They have no inherited word alignment or translation;
|
|
707
|
+
**corrected word timing is not verified**. A separate persisted variant records
|
|
708
|
+
local provider, requested/returned model, UTC completion time, endpoint, successful
|
|
709
|
+
`done_reason=stop`, policy version and original SHA-256. If original job JSON
|
|
710
|
+
changes, its correction is invalidated. No partial replacement is published: bad,
|
|
711
|
+
truncated, missing, duplicated, reordered or extra segments fail the entire attempt.
|
|
712
|
+
A failed retry retains an earlier fully validated variant only if its original
|
|
713
|
+
hash still matches.
|
|
714
|
+
|
|
715
|
+
Cleanup uses a separate SQLite file named `<job database filename>.cleanup.sqlite3`
|
|
716
|
+
beside `TEXTFLOWKIT_DB` (or the UI default database). Include it when backing up UI
|
|
717
|
+
data; it contains transcript text and provenance. The canonical job store is never
|
|
718
|
+
updated by cleanup. Reloading/reopening a completed job retrieves its saved variant,
|
|
719
|
+
even if Ollama is offline. Model selection is per attempt; it is not a global
|
|
720
|
+
transcription/translation model setting.
|
|
721
|
+
|
|
722
|
+
Configuration is process-local environment, consistent with the existing UI:
|
|
723
|
+
|
|
724
|
+
- `TEXTFLOWKIT_CLEANUP_OLLAMA_URL`: default `http://127.0.0.1:11434`; only HTTP on
|
|
725
|
+
a literal loopback IP and explicit port is accepted (IPv6 `[::1]` also works).
|
|
726
|
+
DNS names, credentials, other paths, remote hosts and redirects are refused;
|
|
727
|
+
proxy environment variables are ignored by the cleanup client.
|
|
728
|
+
- `TEXTFLOWKIT_CLEANUP_MODEL`: optional preferred installed local tag; defaults
|
|
729
|
+
to `qwen3.5:9b`. If absent from installed tags, explicit selection is required.
|
|
730
|
+
Cloud tags and Ollama remote-model metadata are refused.
|
|
731
|
+
|
|
732
|
+
One cleanup runs at a time; the browser polls a background worker and remains
|
|
733
|
+
usable. Limits: 2,000 segments, 120,000 source characters, 60 chunks, at most
|
|
734
|
+
1,000 UTF-8 encoded bytes per chunk and 40 segments per chunk. A small read-only
|
|
735
|
+
neighboring context helps with sentences spanning segments without merging them.
|
|
736
|
+
Generation requests use temperature 0, thinking disabled, context 8,192 and at
|
|
737
|
+
most 4,096 generated tokens per chunk. Requests have a 180-second socket timeout,
|
|
738
|
+
bounded response reads (1 MiB), and strict 64 KiB model JSON limits. The overall
|
|
739
|
+
work budget remains 600 seconds, checked between requests and reads; a blocking
|
|
740
|
+
socket operation can take up to its remaining request timeout before failure is
|
|
741
|
+
observed. Oversize or timeout failures leave the original available.
|
|
742
|
+
|
|
743
|
+
Normal UI shutdown drains an active cleanup (it can take several minutes); there
|
|
744
|
+
is no cleanup cancellation button. Abrupt process exit leaves no partial variant;
|
|
745
|
+
an interrupted running lease becomes retryable after at most 785 seconds from its
|
|
746
|
+
start. Cleanup does not restart Ollama or stop/unload other models. Model text is
|
|
747
|
+
rendered with DOM text nodes, never HTML. Cleanup adds no Python dependency,
|
|
748
|
+
telemetry, cloud provider or network destination beyond the configured local
|
|
749
|
+
Ollama service. Existing media acquisition/translation network behavior is separate.
|
|
750
|
+
|
|
751
|
+
### Candidate validation status
|
|
752
|
+
|
|
753
|
+
The first cold full-UI attempt ended with a generic error and produced no variant;
|
|
754
|
+
the original remained intact. A subsequent hot 39-segment run returned zero text
|
|
755
|
+
edits despite clear source spelling errors, so it was not useful cleanup-quality
|
|
756
|
+
evidence. The final cold run began with the model explicitly unloaded and
|
|
757
|
+
completed all 39 segments in three chunks at
|
|
758
|
+
2026-10-16 17:39:52 UTC. It used matching requested/returned
|
|
759
|
+
`qwen3.8:27b-q4_K_M` and changed four segments. The original SQLite JSON matched
|
|
760
|
+
the source file, with segment IDs and timestamps preserved. The in-app-browser
|
|
761
|
+
side-by-side comparison was visible, and **Save corrected TXT** produced a
|
|
762
|
+
2,516-byte file whose SHA-256 matched the validated variant.
|
|
763
|
+
|
|
764
|
+
Observed edits included “guardrails,” “precludes,” and punctuation. “Fundamental”
|
|
765
|
+
and “victims” were plausible guesses, not verified against the audio. This is
|
|
766
|
+
measured evidence that the local full workflow completed and saved its separate
|
|
767
|
+
variant for this run; it does not establish transcription accuracy or general
|
|
768
|
+
cleanup quality. Review every correction against the audio. This is local workflow evidence,
|
|
769
|
+
not an audio-accuracy certification.
|