smartpipe-cli 1.4.0rc2__tar.gz → 1.4.0rc4__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.
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/CHANGELOG.md +142 -13
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/CITATION.cff +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/CONTRIBUTING.md +6 -5
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/PKG-INFO +35 -14
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/README.md +33 -13
- smartpipe_cli-1.4.0rc4/demo/video/README.md +23 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/Main.tsx +26 -7
- smartpipe_cli-1.4.0rc4/demo/video/src/Narration.tsx +94 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/Root.tsx +17 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Background.tsx +3 -10
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Terminal.tsx +69 -4
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/config.ts +10 -6
- smartpipe_cli-1.4.0rc4/demo/video/src/narration/durations.json +13 -0
- smartpipe_cli-1.4.0rc4/demo/video/src/narration/lines.json +13 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/Close.tsx +1 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/CostHonesty.tsx +27 -42
- smartpipe_cli-1.4.0rc4/demo/video/src/scenes/Graph.tsx +236 -0
- smartpipe_cli-1.4.0rc4/demo/video/src/scenes/Hook.tsx +47 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/Multimodal.tsx +150 -31
- smartpipe_cli-1.4.0rc4/demo/video/src/scenes/ScaleA.tsx +43 -0
- smartpipe_cli-1.4.0rc4/demo/video/src/scenes/ScaleB.tsx +42 -0
- smartpipe_cli-1.4.0rc4/docs/assets/demo-thumb.jpg +0 -0
- smartpipe_cli-1.4.0rc4/docs/assets/graph-hero.png +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/comparison.md +2 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/concepts/feeding-smartpipe.md +10 -2
- smartpipe_cli-1.4.0rc4/docs/concepts/granularity.md +109 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/concepts/models-and-providers.md +59 -47
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/concepts/output-formats.md +7 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/concepts/structured-output.md +57 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/concepts/the-item.md +15 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/README.md +3 -2
- smartpipe_cli-1.4.0rc4/docs/cookbook/knowledge-graph.md +131 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/live-monitoring.md +2 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/visualizing-results.md +2 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/demo/index.html +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/index.md +12 -10
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/inputs/files.md +2 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/install.md +3 -3
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/learn/1-first-pipeline.md +29 -14
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/learn/3-files-and-media.md +6 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/learn/6-pipelines-that-last.md +7 -4
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/privacy.md +27 -13
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/reference/cli.md +89 -22
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/reference/sem-files.md +39 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/troubleshooting.md +13 -9
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/cluster.md +2 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/diff.md +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/embed.md +5 -4
- smartpipe_cli-1.4.0rc4/docs/verbs/graph.md +217 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/join.md +7 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/outliers.md +3 -3
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/reduce.md +3 -3
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/sort.md +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/summarize.md +5 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/top-k.md +6 -6
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/where.md +5 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/mkdocs.yml +9 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/pyproject.toml +4 -1
- smartpipe_cli-1.4.0rc4/src/smartpipe/cli/auth_cmd.py +268 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/cluster_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/completions.py +23 -1
- smartpipe_cli-1.4.0rc4/src/smartpipe/cli/config_cmd.py +1248 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/distinct_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/doctor_cmd.py +3 -4
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/embed_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/extend_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/filter_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/join_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/map_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/outliers_cmd.py +5 -2
- smartpipe_cli-1.4.0rc4/src/smartpipe/cli/read_cmd.py +124 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/readable_cmd.py +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/reduce_cmd.py +4 -1
- smartpipe_cli-1.4.0rc4/src/smartpipe/cli/rescue.py +94 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/root.py +37 -20
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/run_cmd.py +28 -4
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/schema_cmd.py +45 -11
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/screens.py +13 -10
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/sem_file.py +55 -10
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/sort_cmd.py +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/split_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/top_k_cmd.py +5 -2
- smartpipe_cli-1.4.0rc4/src/smartpipe/config/authflow.py +202 -0
- smartpipe_cli-1.4.0rc4/src/smartpipe/config/bundles.py +186 -0
- smartpipe_cli-1.4.0rc4/src/smartpipe/config/credentials.py +241 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/display.py +31 -19
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/doctor.py +21 -19
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/picker.py +264 -14
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/state_cache.py +50 -3
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/store.py +92 -118
- smartpipe_cli-1.4.0rc4/src/smartpipe/config/verify.py +288 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/container.py +14 -8
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/aggregate.py +11 -3
- smartpipe_cli-1.4.0rc4/src/smartpipe/engine/fieldpath.py +167 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/predicate.py +26 -3
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/prompts.py +53 -10
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/schema.py +28 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/schema_repl.py +7 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/items.py +13 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/readers.py +53 -21
- smartpipe_cli-1.4.0rc4/src/smartpipe/io/richui.py +112 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/update_check.py +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/writers.py +3 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/budget.py +29 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/catalogs.py +62 -7
- smartpipe_cli-1.4.0rc4/src/smartpipe/models/keycheck.py +108 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/resolve.py +1 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/chart.py +14 -5
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/cluster.py +17 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/common.py +4 -3
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/convert.py +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/diff.py +6 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/filter.py +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/join.py +13 -2
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/outliers.py +1 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/reduce.py +49 -9
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/sortverb.py +4 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/summarize.py +3 -1
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/top_k.py +27 -17
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/where.py +5 -2
- smartpipe_cli-1.4.0rc2/demo/video/README.md +0 -17
- smartpipe_cli-1.4.0rc2/demo/video/src/scenes/Hook.tsx +0 -40
- smartpipe_cli-1.4.0rc2/demo/video/src/scenes/Scale.tsx +0 -47
- smartpipe_cli-1.4.0rc2/docs/assets/demo-thumb.jpg +0 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/auth_cmd.py +0 -78
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/config_cmd.py +0 -564
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/read_cmd.py +0 -68
- smartpipe_cli-1.4.0rc2/src/smartpipe/config/credentials.py +0 -118
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/.gitignore +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/LICENSE +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/NOTICE +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Caption.tsx +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/FileGlyph.tsx +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/SceneFrame.tsx +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Wordmark.tsx +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/font.ts +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/index.ts +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/ColdOpen.tsx +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/concepts/pipes-and-items.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/contract-extraction.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/customer-feedback.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/invoice-reconciliation.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/log-triage.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/meeting-digest.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/ranking-documents.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/stream-enrichment.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/training-data-prep.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/cookbook/video-qa.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/learn/2-structured-data.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/learn/4-free-verbs.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/learn/5-scale-and-cost.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/quickstart.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/reference/agents.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/reference/custom-verbs.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/distinct.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/extend.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/filter.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/getschema.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/map.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/readable.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/sample.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/docs/verbs/split.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/qa/README.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/qa/fixtures/README.md +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/__main__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/assets/probe.png +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/assets/probe.txt +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/assets/probe.wav +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/cache_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/chart_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/cite_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/diff_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/echo_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/getschema_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/graph_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/input_options.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/interrupts.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/probe_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/sample_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/schema_workshop.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/summarize_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/update_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/usage_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/where_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/write_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/paths.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/errors.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/install_channel.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/jsontools.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/versions.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/blocking.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/chart.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/chunking.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/clustering.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/graphkg.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/graphout.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/preview.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/progressbar.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/ranking.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/repair.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/runner.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/schema_dsl.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/tally.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/temporal.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/timebin.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/units.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/windows.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/arrow_menu.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/csvrows.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/diagnostics.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/inputs.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/leaderboard.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/metering.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/preview.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/progress.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/render.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/text.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/tty.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/usage.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/anthropic_adapter.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/base.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/cache.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/gemini_native.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/http_support.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/jina.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/local_embed.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/local_ner.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/ocr.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/ollama.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/openai_codex.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/openai_compat.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/openai_oauth.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/retry.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/stt.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/windows.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/parsing/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/parsing/detect.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/parsing/extract.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/py.typed +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/distinct.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/embed.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/extend.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/getschema.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/graph.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/graphfull.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/map.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/oversize.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/readable.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/sample.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/split.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/write.py +0 -0
- {smartpipe_cli-1.4.0rc2 → smartpipe_cli-1.4.0rc4}/tests/corpus/README.md +0 -0
|
@@ -5,11 +5,20 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
## [1.4.0] — 2026-07-08
|
|
9
10
|
|
|
10
11
|
The identity release.
|
|
11
12
|
|
|
12
13
|
### Knowledge graphs (the highlight)
|
|
14
|
+
- **The showcase**: a full verb page with the modality matrix and a
|
|
15
|
+
live-rendering Mermaid sample, a cookbook chapter written from real
|
|
16
|
+
runs against the downloadable playground corpus, the README highlight
|
|
17
|
+
with a screenshot of the case graph, agent SKILL recipes, and `graph`
|
|
18
|
+
on the welcome screen. Found en route: the playground download in the
|
|
19
|
+
docs pointed at the source tarball (no media inside) - all three
|
|
20
|
+
sites now fetch the actual 26 MB release asset.
|
|
21
|
+
|
|
13
22
|
- **`smartpipe graph --fast` turns a corpus into a knowledge graph for
|
|
14
23
|
exactly $0.** A local zero-shot NER model (GLiNER-small over ONNX -
|
|
15
24
|
no new dependencies, no torch, a one-time ~190 MB download like the
|
|
@@ -44,6 +53,15 @@ The identity release.
|
|
|
44
53
|
power path.
|
|
45
54
|
|
|
46
55
|
### The item — one law for everything in a pipe
|
|
56
|
+
- **Nested field paths, everywhere you read.** `where 'user.plan ==
|
|
57
|
+
"pro"'`, `sort --by metrics.score`, `chart items[0].category`,
|
|
58
|
+
`summarize 'avg(metrics.score) by user.plan'`, and `"Is {user.plan}
|
|
59
|
+
worth it?"` in prompts - one grammar (`a.b.c`, `items[0]`,
|
|
60
|
+
`a.b['weird key']`) across all five surfaces. A column literally
|
|
61
|
+
named `user.plan` always wins over the traversal, so CSV headers
|
|
62
|
+
with dots keep working. Extraction names stay flat - paths are for
|
|
63
|
+
reading, and the error says so.
|
|
64
|
+
|
|
47
65
|
- **Dates are a type, and they come back ISO.** `{due date}` and
|
|
48
66
|
`{ts datetime}` join the brace grammar. However the model phrases it
|
|
49
67
|
("Jan 15, 2026", "15/01/2026"), the field canonicalizes to
|
|
@@ -75,9 +93,20 @@ The identity release.
|
|
|
75
93
|
double-underscore namespace that rides every record: `__source` (path plus
|
|
76
94
|
HOW the item was cut - file, lines, jsonl, pages, minutes, segment index),
|
|
77
95
|
`__media` (one transport object for bytes crossing a pipe), `__score`
|
|
78
|
-
(join), `
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
(top_k and join similarity), `__rank` (top_k), `__snapshot` (top_k
|
|
97
|
+
--stream markers), `__distance` (outliers), `__invalid`/`__error`/`__raw`
|
|
98
|
+
(kept failures). Known fields round-trip through saved files; unknown `__`
|
|
99
|
+
fields warn once and carry. User data owns everything up to one leading
|
|
100
|
+
underscore - which is why the last single-underscore stragglers moved:
|
|
101
|
+
pre-1.4 `top_k`/`outliers` wrote `_score`/`_rank`/`_snapshot`/`_distance`,
|
|
102
|
+
and those spellings stay readable for one release (CSV/TSV still sort them
|
|
103
|
+
into the trailing columns) but are never written again. In the same sweep,
|
|
104
|
+
`cluster --explode` overwriting an existing `cluster` field became a
|
|
105
|
+
disclosed overwrite (one stderr warning) instead of a silent one.
|
|
106
|
+
- **top_k ranks can no longer collide.** Ranking keyed on each item's
|
|
107
|
+
source index, so two page-1 records from different PDFs fought over one
|
|
108
|
+
slot and a result silently vanished. Ranks are now run-scoped ordinals in
|
|
109
|
+
arrival order, in both the embedded and precomputed-vector paths.
|
|
81
110
|
- **Records in, records out.** A plain-prompt `map` over records now returns
|
|
82
111
|
a record (`{"result": …}` plus the spine) instead of bare prose - structure
|
|
83
112
|
and provenance survive transformation. Text lines still leave as text.
|
|
@@ -105,6 +134,22 @@ The identity release.
|
|
|
105
134
|
`where`/`summarize` report rows that had no fields; `--strict-rows` turns
|
|
106
135
|
the notes into errors. Multi-line plain output into a pipe warns that
|
|
107
136
|
line framing is ambiguous (use `--output json`).
|
|
137
|
+
- **`.sem` files are strict about their rows now.** A saved pipeline is a
|
|
138
|
+
program, and a stray plain line in a record stream is a bug, not a
|
|
139
|
+
shrug: `.sem` runs default to `--strict-rows` and fail at ingestion
|
|
140
|
+
naming the exact line, before any spend. Opt out with
|
|
141
|
+
`strict-rows = false` (top-level or per-stage); ad-hoc terminal runs
|
|
142
|
+
keep the permissive census. Eleven verbs that accepted `--strict-rows`
|
|
143
|
+
without actually enforcing it now do, and a text-only `where` predicate
|
|
144
|
+
over a log no longer trips strict mode over "missing fields". A new
|
|
145
|
+
docs page explains the granularity ladder (file → split → lines/rows)
|
|
146
|
+
and when mixing happens.
|
|
147
|
+
- **Synthesized records tell you what they summarize.** join pairs carry
|
|
148
|
+
`__sources` (both parents' refs); reduce windows stamp
|
|
149
|
+
`{"as": "window", "span": [1, 100], "count": 100}`, groups
|
|
150
|
+
`{"as": "group", "group": …, "count": N}`; cluster and diff summary
|
|
151
|
+
rows carry `{"as": "cluster"|"diff", "count": N}`. An audit trail for
|
|
152
|
+
every row that speaks for other rows - and `--bare` strips all of it.
|
|
108
153
|
|
|
109
154
|
### Judgment you can gate, retry, and keep
|
|
110
155
|
- **`--keep-invalid`** (map/extend): after the repair retry fails, keep the
|
|
@@ -114,6 +159,13 @@ The identity release.
|
|
|
114
159
|
`--check FILE` validates rows (exit 0/1), `--example` prints a validating
|
|
115
160
|
instance, bare stdin mode is a REPL. **`--dry-run`** (map/extend) prints
|
|
116
161
|
the composed first request and exits before any model resolution.
|
|
162
|
+
- **`schema --check` stopped failing your own pipelines.** The check is
|
|
163
|
+
open-world now: rows from the documented extend workflow (original
|
|
164
|
+
fields kept, spine aboard) pass instead of tripping "additional
|
|
165
|
+
properties are not allowed" on every row, and `?`-marked fields may be
|
|
166
|
+
absent, not just null. Extras earn one dim hint; `--strict` restores
|
|
167
|
+
the closed world for contract enforcement. The schema sent to models
|
|
168
|
+
at extraction time is unchanged.
|
|
117
169
|
- **Nullability is declared.** `?` on any type (`string?`, `number[]?`, bare
|
|
118
170
|
`field?`) compiles to a null union; bare fields mean scalar-or-scalar-list
|
|
119
171
|
and never admit null (D48, shipped earlier in this cycle).
|
|
@@ -162,6 +214,19 @@ The identity release.
|
|
|
162
214
|
over alphabetical luck (cloud tags compete equally), and speaks in the
|
|
163
215
|
same color voice as the other commands with a menu of detected local
|
|
164
216
|
tags and provider-prefixed cloud examples.
|
|
217
|
+
- **Exit 141 is now deliberate, and the -13 flake is dead.** smartpipe used
|
|
218
|
+
to arm the default SIGPIPE handler, so a downstream `| head` killed it by
|
|
219
|
+
raw signal - and, one run in a few hundred, a stray EPIPE on asyncio's
|
|
220
|
+
own self-pipe killed a healthy run mid-teardown, skipping the receipt
|
|
221
|
+
(the CI flake that delayed rc3). SIGPIPE now stays ignored; a closed
|
|
222
|
+
stdout surfaces as BrokenPipeError and exits a silent, deliberate 141
|
|
223
|
+
with every finally honored. (click 8.4's own EPIPE-to-exit-1 trap is
|
|
224
|
+
defused on the way.) One visible delta: `kill -PIPE` no longer
|
|
225
|
+
terminates smartpipe; pipeline behavior is unchanged.
|
|
226
|
+
- **A files-then-stdin wait has a name.** Chaining positional files into a
|
|
227
|
+
stdin read used to end in a silent hang when nothing was piped. All three
|
|
228
|
+
chain paths now say once, on stderr:
|
|
229
|
+
`note: files done - now reading stdin (pipe data or close it; files-only: add < /dev/null)`.
|
|
165
230
|
- **Docs bug, live-caught: `cluster | chart` drew flat bars.** The summary
|
|
166
231
|
rows are one-per-cluster, so charting them counts every theme once. The
|
|
167
232
|
README quick-tour step, the `cluster` help epilog, and the `.sem`
|
|
@@ -230,15 +295,24 @@ The identity release.
|
|
|
230
295
|
|
|
231
296
|
### Documents parse where they enter, vectors stay honest
|
|
232
297
|
- **The `ocr-model` role: a document parser at ingestion.** Set
|
|
233
|
-
`
|
|
234
|
-
`SMARTPIPE_OCR_MODEL
|
|
235
|
-
|
|
236
|
-
markdown as the text, disclosed per
|
|
237
|
-
conversion. Mistral refs ride the dedicated
|
|
238
|
-
(live-verified, whole PDFs in one call); any other
|
|
239
|
-
chat-vision with extract-the-text framing, so
|
|
240
|
-
local OCR. Parse failures fall back to the
|
|
241
|
-
disclosed, never fatal. Unset = exactly the
|
|
298
|
+
`ocr-model = "mistral/mistral-ocr-latest"` in config.toml (the setup
|
|
299
|
+
flow's OCR stage stamps it; `SMARTPIPE_OCR_MODEL` and `--ocr-model`
|
|
300
|
+
override per run) and ingested PDFs and images parse through it - one
|
|
301
|
+
item per page on the `pages` cut, markdown as the text, disclosed per
|
|
302
|
+
row and metered as a paid conversion. Mistral refs ride the dedicated
|
|
303
|
+
`/v1/ocr` wire (live-verified, whole PDFs in one call); any other
|
|
304
|
+
model ref works as chat-vision with extract-the-text framing, so
|
|
305
|
+
`ollama/llava` is a free local OCR. Parse failures fall back to the
|
|
306
|
+
local extraction ladder, disclosed, never fatal. Unset = exactly the
|
|
307
|
+
old behavior.
|
|
308
|
+
- **Reader mode does what you configured.** `smartpipe scan.pdf` used to
|
|
309
|
+
be pinned "zero model calls" even when you had set an ocr-model - the
|
|
310
|
+
reader now honors the role with the same per-row disclosure, local
|
|
311
|
+
fallback, and `--max-calls` belt as the verbs (plus a preflight note
|
|
312
|
+
when more than 20 files will parse). No ocr-model configured = the
|
|
313
|
+
same free path as always, pinned by a zero-HTTP-calls test. Found en
|
|
314
|
+
route: the mistral OCR wire was never counted by `--max-calls`
|
|
315
|
+
anywhere - it is belted now.
|
|
242
316
|
- **The `media-embed-model` role: one joint space for pixels and prose.**
|
|
243
317
|
Text keeps `embed-model`; media routes to the joint-space model
|
|
244
318
|
(jina-clip-v2 and friends). If a run would mix two vector spaces, the
|
|
@@ -256,6 +330,42 @@ The identity release.
|
|
|
256
330
|
media-embedding capability.
|
|
257
331
|
|
|
258
332
|
### Setup that reads the room
|
|
333
|
+
- **Rich now backs `config show` and `doctor`.** It is a deliberate core
|
|
334
|
+
dependency under the no-extras policy, imported only while those human-facing
|
|
335
|
+
screens render so `--help`, pipes, and `NO_COLOR` keep their existing contracts.
|
|
336
|
+
- **The interactive config wizard can go backward.** Model, embedding, OCR, and
|
|
337
|
+
final review screens expose explicit Back rows; returning to a stage restores
|
|
338
|
+
its pre-stage checkpoint, and typed model prompts accept `back`, `b`, `no`, or
|
|
339
|
+
`n` instead of accidentally saving `ollama/n`.
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
- **Discarding config is terminal and interruption is ordinary.** Choosing
|
|
343
|
+
discard no longer opens the shell-completion prompt after saying "Not saved";
|
|
344
|
+
Ctrl-C or EOF at any Click prompt exits 130 instead of showing the internal-bug
|
|
345
|
+
screen.
|
|
346
|
+
|
|
347
|
+
- **`auth login` now connects every provider, not just ChatGPT.** Pick
|
|
348
|
+
from the full list - OpenAI appears twice because it really is two
|
|
349
|
+
wires (API key vs ChatGPT login, and the login wire has no
|
|
350
|
+
embeddings) - paste your key at a masked prompt after the create-a-key
|
|
351
|
+
URL, and it validates live before storing (with an honest
|
|
352
|
+
"store anyway - the provider may be having a bad minute" escape).
|
|
353
|
+
Keys live at `~/.local/share/smartpipe/auth.json`, owner-only
|
|
354
|
+
permissions from the first byte, masked everywhere they surface, and
|
|
355
|
+
the environment variable always wins. `auth list` shows what's
|
|
356
|
+
connected and which source is live; `auth logout` removes.
|
|
357
|
+
- **Setup walks three questions in order: text model, embeddings,
|
|
358
|
+
document OCR.** Every stage shows every provider - connected ones
|
|
359
|
+
badged, unconnected ones connectable inline without leaving the flow.
|
|
360
|
+
The embedding stage only lists wires that embed; OCR is optional and
|
|
361
|
+
skippable in one keypress. At the end, one consented verification
|
|
362
|
+
pass (~5 tiny requests) probes what your models can actually do -
|
|
363
|
+
and if the basic text check fails, smartpipe reports a setup fault
|
|
364
|
+
instead of pretending your model lacks modalities. Results feed the
|
|
365
|
+
capability chips you see in every picker from then on, alongside a
|
|
366
|
+
public model registry and your own declarations for self-hosted
|
|
367
|
+
models.
|
|
368
|
+
|
|
259
369
|
- **The schema workshop.** `smartpipe schema` with no arguments at a
|
|
260
370
|
terminal opens a small interactive draft loop - your schema pinned up
|
|
261
371
|
top as colored braces, commands scrolling below: `/add name type`,
|
|
@@ -276,7 +386,26 @@ The identity release.
|
|
|
276
386
|
overwrites one you chose yourself), and one y/N question adds a backup
|
|
277
387
|
`fallback-model` for provider outages. After a `doctor --probe`,
|
|
278
388
|
catalog entries carry capability chips (`sees, hears - probed 2d ago`)
|
|
279
|
-
- probed facts, never claims.
|
|
389
|
+
- probed facts, never claims.
|
|
390
|
+
- **`smartpipe use` - setup is one word now.** `use gemini` (or
|
|
391
|
+
`use claude-opus-4-8`, `use ollama/qwen3:8b`) stamps a coherent bundle
|
|
392
|
+
in one shot: the model, its paired embedder, and the captions posture,
|
|
393
|
+
each line disclosed with a ✓ and a reason. No credential for the named
|
|
394
|
+
provider = a clean refusal that names the exact `auth login` command,
|
|
395
|
+
nothing stamped. Bare `use` opens the interactive flow. `smartpipe
|
|
396
|
+
using` answers "what am I running?" with every setting, its value, and
|
|
397
|
+
WHERE it came from (flag, env, config file, default) in one aligned
|
|
398
|
+
grid. The config.toml you get is signed by its door -
|
|
399
|
+
`# stamped by: smartpipe use (2026-07-10T06:38Z)` - so a mystery
|
|
400
|
+
config explains itself. The old setter subcommands (`config model`,
|
|
401
|
+
`config embed-model`, …) and profiles are gone; an old config with
|
|
402
|
+
profile keys loads with one warning and cleans itself on the next
|
|
403
|
+
save.
|
|
404
|
+
- **The no-model dead end offers a hand.** At a real terminal, the
|
|
405
|
+
no-model error now ends with `run setup now? [Y/n]` - accept, walk the
|
|
406
|
+
same setup flow, and it closes with "saved - rerun your command".
|
|
407
|
+
Scripts and CI see byte-identical output to before (the offer is
|
|
408
|
+
TTY-gated), and the exit code stays honest.
|
|
280
409
|
|
|
281
410
|
### Getting it and keeping it current
|
|
282
411
|
- **One-line install on every platform.**
|
|
@@ -9,7 +9,7 @@ Requires [uv](https://docs.astral.sh/uv/) and Python ≥ 3.11 (uv can fetch one
|
|
|
9
9
|
|
|
10
10
|
```console
|
|
11
11
|
$ git clone https://github.com/prabal-rje/smartpipe && cd smartpipe
|
|
12
|
-
$ uv sync --all-extras # creates .venv with
|
|
12
|
+
$ uv sync --all-extras # creates .venv with the project and dev tools
|
|
13
13
|
$ uv run smartpipe # welcome screen = working install
|
|
14
14
|
```
|
|
15
15
|
|
|
@@ -64,12 +64,13 @@ Reverting to built-in search is emptying the three values again.
|
|
|
64
64
|
|
|
65
65
|
## New dependencies
|
|
66
66
|
|
|
67
|
-
Core install weight is a feature
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
Core install weight is a feature, but D46 deliberately ships the complete
|
|
68
|
+
multimodal surface in core: there are no optional extras. The frozen dependency
|
|
69
|
+
snapshot makes every direct or transitive addition an explicit review decision.
|
|
70
|
+
Heavy imports stay function-local so startup remains budgeted.
|
|
70
71
|
|
|
71
72
|
**New heavy import? Function-local or justify.** `--help` must never import
|
|
72
|
-
`httpx`, `jsonschema`, `anthropic`, or `
|
|
73
|
+
`httpx`, `jsonschema`, `anthropic`, `markitdown`, or `rich` —
|
|
73
74
|
`tests/test_startup_imports.py` is the enforcement (it runs `-X importtime` and
|
|
74
75
|
fails on any banned module). `make startup` gives an advisory wall-clock number;
|
|
75
76
|
the import test is the deterministic gate.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: smartpipe-cli
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.0rc4
|
|
4
4
|
Summary: Semantic pipes and queries for your terminal - PDFs, images, audio, video, and text through Unix verbs that understand.
|
|
5
5
|
Project-URL: Homepage, https://github.com/prabal-rje/smartpipe
|
|
6
6
|
Project-URL: Changelog, https://github.com/prabal-rje/smartpipe/blob/main/CHANGELOG.md
|
|
@@ -32,6 +32,7 @@ Requires-Dist: matplotlib>=3.8
|
|
|
32
32
|
Requires-Dist: pdfminer-six>=20231228
|
|
33
33
|
Requires-Dist: plotext>=5
|
|
34
34
|
Requires-Dist: pypdf>=5.0
|
|
35
|
+
Requires-Dist: rich>=13.9
|
|
35
36
|
Requires-Dist: tomli-w>=1.0
|
|
36
37
|
Description-Content-Type: text/markdown
|
|
37
38
|
|
|
@@ -48,9 +49,9 @@ Description-Content-Type: text/markdown
|
|
|
48
49
|
Run PDFs, images, audio, video, and text through Unix verbs that understand
|
|
49
50
|
their input.
|
|
50
51
|
|
|
51
|
-
[](https://prabal-rje.github.io/smartpipe/demo/)
|
|
52
53
|
|
|
53
|
-
*[▶ Watch the full
|
|
54
|
+
*[▶ Watch the full 86-second demo](https://prabal-rje.github.io/smartpipe/demo/) - sound, controls, no download.*
|
|
54
55
|
|
|
55
56
|
## Install
|
|
56
57
|
|
|
@@ -92,7 +93,7 @@ and runs that tool's own upgrade.
|
|
|
92
93
|
smartpipe auth login
|
|
93
94
|
```
|
|
94
95
|
|
|
95
|
-
No ChatGPT plan?
|
|
96
|
+
No ChatGPT plan? Bring a cloud API key, or run local [Ollama][ollama] - see
|
|
96
97
|
[Models & providers][models].
|
|
97
98
|
|
|
98
99
|
## Examples
|
|
@@ -139,6 +140,7 @@ into ordinary Unix tools. Every verb is documented at
|
|
|
139
140
|
| [`distinct`][distinct] | fold near-duplicates; `--exact` is free | `sort -u`, by meaning |
|
|
140
141
|
| [`diff`][diff] | what distinguishes two sets | the post-incident answer |
|
|
141
142
|
| [`outliers`][outliers] | the items least like the rest | novelty, surfaced |
|
|
143
|
+
| [`graph`][graph] | corpus → entity/relationship graph; `--fast` is free | the case wall, with citations |
|
|
142
144
|
|
|
143
145
|
**Free verbs** never call a model. Run them first to cut the corpus before any
|
|
144
146
|
paid stage:
|
|
@@ -154,15 +156,16 @@ paid stage:
|
|
|
154
156
|
| [`chart`][cli] | terminal bars, SVG, facets, time series | quick plots |
|
|
155
157
|
|
|
156
158
|
Some semantic verbs have a **conditionally free mode**: `join --on` (key
|
|
157
|
-
equality, no prompt), `distinct --exact` (hash-only folding), `
|
|
158
|
-
`--dry-run` (compose without sending),
|
|
159
|
-
braces/DSL expression. Each stays at zero model
|
|
159
|
+
equality, no prompt), `distinct --exact` (hash-only folding), `graph --fast`
|
|
160
|
+
(local NER, on-device), `map`/`extend` `--dry-run` (compose without sending),
|
|
161
|
+
and `smartpipe schema` with a braces/DSL expression. Each stays at zero model
|
|
162
|
+
calls by construction.
|
|
160
163
|
|
|
161
164
|
## A one-minute tour
|
|
162
165
|
|
|
163
166
|
```bash
|
|
164
167
|
# 1. point smartpipe at a model (ChatGPT login, a cloud key, or local Ollama)
|
|
165
|
-
smartpipe
|
|
168
|
+
smartpipe use
|
|
166
169
|
|
|
167
170
|
# 2. ask one question across a folder of mixed documents
|
|
168
171
|
smartpipe map "What does this say about pricing?" 'docs/*.pdf'
|
|
@@ -192,6 +195,9 @@ smartpipe map "Extract {vendor string, invoice_number string, total number}" 'in
|
|
|
192
195
|
# 8. video RAG, no vector database: index a folder of recordings once, ask any day
|
|
193
196
|
smartpipe embed 'sessions/**/*.mp4' > sessions.embeddings
|
|
194
197
|
smartpipe top_k 3 --near "user gives up after the coupon fails" < sessions.embeddings
|
|
198
|
+
|
|
199
|
+
# 9. the corpus as a knowledge graph - $0: local NER, zero model calls
|
|
200
|
+
smartpipe graph --fast 'case-files/*.md' --save case.html
|
|
195
201
|
```
|
|
196
202
|
|
|
197
203
|
A `.txt` on a pipe arrives one item per line; `--as file` treats the whole
|
|
@@ -206,6 +212,18 @@ Numbers 7 and 8 are full recipes -
|
|
|
206
212
|
New to this? The [Learn track][quickstart] starts at zero and assumes nothing, including
|
|
207
213
|
what a "model" is.
|
|
208
214
|
|
|
215
|
+
### Highlight: the knowledge graph
|
|
216
|
+
|
|
217
|
+
Number 9 is new: `graph --fast` turns a folder of mixed files into an
|
|
218
|
+
interactive, **cited** knowledge graph without a single model call - a local
|
|
219
|
+
NER model finds the entities you name, co-occurrence weights the edges, and
|
|
220
|
+
hovering any edge shows the files behind it. A focus prompt upgrades the
|
|
221
|
+
strongest edges to model-read relations. Full story:
|
|
222
|
+
[the `graph` page](https://prabal-rje.github.io/smartpipe/verbs/graph/) and
|
|
223
|
+
[the cookbook recipe](docs/cookbook/knowledge-graph.md).
|
|
224
|
+
|
|
225
|
+

|
|
226
|
+
|
|
209
227
|
## Try it on real files
|
|
210
228
|
|
|
211
229
|
No corpus handy? [smartpipe-playground][playground] ships 26 MB of CC0 /
|
|
@@ -213,8 +231,8 @@ public-domain practice files - invoices, reports, photos, recordings, screen
|
|
|
213
231
|
sessions, and JSONL data:
|
|
214
232
|
|
|
215
233
|
```bash
|
|
216
|
-
curl -L https://github.com/prabal-rje/smartpipe-playground/
|
|
217
|
-
cd smartpipe-playground
|
|
234
|
+
curl -L https://github.com/prabal-rje/smartpipe-playground/releases/download/v1/smartpipe-playground-v1.tar.gz | tar xz
|
|
235
|
+
cd smartpipe-playground
|
|
218
236
|
|
|
219
237
|
smartpipe map "Extract {vendor, invoice_number, total number}" 'invoices/*.pdf'
|
|
220
238
|
smartpipe filter "the customer sounds frustrated" 'recordings/*.mp3'
|
|
@@ -236,9 +254,11 @@ For chat, [Ollama][ollama] runs models on your machine. Any cloud model sends
|
|
|
236
254
|
that run's data to its provider - `gpt-5.4-mini`, `claude-opus-4-8`,
|
|
237
255
|
`gemini-3.1-flash-lite`, `mistral-large-latest`, `openrouter/…`.
|
|
238
256
|
|
|
239
|
-
API keys come from environment variables
|
|
240
|
-
subscribers can
|
|
241
|
-
local run and token totals; see
|
|
257
|
+
API keys come from environment variables, or `smartpipe auth login` stores
|
|
258
|
+
one securely for you. ChatGPT subscribers can log in instead of using a key.
|
|
259
|
+
`smartpipe usage` keeps local run and token totals; see
|
|
260
|
+
[Privacy & security][privacy] for where credentials live and how to remove
|
|
261
|
+
them.
|
|
242
262
|
|
|
243
263
|
## Unix behavior
|
|
244
264
|
|
|
@@ -257,7 +277,7 @@ Full docs: **[prabal-rje.github.io/smartpipe][docs]**.
|
|
|
257
277
|
- [Install][install] - packages and platforms
|
|
258
278
|
- [Working with files & media][files] - PDFs, scans, images, audio, video
|
|
259
279
|
- [CLI reference][cli] - every flag, format, and exit code
|
|
260
|
-
- [Models & providers][models] -
|
|
280
|
+
- [Models & providers][models] - ChatGPT login, cloud keys, local Ollama
|
|
261
281
|
- [Privacy & security][privacy]
|
|
262
282
|
|
|
263
283
|
## How to cite
|
|
@@ -303,6 +323,7 @@ lives in [`qa/`](qa/README.md). The CLI surface is a SemVer contract.
|
|
|
303
323
|
[distinct]: https://prabal-rje.github.io/smartpipe/verbs/distinct/
|
|
304
324
|
[diff]: https://prabal-rje.github.io/smartpipe/verbs/diff/
|
|
305
325
|
[outliers]: https://prabal-rje.github.io/smartpipe/verbs/outliers/
|
|
326
|
+
[graph]: https://prabal-rje.github.io/smartpipe/verbs/graph/
|
|
306
327
|
[where]: https://prabal-rje.github.io/smartpipe/verbs/where/
|
|
307
328
|
[summarize]: https://prabal-rje.github.io/smartpipe/verbs/summarize/
|
|
308
329
|
[sort]: https://prabal-rje.github.io/smartpipe/verbs/sort/
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
Run PDFs, images, audio, video, and text through Unix verbs that understand
|
|
12
12
|
their input.
|
|
13
13
|
|
|
14
|
-
[](https://prabal-rje.github.io/smartpipe/demo/)
|
|
15
15
|
|
|
16
|
-
*[▶ Watch the full
|
|
16
|
+
*[▶ Watch the full 86-second demo](https://prabal-rje.github.io/smartpipe/demo/) - sound, controls, no download.*
|
|
17
17
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
@@ -55,7 +55,7 @@ and runs that tool's own upgrade.
|
|
|
55
55
|
smartpipe auth login
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
No ChatGPT plan?
|
|
58
|
+
No ChatGPT plan? Bring a cloud API key, or run local [Ollama][ollama] - see
|
|
59
59
|
[Models & providers][models].
|
|
60
60
|
|
|
61
61
|
## Examples
|
|
@@ -102,6 +102,7 @@ into ordinary Unix tools. Every verb is documented at
|
|
|
102
102
|
| [`distinct`][distinct] | fold near-duplicates; `--exact` is free | `sort -u`, by meaning |
|
|
103
103
|
| [`diff`][diff] | what distinguishes two sets | the post-incident answer |
|
|
104
104
|
| [`outliers`][outliers] | the items least like the rest | novelty, surfaced |
|
|
105
|
+
| [`graph`][graph] | corpus → entity/relationship graph; `--fast` is free | the case wall, with citations |
|
|
105
106
|
|
|
106
107
|
**Free verbs** never call a model. Run them first to cut the corpus before any
|
|
107
108
|
paid stage:
|
|
@@ -117,15 +118,16 @@ paid stage:
|
|
|
117
118
|
| [`chart`][cli] | terminal bars, SVG, facets, time series | quick plots |
|
|
118
119
|
|
|
119
120
|
Some semantic verbs have a **conditionally free mode**: `join --on` (key
|
|
120
|
-
equality, no prompt), `distinct --exact` (hash-only folding), `
|
|
121
|
-
`--dry-run` (compose without sending),
|
|
122
|
-
braces/DSL expression. Each stays at zero model
|
|
121
|
+
equality, no prompt), `distinct --exact` (hash-only folding), `graph --fast`
|
|
122
|
+
(local NER, on-device), `map`/`extend` `--dry-run` (compose without sending),
|
|
123
|
+
and `smartpipe schema` with a braces/DSL expression. Each stays at zero model
|
|
124
|
+
calls by construction.
|
|
123
125
|
|
|
124
126
|
## A one-minute tour
|
|
125
127
|
|
|
126
128
|
```bash
|
|
127
129
|
# 1. point smartpipe at a model (ChatGPT login, a cloud key, or local Ollama)
|
|
128
|
-
smartpipe
|
|
130
|
+
smartpipe use
|
|
129
131
|
|
|
130
132
|
# 2. ask one question across a folder of mixed documents
|
|
131
133
|
smartpipe map "What does this say about pricing?" 'docs/*.pdf'
|
|
@@ -155,6 +157,9 @@ smartpipe map "Extract {vendor string, invoice_number string, total number}" 'in
|
|
|
155
157
|
# 8. video RAG, no vector database: index a folder of recordings once, ask any day
|
|
156
158
|
smartpipe embed 'sessions/**/*.mp4' > sessions.embeddings
|
|
157
159
|
smartpipe top_k 3 --near "user gives up after the coupon fails" < sessions.embeddings
|
|
160
|
+
|
|
161
|
+
# 9. the corpus as a knowledge graph - $0: local NER, zero model calls
|
|
162
|
+
smartpipe graph --fast 'case-files/*.md' --save case.html
|
|
158
163
|
```
|
|
159
164
|
|
|
160
165
|
A `.txt` on a pipe arrives one item per line; `--as file` treats the whole
|
|
@@ -169,6 +174,18 @@ Numbers 7 and 8 are full recipes -
|
|
|
169
174
|
New to this? The [Learn track][quickstart] starts at zero and assumes nothing, including
|
|
170
175
|
what a "model" is.
|
|
171
176
|
|
|
177
|
+
### Highlight: the knowledge graph
|
|
178
|
+
|
|
179
|
+
Number 9 is new: `graph --fast` turns a folder of mixed files into an
|
|
180
|
+
interactive, **cited** knowledge graph without a single model call - a local
|
|
181
|
+
NER model finds the entities you name, co-occurrence weights the edges, and
|
|
182
|
+
hovering any edge shows the files behind it. A focus prompt upgrades the
|
|
183
|
+
strongest edges to model-read relations. Full story:
|
|
184
|
+
[the `graph` page](https://prabal-rje.github.io/smartpipe/verbs/graph/) and
|
|
185
|
+
[the cookbook recipe](docs/cookbook/knowledge-graph.md).
|
|
186
|
+
|
|
187
|
+

|
|
188
|
+
|
|
172
189
|
## Try it on real files
|
|
173
190
|
|
|
174
191
|
No corpus handy? [smartpipe-playground][playground] ships 26 MB of CC0 /
|
|
@@ -176,8 +193,8 @@ public-domain practice files - invoices, reports, photos, recordings, screen
|
|
|
176
193
|
sessions, and JSONL data:
|
|
177
194
|
|
|
178
195
|
```bash
|
|
179
|
-
curl -L https://github.com/prabal-rje/smartpipe-playground/
|
|
180
|
-
cd smartpipe-playground
|
|
196
|
+
curl -L https://github.com/prabal-rje/smartpipe-playground/releases/download/v1/smartpipe-playground-v1.tar.gz | tar xz
|
|
197
|
+
cd smartpipe-playground
|
|
181
198
|
|
|
182
199
|
smartpipe map "Extract {vendor, invoice_number, total number}" 'invoices/*.pdf'
|
|
183
200
|
smartpipe filter "the customer sounds frustrated" 'recordings/*.mp3'
|
|
@@ -199,9 +216,11 @@ For chat, [Ollama][ollama] runs models on your machine. Any cloud model sends
|
|
|
199
216
|
that run's data to its provider - `gpt-5.4-mini`, `claude-opus-4-8`,
|
|
200
217
|
`gemini-3.1-flash-lite`, `mistral-large-latest`, `openrouter/…`.
|
|
201
218
|
|
|
202
|
-
API keys come from environment variables
|
|
203
|
-
subscribers can
|
|
204
|
-
local run and token totals; see
|
|
219
|
+
API keys come from environment variables, or `smartpipe auth login` stores
|
|
220
|
+
one securely for you. ChatGPT subscribers can log in instead of using a key.
|
|
221
|
+
`smartpipe usage` keeps local run and token totals; see
|
|
222
|
+
[Privacy & security][privacy] for where credentials live and how to remove
|
|
223
|
+
them.
|
|
205
224
|
|
|
206
225
|
## Unix behavior
|
|
207
226
|
|
|
@@ -220,7 +239,7 @@ Full docs: **[prabal-rje.github.io/smartpipe][docs]**.
|
|
|
220
239
|
- [Install][install] - packages and platforms
|
|
221
240
|
- [Working with files & media][files] - PDFs, scans, images, audio, video
|
|
222
241
|
- [CLI reference][cli] - every flag, format, and exit code
|
|
223
|
-
- [Models & providers][models] -
|
|
242
|
+
- [Models & providers][models] - ChatGPT login, cloud keys, local Ollama
|
|
224
243
|
- [Privacy & security][privacy]
|
|
225
244
|
|
|
226
245
|
## How to cite
|
|
@@ -266,6 +285,7 @@ lives in [`qa/`](qa/README.md). The CLI surface is a SemVer contract.
|
|
|
266
285
|
[distinct]: https://prabal-rje.github.io/smartpipe/verbs/distinct/
|
|
267
286
|
[diff]: https://prabal-rje.github.io/smartpipe/verbs/diff/
|
|
268
287
|
[outliers]: https://prabal-rje.github.io/smartpipe/verbs/outliers/
|
|
288
|
+
[graph]: https://prabal-rje.github.io/smartpipe/verbs/graph/
|
|
269
289
|
[where]: https://prabal-rje.github.io/smartpipe/verbs/where/
|
|
270
290
|
[summarize]: https://prabal-rje.github.io/smartpipe/verbs/summarize/
|
|
271
291
|
[sort]: https://prabal-rje.github.io/smartpipe/verbs/sort/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# smartpipe demo video
|
|
2
|
+
|
|
3
|
+
A self-contained [Remotion](https://remotion.dev) project that renders the
|
|
4
|
+
86-second smartpipe demo (1920x1080, 30 fps): eight scenes - cold open, the
|
|
5
|
+
hook, multimodal, cost honesty, index, search, graph, close - all driven by
|
|
6
|
+
one reusable `<Terminal>` component and the frame-math constants in
|
|
7
|
+
`src/config.ts` (tune scene lengths there). Run `npm install` once, then
|
|
8
|
+
`npm run studio` to preview in the browser or `npm run render` to produce
|
|
9
|
+
`out/smartpipe-demo.mp4`; each scene is also registered as its own
|
|
10
|
+
composition (`ColdOpen`, `Hook`, `Multimodal`, `CostHonesty`, `ScaleA`,
|
|
11
|
+
`ScaleB`, `Graph`, `Close`), so `npx remotion render Hook out/hook.mp4`
|
|
12
|
+
re-renders one scene independently. The narrated cut is the `MainNarrated`
|
|
13
|
+
composition: the script text lives in `src/narration/lines.json`, and
|
|
14
|
+
`RIME_API_KEY=... node scripts/fetch-narration.mjs` synthesizes the
|
|
15
|
+
voiceover wavs (Rime.AI, speaker cupola) into the gitignored
|
|
16
|
+
`public/narration/` and refreshes `src/narration/durations.json` - fetch
|
|
17
|
+
before rendering `MainNarrated`. The music bed is
|
|
18
|
+
`public/silicon-prism-waltz.m4a` (60 s, looped over the 86 s cut with a
|
|
19
|
+
fade-out, held far below the voice); if you ever need a
|
|
20
|
+
no-strings-attached replacement, `node scripts/make-music.mjs` (ffmpeg
|
|
21
|
+
required) synthesizes an original ambient track from scratch into
|
|
22
|
+
`public/music.m4a` - royalty-free by construction - and you can point the
|
|
23
|
+
`<Audio>` element in `src/Main.tsx` at it.
|
|
@@ -5,22 +5,34 @@ import { Background } from "./components/Background";
|
|
|
5
5
|
import { Close } from "./scenes/Close";
|
|
6
6
|
import { ColdOpen } from "./scenes/ColdOpen";
|
|
7
7
|
import { CostHonesty } from "./scenes/CostHonesty";
|
|
8
|
+
import { Graph } from "./scenes/Graph";
|
|
8
9
|
import { Hook } from "./scenes/Hook";
|
|
9
10
|
import { Multimodal } from "./scenes/Multimodal";
|
|
10
|
-
import {
|
|
11
|
+
import { ScaleA } from "./scenes/ScaleA";
|
|
12
|
+
import { ScaleB } from "./scenes/ScaleB";
|
|
13
|
+
import { duckFactor, Narration } from "./Narration";
|
|
11
14
|
|
|
12
|
-
/**
|
|
13
|
-
|
|
15
|
+
/** Music bed base gain. Owner order (2026-07-09): "lower BG volume much
|
|
16
|
+
* more" — 0.55 → 0.14, about −12 dB. Texture, never presence. */
|
|
17
|
+
const MUSIC_BASE = 0.14;
|
|
18
|
+
|
|
19
|
+
export type MainProps = { narrated?: boolean };
|
|
20
|
+
|
|
21
|
+
/** The full 86s cut: one persistent background, eight scenes in series.
|
|
22
|
+
* With `narrated`, the Rime voiceover plays on top, a subtitle band shows
|
|
23
|
+
* the spoken words, and the music ducks a further few dB under speech. */
|
|
24
|
+
export const Main: React.FC<MainProps> = ({ narrated = false }) => {
|
|
14
25
|
return (
|
|
15
26
|
<AbsoluteFill>
|
|
16
|
-
{/* Music bed: Silicon Prism Waltz (60s, looped to cover the
|
|
27
|
+
{/* Music bed: Silicon Prism Waltz (60s, looped to cover the 86s cut).
|
|
17
28
|
Volume envelope: quick fade-in, steady bed, fade-out over the close.
|
|
18
29
|
A fully synthesized fallback lives at scripts/make-music.mjs. */}
|
|
19
30
|
<Audio
|
|
20
31
|
loop
|
|
21
32
|
src={staticFile("silicon-prism-waltz.m4a")}
|
|
22
33
|
volume={(f) =>
|
|
23
|
-
|
|
34
|
+
MUSIC_BASE *
|
|
35
|
+
(narrated ? duckFactor(f) : 1) *
|
|
24
36
|
interpolate(
|
|
25
37
|
f,
|
|
26
38
|
[0, 36, TOTAL_FRAMES - 96, TOTAL_FRAMES - 8],
|
|
@@ -43,13 +55,20 @@ export const Main: React.FC = () => {
|
|
|
43
55
|
<Series.Sequence durationInFrames={SCENE.cost}>
|
|
44
56
|
<CostHonesty />
|
|
45
57
|
</Series.Sequence>
|
|
46
|
-
<Series.Sequence durationInFrames={SCENE.
|
|
47
|
-
<
|
|
58
|
+
<Series.Sequence durationInFrames={SCENE.scaleA}>
|
|
59
|
+
<ScaleA />
|
|
60
|
+
</Series.Sequence>
|
|
61
|
+
<Series.Sequence durationInFrames={SCENE.scaleB}>
|
|
62
|
+
<ScaleB />
|
|
63
|
+
</Series.Sequence>
|
|
64
|
+
<Series.Sequence durationInFrames={SCENE.graph}>
|
|
65
|
+
<Graph />
|
|
48
66
|
</Series.Sequence>
|
|
49
67
|
<Series.Sequence durationInFrames={SCENE.close}>
|
|
50
68
|
<Close />
|
|
51
69
|
</Series.Sequence>
|
|
52
70
|
</Series>
|
|
71
|
+
{narrated ? <Narration /> : null}
|
|
53
72
|
</AbsoluteFill>
|
|
54
73
|
);
|
|
55
74
|
};
|