kash-shell 0.3.23__tar.gz → 0.3.25__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.
- {kash_shell-0.3.23 → kash_shell-0.3.25}/PKG-INFO +6 -4
- {kash_shell-0.3.23 → kash_shell-0.3.25}/README.md +2 -2
- {kash_shell-0.3.23 → kash_shell-0.3.25}/pyproject.toml +4 -1
- kash_shell-0.3.25/src/kash/actions/core/combine_docs.py +52 -0
- kash_shell-0.3.25/src/kash/actions/core/concat_docs.py +47 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/workspace/workspace_commands.py +2 -2
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/logger.py +3 -2
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/settings.py +8 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/a2_installation.md +2 -2
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/embeddings/embeddings.py +4 -6
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/embeddings/text_similarity.py +2 -5
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/action_exec.py +1 -1
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/fetch_url_items.py +36 -8
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/help_embeddings.py +3 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/llm_completion.py +1 -1
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/llm_features.py +1 -1
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/llms.py +5 -7
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/mcp_cli.py +2 -2
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/params_model.py +1 -1
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/api_utils/api_retries.py +84 -76
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/api_utils/gather_limited.py +227 -89
- kash_shell-0.3.25/src/kash/utils/api_utils/http_utils.py +46 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/api_utils/progress_protocol.py +49 -56
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/rich_custom/multitask_status.py +70 -21
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/text_handling/doc_normalization.py +2 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/text_handling/markdown_utils.py +14 -3
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/web_extract.py +12 -8
- kash_shell-0.3.25/src/kash/web_content/web_fetch.py +373 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/web_page_model.py +5 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/base_styles.css.jinja +8 -1
- {kash_shell-0.3.23 → kash_shell-0.3.25}/tests/kash/utils/api_utils/test_gather_limited.py +69 -13
- {kash_shell-0.3.23 → kash_shell-0.3.25}/tests/kash/utils/rich_custom/test_multitask_status.py +14 -11
- {kash_shell-0.3.23 → kash_shell-0.3.25}/uv.lock +388 -204
- kash_shell-0.3.23/src/kash/web_content/web_fetch.py +0 -144
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.copier-answers.yml +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.cursor/rules/general.mdc +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.cursor/rules/python.mdc +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.env.template +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.github/workflows/ci.yml +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.github/workflows/publish.yml +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/.gitignore +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/LICENSE +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/Makefile +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/development.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/devtools/generate_readme.xsh +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/devtools/lint.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/devtools/profile_main.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/installation.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/publishing.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/__main__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/assistant_chat.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/chat.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/format_markdown_template.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/markdownify_html.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/minify_html.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/readability.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/render_as_html.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/show_webpage.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/strip_html.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/summarize_as_bullets.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/core/tabbed_webpage_generate.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/meta/write_instructions.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/actions/meta/write_new_action.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/basic_file_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/browser_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/debug_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/diff_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/files_command.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/general_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/logs_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/model_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/reformat_command.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/search_command.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/base/show_command.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/extras/parse_uv_lock.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/extras/utils_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/help/assistant_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/help/doc_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/help/help_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/help/logo.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/help/welcome.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/commands/workspace/selection_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/capture_output.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/colors.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/env_settings.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/init.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/lazy_imports.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/logger_basic.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/logo.txt +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/server_config.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/setup.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/suppress_warnings.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/config/text_styles.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/all_docs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/load_actions_info.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/load_api_docs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/load_help_topics.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/load_source_code.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/api_docs_template.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/readme_template.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/a1_what_is_kash.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/b1_kash_overview.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/warning.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs/markdown/welcome.md +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/docs_base.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/load_custom_command_info.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/load_faqs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/load_recipe_snippets.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/embeddings/cosine.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/action_decorators.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/action_registry.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/combiners.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/command_exec.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/command_registry.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/history.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/importing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/llm_transforms.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/precondition_checks.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/precondition_registry.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/preconditions.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/resolve_args.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/runtime_settings.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec/shell_callable_action.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec_model/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec_model/args_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec_model/commands_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec_model/script_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/exec_model/shell_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/file_store.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/item_file_format.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/metadata_dirs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/persisted_yaml.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/store_cache_warmer.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/file_storage/store_filenames.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/assistant.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/assistant_instructions.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/assistant_output.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/function_param_info.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/help_lookups.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/help_pages.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/help_printing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/help_types.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/recommended_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/help/tldr_help.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/clean_headings.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/init_litellm.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/llm_api_keys.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/llm_messages.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/llm_utils/llm_names.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/local_server.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/local_server_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/local_server_routes.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/local_url_formatters.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/port_tools.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/local_server/rich_html_template.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/mcp_main.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/mcp_server_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/mcp_server_routes.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/mcp_server_sse.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/mcp/mcp_server_stdio.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/audio_processing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/media_cache.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/media_services.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/media_tools.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/services/local_file_media.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/timestamp_citations.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/transcription_deepgram.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/transcription_format.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/media_base/transcription_whisper.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/actions_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/assistant_response_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/compound_actions_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/concept_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/exec_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/graph_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/items_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/language_list.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/llm_actions_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/media_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/operations_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/paths_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/model/preconditions_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/completions/completion_scoring.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/completions/completion_types.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/completions/shell_completions.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/file_icons/color_for_format.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/file_icons/nerd_icons.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/input/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/input/input_prompts.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/input/inquirer_settings.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/input/param_inputs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/input/shell_confirm.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/output/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/output/kerm_code_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/output/kerm_codes.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/output/kmarkdown.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/output/shell_formatting.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/output/shell_output.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/shell_main.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/ui/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/ui/shell_results.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/ui/shell_syntax.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/utils/exception_printing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/utils/native_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/shell/version.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/api_utils/cache_requests_limited.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/format_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/function_inspect.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/import_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/lazyobject.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/obj_replace.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/parse_docstring.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/parse_key_vals.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/parse_shell_args.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/stack_traces.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/task_stack.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/testing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/type_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/uniquifier.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/url.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/common/url_slice.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/errors.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_formats/chat_format.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/dir_info.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/file_ext.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/file_formats.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/file_formats_model.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/file_walk.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/filename_parsing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/ignore_files.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/mtime_cache.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/file_utils/path_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/lang_utils/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/lang_utils/capitalization.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/rich_custom/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/rich_custom/rich_indent.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/text_handling/escape_html_tags.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/text_handling/markdown_render.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/utils/text_handling/unified_diffs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/canon_url.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/dir_store.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/file_cache_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/file_processing.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/local_file_cache.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/web_extract_justext.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_content/web_extract_readabilipy.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/simple_webpage.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/tabbed_webpage.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/template_render.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/base_webpage.html.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/components/toc_scripts.js.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/components/toc_styles.css.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/components/tooltip_scripts.js.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/components/tooltip_styles.css.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/__init__.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/param_state.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/selections.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/source_items.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/workspace_dirs.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/workspace_output.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/workspace_registry.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/workspaces/workspaces.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/custom_shell.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/customize_prompt.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/load_into_xonsh.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/shell_which.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/xonsh_env.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xontrib/fnm.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/src/kash/xontrib/kash_extension.py +0 -0
- {kash_shell-0.3.23 → kash_shell-0.3.25}/tests/test_shell.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kash-shell
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.25
|
|
4
4
|
Summary: The knowledge agent shell (core)
|
|
5
5
|
Project-URL: Repository, https://github.com/jlevy/kash-shell
|
|
6
6
|
Author-email: Joshua Levy <joshua@cal.berkeley.edu>
|
|
@@ -24,12 +24,14 @@ Requires-Dist: chopdiff>=0.2.3
|
|
|
24
24
|
Requires-Dist: clideps>=0.1.4
|
|
25
25
|
Requires-Dist: colour>=0.1.5
|
|
26
26
|
Requires-Dist: cssselect>=1.2.0
|
|
27
|
+
Requires-Dist: curl-cffi>=0.11.4
|
|
27
28
|
Requires-Dist: deepgram-sdk>=3.10.1
|
|
28
29
|
Requires-Dist: dunamai>=1.23.0
|
|
29
30
|
Requires-Dist: fastapi>=0.115.11
|
|
30
|
-
Requires-Dist: flowmark>=0.4.
|
|
31
|
+
Requires-Dist: flowmark>=0.4.8
|
|
31
32
|
Requires-Dist: frontmatter-format>=0.2.1
|
|
32
33
|
Requires-Dist: funlog>=0.2.0
|
|
34
|
+
Requires-Dist: httpx[brotli]>=0.28.1
|
|
33
35
|
Requires-Dist: humanfriendly>=10.0
|
|
34
36
|
Requires-Dist: inquirerpy>=0.3.4
|
|
35
37
|
Requires-Dist: jinja2>=3.1.6
|
|
@@ -329,7 +331,7 @@ These are for `kash-media` but you can use a `kash-shell` for a more basic setup
|
|
|
329
331
|
|
|
330
332
|
You can use kash from your MCP client (such as Anthropic Desktop or Cursor).
|
|
331
333
|
|
|
332
|
-
You do this by running the the `
|
|
334
|
+
You do this by running the the `kash-mcp` binary to make kash actions available as MCP
|
|
333
335
|
tools.
|
|
334
336
|
|
|
335
337
|
For Claude Desktop, my config looks like this:
|
|
@@ -338,7 +340,7 @@ For Claude Desktop, my config looks like this:
|
|
|
338
340
|
{
|
|
339
341
|
"mcpServers": {
|
|
340
342
|
"kash": {
|
|
341
|
-
"command": "/Users/levy/.local/bin/
|
|
343
|
+
"command": "/Users/levy/.local/bin/kash-mcp",
|
|
342
344
|
"args": ["--proxy"]
|
|
343
345
|
}
|
|
344
346
|
}
|
|
@@ -255,7 +255,7 @@ These are for `kash-media` but you can use a `kash-shell` for a more basic setup
|
|
|
255
255
|
|
|
256
256
|
You can use kash from your MCP client (such as Anthropic Desktop or Cursor).
|
|
257
257
|
|
|
258
|
-
You do this by running the the `
|
|
258
|
+
You do this by running the the `kash-mcp` binary to make kash actions available as MCP
|
|
259
259
|
tools.
|
|
260
260
|
|
|
261
261
|
For Claude Desktop, my config looks like this:
|
|
@@ -264,7 +264,7 @@ For Claude Desktop, my config looks like this:
|
|
|
264
264
|
{
|
|
265
265
|
"mcpServers": {
|
|
266
266
|
"kash": {
|
|
267
|
-
"command": "/Users/levy/.local/bin/
|
|
267
|
+
"command": "/Users/levy/.local/bin/kash-mcp",
|
|
268
268
|
"args": ["--proxy"]
|
|
269
269
|
}
|
|
270
270
|
}
|
|
@@ -45,7 +45,7 @@ dependencies = [
|
|
|
45
45
|
"strif>=3.0.1",
|
|
46
46
|
"funlog>=0.2.0",
|
|
47
47
|
"prettyfmt>=0.3.1",
|
|
48
|
-
"flowmark>=0.4.
|
|
48
|
+
"flowmark>=0.4.8",
|
|
49
49
|
"frontmatter-format>=0.2.1",
|
|
50
50
|
"chopdiff>=0.2.3",
|
|
51
51
|
"clideps>=0.1.4",
|
|
@@ -77,6 +77,9 @@ dependencies = [
|
|
|
77
77
|
"pathspec>=0.12.1",
|
|
78
78
|
"patch-ng>=1.18.1",
|
|
79
79
|
"inquirerpy>=0.3.4",
|
|
80
|
+
# HTTP clients:
|
|
81
|
+
"httpx[brotli]>=0.28.1", # Include brotli for better compression and browser fingerprint.
|
|
82
|
+
"curl-cffi>=0.11.4",
|
|
80
83
|
# LLM and API essentials:
|
|
81
84
|
"tiktoken>=0.9.0",
|
|
82
85
|
"openai>=1.66.3",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from chopdiff.html.html_in_md import div_wrapper
|
|
2
|
+
|
|
3
|
+
from kash.config.logger import get_logger
|
|
4
|
+
from kash.exec import kash_action
|
|
5
|
+
from kash.model import ONE_OR_MORE_ARGS, ActionInput, ActionResult, Param
|
|
6
|
+
from kash.utils.errors import InvalidInput
|
|
7
|
+
|
|
8
|
+
log = get_logger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@kash_action(
|
|
12
|
+
expected_args=ONE_OR_MORE_ARGS,
|
|
13
|
+
params=(
|
|
14
|
+
Param(
|
|
15
|
+
"class_name",
|
|
16
|
+
"CSS class name to use for wrapping each document in a div.",
|
|
17
|
+
type=str,
|
|
18
|
+
default_value="doc",
|
|
19
|
+
),
|
|
20
|
+
),
|
|
21
|
+
)
|
|
22
|
+
def combine_docs(input: ActionInput, class_name: str = "page") -> ActionResult:
|
|
23
|
+
"""
|
|
24
|
+
Combine multiple text items into a single document, wrapping each piece
|
|
25
|
+
in a div with the specified CSS class.
|
|
26
|
+
"""
|
|
27
|
+
items = input.items
|
|
28
|
+
|
|
29
|
+
if not items:
|
|
30
|
+
raise InvalidInput("No items provided for combination")
|
|
31
|
+
|
|
32
|
+
# Create wrapper function
|
|
33
|
+
wrapper = div_wrapper(class_name=class_name)
|
|
34
|
+
|
|
35
|
+
# Collect and wrap all bodies
|
|
36
|
+
wrapped_bodies = []
|
|
37
|
+
for item in items:
|
|
38
|
+
if not item.body:
|
|
39
|
+
raise InvalidInput(f"Item has no body: {item.store_path}")
|
|
40
|
+
wrapped_bodies.append(wrapper(item.body))
|
|
41
|
+
|
|
42
|
+
# Concatenate with double newlines
|
|
43
|
+
combined_body = "\n\n".join(wrapped_bodies)
|
|
44
|
+
|
|
45
|
+
# Create title
|
|
46
|
+
count = len(items)
|
|
47
|
+
title = f"Combined ({count} doc{'s' if count != 1 else ''})"
|
|
48
|
+
|
|
49
|
+
# Create result item based on first item
|
|
50
|
+
result_item = items[0].derived_copy(body=combined_body, title=title, original_filename=None)
|
|
51
|
+
|
|
52
|
+
return ActionResult([result_item])
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from kash.config.logger import get_logger
|
|
2
|
+
from kash.exec import kash_action
|
|
3
|
+
from kash.model import ONE_OR_MORE_ARGS, ActionInput, ActionResult, Param
|
|
4
|
+
from kash.utils.errors import InvalidInput
|
|
5
|
+
|
|
6
|
+
log = get_logger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@kash_action(
|
|
10
|
+
expected_args=ONE_OR_MORE_ARGS,
|
|
11
|
+
params=(
|
|
12
|
+
Param(
|
|
13
|
+
"separator",
|
|
14
|
+
"String to use between concatenated items.",
|
|
15
|
+
type=str,
|
|
16
|
+
default_value="\n\n",
|
|
17
|
+
),
|
|
18
|
+
),
|
|
19
|
+
)
|
|
20
|
+
def concat_docs(input: ActionInput, separator: str = "\n\n") -> ActionResult:
|
|
21
|
+
"""
|
|
22
|
+
Concatenate multiple text items into a single document with the specified
|
|
23
|
+
separator between each piece.
|
|
24
|
+
"""
|
|
25
|
+
items = input.items
|
|
26
|
+
|
|
27
|
+
if not items:
|
|
28
|
+
raise InvalidInput("No items provided for concatenation")
|
|
29
|
+
|
|
30
|
+
# Collect all bodies
|
|
31
|
+
bodies = []
|
|
32
|
+
for item in items:
|
|
33
|
+
if not item.body:
|
|
34
|
+
raise InvalidInput(f"Item has no body: {item.store_path}")
|
|
35
|
+
bodies.append(item.body)
|
|
36
|
+
|
|
37
|
+
# Concatenate with the specified separator
|
|
38
|
+
concat_body = separator.join(bodies)
|
|
39
|
+
|
|
40
|
+
# Create title
|
|
41
|
+
count = len(items)
|
|
42
|
+
title = f"Concat ({count} doc{'s' if count != 1 else ''})"
|
|
43
|
+
|
|
44
|
+
# Create result item based on first item
|
|
45
|
+
result_item = items[0].derived_copy(body=concat_body, title=title, original_filename=None)
|
|
46
|
+
|
|
47
|
+
return ActionResult([result_item])
|
|
@@ -474,8 +474,8 @@ def fetch_url(*files_or_urls: str, refetch: bool = False) -> ShellResult:
|
|
|
474
474
|
store_paths = []
|
|
475
475
|
for locator in locators:
|
|
476
476
|
try:
|
|
477
|
-
|
|
478
|
-
store_paths.append(
|
|
477
|
+
fetch_result = fetch_url_item(locator, refetch=refetch)
|
|
478
|
+
store_paths.append(fetch_result.item.store_path)
|
|
479
479
|
except InvalidInput as e:
|
|
480
480
|
log.warning(
|
|
481
481
|
"Not a URL or URL resource, will not fetch metadata: %s: %s", fmt_loc(locator), e
|
|
@@ -254,9 +254,10 @@ def _do_logging_setup(log_settings: LogSettings):
|
|
|
254
254
|
_console_handler = basic_stderr_handler(log_settings.log_console_level)
|
|
255
255
|
|
|
256
256
|
# Manually adjust logging for a few packages, removing previous verbose default handlers.
|
|
257
|
-
|
|
257
|
+
# Set root logger to most permissive level so handlers can do the filtering
|
|
258
|
+
root_level = min(log_settings.log_console_level.value, log_settings.log_file_level.value)
|
|
258
259
|
log_levels = {
|
|
259
|
-
None:
|
|
260
|
+
None: root_level,
|
|
260
261
|
"LiteLLM": INFO,
|
|
261
262
|
"LiteLLM Router": INFO,
|
|
262
263
|
"LiteLLM Proxy": INFO,
|
|
@@ -210,6 +210,12 @@ class Settings:
|
|
|
210
210
|
use_nerd_icons: bool
|
|
211
211
|
"""If true, use Nerd Icons in file listings. Requires a compatible font."""
|
|
212
212
|
|
|
213
|
+
limit_rps: float
|
|
214
|
+
"""Default rate limit for API calls."""
|
|
215
|
+
|
|
216
|
+
limit_concurrency: int
|
|
217
|
+
"""Default concurrency limit for API calls."""
|
|
218
|
+
|
|
213
219
|
|
|
214
220
|
ws_root_dir = Path("~/Kash").expanduser()
|
|
215
221
|
|
|
@@ -276,6 +282,8 @@ def _read_settings():
|
|
|
276
282
|
mcp_server_port=DEFAULT_MCP_SERVER_PORT,
|
|
277
283
|
use_kerm_codes=False,
|
|
278
284
|
use_nerd_icons=True,
|
|
285
|
+
limit_rps=5.0,
|
|
286
|
+
limit_concurrency=10,
|
|
279
287
|
)
|
|
280
288
|
|
|
281
289
|
|
|
@@ -124,7 +124,7 @@ These are for `kash-media` but you can use a `kash-shell` for a more basic setup
|
|
|
124
124
|
|
|
125
125
|
You can use kash from your MCP client (such as Anthropic Desktop or Cursor).
|
|
126
126
|
|
|
127
|
-
You do this by running the the `
|
|
127
|
+
You do this by running the the `kash-mcp` binary to make kash actions available as MCP
|
|
128
128
|
tools.
|
|
129
129
|
|
|
130
130
|
For Claude Desktop, my config looks like this:
|
|
@@ -133,7 +133,7 @@ For Claude Desktop, my config looks like this:
|
|
|
133
133
|
{
|
|
134
134
|
"mcpServers": {
|
|
135
135
|
"kash": {
|
|
136
|
-
"command": "/Users/levy/.local/bin/
|
|
136
|
+
"command": "/Users/levy/.local/bin/kash-mcp",
|
|
137
137
|
"args": ["--proxy"]
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import ast
|
|
4
4
|
from collections.abc import Iterable
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import TYPE_CHECKING, TypeAlias
|
|
6
|
+
from typing import TYPE_CHECKING, TypeAlias
|
|
7
7
|
|
|
8
8
|
from pydantic.dataclasses import dataclass
|
|
9
9
|
from strif import abbrev_list
|
|
@@ -65,12 +65,11 @@ class Embeddings:
|
|
|
65
65
|
@classmethod
|
|
66
66
|
def embed(cls, keyvals: list[KeyVal], model=DEFAULT_EMBEDDING_MODEL) -> Embeddings:
|
|
67
67
|
from litellm import embedding
|
|
68
|
-
from litellm.types.utils import EmbeddingResponse
|
|
69
68
|
|
|
70
69
|
init_litellm()
|
|
71
70
|
|
|
72
71
|
data = {}
|
|
73
|
-
log.
|
|
72
|
+
log.info(
|
|
74
73
|
"Embedding %d texts (model %s, batch size %s)…",
|
|
75
74
|
len(keyvals),
|
|
76
75
|
model.litellm_name,
|
|
@@ -82,9 +81,8 @@ class Embeddings:
|
|
|
82
81
|
keys = [kv[0] for kv in batch]
|
|
83
82
|
texts = [kv[1] for kv in batch]
|
|
84
83
|
|
|
85
|
-
response
|
|
86
|
-
|
|
87
|
-
)
|
|
84
|
+
response = embedding(model=model.litellm_name, input=texts)
|
|
85
|
+
|
|
88
86
|
if not response.data:
|
|
89
87
|
raise ValueError("No embedding response data")
|
|
90
88
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from funlog import log_calls
|
|
6
6
|
|
|
@@ -24,12 +24,9 @@ def cosine_relatedness(x: ArrayLike, y: ArrayLike) -> float:
|
|
|
24
24
|
def embed_query(model: EmbeddingModel, query: str) -> EmbeddingResponse:
|
|
25
25
|
import litellm
|
|
26
26
|
from litellm import embedding
|
|
27
|
-
from litellm.types.utils import EmbeddingResponse
|
|
28
27
|
|
|
29
28
|
try:
|
|
30
|
-
response
|
|
31
|
-
EmbeddingResponse, embedding(model=model.litellm_name, input=[query])
|
|
32
|
-
)
|
|
29
|
+
response = embedding(model=model.litellm_name, input=[query])
|
|
33
30
|
except litellm.exceptions.APIError as e:
|
|
34
31
|
log.info("API error embedding query: %s", e)
|
|
35
32
|
raise ApiResultError(str(e))
|
|
@@ -55,7 +55,7 @@ def prepare_action_input(*input_args: CommandArg, refetch: bool = False) -> Acti
|
|
|
55
55
|
if input_items:
|
|
56
56
|
log.message("Assembling metadata for input items:\n%s", fmt_lines(input_items))
|
|
57
57
|
input_items = [
|
|
58
|
-
fetch_url_item_content(item, refetch=refetch) if is_url_resource(item) else item
|
|
58
|
+
fetch_url_item_content(item, refetch=refetch).item if is_url_resource(item) else item
|
|
59
59
|
for item in input_items
|
|
60
60
|
]
|
|
61
61
|
|
|
@@ -1,23 +1,42 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
1
3
|
from kash.config.logger import get_logger
|
|
2
4
|
from kash.exec.preconditions import is_url_resource
|
|
3
|
-
from kash.media_base.media_services import get_media_metadata
|
|
4
5
|
from kash.model.items_model import Item, ItemType
|
|
5
6
|
from kash.model.paths_model import StorePath
|
|
6
7
|
from kash.utils.common.format_utils import fmt_loc
|
|
7
8
|
from kash.utils.common.url import Url, is_url
|
|
8
9
|
from kash.utils.common.url_slice import add_slice_to_url, parse_url_slice
|
|
9
10
|
from kash.utils.errors import InvalidInput
|
|
11
|
+
from kash.web_content.web_page_model import WebPageData
|
|
10
12
|
|
|
11
13
|
log = get_logger(__name__)
|
|
12
14
|
|
|
13
15
|
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class FetchItemResult:
|
|
18
|
+
"""
|
|
19
|
+
Result of fetching a URL item.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
item: Item
|
|
23
|
+
|
|
24
|
+
was_cached: bool
|
|
25
|
+
"""Whether this item was already present in cache (or if we skipped the fetch
|
|
26
|
+
because we already had the data)."""
|
|
27
|
+
|
|
28
|
+
page_data: WebPageData | None = None
|
|
29
|
+
"""If the item was fetched from a URL via the web content cache,
|
|
30
|
+
this will hold additional metadata whether it was cached."""
|
|
31
|
+
|
|
32
|
+
|
|
14
33
|
def fetch_url_item(
|
|
15
34
|
locator: Url | StorePath,
|
|
16
35
|
*,
|
|
17
36
|
save_content: bool = True,
|
|
18
37
|
refetch: bool = False,
|
|
19
38
|
cache: bool = True,
|
|
20
|
-
) ->
|
|
39
|
+
) -> FetchItemResult:
|
|
21
40
|
from kash.workspaces import current_ws
|
|
22
41
|
|
|
23
42
|
ws = current_ws()
|
|
@@ -37,7 +56,7 @@ def fetch_url_item(
|
|
|
37
56
|
|
|
38
57
|
def fetch_url_item_content(
|
|
39
58
|
item: Item, *, save_content: bool = True, refetch: bool = False, cache: bool = True
|
|
40
|
-
) ->
|
|
59
|
+
) -> FetchItemResult:
|
|
41
60
|
"""
|
|
42
61
|
Fetch content and metadata for a URL using a media service if we
|
|
43
62
|
recognize the URL as a known media service. Otherwise, fetch and extract the
|
|
@@ -51,6 +70,7 @@ def fetch_url_item_content(
|
|
|
51
70
|
The content item is returned if content was saved. Otherwise, the updated
|
|
52
71
|
URL item is returned.
|
|
53
72
|
"""
|
|
73
|
+
from kash.media_base.media_services import get_media_metadata
|
|
54
74
|
from kash.web_content.canon_url import canonicalize_url
|
|
55
75
|
from kash.web_content.web_extract import fetch_page_content
|
|
56
76
|
from kash.workspaces import current_ws
|
|
@@ -61,7 +81,7 @@ def fetch_url_item_content(
|
|
|
61
81
|
"Already have title, description, and body, will not fetch: %s",
|
|
62
82
|
item.fmt_loc(),
|
|
63
83
|
)
|
|
64
|
-
return item
|
|
84
|
+
return FetchItemResult(item, was_cached=True)
|
|
65
85
|
|
|
66
86
|
if not item.url:
|
|
67
87
|
raise InvalidInput(f"No URL for item: {item.fmt_loc()}")
|
|
@@ -74,6 +94,8 @@ def fetch_url_item_content(
|
|
|
74
94
|
media_metadata = get_media_metadata(url)
|
|
75
95
|
url_item: Item | None = None
|
|
76
96
|
content_item: Item | None = None
|
|
97
|
+
page_data: WebPageData | None = None
|
|
98
|
+
|
|
77
99
|
if media_metadata:
|
|
78
100
|
url_item = Item.from_media_metadata(media_metadata)
|
|
79
101
|
# Preserve and canonicalize any slice suffix on the URL.
|
|
@@ -101,7 +123,6 @@ def fetch_url_item_content(
|
|
|
101
123
|
original_filename=item.get_filename(),
|
|
102
124
|
format=page_data.format_info.format,
|
|
103
125
|
)
|
|
104
|
-
ws.save(content_item)
|
|
105
126
|
|
|
106
127
|
if not url_item.title:
|
|
107
128
|
log.warning("Failed to fetch page data: title is missing: %s", item.url)
|
|
@@ -112,8 +133,15 @@ def fetch_url_item_content(
|
|
|
112
133
|
if content_item:
|
|
113
134
|
ws.save(content_item)
|
|
114
135
|
assert content_item.store_path
|
|
115
|
-
log.info(
|
|
136
|
+
log.info(
|
|
137
|
+
"Saved both URL and content item: %s, %s",
|
|
138
|
+
url_item.fmt_loc(),
|
|
139
|
+
content_item.fmt_loc(),
|
|
140
|
+
)
|
|
116
141
|
else:
|
|
117
|
-
log.info("Saved URL item: %s", url_item.fmt_loc())
|
|
142
|
+
log.info("Saved URL item (no content): %s", url_item.fmt_loc())
|
|
118
143
|
|
|
119
|
-
|
|
144
|
+
was_cached = bool(
|
|
145
|
+
not page_data or (page_data.cache_result and page_data.cache_result.was_cached)
|
|
146
|
+
)
|
|
147
|
+
return FetchItemResult(content_item or url_item, was_cached=was_cached, page_data=page_data)
|
|
@@ -3,6 +3,8 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
+
from typing_extensions import override
|
|
7
|
+
|
|
6
8
|
from kash.config.logger import get_logger
|
|
7
9
|
from kash.embeddings.embeddings import Embeddings
|
|
8
10
|
from kash.embeddings.text_similarity import rank_by_relatedness
|
|
@@ -19,6 +21,7 @@ class DocKey:
|
|
|
19
21
|
doc_type: HelpDocType
|
|
20
22
|
index: int
|
|
21
23
|
|
|
24
|
+
@override
|
|
22
25
|
def __str__(self) -> str:
|
|
23
26
|
return f"{self.doc_type.value}:{self.index}"
|
|
24
27
|
|
|
@@ -107,7 +107,7 @@ def llm_completion(
|
|
|
107
107
|
|
|
108
108
|
total_input_len = sum(len(m["content"]) for m in messages)
|
|
109
109
|
speed = len(content) / elapsed
|
|
110
|
-
log.
|
|
110
|
+
log.info(
|
|
111
111
|
f"{EMOJI_TIMING} LLM completion from {model.litellm_name} in {format_duration(elapsed)}: "
|
|
112
112
|
f"input {total_input_len} chars in {len(messages)} messages, output {len(content)} chars "
|
|
113
113
|
f"({speed:.0f} char/s)"
|
|
@@ -15,6 +15,7 @@ class LLM(LLMName, Enum):
|
|
|
15
15
|
# https://platform.openai.com/docs/models
|
|
16
16
|
o4_mini = LLMName("o4-mini")
|
|
17
17
|
o3 = LLMName("o3")
|
|
18
|
+
o3_pro = LLMName("o3-pro")
|
|
18
19
|
o3_mini = LLMName("o3-mini")
|
|
19
20
|
o1 = LLMName("o1")
|
|
20
21
|
o1_mini = LLMName("o1-mini")
|
|
@@ -35,13 +36,9 @@ class LLM(LLMName, Enum):
|
|
|
35
36
|
claude_3_5_haiku = LLMName("claude-3-5-haiku-latest")
|
|
36
37
|
|
|
37
38
|
# https://ai.google.dev/gemini-api/docs/models
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
gemini_2_5_flash_preview = LLMName("gemini-2.5-flash-preview-05-20")
|
|
42
|
-
gemini_2_0_flash = LLMName("gemini/gemini-2_0-flash")
|
|
43
|
-
gemini_2_0_flash_lite = LLMName("gemini/gemini-2.0-flash-lite")
|
|
44
|
-
gemini_2_0_pro_exp_02_05 = LLMName("gemini/gemini-2.0-pro-exp-02-05")
|
|
39
|
+
gemini_2_5_pro = LLMName("gemini/gemini-2.5-pro")
|
|
40
|
+
gemini_2_5_flash = LLMName("gemini/gemini-2.5-flash")
|
|
41
|
+
gemini_2_5_flash_lite = LLMName("gemini-2.5-flash-lite-preview-06-17")
|
|
45
42
|
|
|
46
43
|
# https://docs.x.ai/docs/models
|
|
47
44
|
xai_grok_3 = LLMName("xai/grok-3")
|
|
@@ -56,6 +53,7 @@ class LLM(LLMName, Enum):
|
|
|
56
53
|
deepseek_reasoner = LLMName("deepseek/deepseek-reasoner")
|
|
57
54
|
|
|
58
55
|
# https://console.groq.com/docs/models
|
|
56
|
+
groq_gemma2_9b_it = LLMName("groq/gemma2-9b-it")
|
|
59
57
|
groq_llama_3_1_8b_instant = LLMName("groq/llama-3.1-8b-instant")
|
|
60
58
|
groq_llama_3_3_70b_versatile = LLMName("groq/llama-3.3-70b-versatile")
|
|
61
59
|
groq_deepseek_r1_distill_llama_70b = LLMName("groq/deepseek-r1-distill-llama-70b")
|
|
@@ -114,10 +114,10 @@ def main():
|
|
|
114
114
|
args = build_parser().parse_args()
|
|
115
115
|
|
|
116
116
|
if args.list_tools or args.tool_help:
|
|
117
|
-
kash_setup(rich_logging=True,
|
|
117
|
+
kash_setup(rich_logging=True, log_level=LogLevel.warning)
|
|
118
118
|
show_tool_info(args.tool_help)
|
|
119
119
|
else:
|
|
120
|
-
kash_setup(rich_logging=False,
|
|
120
|
+
kash_setup(rich_logging=False, log_level=LogLevel.info)
|
|
121
121
|
run_server(args)
|
|
122
122
|
|
|
123
123
|
|
|
@@ -209,7 +209,7 @@ A list of parameter declarations, possibly with default values.
|
|
|
209
209
|
DEFAULT_CAREFUL_LLM = LLM.o3
|
|
210
210
|
DEFAULT_STRUCTURED_LLM = LLM.gpt_4o
|
|
211
211
|
DEFAULT_STANDARD_LLM = LLM.claude_4_sonnet
|
|
212
|
-
DEFAULT_FAST_LLM = LLM.
|
|
212
|
+
DEFAULT_FAST_LLM = LLM.gpt_4o
|
|
213
213
|
|
|
214
214
|
|
|
215
215
|
# Parameters set globally such as in the workspace.
|