smartpipe-cli 1.4.0rc3__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.0rc3 → smartpipe_cli-1.4.0rc4}/CHANGELOG.md +97 -13
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/CITATION.cff +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/PKG-INFO +5 -5
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/README.md +4 -4
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/ScaleB.tsx +2 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/comparison.md +2 -2
- {smartpipe_cli-1.4.0rc3 → 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.0rc3 → smartpipe_cli-1.4.0rc4}/docs/concepts/models-and-providers.md +42 -44
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/concepts/output-formats.md +7 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/concepts/structured-output.md +57 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/concepts/the-item.md +15 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/live-monitoring.md +2 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/visualizing-results.md +2 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/index.md +4 -4
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/inputs/files.md +2 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/install.md +3 -3
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/learn/1-first-pipeline.md +29 -14
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/learn/3-files-and-media.md +6 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/learn/6-pipelines-that-last.md +7 -4
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/privacy.md +5 -5
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/reference/cli.md +69 -27
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/reference/sem-files.md +39 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/troubleshooting.md +13 -9
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/cluster.md +2 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/diff.md +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/embed.md +5 -4
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/join.md +7 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/outliers.md +3 -3
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/reduce.md +3 -3
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/sort.md +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/summarize.md +5 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/top-k.md +6 -6
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/where.md +5 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/mkdocs.yml +1 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/pyproject.toml +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/cluster_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/completions.py +23 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/config_cmd.py +147 -104
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/distinct_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/doctor_cmd.py +1 -3
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/embed_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/extend_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/filter_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/join_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/map_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → 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.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/readable_cmd.py +1 -1
- {smartpipe_cli-1.4.0rc3 → 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.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/root.py +36 -19
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/run_cmd.py +28 -4
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/schema_cmd.py +45 -11
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/screens.py +12 -10
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/sem_file.py +55 -10
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/sort_cmd.py +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/split_cmd.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/top_k_cmd.py +5 -2
- smartpipe_cli-1.4.0rc4/src/smartpipe/config/bundles.py +186 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/display.py +2 -12
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/picker.py +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/store.py +63 -118
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/container.py +11 -7
- {smartpipe_cli-1.4.0rc3 → 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.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/predicate.py +26 -3
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/prompts.py +53 -10
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/schema.py +28 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/schema_repl.py +7 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/items.py +13 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/readers.py +53 -21
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/update_check.py +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/writers.py +3 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/budget.py +29 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/resolve.py +1 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/chart.py +14 -5
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/cluster.py +17 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/common.py +4 -3
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/convert.py +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/diff.py +6 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/filter.py +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/join.py +13 -2
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/outliers.py +1 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/reduce.py +49 -9
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/sortverb.py +4 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/summarize.py +3 -1
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/top_k.py +27 -17
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/where.py +5 -2
- smartpipe_cli-1.4.0rc3/src/smartpipe/cli/read_cmd.py +0 -68
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/.gitignore +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/CONTRIBUTING.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/LICENSE +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/NOTICE +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/README.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/Main.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/Narration.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/Root.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Background.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Caption.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/FileGlyph.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/SceneFrame.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Terminal.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/components/Wordmark.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/config.ts +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/font.ts +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/index.ts +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/narration/durations.json +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/narration/lines.json +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/Close.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/ColdOpen.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/CostHonesty.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/Graph.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/Hook.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/Multimodal.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/demo/video/src/scenes/ScaleA.tsx +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/assets/demo-thumb.jpg +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/assets/graph-hero.png +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/concepts/pipes-and-items.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/README.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/contract-extraction.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/customer-feedback.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/invoice-reconciliation.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/knowledge-graph.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/log-triage.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/meeting-digest.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/ranking-documents.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/stream-enrichment.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/training-data-prep.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/cookbook/video-qa.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/demo/index.html +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/learn/2-structured-data.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/learn/4-free-verbs.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/learn/5-scale-and-cost.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/quickstart.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/reference/agents.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/reference/custom-verbs.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/distinct.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/extend.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/filter.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/getschema.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/graph.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/map.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/readable.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/sample.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/docs/verbs/split.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/qa/README.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/qa/fixtures/README.md +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/__main__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/assets/probe.png +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/assets/probe.txt +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/assets/probe.wav +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/auth_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/cache_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/chart_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/cite_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/diff_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/echo_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/getschema_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/graph_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/input_options.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/interrupts.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/probe_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/sample_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/schema_workshop.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/summarize_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/update_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/usage_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/where_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/cli/write_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/authflow.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/credentials.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/doctor.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/paths.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/state_cache.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/config/verify.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/errors.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/install_channel.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/jsontools.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/core/versions.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/blocking.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/chart.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/chunking.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/clustering.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/graphkg.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/graphout.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/preview.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/progressbar.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/ranking.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/repair.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/runner.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/schema_dsl.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/tally.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/temporal.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/timebin.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/units.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/engine/windows.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/arrow_menu.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/csvrows.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/diagnostics.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/inputs.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/leaderboard.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/metering.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/preview.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/progress.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/render.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/richui.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/text.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/tty.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/io/usage.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/anthropic_adapter.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/base.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/cache.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/catalogs.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/gemini_native.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/http_support.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/jina.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/keycheck.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/local_embed.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/local_ner.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/ocr.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/ollama.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/openai_codex.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/openai_compat.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/openai_oauth.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/retry.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/stt.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/models/windows.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/parsing/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/parsing/detect.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/parsing/extract.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/py.typed +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/distinct.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/embed.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/extend.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/getschema.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/graph.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/graphfull.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/map.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/oversize.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/readable.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/sample.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/split.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/src/smartpipe/verbs/write.py +0 -0
- {smartpipe_cli-1.4.0rc3 → smartpipe_cli-1.4.0rc4}/tests/corpus/README.md +0 -0
|
@@ -53,6 +53,15 @@ The identity release.
|
|
|
53
53
|
power path.
|
|
54
54
|
|
|
55
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
|
+
|
|
56
65
|
- **Dates are a type, and they come back ISO.** `{due date}` and
|
|
57
66
|
`{ts datetime}` join the brace grammar. However the model phrases it
|
|
58
67
|
("Jan 15, 2026", "15/01/2026"), the field canonicalizes to
|
|
@@ -84,9 +93,20 @@ The identity release.
|
|
|
84
93
|
double-underscore namespace that rides every record: `__source` (path plus
|
|
85
94
|
HOW the item was cut - file, lines, jsonl, pages, minutes, segment index),
|
|
86
95
|
`__media` (one transport object for bytes crossing a pipe), `__score`
|
|
87
|
-
(join), `
|
|
88
|
-
|
|
89
|
-
|
|
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.
|
|
90
110
|
- **Records in, records out.** A plain-prompt `map` over records now returns
|
|
91
111
|
a record (`{"result": …}` plus the spine) instead of bare prose - structure
|
|
92
112
|
and provenance survive transformation. Text lines still leave as text.
|
|
@@ -114,6 +134,22 @@ The identity release.
|
|
|
114
134
|
`where`/`summarize` report rows that had no fields; `--strict-rows` turns
|
|
115
135
|
the notes into errors. Multi-line plain output into a pipe warns that
|
|
116
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.
|
|
117
153
|
|
|
118
154
|
### Judgment you can gate, retry, and keep
|
|
119
155
|
- **`--keep-invalid`** (map/extend): after the repair retry fails, keep the
|
|
@@ -123,6 +159,13 @@ The identity release.
|
|
|
123
159
|
`--check FILE` validates rows (exit 0/1), `--example` prints a validating
|
|
124
160
|
instance, bare stdin mode is a REPL. **`--dry-run`** (map/extend) prints
|
|
125
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.
|
|
126
169
|
- **Nullability is declared.** `?` on any type (`string?`, `number[]?`, bare
|
|
127
170
|
`field?`) compiles to a null union; bare fields mean scalar-or-scalar-list
|
|
128
171
|
and never admit null (D48, shipped earlier in this cycle).
|
|
@@ -171,6 +214,19 @@ The identity release.
|
|
|
171
214
|
over alphabetical luck (cloud tags compete equally), and speaks in the
|
|
172
215
|
same color voice as the other commands with a menu of detected local
|
|
173
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)`.
|
|
174
230
|
- **Docs bug, live-caught: `cluster | chart` drew flat bars.** The summary
|
|
175
231
|
rows are one-per-cluster, so charting them counts every theme once. The
|
|
176
232
|
README quick-tour step, the `cluster` help epilog, and the `.sem`
|
|
@@ -239,15 +295,24 @@ The identity release.
|
|
|
239
295
|
|
|
240
296
|
### Documents parse where they enter, vectors stay honest
|
|
241
297
|
- **The `ocr-model` role: a document parser at ingestion.** Set
|
|
242
|
-
`
|
|
243
|
-
`SMARTPIPE_OCR_MODEL
|
|
244
|
-
|
|
245
|
-
markdown as the text, disclosed per
|
|
246
|
-
conversion. Mistral refs ride the dedicated
|
|
247
|
-
(live-verified, whole PDFs in one call); any other
|
|
248
|
-
chat-vision with extract-the-text framing, so
|
|
249
|
-
local OCR. Parse failures fall back to the
|
|
250
|
-
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.
|
|
251
316
|
- **The `media-embed-model` role: one joint space for pixels and prose.**
|
|
252
317
|
Text keeps `embed-model`; media routes to the joint-space model
|
|
253
318
|
(jina-clip-v2 and friends). If a run would mix two vector spaces, the
|
|
@@ -321,7 +386,26 @@ The identity release.
|
|
|
321
386
|
overwrites one you chose yourself), and one y/N question adds a backup
|
|
322
387
|
`fallback-model` for provider outages. After a `doctor --probe`,
|
|
323
388
|
catalog entries carry capability chips (`sees, hears - probed 2d ago`)
|
|
324
|
-
- 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.
|
|
325
409
|
|
|
326
410
|
### Getting it and keeping it current
|
|
327
411
|
- **One-line install on every platform.**
|
|
@@ -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
|
|
@@ -49,7 +49,7 @@ Description-Content-Type: text/markdown
|
|
|
49
49
|
Run PDFs, images, audio, video, and text through Unix verbs that understand
|
|
50
50
|
their input.
|
|
51
51
|
|
|
52
|
-
[](https://prabal-rje.github.io/smartpipe/demo/)
|
|
53
53
|
|
|
54
54
|
*[▶ Watch the full 86-second demo](https://prabal-rje.github.io/smartpipe/demo/) - sound, controls, no download.*
|
|
55
55
|
|
|
@@ -93,7 +93,7 @@ and runs that tool's own upgrade.
|
|
|
93
93
|
smartpipe auth login
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
No ChatGPT plan?
|
|
96
|
+
No ChatGPT plan? Bring a cloud API key, or run local [Ollama][ollama] - see
|
|
97
97
|
[Models & providers][models].
|
|
98
98
|
|
|
99
99
|
## Examples
|
|
@@ -165,7 +165,7 @@ calls by construction.
|
|
|
165
165
|
|
|
166
166
|
```bash
|
|
167
167
|
# 1. point smartpipe at a model (ChatGPT login, a cloud key, or local Ollama)
|
|
168
|
-
smartpipe
|
|
168
|
+
smartpipe use
|
|
169
169
|
|
|
170
170
|
# 2. ask one question across a folder of mixed documents
|
|
171
171
|
smartpipe map "What does this say about pricing?" 'docs/*.pdf'
|
|
@@ -277,7 +277,7 @@ Full docs: **[prabal-rje.github.io/smartpipe][docs]**.
|
|
|
277
277
|
- [Install][install] - packages and platforms
|
|
278
278
|
- [Working with files & media][files] - PDFs, scans, images, audio, video
|
|
279
279
|
- [CLI reference][cli] - every flag, format, and exit code
|
|
280
|
-
- [Models & providers][models] -
|
|
280
|
+
- [Models & providers][models] - ChatGPT login, cloud keys, local Ollama
|
|
281
281
|
- [Privacy & security][privacy]
|
|
282
282
|
|
|
283
283
|
## How to cite
|
|
@@ -11,7 +11,7 @@
|
|
|
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
16
|
*[▶ Watch the full 86-second demo](https://prabal-rje.github.io/smartpipe/demo/) - sound, controls, no download.*
|
|
17
17
|
|
|
@@ -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
|
|
@@ -127,7 +127,7 @@ calls by construction.
|
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
129
|
# 1. point smartpipe at a model (ChatGPT login, a cloud key, or local Ollama)
|
|
130
|
-
smartpipe
|
|
130
|
+
smartpipe use
|
|
131
131
|
|
|
132
132
|
# 2. ask one question across a folder of mixed documents
|
|
133
133
|
smartpipe map "What does this say about pricing?" 'docs/*.pdf'
|
|
@@ -239,7 +239,7 @@ Full docs: **[prabal-rje.github.io/smartpipe][docs]**.
|
|
|
239
239
|
- [Install][install] - packages and platforms
|
|
240
240
|
- [Working with files & media][files] - PDFs, scans, images, audio, video
|
|
241
241
|
- [CLI reference][cli] - every flag, format, and exit code
|
|
242
|
-
- [Models & providers][models] -
|
|
242
|
+
- [Models & providers][models] - ChatGPT login, cloud keys, local Ollama
|
|
243
243
|
- [Privacy & security][privacy]
|
|
244
244
|
|
|
245
245
|
## How to cite
|
|
@@ -15,10 +15,10 @@ const LINES: readonly TerminalLine[] = [
|
|
|
15
15
|
},
|
|
16
16
|
{ kind: "ord", at: sec(3.2), text: "#1" },
|
|
17
17
|
{ kind: "field", at: sec(3.3), k: "text", v: "Checkout 502 bug …" },
|
|
18
|
-
{ kind: "field", at: sec(3.4), k: "
|
|
18
|
+
{ kind: "field", at: sec(3.4), k: "__score", v: "0.93" },
|
|
19
19
|
{ kind: "ord", at: sec(3.9), text: "#2", gap: true },
|
|
20
20
|
{ kind: "field", at: sec(4.0), k: "text", v: "Pay page hangs …" },
|
|
21
|
-
{ kind: "field", at: sec(4.1), k: "
|
|
21
|
+
{ kind: "field", at: sec(4.1), k: "__score", v: "0.88" },
|
|
22
22
|
];
|
|
23
23
|
|
|
24
24
|
/** Scene 6 — scale B: search the index by meaning. */
|
|
@@ -57,8 +57,8 @@ Some tools fit certain jobs better:
|
|
|
57
57
|
|
|
58
58
|
- **Local model probing, with explicit cloud setup** - if no chat model is configured,
|
|
59
59
|
smartpipe probes local Ollama first. If it finds no usable model, it stops with
|
|
60
|
-
setup instructions. Cloud calls happen only after you choose a cloud model
|
|
61
|
-
|
|
60
|
+
setup instructions. Cloud calls happen only after you choose a cloud model or
|
|
61
|
+
login path.
|
|
62
62
|
|
|
63
63
|
- **`grep --color=auto`-style adaptive output** - human view at a terminal, JSONL when piped, with no flag.
|
|
64
64
|
|
|
@@ -13,8 +13,10 @@ live in [the item](the-item.md); this page is the ingestion mechanics.
|
|
|
13
13
|
| ONE binary document (`< report.pdf`) | one whole-document item, spooled and extracted |
|
|
14
14
|
| an image / audio / video stream | one media item, bytes carried to the model |
|
|
15
15
|
|
|
16
|
-
Mixed streams are legal; `--strict-rows` (or
|
|
17
|
-
them an error
|
|
16
|
+
Mixed streams are legal in an interactive pipe; `--strict-rows` (or
|
|
17
|
+
`SMARTPIPE_STRICT_ROWS=1`) makes them an error naming the first mixed row,
|
|
18
|
+
and `.sem` runs are strict by default (unattended = loud) - the full story is
|
|
19
|
+
[the granularity ladder](granularity.md).
|
|
18
20
|
|
|
19
21
|
## Named files
|
|
20
22
|
|
|
@@ -85,8 +87,14 @@ ingestion made visible, and the front half of the
|
|
|
85
87
|
```bash
|
|
86
88
|
smartpipe report.pdf | head -1
|
|
87
89
|
smartpipe notes.txt --as lines | smartpipe write 'copy/{name}'
|
|
90
|
+
# {name} = the source file's name, carried by __source - notes.txt becomes copy/notes.txt
|
|
88
91
|
```
|
|
89
92
|
|
|
93
|
+
The reader is zero-calls by default. A configured `ocr-model` is the one
|
|
94
|
+
exception: PDFs and images parse through it exactly as the ingesting verbs
|
|
95
|
+
would (disclosed per row; `--max-calls` caps it, and a folder of 20+
|
|
96
|
+
parseable files gets a preflight note before the first call).
|
|
97
|
+
|
|
90
98
|
## What rides along
|
|
91
99
|
|
|
92
100
|
Every item carries its provenance in the `__source` spine field (path, cut
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# The granularity ladder
|
|
2
|
+
|
|
3
|
+
Every pipe starts with one decision: **what is one item?** This page is that
|
|
4
|
+
decision, top to bottom - when each cut applies, how streams end up mixed,
|
|
5
|
+
and what the census and `strict-rows` do about it.
|
|
6
|
+
|
|
7
|
+
## The ladder
|
|
8
|
+
|
|
9
|
+
From coarsest to finest:
|
|
10
|
+
|
|
11
|
+
| Rung | One item is | You get it from |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| **file** | a whole file (its extracted text + media) | naming a path, `--as file`, redirecting one document (`< report.pdf`) |
|
|
14
|
+
| **split** | a piece of a file: a page, N tokens, N minutes/seconds | `smartpipe split --by pages/tokens/minutes/seconds` |
|
|
15
|
+
| **lines / rows** | one text line, one JSONL record, one CSV row | piping text in, `.jsonl`/`.csv` paths, `--as lines/jsonl/csv` |
|
|
16
|
+
|
|
17
|
+
Three rules pick the rung when you don't say:
|
|
18
|
+
|
|
19
|
+
1. **Paths decide the default.** `.jsonl`/`.ndjson` cut into strict records,
|
|
20
|
+
`.csv`/`.tsv` into header-named rows; every other path is one whole-file
|
|
21
|
+
item.
|
|
22
|
+
2. **stdin sniffs per line.** A line that parses as a JSON object is a
|
|
23
|
+
record; anything else is a text line. One redirected binary document is a
|
|
24
|
+
single whole-file item.
|
|
25
|
+
3. **`--as` overrides everything.** `--as file` slurps (even stdin);
|
|
26
|
+
`--as lines` keeps every line text, even lines that look like JSON;
|
|
27
|
+
`--as jsonl` demands one record per line, loudly; `--as csv` reads the
|
|
28
|
+
first line as the header.
|
|
29
|
+
|
|
30
|
+
`split` sits between file and lines: it cuts *below* the file into items
|
|
31
|
+
that remember how they were cut (each chunk carries a `__source` spine, so
|
|
32
|
+
`write` can reassemble them in order at the far end).
|
|
33
|
+
|
|
34
|
+
## When each cut applies
|
|
35
|
+
|
|
36
|
+
- **file** - the unit of meaning is the document: summarize a report,
|
|
37
|
+
caption an image, transcribe a call.
|
|
38
|
+
- **split** - one document is too big, or you want the pieces addressable
|
|
39
|
+
("page 3 says..."). Media clips cut by minutes/seconds; documents by pages
|
|
40
|
+
or tokens.
|
|
41
|
+
- **lines/rows** - the unit of meaning is the row: logs, exports, JSONL
|
|
42
|
+
datasets. This is where per-item verbs earn their keep.
|
|
43
|
+
|
|
44
|
+
## How mixing happens
|
|
45
|
+
|
|
46
|
+
Auto mode sniffs stdin per line, so a stream can come out **mixed** - some
|
|
47
|
+
records, some plain text. It happens innocently:
|
|
48
|
+
|
|
49
|
+
- a log file where some lines are JSON events and some are free text,
|
|
50
|
+
- `cat a.jsonl b.txt` gluing two kinds together,
|
|
51
|
+
- a producer that writes headers, blank-ish banners, or progress lines
|
|
52
|
+
between records.
|
|
53
|
+
|
|
54
|
+
Mixing is legal in an interactive pipe. But a verb given both kinds treats
|
|
55
|
+
them differently (a record has fields; a text line only has `text`), so
|
|
56
|
+
silence would lie. Hence the census.
|
|
57
|
+
|
|
58
|
+
## The census note
|
|
59
|
+
|
|
60
|
+
At end of stream, a mixed pipe gets exactly one stderr note:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
note: input: 812 records · 3 plain lines
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Nothing fails; the note tells you the stream wasn't what you probably
|
|
67
|
+
thought. Declare a kind to make it go away: `--as jsonl` (records) or
|
|
68
|
+
`--as lines` (text).
|
|
69
|
+
|
|
70
|
+
## strict-rows
|
|
71
|
+
|
|
72
|
+
When your pipeline *demands* one kind, make mixing an error:
|
|
73
|
+
|
|
74
|
+
- `--strict-rows` on the verb, or
|
|
75
|
+
- `SMARTPIPE_STRICT_ROWS=1` in the environment.
|
|
76
|
+
|
|
77
|
+
Strict mode fails at the **first** mixed row, naming it - before the verb
|
|
78
|
+
sees it, before any model call could spend on it:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
error: input: line 4 is a plain text line in a record stream
|
|
82
|
+
--strict-rows demands one kind - declare it: --as jsonl (records) or --as lines (text).
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Strictness also covers field misses in the free verbs: `where` errors when
|
|
86
|
+
rows have no fields for a field predicate to read, `summarize` when rows
|
|
87
|
+
lack the `by` field.
|
|
88
|
+
|
|
89
|
+
### `.sem` runs are strict by default
|
|
90
|
+
|
|
91
|
+
A script runs unattended, and unattended means loud: `smartpipe run x.sem`
|
|
92
|
+
behaves as if `--strict-rows` were set, for single-stage files and every
|
|
93
|
+
pipeline stage alike. Mixed-by-design pipelines opt out in the file:
|
|
94
|
+
|
|
95
|
+
```toml
|
|
96
|
+
verb = "split"
|
|
97
|
+
strict-rows = false
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
(per stage or top-level in pipeline files; an explicit CLI flag or
|
|
101
|
+
environment variable still wins). Interactive pipes keep the permissive
|
|
102
|
+
census note. The details live in
|
|
103
|
+
[.sem files - strict rows by default](../reference/sem-files.md#strict-rows-by-default).
|
|
104
|
+
|
|
105
|
+
## See also
|
|
106
|
+
|
|
107
|
+
- [The item](the-item.md) - the five laws behind all of this
|
|
108
|
+
- [Feeding smartpipe](feeding-smartpipe.md) - the ingestion mechanics table
|
|
109
|
+
- [split](../verbs/split.md) - cutting below the file
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
## What's a "model"?
|
|
4
4
|
|
|
5
5
|
A model is the AI that reads your instruction and produces the answer. smartpipe
|
|
6
|
-
doesn't contain one - it sends your text to a model running either
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
doesn't contain one - it sends your text to a model running either in the
|
|
7
|
+
**cloud** (OpenAI, Anthropic, or any compatible service) or **locally** (on
|
|
8
|
+
your machine, via Ollama). You choose which; smartpipe just talks to it.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Cloud vs. local
|
|
11
11
|
|
|
12
|
-
| | Local (Ollama) |
|
|
12
|
+
| | Cloud | Local (Ollama) |
|
|
13
13
|
|---|---|---|
|
|
14
|
-
| Cost |
|
|
15
|
-
| Privacy |
|
|
16
|
-
| Setup |
|
|
17
|
-
| Speed / quality |
|
|
14
|
+
| Cost | Small charge per use | Free |
|
|
15
|
+
| Privacy | Text and supported media go to the provider | Nothing leaves your machine when Ollama is local |
|
|
16
|
+
| Setup | Log in with ChatGPT, or get an API key | Install Ollama, pull a model |
|
|
17
|
+
| Speed / quality | Usually faster and stronger | Depends on your hardware |
|
|
18
18
|
|
|
19
19
|
With no configured chat model, smartpipe tries local Ollama first. If it finds a
|
|
20
20
|
non-embedding model, it uses that model and prints the exact `ollama/...` name.
|
|
@@ -23,7 +23,7 @@ If no model is configured and no usable Ollama model is found, smartpipe stops w
|
|
|
23
23
|
a setup screen. It does not silently fall through to a cloud provider just because
|
|
24
24
|
a key or login exists.
|
|
25
25
|
|
|
26
|
-
Once you choose a cloud model
|
|
26
|
+
Once you choose a cloud model or ChatGPT login path, the relevant item data
|
|
27
27
|
for that run goes to that provider. That is an explicit provider choice, not a hidden
|
|
28
28
|
fallback.
|
|
29
29
|
|
|
@@ -142,40 +142,39 @@ Example: the table floors Gemini at 128k, but the probe can discover that
|
|
|
142
142
|
`SMARTPIPE_CONTEXT_TOKENS=32000` overrides everything. If an estimate is still wrong,
|
|
143
143
|
`reduce` self-corrects: a rejected chunk is split in half and retried.
|
|
144
144
|
|
|
145
|
-
##
|
|
145
|
+
## One command, one coherent setup: `smartpipe use`
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
| Profile | Chat | Embeddings | For |
|
|
151
|
-
|---|---|---|---|
|
|
152
|
-
| `openai` | gpt-5.4-mini | text-embedding-3-small | cloud preset |
|
|
153
|
-
| `gemini` | gemini-3.1-flash-lite | gemini/gemini-embedding-001 | cloud multimodal preset |
|
|
154
|
-
| `local` | ollama/gemma-4-e2b | embeddinggemma | local preset when Ollama runs on your machine |
|
|
147
|
+
`smartpipe use` stamps a COMPLETE bundle - a chat model plus the embedder
|
|
148
|
+
that pairs with it - in one command:
|
|
155
149
|
|
|
156
150
|
```bash
|
|
157
|
-
smartpipe
|
|
158
|
-
smartpipe
|
|
159
|
-
|
|
151
|
+
smartpipe use # interactive: text model, embeddings, OCR
|
|
152
|
+
smartpipe use gemini # gemini-3.1-flash-lite + gemini-embedding-001
|
|
153
|
+
smartpipe use openai # gpt-5.4-mini + text-embedding-3-small
|
|
154
|
+
smartpipe use ollama # the best installed local model + a local embedder
|
|
155
|
+
smartpipe use gpt-5.4-mini # any model ref: that model + its provider's pairing
|
|
160
156
|
```
|
|
161
157
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
A provider whose key is absent refuses with the `smartpipe auth login` fix
|
|
159
|
+
and stamps nothing - never a partial setup. Re-running `use` refreshes the
|
|
160
|
+
whole bundle, which is also the cure for a drifted config.
|
|
161
|
+
|
|
162
|
+
Cloud picks are **multimodal by default**: they stamp `allow-captions = true`,
|
|
163
|
+
so images and audio convert to text through your own model when a run needs
|
|
164
|
+
it (fractions of a cent each, every conversion disclosed per row). Picking
|
|
165
|
+
the cloud setup is the consent; the command says so. Local setups keep the
|
|
166
|
+
conservative `--allow-captions` opt-in.
|
|
168
167
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
Every save also writes a receipt at the top of `config.toml` - `# stamped
|
|
169
|
+
by: smartpipe use (…)` - so the file documents how it got that way. (Profiles
|
|
170
|
+
from older versions are retired: their keys load with one warning, are
|
|
171
|
+
ignored, and disappear on the next save.)
|
|
173
172
|
|
|
174
173
|
## Setting a default
|
|
175
174
|
|
|
176
175
|
```bash
|
|
177
|
-
smartpipe
|
|
178
|
-
smartpipe
|
|
176
|
+
smartpipe use gpt-5.4-mini # save a default (any provider: smartpipe use ollama works the same)
|
|
177
|
+
smartpipe using # see the effective settings + where each comes from
|
|
179
178
|
```
|
|
180
179
|
|
|
181
180
|
Override the default for a single command with `--model`:
|
|
@@ -193,16 +192,13 @@ When the same setting is specified more than one way, the most specific wins:
|
|
|
193
192
|
--model flag > SMARTPIPE_MODEL env var > config file > Ollama autodetect
|
|
194
193
|
```
|
|
195
194
|
|
|
196
|
-
`smartpipe
|
|
195
|
+
`smartpipe using` prints each value with its origin, so you can see which value takes effect.
|
|
197
196
|
|
|
198
197
|
## Two models: chat and embedding
|
|
199
198
|
|
|
200
199
|
Most verbs use a **chat** model. `embed` and `top_k` use a separate
|
|
201
|
-
**embedding** model, configured independently
|
|
202
|
-
|
|
203
|
-
```bash
|
|
204
|
-
smartpipe config embed-model nomic-embed-text
|
|
205
|
-
```
|
|
200
|
+
**embedding** model, configured independently - the embeddings stage of
|
|
201
|
+
`smartpipe use` sets it (or edit `embed-model` in `config.toml` directly).
|
|
206
202
|
|
|
207
203
|
## See also
|
|
208
204
|
|
|
@@ -212,7 +208,8 @@ smartpipe config embed-model nomic-embed-text
|
|
|
212
208
|
|
|
213
209
|
## The stt-model role
|
|
214
210
|
|
|
215
|
-
`
|
|
211
|
+
The `stt-model` config key (e.g. `stt-model = "openai/whisper-1"` in
|
|
212
|
+
`config.toml`) names a dedicated remote
|
|
216
213
|
transcriber. When set, it runs FIRST in the audio ladder (a configured
|
|
217
214
|
transcriber signals wanting verbatim text - LLM hearing paraphrases),
|
|
218
215
|
falling back to the LLM rung and local `whisper` on failure. It is a paid
|
|
@@ -233,7 +230,7 @@ account. Only the `openai` wire exists today; the key accepts
|
|
|
233
230
|
|
|
234
231
|
## The ocr-model role
|
|
235
232
|
|
|
236
|
-
`
|
|
233
|
+
The `ocr-model` config key - the OCR stage of `smartpipe use` sets it - names a dedicated document
|
|
237
234
|
parser. When set, ingested PDFs and images run through it instead of the
|
|
238
235
|
local extraction ladder - page markdown becomes the item text, and a
|
|
239
236
|
multi-page PDF becomes one item per page (the `__source` spine carries the
|
|
@@ -249,7 +246,7 @@ The role is provider-agnostic:
|
|
|
249
246
|
- A **mistral** ref rides the dedicated `/v1/ocr` wire (needs
|
|
250
247
|
`MISTRAL_API_KEY`; the endpoint charges per page).
|
|
251
248
|
- **Any other ref** reads pages through the normal chat-vision wire with an
|
|
252
|
-
extract-the-text framing - `
|
|
249
|
+
extract-the-text framing - `ocr-model = "ollama/llava"` is a
|
|
253
250
|
free local OCR. For PDFs on this rung, pages with a healthy text layer
|
|
254
251
|
keep their locally extracted text (zero calls); only thin, image-bearing
|
|
255
252
|
pages (scans) go through the model.
|
|
@@ -262,7 +259,8 @@ ladder with a note - never a hard stop. `--ocr-model` (per run) >
|
|
|
262
259
|
|
|
263
260
|
## The media-embed-model role
|
|
264
261
|
|
|
265
|
-
`
|
|
262
|
+
The `media-embed-model` config key (e.g. `media-embed-model =
|
|
263
|
+
"jina/jina-clip-v2"` in `config.toml`) names a JOINT
|
|
266
264
|
text+image embedder. When set, `embed` and `top_k` route media items to it
|
|
267
265
|
as pixels while text items keep using `embed-model` - and a text query can
|
|
268
266
|
rank an image corpus, because both live in the same space.
|
|
@@ -76,9 +76,15 @@ The rules that make it a real table:
|
|
|
76
76
|
- **CSV is RFC 4180** (proper quoting, CRLF line endings); **TSV** uses tabs, and
|
|
77
77
|
replaces any tab or newline inside a value with a space (a tab inside a TSV cell
|
|
78
78
|
would corrupt the columns).
|
|
79
|
-
- **`top_k` scores land last.** A `
|
|
79
|
+
- **`top_k` scores land last.** A `__score` column sorts to the right of your data,
|
|
80
80
|
where a spreadsheet reader expects it.
|
|
81
81
|
|
|
82
|
+
> **Migrating from pre-1.4:** `top_k` and `outliers` used to write `_score`
|
|
83
|
+
> (and `_rank`/`_snapshot`/`_distance`) with a single underscore. Those stamps
|
|
84
|
+
> now live in the reserved `__` namespace - update your `jq`/`sort --by`
|
|
85
|
+
> references to `__score` etc. The old spellings are still read for one
|
|
86
|
+
> release (they keep sorting last in CSV/TSV), but are no longer written.
|
|
87
|
+
|
|
82
88
|
CSV and TSV need **structured** output - there have to be named columns. Ask for
|
|
83
89
|
fields with braces or `--schema`; a plain-text prompt with `--output csv` is a
|
|
84
90
|
usage error that tells you so.
|