kweaver-dolphin 0.1.0__tar.gz → 0.2.0__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 (204) hide show
  1. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/PKG-INFO +1 -1
  2. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/pyproject.toml +1 -1
  3. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/ui/console.py +6 -6
  4. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/agent/base_agent.py +70 -7
  5. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/basic_code_block.py +41 -0
  6. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/explore_block.py +87 -8
  7. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/explore_block_v2.py +88 -3
  8. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/explore_strategy.py +2 -1
  9. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/judge_block.py +31 -7
  10. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/tool_block.py +56 -19
  11. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context/context.py +7 -4
  12. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/executor/dolphin_executor.py +9 -0
  13. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/llm/llm.py +2 -3
  14. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/llm/llm_client.py +1 -0
  15. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/utils/cache_kv.py +70 -8
  16. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/utils/tools.py +2 -0
  17. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/skill/traditional_toolkit.py +4 -0
  18. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/kweaver_dolphin.egg-info/PKG-INFO +1 -1
  19. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/LICENSE.txt +0 -0
  20. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/README.md +0 -0
  21. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/setup.cfg +0 -0
  22. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/DolphinLanguageSDK/__init__.py +0 -0
  23. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/__init__.py +0 -0
  24. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/__init__.py +0 -0
  25. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/args/__init__.py +0 -0
  26. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/args/parser.py +0 -0
  27. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/builtin_agents/__init__.py +0 -0
  28. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/commands/__init__.py +0 -0
  29. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/interrupt/__init__.py +0 -0
  30. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/interrupt/handler.py +0 -0
  31. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/interrupt/keyboard.py +0 -0
  32. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/main.py +0 -0
  33. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/multimodal/__init__.py +0 -0
  34. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/multimodal/clipboard.py +0 -0
  35. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/multimodal/handler.py +0 -0
  36. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/multimodal/image_processor.py +0 -0
  37. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/multimodal/input_parser.py +0 -0
  38. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/runner/__init__.py +0 -0
  39. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/runner/runner.py +0 -0
  40. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/ui/__init__.py +0 -0
  41. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/ui/input.py +0 -0
  42. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/ui/layout.py +0 -0
  43. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/ui/stream_renderer.py +0 -0
  44. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/utils/__init__.py +0 -0
  45. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/utils/helpers.py +0 -0
  46. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/cli/utils/version.py +0 -0
  47. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/__init__.py +0 -0
  48. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/agent/__init__.py +0 -0
  49. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/agent/agent_state.py +0 -0
  50. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/__init__.py +0 -0
  51. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/agent_init_block.py +0 -0
  52. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/assign_block.py +0 -0
  53. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/prompt_block.py +0 -0
  54. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/code_block/skill_call_deduplicator.py +0 -0
  55. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/__init__.py +0 -0
  56. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/constants.py +0 -0
  57. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/enums.py +0 -0
  58. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/exceptions.py +0 -0
  59. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/multimodal.py +0 -0
  60. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/object_type.py +0 -0
  61. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/output_format.py +0 -0
  62. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/common/types.py +0 -0
  63. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/config/__init__.py +0 -0
  64. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/config/global_config.py +0 -0
  65. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/config/ontology_config.py +0 -0
  66. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context/__init__.py +0 -0
  67. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context/context_manager.py +0 -0
  68. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context/var_output.py +0 -0
  69. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context/variable_pool.py +0 -0
  70. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/__init__.py +0 -0
  71. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/config/__init__.py +0 -0
  72. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/config/settings.py +0 -0
  73. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/core/__init__.py +0 -0
  74. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/core/budget_manager.py +0 -0
  75. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/core/context_assembler.py +0 -0
  76. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/core/context_manager.py +0 -0
  77. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/core/tokenizer_service.py +0 -0
  78. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/example/incremental_example.py +0 -0
  79. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/example/traditional_example.py +0 -0
  80. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/services/__init__.py +0 -0
  81. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/services/compressor.py +0 -0
  82. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/utils/__init__.py +0 -0
  83. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/utils/context_utils.py +0 -0
  84. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/utils/message_formatter.py +0 -0
  85. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/context_engineer/utils/token_utils.py +0 -0
  86. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/__init__.py +0 -0
  87. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/context_snapshot.py +0 -0
  88. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/context_snapshot_profile.py +0 -0
  89. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/context_snapshot_store.py +0 -0
  90. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/execution_frame.py +0 -0
  91. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/execution_state_registry.py +0 -0
  92. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/resume_handle.py +0 -0
  93. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/coroutine/step_result.py +0 -0
  94. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/executor/__init__.py +0 -0
  95. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/executor/debug_controller.py +0 -0
  96. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/executor/executor.py +0 -0
  97. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/flags/__init__.py +0 -0
  98. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/flags/definitions.py +0 -0
  99. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/flags/manager.py +0 -0
  100. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/hook/__init__.py +0 -0
  101. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/hook/expression_evaluator.py +0 -0
  102. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/hook/hook_dispatcher.py +0 -0
  103. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/hook/hook_types.py +0 -0
  104. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/hook/isolated_variable_pool.py +0 -0
  105. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/interfaces.py +0 -0
  106. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/llm/__init__.py +0 -0
  107. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/llm/llm_call.py +0 -0
  108. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/llm/message_sanitizer.py +0 -0
  109. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/logging/__init__.py +0 -0
  110. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/logging/logger.py +0 -0
  111. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/message/__init__.py +0 -0
  112. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/message/compressor.py +0 -0
  113. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/parser/__init__.py +0 -0
  114. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/parser/parser.py +0 -0
  115. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/runtime/__init__.py +0 -0
  116. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/runtime/runtime_graph.py +0 -0
  117. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/runtime/runtime_instance.py +0 -0
  118. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/skill/__init__.py +0 -0
  119. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/skill/context_retention.py +0 -0
  120. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/skill/skill_function.py +0 -0
  121. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/skill/skill_matcher.py +0 -0
  122. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/skill/skillkit.py +0 -0
  123. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/skill/skillset.py +0 -0
  124. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/trajectory/__init__.py +0 -0
  125. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/trajectory/recorder.py +0 -0
  126. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/trajectory/trajectory.py +0 -0
  127. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/core/utils/__init__.py +0 -0
  128. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/__init__.py +0 -0
  129. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/debug/__init__.py +0 -0
  130. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/debug/visualizer.py +0 -0
  131. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/__init__.py +0 -0
  132. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/async_processor.py +0 -0
  133. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/llm_calls.py +0 -0
  134. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/manager.py +0 -0
  135. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/sandbox.py +0 -0
  136. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/storage.py +0 -0
  137. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/memory/utils.py +0 -0
  138. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/__init__.py +0 -0
  139. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/basic/__init__.py +0 -0
  140. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/basic/base.py +0 -0
  141. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/basic/concept.py +0 -0
  142. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/basic/object.py +0 -0
  143. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/basic/relation.py +0 -0
  144. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/datasource/__init__.py +0 -0
  145. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/datasource/datasource.py +0 -0
  146. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/datasource/oracle_datasource.py +0 -0
  147. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/datasource/sql.py +0 -0
  148. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/mapping.py +0 -0
  149. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/ontology.py +0 -0
  150. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/ontology_context.py +0 -0
  151. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/ontology/ontology_manager.py +0 -0
  152. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/__init__.py +0 -0
  153. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/cache_backend.py +0 -0
  154. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/result_processor.py +0 -0
  155. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/result_reference.py +0 -0
  156. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/skillkit_hook.py +0 -0
  157. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/strategies.py +0 -0
  158. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skill_results/strategy_registry.py +0 -0
  159. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/__init__.py +0 -0
  160. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/agent_skillkit.py +0 -0
  161. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/cognitive_skillkit.py +0 -0
  162. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/env_skillkit.py +0 -0
  163. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/mcp_adapter.py +0 -0
  164. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/mcp_skillkit.py +0 -0
  165. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/memory_skillkit.py +0 -0
  166. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/noop_skillkit.py +0 -0
  167. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/ontology_skillkit.py +0 -0
  168. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/plan_act_skillkit.py +0 -0
  169. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/__init__.py +0 -0
  170. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/models/__init__.py +0 -0
  171. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/models/skill_config.py +0 -0
  172. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/models/skill_meta.py +0 -0
  173. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/resource_skillkit.py +0 -0
  174. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/skill_cache.py +0 -0
  175. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/skill_loader.py +0 -0
  176. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource/skill_validator.py +0 -0
  177. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/resource_skillkit.py +0 -0
  178. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/search_skillkit.py +0 -0
  179. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/sql_skillkit.py +0 -0
  180. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/system_skillkit.py +0 -0
  181. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/skillkits/vm_skillkit.py +0 -0
  182. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/utils/__init__.py +0 -0
  183. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/utils/data_process.py +0 -0
  184. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/utils/handle_progress.py +0 -0
  185. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/utils/security.py +0 -0
  186. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/utils/text_retrieval.py +0 -0
  187. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/vm/__init__.py +0 -0
  188. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/vm/env_executor.py +0 -0
  189. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/vm/python_session_manager.py +0 -0
  190. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/lib/vm/vm.py +0 -0
  191. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/__init__.py +0 -0
  192. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/agent/__init__.py +0 -0
  193. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/agent/agent_factory.py +0 -0
  194. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/agent/dolphin_agent.py +0 -0
  195. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/api/__init__.py +0 -0
  196. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/runtime/__init__.py +0 -0
  197. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/runtime/env.py +0 -0
  198. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/skill/__init__.py +0 -0
  199. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/dolphin/sdk/skill/global_skills.py +0 -0
  200. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/kweaver_dolphin.egg-info/SOURCES.txt +0 -0
  201. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/kweaver_dolphin.egg-info/dependency_links.txt +0 -0
  202. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/kweaver_dolphin.egg-info/entry_points.txt +0 -0
  203. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/kweaver_dolphin.egg-info/requires.txt +0 -0
  204. {kweaver_dolphin-0.1.0 → kweaver_dolphin-0.2.0}/src/kweaver_dolphin.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kweaver-dolphin
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Dolphin Language - An intelligent agent framework
5
5
  Author-email: AnyData <contact@anydata.com>
6
6
  License: Apache 2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kweaver-dolphin"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "Dolphin Language - An intelligent agent framework"
9
9
  authors = [
10
10
  {name = "AnyData", email = "contact@anydata.com"}
@@ -1738,14 +1738,14 @@ class ConsoleUI:
1738
1738
 
1739
1739
  # Block type icons and colors
1740
1740
  block_icons = {
1741
- "explore": ("🔍", Theme.SECONDARY),
1742
- "prompt": ("💬", Theme.SUCCESS),
1743
- "judge": ("⚖️", Theme.WARNING),
1744
- "assign": ("📝", Theme.PRIMARY),
1745
- "tool": ("", Theme.ACCENT),
1741
+ "explore": ("[?]", Theme.SECONDARY),
1742
+ "prompt": ("[>]", Theme.SUCCESS),
1743
+ "judge": ("[J]", Theme.WARNING),
1744
+ "assign": ("[=]", Theme.PRIMARY),
1745
+ "tool": ("[*]", Theme.ACCENT),
1746
1746
  }
1747
1747
 
1748
- icon, color = block_icons.get(block_type.lower(), ("📦", Theme.LABEL))
1748
+ icon, color = block_icons.get(block_type.lower(), ("[X]", Theme.LABEL))
1749
1749
 
1750
1750
  # Build output line
1751
1751
  header = f"{color}{Theme.BOLD}{icon} {block_type.upper()}{Theme.RESET}"
@@ -406,12 +406,34 @@ class BaseAgent(ABC):
406
406
  AgentState.PAUSED, "Agent paused due to tool interrupt"
407
407
  )
408
408
 
409
+ # Map interrupt_type: "tool_interrupt" (internal) -> "tool_confirmation" (API)
410
+ api_interrupt_type = self._pause_type.value
411
+ if run_result.resume_handle:
412
+ internal_type = run_result.resume_handle.interrupt_type
413
+ if internal_type == "tool_interrupt":
414
+ api_interrupt_type = "tool_confirmation"
415
+ elif internal_type == "user_interrupt":
416
+ api_interrupt_type = "user_interrupt"
417
+
409
418
  # 统一输出格式:status 固定为 "interrupted",通过 interrupt_type 区分
410
- yield {
419
+ interrupt_response = {
411
420
  "status": "interrupted",
412
421
  "handle": run_result.resume_handle,
413
- "interrupt_type": run_result.resume_handle.interrupt_type if run_result.resume_handle else self._pause_type.value,
422
+ "interrupt_type": api_interrupt_type,
414
423
  }
424
+
425
+ # For ToolInterrupt, include tool data from frame.error (same as step mode)
426
+ if run_result.is_tool_interrupted and self._current_frame and self._current_frame.error:
427
+ frame_error = self._current_frame.error
428
+ if frame_error.get("error_type") == "ToolInterrupt":
429
+ interrupt_response["data"] = {
430
+ "tool_name": frame_error.get("tool_name", ""),
431
+ "tool_description": "", # Can be added if available
432
+ "tool_args": frame_error.get("tool_args", []),
433
+ "interrupt_config": frame_error.get("tool_config", {}),
434
+ }
435
+
436
+ yield interrupt_response
415
437
  return
416
438
 
417
439
  elif run_result.is_completed:
@@ -463,11 +485,32 @@ class BaseAgent(ABC):
463
485
  )
464
486
 
465
487
  # 统一输出格式
466
- yield {
488
+ # Map interrupt_type: "tool_interrupt" (internal) -> "tool_confirmation" (API)
489
+ api_interrupt_type = self._pause_type.value
490
+ if step_result.resume_handle:
491
+ internal_type = step_result.resume_handle.interrupt_type
492
+ if internal_type == "tool_interrupt":
493
+ api_interrupt_type = "tool_confirmation"
494
+ elif internal_type == "user_interrupt":
495
+ api_interrupt_type = "user_interrupt"
496
+
497
+ interrupt_response = {
467
498
  "status": "interrupted",
468
499
  "handle": step_result.resume_handle,
469
- "interrupt_type": step_result.resume_handle.interrupt_type if step_result.resume_handle else self._pause_type.value,
500
+ "interrupt_type": api_interrupt_type,
470
501
  }
502
+
503
+ # For ToolInterrupt, include tool data from frame.error
504
+ if step_result.is_tool_interrupted and self._current_frame and self._current_frame.error:
505
+ frame_error = self._current_frame.error
506
+ if frame_error.get("error_type") == "ToolInterrupt":
507
+ interrupt_response["data"] = {
508
+ "tool_name": frame_error.get("tool_name", ""),
509
+ "tool_args": frame_error.get("tool_args", []),
510
+ "tool_config": frame_error.get("tool_config", {}),
511
+ }
512
+
513
+ yield interrupt_response
471
514
  break
472
515
 
473
516
  elif step_result.is_completed:
@@ -568,11 +611,22 @@ class BaseAgent(ABC):
568
611
  """Pause logic implemented by subclasses"""
569
612
  pass
570
613
 
571
- async def resume(self, updates: Optional[Dict[str, Any]] = None) -> bool:
614
+ async def resume(
615
+ self,
616
+ updates: Optional[Dict[str, Any]] = None,
617
+ resume_handle=None # External resume handle (for stateless scenarios)
618
+ ) -> bool:
572
619
  """Resume Agent (based on coroutine)
573
620
 
574
621
  Args:
575
622
  updates: Variable updates to inject (used to resume from tool interruption)
623
+ resume_handle: Optional external resume handle (for web apps/stateless scenarios)
624
+ If provided, will override internal _resume_handle
625
+ This allows resuming across different requests/processes
626
+
627
+ Usage Scenarios:
628
+ 1. Stateful (same process): resume(updates) - uses internal _resume_handle
629
+ 2. Stateless (web apps): resume(updates, resume_handle) - uses external handle
576
630
  """
577
631
  if self.state != AgentState.PAUSED:
578
632
  raise AgentLifecycleException(
@@ -580,9 +634,18 @@ class BaseAgent(ABC):
580
634
  )
581
635
 
582
636
  try:
583
- # Resume coroutine execution
584
- if self._resume_handle is not None:
637
+ # Use external handle if provided (for stateless scenarios like web apps)
638
+ # Otherwise use internal handle (for stateful scenarios like testing)
639
+ handle_to_use = resume_handle if resume_handle is not None else self._resume_handle
640
+
641
+ if handle_to_use is not None:
642
+ # Temporarily set internal handle for _on_resume_coroutine to use
643
+ original_handle = self._resume_handle
644
+ self._resume_handle = handle_to_use
645
+
585
646
  self._current_frame = await self._on_resume_coroutine(updates)
647
+
648
+ # Clear handles after resume
586
649
  self._resume_handle = None
587
650
  self._pause_type = None
588
651
 
@@ -1133,6 +1133,7 @@ class BasicCodeBlock:
1133
1133
  skill_params_json: Dict[str, Any] = {},
1134
1134
  props=None,
1135
1135
  ):
1136
+ from dolphin.core.utils.tools import ToolInterrupt
1136
1137
  if self.context.is_skillkit_empty():
1137
1138
  self.context.warn(f"skillkit is None, skill_name[{skill_name}]")
1138
1139
  return
@@ -1199,6 +1200,40 @@ class BasicCodeBlock:
1199
1200
  props = {}
1200
1201
  props.update({"gvp": self.context})
1201
1202
  try:
1203
+ # Check for tool interrupt configuration (ToolInterrupt mechanism)
1204
+ # Default: all tool calls support interrupt if tool has interrupt_config
1205
+ # Skip interrupt check if this is a resumed tool call (intervention=False)
1206
+ if props.get('intervention', True):
1207
+ interrupt_config = getattr(skill, 'interrupt_config', None)
1208
+ logger.debug(f"[DEBUG skill_run] skill_name={skill_name}, interrupt_config={interrupt_config}, intervention={props.get('intervention', True)}")
1209
+
1210
+ if interrupt_config and interrupt_config.get('requires_confirmation'):
1211
+ logger.debug(f"[DEBUG skill_run] Tool {skill_name} requires confirmation, raising ToolInterrupt")
1212
+ # Format confirmation message (support parameter interpolation)
1213
+ message = interrupt_config.get('confirmation_message', 'Tool requires confirmation')
1214
+ if message and skill_params_json:
1215
+ try:
1216
+ message = message.format(**skill_params_json)
1217
+ except (KeyError, ValueError):
1218
+ # If parameter interpolation fails, use original message
1219
+ pass
1220
+
1221
+ # Construct tool arguments list
1222
+ tool_args = [
1223
+ {"key": k, "value": v, "type": type(v).__name__}
1224
+ for k, v in skill_params_json.items()
1225
+ ]
1226
+
1227
+ # Throw ToolInterrupt (checked before execution)
1228
+ raise ToolInterrupt(
1229
+ message=message,
1230
+ tool_name=skill_name,
1231
+ tool_args=tool_args,
1232
+ tool_config=interrupt_config
1233
+ )
1234
+ else:
1235
+ logger.debug(f"[DEBUG skill_run] Tool {skill_name} does not require confirmation, proceeding with execution")
1236
+
1202
1237
  console_skill_call(
1203
1238
  skill_name, skill_params_json, verbose=self.context.verbose, skill=skill
1204
1239
  )
@@ -1410,6 +1445,12 @@ class BasicCodeBlock:
1410
1445
  if recorder:
1411
1446
  recorder.update(item=stream_item, raw_output=stream_item.answer)
1412
1447
 
1448
+ # Update tool call detection flags
1449
+ if stream_item.has_tool_call():
1450
+ tool_call_detected = True
1451
+ if stream_item.has_complete_tool_call():
1452
+ complete_tool_call = stream_item.get_tool_call()
1453
+
1413
1454
  yield stream_item
1414
1455
 
1415
1456
  # If a complete tool call is detected and early-stop is enabled, stop streaming.
@@ -558,10 +558,10 @@ Please reconsider your approach and improve your answer based on the feedback ab
558
558
  def _has_pending_tool_call(self) -> bool:
559
559
  """Check if there are pending tool calls (interrupt recovery)"""
560
560
  intervention_tmp_key = "intervention_explore_block_vars"
561
- return (
562
- intervention_tmp_key in self.context.get_all_variables().keys()
563
- and "tool" in self.context.get_all_variables().keys()
564
- )
561
+ has_intervention = intervention_tmp_key in self.context.get_all_variables().keys()
562
+ has_tool = "tool" in self.context.get_all_variables().keys()
563
+ logger.debug(f"[DEBUG _has_pending_tool_call] has_intervention={has_intervention}, has_tool={has_tool}")
564
+ return has_intervention and has_tool
565
565
 
566
566
  async def _handle_resumed_tool_call(self):
567
567
  """Tools for handling interrupt recovery calls """
@@ -571,17 +571,47 @@ Please reconsider your approach and improve your answer based on the feedback ab
571
571
  intervention_vars = self.context.get_var_value(intervention_tmp_key)
572
572
  self.context.delete_variable(intervention_tmp_key)
573
573
 
574
- # Restore complete message context
574
+ # Restore complete message context to context_manager buckets
575
575
  saved_messages = intervention_vars.get("prompt")
576
576
  if saved_messages is not None:
577
+ from dolphin.core.common.enums import MessageRole
578
+
579
+ # *** FIX: Filter out messages that are already in other buckets ***
580
+ # To avoid duplication, only restore messages generated during the conversation:
581
+ # - SYSTEM messages are already in SYSTEM bucket (from initial execute)
582
+ # - USER messages are already in QUERY/HISTORY buckets (initial query and history)
583
+ # - We only need to restore ASSISTANT and TOOL messages (conversation progress)
584
+ filtered_messages = [
585
+ msg for msg in saved_messages
586
+ if msg.get("role") in [MessageRole.ASSISTANT.value, MessageRole.TOOL.value]
587
+ ]
588
+
577
589
  msgs = Messages()
578
- msgs.extend_plain_messages(saved_messages)
579
- self.context.set_messages(msgs)
590
+ msgs.extend_plain_messages(filtered_messages)
591
+ # Use set_messages_batch to restore to context_manager buckets
592
+ # This ensures messages are available when to_dph_messages() is called
593
+ self.context.set_messages_batch(msgs, bucket=BuildInBucket.SCRATCHPAD.value)
580
594
 
581
595
  input_dict = self.context.get_var_value("tool")
582
596
  function_name = input_dict["tool_name"]
583
597
  raw_tool_args = input_dict["tool_args"]
584
598
  function_params_json = {arg["key"]: arg["value"] for arg in raw_tool_args}
599
+
600
+ # *** FIX: Update the last tool_call message with modified parameters ***
601
+ # This ensures LLM sees the actual parameters used, not the original ones
602
+ messages = self.context.get_messages()
603
+ if messages and len(messages.get_messages()) > 0:
604
+ last_message = messages.get_messages()[-1]
605
+ # Check if last message is an assistant message with tool_calls
606
+ if (hasattr(last_message, 'role') and last_message.role == "assistant" and
607
+ hasattr(last_message, 'tool_calls') and last_message.tool_calls):
608
+ # Find the matching tool_call
609
+ for tool_call in last_message.tool_calls:
610
+ if hasattr(tool_call, 'function') and tool_call.function.name == function_name:
611
+ # Update the arguments with modified parameters
612
+ import json
613
+ tool_call.function.arguments = json.dumps(function_params_json, ensure_ascii=False)
614
+ logger.debug(f"[FIX] Updated tool_call arguments from original to modified: {function_params_json}")
585
615
 
586
616
  if self.recorder:
587
617
  self.recorder.update(
@@ -591,9 +621,58 @@ Please reconsider your approach and improve your answer based on the feedback ab
591
621
  skill_type=self.context.get_skill_type(function_name),
592
622
  skill_args=function_params_json,
593
623
  )
624
+
625
+ # *** Handle skip action ***
626
+ skip_tool = self.context.get_var_value("__skip_tool__")
627
+ skip_message = self.context.get_var_value("__skip_message__")
628
+
629
+ # Clean up skip flags
630
+ if skip_tool:
631
+ self.context.delete_variable("__skip_tool__")
632
+ if skip_message:
633
+ self.context.delete_variable("__skip_message__")
634
+
594
635
  self.context.delete_variable("tool")
595
636
 
596
637
  return_answer = {}
638
+
639
+ # If user chose to skip, don't execute the tool
640
+ if skip_tool:
641
+ # Generate friendly skip message
642
+ params_str = ", ".join([f"{k}={v}" for k, v in function_params_json.items()])
643
+ default_skip_msg = f"Tool '{function_name}' was skipped by user"
644
+ if skip_message:
645
+ skip_response = f"[SKIPPED] {skip_message}"
646
+ else:
647
+ skip_response = f"[SKIPPED] {default_skip_msg} (parameters: {params_str})"
648
+
649
+ return_answer["answer"] = skip_response
650
+ return_answer["think"] = skip_response
651
+ return_answer["status"] = "completed"
652
+
653
+ if self.recorder:
654
+ self.recorder.update(
655
+ item={"answer": skip_response, "block_answer": skip_response},
656
+ stage=TypeStage.SKILL,
657
+ source_type=SourceType.EXPLORE,
658
+ skill_name=function_name,
659
+ skill_type=self.context.get_skill_type(function_name),
660
+ skill_args=function_params_json,
661
+ )
662
+
663
+ yield [return_answer]
664
+
665
+ # Add tool response message with skip indicator
666
+ tool_call_id = self._extract_tool_call_id()
667
+ if not tool_call_id:
668
+ tool_call_id = f"call_{function_name}_{self.times}"
669
+
670
+ self.strategy.append_tool_response_message(
671
+ self.context, tool_call_id, skip_response, metadata={"skipped": True}
672
+ )
673
+ return
674
+
675
+ # Normal execution (not skipped)
597
676
  try:
598
677
  props = {"intervention": False}
599
678
  have_answer = False
@@ -1061,7 +1140,7 @@ Please reconsider your approach and improve your answer based on the feedback ab
1061
1140
 
1062
1141
  def _handle_tool_interrupt(self, e: Exception, tool_name: str):
1063
1142
  """Handling Tool Interruptions"""
1064
- self.context.info(f"tool interrupt in call {tool_name} tool")
1143
+ self.context.info(f"Tool interrupt in call {tool_name} tool")
1065
1144
  if "※tool" in self.context.get_all_variables().keys():
1066
1145
  self.context.delete_variable("※tool")
1067
1146
 
@@ -295,17 +295,48 @@ class ExploreBlockV2(BasicCodeBlock):
295
295
  intervention_vars = self.context.get_var_value(intervention_tmp_key)
296
296
  self.context.delete_variable(intervention_tmp_key)
297
297
 
298
- # restore the complete message context before tool execution
298
+ # restore the complete message context to context_manager buckets
299
299
  saved_messages = intervention_vars.get("prompt")
300
300
  if saved_messages is not None:
301
+ from dolphin.core.common.enums import MessageRole
302
+ from dolphin.core.context_engineer.config.settings import BuildInBucket
303
+
304
+ # *** FIX: Filter out messages that are already in other buckets ***
305
+ # To avoid duplication, only restore messages generated during the conversation:
306
+ # - SYSTEM messages are already in SYSTEM bucket (from initial execute)
307
+ # - USER messages are already in QUERY/HISTORY buckets (initial query and history)
308
+ # - We only need to restore ASSISTANT and TOOL messages (conversation progress)
309
+ filtered_messages = [
310
+ msg for msg in saved_messages
311
+ if msg.get("role") in [MessageRole.ASSISTANT.value, MessageRole.TOOL.value]
312
+ ]
313
+
301
314
  msgs = Messages()
302
- msgs.extend_plain_messages(saved_messages)
303
- self.context.set_messages(msgs)
315
+ msgs.extend_plain_messages(filtered_messages)
316
+ # Use set_messages_batch to restore to context_manager buckets
317
+ # This ensures messages are available when to_dph_messages() is called
318
+ self.context.set_messages_batch(msgs, bucket=BuildInBucket.SCRATCHPAD.value)
304
319
 
305
320
  input_dict = self.context.get_var_value("tool")
306
321
  function_name = input_dict["tool_name"]
307
322
  raw_tool_args = input_dict["tool_args"]
308
323
  function_params_json = {arg["key"]: arg["value"] for arg in raw_tool_args}
324
+
325
+ # *** FIX: Update the last tool_call message with modified parameters ***
326
+ # This ensures LLM sees the actual parameters used, not the original ones
327
+ messages = self.context.get_messages()
328
+ if messages and len(messages.get_messages()) > 0:
329
+ last_message = messages.get_messages()[-1]
330
+ # Check if last message is an assistant message with tool_calls
331
+ if (hasattr(last_message, 'role') and last_message.role == "assistant" and
332
+ hasattr(last_message, 'tool_calls') and last_message.tool_calls):
333
+ # Find the matching tool_call
334
+ for tool_call in last_message.tool_calls:
335
+ if hasattr(tool_call, 'function') and tool_call.function.name == function_name:
336
+ # Update the arguments with modified parameters
337
+ import json
338
+ tool_call.function.arguments = json.dumps(function_params_json, ensure_ascii=False)
339
+ logger.debug(f"[FIX] Updated tool_call arguments from original to modified: {function_params_json}")
309
340
 
310
341
  (
311
342
  self.recorder.update(
@@ -318,9 +349,59 @@ class ExploreBlockV2(BasicCodeBlock):
318
349
  if self.recorder
319
350
  else None
320
351
  )
352
+
353
+ # *** Handle skip action ***
354
+ skip_tool = self.context.get_var_value("__skip_tool__")
355
+ skip_message = self.context.get_var_value("__skip_message__")
356
+
357
+ # Clean up skip flags
358
+ if skip_tool:
359
+ self.context.delete_variable("__skip_tool__")
360
+ if skip_message:
361
+ self.context.delete_variable("__skip_message__")
362
+
321
363
  self.context.delete_variable("tool")
322
364
 
323
365
  return_answer = {}
366
+
367
+ # If user chose to skip, don't execute the tool
368
+ if skip_tool:
369
+ # Generate friendly skip message
370
+ params_str = ", ".join([f"{k}={v}" for k, v in function_params_json.items()])
371
+ default_skip_msg = f"Tool '{function_name}' was skipped by user"
372
+ if skip_message:
373
+ skip_response = f"[SKIPPED] {skip_message}"
374
+ else:
375
+ skip_response = f"[SKIPPED] {default_skip_msg} (parameters: {params_str})"
376
+
377
+ return_answer["answer"] = skip_response
378
+ return_answer["think"] = skip_response
379
+ return_answer["status"] = "completed"
380
+
381
+ (
382
+ self.recorder.update(
383
+ item={"answer": skip_response, "block_answer": skip_response},
384
+ stage=TypeStage.SKILL,
385
+ source_type=SourceType.EXPLORE,
386
+ skill_name=function_name,
387
+ skill_type=self.context.get_skill_type(function_name),
388
+ skill_args=function_params_json,
389
+ )
390
+ if self.recorder
391
+ else None
392
+ )
393
+
394
+ yield [return_answer]
395
+
396
+ # Add tool response message with skip indicator
397
+ tool_call_id = self._extract_tool_call_id()
398
+ if not tool_call_id:
399
+ tool_call_id = f"call_{function_name}_{self.times}"
400
+
401
+ self._append_tool_message(tool_call_id, skip_response, metadata={"skipped": True})
402
+ return
403
+
404
+ # Normal execution (not skipped)
324
405
  try:
325
406
  props = {"intervention": False}
326
407
  have_answer = False
@@ -480,6 +561,7 @@ class ExploreBlockV2(BasicCodeBlock):
480
561
  return
481
562
 
482
563
  # Add assistant message containing tool calls
564
+ logger.debug(f"[DEBUG] Tool call detected, preparing to execute: {stream_item.tool_name}")
483
565
  tool_call_id = f"call_{stream_item.tool_name}_{self.times}"
484
566
  tool_call_openai_format = [
485
567
  {
@@ -506,13 +588,16 @@ class ExploreBlockV2(BasicCodeBlock):
506
588
  )
507
589
  self.deduplicator_skillcall.add(tool_call)
508
590
 
591
+ logger.debug(f"[DEBUG] Calling _execute_tool_call for: {stream_item.tool_name}")
509
592
  async for ret in self._execute_tool_call(stream_item, tool_call_id):
510
593
  yield ret
594
+ logger.debug(f"[DEBUG] _execute_tool_call completed for: {stream_item.tool_name}")
511
595
  else:
512
596
  await self._handle_duplicate_tool_call(tool_call, stream_item)
513
597
 
514
598
  async def _execute_tool_call(self, stream_item, tool_call_id: str):
515
599
  """Execute tool call"""
600
+ logger.debug(f"[DEBUG] _execute_tool_call ENTERED for: {stream_item.tool_name}")
516
601
  intervention_tmp_key = "intervention_explore_block_vars"
517
602
 
518
603
  try:
@@ -574,11 +574,12 @@ class ToolCallStrategy(ExploreStrategy):
574
574
  no_cache: bool = False,
575
575
  ) -> Dict[str, Any]:
576
576
  """Includes the tools parameter and an optional tool_choice"""
577
+ tools = skillkit.getSkillsSchema() if skillkit and not skillkit.isEmpty() else []
577
578
  llm_params = {
578
579
  "messages": messages,
579
580
  "model": model,
580
581
  "no_cache": no_cache,
581
- "tools": skillkit.getSkillsSchema() if skillkit and not skillkit.isEmpty() else [],
582
+ "tools": tools,
582
583
  }
583
584
 
584
585
  if tool_choice:
@@ -148,15 +148,39 @@ class JudgeBlock(BasicCodeBlock):
148
148
  new_tool_args = {arg["key"]: arg["value"] for arg in raw_tool_args}
149
149
 
150
150
  props = {"intervention": False, "gvp": self.context}
151
+
152
+ # *** Handle skip action ***
153
+ skip_tool = self.context.get_var_value("__skip_tool__")
154
+ skip_message = self.context.get_var_value("__skip_message__")
155
+
156
+ # Clean up skip flags
157
+ if skip_tool:
158
+ self.context.delete_variable("__skip_tool__")
159
+ if skip_message:
160
+ self.context.delete_variable("__skip_message__")
161
+
151
162
  self.context.delete_variable("tool")
152
163
 
153
- async for resp_item in self.skill_run(
154
- source_type=SourceType.SKILL,
155
- skill_name=tool_name,
156
- skill_params_json=new_tool_args,
157
- props=props,
158
- ):
159
- yield resp_item
164
+ # If user chose to skip, don't execute the tool
165
+ if skip_tool:
166
+ # Generate friendly skip message
167
+ params_str = ", ".join([f"{k}={v}" for k, v in new_tool_args.items()])
168
+ default_skip_msg = f"Tool '{tool_name}' was skipped by user"
169
+ if skip_message:
170
+ skip_response = f"[SKIPPED] {skip_message}"
171
+ else:
172
+ skip_response = f"[SKIPPED] {default_skip_msg} (parameters: {params_str})"
173
+
174
+ yield {"answer": skip_response}
175
+ else:
176
+ # Normal execution (not skipped)
177
+ async for resp_item in self.skill_run(
178
+ source_type=SourceType.SKILL,
179
+ skill_name=tool_name,
180
+ skill_params_json=new_tool_args,
181
+ props=props,
182
+ ):
183
+ yield resp_item
160
184
  else:
161
185
  self.recorder.set_output_var(self.assign_type, self.output_var)
162
186
 
@@ -70,28 +70,65 @@ class ToolBlock(BasicCodeBlock):
70
70
  new_tool_args = {arg["key"]: arg["value"] for arg in raw_tool_args}
71
71
 
72
72
  props = {"intervention": False, "gvp": self.context}
73
+
74
+ # *** Handle skip action ***
75
+ skip_tool = self.context.get_var_value("__skip_tool__")
76
+ skip_message = self.context.get_var_value("__skip_message__")
77
+
78
+ # Clean up skip flags
79
+ if skip_tool:
80
+ self.context.delete_variable("__skip_tool__")
81
+ if skip_message:
82
+ self.context.delete_variable("__skip_message__")
83
+
73
84
  input_dict = self.context.delete_variable("tool")
74
85
 
75
- resp_item = None
76
- async for resp_item in self.skill_run(
77
- source_type=SourceType.SKILL,
78
- skill_name=tool_name,
79
- skill_params_json=new_tool_args,
80
- props=props,
81
- ):
82
- yield resp_item
83
-
84
- if self.recorder is not None:
85
- self.recorder.update(
86
- stage=TypeStage.SKILL,
87
- item=resp_item,
88
- skill_name=tool_name,
89
- skill_args=new_tool_args,
90
- skill_type=self.context.get_skill_type(tool_name),
86
+ # If user chose to skip, don't execute the tool
87
+ if skip_tool:
88
+ # Generate friendly skip message
89
+ params_str = ", ".join([f"{k}={v}" for k, v in new_tool_args.items()])
90
+ default_skip_msg = f"Tool '{tool_name}' was skipped by user"
91
+ if skip_message:
92
+ skip_response = f"[SKIPPED] {skip_message}"
93
+ else:
94
+ skip_response = f"[SKIPPED] {default_skip_msg} (parameters: {params_str})"
95
+
96
+ resp_item = {"answer": skip_response}
97
+
98
+ if self.recorder is not None:
99
+ self.recorder.update(
100
+ stage=TypeStage.SKILL,
101
+ item=resp_item,
102
+ skill_name=tool_name,
103
+ skill_args=new_tool_args,
104
+ skill_type=self.context.get_skill_type(tool_name),
105
+ source_type=SourceType.SKILL,
106
+ is_completed=True,
107
+ )
108
+
109
+ yield {"data": resp_item}
110
+ else:
111
+ # Normal execution (not skipped)
112
+ resp_item = None
113
+ async for resp_item in self.skill_run(
91
114
  source_type=SourceType.SKILL,
92
- is_completed=True,
93
- )
94
- yield {"data": resp_item}
115
+ skill_name=tool_name,
116
+ skill_params_json=new_tool_args,
117
+ props=props,
118
+ ):
119
+ yield resp_item
120
+
121
+ if self.recorder is not None:
122
+ self.recorder.update(
123
+ stage=TypeStage.SKILL,
124
+ item=resp_item,
125
+ skill_name=tool_name,
126
+ skill_args=new_tool_args,
127
+ skill_type=self.context.get_skill_type(tool_name),
128
+ source_type=SourceType.SKILL,
129
+ is_completed=True,
130
+ )
131
+ yield {"data": resp_item}
95
132
  else:
96
133
  # step1: First parse, then retrieve the actual values from gvpool when actually calling the function (the actual variable values might be of type dict, list)
97
134
  tool_call_info = self.parse_tool_call()
@@ -969,10 +969,13 @@ class Context:
969
969
  if bucket is None:
970
970
  bucket = BuildInBucket.SCRATCHPAD.value
971
971
 
972
- # Empty the current bucket
973
- self.context_manager.clear_bucket(bucket)
974
- # Add new messages
975
- self.context_manager.add_bucket(bucket, messages)
972
+ # Replace bucket content (or create if not exists)
973
+ if self.context_manager.has_bucket(bucket):
974
+ # Use replace_bucket_content to directly replace existing bucket
975
+ self.context_manager.replace_bucket_content(bucket, messages)
976
+ else:
977
+ # Create new bucket if it doesn't exist
978
+ self.context_manager.add_bucket(bucket, messages)
976
979
 
977
980
  # Mark as dirty
978
981
  self.messages_dirty = True