ayder-cli 2.3.0__tar.gz → 2.3.1__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.
Files changed (317) hide show
  1. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/PKG-INFO +87 -5
  2. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/README.md +83 -1
  3. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/config.toml.example +21 -15
  4. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/pyproject.toml +8 -4
  5. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/check_exception_handlers.py +1 -1
  6. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/check_log_arguments.py +8 -8
  7. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/log_argument_baseline.txt +11 -0
  8. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/config.py +13 -4
  9. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/registry.py +4 -0
  10. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/application/runtime_factory.py +3 -0
  11. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/cli.py +9 -0
  12. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/config.py +36 -20
  13. ayder_cli-2.3.1/src/ayder_cli/core/reasoning.py +66 -0
  14. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/loops/chat_loop.py +63 -2
  15. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama.py +35 -4
  16. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/openai.py +7 -0
  17. ayder_cli-2.3.1/src/ayder_cli/services/messaging_inbox.py +413 -0
  18. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/filesystem.py +10 -0
  19. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/filesystem_definitions.py +8 -3
  20. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/execution.py +33 -0
  21. ayder_cli-2.3.1/src/ayder_cli/tools/mcp.py +113 -0
  22. ayder_cli-2.3.1/src/ayder_cli/tools/mcp_client.py +157 -0
  23. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/plugin_manager.py +4 -0
  24. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/registry.py +10 -1
  25. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/__init__.py +5 -2
  26. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/app.py +107 -1
  27. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/commands.py +103 -0
  28. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/widgets.py +55 -2
  29. ayder_cli-2.3.1/tests/core/test_reasoning_config.py +130 -0
  30. ayder_cli-2.3.1/tests/loops/test_required_args_aliases.py +75 -0
  31. ayder_cli-2.3.1/tests/providers/test_ollama_parallel_tool_call_ids.py +92 -0
  32. ayder_cli-2.3.1/tests/providers/test_reasoning_effort.py +139 -0
  33. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/scripts/test_exception_gate.py +19 -5
  34. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/scripts/test_log_argument_gate.py +18 -18
  35. ayder_cli-2.3.1/tests/services/test_messaging_inbox.py +289 -0
  36. ayder_cli-2.3.1/tests/tools/test_file_editor_size_limit.py +62 -0
  37. ayder_cli-2.3.1/tests/tools/test_mcp.py +202 -0
  38. ayder_cli-2.3.1/tests/tools/test_mcp_client.py +158 -0
  39. ayder_cli-2.3.1/tests/tools/test_unexpected_args.py +99 -0
  40. ayder_cli-2.3.1/tests/tui/test_peer_message_turn.py +202 -0
  41. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_widgets.py +103 -1
  42. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_confirm_screen.py +2 -0
  43. ayder_cli-2.3.1/tests/ui/test_tui_commands_effort.py +136 -0
  44. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_commands_provider.py +13 -0
  45. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/uv.lock +5 -7
  46. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/.github/workflows/ci.yml +0 -0
  47. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/.github/workflows/python-package.yml +0 -0
  48. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/.gitignore +0 -0
  49. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/.python-version +0 -0
  50. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/AGENTS.md +0 -0
  51. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/LICENSE +0 -0
  52. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/PROJECT_STRUCTURE.md +0 -0
  53. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/README_AGENT_WORKFLOW.md +0 -0
  54. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/README_OLLAMA.md +0 -0
  55. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/cc.png +0 -0
  56. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/superpowers/plans/2026-06-26-file-editor-improvements.md +0 -0
  57. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/superpowers/plans/2026-06-26-session-save-resume.md +0 -0
  58. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/superpowers/specs/2026-06-26-file-editor-improvements-design.md +0 -0
  59. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/docs/superpowers/specs/2026-06-26-session-save-resume-design.md +0 -0
  60. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/check_logging_imports.py +0 -0
  61. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/exception_baseline.txt +0 -0
  62. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/find_percent_logging.py +0 -0
  63. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/scripts/logging_gates.py +0 -0
  64. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/__init__.py +0 -0
  65. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/__main__.py +0 -0
  66. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/__init__.py +0 -0
  67. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/callbacks.py +0 -0
  68. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/run.py +0 -0
  69. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/runner.py +0 -0
  70. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/tool.py +0 -0
  71. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/agents/worktree.py +0 -0
  72. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/application/README.md +0 -0
  73. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/application/__init__.py +0 -0
  74. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/application/execution_policy.py +0 -0
  75. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/application/message_contract.py +0 -0
  76. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/application/validation.py +0 -0
  77. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/cli_callbacks.py +0 -0
  78. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/cli_runner.py +0 -0
  79. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/console.py +0 -0
  80. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/cache_monitor.py +0 -0
  81. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/config_migration.py +0 -0
  82. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/context.py +0 -0
  83. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/context_manager.py +0 -0
  84. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/context_manager_factory.py +0 -0
  85. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/default_context_manager.py +0 -0
  86. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/ollama_context_manager.py +0 -0
  87. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/result.py +0 -0
  88. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/core/session.py +0 -0
  89. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/diagnostics.py +0 -0
  90. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/log.py +0 -0
  91. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/logging_config.py +0 -0
  92. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/loops/__init__.py +0 -0
  93. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/masking.py +0 -0
  94. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/parser.py +0 -0
  95. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/process_manager.py +0 -0
  96. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/prompts.py +0 -0
  97. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/__init__.py +0 -0
  98. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/base.py +0 -0
  99. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/claude.py +0 -0
  100. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/deepseek.py +0 -0
  101. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/gemini.py +0 -0
  102. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/glm.py +0 -0
  103. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/__init__.py +0 -0
  104. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/_errors.py +0 -0
  105. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/base.py +0 -0
  106. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/deepseek.py +0 -0
  107. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/generic_native.py +0 -0
  108. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/generic_xml.py +0 -0
  109. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/matrix.py +0 -0
  110. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/minimax.py +0 -0
  111. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/qwen3.py +0 -0
  112. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_drivers/registry.py +0 -0
  113. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/ollama_inspector.py +0 -0
  114. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/impl/qwen.py +0 -0
  115. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/orchestrator.py +0 -0
  116. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/providers/retry.py +0 -0
  117. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/services/__init__.py +0 -0
  118. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/services/interactions.py +0 -0
  119. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/themes/__init__.py +0 -0
  120. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/themes/ayder.py +0 -0
  121. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/themes/claude.py +0 -0
  122. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/__init__.py +0 -0
  123. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/__init__.py +0 -0
  124. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/background_process_tool.py +0 -0
  125. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/context.py +0 -0
  126. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/context_definitions.py +0 -0
  127. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/note_tool.py +0 -0
  128. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/notes.py +0 -0
  129. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/notes_definitions.py +0 -0
  130. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/process_manager_definitions.py +0 -0
  131. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/search.py +0 -0
  132. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/search_definitions.py +0 -0
  133. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/shell.py +0 -0
  134. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/shell_definitions.py +0 -0
  135. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/skill.py +0 -0
  136. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/skill_definitions.py +0 -0
  137. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/task_definitions.py +0 -0
  138. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/task_tool.py +0 -0
  139. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/tasks.py +0 -0
  140. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/utils_tools.py +0 -0
  141. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/utils_tools_definitions.py +0 -0
  142. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/web.py +0 -0
  143. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/builtins/web_definitions.py +0 -0
  144. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/definition.py +0 -0
  145. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/hooks.py +0 -0
  146. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/normalization.py +0 -0
  147. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/plugin_api.py +0 -0
  148. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/plugin_github.py +0 -0
  149. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/plugin_status.py +0 -0
  150. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/schemas.py +0 -0
  151. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tools/utils.py +0 -0
  152. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/adapter.py +0 -0
  153. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/helpers.py +0 -0
  154. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/keybindings.py +0 -0
  155. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/parser.py +0 -0
  156. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/rendering.py +0 -0
  157. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/screens.py +0 -0
  158. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/theme_manager.py +0 -0
  159. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/tui/types.py +0 -0
  160. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/ui.py +0 -0
  161. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/src/ayder_cli/version.py +0 -0
  162. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/COVERAGE.md +0 -0
  163. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/__init__.py +0 -0
  164. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/__init__.py +0 -0
  165. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_agent_consolidated.py +0 -0
  166. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_agent_severity.py +0 -0
  167. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_agent_tools.py +0 -0
  168. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_callbacks.py +0 -0
  169. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_config.py +0 -0
  170. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_integration.py +0 -0
  171. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_queue.py +0 -0
  172. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_registry.py +0 -0
  173. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_run.py +0 -0
  174. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_runner.py +0 -0
  175. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_runner_provider_unavailable.py +0 -0
  176. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_tool.py +0 -0
  177. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_worktree_helpers.py +0 -0
  178. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/agents/test_worktree_isolation.py +0 -0
  179. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/application/test_execution_result_truthfulness.py +0 -0
  180. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/application/test_message_contract.py +0 -0
  181. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/application/test_runtime_factory.py +0 -0
  182. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/client/test_main.py +0 -0
  183. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/conftest.py +0 -0
  184. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/convergence/__init__.py +0 -0
  185. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/convergence/test_execution_policy_parity.py +0 -0
  186. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/convergence/test_runtime_wiring.py +0 -0
  187. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/convergence/test_validation_path.py +0 -0
  188. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_asyncio_bridge.py +0 -0
  189. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_cache_monitor.py +0 -0
  190. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_config.py +0 -0
  191. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_config_coverage.py +0 -0
  192. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_config_migration.py +0 -0
  193. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_config_provider_logging.py +0 -0
  194. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_config_retry.py +0 -0
  195. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_config_v2.py +0 -0
  196. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_context_manager_factory.py +0 -0
  197. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_default_context_manager.py +0 -0
  198. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_default_context_manager_should_compact.py +0 -0
  199. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_event_emission.py +0 -0
  200. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_event_stream.py +0 -0
  201. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_exception_guarantee.py +0 -0
  202. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_exception_hooks.py +0 -0
  203. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_log_facade.py +0 -0
  204. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_logging_config_keys.py +0 -0
  205. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_logging_sinks.py +0 -0
  206. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_loguru_caplog.py +0 -0
  207. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_ollama_context_manager.py +0 -0
  208. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_ollama_context_manager_cache_monitor.py +0 -0
  209. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_ollama_context_manager_max_history.py +0 -0
  210. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_parameter_aliasing.py +0 -0
  211. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_parser.py +0 -0
  212. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_session.py +0 -0
  213. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_session_id_threading.py +0 -0
  214. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/core/test_sink_masking.py +0 -0
  215. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/loops/__init__.py +0 -0
  216. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/loops/test_base.py +0 -0
  217. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/loops/test_chat_loop_hook.py +0 -0
  218. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/loops/test_chat_loop_tool_truncation.py +0 -0
  219. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/loops/test_loop_severity.py +0 -0
  220. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/__init__.py +0 -0
  221. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/__init__.py +0 -0
  222. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_base.py +0 -0
  223. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_deepseek.py +0 -0
  224. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_errors.py +0 -0
  225. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_fallback.py +0 -0
  226. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_generic_native.py +0 -0
  227. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_generic_xml.py +0 -0
  228. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_matrix.py +0 -0
  229. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_minimax.py +0 -0
  230. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_provider_integration.py +0 -0
  231. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_qwen3.py +0 -0
  232. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/ollama_drivers/test_registry.py +0 -0
  233. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_glm_async.py +0 -0
  234. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_ollama_inspector.py +0 -0
  235. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_ollama_native.py +0 -0
  236. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_ollama_xml.py +0 -0
  237. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_ollama_xml_autoroute.py +0 -0
  238. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_ollama_xml_usage.py +0 -0
  239. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_orchestrator_capabilities.py +0 -0
  240. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_provider_channel_binding.py +0 -0
  241. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_provider_severity.py +0 -0
  242. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_qwen_async.py +0 -0
  243. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_retry_classifier.py +0 -0
  244. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_retry_integration.py +0 -0
  245. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/providers/test_retrying_provider.py +0 -0
  246. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/scripts/test_logging_policy_gates.py +0 -0
  247. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/scripts/test_loguru_private_shape.py +0 -0
  248. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/services/test_boundary.py +0 -0
  249. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/services/test_interaction_sink.py +0 -0
  250. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_cli.py +0 -0
  251. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_cli_callbacks.py +0 -0
  252. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_context.py +0 -0
  253. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_env_manager.py +0 -0
  254. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_logging_config.py +0 -0
  255. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_notes.py +0 -0
  256. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_process_manager.py +0 -0
  257. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/test_tasks.py +0 -0
  258. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/__init__.py +0 -0
  259. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_agent_notes.py +0 -0
  260. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_background_process_tool.py +0 -0
  261. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_bash_tool.py +0 -0
  262. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_definition_discovery.py +0 -0
  263. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_di_injection.py +0 -0
  264. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_file_editor_hardening.py +0 -0
  265. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_impl.py +0 -0
  266. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_impl_coverage.py +0 -0
  267. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_note_tool.py +0 -0
  268. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_notes_api.py +0 -0
  269. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_path_security.py +0 -0
  270. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_plugin_api.py +0 -0
  271. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_plugin_github.py +0 -0
  272. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_plugin_loading.py +0 -0
  273. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_plugin_manager.py +0 -0
  274. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_plugin_status.py +0 -0
  275. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_registry.py +0 -0
  276. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_registry_coverage.py +0 -0
  277. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_result.py +0 -0
  278. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_schemas.py +0 -0
  279. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_search_codebase.py +0 -0
  280. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_search_hardening.py +0 -0
  281. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_skill_tool.py +0 -0
  282. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_task_tool.py +0 -0
  283. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_tool_severity.py +0 -0
  284. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_utils.py +0 -0
  285. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tools/test_web.py +0 -0
  286. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/__init__.py +0 -0
  287. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_agent_list_screen.py +0 -0
  288. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_do_clear_coordination.py +0 -0
  289. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_follow_mode.py +0 -0
  290. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_help_screen.py +0 -0
  291. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_input_box.py +0 -0
  292. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_keybindings.py +0 -0
  293. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_multi_select_screen.py +0 -0
  294. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_multiline_input.py +0 -0
  295. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_paste.py +0 -0
  296. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_pending_compact_consumer.py +0 -0
  297. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_pull_delivery.py +0 -0
  298. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_resume.py +0 -0
  299. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_status_bar_badges.py +0 -0
  300. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_themes.py +0 -0
  301. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/tui/test_turn_consumer.py +0 -0
  302. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_diff_preview.py +0 -0
  303. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_plugin_autoenable.py +0 -0
  304. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_provider_switch.py +0 -0
  305. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_run_tui_startup.py +0 -0
  306. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_assistant_sanitization.py +0 -0
  307. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_chat_loop.py +0 -0
  308. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_commands_agent.py +0 -0
  309. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_commands_logging.py +0 -0
  310. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_commands_plugin.py +0 -0
  311. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_commands_skill.py +0 -0
  312. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_helpers.py +0 -0
  313. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_temporal_command.py +0 -0
  314. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_tui_widgets.py +0 -0
  315. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_ui.py +0 -0
  316. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_ui_coverage.py +0 -0
  317. {ayder_cli-2.3.0 → ayder_cli-2.3.1}/tests/ui/test_ui_verbose.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ayder-cli
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: AI agent for any LLMs
5
5
  Project-URL: Homepage, https://github.com/ayder/ayder-cli
6
6
  Project-URL: Repository, https://github.com/ayder/ayder-cli.git
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3
16
16
  Requires-Python: >=3.12
17
17
  Requires-Dist: httpx
18
18
  Requires-Dist: loguru<0.8,>=0.7
19
+ Requires-Dist: mcp<2,>=1.19
19
20
  Requires-Dist: ollama>=0.6.2
20
21
  Requires-Dist: openai
21
22
  Requires-Dist: python-dotenv>=1.0.0
@@ -26,17 +27,16 @@ Provides-Extra: all
26
27
  Requires-Dist: anthropic; extra == 'all'
27
28
  Requires-Dist: dashscope; extra == 'all'
28
29
  Requires-Dist: google-genai; extra == 'all'
29
- Requires-Dist: zhipuai; extra == 'all'
30
+ Requires-Dist: zhipuai>=2; extra == 'all'
30
31
  Provides-Extra: anthropic
31
32
  Requires-Dist: anthropic; extra == 'anthropic'
32
33
  Provides-Extra: glm
33
- Requires-Dist: zhipuai; extra == 'glm'
34
+ Requires-Dist: zhipuai>=2; extra == 'glm'
34
35
  Provides-Extra: google
35
36
  Requires-Dist: google-genai; extra == 'google'
36
37
  Provides-Extra: libcst
37
38
  Requires-Dist: libcst>=1.0.0; extra == 'libcst'
38
39
  Provides-Extra: mcp
39
- Requires-Dist: mcp; extra == 'mcp'
40
40
  Provides-Extra: qwen
41
41
  Requires-Dist: dashscope; extra == 'qwen'
42
42
  Description-Content-Type: text/markdown
@@ -266,6 +266,50 @@ num_ctx = 1000000
266
266
 
267
267
  Please adjust `num_ctx` context size window according to your local computer RAM. If Ollama crashes, decrease the value.
268
268
 
269
+ ### Reasoning Effort (`/effort`)
270
+
271
+ Use `/effort` to open a picker, or `/effort high` to change the active session.
272
+ Changes apply between turns and are inherited by future agents that use the
273
+ session's profile; explicit agent settings take precedence. They do not change
274
+ `config.toml`. `/effort default` restores the provider's default behavior
275
+ (omits OpenAI effort and Ollama's `think` parameter).
276
+
277
+ | Driver | Runtime values |
278
+ |--------|----------------|
279
+ | `openai` | `default`, `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` |
280
+ | `ollama` | `default`, `on`, `off`, `low`, `medium`, `high` (`true`/`false` and `none` are also accepted) |
281
+
282
+ Support varies by model. OpenAI values follow its
283
+ [Chat Completions API](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create).
284
+ Ollama uses the installed Python SDK's boolean and three-level `think` options;
285
+ its SDK does not yet accept the server API's newer `max` value. GPT-OSS expects
286
+ `low`, `medium`, or `high`, and cannot disable thinking. See
287
+ [Ollama thinking](https://docs.ollama.com/capabilities/thinking).
288
+
289
+ Set persistent defaults per LLM profile and agent:
290
+
291
+ ```toml
292
+ [llm.openai]
293
+ driver = "openai"
294
+ reasoning_effort = "medium"
295
+
296
+ [llm.ollama]
297
+ driver = "ollama"
298
+ reasoning_effort = "high"
299
+
300
+ [agents.reviewer]
301
+ provider = "openai"
302
+ reasoning_effort = "high"
303
+ system_prompt = "Review code and report findings."
304
+ ```
305
+
306
+ Omit an agent's `reasoning_effort` to inherit its profile, or set it to
307
+ `"default"` to clear an inherited effort. On Ollama, `"none"` maps to
308
+ `think = false`; an explicit effort overrides the legacy `think` setting.
309
+ Existing `think = true/false/"low"/"medium"/"high"` profile and agent settings
310
+ remain supported. OpenAI omits reasoning effort by default, preserving
311
+ compatibility with models and endpoints that do not support it.
312
+
269
313
  ### Changing Models on the Fly (`/model`)
270
314
 
271
315
  You do **not** need a separate profile for every model. The profile defines the *connection* (driver, base URL, API key).
@@ -392,6 +436,7 @@ You can also manually manage context with the `context` tool and its slash-comma
392
436
  | `/help` | Show available commands and keyboard shortcuts |
393
437
  | `/provider` | Switch LLM provider (interactive selector or direct name) |
394
438
  | `/model` | List available models or switch model (e.g., `/model qwen3-coder`) |
439
+ | `/effort` | Pick reasoning effort or set it directly (e.g., `/effort high`) |
395
440
  | `/plugin` | Toggle tool plugins by tag (e.g., venv, http, background, python, dbs) |
396
441
  | `/tools` | List currently enabled tools and descriptions |
397
442
  | `/permission` | Toggle permission levels (r/w/x/http) interactively |
@@ -670,9 +715,46 @@ RECOMMENDATIONS: Parameterize all DB queries; add Pydantic validators to all end
670
715
 
671
716
  This summary is injected into the main LLM's context as a system message so the main agent can act on it, summarize it for you, or chain it to further work.
672
717
 
718
+ ## MCP servers
719
+
720
+ MCP support is built in and installed with Ayder. Add `.ayder/mcp.json` in your
721
+ project root, then start Ayder:
722
+
723
+ ```json
724
+ {
725
+ "mcpServers": {
726
+ "local-tools": {
727
+ "command": "python",
728
+ "args": ["server.py"],
729
+ "env": {"EXAMPLE_SETTING": "value"}
730
+ },
731
+ "remote-tools": {
732
+ "url": "http://localhost:8000/mcp"
733
+ }
734
+ }
735
+ }
736
+ ```
737
+
738
+ Local servers use stdio and run from the project root; remote servers use
739
+ Streamable HTTP. Their tools automatically join the standard `core` toolset in
740
+ the CLI, TUI, and delegated agents. No plugin installation or `/plugin` toggle
741
+ is needed. Tool calls retain the usual permissions: `x` for stdio servers and
742
+ `http` for HTTP servers. Configure only servers you intend Ayder to connect to:
743
+ local server commands start during runtime initialization to discover tools.
744
+
745
+ Tools keep their server-provided names unless they conflict with an existing
746
+ tool; conflicting names receive a `server__` prefix (and a numeric suffix if
747
+ needed). Unreachable servers are skipped so other tools remain available.
748
+ Connections are shared by agents in the same project and closed on process
749
+ exit. Restart Ayder after changing `mcp.json`.
750
+
751
+ Existing `mcp-tool` plugin installations are automatically skipped in favor of
752
+ built-in support; your existing `.ayder/mcp.json` continues to work. The legacy
753
+ `ayder-cli[mcp]` installation extra is still accepted.
754
+
673
755
  ## Plugins
674
756
 
675
- Official plugins (venv, python, dbs, mcp, temporal) are maintained in the **[ayder/ayder-plugins](https://github.com/ayder/ayder-plugins)** repository. Install any plugin directly from GitHub:
757
+ Official plugins (venv, python, dbs, temporal) are maintained in the **[ayder/ayder-plugins](https://github.com/ayder/ayder-plugins)** repository. Install any plugin directly from GitHub:
676
758
 
677
759
  ```bash
678
760
  ayder install-plugin https://github.com/ayder/ayder-plugins/tree/main/venv-tools
@@ -223,6 +223,50 @@ num_ctx = 1000000
223
223
 
224
224
  Please adjust `num_ctx` context size window according to your local computer RAM. If Ollama crashes, decrease the value.
225
225
 
226
+ ### Reasoning Effort (`/effort`)
227
+
228
+ Use `/effort` to open a picker, or `/effort high` to change the active session.
229
+ Changes apply between turns and are inherited by future agents that use the
230
+ session's profile; explicit agent settings take precedence. They do not change
231
+ `config.toml`. `/effort default` restores the provider's default behavior
232
+ (omits OpenAI effort and Ollama's `think` parameter).
233
+
234
+ | Driver | Runtime values |
235
+ |--------|----------------|
236
+ | `openai` | `default`, `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` |
237
+ | `ollama` | `default`, `on`, `off`, `low`, `medium`, `high` (`true`/`false` and `none` are also accepted) |
238
+
239
+ Support varies by model. OpenAI values follow its
240
+ [Chat Completions API](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create).
241
+ Ollama uses the installed Python SDK's boolean and three-level `think` options;
242
+ its SDK does not yet accept the server API's newer `max` value. GPT-OSS expects
243
+ `low`, `medium`, or `high`, and cannot disable thinking. See
244
+ [Ollama thinking](https://docs.ollama.com/capabilities/thinking).
245
+
246
+ Set persistent defaults per LLM profile and agent:
247
+
248
+ ```toml
249
+ [llm.openai]
250
+ driver = "openai"
251
+ reasoning_effort = "medium"
252
+
253
+ [llm.ollama]
254
+ driver = "ollama"
255
+ reasoning_effort = "high"
256
+
257
+ [agents.reviewer]
258
+ provider = "openai"
259
+ reasoning_effort = "high"
260
+ system_prompt = "Review code and report findings."
261
+ ```
262
+
263
+ Omit an agent's `reasoning_effort` to inherit its profile, or set it to
264
+ `"default"` to clear an inherited effort. On Ollama, `"none"` maps to
265
+ `think = false`; an explicit effort overrides the legacy `think` setting.
266
+ Existing `think = true/false/"low"/"medium"/"high"` profile and agent settings
267
+ remain supported. OpenAI omits reasoning effort by default, preserving
268
+ compatibility with models and endpoints that do not support it.
269
+
226
270
  ### Changing Models on the Fly (`/model`)
227
271
 
228
272
  You do **not** need a separate profile for every model. The profile defines the *connection* (driver, base URL, API key).
@@ -349,6 +393,7 @@ You can also manually manage context with the `context` tool and its slash-comma
349
393
  | `/help` | Show available commands and keyboard shortcuts |
350
394
  | `/provider` | Switch LLM provider (interactive selector or direct name) |
351
395
  | `/model` | List available models or switch model (e.g., `/model qwen3-coder`) |
396
+ | `/effort` | Pick reasoning effort or set it directly (e.g., `/effort high`) |
352
397
  | `/plugin` | Toggle tool plugins by tag (e.g., venv, http, background, python, dbs) |
353
398
  | `/tools` | List currently enabled tools and descriptions |
354
399
  | `/permission` | Toggle permission levels (r/w/x/http) interactively |
@@ -627,9 +672,46 @@ RECOMMENDATIONS: Parameterize all DB queries; add Pydantic validators to all end
627
672
 
628
673
  This summary is injected into the main LLM's context as a system message so the main agent can act on it, summarize it for you, or chain it to further work.
629
674
 
675
+ ## MCP servers
676
+
677
+ MCP support is built in and installed with Ayder. Add `.ayder/mcp.json` in your
678
+ project root, then start Ayder:
679
+
680
+ ```json
681
+ {
682
+ "mcpServers": {
683
+ "local-tools": {
684
+ "command": "python",
685
+ "args": ["server.py"],
686
+ "env": {"EXAMPLE_SETTING": "value"}
687
+ },
688
+ "remote-tools": {
689
+ "url": "http://localhost:8000/mcp"
690
+ }
691
+ }
692
+ }
693
+ ```
694
+
695
+ Local servers use stdio and run from the project root; remote servers use
696
+ Streamable HTTP. Their tools automatically join the standard `core` toolset in
697
+ the CLI, TUI, and delegated agents. No plugin installation or `/plugin` toggle
698
+ is needed. Tool calls retain the usual permissions: `x` for stdio servers and
699
+ `http` for HTTP servers. Configure only servers you intend Ayder to connect to:
700
+ local server commands start during runtime initialization to discover tools.
701
+
702
+ Tools keep their server-provided names unless they conflict with an existing
703
+ tool; conflicting names receive a `server__` prefix (and a numeric suffix if
704
+ needed). Unreachable servers are skipped so other tools remain available.
705
+ Connections are shared by agents in the same project and closed on process
706
+ exit. Restart Ayder after changing `mcp.json`.
707
+
708
+ Existing `mcp-tool` plugin installations are automatically skipped in favor of
709
+ built-in support; your existing `.ayder/mcp.json` continues to work. The legacy
710
+ `ayder-cli[mcp]` installation extra is still accepted.
711
+
630
712
  ## Plugins
631
713
 
632
- Official plugins (venv, python, dbs, mcp, temporal) are maintained in the **[ayder/ayder-plugins](https://github.com/ayder/ayder-plugins)** repository. Install any plugin directly from GitHub:
714
+ Official plugins (venv, python, dbs, temporal) are maintained in the **[ayder/ayder-plugins](https://github.com/ayder/ayder-plugins)** repository. Install any plugin directly from GitHub:
633
715
 
634
716
  ```bash
635
717
  ayder install-plugin https://github.com/ayder/ayder-plugins/tree/main/venv-tools
@@ -48,12 +48,15 @@
48
48
  # `export OLLAMA_API_KEY="<key>"`. The api_key config field is INERT on the
49
49
  # native path, so a missing env var ⇒ 401 Unauthorized.
50
50
  #
51
- # NOTE on `think`: on the native `ollama` driver, ayder defaults thinking ON
52
- # (think = true) and forwards either a boolean or Ollama's "low",
53
- # "medium", "high" levels. If a selected model rejects thinking mode,
54
- # ayder retries that request once with think=false. Set `think = false`
55
- # in an [llm.*] profile for known non-thinking models. The `openai`
56
- # driver sends no reasoning-effort parameter at all.
51
+ # Reasoning defaults can be set in [llm.*] and overridden in [agents.*].
52
+ # reasoning_effort = "default" uses existing think behavior on Ollama and omits
53
+ # the effort parameter on OpenAI. Explicit effort overrides legacy `think`.
54
+ # OpenAI: none, minimal, low, medium, high, xhigh, max (model-dependent).
55
+ # Ollama SDK: none (= think=false), low, medium, high. To enable/disable
56
+ # boolean thinking explicitly, the legacy think = true/false still works.
57
+ # Use /effort in the TUI for a session-only override or interactive picker.
58
+ # Explicit unsupported efforts report a server error; only legacy `think`
59
+ # retains the automatic retry with think=false for non-thinking models.
57
60
  #
58
61
  # NOTE on tuning knobs — which actually take effect depends on the DRIVER. These
59
62
  # agents run on the native `ollama` driver, which ignores most of them:
@@ -69,8 +72,8 @@
69
72
  # path it sizes the context-manager budget.
70
73
  # Default 65536.
71
74
  # The per-agent temperature / max_output_tokens values below are largely
72
- # INERT on this Ollama pipeline; per-agent `think` is applied when the
73
- # agent uses the native ollama driver.
75
+ # INERT on this Ollama pipeline; per-agent reasoning_effort takes
76
+ # precedence over the selected profile.
74
77
  # =============================================================================
75
78
 
76
79
  config_version = "2.0"
@@ -167,6 +170,7 @@ driver = "ollama"
167
170
  base_url = "http://localhost:11434" # route :cloud models through the LOCAL daemon (auth via ~/.ollama/id_ed25519, one-time `ollama signin`)
168
171
  model = "deepseek-v4-pro:cloud" # orchestrator default; per-agent `model` overrides this
169
172
  num_ctx = 131072
173
+ reasoning_effort = "default"
170
174
  think = true # default; set false for known non-thinking models
171
175
  # To hit ollama.com directly instead, swap the line above for:
172
176
  # base_url = "https://ollama.com" # no /v1; then `export OLLAMA_API_KEY=<key>` (the api_key field is inert on this path)
@@ -176,6 +180,7 @@ driver = "ollama"
176
180
  base_url = "http://localhost:11434"
177
181
  model = "qwen3.6:35b-a3b-coding-nvfp4"
178
182
  num_ctx = 32768 # keep modest: local VRAM is the constraint
183
+ reasoning_effort = "default"
179
184
  think = true # default; set false if the selected model rejects thinking
180
185
 
181
186
  # Budget/throughput alternative — swap any cloud agent's `provider` to this, or
@@ -198,7 +203,8 @@ think = true # default; set false if the selected model r
198
203
  # num_ctx = 65536 # sizes the context-manager budget (default 65536); NOT sent to the API
199
204
  # max_output_tokens = 8192 # -> max_tokens / max_completion_tokens (default 4096); keep WELL below num_ctx
200
205
  # stop_sequences = [] # -> stop (default [])
201
- # # temperature / think are NOT applied by the openai driver today (no-ops) — omitted on purpose.
206
+ # reasoning_effort = "medium" # choose a value supported by the selected model
207
+ # # temperature / think are NOT applied by the openai driver.
202
208
 
203
209
  # =============================================================================
204
210
  # Agents
@@ -211,7 +217,7 @@ provider = "ollama_cloud"
211
217
  model = "glm-5.2:cloud"
212
218
  temperature = 0.4
213
219
  max_output_tokens = 8192
214
- think = "high"
220
+ reasoning_effort = "high"
215
221
  system_prompt = """
216
222
  You are Project Manager #1 — the requirements analyst and spec author.
217
223
 
@@ -239,7 +245,7 @@ provider = "ollama_cloud"
239
245
  model = "deepseek-v4-pro:cloud"
240
246
  temperature = 0.2
241
247
  max_output_tokens = 4096
242
- think = "high"
248
+ reasoning_effort = "high"
243
249
  system_prompt = """
244
250
  You are Project Manager #2 — the independent spec reviewer.
245
251
 
@@ -268,7 +274,7 @@ provider = "ollama_cloud"
268
274
  model = "deepseek-v4-pro:cloud"
269
275
  temperature = 0.3
270
276
  max_output_tokens = 8192
271
- think = "high"
277
+ reasoning_effort = "high"
272
278
  num_ctx = 262144 # long window: hold the whole spec while splitting it into tasks (delays compaction)
273
279
  system_prompt = """
274
280
  You are the Architect — you turn an APPROVED spec into an implementation plan.
@@ -296,7 +302,7 @@ provider = "ollama_cloud"
296
302
  model = "kimi-k2.7-code:cloud"
297
303
  temperature = 0.2
298
304
  max_output_tokens = 8192
299
- think = "high"
305
+ reasoning_effort = "high"
300
306
  system_prompt = """
301
307
  You are the Architecture Reviewer — independent of the Architect.
302
308
 
@@ -398,7 +404,7 @@ provider = "ollama_cloud"
398
404
  model = "kimi-k2.7-code:cloud"
399
405
  temperature = 0.1
400
406
  max_output_tokens = 4096
401
- think = "high"
407
+ reasoning_effort = "high"
402
408
  system_prompt = """
403
409
  You are the Code Reviewer. You review a diff for correctness and quality.
404
410
 
@@ -424,7 +430,7 @@ provider = "ollama_cloud"
424
430
  model = "minimax-m3:cloud"
425
431
  temperature = 0.1
426
432
  max_output_tokens = 4096
427
- think = "high"
433
+ reasoning_effort = "high"
428
434
  num_ctx = 262144 # long window: holds spec + all criteria + diff + test output at once
429
435
  system_prompt = """
430
436
  You are the Acceptance Gate — the final, independent check before "done".
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ayder-cli"
7
- version = "2.3.0"
7
+ version = "2.3.1"
8
8
  description = "AI agent for any LLMs"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -26,6 +26,7 @@ dependencies = [
26
26
  # Message / StreamSink shapes (§F5-R6), guarded by `_shape_guard()`.
27
27
  "loguru>=0.7,<0.8",
28
28
  "httpx",
29
+ "mcp>=1.19,<2",
29
30
  "rich>=13.0.0",
30
31
  # Pinned exactly to match the runtime: 8.2.5+ replaced the single
31
32
  # "textual-ansi" builtin with per-theme `ansi` flags and ansi-dark/
@@ -39,9 +40,12 @@ dependencies = [
39
40
  anthropic = ["anthropic"]
40
41
  google = ["google-genai"]
41
42
  qwen = ["dashscope"]
42
- glm = ["zhipuai"]
43
+ # The provider uses the v2 client; do not let MCP's shared PyJWT dependency
44
+ # make the resolver select the incompatible v1 SDK.
45
+ glm = ["zhipuai>=2"]
43
46
  all = ["ayder-cli[anthropic,google,qwen,glm]"]
44
- mcp = ["mcp"]
47
+ # Compatibility extra: MCP is now included in every installation.
48
+ mcp = []
45
49
  # Optional: required only by plugins that do CST-based code transforms.
46
50
  libcst = ["libcst>=1.0.0"]
47
51
 
@@ -71,7 +75,7 @@ dev = [
71
75
  "anthropic",
72
76
  "google-genai",
73
77
  "dashscope",
74
- "zhipuai",
78
+ "zhipuai>=2",
75
79
  ]
76
80
 
77
81
  [tool.poe.tasks]
@@ -24,7 +24,7 @@ DEFAULT_BASELINE = REPO / "scripts" / "exception_baseline.txt"
24
24
 
25
25
  # Frozen census (§C10). A different number means the gate is looking at the
26
26
  # wrong tree, or the census moved without the plan being updated.
27
- EXPECTED_BROAD = 131
27
+ EXPECTED_BROAD = 138
28
28
  BRANCHING = (ast.If, ast.Try, ast.For, ast.While, ast.With, ast.Match)
29
29
  TERMINAL = (ast.Return, ast.Break, ast.Continue, ast.Pass)
30
30
 
@@ -203,13 +203,13 @@ FROZEN_CHAIN_SITES: dict[tuple[str, str, str, str], tuple[str, int]] = {
203
203
  ("log.py", "emit_event", "bind", "**"): ("Name(id='fields', ctx=Load())", 1),
204
204
  }
205
205
 
206
- # The 93 `exception=True` inputs are homogeneous, so they are governed as one
207
- # package-wide shape/count rule rather than 93 site identities - their per-site
206
+ # The 100 `exception=True` inputs are homogeneous, so they are governed as one
207
+ # package-wide shape/count rule rather than 100 site identities - their per-site
208
208
  # discipline is C10's.
209
- FROZEN_EXCEPTION_TRUE = 93
209
+ FROZEN_EXCEPTION_TRUE = 100
210
210
 
211
211
  # Live chain inputs, counted per method. Printed on every run.
212
- CHAIN_TALLY: dict[str, int] = {"bind": 6, "opt": 97, "patch": 0}
212
+ CHAIN_TALLY: dict[str, int] = {"bind": 6, "opt": 104, "patch": 0}
213
213
 
214
214
  # The reviewed composition of THE COMMITTED baseline, frozen by the Phase 5
215
215
  # census: 252 retained non-path + 22 paths + 2 deferred interpolated rows, plus
@@ -218,12 +218,12 @@ CHAIN_TALLY: dict[str, int] = {"bind": 6, "opt": 97, "patch": 0}
218
218
  # unchanged - so the composition is gated too. Caller-supplied baselines (the
219
219
  # gate's own synthetic fixtures) are exempt: this is a fact about one file.
220
220
  FROZEN_TALLY: dict[str, int] = {
221
- "R-name": 93,
222
- "R-id": 36,
223
- "R-count": 88,
221
+ "R-name": 96,
222
+ "R-id": 40,
223
+ "R-count": 90,
224
224
  "R-status": 27,
225
225
  "R-class": 10,
226
- "R-path": 22,
226
+ "R-path": 24,
227
227
  # Both 5-04 deferrals are closed: the two asyncio rows now interpolate the
228
228
  # B2-prime normalized value, and the bridge's dynamic message is masked by
229
229
  # the prose sinks it reaches.
@@ -1,6 +1,8 @@
1
1
  {"class":"dynamic-residual:known-shape-masked","site":{"arg_index":"bind:lib","expr":"record.name","message":null,"method":"bind","path":"logging_config.py","qualname":"_InterceptHandler.emit"}}
2
2
  {"class":"R-name","site":{"arg_index":"kw:agent","expr":"run.agent_name","message":null,"method":"emit_event","path":"agents/registry.py","qualname":"AgentRegistry._run_and_queue"}}
3
+ {"class":"R-count","site":{"arg_index":"kw:arg_chars","expr":"arg_chars","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call_received"}}
3
4
  {"class":"R-count","site":{"arg_index":"kw:args_len","expr":"len(str(args or ''))","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
5
+ {"class":"R-id","site":{"arg_index":"kw:call_id","expr":"call_id","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call_received"}}
4
6
  {"class":"R-count","site":{"arg_index":"kw:content_len","expr":"len(final_content)","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
5
7
  {"class":"R-class","site":{"arg_index":"kw:err_type","expr":"None if ok else type(exec_result.error).__name__","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
6
8
  {"class":"R-count","site":{"arg_index":"kw:hist_tokens","expr":"self._total_tokens","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
@@ -9,6 +11,7 @@
9
11
  {"class":"R-count","site":{"arg_index":"kw:ms","expr":"int((time.perf_counter() - started) * 1000)","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
10
12
  {"class":"R-count","site":{"arg_index":"kw:n","expr":"iteration_n","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
11
13
  {"class":"R-name","site":{"arg_index":"kw:name","expr":"name","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
14
+ {"class":"R-name","site":{"arg_index":"kw:name","expr":"name","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call_received"}}
12
15
  {"class":"R-status","site":{"arg_index":"kw:ok","expr":"ok","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
13
16
  {"class":"R-count","site":{"arg_index":"kw:reasoning_len","expr":"len(final_reasoning)","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
14
17
  {"class":"R-id","site":{"arg_index":"kw:run_id","expr":"run.run_id","message":null,"method":"emit_event","path":"agents/registry.py","qualname":"AgentRegistry._run_and_queue"}}
@@ -39,6 +42,7 @@
39
42
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"driver.name","message":"Ollama driver={} mode={} for {!r}","method":"info","path":"providers/impl/ollama.py","qualname":"OllamaProvider.stream_with_tools"}}
40
43
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"driver.name","message":"{} ({}) failed mid-stream (error_type={}); transparently retrying with {} ({})","method":"info","path":"providers/impl/ollama.py","qualname":"OllamaProvider.stream_with_tools"}}
41
44
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"err_name","message":"Appending Tool Error [{}] to history: {} chars","method":"trace","path":"loops/chat_loop.py","qualname":"ChatLoop._execute_tool_calls"}}
45
+ {"class":"R-name","site":{"arg_index":"pos:0","expr":"existing_tc['function']['name']","message":"Tool call id reused by a different tool ({} then {}); calls would merge","method":"warning","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
42
46
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"file_path","message":"Diff preview generation failed for {}","method":"debug","path":"ui.py","qualname":"generate_diff_preview"}}
43
47
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"file_path","message":"Failed to render file panel for {}","method":"warning","path":"ui.py","qualname":"print_file_content"}}
44
48
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"file_path","message":"Failed to render file panel for {}","method":"warning","path":"ui.py","qualname":"print_file_content_rich"}}
@@ -55,6 +59,7 @@
55
59
  {"class":"R-count","site":{"arg_index":"pos:0","expr":"len(self._frozen_system or '')","message":"Context: system prompt updated on first call ({} \u2192 {} chars)","method":"info","path":"core/ollama_context_manager.py","qualname":"OllamaContextManager.prepare_messages"}}
56
60
  {"class":"R-count","site":{"arg_index":"pos:0","expr":"len(system_content)","message":"Context: system prompt frozen ({} chars, {} tool schemas, ctx={})","method":"info","path":"core/ollama_context_manager.py","qualname":"OllamaContextManager.freeze_system_prompt"}}
57
61
  {"class":"R-count","site":{"arg_index":"pos:0","expr":"len(text)","message":"Encoder failed unexpectedly on a string of length {}; disabling it for the rest of this session","method":"debug","path":"core/default_context_manager.py","qualname":"TokenCounter._estimate_string"}}
62
+ {"class":"R-count","site":{"arg_index":"pos:0","expr":"len(text)","message":"Inbox: accepted a {}-char prompt","method":"info","path":"services/messaging_inbox.py","qualname":"MessagingInbox._handle_client"}}
58
63
  {"class":"R-count","site":{"arg_index":"pos:0","expr":"len(v)","message":"Unsupported driver (value_chars={}); must be one of: {}. Fix the driver in your [llm.<provider>] profile.","method":"error","path":"core/config.py","qualname":"Config.validate_driver"}}
59
64
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"manifest.name","message":"Dependency install failed for plugin {!r}; rolling back","method":"error","path":"cli.py","qualname":"main"}}
60
65
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"manifest.name","message":"Installed plugin '{}' v{}","method":"info","path":"tools/plugin_manager.py","qualname":"install_plugin_from_github"}}
@@ -82,12 +87,14 @@
82
87
  {"class":"R-status","site":{"arg_index":"pos:0","expr":"normalized","message":"Unhandled asyncio exception: {}","method":"critical","path":"diagnostics.py","qualname":"_handle_asyncio"}}
83
88
  {"class":"R-count","site":{"arg_index":"pos:0","expr":"num_ctx","message":"Context budget: {} tokens (derived from num_ctx; max_context_tokens unset)","method":"info","path":"core/default_context_manager.py","qualname":"DefaultContextManager.__init__"}}
84
89
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"panel_id","message":"Panel lookup failed for {}","method":"debug","path":"tui/app.py","qualname":"AyderApp._scroll_open_panel"}}
90
+ {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Could not remove {}","method":"debug","path":"services/messaging_inbox.py","qualname":"MessagingInbox.stop"}}
85
91
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Failed to read note file {}","method":"error","path":"tui/commands.py","qualname":"_open_note_in_editor"}}
86
92
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Failed to read task file {}","method":"error","path":"tui/commands.py","qualname":"_open_task_in_editor"}}
87
93
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Failed to read task file {}","method":"warning","path":"tools/builtins/tasks.py","qualname":"read_task"}}
88
94
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Failed to save note file {}","method":"error","path":"tui/commands.py","qualname":"_open_note_in_editor.on_edit_result"}}
89
95
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Failed to save task file {}","method":"error","path":"tui/commands.py","qualname":"_open_task_in_editor.on_edit_result"}}
90
96
  {"class":"R-path","site":{"arg_index":"pos:0","expr":"path","message":"Unreadable context slot at {}: {}","method":"warning","path":"tools/builtins/context.py","qualname":"_scan_context_dir"}}
97
+ {"class":"R-id","site":{"arg_index":"pos:0","expr":"pid","message":"Could not determine process start time for pid {}","method":"debug","path":"services/messaging_inbox.py","qualname":"proc_start"}}
91
98
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"plugin_dir.name","message":"Loaded global plugin '{}' ({} tools)","method":"info","path":"tools/plugin_manager.py","qualname":"discover_global_plugins"}}
92
99
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"plugin_dir.name","message":"Loaded project plugin '{}' ({} tools)","method":"info","path":"tools/registry.py","qualname":"_load_project_plugins"}}
93
100
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"plugin_dir.name","message":"Plugin '{}' is missing a dependency ({!r}). Reinstall it to install its declared dependencies \u2014 e.g. `ayder install-plugin {} --force` \u2014 or install the package manually.","method":"warning","path":"tools/plugin_manager.py","qualname":"discover_global_plugins"}}
@@ -116,6 +123,7 @@
116
123
  {"class":"R-count","site":{"arg_index":"pos:0","expr":"self._history[-1].ns_per_token","message":"KV-cache invalidated: was {:.0f} ns/tok, now {:.0f} ns/tok. Prefix likely changed.","method":"warning","path":"core/cache_monitor.py","qualname":"CacheMonitor.record"}}
117
124
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"self._model or '?'","message":"Context[{}]: {}/{} tokens ({:.0f}%), completion={}, speed={}{}","method":"debug","path":"core/ollama_context_manager.py","qualname":"OllamaContextManager.update_from_response"}}
118
125
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"self._model","message":"Context: model '{}' did not report context_length, using configured num_ctx={}","method":"info","path":"core/ollama_context_manager.py","qualname":"OllamaContextManager.detect_context_length"}}
126
+ {"class":"R-path","site":{"arg_index":"pos:0","expr":"self._sock_path","message":"Messaging inbox listening at {}","method":"info","path":"services/messaging_inbox.py","qualname":"MessagingInbox.start"}}
119
127
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"self.agent_name","message":"Agent '{}' auto-approving tool: {}","method":"debug","path":"agents/callbacks.py","qualname":"AgentCallbacks.request_confirmation"}}
120
128
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"self.agent_name","message":"Agent '{}' failed","method":"exception","path":"agents/runner.py","qualname":"AgentRunner.run"}}
121
129
  {"class":"R-name","site":{"arg_index":"pos:0","expr":"self.agent_name","message":"agent token_usage: agent='{}' run_id={} tokens={}","method":"debug","path":"agents/callbacks.py","qualname":"AgentCallbacks.on_token_usage"}}
@@ -211,6 +219,7 @@
211
219
  {"class":"R-id","site":{"arg_index":"pos:1","expr":"self.run_id","message":"run timeout: agent='{}' run_id={} after {}s","method":"debug","path":"agents/runner.py","qualname":"AgentRunner.run"}}
212
220
  {"class":"R-id","site":{"arg_index":"pos:1","expr":"self.run_id","message":"run vacuous: agent='{}' run_id={}","method":"error","path":"agents/runner.py","qualname":"AgentRunner.run"}}
213
221
  {"class":"R-path","site":{"arg_index":"pos:1","expr":"source","message":"Source path for '{}' no longer exists: {}","method":"warning","path":"tools/plugin_manager.py","qualname":"update_plugin"}}
222
+ {"class":"R-name","site":{"arg_index":"pos:1","expr":"tc.name","message":"Tool call id reused by a different tool ({} then {}); calls would merge","method":"warning","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
214
223
  {"class":"R-status","site":{"arg_index":"pos:1","expr":"think","message":"Ollama model {!r} rejected think={!r}; retrying with think=False","method":"info","path":"providers/impl/ollama.py","qualname":"OllamaProvider._stream_in_content"}}
215
224
  {"class":"R-status","site":{"arg_index":"pos:1","expr":"think","message":"Ollama model {!r} rejected think={!r}; retrying with think=False","method":"info","path":"providers/impl/ollama.py","qualname":"OllamaProvider._stream_native"}}
216
225
  {"class":"R-class","site":{"arg_index":"pos:1","expr":"type(exc).__name__","message":"Provider retry budget exhausted after {} attempts; raising {}","method":"warning","path":"providers/retry.py","qualname":"RetryingProvider.stream_with_tools"}}
@@ -272,8 +281,10 @@
272
281
  {"class":"R-status","site":{"arg_index":"splat:fields:strategy","expr":"fields['strategy']","message":null,"method":"emit_event","path":"core/default_context_manager.py","qualname":"DefaultContextManager._emit_trim"}}
273
282
  {"class":"R-status","site":{"arg_index":"splat:fields:strategy","expr":"fields['strategy']","message":null,"method":"emit_event","path":"core/ollama_context_manager.py","qualname":"OllamaContextManager._emit_trim"}}
274
283
  {"class":"R-id","site":{"arg_index":"splat:self._correlation():run_id","expr":"self._correlation()['run_id']","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
284
+ {"class":"R-id","site":{"arg_index":"splat:self._correlation():run_id","expr":"self._correlation()['run_id']","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call_received"}}
275
285
  {"class":"R-id","site":{"arg_index":"splat:self._correlation():run_id","expr":"self._correlation()['run_id']","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
276
286
  {"class":"R-id","site":{"arg_index":"splat:self._correlation():session_id","expr":"self._correlation()['session_id']","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call"}}
287
+ {"class":"R-id","site":{"arg_index":"splat:self._correlation():session_id","expr":"self._correlation()['session_id']","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop._emit_tool_call_received"}}
277
288
  {"class":"R-id","site":{"arg_index":"splat:self._correlation():session_id","expr":"self._correlation()['session_id']","message":null,"method":"emit_event","path":"loops/chat_loop.py","qualname":"ChatLoop.run"}}
278
289
  {"class":"dynamic-trusted","site":{"arg_index":null,"expr":"evt","message":null,"method":"trace","path":"log.py","qualname":"emit_event"}}
279
290
  {"class":"dynamic-residual:known-shape-masked","site":{"arg_index":null,"expr":"message","message":null,"method":"log","path":"logging_config.py","qualname":"_InterceptHandler.emit"}}
@@ -4,13 +4,15 @@ from typing import Any
4
4
 
5
5
  from pydantic import BaseModel, ConfigDict, model_validator
6
6
 
7
+ from ayder_cli.core.reasoning import ReasoningEffort, ThinkOption
8
+
7
9
 
8
10
  class AgentConfig(BaseModel):
9
11
  """Configuration for a single agent, parsed from [agents.<name>] TOML sections.
10
12
 
11
13
  Connection-level fields (base_url, api_key, num_ctx, temperature, think,
12
- driver) are optional; when set they override the values pulled from the
13
- parent provider profile. This lets one agent target an entirely different
14
+ reasoning_effort, driver) are optional; when set they override values from
15
+ the parent provider profile. This lets one agent target an entirely different
14
16
  endpoint than the main session without needing a separate [llm.<name>]
15
17
  profile.
16
18
  """
@@ -28,7 +30,8 @@ class AgentConfig(BaseModel):
28
30
  num_ctx: int | None = None
29
31
  temperature: float | None = None
30
32
  max_output_tokens: int | None = None
31
- think: str | None = None
33
+ think: ThinkOption = None
34
+ reasoning_effort: ReasoningEffort = None
32
35
 
33
36
  @model_validator(mode="before")
34
37
  @classmethod
@@ -56,7 +59,7 @@ class AgentConfig(BaseModel):
56
59
  return new_data
57
60
 
58
61
  def overrides(self) -> dict[str, Any]:
59
- """Return non-None connection-level fields suitable for cfg.model_copy()."""
62
+ """Return profile overrides, including an explicitly reset effort."""
60
63
  out: dict[str, Any] = {}
61
64
  for field in (
62
65
  "model",
@@ -71,4 +74,10 @@ class AgentConfig(BaseModel):
71
74
  value = getattr(self, field)
72
75
  if value is not None:
73
76
  out[field] = value
77
+ if "reasoning_effort" in self.model_fields_set:
78
+ # Explicit "default" clears a profile's effort; omission inherits it.
79
+ out["reasoning_effort"] = self.reasoning_effort
80
+ elif self.think is not None:
81
+ # An explicit legacy think override must beat an inherited effort.
82
+ out["reasoning_effort"] = None
74
83
  return out
@@ -154,6 +154,10 @@ class AgentRegistry:
154
154
  def current_generation(self) -> int:
155
155
  return self._current_generation
156
156
 
157
+ def set_parent_config(self, config: Any) -> None:
158
+ """Update defaults for future runs without mutating active agents."""
159
+ self._parent_config = config
160
+
157
161
  def new_generation(self) -> int:
158
162
  """Bump the conversation generation and reset the re-dispatch guard.
159
163
  Does NOT drop _runs: active agents keep running and are simply filtered
@@ -10,6 +10,7 @@ from dataclasses import dataclass, field
10
10
  from typing import TYPE_CHECKING, Any
11
11
 
12
12
  from ayder_cli.core.config import Config, load_config, load_config_for_provider
13
+ from ayder_cli.core.reasoning import validate_effort
13
14
  from ayder_cli.core.context_manager_factory import context_manager_factory
14
15
 
15
16
  if TYPE_CHECKING:
@@ -183,6 +184,8 @@ def create_agent_runtime(
183
184
  if overrides:
184
185
  cfg = cfg.model_copy(update=overrides)
185
186
 
187
+ validate_effort(cfg.driver, cfg.reasoning_effort)
188
+
186
189
  # 3. Create isolated AIProvider
187
190
  llm_provider = provider_orchestrator.create(cfg)
188
191