deepagents-cli 0.0.41__tar.gz → 0.0.43__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.
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/.gitignore +6 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/CHANGELOG.md +26 -10
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/PKG-INFO +5 -5
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_env_vars.py +3 -0
- deepagents_cli-0.0.43/deepagents_cli/_textual_patches.py +66 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_version.py +1 -1
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/agent.py +34 -7
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/app.py +23 -1
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/config.py +82 -35
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/bundler.py +135 -9
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/commands.py +45 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/config.py +116 -7
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +1 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +23 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +1 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +205 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +1 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +44 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/index.html +16 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/logo-dark.svg +12 -0
- deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/logo-light.svg +12 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/templates.py +112 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/local_context.py +21 -7
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/system_prompt.md +1 -1
- deepagents_cli-0.0.43/deepagents_cli/terminal_capabilities.py +115 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/model_selector.py +23 -2
- deepagents_cli-0.0.43/frontend/.nvmrc +1 -0
- deepagents_cli-0.0.43/frontend/index.html +15 -0
- deepagents_cli-0.0.43/frontend/package-lock.json +6207 -0
- deepagents_cli-0.0.43/frontend/package.json +34 -0
- deepagents_cli-0.0.43/frontend/postcss.config.js +5 -0
- deepagents_cli-0.0.43/frontend/public/logo-dark.svg +12 -0
- deepagents_cli-0.0.43/frontend/public/logo-light.svg +12 -0
- deepagents_cli-0.0.43/frontend/src/App.tsx +342 -0
- deepagents_cli-0.0.43/frontend/src/ThemeProvider.tsx +66 -0
- deepagents_cli-0.0.43/frontend/src/auth/anonymous.tsx +45 -0
- deepagents_cli-0.0.43/frontend/src/auth/clerk.tsx +138 -0
- deepagents_cli-0.0.43/frontend/src/auth/loader.tsx +26 -0
- deepagents_cli-0.0.43/frontend/src/auth/supabase.tsx +236 -0
- deepagents_cli-0.0.43/frontend/src/auth/types.ts +22 -0
- deepagents_cli-0.0.43/frontend/src/components/AppHeader.tsx +70 -0
- deepagents_cli-0.0.43/frontend/src/components/FilePanels.tsx +148 -0
- deepagents_cli-0.0.43/frontend/src/components/MessageList.tsx +177 -0
- deepagents_cli-0.0.43/frontend/src/components/SubagentActivity.tsx +262 -0
- deepagents_cli-0.0.43/frontend/src/components/ThreadPicker.tsx +162 -0
- deepagents_cli-0.0.43/frontend/src/components/TodosPanel.tsx +54 -0
- deepagents_cli-0.0.43/frontend/src/components/ToolCallCard.tsx +136 -0
- deepagents_cli-0.0.43/frontend/src/components/toolcalls/FileToolCard.tsx +126 -0
- deepagents_cli-0.0.43/frontend/src/components/toolcalls/SearchCard.tsx +107 -0
- deepagents_cli-0.0.43/frontend/src/components/toolcalls/ThinkCard.tsx +60 -0
- deepagents_cli-0.0.43/frontend/src/components/toolcalls/TodosCard.tsx +63 -0
- deepagents_cli-0.0.43/frontend/src/components/toolcalls/index.ts +51 -0
- deepagents_cli-0.0.43/frontend/src/constants.ts +15 -0
- deepagents_cli-0.0.43/frontend/src/index.css +220 -0
- deepagents_cli-0.0.43/frontend/src/main.tsx +20 -0
- deepagents_cli-0.0.43/frontend/src/runtimeConfig.ts +75 -0
- deepagents_cli-0.0.43/frontend/src/types.ts +22 -0
- deepagents_cli-0.0.43/frontend/src/vite-env.d.ts +1 -0
- deepagents_cli-0.0.43/frontend/tsconfig.json +19 -0
- deepagents_cli-0.0.43/frontend/vite.config.ts +25 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/pyproject.toml +13 -4
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/conftest.py +15 -0
- deepagents_cli-0.0.43/tests/unit_tests/deploy/test_frontend_bundle.py +427 -0
- deepagents_cli-0.0.43/tests/unit_tests/deploy/test_frontend_config.py +181 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_agent.py +110 -6
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_config.py +372 -45
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_local_context.py +39 -10
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_model_switch.py +80 -0
- deepagents_cli-0.0.43/tests/unit_tests/test_terminal_capabilities.py +203 -0
- deepagents_cli-0.0.43/tests/unit_tests/test_textual_patches.py +92 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_version.py +11 -1
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/uv.lock +34 -21
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/DEV.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/Makefile +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/README.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/THREAT_MODEL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/__main__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_ask_user_types.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_cli_context.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_debug.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_git.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_server_config.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_session_stats.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_testing_models.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/app.tcss +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/ask_user.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/clipboard.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/command_registry.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/configurable_model.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/default_agent_prompt.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/editor.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/extras_info.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/file_ops.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/formatting.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/hooks.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/input.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/integrations/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/integrations/sandbox_factory.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/integrations/sandbox_provider.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/main.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/mcp_tools.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/mcp_trust.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/media_utils.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/model_config.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/non_interactive.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/notifications.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/offload.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/output.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/project_utils.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/py.typed +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/remote_client.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/server.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/server_graph.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/server_manager.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/sessions.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/commands.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/invocation.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/load.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/subagents.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/textual_adapter.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/theme.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/token_state.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/tool_display.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/tools.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/ui.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/unicode_security.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/update_check.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/_links.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/agent_selector.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/approval.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/ask_user.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/autocomplete.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/chat_input.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/diff.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/history.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/loading.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/mcp_viewer.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/message_store.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/messages.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/notification_center.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/notification_detail.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/notification_settings.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/status.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/theme_selector.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/thread_selector.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/tool_renderers.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/tool_widgets.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/update_available.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/welcome.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/.env.example +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/user/context.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/user/preferences.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/images/cli.png +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/scripts/check_imports.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/scripts/debug_server.sh +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/scripts/install.sh +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/README.md +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/conftest.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/test_bundler.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/test_commands.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/test_config.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_app.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_args.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_git.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_history.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_links.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_main.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_output.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_status.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_token_tracker.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/tools/test_fetch_url.py +0 -0
|
@@ -15,6 +15,7 @@ downloads/
|
|
|
15
15
|
eggs/
|
|
16
16
|
.eggs/
|
|
17
17
|
lib/
|
|
18
|
+
!libs/cli/frontend/src/lib/
|
|
18
19
|
lib64/
|
|
19
20
|
parts/
|
|
20
21
|
sdist/
|
|
@@ -227,3 +228,8 @@ libs/cli/TEXTUAL_PROGRESS.md
|
|
|
227
228
|
|
|
228
229
|
CLAUDE.md
|
|
229
230
|
.worktrees/
|
|
231
|
+
|
|
232
|
+
# Frontend build artifacts (source tree; package data under libs/cli/deepagents_cli/deploy/frontend_dist/ is tracked)
|
|
233
|
+
libs/cli/frontend/node_modules/
|
|
234
|
+
libs/cli/frontend/dist/
|
|
235
|
+
node_modules/
|
|
@@ -1,23 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.0.
|
|
3
|
+
## [0.0.43](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.42...deepagents-cli==0.0.43) (2026-04-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **cli:** bundled chat frontend for deepagent deploy ([#2940](https://github.com/langchain-ai/deepagents/issues/2940)) ([9bde0c7](https://github.com/langchain-ai/deepagents/commit/9bde0c7835ded20e80466d8361f40784141d68d8))
|
|
4
9
|
|
|
10
|
+
## [0.0.42](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.41...deepagents-cli==0.0.42) (2026-04-29)
|
|
5
11
|
|
|
6
12
|
### Features
|
|
7
13
|
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
* `shift+enter` newline on kitty-capable terminals ([#2869](https://github.com/langchain-ai/deepagents/issues/2869)) ([34e6614](https://github.com/langchain-ai/deepagents/commit/34e6614a2c6e6a7e33f763ac5b527c13b324a690))
|
|
15
|
+
* Hint `Enter` behavior in `/model` empty state ([#2933](https://github.com/langchain-ai/deepagents/issues/2933)) ([7cffa16](https://github.com/langchain-ai/deepagents/commit/7cffa16a072bc77def78e4cda09c2e5a2cf8ca39))
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* Queue `/model` switches during server startup ([#2895](https://github.com/langchain-ai/deepagents/issues/2895)) ([6ed7b65](https://github.com/langchain-ai/deepagents/commit/6ed7b65a40ac5bd926e94edd944bd552e8d6b5b4))
|
|
20
|
+
|
|
21
|
+
## [0.0.41](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.40...deepagents-cli==0.0.41) (2026-04-21)
|
|
22
|
+
|
|
23
|
+
### Features
|
|
13
24
|
|
|
25
|
+
* `--startup-cmd` flag ([#2841](https://github.com/langchain-ai/deepagents/issues/2841)) ([8adcc2c](https://github.com/langchain-ai/deepagents/commit/8adcc2c2e612346c263d02d1ec5c33e0d63da5a3))
|
|
26
|
+
* Actionable notifications, update modal ([#2855](https://github.com/langchain-ai/deepagents/issues/2855)) ([5fcd368](https://github.com/langchain-ai/deepagents/commit/5fcd368088079a84f151e0a3f5e4b9ac29c360c1))
|
|
27
|
+
* Custom auth via `[auth]` in `deepagents deploy` ([#2734](https://github.com/langchain-ai/deepagents/issues/2734)) ([417ddaa](https://github.com/langchain-ai/deepagents/commit/417ddaab4804a54a8f83721bb8577d65cfa3659f))
|
|
28
|
+
* Refresh footer git branch after shell commands ([#2851](https://github.com/langchain-ai/deepagents/issues/2851)) ([ee4fddd](https://github.com/langchain-ai/deepagents/commit/ee4fddde9454ee8f7ede98ee9a346da6c5ccd3d9))
|
|
29
|
+
* Rework `/version`, add release-age and editable-install guard ([#2854](https://github.com/langchain-ai/deepagents/issues/2854)) ([1ae053f](https://github.com/langchain-ai/deepagents/commit/1ae053f347679e58562d2b81eb6d6e6e9bbf0b07))
|
|
14
30
|
|
|
15
31
|
### Bug Fixes
|
|
16
32
|
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
33
|
+
* Gate agent-swap resume hint on server checkpoint ([#2862](https://github.com/langchain-ai/deepagents/issues/2862)) ([f14b9cd](https://github.com/langchain-ai/deepagents/commit/f14b9cd3cc41f92ddb089d4294cba8496d517807))
|
|
34
|
+
* Keep thinking spinner visible during text streaming ([#2849](https://github.com/langchain-ai/deepagents/issues/2849)) ([2cb2244](https://github.com/langchain-ai/deepagents/commit/2cb22446bc1351d20e8bbfa9f23b5d668947351f))
|
|
35
|
+
* Re-show thinking spinner on hitl/`ask_user` resume ([#2847](https://github.com/langchain-ai/deepagents/issues/2847)) ([34a6167](https://github.com/langchain-ai/deepagents/commit/34a6167b0c275c7e4da067ef276a837f60da2f8a))
|
|
36
|
+
* Restore `ctrl+j` newline keybinding ([#2827](https://github.com/langchain-ai/deepagents/issues/2827)) ([2e1a3f4](https://github.com/langchain-ai/deepagents/commit/2e1a3f45a9ff56390e294ea5b0f6a837200874ec))
|
|
21
37
|
|
|
22
38
|
## [0.0.40](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.39...deepagents-cli==0.0.40) (2026-04-20)
|
|
23
39
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.43
|
|
4
4
|
Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
@@ -27,9 +27,9 @@ Classifier: Topic :: Terminals
|
|
|
27
27
|
Requires-Python: <4.0,>=3.11
|
|
28
28
|
Requires-Dist: aiosqlite<1.0.0,>=0.19.0
|
|
29
29
|
Requires-Dist: deepagents-acp>=0.0.4
|
|
30
|
-
Requires-Dist: deepagents==0.5.
|
|
30
|
+
Requires-Dist: deepagents==0.5.4
|
|
31
31
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
32
|
-
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.
|
|
32
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2
|
|
33
33
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.1
|
|
34
34
|
Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.2.0
|
|
35
35
|
Requires-Dist: langchain-openai<2.0.0,>=1.1.12
|
|
@@ -57,7 +57,7 @@ Requires-Dist: uuid-utils<1.0.0,>=0.10.0
|
|
|
57
57
|
Provides-Extra: agentcore
|
|
58
58
|
Requires-Dist: langchain-agentcore-codeinterpreter>=0.0.1; extra == 'agentcore'
|
|
59
59
|
Provides-Extra: all-providers
|
|
60
|
-
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.
|
|
60
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2; extra == 'all-providers'
|
|
61
61
|
Requires-Dist: langchain-aws<2.0.0,>=1.0.0; extra == 'all-providers'
|
|
62
62
|
Requires-Dist: langchain-baseten<1.0.0,>=0.1.9; extra == 'all-providers'
|
|
63
63
|
Requires-Dist: langchain-cohere<1.0.0,>=0.5.0; extra == 'all-providers'
|
|
@@ -82,7 +82,7 @@ Requires-Dist: langchain-daytona>=0.0.4; extra == 'all-sandboxes'
|
|
|
82
82
|
Requires-Dist: langchain-modal>=0.0.2; extra == 'all-sandboxes'
|
|
83
83
|
Requires-Dist: langchain-runloop>=0.0.3; extra == 'all-sandboxes'
|
|
84
84
|
Provides-Extra: anthropic
|
|
85
|
-
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.
|
|
85
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2; extra == 'anthropic'
|
|
86
86
|
Provides-Extra: baseten
|
|
87
87
|
Requires-Dist: langchain-baseten<1.0.0,>=0.1.9; extra == 'baseten'
|
|
88
88
|
Provides-Extra: bedrock
|
|
@@ -52,6 +52,9 @@ real PyPI release. Any non-empty value enables the flag (including `"0"` or
|
|
|
52
52
|
EXTRA_SKILLS_DIRS = "DEEPAGENTS_CLI_EXTRA_SKILLS_DIRS"
|
|
53
53
|
"""Colon-separated paths added to the skill containment allowlist."""
|
|
54
54
|
|
|
55
|
+
KITTY_KEYBOARD = "DEEPAGENTS_CLI_KITTY_KEYBOARD"
|
|
56
|
+
"""Override kitty-keyboard detection (`1` forces on, `0` forces off)."""
|
|
57
|
+
|
|
55
58
|
LANGSMITH_PROJECT = "DEEPAGENTS_CLI_LANGSMITH_PROJECT"
|
|
56
59
|
"""Override LangSmith project name for agent traces."""
|
|
57
60
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
r"""Preserve the `alt` modifier on legacy `ESC + <byte>` sequences.
|
|
2
|
+
|
|
3
|
+
Upstream `XTermParser._sequence_to_key_events` drops the `alt` flag on
|
|
4
|
+
the tuple-branch fast path, so VSCode's `sendSequence` shift+enter
|
|
5
|
+
binding (which writes `\x1b\r` to the PTY) arrives as bare `enter`
|
|
6
|
+
instead of `alt+enter`. Tracked in Textualize/textual#6378. Remove this
|
|
7
|
+
file and the Textual pin comment in `pyproject.toml` when that lands.
|
|
8
|
+
|
|
9
|
+
Imported for side effect from `app.py` before any `App()` is created.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Iterable
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
_ESC_PREFIX_LEN = 2
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
from textual import events
|
|
26
|
+
from textual._ansi_sequences import (
|
|
27
|
+
ANSI_SEQUENCES_KEYS, # noqa: PLC2701
|
|
28
|
+
IGNORE_SEQUENCE, # noqa: PLC2701
|
|
29
|
+
)
|
|
30
|
+
from textual._xterm_parser import XTermParser # noqa: PLC2701
|
|
31
|
+
|
|
32
|
+
_original = XTermParser._sequence_to_key_events
|
|
33
|
+
except (ImportError, AttributeError) as exc: # pragma: no cover - defensive
|
|
34
|
+
logger.warning("Textual keyboard parser patch skipped: %s", exc)
|
|
35
|
+
else:
|
|
36
|
+
|
|
37
|
+
def _emit_alt(keys: tuple, character: str | None) -> Iterable[events.Key]:
|
|
38
|
+
for key in keys:
|
|
39
|
+
yield events.Key(f"alt+{key.value}", character)
|
|
40
|
+
|
|
41
|
+
def _sequence_to_key_events_with_alt(
|
|
42
|
+
self: XTermParser, sequence: str, alt: bool = False
|
|
43
|
+
) -> Iterable[events.Key]:
|
|
44
|
+
# Fast path: \x1b<byte> on first pass. Short-circuits the ~100 ms
|
|
45
|
+
# escape-delay wait when both bytes arrive together. Semantic side
|
|
46
|
+
# effect: \x1b\x1b dispatches as `alt+escape` with no delay, matching
|
|
47
|
+
# crossterm and Node TTY.
|
|
48
|
+
if not alt and len(sequence) == _ESC_PREFIX_LEN and sequence[0] == "\x1b":
|
|
49
|
+
inner = ANSI_SEQUENCES_KEYS.get(sequence[1])
|
|
50
|
+
if inner is not IGNORE_SEQUENCE and isinstance(inner, tuple):
|
|
51
|
+
yield from _emit_alt(inner, None)
|
|
52
|
+
return
|
|
53
|
+
# Correctness fix (Textualize/textual#6378): preserve `alt` on the
|
|
54
|
+
# reissue path for single-byte tuple mappings.
|
|
55
|
+
if alt:
|
|
56
|
+
keys = ANSI_SEQUENCES_KEYS.get(sequence)
|
|
57
|
+
if keys is not IGNORE_SEQUENCE and isinstance(keys, tuple):
|
|
58
|
+
character = sequence if len(sequence) == 1 else None
|
|
59
|
+
yield from _emit_alt(keys, character)
|
|
60
|
+
return
|
|
61
|
+
yield from _original(self, sequence, alt=alt)
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
XTermParser._sequence_to_key_events = _sequence_to_key_events_with_alt # ty: ignore[invalid-assignment]
|
|
65
|
+
except (AttributeError, TypeError) as exc: # pragma: no cover - defensive
|
|
66
|
+
logger.warning("Textual keyboard parser patch assignment rejected: %s", exc)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Version information and lightweight constants for `deepagents-cli`."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.0.
|
|
3
|
+
__version__ = "0.0.43" # x-release-please-version
|
|
4
4
|
|
|
5
5
|
DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/cli"
|
|
6
6
|
"""URL for `deepagents-cli` documentation."""
|
|
@@ -16,6 +16,18 @@ from deepagents.backends import CompositeBackend, LocalShellBackend
|
|
|
16
16
|
from deepagents.backends.filesystem import FilesystemBackend
|
|
17
17
|
from deepagents.middleware import MemoryMiddleware, SkillsMiddleware
|
|
18
18
|
|
|
19
|
+
# Backwards-compat flag: SDKs before 0.5.4 accept only `list[str]` for
|
|
20
|
+
# `SkillsMiddleware.sources`; newer SDKs expose the `SkillSource` alias
|
|
21
|
+
# that permits `(path, label)` tuples. The `skills` module is already
|
|
22
|
+
# loaded by the `SkillsMiddleware` import above, so the extra lookup
|
|
23
|
+
# here adds no startup cost.
|
|
24
|
+
try:
|
|
25
|
+
from deepagents.middleware.skills import SkillSource as _SkillSource # noqa: F401
|
|
26
|
+
except ImportError:
|
|
27
|
+
_SUPPORTS_SKILL_SOURCE_TUPLES = False
|
|
28
|
+
else:
|
|
29
|
+
_SUPPORTS_SKILL_SOURCE_TUPLES = True
|
|
30
|
+
|
|
19
31
|
if TYPE_CHECKING:
|
|
20
32
|
from collections.abc import Awaitable, Callable, Sequence
|
|
21
33
|
|
|
@@ -1116,25 +1128,40 @@ def create_cli_agent(
|
|
|
1116
1128
|
# built-in -> user .deepagents -> user .agents
|
|
1117
1129
|
# -> project .deepagents -> project .agents
|
|
1118
1130
|
# -> user .claude (experimental) -> project .claude (experimental)
|
|
1119
|
-
sources
|
|
1120
|
-
|
|
1131
|
+
# Labels disambiguate user- vs project-scoped sources that share a
|
|
1132
|
+
# `.../skills` leaf; the middleware would otherwise derive identical
|
|
1133
|
+
# labels from the parent directory name.
|
|
1134
|
+
sources: list[tuple[str, str]] = [
|
|
1135
|
+
(str(settings.get_built_in_skills_dir()), "Built-in"),
|
|
1136
|
+
(str(skills_dir), "User Deepagents"),
|
|
1137
|
+
(str(user_agent_skills_dir), "User Agents"),
|
|
1138
|
+
]
|
|
1121
1139
|
if project_skills_dir:
|
|
1122
|
-
sources.append(str(project_skills_dir))
|
|
1140
|
+
sources.append((str(project_skills_dir), "Project Deepagents"))
|
|
1123
1141
|
if project_agent_skills_dir:
|
|
1124
|
-
sources.append(str(project_agent_skills_dir))
|
|
1142
|
+
sources.append((str(project_agent_skills_dir), "Project Agents"))
|
|
1125
1143
|
|
|
1126
1144
|
# Experimental: Claude Code skill directories
|
|
1127
1145
|
user_claude_skills_dir = settings.get_user_claude_skills_dir()
|
|
1128
1146
|
if user_claude_skills_dir.exists():
|
|
1129
|
-
sources.append(str(user_claude_skills_dir))
|
|
1147
|
+
sources.append((str(user_claude_skills_dir), "User Claude"))
|
|
1130
1148
|
project_claude_skills_dir = settings.get_project_claude_skills_dir()
|
|
1131
1149
|
if project_claude_skills_dir:
|
|
1132
|
-
sources.append(str(project_claude_skills_dir))
|
|
1150
|
+
sources.append((str(project_claude_skills_dir), "Project Claude"))
|
|
1151
|
+
|
|
1152
|
+
# Backwards-compat: strip labels when the installed SDK is too old
|
|
1153
|
+
# to accept `(path, label)` tuples. Label-based disambiguation
|
|
1154
|
+
# regresses to the pre-alias behavior (user- and project-scoped
|
|
1155
|
+
# `.claude/skills` collapse to the same label), but functionality
|
|
1156
|
+
# is preserved.
|
|
1157
|
+
middleware_sources: Sequence[str | tuple[str, str]] = (
|
|
1158
|
+
sources if _SUPPORTS_SKILL_SOURCE_TUPLES else [path for path, _ in sources]
|
|
1159
|
+
)
|
|
1133
1160
|
|
|
1134
1161
|
agent_middleware.append(
|
|
1135
1162
|
SkillsMiddleware(
|
|
1136
1163
|
backend=FilesystemBackend(),
|
|
1137
|
-
sources=
|
|
1164
|
+
sources=middleware_sources,
|
|
1138
1165
|
)
|
|
1139
1166
|
)
|
|
1140
1167
|
|
|
@@ -33,7 +33,11 @@ from textual.widgets._toast import (
|
|
|
33
33
|
Toast as _Toast, # noqa: PLC2701 # for Toast click routing
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
# Applied as an import-time side effect; must come before any App is created.
|
|
37
|
+
from deepagents_cli import (
|
|
38
|
+
_textual_patches, # noqa: F401
|
|
39
|
+
theme,
|
|
40
|
+
)
|
|
37
41
|
from deepagents_cli._cli_context import CLIContext
|
|
38
42
|
from deepagents_cli._git import (
|
|
39
43
|
read_git_branch_from_filesystem,
|
|
@@ -6370,6 +6374,24 @@ class DeepAgentsApp(App):
|
|
|
6370
6374
|
model_spec = model_spec.removeprefix(":")
|
|
6371
6375
|
|
|
6372
6376
|
if not self._remote_agent():
|
|
6377
|
+
if self._connecting:
|
|
6378
|
+
from functools import partial
|
|
6379
|
+
|
|
6380
|
+
self._defer_action(
|
|
6381
|
+
DeferredAction(
|
|
6382
|
+
kind="model_switch",
|
|
6383
|
+
execute=partial(
|
|
6384
|
+
self._switch_model,
|
|
6385
|
+
model_spec,
|
|
6386
|
+
extra_kwargs=extra_kwargs,
|
|
6387
|
+
),
|
|
6388
|
+
)
|
|
6389
|
+
)
|
|
6390
|
+
self.notify(
|
|
6391
|
+
"Model will switch once the session is ready.",
|
|
6392
|
+
timeout=3,
|
|
6393
|
+
)
|
|
6394
|
+
return
|
|
6373
6395
|
await self._mount_message(
|
|
6374
6396
|
ErrorMessage("Model switching requires a server-backed session.")
|
|
6375
6397
|
)
|
|
@@ -496,14 +496,22 @@ def is_ascii_mode() -> bool:
|
|
|
496
496
|
|
|
497
497
|
|
|
498
498
|
def newline_shortcut() -> str:
|
|
499
|
-
"""Return the
|
|
499
|
+
"""Return the terminal-appropriate label for the newline keyboard shortcut.
|
|
500
500
|
|
|
501
|
-
|
|
502
|
-
|
|
501
|
+
Prefers `Shift+Enter` when the terminal is known to support the kitty
|
|
502
|
+
keyboard protocol, either via conservative terminal-identity heuristics
|
|
503
|
+
or the `DEEPAGENTS_CLI_KITTY_KEYBOARD` override. Falls back to
|
|
504
|
+
`Option+Enter` on macOS and `Ctrl+J` elsewhere — both survive legacy
|
|
505
|
+
terminals that strip the shift modifier from `Enter`.
|
|
503
506
|
|
|
504
507
|
Returns:
|
|
505
|
-
A human-readable shortcut string,
|
|
508
|
+
A human-readable shortcut string,
|
|
509
|
+
e.g. `'Shift+Enter'`, `'Option+Enter'`, or `'Ctrl+J'`.
|
|
506
510
|
"""
|
|
511
|
+
from deepagents_cli.terminal_capabilities import supports_kitty_keyboard_protocol
|
|
512
|
+
|
|
513
|
+
if supports_kitty_keyboard_protocol():
|
|
514
|
+
return "Shift+Enter"
|
|
507
515
|
return "Option+Enter" if sys.platform == "darwin" else "Ctrl+J"
|
|
508
516
|
|
|
509
517
|
|
|
@@ -1854,36 +1862,52 @@ _OPENROUTER_APP_TITLE = "Deep Agents CLI"
|
|
|
1854
1862
|
_OPENROUTER_APP_CATEGORIES: list[str] = ["cli-agent"]
|
|
1855
1863
|
"""Default `app_categories` (maps to `X-OpenRouter-Categories`) for OpenRouter."""
|
|
1856
1864
|
|
|
1865
|
+
_cli_openrouter_profile_registered = False
|
|
1866
|
+
"""Process-wide guard so the CLI OpenRouter profile is registered exactly once."""
|
|
1857
1867
|
|
|
1858
|
-
def _apply_openrouter_defaults(kwargs: dict[str, Any]) -> None:
|
|
1859
|
-
"""Inject default OpenRouter attribution kwargs.
|
|
1860
1868
|
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
`HTTP-Referer`, `X-Title`, and `X-OpenRouter-Categories` headers that
|
|
1864
|
-
`ChatOpenRouter` sends for app attribution
|
|
1865
|
-
(see https://openrouter.ai/docs/app-attribution).
|
|
1869
|
+
def _cli_openrouter_attribution_kwargs() -> dict[str, Any]:
|
|
1870
|
+
"""CLI-specific OpenRouter attribution kwargs.
|
|
1866
1871
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1872
|
+
Layered on top of the SDK's built-in factory via profile stacking; these
|
|
1873
|
+
values override the SDK defaults but still sit beneath any caller-supplied
|
|
1874
|
+
`kwargs` (i.e. `config.toml`-resolved values), preserving the precedence
|
|
1875
|
+
documented on `apply_provider_profile`.
|
|
1869
1876
|
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1877
|
+
Returns:
|
|
1878
|
+
Mapping of `app_url` and `app_title` to spread into `init_chat_model`.
|
|
1879
|
+
"""
|
|
1880
|
+
return {
|
|
1881
|
+
"app_url": _OPENROUTER_APP_URL,
|
|
1882
|
+
"app_title": _OPENROUTER_APP_TITLE,
|
|
1883
|
+
}
|
|
1875
1884
|
|
|
1876
|
-
# Per-model (shallow-merges on top of provider-wide)
|
|
1877
|
-
[models.providers.openrouter.params."openai/gpt-oss-120b"]
|
|
1878
|
-
app_title = "My App (GPT)"
|
|
1879
|
-
```
|
|
1880
1885
|
|
|
1881
|
-
|
|
1882
|
-
|
|
1886
|
+
def _ensure_cli_openrouter_profile_registered() -> None:
|
|
1887
|
+
"""Stack the CLI OpenRouter attribution onto the SDK's built-in profile.
|
|
1888
|
+
|
|
1889
|
+
Stacking (vs. duplicating the inline `_get_provider_kwargs` path) means the
|
|
1890
|
+
SDK's `pre_init` version check fires exactly once and the CLI's app-
|
|
1891
|
+
attribution defaults are composed via the same `apply_provider_profile`
|
|
1892
|
+
path used for every other provider. `register_provider_profile` merges on
|
|
1893
|
+
top of the existing built-in registration: the CLI's `init_kwargs` and
|
|
1894
|
+
factory output win on shared keys, while the built-in's `pre_init` and
|
|
1895
|
+
factory still chain.
|
|
1883
1896
|
"""
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1897
|
+
global _cli_openrouter_profile_registered # noqa: PLW0603
|
|
1898
|
+
if _cli_openrouter_profile_registered:
|
|
1899
|
+
return
|
|
1900
|
+
|
|
1901
|
+
from deepagents.profiles.provider import ProviderProfile, register_provider_profile
|
|
1902
|
+
|
|
1903
|
+
register_provider_profile(
|
|
1904
|
+
"openrouter",
|
|
1905
|
+
ProviderProfile(
|
|
1906
|
+
init_kwargs={"app_categories": _OPENROUTER_APP_CATEGORIES},
|
|
1907
|
+
init_kwargs_factory=_cli_openrouter_attribution_kwargs,
|
|
1908
|
+
),
|
|
1909
|
+
)
|
|
1910
|
+
_cli_openrouter_profile_registered = True
|
|
1887
1911
|
|
|
1888
1912
|
|
|
1889
1913
|
def _get_provider_kwargs(
|
|
@@ -1927,14 +1951,6 @@ def _get_provider_kwargs(
|
|
|
1927
1951
|
if api_key:
|
|
1928
1952
|
result["api_key"] = api_key
|
|
1929
1953
|
|
|
1930
|
-
if provider == "openrouter":
|
|
1931
|
-
from deepagents.profiles._openrouter import (
|
|
1932
|
-
check_openrouter_version, # noqa: PLC2701
|
|
1933
|
-
)
|
|
1934
|
-
|
|
1935
|
-
check_openrouter_version()
|
|
1936
|
-
_apply_openrouter_defaults(result)
|
|
1937
|
-
|
|
1938
1954
|
return result
|
|
1939
1955
|
|
|
1940
1956
|
|
|
@@ -2242,6 +2258,37 @@ def create_model(
|
|
|
2242
2258
|
# Provider-specific kwargs (with per-model overrides)
|
|
2243
2259
|
kwargs = _get_provider_kwargs(provider, model_name=model_name)
|
|
2244
2260
|
|
|
2261
|
+
# Compose under existing kwargs: profile < config.toml < --model-params
|
|
2262
|
+
# (applied below). The CLI's OpenRouter profile is stacked on top of the
|
|
2263
|
+
# built-in SDK profile so its `pre_init` (version check) and factory
|
|
2264
|
+
# (app attribution) compose into a single `apply_provider_profile` call.
|
|
2265
|
+
if provider:
|
|
2266
|
+
from deepagents.profiles.provider import apply_provider_profile
|
|
2267
|
+
|
|
2268
|
+
if provider == "openrouter":
|
|
2269
|
+
_ensure_cli_openrouter_profile_registered()
|
|
2270
|
+
|
|
2271
|
+
spec = f"{provider}:{model_name}" if model_name else provider
|
|
2272
|
+
try:
|
|
2273
|
+
kwargs = apply_provider_profile(spec, kwargs)
|
|
2274
|
+
except ModelConfigError:
|
|
2275
|
+
raise
|
|
2276
|
+
except Exception as exc:
|
|
2277
|
+
# `pre_init` and `init_kwargs_factory` callables registered on a
|
|
2278
|
+
# `ProviderProfile` may raise arbitrary exceptions (e.g. an
|
|
2279
|
+
# `ImportError` from the OpenRouter min-version check). Surface
|
|
2280
|
+
# them as `ModelConfigError` so the CLI's error path renders an
|
|
2281
|
+
# actionable message instead of a raw stack trace.
|
|
2282
|
+
logger.debug(
|
|
2283
|
+
"ProviderProfile resolution for %r failed.", spec, exc_info=True
|
|
2284
|
+
)
|
|
2285
|
+
msg = (
|
|
2286
|
+
f"Failed to apply provider profile for '{spec}': {exc}. "
|
|
2287
|
+
f"Check that the provider package is installed and up to date, "
|
|
2288
|
+
f"or set explicit kwargs via `--model-params`."
|
|
2289
|
+
)
|
|
2290
|
+
raise ModelConfigError(msg) from exc
|
|
2291
|
+
|
|
2245
2292
|
# CLI --model-params take highest priority
|
|
2246
2293
|
if extra_kwargs:
|
|
2247
2294
|
kwargs.update(extra_kwargs)
|
|
@@ -25,6 +25,8 @@ from __future__ import annotations
|
|
|
25
25
|
|
|
26
26
|
import json
|
|
27
27
|
import logging
|
|
28
|
+
import os
|
|
29
|
+
import re
|
|
28
30
|
import shutil
|
|
29
31
|
from pathlib import Path
|
|
30
32
|
from typing import Any
|
|
@@ -39,6 +41,7 @@ from deepagents_cli.deploy.config import (
|
|
|
39
41
|
load_subagents,
|
|
40
42
|
)
|
|
41
43
|
from deepagents_cli.deploy.templates import (
|
|
44
|
+
APP_PY_TEMPLATE,
|
|
42
45
|
AUTH_BLOCKS,
|
|
43
46
|
AUTH_ON_HANDLER,
|
|
44
47
|
DEPLOY_GRAPH_TEMPLATE,
|
|
@@ -69,6 +72,97 @@ _MODEL_PROVIDER_DEPS: dict[str, str] = {
|
|
|
69
72
|
}
|
|
70
73
|
"""Dependencies inferred from a provider: prefix on the model string."""
|
|
71
74
|
|
|
75
|
+
_FRONTEND_DIST_SRC = Path(__file__).parent / "frontend_dist"
|
|
76
|
+
"""Location of the shipped pre-built frontend, inside this Python package."""
|
|
77
|
+
|
|
78
|
+
_FRONTEND_PLACEHOLDER_RE = re.compile(
|
|
79
|
+
r"window\.__DEEPAGENTS_CONFIG__\s*=\s*\{[^<]*?\};",
|
|
80
|
+
re.DOTALL,
|
|
81
|
+
)
|
|
82
|
+
"""Matches the placeholder script we injected into index.html at build time."""
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _build_runtime_config_json(config: DeployConfig) -> str:
|
|
86
|
+
"""Build the JSON value injected into `window.__DEEPAGENTS_CONFIG__`.
|
|
87
|
+
|
|
88
|
+
Only reached when `[frontend].enabled` and `[auth]` is set —
|
|
89
|
+
validation guarantees both. The `is None` guards below exist so
|
|
90
|
+
the optional fields narrow for type-checkers.
|
|
91
|
+
"""
|
|
92
|
+
if config.frontend is None:
|
|
93
|
+
msg = "runtime config requires [frontend] to be configured"
|
|
94
|
+
raise ValueError(msg)
|
|
95
|
+
if config.auth is None:
|
|
96
|
+
msg = "runtime config requires [auth] to be configured"
|
|
97
|
+
raise ValueError(msg)
|
|
98
|
+
|
|
99
|
+
app_name = config.frontend.app_name or config.agent.name
|
|
100
|
+
payload: dict[str, Any] = {
|
|
101
|
+
"appName": app_name,
|
|
102
|
+
"assistantId": "agent",
|
|
103
|
+
}
|
|
104
|
+
# Optional UI-customization fields — only injected when the user
|
|
105
|
+
# set them, so the default-bundle case stays small.
|
|
106
|
+
if config.frontend.subtitle is not None:
|
|
107
|
+
payload["subtitle"] = config.frontend.subtitle
|
|
108
|
+
if config.frontend.prompts is not None:
|
|
109
|
+
payload["prompts"] = list(config.frontend.prompts)
|
|
110
|
+
|
|
111
|
+
provider = config.auth.provider
|
|
112
|
+
payload["auth"] = provider
|
|
113
|
+
if provider == "supabase":
|
|
114
|
+
payload["supabaseUrl"] = os.environ["SUPABASE_URL"]
|
|
115
|
+
payload["supabaseAnonKey"] = os.environ["SUPABASE_PUBLISHABLE_DEFAULT_KEY"]
|
|
116
|
+
elif provider == "clerk":
|
|
117
|
+
payload["clerkPublishableKey"] = os.environ["CLERK_PUBLISHABLE_KEY"]
|
|
118
|
+
elif provider == "anonymous":
|
|
119
|
+
# No env vars; payload["auth"] = "anonymous" is enough.
|
|
120
|
+
pass
|
|
121
|
+
else:
|
|
122
|
+
msg = f"Unknown auth provider for frontend: {provider}"
|
|
123
|
+
raise ValueError(msg)
|
|
124
|
+
|
|
125
|
+
# Escape `<` so a hostile or accidental `</script>` inside a string value
|
|
126
|
+
# can't break out of the inline <script> tag.
|
|
127
|
+
return json.dumps(payload, separators=(",", ":")).replace("<", "\\u003c")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _copy_frontend_dist(config: DeployConfig, build_dir: Path) -> None:
|
|
131
|
+
"""Copy the pre-built bundle into build_dir and rewrite the config placeholder."""
|
|
132
|
+
if not _FRONTEND_DIST_SRC.is_dir():
|
|
133
|
+
msg = (
|
|
134
|
+
f"Shipped frontend bundle not found at {_FRONTEND_DIST_SRC}. "
|
|
135
|
+
"Did you run `make build-frontends`?"
|
|
136
|
+
)
|
|
137
|
+
raise RuntimeError(msg)
|
|
138
|
+
|
|
139
|
+
dest = build_dir / "frontend_dist"
|
|
140
|
+
if dest.exists():
|
|
141
|
+
shutil.rmtree(dest)
|
|
142
|
+
shutil.copytree(_FRONTEND_DIST_SRC, dest)
|
|
143
|
+
|
|
144
|
+
index_html = dest / "index.html"
|
|
145
|
+
if not index_html.is_file():
|
|
146
|
+
msg = f"expected index.html inside {_FRONTEND_DIST_SRC}"
|
|
147
|
+
raise RuntimeError(msg)
|
|
148
|
+
|
|
149
|
+
html = index_html.read_text(encoding="utf-8")
|
|
150
|
+
payload = _build_runtime_config_json(config)
|
|
151
|
+
replacement = f"window.__DEEPAGENTS_CONFIG__ = {payload};"
|
|
152
|
+
new_html, count = _FRONTEND_PLACEHOLDER_RE.subn(
|
|
153
|
+
lambda _m: replacement,
|
|
154
|
+
html,
|
|
155
|
+
count=1,
|
|
156
|
+
)
|
|
157
|
+
if count == 0:
|
|
158
|
+
msg = (
|
|
159
|
+
"Could not find window.__DEEPAGENTS_CONFIG__ placeholder in the "
|
|
160
|
+
"shipped index.html. The frontend bundle is out of sync with the "
|
|
161
|
+
"bundler — rebuild with `make build-frontends`."
|
|
162
|
+
)
|
|
163
|
+
raise RuntimeError(msg)
|
|
164
|
+
index_html.write_text(new_html, encoding="utf-8")
|
|
165
|
+
|
|
72
166
|
|
|
73
167
|
def bundle(
|
|
74
168
|
config: DeployConfig,
|
|
@@ -127,18 +221,38 @@ def bundle(
|
|
|
127
221
|
)
|
|
128
222
|
logger.info("Generated deploy_graph.py")
|
|
129
223
|
|
|
130
|
-
# 6. Generate auth.py
|
|
131
|
-
|
|
132
|
-
|
|
224
|
+
# 6. Generate auth.py from the [auth] provider, if any. Skipped
|
|
225
|
+
# entirely when [auth] is omitted — in that case LangSmith Cloud's
|
|
226
|
+
# default x-api-key auth applies. Validation guarantees [auth] is
|
|
227
|
+
# set whenever [frontend].enabled, so auth.py is always present
|
|
228
|
+
# for frontend deploys (including the "anonymous" provider, whose
|
|
229
|
+
# permissive handler lets the bundled UI reach /threads).
|
|
230
|
+
frontend_enabled = config.frontend is not None and config.frontend.enabled
|
|
231
|
+
auth_provider: str | None = (
|
|
232
|
+
config.auth.provider if config.auth is not None else None
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
auth_present = auth_provider is not None
|
|
236
|
+
if auth_provider is not None:
|
|
133
237
|
(build_dir / "auth.py").write_text(
|
|
134
|
-
_render_auth_py(
|
|
238
|
+
_render_auth_py(auth_provider),
|
|
135
239
|
encoding="utf-8",
|
|
136
240
|
)
|
|
137
|
-
logger.info("Generated auth.py (%s)",
|
|
241
|
+
logger.info("Generated auth.py (%s)", auth_provider)
|
|
242
|
+
|
|
243
|
+
# 6b. Copy frontend bundle when enabled.
|
|
244
|
+
if frontend_enabled:
|
|
245
|
+
_copy_frontend_dist(config, build_dir)
|
|
246
|
+
(build_dir / "app.py").write_text(APP_PY_TEMPLATE, encoding="utf-8")
|
|
247
|
+
logger.info("Copied frontend bundle and wrote app.py (%s)", auth_provider)
|
|
138
248
|
|
|
139
249
|
# 7. Render langgraph.json.
|
|
140
250
|
(build_dir / "langgraph.json").write_text(
|
|
141
|
-
_render_langgraph_json(
|
|
251
|
+
_render_langgraph_json(
|
|
252
|
+
env_present=env_present,
|
|
253
|
+
auth_present=auth_present,
|
|
254
|
+
frontend_present=frontend_enabled,
|
|
255
|
+
),
|
|
142
256
|
encoding="utf-8",
|
|
143
257
|
)
|
|
144
258
|
|
|
@@ -312,8 +426,13 @@ def _render_auth_py(provider: str) -> str:
|
|
|
312
426
|
return auth_block + AUTH_ON_HANDLER
|
|
313
427
|
|
|
314
428
|
|
|
315
|
-
def _render_langgraph_json(
|
|
316
|
-
|
|
429
|
+
def _render_langgraph_json(
|
|
430
|
+
*,
|
|
431
|
+
env_present: bool,
|
|
432
|
+
auth_present: bool = False,
|
|
433
|
+
frontend_present: bool = False,
|
|
434
|
+
) -> str:
|
|
435
|
+
"""Render `langgraph.json` — adds `"env"`, `"auth"`, `"http"` when applicable."""
|
|
317
436
|
data: dict = {
|
|
318
437
|
"dependencies": ["."],
|
|
319
438
|
"graphs": {"agent": "./deploy_graph.py:make_graph"},
|
|
@@ -323,6 +442,8 @@ def _render_langgraph_json(*, env_present: bool, auth_present: bool = False) ->
|
|
|
323
442
|
data["env"] = ".env"
|
|
324
443
|
if auth_present:
|
|
325
444
|
data["auth"] = {"path": "./auth.py:auth"}
|
|
445
|
+
if frontend_present:
|
|
446
|
+
data["http"] = {"app": "./app.py:app"}
|
|
326
447
|
return json.dumps(data, indent=2) + "\n"
|
|
327
448
|
|
|
328
449
|
|
|
@@ -392,7 +513,12 @@ def print_bundle_summary(config: DeployConfig, build_dir: Path) -> None:
|
|
|
392
513
|
print(f"\n Agent: {config.agent.name}")
|
|
393
514
|
print(f" Model: {config.agent.model}")
|
|
394
515
|
if config.auth is not None:
|
|
395
|
-
|
|
516
|
+
if config.auth.provider == "anonymous":
|
|
517
|
+
print(" Auth: anonymous (API open to anyone)")
|
|
518
|
+
else:
|
|
519
|
+
print(f" Auth: {config.auth.provider}")
|
|
520
|
+
else:
|
|
521
|
+
print(" Auth: none (LangSmith API key required to call the API)")
|
|
396
522
|
|
|
397
523
|
memory_files = sorted(seed.get("memories", {}).keys())
|
|
398
524
|
if memory_files:
|