smartpipe-cli 1.4.0rc1__tar.gz → 1.4.0rc2__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.0rc1 → smartpipe_cli-1.4.0rc2}/CHANGELOG.md +235 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/CITATION.cff +1 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/CONTRIBUTING.md +18 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/PKG-INFO +54 -7
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/README.md +51 -5
- smartpipe_cli-1.4.0rc2/docs/assets/demo-thumb.jpg +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/concepts/feeding-smartpipe.md +36 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/concepts/models-and-providers.md +47 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/concepts/output-formats.md +25 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/concepts/pipes-and-items.md +5 -4
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/concepts/structured-output.md +40 -8
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/concepts/the-item.md +22 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/README.md +15 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/contract-extraction.md +3 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/customer-feedback.md +6 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/live-monitoring.md +1 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/log-triage.md +1 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/meeting-digest.md +2 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/ranking-documents.md +1 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/training-data-prep.md +1 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/visualizing-results.md +3 -3
- smartpipe_cli-1.4.0rc2/docs/demo/index.html +26 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/index.md +24 -2
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/inputs/files.md +6 -0
- smartpipe_cli-1.4.0rc2/docs/install.md +94 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/learn/1-first-pipeline.md +8 -5
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/learn/2-structured-data.md +39 -6
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/learn/3-files-and-media.md +3 -2
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/reference/cli.md +37 -6
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/reference/sem-files.md +43 -28
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/troubleshooting.md +11 -12
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/embed.md +23 -4
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/extend.md +5 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/map.md +8 -5
- smartpipe_cli-1.4.0rc2/docs/verbs/readable.md +53 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/sort.md +6 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/split.md +7 -6
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/summarize.md +2 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/top-k.md +12 -4
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/where.md +6 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/mkdocs.yml +15 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/pyproject.toml +8 -2
- smartpipe_cli-1.4.0rc2/qa/fixtures/README.md +7 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/chart_cmd.py +15 -5
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/cluster_cmd.py +1 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/config_cmd.py +564 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/doctor_cmd.py +10 -8
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/embed_cmd.py +17 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/extend_cmd.py +4 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/filter_cmd.py +10 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/graph_cmd.py +185 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/input_options.py +15 -2
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/map_cmd.py +4 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/probe_cmd.py +18 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/read_cmd.py +4 -2
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/readable_cmd.py +20 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/reduce_cmd.py +4 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/root.py +18 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/run_cmd.py +3 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/schema_cmd.py +8 -8
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/schema_workshop.py +318 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/screens.py +50 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/sem_file.py +14 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/top_k_cmd.py +17 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/cli/update_cmd.py +103 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/write_cmd.py +1 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/config/picker.py +353 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/config/state_cache.py +128 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/config/store.py +12 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/container.py +106 -4
- smartpipe_cli-1.4.0rc2/src/smartpipe/core/install_channel.py +60 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/core/versions.py +87 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/chart.py +234 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/graphkg.py +484 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/graphout.py +513 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/predicate.py +19 -3
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/preview.py +120 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/progressbar.py +68 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/prompts.py +203 -21
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/repair.py +137 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/schema.py +171 -11
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/schema_dsl.py +20 -4
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/schema_repl.py +421 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/engine/temporal.py +166 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/timebin.py +2 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/io/arrow_menu.py +198 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/io/csvrows.py +174 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/inputs.py +1 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/items.py +54 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/metering.py +3 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/io/preview.py +296 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/progress.py +45 -33
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/readers.py +320 -29
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/render.py +20 -15
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/tty.py +1 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/io/update_check.py +214 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/writers.py +18 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/anthropic_adapter.py +9 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/budget.py +34 -1
- smartpipe_cli-1.4.0rc2/src/smartpipe/models/catalogs.py +134 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/models/local_ner.py +299 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/models/ocr.py +218 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/openai_codex.py +9 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/parsing/detect.py +15 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/chart.py +58 -15
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/common.py +85 -12
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/convert.py +14 -2
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/embed.py +61 -10
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/extend.py +11 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/filter.py +28 -8
- smartpipe_cli-1.4.0rc2/src/smartpipe/verbs/graph.py +492 -0
- smartpipe_cli-1.4.0rc2/src/smartpipe/verbs/graphfull.py +614 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/map.py +26 -10
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/oversize.py +14 -6
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/readable.py +11 -1
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/reduce.py +52 -23
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/sortverb.py +22 -3
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/top_k.py +112 -15
- smartpipe_cli-1.4.0rc1/docs/assets/demo-thumb.jpg +0 -0
- smartpipe_cli-1.4.0rc1/docs/demo/index.html +0 -24
- smartpipe_cli-1.4.0rc1/docs/install.md +0 -68
- smartpipe_cli-1.4.0rc1/src/smartpipe/cli/config_cmd.py +0 -338
- smartpipe_cli-1.4.0rc1/src/smartpipe/engine/chart.py +0 -143
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/.gitignore +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/LICENSE +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/NOTICE +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/README.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/Main.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/Root.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/components/Background.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/components/Caption.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/components/FileGlyph.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/components/SceneFrame.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/components/Terminal.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/components/Wordmark.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/config.ts +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/font.ts +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/index.ts +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/scenes/Close.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/scenes/ColdOpen.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/scenes/CostHonesty.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/scenes/Hook.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/scenes/Multimodal.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/demo/video/src/scenes/Scale.tsx +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/comparison.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/invoice-reconciliation.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/stream-enrichment.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/cookbook/video-qa.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/learn/4-free-verbs.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/learn/5-scale-and-cost.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/learn/6-pipelines-that-last.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/privacy.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/quickstart.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/reference/agents.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/reference/custom-verbs.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/cluster.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/diff.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/distinct.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/filter.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/getschema.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/join.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/outliers.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/reduce.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/docs/verbs/sample.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/qa/README.md +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/__main__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/assets/probe.png +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/assets/probe.txt +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/assets/probe.wav +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/auth_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/cache_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/cite_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/completions.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/diff_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/distinct_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/echo_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/getschema_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/interrupts.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/join_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/outliers_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/sample_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/sort_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/split_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/summarize_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/usage_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/cli/where_cmd.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/config/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/config/credentials.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/config/display.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/config/doctor.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/config/paths.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/core/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/core/errors.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/core/jsontools.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/aggregate.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/blocking.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/chunking.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/clustering.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/ranking.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/runner.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/tally.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/units.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/engine/windows.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/diagnostics.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/leaderboard.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/text.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/io/usage.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/base.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/cache.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/gemini_native.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/http_support.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/jina.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/local_embed.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/ollama.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/openai_compat.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/openai_oauth.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/resolve.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/retry.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/stt.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/models/windows.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/parsing/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/parsing/extract.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/py.typed +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/__init__.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/cluster.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/diff.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/distinct.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/getschema.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/join.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/outliers.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/sample.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/split.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/summarize.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/where.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/src/smartpipe/verbs/write.py +0 -0
- {smartpipe_cli-1.4.0rc1 → smartpipe_cli-1.4.0rc2}/tests/corpus/README.md +0 -0
|
@@ -9,7 +9,68 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
|
|
|
9
9
|
|
|
10
10
|
The identity release.
|
|
11
11
|
|
|
12
|
+
### Knowledge graphs (the highlight)
|
|
13
|
+
- **`smartpipe graph --fast` turns a corpus into a knowledge graph for
|
|
14
|
+
exactly $0.** A local zero-shot NER model (GLiNER-small over ONNX -
|
|
15
|
+
no new dependencies, no torch, a one-time ~190 MB download like the
|
|
16
|
+
local embedder) finds YOUR entity types (`--entities "person, vessel,
|
|
17
|
+
account"`), entities co-occurring in a window become weighted edges,
|
|
18
|
+
near-duplicate names fold into one node (disclosed), and every edge
|
|
19
|
+
carries its `sources` - the files, pages, and minutes where it was
|
|
20
|
+
seen. Zero model calls, pinned by test. Free transcripts (local
|
|
21
|
+
whisper) mean audio and video speech join the graph; scans and
|
|
22
|
+
images wait for the paid mode, counted out loud.
|
|
23
|
+
- **Six ways out, all deterministic**: `.graphml` (Gephi), `.dot`
|
|
24
|
+
(Graphviz), `.mmd` (Mermaid), `nodes.csv`+`edges.csv` (Neo4j/Kuzu),
|
|
25
|
+
a self-contained interactive `.html` (search, weight slider, hover
|
|
26
|
+
cards with clickable `file://` evidence links), or a trailing `/`
|
|
27
|
+
for an Obsidian vault of wikilinked entity notes.
|
|
28
|
+
- **A focus prompt buys named relations.** `smartpipe graph "people,
|
|
29
|
+
orgs, and money flows" case/**/*` extracts typed triples per chunk
|
|
30
|
+
through the full multimodal ladders - vision, OCR, native video -
|
|
31
|
+
with `--entities`/`--relations` compiling to enums when you want a
|
|
32
|
+
strict ontology. The cost plan prints BEFORE any spend (`~810
|
|
33
|
+
extraction calls; belt is 500 - the graph will be partial`), a
|
|
34
|
+
terminal decline exits clean at zero calls, and a belted run drains
|
|
35
|
+
to a valid partial graph at exit 1, never a fake success.
|
|
36
|
+
- **The hybrid ladder: `--name-top 200`.** The free pass finds the
|
|
37
|
+
candidates; the model names only the strongest links - one call per
|
|
38
|
+
edge, and if the belt runs out the remainder keeps its honest
|
|
39
|
+
`co-occurs` label, disclosed. Free graph in seconds; name the top
|
|
40
|
+
edges for cents.
|
|
41
|
+
- **Bring your own edges.** Records with `{source, target}` or
|
|
42
|
+
`{subject, relation, object}` on stdin skip extraction entirely -
|
|
43
|
+
canonicalize, fold, serialize. Your own `extend` pipeline is the
|
|
44
|
+
power path.
|
|
45
|
+
|
|
12
46
|
### The item — one law for everything in a pipe
|
|
47
|
+
- **Dates are a type, and they come back ISO.** `{due date}` and
|
|
48
|
+
`{ts datetime}` join the brace grammar. However the model phrases it
|
|
49
|
+
("Jan 15, 2026", "15/01/2026"), the field canonicalizes to
|
|
50
|
+
`YYYY-MM-DD` / full ISO-8601 - offsets preserved, never invented;
|
|
51
|
+
genuinely ambiguous slash-dates read month-first and say so on
|
|
52
|
+
stderr. Downstream just works: `where 'due >= "2026-01-01"'`
|
|
53
|
+
compares temporally, `sort --by due` orders by instant, and
|
|
54
|
+
`summarize 'count() by bin(due, 1d)'` buckets date-only values.
|
|
55
|
+
- **The model sees your data framed, not dumped.** Every item payload
|
|
56
|
+
now arrives inside an `<input>` fence - records rendered as clean
|
|
57
|
+
YAML-ish (the `__` plumbing excluded), text as itself. The
|
|
58
|
+
instruction can no longer blur into the data, and the fence is the
|
|
59
|
+
foundation the planned request-batching builds on.
|
|
60
|
+
- **CSV is a first-class row format.** `--as csv` (and `.csv`/`.tsv`
|
|
61
|
+
extension defaults - tab dialect for `.tsv`) reads the header row as
|
|
62
|
+
field names and streams every data row as a record, with per-cell
|
|
63
|
+
int → float → string coercion and multi-line quoted cells handled. A
|
|
64
|
+
ragged row is a loud error naming the file and physical line; rows
|
|
65
|
+
carry `__source {"as": "csv", "line": N}`. Works on stdin too, and
|
|
66
|
+
`.sem` files gain the `as` key.
|
|
67
|
+
- **Malformed model replies repair for free before they cost money.**
|
|
68
|
+
A structured reply that fails to parse now passes through a
|
|
69
|
+
deterministic fixer first - code fences, JSON-island extraction,
|
|
70
|
+
Python-repr literals, trailing commas, quote fixes, all validated by
|
|
71
|
+
an actual parse - and only escalates to the paid model-repair round
|
|
72
|
+
trip when that fails. Disclosed once per run:
|
|
73
|
+
`note: N replies repaired deterministically (fences/commas/quotes)`.
|
|
13
74
|
- **The `__` metadata spine.** Tool metadata lives in a reserved
|
|
14
75
|
double-underscore namespace that rides every record: `__source` (path plus
|
|
15
76
|
HOW the item was cut - file, lines, jsonl, pages, minutes, segment index),
|
|
@@ -70,12 +131,182 @@ The identity release.
|
|
|
70
131
|
model calls. Verb tables mark the free rungs.
|
|
71
132
|
|
|
72
133
|
### The terminal behaves
|
|
134
|
+
- **A real progress bar.** When the total is knowable (file lists), the
|
|
135
|
+
status line becomes `[██████░░░░░░░░░] 41% · 205/500 · 12/s · ~25s
|
|
136
|
+
left` - fill and percent truncate so 100% is earned, the ETA appears
|
|
137
|
+
once the first item completes, ASCII terminals get `[=====>....]`,
|
|
138
|
+
and multi-stage runs prefix the stage name. Streams keep the
|
|
139
|
+
count-and-rate line: a `tail -f` has no percent.
|
|
140
|
+
- **Braces extract lists of objects.** `{events {name string, when
|
|
141
|
+
date, severity enum(low, high)}[]}` pulls every event out of an item
|
|
142
|
+
in one call, typed and validated - inner dates still canonicalize to
|
|
143
|
+
ISO, `--explode events` turns the list into one row each. One level
|
|
144
|
+
deep by design; deeper nesting faults free at parse time with the
|
|
145
|
+
two-pass hint.
|
|
73
146
|
- Result writes pause/erase/redraw the status line under an arbiter - the
|
|
74
147
|
spinner can never interleave with output again. Only the final pipe stage
|
|
75
148
|
(stdout a TTY) animates; mid-pipe stages stay line-atomic.
|
|
76
149
|
- Records render at the TTY as YAML-ish blocks. The welcome screen links
|
|
77
150
|
docs, cookbook, and issues. The wizard offers to install shell
|
|
78
151
|
completions (consented, idempotent).
|
|
152
|
+
- **`chart` re-platformed: plotext draws the terminal, matplotlib renders
|
|
153
|
+
`--save`.** TTY bars get color (cyan bars, green time-series); piped or
|
|
154
|
+
`NO_COLOR` output keeps the plain-ASCII contract byte-for-byte. `--save`
|
|
155
|
+
now writes SVG or PNG by extension (identity-styled, deterministic
|
|
156
|
+
output); svgwrite - unmaintained since 2022 - leaves the tree. Both
|
|
157
|
+
libraries ship in core per the no-extras rule; imports stay
|
|
158
|
+
function-local so startup holds. The run receipt now reads
|
|
159
|
+
`run: ↑40 ↓25 tok` (arrows for in/out). The wizard validates model names
|
|
160
|
+
before saving (two strikes, then a typed fault), prints completions
|
|
161
|
+
before the paste-bait "Try it" line, prefers a sensible local default
|
|
162
|
+
over alphabetical luck (cloud tags compete equally), and speaks in the
|
|
163
|
+
same color voice as the other commands with a menu of detected local
|
|
164
|
+
tags and provider-prefixed cloud examples.
|
|
165
|
+
- **Docs bug, live-caught: `cluster | chart` drew flat bars.** The summary
|
|
166
|
+
rows are one-per-cluster, so charting them counts every theme once. The
|
|
167
|
+
README quick-tour step, the `cluster` help epilog, and the `.sem`
|
|
168
|
+
pipeline example now route `cluster --explode members` into
|
|
169
|
+
`chart cluster --top 8`, which draws real sizes.
|
|
170
|
+
|
|
171
|
+
### Every example, run for real
|
|
172
|
+
- **`map` and `extend` records finally carry their provenance.** The
|
|
173
|
+
`__source` spine - the law said it rides every record - was being
|
|
174
|
+
dropped by braces extraction: a reader-stamped row went in with
|
|
175
|
+
`{"path", "as", "line"}` and came out with only the extracted fields.
|
|
176
|
+
Every record leaving `map`/`extend` now carries `__source` (incoming
|
|
177
|
+
spines adopted verbatim, fresh ones stamped from the item's
|
|
178
|
+
provenance), which also means the terminal preview now shows the dim
|
|
179
|
+
file-and-line origin under each block. `--bare` still strips it.
|
|
180
|
+
- **Docs truth sweep** (owner-reported): four `echo "... $1250"`
|
|
181
|
+
examples silently shell-expanded to "250" - single-quoted; text files
|
|
182
|
+
are declared one-item-per-line at first use; "everything outside the
|
|
183
|
+
braces is the instruction" stated wherever braces are taught; typed
|
|
184
|
+
braces are the norm across the examples; the playground corpus is
|
|
185
|
+
linked from README, docs home, and the cookbook; the demo video plays
|
|
186
|
+
on the docs front page.
|
|
187
|
+
- **Row cuts keep their rows through `filter` and `top_k`.** The grep-l
|
|
188
|
+
contract (match whole files, get paths back) leaked onto `--as jsonl` /
|
|
189
|
+
`--as lines` rows read from a positional file: every matching ROW came
|
|
190
|
+
out as the filename. Both verbs now key path-back on the whole-file cut;
|
|
191
|
+
rows pass through as records. Found by a zero-context agent driving
|
|
192
|
+
smartpipe purely from SKILL.md; pinned in tests both ways.
|
|
193
|
+
- **The docs were audited by executing them**: all 236 example blocks
|
|
194
|
+
(README, docs, SKILL files, CLI help) inventoried, statically checked,
|
|
195
|
+
and ~105 run verbatim against a generated corpus of real-format files.
|
|
196
|
+
Three code bugs surfaced and are fixed with pinning tests:
|
|
197
|
+
- **Quoted globs reach the reader.** `smartpipe 'logs/*.jsonl'` - a
|
|
198
|
+
documented form - exited 64 ("no verb"); unexpanded glob tokens now
|
|
199
|
+
route to reader mode, and an unmatched glob errs loudly.
|
|
200
|
+
- **Video is refused pre-send on wires that can't watch.** The
|
|
201
|
+
ChatGPT-login (codex) and anthropic adapters silently dropped video
|
|
202
|
+
parts and sent prompt-only requests - the model answered "no video
|
|
203
|
+
provided", no degraded note fired, and video-RAG examples embedded
|
|
204
|
+
that refusal prose as vectors. Both wires now raise before sending,
|
|
205
|
+
so the documented ladder (`degraded: … video → frames+audio`)
|
|
206
|
+
actually engages.
|
|
207
|
+
- 7 broken and 12 misleading example sites corrected against observed
|
|
208
|
+
behavior (SKILL files now run verbatim; the `.sem` key table is
|
|
209
|
+
re-derived from the runtime's own validation errors; `__score`
|
|
210
|
+
spelling; stale "oversized items are refused" claims rewritten for
|
|
211
|
+
auto-chunking).
|
|
212
|
+
|
|
213
|
+
### The terminal shows your media
|
|
214
|
+
- **Every block at the terminal gets a number.** The human view opens
|
|
215
|
+
each record block with a cyan `#N` - so "look at object 5" is a thing
|
|
216
|
+
you can say. The ordinal is the one handle every output is guaranteed
|
|
217
|
+
to have (provenance can repeat across rows - fifty pages of one PDF
|
|
218
|
+
share a path - or be absent on plain text). Display only: piped
|
|
219
|
+
output is byte-identical.
|
|
220
|
+
- **Media previews at the human view.** At a terminal (and through
|
|
221
|
+
`readable`), the first media part of an item now renders under its
|
|
222
|
+
summary line: images as color thumbnails, video as a three-frame strip
|
|
223
|
+
sampled at 10/50/90% of its duration (never frame zero - intros are
|
|
224
|
+
black), audio as a peak-envelope waveform. Audio and video that still
|
|
225
|
+
live on disk get a clickable `▶ play (0:42, 2.1 MB)` link (OSC 8 -
|
|
226
|
+
opens your system player in iTerm2/kitty/WezTerm/Ghostty/Windows
|
|
227
|
+
Terminal). Piped output, JSONL, NO_COLOR, and `--bare` are
|
|
228
|
+
byte-identical to before - previews exist only where a human is
|
|
229
|
+
looking. `smartpipe config media-previews off` turns them off.
|
|
230
|
+
|
|
231
|
+
### Documents parse where they enter, vectors stay honest
|
|
232
|
+
- **The `ocr-model` role: a document parser at ingestion.** Set
|
|
233
|
+
`smartpipe config ocr-model mistral/mistral-ocr-latest` (or
|
|
234
|
+
`SMARTPIPE_OCR_MODEL`, or `--ocr-model` per run) and ingested PDFs and
|
|
235
|
+
images parse through it - one item per page on the `pages` cut,
|
|
236
|
+
markdown as the text, disclosed per row and metered as a paid
|
|
237
|
+
conversion. Mistral refs ride the dedicated `/v1/ocr` wire
|
|
238
|
+
(live-verified, whole PDFs in one call); any other model ref works as
|
|
239
|
+
chat-vision with extract-the-text framing, so `ollama/llava` is a free
|
|
240
|
+
local OCR. Parse failures fall back to the local extraction ladder,
|
|
241
|
+
disclosed, never fatal. Unset = exactly the old behavior.
|
|
242
|
+
- **The `media-embed-model` role: one joint space for pixels and prose.**
|
|
243
|
+
Text keeps `embed-model`; media routes to the joint-space model
|
|
244
|
+
(jina-clip-v2 and friends). If a run would mix two vector spaces, the
|
|
245
|
+
geometry fence stops it with exit 64 BEFORE any spend, naming both
|
|
246
|
+
models and both fixes. A text query now ranks an image corpus in the
|
|
247
|
+
joint space - that is the point.
|
|
248
|
+
- **Embed rows carry their provenance.** Output rows are now
|
|
249
|
+
`{"text", "vector", "__embedder", "__source"}` - the spine like every
|
|
250
|
+
other verb, plus the model that made the vector. `top_k` refuses a
|
|
251
|
+
corpus whose stamp disagrees with the query's embedder (the
|
|
252
|
+
same-dimensions-different-model trap), and reads old-style rows for
|
|
253
|
+
one release. Two bugs died en route: records piped from the reader
|
|
254
|
+
embedded their serialized JSON instead of their content text, and
|
|
255
|
+
`--max-calls` silently demoted pixels to captions by stripping the
|
|
256
|
+
media-embedding capability.
|
|
257
|
+
|
|
258
|
+
### Setup that reads the room
|
|
259
|
+
- **The schema workshop.** `smartpipe schema` with no arguments at a
|
|
260
|
+
terminal opens a small interactive draft loop - your schema pinned up
|
|
261
|
+
top as colored braces, commands scrolling below: `/add name type`,
|
|
262
|
+
`/drop`, `/test data.jsonl` (per-field coverage bars against your real
|
|
263
|
+
rows), `/example` (a synthetic instance), `/save` (writes schema.json
|
|
264
|
+
and prints the paste-ready braces and `--schema` lines). Zero model
|
|
265
|
+
calls by construction - iterate freely, commit when the bars are
|
|
266
|
+
green. Paste any `{braces}` string to replace the draft. Piped and
|
|
267
|
+
argument invocations are unchanged.
|
|
268
|
+
- **`smartpipe config` is now a provider-first picker.** Detect what's
|
|
269
|
+
already connected (API keys in the environment, a ChatGPT login, local
|
|
270
|
+
Ollama), pick a provider, pick from its LIVE model catalog - arrow keys
|
|
271
|
+
on a real terminal, a numbered prompt everywhere else. Undetected
|
|
272
|
+
providers show the exact `export ..._API_KEY=` line (smartpipe never
|
|
273
|
+
prompts for or stores a key). Catalogs cache for a day; a failed fetch
|
|
274
|
+
degrades to typed input with provider-prefixed examples. Picking a
|
|
275
|
+
provider auto-pairs a coherent embedding model (announced, and never
|
|
276
|
+
overwrites one you chose yourself), and one y/N question adds a backup
|
|
277
|
+
`fallback-model` for provider outages. After a `doctor --probe`,
|
|
278
|
+
catalog entries carry capability chips (`sees, hears - probed 2d ago`)
|
|
279
|
+
- probed facts, never claims. All the setter subcommands still work.
|
|
280
|
+
|
|
281
|
+
### Getting it and keeping it current
|
|
282
|
+
- **One-line install on every platform.**
|
|
283
|
+
`curl -LsSf https://prabal-rje.github.io/smartpipe/install.sh | sh`
|
|
284
|
+
(macOS/Linux) and the `install.ps1` analog for Windows PowerShell, both
|
|
285
|
+
published at the docs-site root. The script uses Homebrew when present,
|
|
286
|
+
otherwise bootstraps uv and runs `uv tool install smartpipe-cli`;
|
|
287
|
+
`SMARTPIPE_VERSION` pins a version; it ends with a loud
|
|
288
|
+
`smartpipe --version` verify. brew/uv/pipx/pip remain as explicit
|
|
289
|
+
alternatives.
|
|
290
|
+
- **The installers survive the real world.** Rerunning the one-liner
|
|
291
|
+
upgrades in place instead of erroring (brew-, uv-, and
|
|
292
|
+
otherwise-managed installs each get the right move); the uv bootstrap
|
|
293
|
+
falls back to `wget` when `curl` is missing; Alpine/musl systems get
|
|
294
|
+
a wheels warning before anything installs; Rosetta-translated macOS
|
|
295
|
+
shells get an arch hint; GitHub Actions runners get `~/.local/bin`
|
|
296
|
+
appended to `GITHUB_PATH`. Footguns adopted from studying opencode's
|
|
297
|
+
installer. `install.sh` stays readable POSIX sh at 96 lines.
|
|
298
|
+
- **`smartpipe update`.** Detects how smartpipe was installed (homebrew,
|
|
299
|
+
uv tool, pipx, or pip - fingerprinted from the executable path), shows
|
|
300
|
+
the exact upgrade command, asks consent (`--yes` skips), runs it, and
|
|
301
|
+
reports honestly. Unrecognized installs get the per-channel commands
|
|
302
|
+
instead of a guess.
|
|
303
|
+
- **A calm update notice.** At most once a day smartpipe checks PyPI in a
|
|
304
|
+
background thread (2 s cap, silent on any failure) and - on a later
|
|
305
|
+
run, at a terminal, never in CI, never on stdout - prints one dim line:
|
|
306
|
+
`note: smartpipe X.Y.Z is available (you have A.B.C) - run: smartpipe
|
|
307
|
+
update`. Rc users aren't nagged about older stables. Off switches:
|
|
308
|
+
`SMARTPIPE_NO_UPDATE_CHECK=1` or `smartpipe config update-check off`.
|
|
309
|
+
The welcome screen's utility list now includes `update`.
|
|
79
310
|
|
|
80
311
|
### Docs: a shape, not a pile
|
|
81
312
|
- New Learn track (`docs/learn/1…6`), `concepts/the-item.md` (the five
|
|
@@ -435,6 +666,10 @@ estimated dollars.
|
|
|
435
666
|
live-caught). `doctor` now closes with a bold yellow pointer at `--probe`.
|
|
436
667
|
Also fixed live: streaming `embed` emitted the pre-conversion item text
|
|
437
668
|
(empty for media), so records now carry the text the vector actually means.
|
|
669
|
+
And the streaming path (piped stdin) skipped the native media route
|
|
670
|
+
entirely - image-only items caption-pivoted even on jina-clip while the
|
|
671
|
+
finite-corpus branch embedded pixels. Both branches now share one router
|
|
672
|
+
(live-verified: `dims: 1024` from jina-clip-v2 on a piped image).
|
|
438
673
|
- **Gemini watches video natively (D34).** Gemini chat moved to Google's
|
|
439
674
|
native `:generateContent` wire — the only wired endpoint with video input.
|
|
440
675
|
`map "what happens?" --in demo.mp4 --model gemini-2.5-flash` sends the
|
|
@@ -44,6 +44,24 @@ Optional but recommended: `uv run pre-commit install` wires ruff into your commi
|
|
|
44
44
|
|
|
45
45
|
Release ritual: [RELEASING.md](RELEASING.md) · upkeep: [MAINTENANCE.md](MAINTENANCE.md).
|
|
46
46
|
|
|
47
|
+
## Docs search (Algolia DocSearch)
|
|
48
|
+
|
|
49
|
+
The site is pre-wired for [DocSearch](https://docsearch.algolia.com/) but ships
|
|
50
|
+
with it OFF: `extra.algolia` in `mkdocs.yml` holds three empty strings, and
|
|
51
|
+
while any of them is empty `overrides/main.html` renders nothing extra -
|
|
52
|
+
mkdocs-material's built-in search keeps working. To activate once the
|
|
53
|
+
DocSearch application is approved:
|
|
54
|
+
|
|
55
|
+
1. Put the credentials Algolia sends into `mkdocs.yml` → `extra.algolia`
|
|
56
|
+
(`app_id`, `index_name`, and the **search-only** public `api_key` - that
|
|
57
|
+
key is safe to commit; never the admin key).
|
|
58
|
+
2. `make docs-check` - the strict build must stay green.
|
|
59
|
+
3. Open the built site and confirm the DocSearch button replaced the
|
|
60
|
+
built-in search box (the override hides `.md-search` and mounts
|
|
61
|
+
docsearch.js v3 in the header).
|
|
62
|
+
|
|
63
|
+
Reverting to built-in search is emptying the three values again.
|
|
64
|
+
|
|
47
65
|
## New dependencies
|
|
48
66
|
|
|
49
67
|
Core install weight is a feature: the runtime dependency list is `click`, `httpx`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: smartpipe-cli
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.0rc2
|
|
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
|
|
@@ -28,9 +28,10 @@ Requires-Dist: httpx>=0.27
|
|
|
28
28
|
Requires-Dist: imageio-ffmpeg>=0.5
|
|
29
29
|
Requires-Dist: jsonschema>=4.23
|
|
30
30
|
Requires-Dist: markitdown[docx,pdf,pptx,xlsx]>=0.1.6; python_version < '3.14'
|
|
31
|
+
Requires-Dist: matplotlib>=3.8
|
|
31
32
|
Requires-Dist: pdfminer-six>=20231228
|
|
33
|
+
Requires-Dist: plotext>=5
|
|
32
34
|
Requires-Dist: pypdf>=5.0
|
|
33
|
-
Requires-Dist: svgwrite>=1.4
|
|
34
35
|
Requires-Dist: tomli-w>=1.0
|
|
35
36
|
Description-Content-Type: text/markdown
|
|
36
37
|
|
|
@@ -47,17 +48,43 @@ Description-Content-Type: text/markdown
|
|
|
47
48
|
Run PDFs, images, audio, video, and text through Unix verbs that understand
|
|
48
49
|
their input.
|
|
49
50
|
|
|
50
|
-
[](https://prabal-rje.github.io/smartpipe/demo/)
|
|
51
52
|
|
|
52
53
|
*[▶ Watch the full 70-second demo](https://prabal-rje.github.io/smartpipe/demo/) - sound, controls, no download.*
|
|
53
54
|
|
|
54
55
|
## Install
|
|
55
56
|
|
|
57
|
+
**macOS** - Homebrew is the happy path:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
brew install prabal-rje/tap/smartpipe
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Linux** - one line (uses Homebrew if you have it, bootstraps uv otherwise;
|
|
64
|
+
works on macOS too):
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
curl -LsSf https://prabal-rje.github.io/smartpipe/install.sh | sh
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Windows**:
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
powershell -ExecutionPolicy Bypass -c "irm https://prabal-rje.github.io/smartpipe/install.ps1 | iex"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Prefer your own Python tooling? Any of these works on every platform:
|
|
77
|
+
|
|
56
78
|
```bash
|
|
57
|
-
|
|
58
|
-
|
|
79
|
+
uv tool install smartpipe-cli # uv
|
|
80
|
+
pipx install smartpipe-cli # pipx
|
|
81
|
+
pip install smartpipe-cli # pip
|
|
82
|
+
uvx --from smartpipe-cli smartpipe # zero-install trial
|
|
59
83
|
```
|
|
60
84
|
|
|
85
|
+
Stay current with `smartpipe update` - it detects how smartpipe was installed
|
|
86
|
+
and runs that tool's own upgrade.
|
|
87
|
+
|
|
61
88
|
## Point it at a model
|
|
62
89
|
|
|
63
90
|
```bash
|
|
@@ -146,8 +173,8 @@ cat tickets.jsonl \
|
|
|
146
173
|
|
|
147
174
|
# 4. group feedback by meaning, label each theme, chart it
|
|
148
175
|
cat feedback.txt \
|
|
149
|
-
| smartpipe cluster --
|
|
150
|
-
| smartpipe chart cluster --save themes.svg
|
|
176
|
+
| smartpipe cluster --explode members \
|
|
177
|
+
| smartpipe chart cluster --top 8 --save themes.svg
|
|
151
178
|
|
|
152
179
|
# 5. cut for free with `where`, then let the model judge only what is left
|
|
153
180
|
cat app.log \
|
|
@@ -167,6 +194,10 @@ smartpipe embed 'sessions/**/*.mp4' > sessions.embeddings
|
|
|
167
194
|
smartpipe top_k 3 --near "user gives up after the coupon fails" < sessions.embeddings
|
|
168
195
|
```
|
|
169
196
|
|
|
197
|
+
A `.txt` on a pipe arrives one item per line; `--as file` treats the whole
|
|
198
|
+
file as one item ([feeding smartpipe](docs/concepts/feeding-smartpipe.md) has
|
|
199
|
+
the full ingestion table).
|
|
200
|
+
|
|
170
201
|
Numbers 7 and 8 are full recipes -
|
|
171
202
|
[invoice reconciliation](docs/cookbook/invoice-reconciliation.md) and
|
|
172
203
|
[video RAG](docs/cookbook/video-qa.md) - two of a dozen in the
|
|
@@ -175,6 +206,21 @@ Numbers 7 and 8 are full recipes -
|
|
|
175
206
|
New to this? The [Learn track][quickstart] starts at zero and assumes nothing, including
|
|
176
207
|
what a "model" is.
|
|
177
208
|
|
|
209
|
+
## Try it on real files
|
|
210
|
+
|
|
211
|
+
No corpus handy? [smartpipe-playground][playground] ships 26 MB of CC0 /
|
|
212
|
+
public-domain practice files - invoices, reports, photos, recordings, screen
|
|
213
|
+
sessions, and JSONL data:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
curl -L https://github.com/prabal-rje/smartpipe-playground/archive/refs/tags/v1.tar.gz | tar xz
|
|
217
|
+
cd smartpipe-playground-1
|
|
218
|
+
|
|
219
|
+
smartpipe map "Extract {vendor, invoice_number, total number}" 'invoices/*.pdf'
|
|
220
|
+
smartpipe filter "the customer sounds frustrated" 'recordings/*.mp3'
|
|
221
|
+
smartpipe top_k 3 --near "supply chain risk" 'reports/*.pdf'
|
|
222
|
+
```
|
|
223
|
+
|
|
178
224
|
## For AI agents
|
|
179
225
|
|
|
180
226
|
Driving smartpipe from an agent? [SKILL.md](SKILL.md) is the operating
|
|
@@ -245,6 +291,7 @@ lives in [`qa/`](qa/README.md). The CLI surface is a SemVer contract.
|
|
|
245
291
|
[models]: https://prabal-rje.github.io/smartpipe/concepts/models-and-providers/
|
|
246
292
|
[privacy]: https://prabal-rje.github.io/smartpipe/privacy/
|
|
247
293
|
[ollama]: https://ollama.com
|
|
294
|
+
[playground]: https://github.com/prabal-rje/smartpipe-playground
|
|
248
295
|
[map]: https://prabal-rje.github.io/smartpipe/verbs/map/
|
|
249
296
|
[extend]: https://prabal-rje.github.io/smartpipe/verbs/extend/
|
|
250
297
|
[filter]: https://prabal-rje.github.io/smartpipe/verbs/filter/
|
|
@@ -11,17 +11,43 @@
|
|
|
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 70-second demo](https://prabal-rje.github.io/smartpipe/demo/) - sound, controls, no download.*
|
|
17
17
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
20
|
+
**macOS** - Homebrew is the happy path:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
brew install prabal-rje/tap/smartpipe
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Linux** - one line (uses Homebrew if you have it, bootstraps uv otherwise;
|
|
27
|
+
works on macOS too):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
curl -LsSf https://prabal-rje.github.io/smartpipe/install.sh | sh
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Windows**:
|
|
34
|
+
|
|
35
|
+
```powershell
|
|
36
|
+
powershell -ExecutionPolicy Bypass -c "irm https://prabal-rje.github.io/smartpipe/install.ps1 | iex"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Prefer your own Python tooling? Any of these works on every platform:
|
|
40
|
+
|
|
20
41
|
```bash
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
uv tool install smartpipe-cli # uv
|
|
43
|
+
pipx install smartpipe-cli # pipx
|
|
44
|
+
pip install smartpipe-cli # pip
|
|
45
|
+
uvx --from smartpipe-cli smartpipe # zero-install trial
|
|
23
46
|
```
|
|
24
47
|
|
|
48
|
+
Stay current with `smartpipe update` - it detects how smartpipe was installed
|
|
49
|
+
and runs that tool's own upgrade.
|
|
50
|
+
|
|
25
51
|
## Point it at a model
|
|
26
52
|
|
|
27
53
|
```bash
|
|
@@ -110,8 +136,8 @@ cat tickets.jsonl \
|
|
|
110
136
|
|
|
111
137
|
# 4. group feedback by meaning, label each theme, chart it
|
|
112
138
|
cat feedback.txt \
|
|
113
|
-
| smartpipe cluster --
|
|
114
|
-
| smartpipe chart cluster --save themes.svg
|
|
139
|
+
| smartpipe cluster --explode members \
|
|
140
|
+
| smartpipe chart cluster --top 8 --save themes.svg
|
|
115
141
|
|
|
116
142
|
# 5. cut for free with `where`, then let the model judge only what is left
|
|
117
143
|
cat app.log \
|
|
@@ -131,6 +157,10 @@ smartpipe embed 'sessions/**/*.mp4' > sessions.embeddings
|
|
|
131
157
|
smartpipe top_k 3 --near "user gives up after the coupon fails" < sessions.embeddings
|
|
132
158
|
```
|
|
133
159
|
|
|
160
|
+
A `.txt` on a pipe arrives one item per line; `--as file` treats the whole
|
|
161
|
+
file as one item ([feeding smartpipe](docs/concepts/feeding-smartpipe.md) has
|
|
162
|
+
the full ingestion table).
|
|
163
|
+
|
|
134
164
|
Numbers 7 and 8 are full recipes -
|
|
135
165
|
[invoice reconciliation](docs/cookbook/invoice-reconciliation.md) and
|
|
136
166
|
[video RAG](docs/cookbook/video-qa.md) - two of a dozen in the
|
|
@@ -139,6 +169,21 @@ Numbers 7 and 8 are full recipes -
|
|
|
139
169
|
New to this? The [Learn track][quickstart] starts at zero and assumes nothing, including
|
|
140
170
|
what a "model" is.
|
|
141
171
|
|
|
172
|
+
## Try it on real files
|
|
173
|
+
|
|
174
|
+
No corpus handy? [smartpipe-playground][playground] ships 26 MB of CC0 /
|
|
175
|
+
public-domain practice files - invoices, reports, photos, recordings, screen
|
|
176
|
+
sessions, and JSONL data:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
curl -L https://github.com/prabal-rje/smartpipe-playground/archive/refs/tags/v1.tar.gz | tar xz
|
|
180
|
+
cd smartpipe-playground-1
|
|
181
|
+
|
|
182
|
+
smartpipe map "Extract {vendor, invoice_number, total number}" 'invoices/*.pdf'
|
|
183
|
+
smartpipe filter "the customer sounds frustrated" 'recordings/*.mp3'
|
|
184
|
+
smartpipe top_k 3 --near "supply chain risk" 'reports/*.pdf'
|
|
185
|
+
```
|
|
186
|
+
|
|
142
187
|
## For AI agents
|
|
143
188
|
|
|
144
189
|
Driving smartpipe from an agent? [SKILL.md](SKILL.md) is the operating
|
|
@@ -209,6 +254,7 @@ lives in [`qa/`](qa/README.md). The CLI surface is a SemVer contract.
|
|
|
209
254
|
[models]: https://prabal-rje.github.io/smartpipe/concepts/models-and-providers/
|
|
210
255
|
[privacy]: https://prabal-rje.github.io/smartpipe/privacy/
|
|
211
256
|
[ollama]: https://ollama.com
|
|
257
|
+
[playground]: https://github.com/prabal-rje/smartpipe-playground
|
|
212
258
|
[map]: https://prabal-rje.github.io/smartpipe/verbs/map/
|
|
213
259
|
[extend]: https://prabal-rje.github.io/smartpipe/verbs/extend/
|
|
214
260
|
[filter]: https://prabal-rje.github.io/smartpipe/verbs/filter/
|
|
Binary file
|
|
@@ -22,6 +22,8 @@ Files go after the prompt (quote globs). Each path's default:
|
|
|
22
22
|
|
|
23
23
|
- `.jsonl` / `.ndjson` → strict records, one per line; a bad row is a loud
|
|
24
24
|
error naming file and line.
|
|
25
|
+
- `.csv` / `.tsv` → header-named records, one per row (`.tsv` cuts on tabs);
|
|
26
|
+
see [csv rows](#csv-rows) below.
|
|
25
27
|
- everything else → one whole-file item: documents extract their text (and
|
|
26
28
|
carry embedded figures to vision models), media carry their bytes.
|
|
27
29
|
|
|
@@ -30,19 +32,50 @@ Files go after the prompt (quote globs). Each path's default:
|
|
|
30
32
|
|
|
31
33
|
## The `--as` dial
|
|
32
34
|
|
|
33
|
-
`--as file|lines|jsonl` overrides every default, stdin included:
|
|
35
|
+
`--as file|lines|jsonl|csv` overrides every default, stdin included:
|
|
34
36
|
|
|
35
37
|
```bash
|
|
36
38
|
cat poem.txt | smartpipe map "translate, keep the shape" --as file
|
|
37
39
|
smartpipe map "translate" 'notes/*.txt' --as lines
|
|
38
40
|
smartpipe map "classify {label}" export.txt --as jsonl
|
|
41
|
+
cat export.txt | smartpipe map "classify {label}" --as csv
|
|
39
42
|
```
|
|
40
43
|
|
|
41
|
-
An explicit `--as lines`/`jsonl` must hold for EVERY matched file:
|
|
42
|
-
refuse (no finer granularity), audio/video point at `split --by
|
|
44
|
+
An explicit `--as lines`/`jsonl`/`csv` must hold for EVERY matched file:
|
|
45
|
+
images refuse (no finer granularity), audio/video point at `split --by
|
|
43
46
|
minutes/seconds`, documents point at `split --by pages` - with offender
|
|
44
47
|
counts, never silent partial application.
|
|
45
48
|
|
|
49
|
+
## csv rows
|
|
50
|
+
|
|
51
|
+
`--as csv` (the default for `.csv`/`.tsv` paths) reads the header row as the
|
|
52
|
+
field names and every later row as one record - `name,age` + `alice,31`
|
|
53
|
+
becomes `{"name": "alice", "age": 31}`. On stdin the header is simply the
|
|
54
|
+
first line. Rows stream one at a time, exactly like jsonl - a 10 GB export
|
|
55
|
+
never materializes in memory.
|
|
56
|
+
|
|
57
|
+
The details, all deliberate:
|
|
58
|
+
|
|
59
|
+
- **Cell coercion is int → float → string.** A cell that is a whole number
|
|
60
|
+
becomes an int (`31`), a decimal or scientific number becomes a float
|
|
61
|
+
(`2.5`, `1e3`), and anything else - empty cells included - stays the string
|
|
62
|
+
it was (`007x` keeps its leading zeros). `NaN`/`Infinity` spellings stay
|
|
63
|
+
strings; they have no JSON form.
|
|
64
|
+
- **`__source` carries the PHYSICAL line number.** The header is line 1, the
|
|
65
|
+
first data row line 2 - so `grep -n`/`sed -n` line references match the
|
|
66
|
+
file exactly. A quoted cell may span lines; such a row carries its FIRST
|
|
67
|
+
physical line.
|
|
68
|
+
- **Dialect by extension.** `.tsv` cuts on tabs, with or without an explicit
|
|
69
|
+
`--as csv`; everything else - stdin included - cuts on commas. There is no
|
|
70
|
+
delimiter sniffing beyond that: extensions are predictable, sniffers guess.
|
|
71
|
+
- **Errors are loud, jsonl-style.** A ragged row names the file, the physical
|
|
72
|
+
line, and both column counts; an empty file (or blank header cell, or
|
|
73
|
+
duplicate column name) refuses with the fix. `--as csv` on media or
|
|
74
|
+
documents refuses with the same signposts as `lines`/`jsonl`.
|
|
75
|
+
|
|
76
|
+
Egress is the mirror you already have: `--output csv` on the verbs that emit
|
|
77
|
+
records, so `csv in → csv out` round-trips.
|
|
78
|
+
|
|
46
79
|
## Reader mode
|
|
47
80
|
|
|
48
81
|
`smartpipe PATH…` with no verb emits the crate's items as JSONL records -
|
|
@@ -217,6 +217,53 @@ account. Only the `openai` wire exists today; the key accepts
|
|
|
217
217
|
`provider/model` so more can land behind the same seam.
|
|
218
218
|
|
|
219
219
|
|
|
220
|
+
## The ocr-model role
|
|
221
|
+
|
|
222
|
+
`smartpipe config ocr-model mistral-ocr-latest` names a dedicated document
|
|
223
|
+
parser. When set, ingested PDFs and images run through it instead of the
|
|
224
|
+
local extraction ladder - page markdown becomes the item text, and a
|
|
225
|
+
multi-page PDF becomes one item per page (the `__source` spine carries the
|
|
226
|
+
page cut, exactly like `split --by pages`). Setting the role is the consent;
|
|
227
|
+
every parsed page is disclosed per row:
|
|
228
|
+
|
|
229
|
+
```text
|
|
230
|
+
⚠ degraded: report.pdf p.3 document → markdown (parsed by mistral/mistral-ocr-latest)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
The role is provider-agnostic:
|
|
234
|
+
|
|
235
|
+
- A **mistral** ref rides the dedicated `/v1/ocr` wire (needs
|
|
236
|
+
`MISTRAL_API_KEY`; the endpoint charges per page).
|
|
237
|
+
- **Any other ref** reads pages through the normal chat-vision wire with an
|
|
238
|
+
extract-the-text framing - `smartpipe config ocr-model ollama/llava` is a
|
|
239
|
+
free local OCR. For PDFs on this rung, pages with a healthy text layer
|
|
240
|
+
keep their locally extracted text (zero calls); only thin, image-bearing
|
|
241
|
+
pages (scans) go through the model.
|
|
242
|
+
|
|
243
|
+
Inside the conversion ladder, a configured `ocr-model` also outranks the
|
|
244
|
+
vision-chat rung for page images, so scanned documents read as text
|
|
245
|
+
everywhere. If a parse fails, the item falls back to the local extraction
|
|
246
|
+
ladder with a note - never a hard stop. `--ocr-model` (per run) >
|
|
247
|
+
`SMARTPIPE_OCR_MODEL` > the config key. Unset: nothing changes.
|
|
248
|
+
|
|
249
|
+
## The media-embed-model role
|
|
250
|
+
|
|
251
|
+
`smartpipe config media-embed-model jina/jina-clip-v2` names a JOINT
|
|
252
|
+
text+image embedder. When set, `embed` and `top_k` route media items to it
|
|
253
|
+
as pixels while text items keep using `embed-model` - and a text query can
|
|
254
|
+
rank an image corpus, because both live in the same space.
|
|
255
|
+
|
|
256
|
+
One vector space per run is the law: if a run holds BOTH text and media
|
|
257
|
+
items while the two roles name different models, smartpipe refuses loudly
|
|
258
|
+
(vectors from two models can't be compared). The fix it names: set
|
|
259
|
+
`embed-model` to the joint model too, or feed media-only input. Unset, media
|
|
260
|
+
items keep today's behavior (native embedding when `embed-model` itself is
|
|
261
|
+
media-capable, the caption pivot otherwise).
|
|
262
|
+
|
|
263
|
+
`--media-embed-model` (per run) > `SMARTPIPE_MEDIA_EMBED_MODEL` > the config
|
|
264
|
+
key.
|
|
265
|
+
|
|
266
|
+
|
|
220
267
|
## The usage ledger
|
|
221
268
|
|
|
222
269
|
`smartpipe usage` shows what the meter observed over the past hour, day, week,
|
|
@@ -15,6 +15,31 @@ With no `--output` flag, smartpipe looks at whether `stdout` is a terminal:
|
|
|
15
15
|
So `smartpipe map "Extract {name, role}"` shows you a tidy view on screen, but the
|
|
16
16
|
moment you pipe it into `jq` or a file, it becomes clean JSONL - no flags needed.
|
|
17
17
|
|
|
18
|
+
### Media previews at the terminal
|
|
19
|
+
|
|
20
|
+
In the terminal view (and in [`readable`](../verbs/readable.md)), an item
|
|
21
|
+
carrying media gets more than its `image/png (48 KB)` summary line - the first
|
|
22
|
+
media part renders right under it:
|
|
23
|
+
|
|
24
|
+
- **Images** show a small color thumbnail (aspect preserved, about 40x12
|
|
25
|
+
cells).
|
|
26
|
+
- **Video** shows a 3-frame strip sampled at 10%/50%/90% of the duration -
|
|
27
|
+
never the first frame, which is usually a black or logo intro.
|
|
28
|
+
- **Audio** shows a waveform envelope (long files decode at most the first
|
|
29
|
+
10 minutes).
|
|
30
|
+
- **Audio and video with a real file behind them** add a
|
|
31
|
+
`▶ play (0:42, 2.1 MB)` line - an OSC 8 hyperlink to the `file://` URL, so
|
|
32
|
+
a click opens your system player. Media that exists only as pipe bytes
|
|
33
|
+
still gets its picture, just no link.
|
|
34
|
+
|
|
35
|
+
Previews exist only where the human view does: pipes, `--output json`,
|
|
36
|
+
`NO_COLOR`, and `TERM=dumb` output stay byte-for-byte what they were. The
|
|
37
|
+
persisted kill switch:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
smartpipe config media-previews off # back to summary lines only
|
|
41
|
+
```
|
|
42
|
+
|
|
18
43
|
## Explicit formats
|
|
19
44
|
|
|
20
45
|
| `--output` | What you get |
|